/* Generated by re2c */
#line 1 "codegen/c/recursive_functions/advanced.re"
// re2c $INPUT -o $OUTPUT -cf --recursive-functions -Wno-nondeterministic-tags

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#line 10 "codegen/c/recursive_functions/advanced.c"
enum YYCONDTYPE {
	yycmedia_type = 1,
	yycheader = 23
};
#line 7 "codegen/c/recursive_functions/advanced.re"


struct mtag {
    struct mtag* prev;
    int          dist;
};

struct mtagpool {
    struct mtag* head;
    struct mtag* next;
    struct mtag* last;
};

enum con_status {
    CON_STATUS_WAITING,
    CON_STATUS_DONE,
    CON_STATUS_END,
    CON_STATUS_ERROR
};

#define CON_STATE_SIZE  (4096-32)
typedef struct con_state {
    unsigned char*  cur;
    unsigned char*  mar;
    unsigned char*  tok;
    unsigned char*  lim;
    int             cond;
    int             state;
    struct mtagpool mtp;
    
#line 46 "codegen/c/recursive_functions/advanced.c"
	unsigned char*		yyt1;
	unsigned char*		yyt2;
#line 36 "codegen/c/recursive_functions/advanced.re"

    
#line 52 "codegen/c/recursive_functions/advanced.c"
	struct mtag				*yytm1;
	struct mtag				*yytm10;
	struct mtag				*yytm2;
	struct mtag				*yytm3;
	struct mtag				*yytm4;
	struct mtag				*yytm5;
	struct mtag				*yytm6;
	struct mtag				*yytm7;
	struct mtag				*yytm8;
	struct mtag				*yytm9;
#line 37 "codegen/c/recursive_functions/advanced.re"

    unsigned int    accept;
    const unsigned char *l1, *l2;
    struct mtag     *f1, *f2, *p1, *p2, *p3, *p4;
    size_t          buf_size;
    unsigned char*  buf;
    unsigned char   static_buf[];
} con_state;
#define CON_READ_BUF_LEN  (CON_STATE_SIZE - sizeof(struct con_state) - 1) // -1: ensure a sentinel at the end of buf

static void mtagpool_init(struct mtagpool* mtp)
{
    static const unsigned size = 1024 * 1024;
    mtp->head = (struct mtag*)malloc(size * sizeof(struct mtag));
    mtp->next = mtp->head;
    mtp->last = mtp->head + size;
}

static void mtagpool_free(struct mtagpool* mtp)
{
    free(mtp->head);
    mtp->head = mtp->next = mtp->last = NULL;
}

static struct mtag* mtagpool_next(struct mtagpool* mtp)
{
    unsigned     size;
    struct mtag* head;

    if (mtp->next < mtp->last) return mtp->next++;

    size = mtp->last - mtp->head;
    head = (struct mtag*)malloc(2 * size * sizeof(struct mtag));
    memcpy(head, mtp->head, size * sizeof(struct mtag));
    free(mtp->head);
    mtp->head = head;
    mtp->next = head + size;
    mtp->last = head + size * 2;

    return mtp->next++;
}

static void mtag(struct mtag** pmt, const unsigned char* b, const unsigned char* t, struct mtagpool* mtp)
{
    struct mtag* mt = mtagpool_next(mtp);
    mt->prev = *pmt;
    mt->dist = t - b;
    *pmt = mt;
}


