std::ifstreamΒΆ

This example shows how to override re2c input mechanism: instead of reading input characters from a buffer in memory, read them directly from file using STL std::ifstream class. Note that we use tellg / seekg and rely on the ability to move backward and forward in the input stream: this might not be possible, for example with stdin stream. The program below converts Windows-style line endings CR LF to Unix-style line endings LF.

This program uses a non-standard way of checking for the end of input: it disables the usual cheching mechnism with re2c:yyfill:enable = 0; (this suppresses the generation of YYLESSTHAN and YYFILL) and puts the responsibility for checking on YYSKIP. This results in more frequent checks: YYSKIP is happens on each input character, while YYLESSTHAN happens only once per each strongly connected component of automaton. However, this method allows to avoid padding, which would require buffering input and nullify all advantages of direct-file input.

[ifstream.re]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <fstream>

static void conv(std::ifstream &in, std::ofstream &out)
{
    std::streampos mar;
#   define YYCTYPE     char
#   define YYPEEK()    in.peek()
#   define YYSKIP()    do { in.ignore(); if (in.eof()) return; } while(0)
#   define YYBACKUP()  mar = in.tellg()
#   define YYRESTORE() in.seekg(mar)
loop:
    /*!re2c
        re2c:yyfill:enable = 0;

        *      { out.put(yych); goto loop; }
        "\r\n" { out.put('\n'); goto loop; }
    */
}

int main(int argc, char **argv)
{
    if (argc != 3) return 1;

    std::ifstream in(argv[1], std::ios::binary);
    std::ofstream out(argv[2], std::ios::binary);
    if (in.fail() || out.fail()) return 2;

    conv(in, out);
    return 0;
}

Compile:

$ re2c --input custom -o ifstream.cc ifstream.re
$ g++ -o ifstream ifstream.cc