Annotation of embedaddon/php/Zend/zend_ini_scanner.l, revision 1.1.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>