#line 115 "codegen/c/recursive_functions/advanced.c"
static enum con_status yy1(struct con_state* c);
static enum con_status yy2(struct con_state* c);
static enum con_status yy3(struct con_state* c);
static enum con_status yy4(struct con_state* c);
static enum con_status yy5(struct con_state* c);
static enum con_status yy6(struct con_state* c, unsigned char yych);
static enum con_status yy7(struct con_state* c);
static enum con_status yy8(struct con_state* c);
static enum con_status yy9(struct con_state* c);
static enum con_status yy10(struct con_state* c, unsigned char yych);
static enum con_status yy11(struct con_state* c);
static enum con_status yy12(struct con_state* c);
static enum con_status yy13(struct con_state* c);
static enum con_status yy14(struct con_state* c);
static enum con_status yy15(struct con_state* c);
static enum con_status yy16(struct con_state* c);
static enum con_status yy17(struct con_state* c);
static enum con_status yy18(struct con_state* c);
static enum con_status yy19(struct con_state* c);
static enum con_status yy20(struct con_state* c);
static enum con_status yy21(struct con_state* c);
static enum con_status yy22(struct con_state* c);
static enum con_status yyfnmedia_type(struct con_state* c);
static enum con_status yy23(struct con_state* c);
static enum con_status yy24(struct con_state* c);
static enum con_status yy25(struct con_state* c);
static enum con_status yy26(struct con_state* c);
static enum con_status yy27(struct con_state* c);
static enum con_status yy28(struct con_state* c);
static enum con_status yy29(struct con_state* c);
static enum con_status yy30(struct con_state* c);
static enum con_status yy31(struct con_state* c);
static enum con_status yy32(struct con_state* c);
static enum con_status yy33(struct con_state* c);
static enum con_status yy34(struct con_state* c);
static enum con_status yy35(struct con_state* c);
static enum con_status yy36(struct con_state* c);
static enum con_status yy37(struct con_state* c);
static enum con_status yy38(struct con_state* c);
static enum con_status yy39(struct con_state* c);
static enum con_status yy40(struct con_state* c);
static enum con_status yy41(struct con_state* c);
static enum con_status yy42(struct con_state* c);
static enum con_status yy43(struct con_state* c);
static enum con_status yy44(struct con_state* c);
static enum con_status yyfnheader(struct con_state* c);
static enum con_status yy0(struct con_state* c);
static enum con_status parse_con_req(struct con_state* c);

static enum con_status yy1(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			c->yyt1 = c->cur;
			++c->cur;
			return yy4(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 0;
				return CON_STATUS_WAITING;
			} else {
				++c->cur;
				return yy2(c);
			}
	}
}

static enum con_status yy2(struct con_state* c) {
	return yy3(c);
}

static enum con_status yy3(struct con_state* c) {
	c->state = -1;
#line 171 "codegen/c/recursive_functions/advanced.re"
	return CON_STATUS_ERROR;
#line 267 "codegen/c/recursive_functions/advanced.c"
}

static enum con_status yy4(struct con_state* c) {
	unsigned char yych = *(c->mar = c->cur);
	switch (yych) {
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '/':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~': return yy6(c, yych);
		default:
			if (c->lim <= c->cur) {
				c->state = 1;
				return CON_STATUS_WAITING;
			} else {
				return yy3(c);
			}
	}
}

static enum con_status yy5(struct con_state* c) {
	unsigned char yych = *c->cur;
	return yy6(c, yych);
}

