/* Generated by re2c */
// re2c $INPUT -o $OUTPUT --loop-switch -i
#include <assert.h>
#include <stdio.h>
#include <string.h>

#define YYMAXFILL 1

#define SIZE 4096

typedef struct {
    FILE *file;
    char buf[SIZE + YYMAXFILL], *lim, *cur, *mar, *tok;
    int eof;
} Input;

static int fill(Input *in, size_t need)
{
    if (in->eof) {
        return 1;
    }
    const size_t free = in->tok - in->buf;
    if (free < need) {
        return 2;
    }
    memmove(in->buf, in->tok, in->lim - in->tok);
    in->lim -= free;
    in->cur -= free;
    in->mar -= free;
    in->tok -= free;
    in->lim += fread(in->lim, 1, free, in->file);
    if (in->lim < in->buf + SIZE) {
        in->eof = 1;
        memset(in->lim, 0, YYMAXFILL);
        in->lim += YYMAXFILL;
    }
    return 0;
}

static void init(Input *in, FILE *file)
{
    in->file = file;
    in->cur = in->mar = in->tok = in->lim = in->buf + SIZE;
    in->eof = 0;
    fill(in, 1);
}

static int lex(Input *in)
{
    int count = 0;
loop:
    in->tok = in->cur;
    
{
	char yych;
	unsigned int yystate = 0;
	for (;;) {
		switch (yystate) {
			case 0:
				if (in->lim <= in->cur) if (fill(in, 1) != 0) return -1;
				yych = *in->cur;
				++in->cur;
				switch (yych) {
					case 0x00:
						yystate = 1;
						continue;
					case ' ':
						yystate = 3;
						continue;
					case '\'':
						yystate = 5;
						continue;
					default:
						yystate = 2;
						continue;
				}
			case 1: { return (in->lim - in->cur == YYMAXFILL - 1) ? count : -1; }
			case 2: { return -1; }
			case 3:
				if (in->lim <= in->cur) if (fill(in, 1) != 0) return -1;
				yych = *in->cur;
				switch (yych) {
					case ' ':
						++in->cur;
						yystate = 3;
						continue;
					default:
						yystate = 4;
						continue;
				}
			case 4: { goto loop; }
			case 5:
				if (in->lim <= in->cur) if (fill(in, 1) != 0) return -1;
				yych = *in->cur;
				++in->cur;
				switch (yych) {
					case '\'':
						yystate = 6;
						continue;
					case '\\':
						yystate = 7;
						continue;
					default:
						yystate = 5;
						continue;
				}
			case 6: { ++count; goto loop; }
			case 7:
				if (in->lim <= in->cur) if (fill(in, 1) != 0) return -1;
				++in->cur;
				yystate = 5;
				continue;
		}
	}
}

}

int main()
{
    const char *fname = "input";
    const char str[] = "'qu\0tes' 'are' 'fine: \\'' ";
    FILE *f;
    Input in;

    // prepare input file: a few times the size of the buffer,
    // containing strings with zeroes and escaped quotes
    f = fopen(fname, "w");
    for (int i = 0; i < SIZE; ++i) {
        fwrite(str, 1, sizeof(str) - 1, f);
    }
    fclose(f);

    f = fopen(fname, "r");
    init(&in, f);
    assert(lex(&in) == SIZE * 3);
    fclose(f);

    remove(fname);
    return 0;
}
