/* Generated by re2c */
#line 1 "c/eof/02_bounds_checking.re"
// re2c $INPUT -o $OUTPUT 
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define YYMAXFILL 1


// expect YYMAXFILL-padded string
static int lex(const char *str, unsigned int len)
{
    const char *YYCURSOR = str, *YYLIMIT = str + len + YYMAXFILL;
    int count = 0;

loop:
    
#line 20 "c/eof/02_bounds_checking.c"
{
	char yych;
	if (YYLIMIT <= YYCURSOR) return -1;
	yych = *YYCURSOR;
	switch (yych) {
	case 0x00:	goto yy2;
	case ' ':	goto yy6;
	case '\'':	goto yy9;
	default:	goto yy4;
	}
yy2:
	++YYCURSOR;
#line 21 "c/eof/02_bounds_checking.re"
	{ return YYCURSOR == YYLIMIT ? count : -1; }
#line 35 "c/eof/02_bounds_checking.c"
yy4:
	++YYCURSOR;
#line 20 "c/eof/02_bounds_checking.re"
	{ return -1; }
#line 40 "c/eof/02_bounds_checking.c"
yy6:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) return -1;
	yych = *YYCURSOR;
	switch (yych) {
	case ' ':	goto yy6;
	default:	goto yy8;
	}
yy8:
#line 23 "c/eof/02_bounds_checking.re"
	{ goto loop; }
#line 52 "c/eof/02_bounds_checking.c"
yy9:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) return -1;
	yych = *YYCURSOR;
	switch (yych) {
	case '\'':	goto yy11;
	case '\\':	goto yy13;
	default:	goto yy9;
	}
yy11:
	++YYCURSOR;
#line 22 "c/eof/02_bounds_checking.re"
	{ ++count; goto loop; }
#line 66 "c/eof/02_bounds_checking.c"
yy13:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) return -1;
	yych = *YYCURSOR;
	goto yy9;
}
#line 25 "c/eof/02_bounds_checking.re"

}

// make a copy of the string with YYMAXFILL zeroes at the end
static void test(const char *str, unsigned int len, int res)
{
    char *s = (char*) malloc(len + YYMAXFILL);
    memcpy(s, str, len);
    memset(s + len, 0, YYMAXFILL);
    int r = lex(s, len);
    free(s);
    assert(r == res);
}

#define TEST(s, r) test(s, sizeof(s) - 1, r)
int main()
{
    TEST("", 0);
    TEST("'qu\0tes' 'are' 'fine: \\'' ", 3);
    TEST("'unterminated\\'", -1);
    return 0;
}