static enum con_status yy6(struct con_state* c, unsigned char yych) {
	switch (yych) {
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			++c->cur;
			return yy5(c);
		case '/':
			++c->cur;
			return yy8(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 2;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy7(struct con_state* c) {
	c->cur = c->mar;
	return yy3(c);
}

static enum con_status yy8(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case '\t':
		case '\r':
		case ' ':
		case ';':
			if (c->lim <= c->cur) {
				c->state = 3;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
		default: return yy10(c, yych);
	}
}

static enum con_status yy9(struct con_state* c) {
	unsigned char yych = *c->cur;
	return yy10(c, yych);
}

static enum con_status yy10(struct con_state* c, unsigned char yych) {
	switch (yych) {
		case '\t':
		case ' ':
			c->yytm6 = c->yytm10;
			mtag(&c->yytm6, c->tok, NULL, &c->mtp);
			c->yytm5 = c->yytm9;
			mtag(&c->yytm5, c->tok, NULL, &c->mtp);
			c->yytm4 = c->yytm8;
			mtag(&c->yytm4, c->tok, NULL, &c->mtp);
			c->yytm3 = c->yytm7;
			mtag(&c->yytm3, c->tok, NULL, &c->mtp);
			c->yyt2 = c->cur;
			++c->cur;
			return yy11(c);
		case '\r':
			c->yytm6 = c->yytm10;
			mtag(&c->yytm6, c->tok, NULL, &c->mtp);
			c->yytm5 = c->yytm9;
			mtag(&c->yytm5, c->tok, NULL, &c->mtp);
			c->yytm4 = c->yytm8;
			mtag(&c->yytm4, c->tok, NULL, &c->mtp);
			c->yytm3 = c->yytm7;
			mtag(&c->yytm3, c->tok, NULL, &c->mtp);
			c->yyt2 = c->cur;
			++c->cur;
			return yy12(c);
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			++c->cur;
			return yy9(c);
		case ';':
			c->yyt2 = c->cur;
			++c->cur;
			return yy13(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 4;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy11(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			++c->cur;
			return yy11(c);
		case '\r':
			++c->cur;
			return yy12(c);
		case ';':
			++c->cur;
			return yy13(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 5;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy12(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\n':
			++c->cur;
			return yy14(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 6;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy13(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			++c->cur;
			return yy13(c);
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			mtag(&c->yytm7, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy15(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 7;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy14(struct con_state* c) {
	c->l1 = c->yyt1;
	c->l2 = c->yyt2;
	c->p1 = c->yytm3;
	c->p2 = c->yytm4;
	c->p3 = c->yytm5;
	c->p4 = c->yytm6;
	c->state = -1;
#line 135 "codegen/c/recursive_functions/advanced.re"
	
        struct mtag*    pname_start = c->p1;
        struct mtag*    pname_end   = c->p2;
        struct mtag*    pval_start  = c->p3;
        struct mtag*    pval_end    = c->p4;

        printf("media type: %.*s\n", (int)(c->l2-c->l1), c->l1);

        while (0 && pname_start) {
            printf("\t(%.*s) = (%.*s)\n",
                pname_end->dist - pname_start->dist, c->tok + pname_start->dist,
                pval_end->dist - pval_start->dist, c->tok + pval_start->dist);

            pname_start = pname_start->prev;
            pname_end = pname_end->prev;
            pval_start = pval_start->prev;
            pval_end = pval_end->prev;
        }

        return CON_STATUS_DONE;

#line 774 "codegen/c/recursive_functions/advanced.c"
}

static enum con_status yy15(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			++c->cur;
			return yy15(c);
		case '=':
			mtag(&c->yytm8, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy16(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 8;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy16(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			mtag(&c->yytm9, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy17(c);
		case '"':
			mtag(&c->yytm9, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy18(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 9;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy17(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			mtag(&c->yytm10, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy19(c);
		case '\r':
			c->yytm3 = c->yytm7;
			c->yytm4 = c->yytm8;
			c->yytm5 = c->yytm9;
			c->yytm6 = c->yytm10;
			mtag(&c->yytm6, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy12(c);
		case '!':
		case '#':
		case '$':
		case '%':
		case '&':
		case '\'':
		case '*':
		case '+':
		case '-':
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '^':
		case '_':
		case '`':
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case '|':
		case '~':
			++c->cur;
			return yy17(c);
		case ';':
			mtag(&c->yytm10, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy13(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 10;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy18(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case '\r':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x1F:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 11;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
		case '"':
			++c->cur;
			return yy20(c);
		case '\\':
			++c->cur;
			return yy21(c);
		default:
			++c->cur;
			return yy18(c);
	}
}

static enum con_status yy19(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			++c->cur;
			return yy19(c);
		case '\r':
			c->yytm3 = c->yytm7;
			c->yytm4 = c->yytm8;
			c->yytm5 = c->yytm9;
			c->yytm6 = c->yytm10;
			++c->cur;
			return yy12(c);
		case ';':
			++c->cur;
			return yy13(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 12;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy20(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			mtag(&c->yytm10, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy19(c);
		case '\r':
			c->yytm3 = c->yytm7;
			c->yytm4 = c->yytm8;
			c->yytm5 = c->yytm9;
			c->yytm6 = c->yytm10;
			mtag(&c->yytm6, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy12(c);
		case ';':
			mtag(&c->yytm10, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy13(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 13;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
	}
}

static enum con_status yy21(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case '\r':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 14;
				return CON_STATUS_WAITING;
			} else {
				return yy7(c);
			}
		default:
			++c->cur;
			return yy18(c);
	}
}

static enum con_status yy22(struct con_state* c) {
	c->state = -1;
#line 170 "codegen/c/recursive_functions/advanced.re"
	return CON_STATUS_END;
#line 1239 "codegen/c/recursive_functions/advanced.c"
}

static enum con_status yyfnmedia_type(struct con_state* c) {
	return yy1(c);
}

static enum con_status yy23(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\t':
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 15;
				return CON_STATUS_WAITING;
			} else {
				++c->cur;
				return yy24(c);
			}
		case '\r':
			mtag(&c->yytm3, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy26(c);
		default:
			++c->cur;
			return yy27(c);
	}
}

static enum con_status yy24(struct con_state* c) {
	return yy25(c);
}

static enum con_status yy25(struct con_state* c) {
	c->state = -1;
#line 171 "codegen/c/recursive_functions/advanced.re"
	return CON_STATUS_ERROR;
#line 1305 "codegen/c/recursive_functions/advanced.c"
}

static enum con_status yy26(struct con_state* c) {
	c->accept = 0;
	unsigned char yych = *(c->mar = c->cur);
	switch (yych) {
		case '\n':
			++c->cur;
			return yy28(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 16;
				return CON_STATUS_WAITING;
			} else {
				return yy25(c);
			}
	}
}

static enum con_status yy27(struct con_state* c) {
	c->accept = 0;
	unsigned char yych = *(c->mar = c->cur);
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 17;
				return CON_STATUS_WAITING;
			} else {
				return yy25(c);
			}
		case '\t':
			++c->cur;
			return yy30(c);
		case '\r':
			mtag(&c->yytm3, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy31(c);
		default:
			++c->cur;
			return yy32(c);
	}
}

static enum con_status yy28(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			++c->cur;
			return yy33(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 18;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
	}
}

static enum con_status yy29(struct con_state* c) {
	c->cur = c->mar;
	if (c->accept == 0) return yy25(c);
	else return yy38(c);
}

static enum con_status yy30(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case '\r':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 19;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\t':
			++c->cur;
			return yy30(c);
		case ' ':
			++c->cur;
			return yy32(c);
		default:
			++c->cur;
			return yy34(c);
	}
}

static enum con_status yy31(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\n':
			++c->cur;
			return yy28(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 20;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
	}
}

static enum con_status yy32(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 21;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\t':
			++c->cur;
			return yy30(c);
		case '\r':
			mtag(&c->yytm3, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy31(c);
		default:
			++c->cur;
			return yy32(c);
	}
}

static enum con_status yy33(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 22;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\t':
		case ' ':
			++c->cur;
			return yy33(c);
		case '\r':
			mtag(&c->yytm5, c->tok, c->cur, &c->mtp);
			c->yytm4 = c->yytm3;
			mtag(&c->yytm4, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy35(c);
		default:
			mtag(&c->yytm5, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy36(c);
	}
}

static enum con_status yy34(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\t':
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 23;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\r':
			mtag(&c->yytm3, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy31(c);
		default:
			++c->cur;
			return yy32(c);
	}
}

static enum con_status yy35(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\n':
			++c->cur;
			return yy37(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 24;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
	}
}

static enum con_status yy36(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 25;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\t':
			++c->cur;
			return yy39(c);
		case '\r':
			c->yytm4 = c->yytm3;
			mtag(&c->yytm4, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy35(c);
		default:
			++c->cur;
			return yy36(c);
	}
}

static enum con_status yy37(struct con_state* c) {
	c->accept = 1;
	unsigned char yych = *(c->mar = c->cur);
	switch (yych) {
		case '\t':
		case ' ':
			c->yytm1 = c->yytm3;
			c->yytm2 = c->yytm5;
			c->yytm3 = c->yytm4;
			++c->cur;
			return yy33(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 26;
				return CON_STATUS_WAITING;
			} else {
				c->yytm1 = c->yytm3;
				c->yytm2 = c->yytm5;
				return yy38(c);
			}
	}
}

static enum con_status yy38(struct con_state* c) {
	c->f1 = c->yytm1;
	c->f2 = c->yytm2;
	c->state = -1;
#line 157 "codegen/c/recursive_functions/advanced.re"
	
        struct mtag*    fold_start  = c->f1;
        struct mtag*    fold_end    = c->f2;

        while (fold_start) {
            memset(c->tok + fold_start->dist, ' ', fold_end->dist - fold_start->dist);
            fold_start  = fold_start->prev;
            fold_end    = fold_end->prev;
        }

        return CON_STATUS_DONE;

#line 1736 "codegen/c/recursive_functions/advanced.c"
}

static enum con_status yy39(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 27;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\t':
			++c->cur;
			return yy39(c);
		case '\r':
			++c->cur;
			return yy40(c);
		case ' ':
			++c->cur;
			return yy36(c);
		default:
			++c->cur;
			return yy41(c);
	}
}

static enum con_status yy40(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\n':
			++c->cur;
			return yy42(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 28;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
	}
}

static enum con_status yy41(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case 0x00:
		case 0x01:
		case 0x02:
		case 0x03:
		case 0x04:
		case 0x05:
		case 0x06:
		case 0x07:
		case 0x08:
		case '\n':
		case '\v':
		case '\f':
		case 0x0E:
		case 0x0F:
		case 0x10:
		case 0x11:
		case 0x12:
		case 0x13:
		case 0x14:
		case 0x15:
		case 0x16:
		case 0x17:
		case 0x18:
		case 0x19:
		case 0x1A:
		case 0x1B:
		case 0x1C:
		case 0x1D:
		case 0x1E:
		case 0x7F:
			if (c->lim <= c->cur) {
				c->state = 29;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
		case '\t':
			++c->cur;
			return yy43(c);
		case '\r':
			c->yytm4 = c->yytm3;
			mtag(&c->yytm4, c->tok, c->cur, &c->mtp);
			++c->cur;
			return yy35(c);
		default:
			++c->cur;
			return yy36(c);
	}
}

static enum con_status yy42(struct con_state* c) {
	c->yytm1 = c->yytm3;
	c->yytm2 = c->yytm5;
	return yy38(c);
}

static enum con_status yy43(struct con_state* c) {
	unsigned char yych = *c->cur;
	switch (yych) {
		case '\t':
		case ' ':
			++c->cur;
			return yy43(c);
		case '\r':
			++c->cur;
			return yy40(c);
		default:
			if (c->lim <= c->cur) {
				c->state = 30;
				return CON_STATUS_WAITING;
			} else {
				return yy29(c);
			}
	}
}

static enum con_status yy44(struct con_state* c) {
	c->state = -1;
#line 170 "codegen/c/recursive_functions/advanced.re"
	return CON_STATUS_END;
#line 1892 "codegen/c/recursive_functions/advanced.c"
}

static enum con_status yyfnheader(struct con_state* c) {
	return yy23(c);
}

static enum con_status yy0(struct con_state* c) {
	switch (c->cond) {
		case yycmedia_type: return yyfnmedia_type(c);
		case yycheader: return yyfnheader(c);
		default: abort();
	}
}

static enum con_status parse_con_req(struct con_state* c) {
	switch (c->state) {
		case -1: return yy0(c);
		case 0:
			if (c->lim <= c->cur) return yy22(c);
			else return yy1(c);
		case 1:
			if (c->lim <= c->cur) return yy3(c);
			else return yy4(c);
		case 2:
			if (c->lim <= c->cur) return yy7(c);
			else return yy5(c);
		case 3:
			if (c->lim <= c->cur) return yy7(c);
			else return yy8(c);
		case 4:
			if (c->lim <= c->cur) return yy7(c);
			else return yy9(c);
		case 5:
			if (c->lim <= c->cur) return yy7(c);
			else return yy11(c);
		case 6:
			if (c->lim <= c->cur) return yy7(c);
			else return yy12(c);
		case 7:
			if (c->lim <= c->cur) return yy7(c);
			else return yy13(c);
		case 8:
			if (c->lim <= c->cur) return yy7(c);
			else return yy15(c);
		case 9:
			if (c->lim <= c->cur) return yy7(c);
			else return yy16(c);
		case 10:
			if (c->lim <= c->cur) return yy7(c);
			else return yy17(c);
		case 11:
			if (c->lim <= c->cur) return yy7(c);
			else return yy18(c);
		case 12:
			if (c->lim <= c->cur) return yy7(c);
			else return yy19(c);
		case 13:
			if (c->lim <= c->cur) return yy7(c);
			else return yy20(c);
		case 14:
			if (c->lim <= c->cur) return yy7(c);
			else return yy21(c);
		case 15:
			if (c->lim <= c->cur) return yy44(c);
			else return yy23(c);
		case 16:
			if (c->lim <= c->cur) return yy25(c);
			else return yy26(c);
		case 17:
			if (c->lim <= c->cur) return yy25(c);
			else return yy27(c);
		case 18:
			if (c->lim <= c->cur) return yy29(c);
			else return yy28(c);
		case 19:
			if (c->lim <= c->cur) return yy29(c);
			else return yy30(c);
		case 20:
			if (c->lim <= c->cur) return yy29(c);
			else return yy31(c);
		case 21:
			if (c->lim <= c->cur) return yy29(c);
			else return yy32(c);
		case 22:
			if (c->lim <= c->cur) return yy29(c);
			else return yy33(c);
		case 23:
			if (c->lim <= c->cur) return yy29(c);
			else return yy34(c);
		case 24:
			if (c->lim <= c->cur) return yy29(c);
			else return yy35(c);
		case 25:
			if (c->lim <= c->cur) return yy29(c);
			else return yy36(c);
		case 26:
			if (c->lim <= c->cur) {
				c->yytm1 = c->yytm3;
				c->yytm2 = c->yytm5;
				return yy38(c);
			} else {
				return yy37(c);
			}
		case 27:
			if (c->lim <= c->cur) return yy29(c);
			else return yy39(c);
		case 28:
			if (c->lim <= c->cur) return yy29(c);
			else return yy40(c);
		case 29:
			if (c->lim <= c->cur) return yy29(c);
			else return yy41(c);
		case 30:
			if (c->lim <= c->cur) return yy29(c);
			else return yy43(c);
		default: abort();
	}
}

#line 172 "codegen/c/recursive_functions/advanced.re"


int feed(struct con_state* c, const unsigned char* chunk, size_t len)
{
    const size_t shift = c->tok - c->buf;
    const size_t free = c->buf_size - (c->lim - c->tok);

    if (free < len) {
        fprintf(stderr, "Token too long for receive buffer: %ld\n", c->buf_size);
        return 1;
    }

    if (shift) {
        memmove(c->buf, c->tok, c->buf_size - shift);
        c->lim -= shift;
        c->cur -= shift;
        c->mar -= shift;
        c->tok -= shift;
        
#line 2032 "codegen/c/recursive_functions/advanced.c"
			if (c->yyt1) c->yyt1 -= shift;
			if (c->yyt2) c->yyt2 -= shift;
#line 190 "codegen/c/recursive_functions/advanced.re"

    }

    memcpy(c->lim, chunk, len);

    c->lim += len;
    c->lim[0] = 0;  // Append sentinel

    return 0;
}

int main(int argc, char** argv)
{
    int rc = 0;
    int i;
    struct con_state* c = NULL;
    static const char* chunks[] = {
        "ap",
        "plication/j",
        "son;",
        " charset=\"",
        "utf\\\"-8\"\r",
        "\n",
        "",
        NULL
    };

    c = (con_state*)malloc(CON_STATE_SIZE);
    c->buf = c->static_buf;
    c->cur = c->mar = c->tok = c->lim = c->buf + CON_READ_BUF_LEN;
    c->lim[0] = 0; // sentinel
    c->state = -1;
    c->cond = yycmedia_type;
    c->buf_size = CON_READ_BUF_LEN;
    
#line 2071 "codegen/c/recursive_functions/advanced.c"
	c->yyt1 = 0;
	c->yyt2 = 0;
#line 224 "codegen/c/recursive_functions/advanced.re"

    
#line 2077 "codegen/c/recursive_functions/advanced.c"
	c->yytm1 = NULL;
	c->yytm10 = NULL;
	c->yytm2 = NULL;
	c->yytm3 = NULL;
	c->yytm4 = NULL;
	c->yytm5 = NULL;
	c->yytm6 = NULL;
	c->yytm7 = NULL;
	c->yytm8 = NULL;
	c->yytm9 = NULL;
#line 225 "codegen/c/recursive_functions/advanced.re"

    mtagpool_init(&c->mtp);

    for (i=0;;) {
        switch (parse_con_req(c)) {
            case CON_STATUS_WAITING:
                printf("waiting\n");
                rc = feed(c, (const unsigned char*)chunks[i], strlen(chunks[i]));
                ++i;
                if (rc) goto finally;
                break;
            case CON_STATUS_DONE:
                printf("done\n");
                break;
            case CON_STATUS_END:
                printf("end\n");
                goto finally;
            case CON_STATUS_ERROR:
                printf("error\n");
                rc = 1;
                goto finally;
        }
    }

finally:
    if (c) {
        mtagpool_free(&c->mtp);
        free(c);
        c = NULL;
    }
    if (rc) fprintf(stderr, "Error exit: %d\n", rc);
    return rc;
}
