/* Generated by re2c 0.5 on Thu Sep 23 16:52:44 1999 */ #line 1 "../../../php4/ext/standard/url_scanner.re" /* +----------------------------------------------------------------------+ | PHP version 4.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997, 1998, 1999 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.0 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available at through the world-wide-web at | | http://www.php.net/license/2_0.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Sascha Schumann | +----------------------------------------------------------------------+ */ /* $Id$ */ #include #include #include #include #undef MIN #define MIN(a,b) (a)<(b)?(a):(b) #define YYCTYPE char #define YYCURSOR state->crs #define YYLIMIT state->end #define YYMARKER state->ptr #define YYFILL(n) typedef enum { INITIAL, REF } state; typedef struct { state state; const char *crs; const char *end; const char *ptr; const char *start; char *target; size_t targetsize; const char *data; } lexdata; #define FINISH { catchup(state); goto finish; } #define BEGIN(x) \ switch(state->state) { \ case INITIAL: \ catchup(state); \ break; \ case REF: \ screw_url(state); \ break; \ } \ state->state = x; \ state->start = state->crs; \ goto nextiter #define ATTACH(s, n) \ { \ size_t _newlen = state->targetsize + n; \ state->target = realloc(state->target, _newlen + 1); \ memcpy(state->target + state->targetsize, s, n); \ state->targetsize = _newlen; \ state->target[_newlen] = '\0'; \ } #define URLLEN 512 static void screw_url(lexdata *state) { int len; char buf[URLLEN]; char url[URLLEN]; const char *p, *q; char c; /* search outer limits for URI */ for(p = state->start; p < state->crs && (c = *p); p++) if(c != '"' && c != ' ') break; /* * we look at q-1, because q points to the character behind the last * character we are going to copy and the decision is based on that last * character */ for(q = state->crs; q > state->start && (c = *(q-1)); q--) if(c != '"' && c != ' ') break; /* attach beginning */ ATTACH(state->start, p-state->start); /* copy old URI */ len = MIN(q - p, sizeof(buf) - 1); memcpy(url, p, len); url[len] = '\0'; /* construct new URI */ len = snprintf(buf, sizeof(buf), "%s%c%s", url, memchr(state->start, '?', len) ? '&' : '?', state->data); /* attach new URI */ ATTACH(buf, len); /* attach rest */ ATTACH(q, state->crs - q); } static void catchup(lexdata *state) { ATTACH(state->start, (state->crs - state->start)); } #line 135 static void url_scanner(lexdata *state) { while(state->crs < state->end) { switch(state->state) { case INITIAL: { YYCTYPE yych; unsigned int yyaccept; goto yy0; yy1: ++YYCURSOR; yy0: if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; switch(yych){ case '\000': goto yy7; case '<': goto yy2; default: goto yy4; } yy2: yych = *++YYCURSOR; switch(yych){ case 'A': case 'a': goto yy9; case 'F': case 'f': goto yy10; default: goto yy3; } yy3:yy4: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy5: switch(yych){ case '\000': case '<': goto yy6; default: goto yy4; } yy6: #line 146 { BEGIN(INITIAL); } yy7: yych = *++YYCURSOR; yy8: #line 147 { FINISH; } yy9: yych = *++YYCURSOR; switch(yych){ case 'H': case 'h': goto yy3; default: goto yy25; } yy10: yych = *++YYCURSOR; switch(yych){ case 'R': case 'r': goto yy11; default: goto yy3; } yy11: yych = *++YYCURSOR; switch(yych){ case 'A': case 'a': goto yy12; default: goto yy3; } yy12: yych = *++YYCURSOR; switch(yych){ case 'M': case 'm': goto yy13; default: goto yy3; } yy13: yych = *++YYCURSOR; switch(yych){ case 'E': case 'e': goto yy14; default: goto yy3; } yy14: yych = *++YYCURSOR; switch(yych){ case 'S': case 's': goto yy3; default: goto yy16; } yy15: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy16: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy15; case 'S': case 's': goto yy17; default: goto yy3; } yy17: yych = *++YYCURSOR; switch(yych){ case 'R': case 'r': goto yy18; default: goto yy3; } yy18: yych = *++YYCURSOR; switch(yych){ case 'C': case 'c': goto yy19; default: goto yy3; } yy19: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy20: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy19; case '=': goto yy21; default: goto yy3; } yy21: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy22: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy21; default: goto yy23; } yy23: #line 144 { BEGIN(REF); } yy24: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy25: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy24; case 'H': case 'h': goto yy26; default: goto yy3; } yy26: yych = *++YYCURSOR; switch(yych){ case 'R': case 'r': goto yy27; default: goto yy3; } yy27: yych = *++YYCURSOR; switch(yych){ case 'E': case 'e': goto yy28; default: goto yy3; } yy28: yych = *++YYCURSOR; switch(yych){ case 'F': case 'f': goto yy29; default: goto yy3; } yy29: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy30: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy29; case '=': goto yy31; default: goto yy3; } yy31: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy32: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy31; default: goto yy33; } yy33: #line 145 { BEGIN(REF); } } #line 148 break; case REF: { YYCTYPE yych; unsigned int yyaccept; goto yy34; yy35: ++YYCURSOR; yy34: if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; switch(yych){ case '\000': case '#': case '>': goto yy36; case '\t': case '\v': case '\f': case ' ': case '"': goto yy37; case ':': goto yy42; default: goto yy39; } yy36:yy37: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy38: switch(yych){ case '\000': case '"': case '#': case '>': goto yy36; case '\t': case '\v': case '\f': case ' ': goto yy37; case ':': goto yy42; default: goto yy39; } yy39: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy40: switch(yych){ case '\000': case '>': goto yy41; case '\t': case '\v': case '\f': case ' ': goto yy48; case '"': goto yy50; case '#': goto yy51; case ':': goto yy42; default: goto yy39; } yy41: #line 152 { BEGIN(INITIAL); } yy42: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy43: switch(yych){ case '\000': case '#': case '>': goto yy44; case '\t': case '\v': case '\f': case ' ': goto yy45; case '"': goto yy47; default: goto yy42; } yy44: #line 154 { /* don't modify absolute links */ state->state = INITIAL; BEGIN(INITIAL); } yy45: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy46: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy45; case '"': goto yy47; default: goto yy44; } yy47: yych = *++YYCURSOR; goto yy44; yy48: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy49: switch(yych){ case '\t': case '\v': case '\f': case ' ': goto yy48; case '"': goto yy50; default: goto yy41; } yy50: yych = *++YYCURSOR; goto yy41; yy51: yych = *++YYCURSOR; yy52: YYCURSOR -= 1; #line 153 { BEGIN(INITIAL); } } #line 158 break; } nextiter: ; } finish: ; } char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen) { lexdata state; state.state = INITIAL; state.start = state.crs = src; state.end = src + srclen; state.ptr = NULL; state.target = NULL; state.targetsize = 0; state.data = data; url_scanner(&state); if(newlen) *newlen = state.targetsize; return state.target; }