2000-10-29 22:56:16 +08:00
/*
+----------------------------------------------------------------------+
| Zend Engine |
+----------------------------------------------------------------------+
2013-01-01 16:37:09 +08:00
| Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) |
2000-10-29 22:56:16 +08:00
+----------------------------------------------------------------------+
2001-12-11 23:16:21 +08:00
| This source file is subject to version 2.00 of the Zend license, |
2000-10-29 22:56:16 +08:00
| that is bundled with this package in the file LICENSE, and is |
2003-06-11 04:04:29 +08:00
| available through the world-wide-web at the following url: |
2001-12-11 23:16:21 +08:00
| http://www.zend.com/license/2_00.txt. |
2000-10-29 22:56:16 +08:00
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
2007-09-28 10:05:10 +08:00
| Authors: Zeev Suraski <zeev@zend.com> |
| Jani Taskinen <jani@php.net> |
2008-03-17 05:06:55 +08:00
| Marcus Boerger <helly@php.net> |
| Nuno Lopes <nlopess@php.net> |
| Scott MacVicar <scottmac@php.net> |
2000-10-29 22:56:16 +08:00
+----------------------------------------------------------------------+
*/
2003-02-01 09:49:15 +08:00
/* $Id$ */
2008-04-04 23:01:23 +08:00
#include <errno.h>
#include "zend.h"
#include "zend_globals.h"
#include <zend_ini_parser.h>
#include "zend_ini_scanner.h"
2007-09-28 10:05:10 +08:00
2008-03-17 05:06:55 +08:00
#if 0
# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c)
#else
# define YYDEBUG(s, c)
#endif
#include "zend_ini_scanner_defs.h"
#define YYCTYPE unsigned char
2008-08-18 05:00:22 +08:00
/* allow the scanner to read one null byte after the end of the string (from ZEND_MMAP_AHEAD)
* so that if will be able to terminate to match the current token (e.g. non-enclosed string) */
#define YYFILL(n) { if (YYCURSOR > YYLIMIT) return 0; }
2008-03-17 05:06:55 +08:00
#define YYCURSOR SCNG(yy_cursor)
#define YYLIMIT SCNG(yy_limit)
#define YYMARKER SCNG(yy_marker)
#define YYGETCONDITION() SCNG(yy_state)
#define YYSETCONDITION(s) SCNG(yy_state) = s
#define STATE(name) yyc##name
/* emulate flex constructs */
#define BEGIN(state) YYSETCONDITION(STATE(state))
#define YYSTATE YYGETCONDITION()
#define yytext ((char*)SCNG(yy_text))
#define yyleng SCNG(yy_leng)
2009-08-07 22:21:38 +08:00
#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \
yyleng = (unsigned int)x; } while(0)
2008-03-17 05:06:55 +08:00
/* #define yymore() goto yymore_restart */
2007-09-28 10:05:10 +08:00
2008-04-04 23:01:23 +08:00
/* perform sanity check. If this message is triggered you should
increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */
/*!max:re2c */
2008-08-18 05:00:22 +08:00
#if ZEND_MMAP_AHEAD < (YYMAXFILL + 1)
# error ZEND_MMAP_AHEAD should be greater than YYMAXFILL
2008-04-04 23:01:23 +08:00
#endif
2007-09-28 10:05:10 +08:00
/* How it works (for the core ini directives):
* ===========================================
*
* 1. Scanner scans file for tokens and passes them to parser.
* 2. Parser parses the tokens and passes the name/value pairs to the callback
* function which stores them in the configuration hash table.
* 3. Later REGISTER_INI_ENTRIES() is called which triggers the actual
* registering of ini entries and uses zend_get_configuration_directive()
* to fetch the previously stored name/value pair from configuration hash table
* and registers the static ini entries which match the name to the value
* into EG(ini_directives) hash table.
* 4. PATH section entries are used per-request from down to top, each overriding
* previous if one exists. zend_alter_ini_entry() is called for each entry.
* Settings in PATH section are ZEND_INI_SYSTEM accessible and thus mimics the
* php_admin_* directives used within Apache httpd.conf when PHP is compiled as
* module for Apache.
* 5. User defined ini files (like .htaccess for apache) are parsed for each request and
* stored in separate hash defined by SAPI.
*/
2008-03-17 05:06:55 +08:00
2007-09-28 10:05:10 +08:00
/* TODO: (ordered by importance :-)
* ===============================================================================
*
* - Separate constant lookup totally from plain strings (using CONSTANT pattern)
* - Add #if .. #else .. #endif and ==, !=, <, > , <=, >= operators
* - Add #include "some.ini"
* - Allow variables to refer to options also when using parse_ini_file()
*
*/
2001-08-06 21:48:51 +08:00
/* Globals Macros */
#define SCNG INI_SCNG
#ifdef ZTS
ZEND_API ts_rsrc_id ini_scanner_globals_id;
#else
2008-03-17 05:06:55 +08:00
ZEND_API zend_ini_scanner_globals ini_scanner_globals;
2001-08-06 21:48:51 +08:00
#endif
2000-12-27 06:15:13 +08:00
2009-12-01 06:38:32 +08:00
/* Eat leading whitespace */
#define EAT_LEADING_WHITESPACE() \
while (yytext[0]) { \
if (yytext[0] == ' ' || yytext[0] == '\t') { \
SCNG(yy_text)++; \
yyleng--; \
} else { \
break; \
} \
}
2007-09-28 10:05:10 +08:00
/* Eat trailing whitespace + extra char */
#define EAT_TRAILING_WHITESPACE_EX(ch) \
while (yyleng > 0 && ( \
(ch != 'X' && yytext[yyleng - 1] == ch) || \
yytext[yyleng - 1] == '\n' || \
yytext[yyleng - 1] == '\r' || \
yytext[yyleng - 1] == '\t' || \
yytext[yyleng - 1] == ' ') \
) { \
yyleng--; \
}
/* Eat trailing whitespace */
#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X')
#define zend_ini_copy_value(retval, str, len) { \
Z_STRVAL_P(retval) = zend_strndup(str, len); \
Z_STRLEN_P(retval) = len; \
Z_TYPE_P(retval) = IS_STRING; \
}
#define RETURN_TOKEN(type, str, len) { \
zend_ini_copy_value(ini_lval, str, len); \
return type; \
}
2000-12-27 06:15:13 +08:00
2008-03-17 05:06:55 +08:00
static void _yy_push_state(int new_state TSRMLS_DC)
{
zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
YYSETCONDITION(new_state);
}
#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
static void yy_pop_state(TSRMLS_D)
{
int *stack_state;
zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
YYSETCONDITION(*stack_state);
zend_stack_del_top(&SCNG(state_stack));
}
static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
{
YYCURSOR = (YYCTYPE*)str;
SCNG(yy_start) = YYCURSOR;
YYLIMIT = YYCURSOR + len;
}
#define ini_filename SCNG(filename)
2000-10-31 07:19:48 +08:00
2007-09-28 10:05:10 +08:00
/* {{{ init_ini_scanner()
*/
2009-08-07 23:44:37 +08:00
static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
2007-09-28 10:05:10 +08:00
{
2009-08-07 23:44:37 +08:00
/* Sanity check */
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) {
zend_error(E_WARNING, "Invalid scanner mode");
return FAILURE;
}
2007-09-28 10:05:10 +08:00
SCNG(lineno) = 1;
2009-08-07 23:44:37 +08:00
SCNG(scanner_mode) = scanner_mode;
SCNG(yy_in) = fh;
if (fh != NULL) {
ini_filename = zend_strndup(fh->filename, strlen(fh->filename));
} else {
ini_filename = NULL;
}
2008-03-17 05:06:55 +08:00
zend_stack_init(&SCNG(state_stack));
BEGIN(INITIAL);
2009-08-07 23:44:37 +08:00
return SUCCESS;
2007-09-28 10:05:10 +08:00
}
/* }}} */
/* {{{ shutdown_ini_scanner()
*/
void shutdown_ini_scanner(TSRMLS_D)
2000-10-29 22:56:16 +08:00
{
2008-03-17 05:06:55 +08:00
zend_stack_destroy(&SCNG(state_stack));
2007-09-28 10:05:10 +08:00
if (ini_filename) {
free(ini_filename);
}
2000-10-29 22:56:16 +08:00
}
2007-09-28 10:05:10 +08:00
/* }}} */
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
/* {{{ zend_ini_scanner_get_lineno()
*/
2001-08-06 21:48:51 +08:00
int zend_ini_scanner_get_lineno(TSRMLS_D)
2000-10-30 02:23:51 +08:00
{
2005-02-03 10:58:21 +08:00
return SCNG(lineno);
2000-10-30 02:23:51 +08:00
}
2007-09-28 10:05:10 +08:00
/* }}} */
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
/* {{{ zend_ini_scanner_get_filename()
*/
2001-07-31 14:07:25 +08:00
char *zend_ini_scanner_get_filename(TSRMLS_D)
2000-10-31 07:19:48 +08:00
{
2008-11-06 05:35:02 +08:00
return ini_filename ? ini_filename : "Unknown";
2000-10-31 07:19:48 +08:00
}
2007-09-28 10:05:10 +08:00
/* }}} */
2000-10-31 07:19:48 +08:00
2007-09-28 10:05:10 +08:00
/* {{{ zend_ini_open_file_for_scanning()
*/
int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC)
2000-10-30 06:40:01 +08:00
{
2008-03-17 05:06:55 +08:00
char *buf;
size_t size;
2012-02-25 22:15:11 +08:00
if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) {
return FAILURE;
}
if (init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE) {
zend_file_handle_dtor(fh TSRMLS_CC);
2003-02-18 17:37:54 +08:00
return FAILURE;
2000-10-30 06:40:01 +08:00
}
2008-03-17 05:06:55 +08:00
yy_scan_buffer(buf, size TSRMLS_CC);
2009-08-07 23:44:37 +08:00
2000-10-30 06:40:01 +08:00
return SUCCESS;
}
2007-09-28 10:05:10 +08:00
/* }}} */
2000-10-30 06:40:01 +08:00
2007-09-28 10:05:10 +08:00
/* {{{ zend_ini_prepare_string_for_scanning()
*/
int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC)
2006-09-20 04:33:12 +08:00
{
int len = strlen(str);
2009-08-07 23:44:37 +08:00
if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) {
return FAILURE;
}
2008-03-17 05:06:55 +08:00
yy_scan_buffer(str, len TSRMLS_CC);
2009-08-07 23:44:37 +08:00
2006-09-20 04:33:12 +08:00
return SUCCESS;
}
2007-09-28 10:05:10 +08:00
/* }}} */
2006-09-20 04:33:12 +08:00
2007-09-28 10:05:10 +08:00
/* {{{ zend_ini_escape_string()
*/
static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC)
{
register char *s, *t;
char *end;
zend_ini_copy_value(lval, str, len);
/* convert escape sequences */
s = t = Z_STRVAL_P(lval);
end = s + Z_STRLEN_P(lval);
while (s < end) {
if (*s == '\\') {
s++;
if (s >= end) {
2008-09-11 08:33:38 +08:00
*t++ = '\\';
2007-09-28 10:05:10 +08:00
continue;
}
switch (*s) {
case '"':
if (*s != quote_type) {
*t++ = '\\';
*t++ = *s;
break;
}
case '\\':
case '$':
*t++ = *s;
Z_STRLEN_P(lval)--;
break;
default:
*t++ = '\\';
*t++ = *s;
break;
}
} else {
*t++ = *s;
}
if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
SCNG(lineno)++;
}
s++;
}
*t = 0;
}
/* }}} */
2000-10-30 07:10:04 +08:00
2008-03-17 05:06:55 +08:00
int ini_lex(zval *ini_lval TSRMLS_DC)
{
restart:
SCNG(yy_text) = YYCURSOR;
/* yymore_restart: */
/* detect EOF */
if (YYCURSOR >= YYLIMIT) {
if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) {
BEGIN(INITIAL);
2010-05-26 10:18:17 +08:00
return END_OF_LINE;
2008-03-17 05:06:55 +08:00
}
return 0;
}
2008-12-24 21:49:31 +08:00
/* Eat any UTF-8 BOM we find in the first 3 bytes */
if (YYCURSOR == SCNG(yy_start) && YYCURSOR + 3 < YYLIMIT) {
if (memcmp(YYCURSOR, "\xef\xbb\xbf", 3) == 0) {
YYCURSOR += 3;
goto restart;
}
}
2008-03-17 05:06:55 +08:00
/*!re2c
2008-03-23 01:59:52 +08:00
re2c:yyfill:check = 0;
2007-09-28 10:05:10 +08:00
LNUM [0-9]+
DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
2008-02-05 04:45:20 +08:00
NUMBER [-]?{LNUM}|{DNUM}
ANY_CHAR (.|[\n\t])
2007-09-28 10:05:10 +08:00
NEWLINE ("\r"|"\n"|"\r\n")
TABS_AND_SPACES [ \t]
2008-02-05 04:45:20 +08:00
WHITESPACE [ \t]+
2010-02-07 19:40:29 +08:00
CONSTANT [a-zA-Z_][a-zA-Z0-9_]*
2009-12-01 06:38:32 +08:00
LABEL [^=\n\r\t;|&$~(){}!"\[]+
2008-02-05 04:45:20 +08:00
TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@{}]
2007-09-28 10:05:10 +08:00
OPERATORS [&|~()!]
2008-02-05 04:45:20 +08:00
DOLLAR_CURLY "${"
2007-09-28 10:05:10 +08:00
SECTION_RAW_CHARS [^\]\n\r]
2008-02-05 04:45:20 +08:00
SINGLE_QUOTED_CHARS [^']
2012-11-17 07:04:14 +08:00
RAW_VALUE_CHARS [^\n\r;\000]
2001-05-03 05:52:30 +08:00
2008-04-07 19:39:14 +08:00
LITERAL_DOLLAR ("$"([^{\000]|("\\"{ANY_CHAR})))
2008-03-17 05:06:55 +08:00
VALUE_CHARS ([^$= \t\n\r;&|~()!"'\000]|{LITERAL_DOLLAR})
2008-02-05 04:45:20 +08:00
SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
2007-09-28 10:05:10 +08:00
2008-03-17 05:06:55 +08:00
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
<INITIAL>"[" { /* Section start */
/* Enter section data lookup state */
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
yy_push_state(ST_SECTION_RAW TSRMLS_CC);
} else {
yy_push_state(ST_SECTION_VALUE TSRMLS_CC);
}
return TC_SECTION;
}
<ST_VALUE,ST_SECTION_VALUE,ST_OFFSET>"'"{SINGLE_QUOTED_CHARS}+"'" { /* Raw string */
/* Eat leading and trailing single quotes */
if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') {
2008-03-17 05:06:55 +08:00
SCNG(yy_text)++;
2007-09-28 10:05:10 +08:00
yyleng = yyleng - 2;
}
RETURN_TOKEN(TC_RAW, yytext, yyleng);
2003-01-19 20:01:38 +08:00
}
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
<ST_SECTION_RAW,ST_SECTION_VALUE>"]"{TABS_AND_SPACES}*{NEWLINE}? { /* End of section */
BEGIN(INITIAL);
SCNG(lineno)++;
return ']';
2000-10-29 22:56:16 +08:00
}
2007-09-28 10:05:10 +08:00
<INITIAL>{LABEL}"["{TABS_AND_SPACES}* { /* Start of option with offset */
2009-12-01 06:38:32 +08:00
/* Eat leading whitespace */
EAT_LEADING_WHITESPACE();
2007-09-28 10:05:10 +08:00
/* Eat trailing whitespace and [ */
EAT_TRAILING_WHITESPACE_EX('[');
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
/* Enter offset lookup state */
yy_push_state(ST_OFFSET TSRMLS_CC);
2008-03-17 05:06:55 +08:00
2007-09-28 10:05:10 +08:00
RETURN_TOKEN(TC_OFFSET, yytext, yyleng);
2000-10-29 22:56:16 +08:00
}
2007-09-28 10:05:10 +08:00
<ST_OFFSET>{TABS_AND_SPACES}*"]" { /* End of section or an option offset */
BEGIN(INITIAL);
return ']';
}
2000-10-29 22:56:16 +08:00
2008-02-05 04:45:20 +08:00
<ST_DOUBLE_QUOTES,ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{DOLLAR_CURLY} { /* Variable start */
2007-09-28 10:05:10 +08:00
yy_push_state(ST_VARNAME TSRMLS_CC);
return TC_DOLLAR_CURLY;
}
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
<ST_VARNAME>{LABEL} { /* Variable name */
2009-12-01 06:38:32 +08:00
/* Eat leading whitespace */
EAT_LEADING_WHITESPACE();
/* Eat trailing whitespace */
EAT_TRAILING_WHITESPACE();
2007-09-28 10:05:10 +08:00
RETURN_TOKEN(TC_VARNAME, yytext, yyleng);
}
2002-10-15 07:41:32 +08:00
2007-09-28 10:05:10 +08:00
<ST_VARNAME>"}" { /* Variable end */
yy_pop_state(TSRMLS_C);
return '}';
}
<INITIAL,ST_VALUE>("true"|"on"|"yes"){TABS_AND_SPACES}* { /* TRUE value (when used outside option value/offset this causes parse error!) */
RETURN_TOKEN(BOOL_TRUE, "1", 1);
}
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"|"null"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
RETURN_TOKEN(BOOL_FALSE, "", 0);
2000-10-29 22:56:16 +08:00
}
2008-02-05 04:45:20 +08:00
<INITIAL>{LABEL} { /* Get option name */
2009-12-01 06:38:32 +08:00
/* Eat leading whitespace */
EAT_LEADING_WHITESPACE();
/* Eat trailing whitespace */
EAT_TRAILING_WHITESPACE();
2008-02-05 04:45:20 +08:00
RETURN_TOKEN(TC_LABEL, yytext, yyleng);
2007-09-28 10:05:10 +08:00
}
2006-01-18 03:56:25 +08:00
2008-03-17 05:06:55 +08:00
<INITIAL>{TABS_AND_SPACES}*[=]{TABS_AND_SPACES}* { /* Start option value */
2007-09-28 10:05:10 +08:00
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
yy_push_state(ST_RAW TSRMLS_CC);
} else {
yy_push_state(ST_VALUE TSRMLS_CC);
}
return '=';
}
2000-10-29 22:56:16 +08:00
2012-11-17 07:04:14 +08:00
<ST_RAW>{RAW_VALUE_CHARS} { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
char *sc = NULL;
2012-06-07 23:44:20 +08:00
while (YYCURSOR < YYLIMIT) {
2012-11-17 07:04:14 +08:00
switch (*YYCURSOR) {
2012-06-07 23:44:20 +08:00
case '\n':
case '\r':
2012-11-17 07:04:14 +08:00
goto end_raw_value_chars;
2012-06-07 23:44:20 +08:00
break;
2012-11-17 07:04:14 +08:00
case ';':
if (sc == NULL) {
sc = YYCURSOR;
2012-06-07 23:44:20 +08:00
}
2012-11-17 07:04:14 +08:00
/* no break */
default:
YYCURSOR++;
2012-06-07 23:44:20 +08:00
break;
}
2006-01-18 03:56:25 +08:00
}
2012-11-17 07:04:14 +08:00
end_raw_value_chars:
2012-06-07 23:44:20 +08:00
yyleng = YYCURSOR - SCNG(yy_text);
2012-11-17 07:04:14 +08:00
/* Eat trailing semicolons */
while (yytext[yyleng - 1] == ';') {
yyleng--;
}
/* Eat leading and trailing double quotes */
if (yytext[0] == '"' && yytext[yyleng - 1] == '"') {
SCNG(yy_text)++;
yyleng = yyleng - 2;
} else if (sc) {
YYCURSOR = sc;
yyleng = YYCURSOR - SCNG(yy_text);
}
2007-09-28 10:05:10 +08:00
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
2006-01-18 03:56:25 +08:00
2007-09-28 10:05:10 +08:00
<ST_SECTION_RAW>{SECTION_RAW_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
2003-02-01 15:32:09 +08:00
2008-02-05 04:45:20 +08:00
<ST_VALUE,ST_RAW>{TABS_AND_SPACES}*{NEWLINE} { /* End of option value */
2007-09-28 10:05:10 +08:00
BEGIN(INITIAL);
SCNG(lineno)++;
return END_OF_LINE;
}
2000-10-29 22:56:16 +08:00
2008-02-05 04:45:20 +08:00
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{CONSTANT} { /* Get constant option value */
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
2000-10-29 22:56:16 +08:00
}
2008-02-05 04:45:20 +08:00
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{NUMBER} { /* Get number option value as string */
2007-09-28 10:05:10 +08:00
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
2004-08-19 00:58:20 +08:00
}
2007-09-28 10:05:10 +08:00
<INITIAL>{TOKENS} { /* Disallow these chars outside option values */
2007-07-24 00:17:10 +08:00
return yytext[0];
}
2007-09-28 10:05:10 +08:00
<ST_VALUE>{OPERATORS}{TABS_AND_SPACES}* { /* Boolean operators */
2004-08-19 00:58:20 +08:00
return yytext[0];
}
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
<ST_VALUE>[=] { /* Make = used in option value to trigger error */
2008-03-17 05:06:55 +08:00
yyless(0);
2007-09-28 10:05:10 +08:00
BEGIN(INITIAL);
return END_OF_LINE;
}
2000-10-29 22:56:16 +08:00
2007-09-28 10:05:10 +08:00
<ST_VALUE>{VALUE_CHARS}+ { /* Get everything else as option/offset value */
RETURN_TOKEN(TC_STRING, yytext, yyleng);
2000-10-29 22:56:16 +08:00
}
2007-09-28 10:05:10 +08:00
<ST_SECTION_VALUE,ST_OFFSET>{SECTION_VALUE_CHARS}+ { /* Get rest as section/offset value */
RETURN_TOKEN(TC_STRING, yytext, yyleng);
2000-10-29 22:56:16 +08:00
}
2008-02-05 04:45:20 +08:00
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{TABS_AND_SPACES}*["] { /* Double quoted '"' string start */
2007-09-28 10:05:10 +08:00
yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC);
return '"';
2000-10-29 22:56:16 +08:00
}
2008-02-05 04:45:20 +08:00
<ST_DOUBLE_QUOTES>["]{TABS_AND_SPACES}* { /* Double quoted '"' string ends */
2007-09-28 10:05:10 +08:00
yy_pop_state(TSRMLS_C);
return '"';
2000-10-29 22:56:16 +08:00
}
2009-08-07 22:21:38 +08:00
<ST_DOUBLE_QUOTES>[^] { /* Escape double quoted string contents */
if (YYCURSOR > YYLIMIT) {
return 0;
}
while (YYCURSOR < YYLIMIT) {
switch (*YYCURSOR++) {
case '"':
if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') {
continue;
}
break;
case '$':
if (*YYCURSOR == '{') {
break;
}
continue;
case '\\':
if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') {
YYCURSOR++;
}
/* fall through */
default:
continue;
}
YYCURSOR--;
break;
}
yyleng = YYCURSOR - SCNG(yy_text);
zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC);
return TC_QUOTED_STRING;
}
2008-02-05 04:45:20 +08:00
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{WHITESPACE} {
RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng);
}
<INITIAL,ST_RAW>{TABS_AND_SPACES}+ {
2000-10-29 22:56:16 +08:00
/* eat whitespace */
2008-03-17 05:06:55 +08:00
goto restart;
2000-10-29 22:56:16 +08:00
}
2008-02-05 04:45:20 +08:00
<INITIAL>{TABS_AND_SPACES}*{NEWLINE} {
2007-09-28 10:05:10 +08:00
SCNG(lineno)++;
return END_OF_LINE;
}
2008-02-05 04:45:20 +08:00
<INITIAL,ST_VALUE,ST_RAW>{TABS_AND_SPACES}*[;][^\r\n]*{NEWLINE} { /* Comment */
2007-09-28 10:05:10 +08:00
BEGIN(INITIAL);
SCNG(lineno)++;
return END_OF_LINE;
}
2008-11-03 07:36:10 +08:00
<INITIAL>{TABS_AND_SPACES}*[#][^\r\n]*{NEWLINE} { /* #Comment */
2008-11-06 05:35:02 +08:00
zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno));
2008-11-03 07:36:10 +08:00
BEGIN(INITIAL);
SCNG(lineno)++;
return END_OF_LINE;
}
2008-03-17 05:06:55 +08:00
<ST_VALUE,ST_RAW>[^] { /* End of option value (if EOF is reached before EOL */
2007-09-28 10:05:10 +08:00
BEGIN(INITIAL);
2008-04-07 19:39:14 +08:00
return END_OF_LINE;
2000-10-29 22:56:16 +08:00
}
2000-11-03 10:45:55 +08:00
2008-03-17 05:06:55 +08:00
<*>[^] {
return 0;
}
2007-09-28 10:05:10 +08:00
2008-03-17 05:06:55 +08:00
*/
2000-11-03 10:45:55 +08:00
}