File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / Zend / zend_ini_scanner.l
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:47:52 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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,v 1.1 2012/02/21 23:47:52 misho Exp $ */
   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>