/* Generated by re2c */
#line 1 "c/submatch/01_stags_fill.re"
// re2c $INPUT -o $OUTPUT --tags
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <vector>

#define SIZE 4096

typedef struct {
    FILE *file;
    char buf[SIZE + 1], *lim, *cur, *mar, *tok;
    // Tag variables must be part of the lexer state passed to YYFILL.
    // They don't correspond to tags and should be autogenerated by re2c.
    
#line 19 "c/submatch/01_stags_fill.c"
const char *yyt1;const char *yyt2;const char *yyt3;const char *yyt4;
#line 15 "c/submatch/01_stags_fill.re"

    int eof;
} Input;

static int fill(Input *in)
{
    if (in->eof) return 1;

    const size_t free = in->tok - in->buf;
    if (free < 1) return 2;

    memmove(in->buf, in->tok, in->lim - in->tok);

    in->lim -= free;
    in->cur -= free;
    in->mar -= free;
    in->tok -= free;
    // Tag variables need to be shifted like other input positions. The check
    // for non-NULL is only needed if some tags are nested inside of alternative
    // or repetition, so that they can have NULL value.
    
#line 43 "c/submatch/01_stags_fill.c"
if (in->yyt1) in->yyt1 -= free;
if (in->yyt2) in->yyt2 -= free;
if (in->yyt3) in->yyt3 -= free;
if (in->yyt4) in->yyt4 -= free;
#line 35 "c/submatch/01_stags_fill.re"


    in->lim += fread(in->lim, 1, free, in->file);
    in->lim[0] = 0;
    in->eof |= in->lim < in->buf + SIZE;

    return 0;
}

static void init(Input *in, FILE *file)
{
    in->file = file;
    in->cur = in->mar = in->tok = in->lim = in->buf + SIZE;
    // Initialization is only needed to avoid "use of uninitialized" warnings
    // when shifting tags in YYFILL. In the lexer tags are guaranteed to be
    // set before they are used (either to a valid input position, or NULL).
    
#line 66 "c/submatch/01_stags_fill.c"
in->yyt1 = in->lim;
in->yyt2 = in->lim;
in->yyt3 = in->lim;
in->yyt4 = in->lim;
#line 51 "c/submatch/01_stags_fill.re"

    in->eof = 0;
    fill(in);
}

static uint32_t num(const char *s, const char *e)
{
    uint32_t n = 0;
    for (; s < e; ++s) n = n * 10 + (*s - '0');
    return n;
}

static bool lex(Input *in, std::vector<uint32_t> &ips)
{
    // User-defined local variables that store final tag values.
    // They are different from tag variables autogenerated with `stags:re2c`,
    // as they are set at the end of match and used only in semantic actions.
    const char *o1, *o2, *o3, *o4;
loop:
    in->tok = in->cur;
    
#line 93 "c/submatch/01_stags_fill.c"
{
	char yych;
yyFillLabel0:
	yych = *in->cur;
	switch (yych) {
	case '0':
		in->yyt1 = in->cur;
		goto yy4;
	case '1':
		in->yyt1 = in->cur;
		goto yy5;
	case '2':
		in->yyt1 = in->cur;
		goto yy6;
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		in->yyt1 = in->cur;
		goto yy7;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel0;
			goto yy32;
		}
		goto yy2;
	}
yy2:
	++in->cur;
yy3:
#line 96 "c/submatch/01_stags_fill.re"
	{ return false; }
#line 129 "c/submatch/01_stags_fill.c"
yy4:
	in->mar = ++in->cur;
yyFillLabel1:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel1;
		}
		goto yy3;
	}
yy5:
	in->mar = ++in->cur;
yyFillLabel2:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy10;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel2;
		}
		goto yy3;
	}
yy6:
	in->mar = ++in->cur;
yyFillLabel3:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':	goto yy10;
	case '5':	goto yy11;
	case '6':
	case '7':
	case '8':
	case '9':	goto yy12;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel3;
		}
		goto yy3;
	}
yy7:
	in->mar = ++in->cur;
yyFillLabel4:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy12;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel4;
		}
		goto yy3;
	}
yy8:
	++in->cur;
yyFillLabel5:
	yych = *in->cur;
	switch (yych) {
	case '0':
		in->yyt2 = in->cur;
		goto yy13;
	case '1':
		in->yyt2 = in->cur;
		goto yy14;
	case '2':
		in->yyt2 = in->cur;
		goto yy15;
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		in->yyt2 = in->cur;
		goto yy16;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel5;
		}
		goto yy9;
	}
yy9:
	in->cur = in->mar;
	goto yy3;
yy10:
	++in->cur;
yyFillLabel6:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy12;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel6;
		}
		goto yy9;
	}
yy11:
	++in->cur;
yyFillLabel7:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':	goto yy12;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel7;
		}
		goto yy9;
	}
yy12:
	++in->cur;
yyFillLabel8:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy8;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel8;
		}
		goto yy9;
	}
yy13:
	++in->cur;
