Annotation of embedaddon/php/Zend/zend_ini_scanner.l, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | Zend Engine                                                          |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 2.00 of the Zend license,     |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.zend.com/license/2_00.txt.                                |
        !            11:    | If you did not receive a copy of the Zend license and are unable to  |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@zend.com so we can mail you a copy immediately.              |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Authors: Zeev Suraski <zeev@zend.com>                                |
        !            16:    |          Jani Taskinen <jani@php.net>                                |
        !            17:    |          Marcus Boerger <helly@php.net>                              |
        !            18:    |          Nuno Lopes <nlopess@php.net>                                |
        !            19:    |          Scott MacVicar <scottmac@php.net>                           |
        !            20:    +----------------------------------------------------------------------+
        !            21: */
        !            22: 
        !            23: /* $Id: zend_ini_scanner.l 321634 2012-01-01 13:15:04Z felipe $ */
        !            24: 
        !            25: #include <errno.h>
        !            26: #include "zend.h"
        !            27: #include "zend_globals.h"
        !            28: #include <zend_ini_parser.h>
        !            29: #include "zend_ini_scanner.h"
        !            30: 
        !            31: #if 0
        !            32: # define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c)
        !            33: #else
        !            34: # define YYDEBUG(s, c)
        !            35: #endif
        !            36: 
        !            37: #include "zend_ini_scanner_defs.h"
        !            38: 
        !            39: #define YYCTYPE   unsigned char
        !            40: /* allow the scanner to read one null byte after the end of the string (from ZEND_MMAP_AHEAD)
        !            41:  * so that if will be able to terminate to match the current token (e.g. non-enclosed string) */
        !            42: #define YYFILL(n) { if (YYCURSOR > YYLIMIT) return 0; }
        !            43: #define YYCURSOR  SCNG(yy_cursor)
        !            44: #define YYLIMIT   SCNG(yy_limit)
        !            45: #define YYMARKER  SCNG(yy_marker)
        !            46: 
        !            47: #define YYGETCONDITION()  SCNG(yy_state)
        !            48: #define YYSETCONDITION(s) SCNG(yy_state) = s
        !            49: 
        !            50: #define STATE(name)  yyc##name
        !            51: 
        !            52: /* emulate flex constructs */
        !            53: #define BEGIN(state) YYSETCONDITION(STATE(state))
        !            54: #define YYSTATE      YYGETCONDITION()
        !            55: #define yytext       ((char*)SCNG(yy_text))
        !            56: #define yyleng       SCNG(yy_leng)
        !            57: #define yyless(x)    do {      YYCURSOR = (unsigned char*)yytext + x; \
        !            58:                                                        yyleng   = (unsigned int)x; } while(0)
        !            59: 
        !            60: /* #define yymore()     goto yymore_restart */
        !            61: 
        !            62: /* perform sanity check. If this message is triggered you should
        !            63:    increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */
        !            64: /*!max:re2c */
        !            65: #if ZEND_MMAP_AHEAD < (YYMAXFILL + 1)
        !            66: # error ZEND_MMAP_AHEAD should be greater than YYMAXFILL
        !            67: #endif
        !            68: 
        !            69: 
        !            70: /* How it works (for the core ini directives):
        !            71:  * ===========================================
        !            72:  *
        !            73:  * 1. Scanner scans file for tokens and passes them to parser.
        !            74:  * 2. Parser parses the tokens and passes the name/value pairs to the callback
        !            75:  *    function which stores them in the configuration hash table.
        !            76:  * 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual
        !            77:  *    registering of ini entries and uses zend_get_configuration_directive()
        !            78:  *    to fetch the previously stored name/value pair from configuration hash table
        !            79:  *    and registers the static ini entries which match the name to the value
        !            80:  *    into EG(ini_directives) hash table.
        !            81:  * 4. PATH section entries are used per-request from down to top, each overriding
        !            82:  *    previous if one exists. zend_alter_ini_entry() is called for each entry.
        !            83:  *    Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the
        !            84:  *    php_admin_* directives used within Apache httpd.conf when PHP is compiled as
        !            85:  *    module for Apache.
        !            86:  * 5. User defined ini files (like .htaccess for apache) are parsed for each request and
        !            87:  *    stored in separate hash defined by SAPI.
        !            88:  */
        !            89: 
        !            90: /* TODO: (ordered by importance :-)
        !            91:  * ===============================================================================
        !            92:  *
        !            93:  *  - Separate constant lookup totally from plain strings (using CONSTANT pattern)
        !            94:  *  - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators
        !            95:  *  - Add #include "some.ini"
        !            96:  *  - Allow variables to refer to options also when using parse_ini_file()
        !            97:  *
        !            98:  */
        !            99: 
        !           100: /* Globals Macros */
        !           101: #define SCNG   INI_SCNG
        !           102: #ifdef ZTS
        !           103: ZEND_API ts_rsrc_id ini_scanner_globals_id;
        !           104: #else
        !           105: ZEND_API zend_ini_scanner_globals ini_scanner_globals;
        !           106: #endif
        !           107: 
        !           108: /* Eat leading whitespace */
        !           109: #define EAT_LEADING_WHITESPACE()                     \
        !           110:        while (yytext[0]) {                              \
        !           111:                if (yytext[0] == ' ' || yytext[0] == '\t') { \
        !           112:                        SCNG(yy_text)++;                         \
        !           113:                        yyleng--;                                \
        !           114:                } else {                                     \
        !           115:                        break;                                   \
        !           116:                }                                            \
        !           117:        }
        !           118: 
        !           119: /* Eat trailing whitespace + extra char */
        !           120: #define EAT_TRAILING_WHITESPACE_EX(ch)              \
        !           121:        while (yyleng > 0 && (                          \
        !           122:                (ch != 'X' && yytext[yyleng - 1] ==  ch) || \
        !           123:                yytext[yyleng - 1] == '\n' ||               \
        !           124:                yytext[yyleng - 1] == '\r' ||               \
        !           125:                yytext[yyleng - 1] == '\t' ||               \
        !           126:                yytext[yyleng - 1] == ' ')                  \
        !           127:        ) {                                             \
        !           128:                yyleng--;                                   \
        !           129:        }
        !           130: 
        !           131: /* Eat trailing whitespace */
        !           132: #define EAT_TRAILING_WHITESPACE()      EAT_TRAILING_WHITESPACE_EX('X')
        !           133: 
        !           134: #define zend_ini_copy_value(retval, str, len) {  \
        !           135:        Z_STRVAL_P(retval) = zend_strndup(str, len); \
        !           136:        Z_STRLEN_P(retval) = len;                    \
        !           137:        Z_TYPE_P(retval) = IS_STRING;                \
        !           138: }
        !           139: 
        !           140: #define RETURN_TOKEN(type, str, len) {           \
        !           141:        zend_ini_copy_value(ini_lval, str, len);     \
        !           142:        return type;                                 \
        !           143: }
        !           144: 
        !           145: static void _yy_push_state(int new_state TSRMLS_DC)
        !           146: {
        !           147:        zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
        !           148:        YYSETCONDITION(new_state);
        !           149: }
        !           150: 
        !           151: #define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
        !           152: 
        !           153: static void yy_pop_state(TSRMLS_D)
        !           154: {
        !           155:        int *stack_state;
        !           156:        zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
        !           157:        YYSETCONDITION(*stack_state);
        !           158:        zend_stack_del_top(&SCNG(state_stack));
        !           159: }
        !           160: 
        !           161: static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
        !           162: {
        !           163:        YYCURSOR = (YYCTYPE*)str;
        !           164:        SCNG(yy_start) = YYCURSOR;
        !           165:        YYLIMIT  = YYCURSOR + len;
        !           166: }
        !           167: 
        !           168: #define ini_filename SCNG(filename)
        !           169: 
        !           170: /* {{{ init_ini_scanner()
        !           171: */
        !           172: static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
        !           173: {
        !           174:        /* Sanity check */
        !           175:        if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) {
        !           176:                zend_error(E_WARNING, "Invalid scanner mode");
        !           177:                return FAILURE;
        !           178:        }
        !           179: 
        !           180:        SCNG(lineno) = 1;
        !           181:        SCNG(scanner_mode) = scanner_mode;
        !           182:        SCNG(yy_in) = fh;
        !           183: 
        !           184:        if (fh != NULL) {
        !           185:                ini_filename = zend_strndup(fh->filename, strlen(fh->filename));
        !           186:        } else {
        !           187:                ini_filename = NULL;
        !           188:        }
        !           189: 
        !           190:        zend_stack_init(&SCNG(state_stack));
        !           191:        BEGIN(INITIAL);
        !           192: 
        !           193:        return SUCCESS;
        !           194: }
        !           195: /* }}} */
        !           196: 
        !           197: /* {{{ shutdown_ini_scanner()
        !           198: */
        !           199: void shutdown_ini_scanner(TSRMLS_D)
        !           200: {
        !           201:        zend_stack_destroy(&SCNG(state_stack));
        !           202:        if (ini_filename) {
        !           203:                free(ini_filename);
        !           204:        }
        !           205: }
        !           206: /* }}} */
        !           207: 
        !           208: /* {{{ zend_ini_scanner_get_lineno()
        !           209: */
        !           210: int zend_ini_scanner_get_lineno(TSRMLS_D)
        !           211: {
        !           212:        return SCNG(lineno);
        !           213: }
        !           214: /* }}} */
        !           215: 
        !           216: /* {{{ zend_ini_scanner_get_filename()
        !           217: */
        !           218: char *zend_ini_scanner_get_filename(TSRMLS_D)
        !           219: {
        !           220:        return ini_filename ? ini_filename : "Unknown";
        !           221: }
        !           222: /* }}} */
        !           223: 
        !           224: /* {{{ zend_ini_open_file_for_scanning()
        !           225: */
        !           226: int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC)
        !           227: {
        !           228:        char *buf;
        !           229:        size_t size;
        !           230: 
        !           231:        if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE ||
        !           232:                init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE
        !           233:        ) {
        !           234:                return FAILURE;
        !           235:        }
        !           236: 
        !           237:        yy_scan_buffer(buf, size TSRMLS_CC);
        !           238: 
        !           239:        return SUCCESS;
        !           240: }
        !           241: /* }}} */
        !           242: 
        !           243: /* {{{ zend_ini_prepare_string_for_scanning()
        !           244: */
        !           245: int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC)
        !           246: {
        !           247:        int len = strlen(str);
        !           248: 
        !           249:        if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) {
        !           250:                return FAILURE;
        !           251:        }
        !           252: 
        !           253:        yy_scan_buffer(str, len TSRMLS_CC);
        !           254: 
        !           255:        return SUCCESS;
        !           256: }
        !           257: /* }}} */
        !           258: 
        !           259: /* {{{ zend_ini_escape_string()
        !           260:  */
        !           261: static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC)
        !           262: {
        !           263:        register char *s, *t;
        !           264:        char *end;
        !           265: 
        !           266:        zend_ini_copy_value(lval, str, len);
        !           267: 
        !           268:        /* convert escape sequences */
        !           269:        s = t = Z_STRVAL_P(lval);
        !           270:        end = s + Z_STRLEN_P(lval);
        !           271: 
        !           272:        while (s < end) {
        !           273:                if (*s == '\\') {
        !           274:                        s++;
        !           275:                        if (s >= end) {
        !           276:                                *t++ = '\\';
        !           277:                                continue;
        !           278:                        }
        !           279:                        switch (*s) {
        !           280:                                case '"':
        !           281:                                        if (*s != quote_type) {
        !           282:                                                *t++ = '\\';
        !           283:                                                *t++ = *s;
        !           284:                                                break;
        !           285:                                        }
        !           286:                                case '\\':
        !           287:                                case '$':
        !           288:                                        *t++ = *s;
        !           289:                                        Z_STRLEN_P(lval)--;
        !           290:                                        break;
        !           291:                                default:
        !           292:                                        *t++ = '\\';
        !           293:                                        *t++ = *s;
        !           294:                                        break;
        !           295:                        }
        !           296:                } else {
        !           297:                        *t++ = *s;
        !           298:                }
        !           299:                if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
        !           300:                        SCNG(lineno)++;
        !           301:                }
        !           302:                s++;
        !           303:        }
        !           304:        *t = 0;
        !           305: }
        !           306: /* }}} */
        !           307: 
        !           308: int ini_lex(zval *ini_lval TSRMLS_DC)
        !           309: {
        !           310: restart:
        !           311:        SCNG(yy_text) = YYCURSOR;
        !           312: 
        !           313: /* yymore_restart: */
        !           314:        /* detect EOF */
        !           315:        if (YYCURSOR >= YYLIMIT) {
        !           316:                if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) {
        !           317:                        BEGIN(INITIAL);
        !           318:                        return END_OF_LINE;
        !           319:                }
        !           320:                return 0;
        !           321:        }
        !           322: 
        !           323:        /* Eat any UTF-8 BOM we find in the first 3 bytes */
        !           324:        if (YYCURSOR == SCNG(yy_start) && YYCURSOR + 3 < YYLIMIT) {
        !           325:                if (memcmp(YYCURSOR, "\xef\xbb\xbf", 3) == 0) {
        !           326:                        YYCURSOR += 3;
        !           327:                        goto restart;
        !           328:                }
        !           329:        }
        !           330: /*!re2c
        !           331: re2c:yyfill:check = 0;
        !           332: LNUM [0-9]+
        !           333: DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
        !           334: NUMBER [-]?{LNUM}|{DNUM}
        !           335: ANY_CHAR (.|[\n\t])
        !           336: NEWLINE        ("\r"|"\n"|"\r\n")
        !           337: TABS_AND_SPACES [ \t]
        !           338: WHITESPACE [ \t]+
        !           339: CONSTANT [a-zA-Z_][a-zA-Z0-9_]*
        !           340: LABEL [^=\n\r\t;|&$~(){}!"\[]+
        !           341: TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@{}]
        !           342: OPERATORS [&|~()!]
        !           343: DOLLAR_CURLY "${"
        !           344: 
        !           345: SECTION_RAW_CHARS [^\]\n\r]
        !           346: SINGLE_QUOTED_CHARS [^']
        !           347: RAW_VALUE_CHARS [^\n\r;\000]
        !           348: 
        !           349: LITERAL_DOLLAR ("$"([^{\000]|("\\"{ANY_CHAR})))
        !           350: VALUE_CHARS         ([^$= \t\n\r;&|~()!"'\000]|{LITERAL_DOLLAR})
        !           351: SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
        !           352: 
        !           353: <!*> := yyleng = YYCURSOR - SCNG(yy_text);
        !           354: 
        !           355: <INITIAL>"[" { /* Section start */
        !           356:        /* Enter section data lookup state */
        !           357:        if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
        !           358:                yy_push_state(ST_SECTION_RAW TSRMLS_CC);
        !           359:        } else {
        !           360:                yy_push_state(ST_SECTION_VALUE TSRMLS_CC);
        !           361:        }
        !           362:        return TC_SECTION;
        !           363: }
        !           364: 
        !           365: <ST_VALUE,ST_SECTION_VALUE,ST_OFFSET>"'"{SINGLE_QUOTED_CHARS}+"'" { /* Raw string */
        !           366:        /* Eat leading and trailing single quotes */
        !           367:        if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') {
        !           368:                SCNG(yy_text)++;
        !           369:                yyleng = yyleng - 2;
        !           370:        }
        !           371:        RETURN_TOKEN(TC_RAW, yytext, yyleng);
        !           372: }
        !           373: 
        !           374: <ST_SECTION_RAW,ST_SECTION_VALUE>"]"{TABS_AND_SPACES}*{NEWLINE}? { /* End of section */
        !           375:        BEGIN(INITIAL);
        !           376:        SCNG(lineno)++;
        !           377:        return ']';
        !           378: }
        !           379: 
        !           380: <INITIAL>{LABEL}"["{TABS_AND_SPACES}* { /* Start of option with offset */
        !           381:        /* Eat leading whitespace */
        !           382:        EAT_LEADING_WHITESPACE();
        !           383:        
        !           384:        /* Eat trailing whitespace and [ */
        !           385:        EAT_TRAILING_WHITESPACE_EX('[');
        !           386: 
        !           387:        /* Enter offset lookup state */
        !           388:        yy_push_state(ST_OFFSET TSRMLS_CC);
        !           389: 
        !           390:        RETURN_TOKEN(TC_OFFSET, yytext, yyleng);
        !           391: }
        !           392: 
        !           393: <ST_OFFSET>{TABS_AND_SPACES}*"]" { /* End of section or an option offset */
        !           394:        BEGIN(INITIAL);
        !           395:        return ']';
        !           396: }
        !           397: 
        !           398: <ST_DOUBLE_QUOTES,ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{DOLLAR_CURLY} { /* Variable start */
        !           399:        yy_push_state(ST_VARNAME TSRMLS_CC);
        !           400:        return TC_DOLLAR_CURLY;
        !           401: }
        !           402: 
        !           403: <ST_VARNAME>{LABEL} { /* Variable name */
        !           404:        /* Eat leading whitespace */
        !           405:        EAT_LEADING_WHITESPACE();
        !           406: 
        !           407:        /* Eat trailing whitespace */
        !           408:        EAT_TRAILING_WHITESPACE();
        !           409: 
        !           410:        RETURN_TOKEN(TC_VARNAME, yytext, yyleng);
        !           411: }
        !           412: 
        !           413: <ST_VARNAME>"}" { /* Variable end */
        !           414:        yy_pop_state(TSRMLS_C);
        !           415:        return '}';
        !           416: }
        !           417: 
        !           418: <INITIAL,ST_VALUE>("true"|"on"|"yes"){TABS_AND_SPACES}* { /* TRUE value (when used outside option value/offset this causes parse error!) */
        !           419:        RETURN_TOKEN(BOOL_TRUE, "1", 1);
        !           420: }
        !           421: 
        !           422: <INITIAL,ST_VALUE>("false"|"off"|"no"|"none"|"null"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
        !           423:        RETURN_TOKEN(BOOL_FALSE, "", 0);
        !           424: }
        !           425: 
        !           426: <INITIAL>{LABEL} { /* Get option name */
        !           427:        /* Eat leading whitespace */
        !           428:        EAT_LEADING_WHITESPACE();
        !           429: 
        !           430:        /* Eat trailing whitespace */
        !           431:        EAT_TRAILING_WHITESPACE();
        !           432: 
        !           433:        RETURN_TOKEN(TC_LABEL, yytext, yyleng);
        !           434: }
        !           435: 
        !           436: <INITIAL>{TABS_AND_SPACES}*[=]{TABS_AND_SPACES}* { /* Start option value */
        !           437:        if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
        !           438:                yy_push_state(ST_RAW TSRMLS_CC);
        !           439:        } else {
        !           440:                yy_push_state(ST_VALUE TSRMLS_CC);
        !           441:        }
        !           442:        return '=';
        !           443: }
        !           444: 
        !           445: <ST_RAW>{RAW_VALUE_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
        !           446:        /* Eat leading and trailing double quotes */
        !           447:        if (yytext[0] == '"' && yytext[yyleng - 1] == '"') {
        !           448:                SCNG(yy_text)++;
        !           449:                yyleng = yyleng - 2;
        !           450:        }
        !           451:        RETURN_TOKEN(TC_RAW, yytext, yyleng);
        !           452: }
        !           453: 
        !           454: <ST_SECTION_RAW>{SECTION_RAW_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
        !           455:        RETURN_TOKEN(TC_RAW, yytext, yyleng);
        !           456: }
        !           457: 
        !           458: <ST_VALUE,ST_RAW>{TABS_AND_SPACES}*{NEWLINE} { /* End of option value */
        !           459:        BEGIN(INITIAL);
        !           460:        SCNG(lineno)++;
        !           461:        return END_OF_LINE;
        !           462: }
        !           463: 
        !           464: <ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{CONSTANT} { /* Get constant option value */
        !           465:        RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
        !           466: }
        !           467: 
        !           468: <ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{NUMBER} { /* Get number option value as string */
        !           469:        RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
        !           470: }
        !           471: 
        !           472: <INITIAL>{TOKENS} { /* Disallow these chars outside option values */
        !           473:        return yytext[0];
        !           474: }
        !           475: 
        !           476: <ST_VALUE>{OPERATORS}{TABS_AND_SPACES}* { /* Boolean operators */
        !           477:        return yytext[0];
        !           478: }
        !           479: 
        !           480: <ST_VALUE>[=] { /* Make = used in option value to trigger error */
        !           481:        yyless(0);
        !           482:        BEGIN(INITIAL);
        !           483:        return END_OF_LINE;
        !           484: }
        !           485: 
        !           486: <ST_VALUE>{VALUE_CHARS}+ { /* Get everything else as option/offset value */
        !           487:        RETURN_TOKEN(TC_STRING, yytext, yyleng);
        !           488: }
        !           489: 
        !           490: <ST_SECTION_VALUE,ST_OFFSET>{SECTION_VALUE_CHARS}+ { /* Get rest as section/offset value */
        !           491:        RETURN_TOKEN(TC_STRING, yytext, yyleng);
        !           492: }
        !           493: 
        !           494: <ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{TABS_AND_SPACES}*["] { /* Double quoted '"' string start */
        !           495:        yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC);
        !           496:        return '"';
        !           497: }
        !           498: 
        !           499: <ST_DOUBLE_QUOTES>["]{TABS_AND_SPACES}* { /* Double quoted '"' string ends */
        !           500:        yy_pop_state(TSRMLS_C);
        !           501:        return '"';
        !           502: }
        !           503: 
        !           504: <ST_DOUBLE_QUOTES>[^] { /* Escape double quoted string contents */
        !           505:        if (YYCURSOR > YYLIMIT) {
        !           506:                return 0;
        !           507:        }
        !           508:        
        !           509:        while (YYCURSOR < YYLIMIT) {
        !           510:                switch (*YYCURSOR++) {
        !           511:                        case '"':
        !           512:                                if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') {
        !           513:                                        continue;
        !           514:                                }
        !           515:                                break;
        !           516:                        case '$':
        !           517:                                if (*YYCURSOR == '{') {
        !           518:                                        break;
        !           519:                                }
        !           520:                                continue;
        !           521:                        case '\\':
        !           522:                                if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') {
        !           523:                                        YYCURSOR++;
        !           524:                                }
        !           525:                                /* fall through */
        !           526:                        default:
        !           527:                                continue;
        !           528:                }
        !           529:                
        !           530:                YYCURSOR--;
        !           531:                break;
        !           532:        }
        !           533: 
        !           534:        yyleng = YYCURSOR - SCNG(yy_text);
        !           535:        
        !           536:        zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC);
        !           537:        return TC_QUOTED_STRING;
        !           538: }
        !           539: 
        !           540: <ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{WHITESPACE} {
        !           541:        RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng);
        !           542: }
        !           543: 
        !           544: <INITIAL,ST_RAW>{TABS_AND_SPACES}+ {
        !           545:        /* eat whitespace */
        !           546:        goto restart;
        !           547: }
        !           548: 
        !           549: <INITIAL>{TABS_AND_SPACES}*{NEWLINE} {
        !           550:        SCNG(lineno)++;
        !           551:        return END_OF_LINE;
        !           552: }
        !           553: 
        !           554: <INITIAL,ST_VALUE,ST_RAW>{TABS_AND_SPACES}*[;][^\r\n]*{NEWLINE} { /* Comment */
        !           555:        BEGIN(INITIAL);
        !           556:        SCNG(lineno)++;
        !           557:        return END_OF_LINE;
        !           558: }
        !           559: 
        !           560: <INITIAL>{TABS_AND_SPACES}*[#][^\r\n]*{NEWLINE} { /* #Comment */
        !           561:        zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno));
        !           562:        BEGIN(INITIAL);
        !           563:        SCNG(lineno)++;
        !           564:        return END_OF_LINE;
        !           565: }
        !           566: 
        !           567: <ST_VALUE,ST_RAW>[^] { /* End of option value (if EOF is reached before EOL */
        !           568:        BEGIN(INITIAL);
        !           569:        return END_OF_LINE;
        !           570: }
        !           571: 
        !           572: <*>[^] {
        !           573:        return 0;
        !           574: }
        !           575: 
        !           576: */
        !           577: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>