yyFillLabel9:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy17;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel9;
		}
		goto yy9;
	}
yy14:
	++in->cur;
yyFillLabel10:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy17;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy16;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel10;
		}
		goto yy9;
	}
yy15:
	++in->cur;
yyFillLabel11:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy17;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':	goto yy16;
	case '5':	goto yy18;
	case '6':
	case '7':
	case '8':
	case '9':	goto yy13;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel11;
		}
		goto yy9;
	}
yy16:
	++in->cur;
yyFillLabel12:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy17;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy13;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel12;
		}
		goto yy9;
	}
yy17:
	++in->cur;
yyFillLabel13:
	yych = *in->cur;
	switch (yych) {
	case '0':
		in->yyt3 = in->cur;
		goto yy19;
	case '1':
		in->yyt3 = in->cur;
		goto yy20;
	case '2':
		in->yyt3 = in->cur;
		goto yy21;
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		in->yyt3 = in->cur;
		goto yy22;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel13;
		}
		goto yy9;
	}
yy18:
	++in->cur;
yyFillLabel14:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy17;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':	goto yy13;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel14;
		}
		goto yy9;
	}
yy19:
	++in->cur;
yyFillLabel15:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy23;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel15;
		}
		goto yy9;
	}
yy20:
	++in->cur;
yyFillLabel16:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy23;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy22;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel16;
		}
		goto yy9;
	}
yy21:
	++in->cur;
yyFillLabel17:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy23;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':	goto yy22;
	case '5':	goto yy24;
	case '6':
	case '7':
	case '8':
	case '9':	goto yy19;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel17;
		}
		goto yy9;
	}
yy22:
	++in->cur;
yyFillLabel18:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy23;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy19;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel18;
		}
		goto yy9;
	}
yy23:
	++in->cur;
yyFillLabel19:
	yych = *in->cur;
	switch (yych) {
	case '0':
		in->yyt4 = in->cur;
		goto yy25;
	case '1':
		in->yyt4 = in->cur;
		goto yy26;
	case '2':
		in->yyt4 = in->cur;
		goto yy27;
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
		in->yyt4 = in->cur;
		goto yy28;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel19;
		}
		goto yy9;
	}
yy24:
	++in->cur;
yyFillLabel20:
	yych = *in->cur;
	switch (yych) {
	case '.':	goto yy23;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':	goto yy19;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel20;
		}
		goto yy9;
	}
yy25:
	++in->cur;
yyFillLabel21:
	yych = *in->cur;
	switch (yych) {
	case '\n':	goto yy29;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel21;
		}
		goto yy9;
	}
yy26:
	++in->cur;
yyFillLabel22:
	yych = *in->cur;
	switch (yych) {
	case '\n':	goto yy29;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy28;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel22;
		}
		goto yy9;
	}
yy27:
	++in->cur;
yyFillLabel23:
	yych = *in->cur;
	switch (yych) {
	case '\n':	goto yy29;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':	goto yy28;
	case '5':	goto yy31;
	case '6':
	case '7':
	case '8':
	case '9':	goto yy25;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel23;
		}
		goto yy9;
	}
yy28:
	++in->cur;
yyFillLabel24:
	yych = *in->cur;
	switch (yych) {
	case '\n':	goto yy29;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':	goto yy25;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel24;
		}
		goto yy9;
	}
yy29:
	++in->cur;
	o1 = in->yyt1;
	o2 = in->yyt2;
	o3 = in->yyt3;
	o4 = in->yyt4;
#line 88 "c/submatch/01_stags_fill.re"
	{
        ips.push_back(num(o4, in->cur - 1)
            + (num(o3, o4 - 1) << 8)
            + (num(o2, o3 - 1) << 16)
            + (num(o1, o2 - 1) << 24));
        goto loop;
    }
#line 634 "c/submatch/01_stags_fill.c"
yy31:
	++in->cur;
yyFillLabel25:
	yych = *in->cur;
	switch (yych) {
	case '\n':	goto yy29;
	case '0':
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':	goto yy25;
	default:
		if (in->lim <= in->cur) {
			if (fill(in) == 0) goto yyFillLabel25;
		}
		goto yy9;
	}
yy32:
#line 95 "c/submatch/01_stags_fill.re"
	{ return true; }
#line 656 "c/submatch/01_stags_fill.c"
}
#line 97 "c/submatch/01_stags_fill.re"

}

int main()
{
    const char *fname = "input";
    FILE *f;
    Input in;
    std::vector<uint32_t> have, want;

    // Write a few IPv4 addresses to the input file and save them to compare
    // against parse results.
    f = fopen(fname, "w");
    for (int i = 0; i < 256; ++i) {
        fprintf(f, "%d.%d.%d.%d\n", i, i, i, i);
        want.push_back(i + (i << 8) + (i << 16) + (i << 24));
    }
    fclose(f);

    f = fopen(fname, "r");
    init(&in, f);

    assert(lex(&in, have) && have == want);

    fclose(f);
    remove(fname);
    return 0;
}
