mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Merge pull request #2390 from larsbrinkhoff/lex-yacc
Add Lex and Yacc languages
This commit is contained in:
		@@ -289,5 +289,15 @@ module Linguist
 | 
			
		||||
        Language["RenderScript"]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    disambiguate "Common Lisp", "Lex", "Groff" do |data|
 | 
			
		||||
      if data.include?("(def(un|macro)\s")
 | 
			
		||||
        Language["Common Lisp"]
 | 
			
		||||
      elsif /^(%[%{}]xs|<.*>)/.match(data)
 | 
			
		||||
        Language["Lex"]
 | 
			
		||||
      elsif /^\.[a-z][a-z](\s|$)/.match(data)
 | 
			
		||||
        Language["Groff"]
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -296,9 +296,10 @@ Befunge:
 | 
			
		||||
 | 
			
		||||
Bison:
 | 
			
		||||
  type: programming
 | 
			
		||||
  group: Yacc
 | 
			
		||||
  tm_scope: source.bison
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .y
 | 
			
		||||
  - .bison
 | 
			
		||||
  ace_mode: text
 | 
			
		||||
 | 
			
		||||
BitBake:
 | 
			
		||||
@@ -601,6 +602,7 @@ Common Lisp:
 | 
			
		||||
  - .lisp
 | 
			
		||||
  - .asd
 | 
			
		||||
  - .cl
 | 
			
		||||
  - .l
 | 
			
		||||
  - .lsp
 | 
			
		||||
  - .ny
 | 
			
		||||
  - .podsl
 | 
			
		||||
@@ -1213,6 +1215,7 @@ Groff:
 | 
			
		||||
  - '.5'
 | 
			
		||||
  - '.6'
 | 
			
		||||
  - '.7'
 | 
			
		||||
  - .l
 | 
			
		||||
  tm_scope: text.groff
 | 
			
		||||
  aliases:
 | 
			
		||||
  - nroff
 | 
			
		||||
@@ -1469,6 +1472,7 @@ J:
 | 
			
		||||
JFlex:
 | 
			
		||||
  type: programming
 | 
			
		||||
  color: "#DBCA00"
 | 
			
		||||
  group: Lex
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .flex
 | 
			
		||||
  - .jflex
 | 
			
		||||
@@ -1704,6 +1708,17 @@ Less:
 | 
			
		||||
  tm_scope: source.css.less
 | 
			
		||||
  ace_mode: less
 | 
			
		||||
 | 
			
		||||
Lex:
 | 
			
		||||
  type: programming
 | 
			
		||||
  color: "#DBCA00"
 | 
			
		||||
  aliases:
 | 
			
		||||
  - flex
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .l
 | 
			
		||||
  - .lex
 | 
			
		||||
  tm_scope: none
 | 
			
		||||
  ace_mode: text
 | 
			
		||||
 | 
			
		||||
LilyPond:
 | 
			
		||||
  type: programming
 | 
			
		||||
  extensions:
 | 
			
		||||
@@ -3574,6 +3589,15 @@ YAML:
 | 
			
		||||
  - .yaml
 | 
			
		||||
  ace_mode: yaml
 | 
			
		||||
 | 
			
		||||
Yacc:
 | 
			
		||||
  type: programming
 | 
			
		||||
  extensions:
 | 
			
		||||
  - .y
 | 
			
		||||
  - .yacc
 | 
			
		||||
  - .yy
 | 
			
		||||
  tm_scope: source.bison
 | 
			
		||||
  ace_mode: text
 | 
			
		||||
 | 
			
		||||
Zephir:
 | 
			
		||||
  type: programming
 | 
			
		||||
  color: "#118f9e"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1201
									
								
								samples/Common Lisp/common.l
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1201
									
								
								samples/Common Lisp/common.l
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										135
									
								
								samples/Groff/create_view.l
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								samples/Groff/create_view.l
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
.\\" auto-generated by docbook2man-spec $Revision: 1.1.1.1 $
 | 
			
		||||
.TH "CREATE VIEW" "" "2005-11-05" "SQL - Language Statements" "SQL Commands"
 | 
			
		||||
.SH NAME
 | 
			
		||||
CREATE VIEW \- define a new view
 | 
			
		||||
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.sp
 | 
			
		||||
.nf
 | 
			
		||||
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW \fIname\fR [ ( \fIcolumn_name\fR [, ...] ) ]
 | 
			
		||||
    AS \fIquery\fR
 | 
			
		||||
.sp
 | 
			
		||||
.fi
 | 
			
		||||
.SH "DESCRIPTION"
 | 
			
		||||
.PP
 | 
			
		||||
\fBCREATE VIEW\fR defines a view of a query. The view
 | 
			
		||||
is not physically materialized. Instead, the query is run every time
 | 
			
		||||
the view is referenced in a query.
 | 
			
		||||
.PP
 | 
			
		||||
\fBCREATE OR REPLACE VIEW\fR is similar, but if a view
 | 
			
		||||
of the same name already exists, it is replaced. You can only replace
 | 
			
		||||
a view with a new query that generates the identical set of columns
 | 
			
		||||
(i.e., same column names and data types).
 | 
			
		||||
.PP
 | 
			
		||||
If a schema name is given (for example, CREATE VIEW
 | 
			
		||||
myschema.myview ...) then the view is created in the specified
 | 
			
		||||
schema. Otherwise it is created in the current schema. Temporary
 | 
			
		||||
views exist in a special schema, so a schema name may not be given
 | 
			
		||||
when creating a temporary view. The name of the view must be
 | 
			
		||||
distinct from the name of any other view, table, sequence, or index
 | 
			
		||||
in the same schema.
 | 
			
		||||
.SH "PARAMETERS"
 | 
			
		||||
.TP
 | 
			
		||||
\fBTEMPORARY or TEMP\fR
 | 
			
		||||
If specified, the view is created as a temporary view.
 | 
			
		||||
Temporary views are automatically dropped at the end of the
 | 
			
		||||
current session. Existing
 | 
			
		||||
permanent relations with the same name are not visible to the
 | 
			
		||||
current session while the temporary view exists, unless they are
 | 
			
		||||
referenced with schema-qualified names.
 | 
			
		||||
 | 
			
		||||
If any of the tables referenced by the view are temporary,
 | 
			
		||||
the view is created as a temporary view (whether
 | 
			
		||||
TEMPORARY is specified or not).
 | 
			
		||||
.TP
 | 
			
		||||
\fB\fIname\fB\fR
 | 
			
		||||
The name (optionally schema-qualified) of a view to be created.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\fIcolumn_name\fB\fR
 | 
			
		||||
An optional list of names to be used for columns of the view.
 | 
			
		||||
If not given, the column names are deduced from the query.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\fIquery\fB\fR
 | 
			
		||||
A query (that is, a \fBSELECT\fR statement) which will
 | 
			
		||||
provide the columns and rows of the view.
 | 
			
		||||
 | 
			
		||||
Refer to SELECT [\fBselect\fR(l)]
 | 
			
		||||
for more information about valid queries.
 | 
			
		||||
.SH "NOTES"
 | 
			
		||||
.PP
 | 
			
		||||
Currently, views are read only: the system will not allow an insert,
 | 
			
		||||
update, or delete on a view. You can get the effect of an updatable
 | 
			
		||||
view by creating rules that rewrite inserts, etc. on the view into
 | 
			
		||||
appropriate actions on other tables. For more information see
 | 
			
		||||
CREATE RULE [\fBcreate_rule\fR(l)].
 | 
			
		||||
.PP
 | 
			
		||||
Use the DROP VIEW [\fBdrop_view\fR(l)]
 | 
			
		||||
statement to drop views.
 | 
			
		||||
.PP
 | 
			
		||||
Be careful that the names and types of the view's columns will be
 | 
			
		||||
assigned the way you want. For example,
 | 
			
		||||
.sp
 | 
			
		||||
.nf
 | 
			
		||||
CREATE VIEW vista AS SELECT 'Hello World';
 | 
			
		||||
.sp
 | 
			
		||||
.fi
 | 
			
		||||
is bad form in two ways: the column name defaults to ?column?,
 | 
			
		||||
and the column data type defaults to \fBunknown\fR. If you want a
 | 
			
		||||
string literal in a view's result, use something like
 | 
			
		||||
.sp
 | 
			
		||||
.nf
 | 
			
		||||
CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
 | 
			
		||||
.sp
 | 
			
		||||
.fi
 | 
			
		||||
.PP
 | 
			
		||||
Access to tables referenced in the view is determined by permissions of
 | 
			
		||||
the view owner. However, functions called in the view are treated the
 | 
			
		||||
same as if they had been called directly from the query using the view.
 | 
			
		||||
Therefore the user of a view must have permissions to call all functions
 | 
			
		||||
used by the view.
 | 
			
		||||
.SH "EXAMPLES"
 | 
			
		||||
.PP
 | 
			
		||||
Create a view consisting of all comedy films:
 | 
			
		||||
.sp
 | 
			
		||||
.nf
 | 
			
		||||
CREATE VIEW comedies AS
 | 
			
		||||
    SELECT *
 | 
			
		||||
    FROM films
 | 
			
		||||
    WHERE kind = 'Comedy';
 | 
			
		||||
.sp
 | 
			
		||||
.fi
 | 
			
		||||
.SH "COMPATIBILITY"
 | 
			
		||||
.PP
 | 
			
		||||
The SQL standard specifies some additional capabilities for the
 | 
			
		||||
\fBCREATE VIEW\fR statement:
 | 
			
		||||
.sp
 | 
			
		||||
.nf
 | 
			
		||||
CREATE VIEW \fIname\fR [ ( \fIcolumn_name\fR [, ...] ) ]
 | 
			
		||||
    AS \fIquery\fR
 | 
			
		||||
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
 | 
			
		||||
.sp
 | 
			
		||||
.fi
 | 
			
		||||
.PP
 | 
			
		||||
The optional clauses for the full SQL command are:
 | 
			
		||||
.TP
 | 
			
		||||
\fBCHECK OPTION\fR
 | 
			
		||||
This option has to do with updatable views. All
 | 
			
		||||
\fBINSERT\fR and \fBUPDATE\fR commands on the view
 | 
			
		||||
will be checked to ensure data satisfy the view-defining
 | 
			
		||||
condition (that is, the new data would be visible through the
 | 
			
		||||
view). If they do not, the update will be rejected.
 | 
			
		||||
.TP
 | 
			
		||||
\fBLOCAL\fR
 | 
			
		||||
Check for integrity on this view.
 | 
			
		||||
.TP
 | 
			
		||||
\fBCASCADED\fR
 | 
			
		||||
Check for integrity on this view and on any dependent
 | 
			
		||||
view. CASCADED is assumed if neither
 | 
			
		||||
CASCADED nor LOCAL is specified.
 | 
			
		||||
.PP
 | 
			
		||||
.PP
 | 
			
		||||
\fBCREATE OR REPLACE VIEW\fR is a
 | 
			
		||||
PostgreSQL language extension.
 | 
			
		||||
So is the concept of a temporary view.
 | 
			
		||||
.SH "SEE ALSO"
 | 
			
		||||
DROP VIEW [\fBdrop_view\fR(l)]
 | 
			
		||||
							
								
								
									
										601
									
								
								samples/Lex/zend_ini_scanner.l
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										601
									
								
								samples/Lex/zend_ini_scanner.l
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,601 @@
 | 
			
		||||
/*
 | 
			
		||||
   +----------------------------------------------------------------------+
 | 
			
		||||
   | Zend Engine                                                          |
 | 
			
		||||
   +----------------------------------------------------------------------+
 | 
			
		||||
   | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
 | 
			
		||||
   +----------------------------------------------------------------------+
 | 
			
		||||
   | This source file is subject to version 2.00 of the Zend license,     |
 | 
			
		||||
   | that is bundled with this package in the file LICENSE, and is        |
 | 
			
		||||
   | available through the world-wide-web at the following url:           |
 | 
			
		||||
   | http://www.zend.com/license/2_00.txt.                                |
 | 
			
		||||
   | 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.              |
 | 
			
		||||
   +----------------------------------------------------------------------+
 | 
			
		||||
   | Authors: Zeev Suraski <zeev@zend.com>                                |
 | 
			
		||||
   |          Jani Taskinen <jani@php.net>                                |
 | 
			
		||||
   |          Marcus Boerger <helly@php.net>                              |
 | 
			
		||||
   |          Nuno Lopes <nlopess@php.net>                                |
 | 
			
		||||
   |          Scott MacVicar <scottmac@php.net>                           |
 | 
			
		||||
   +----------------------------------------------------------------------+
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* $Id$ */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include "zend.h"
 | 
			
		||||
#include "zend_globals.h"
 | 
			
		||||
#include <zend_ini_parser.h>
 | 
			
		||||
#include "zend_ini_scanner.h"
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
/* 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; }
 | 
			
		||||
#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)
 | 
			
		||||
#define yyless(x)    do {	YYCURSOR = (unsigned char*)yytext + x; \
 | 
			
		||||
							yyleng   = (unsigned int)x; } while(0)
 | 
			
		||||
 | 
			
		||||
/* #define yymore()     goto yymore_restart */
 | 
			
		||||
 | 
			
		||||
/* perform sanity check. If this message is triggered you should
 | 
			
		||||
   increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */
 | 
			
		||||
/*!max:re2c */
 | 
			
		||||
#if ZEND_MMAP_AHEAD < (YYMAXFILL + 1)
 | 
			
		||||
# error ZEND_MMAP_AHEAD should be greater than YYMAXFILL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* 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()
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Globals Macros */
 | 
			
		||||
#define SCNG	INI_SCNG
 | 
			
		||||
#ifdef ZTS
 | 
			
		||||
ZEND_API ts_rsrc_id ini_scanner_globals_id;
 | 
			
		||||
#else
 | 
			
		||||
ZEND_API zend_ini_scanner_globals ini_scanner_globals;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Eat leading whitespace */
 | 
			
		||||
#define EAT_LEADING_WHITESPACE()                     \
 | 
			
		||||
	while (yytext[0]) {                              \
 | 
			
		||||
		if (yytext[0] == ' ' || yytext[0] == '\t') { \
 | 
			
		||||
			SCNG(yy_text)++;                         \
 | 
			
		||||
			yyleng--;                                \
 | 
			
		||||
		} else {                                     \
 | 
			
		||||
			break;                                   \
 | 
			
		||||
		}                                            \
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* 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;                                 \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
/* {{{ init_ini_scanner()
 | 
			
		||||
*/
 | 
			
		||||
static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
 | 
			
		||||
{
 | 
			
		||||
	/* Sanity check */
 | 
			
		||||
	if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) {
 | 
			
		||||
		zend_error(E_WARNING, "Invalid scanner mode");
 | 
			
		||||
		return FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SCNG(lineno) = 1;
 | 
			
		||||
	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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	zend_stack_init(&SCNG(state_stack));
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
 | 
			
		||||
	return SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
/* {{{ shutdown_ini_scanner()
 | 
			
		||||
*/
 | 
			
		||||
void shutdown_ini_scanner(TSRMLS_D)
 | 
			
		||||
{
 | 
			
		||||
	zend_stack_destroy(&SCNG(state_stack));
 | 
			
		||||
	if (ini_filename) {
 | 
			
		||||
		free(ini_filename);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
/* {{{ zend_ini_scanner_get_lineno()
 | 
			
		||||
*/
 | 
			
		||||
int zend_ini_scanner_get_lineno(TSRMLS_D)
 | 
			
		||||
{
 | 
			
		||||
	return SCNG(lineno);
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
/* {{{ zend_ini_scanner_get_filename()
 | 
			
		||||
*/
 | 
			
		||||
char *zend_ini_scanner_get_filename(TSRMLS_D)
 | 
			
		||||
{
 | 
			
		||||
	return ini_filename ? ini_filename : "Unknown";
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
/* {{{ zend_ini_open_file_for_scanning()
 | 
			
		||||
*/
 | 
			
		||||
int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC)
 | 
			
		||||
{
 | 
			
		||||
	char *buf;
 | 
			
		||||
	size_t size;
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
		return FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	yy_scan_buffer(buf, size TSRMLS_CC);
 | 
			
		||||
 | 
			
		||||
	return SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
/* {{{ zend_ini_prepare_string_for_scanning()
 | 
			
		||||
*/
 | 
			
		||||
int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC)
 | 
			
		||||
{
 | 
			
		||||
	int len = strlen(str);
 | 
			
		||||
 | 
			
		||||
	if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) {
 | 
			
		||||
		return FAILURE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	yy_scan_buffer(str, len TSRMLS_CC);
 | 
			
		||||
 | 
			
		||||
	return SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
/* {{{ 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) {
 | 
			
		||||
				*t++ = '\\';
 | 
			
		||||
				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;
 | 
			
		||||
}
 | 
			
		||||
/* }}} */
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
			return END_OF_LINE;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* 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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
/*!re2c
 | 
			
		||||
re2c:yyfill:check = 0;
 | 
			
		||||
LNUM [0-9]+
 | 
			
		||||
DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
 | 
			
		||||
NUMBER [-]?{LNUM}|{DNUM}
 | 
			
		||||
ANY_CHAR (.|[\n\t])
 | 
			
		||||
NEWLINE	("\r"|"\n"|"\r\n")
 | 
			
		||||
TABS_AND_SPACES [ \t]
 | 
			
		||||
WHITESPACE [ \t]+
 | 
			
		||||
CONSTANT [a-zA-Z_][a-zA-Z0-9_]*
 | 
			
		||||
LABEL [^=\n\r\t;|&$~(){}!"\[]+
 | 
			
		||||
TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@{}]
 | 
			
		||||
OPERATORS [&|~()!]
 | 
			
		||||
DOLLAR_CURLY "${"
 | 
			
		||||
 | 
			
		||||
SECTION_RAW_CHARS [^\]\n\r]
 | 
			
		||||
SINGLE_QUOTED_CHARS [^']
 | 
			
		||||
RAW_VALUE_CHARS [^"\n\r;\000]
 | 
			
		||||
 | 
			
		||||
LITERAL_DOLLAR ("$"([^{\000]|("\\"{ANY_CHAR})))
 | 
			
		||||
VALUE_CHARS         ([^$= \t\n\r;&|~()!"'\000]|{LITERAL_DOLLAR})
 | 
			
		||||
SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
 | 
			
		||||
 | 
			
		||||
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
 | 
			
		||||
 | 
			
		||||
<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] == '\'') {
 | 
			
		||||
		SCNG(yy_text)++;
 | 
			
		||||
		yyleng = yyleng - 2;
 | 
			
		||||
	}
 | 
			
		||||
	RETURN_TOKEN(TC_RAW, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_RAW,ST_SECTION_VALUE>"]"{TABS_AND_SPACES}*{NEWLINE}? { /* End of section */
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	SCNG(lineno)++;
 | 
			
		||||
	return ']';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL>{LABEL}"["{TABS_AND_SPACES}* { /* Start of option with offset */
 | 
			
		||||
	/* Eat leading whitespace */
 | 
			
		||||
	EAT_LEADING_WHITESPACE();
 | 
			
		||||
	
 | 
			
		||||
	/* Eat trailing whitespace and [ */
 | 
			
		||||
	EAT_TRAILING_WHITESPACE_EX('[');
 | 
			
		||||
 | 
			
		||||
	/* Enter offset lookup state */
 | 
			
		||||
	yy_push_state(ST_OFFSET TSRMLS_CC);
 | 
			
		||||
 | 
			
		||||
	RETURN_TOKEN(TC_OFFSET, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_OFFSET>{TABS_AND_SPACES}*"]" { /* End of section or an option offset */
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	return ']';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_DOUBLE_QUOTES,ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{DOLLAR_CURLY} { /* Variable start */
 | 
			
		||||
	yy_push_state(ST_VARNAME TSRMLS_CC);
 | 
			
		||||
	return TC_DOLLAR_CURLY;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_VARNAME>{LABEL} { /* Variable name */
 | 
			
		||||
	/* Eat leading whitespace */
 | 
			
		||||
	EAT_LEADING_WHITESPACE();
 | 
			
		||||
 | 
			
		||||
	/* Eat trailing whitespace */
 | 
			
		||||
	EAT_TRAILING_WHITESPACE();
 | 
			
		||||
 | 
			
		||||
	RETURN_TOKEN(TC_VARNAME, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL>{LABEL} { /* Get option name */
 | 
			
		||||
	/* Eat leading whitespace */
 | 
			
		||||
	EAT_LEADING_WHITESPACE();
 | 
			
		||||
 | 
			
		||||
	/* Eat trailing whitespace */
 | 
			
		||||
	EAT_TRAILING_WHITESPACE();
 | 
			
		||||
 | 
			
		||||
	RETURN_TOKEN(TC_LABEL, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL>{TABS_AND_SPACES}*[=]{TABS_AND_SPACES}* { /* Start option value */
 | 
			
		||||
	if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) {
 | 
			
		||||
		yy_push_state(ST_RAW TSRMLS_CC);
 | 
			
		||||
	} else {
 | 
			
		||||
		yy_push_state(ST_VALUE TSRMLS_CC);
 | 
			
		||||
	}
 | 
			
		||||
	return '=';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_RAW>["] {
 | 
			
		||||
	while (YYCURSOR < YYLIMIT) {
 | 
			
		||||
		switch (*YYCURSOR++) {
 | 
			
		||||
			case '\n':
 | 
			
		||||
				SCNG(lineno)++;
 | 
			
		||||
				break;
 | 
			
		||||
			case '\r':
 | 
			
		||||
				if (*YYCURSOR != '\n') {
 | 
			
		||||
					SCNG(lineno)++;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '"':
 | 
			
		||||
				yyleng = YYCURSOR - SCNG(yy_text) - 2;
 | 
			
		||||
				SCNG(yy_text)++;
 | 
			
		||||
				RETURN_TOKEN(TC_RAW, yytext, yyleng);
 | 
			
		||||
			case '\\':
 | 
			
		||||
				if (YYCURSOR < YYLIMIT) {
 | 
			
		||||
					YYCURSOR++;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	yyleng = YYCURSOR - SCNG(yy_text);
 | 
			
		||||
	RETURN_TOKEN(TC_RAW, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_RAW>{RAW_VALUE_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
 | 
			
		||||
	RETURN_TOKEN(TC_RAW, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_RAW>{SECTION_RAW_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
 | 
			
		||||
	RETURN_TOKEN(TC_RAW, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_VALUE,ST_RAW>{TABS_AND_SPACES}*{NEWLINE} { /* End of option value */
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	SCNG(lineno)++;
 | 
			
		||||
	return END_OF_LINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{CONSTANT} { /* Get constant option value */
 | 
			
		||||
	RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{NUMBER} { /* Get number option value as string */
 | 
			
		||||
	RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL>{TOKENS} { /* Disallow these chars outside option values */
 | 
			
		||||
	return yytext[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_VALUE>{OPERATORS}{TABS_AND_SPACES}* { /* Boolean operators */
 | 
			
		||||
	return yytext[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_VALUE>[=] { /* Make = used in option value to trigger error */
 | 
			
		||||
	yyless(0);
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	return END_OF_LINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_VALUE>{VALUE_CHARS}+ { /* Get everything else as option/offset value */
 | 
			
		||||
	RETURN_TOKEN(TC_STRING, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_VALUE,ST_OFFSET>{SECTION_VALUE_CHARS}+ { /* Get rest as section/offset value */
 | 
			
		||||
	RETURN_TOKEN(TC_STRING, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{TABS_AND_SPACES}*["] { /* Double quoted '"' string start */
 | 
			
		||||
	yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC);
 | 
			
		||||
	return '"';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_DOUBLE_QUOTES>["]{TABS_AND_SPACES}* { /* Double quoted '"' string ends */
 | 
			
		||||
	yy_pop_state(TSRMLS_C);
 | 
			
		||||
	return '"';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_SECTION_VALUE,ST_VALUE,ST_OFFSET>{WHITESPACE} {
 | 
			
		||||
	RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL,ST_RAW>{TABS_AND_SPACES}+ {
 | 
			
		||||
	/* eat whitespace */
 | 
			
		||||
	goto restart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL>{TABS_AND_SPACES}*{NEWLINE} {
 | 
			
		||||
	SCNG(lineno)++;
 | 
			
		||||
	return END_OF_LINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL,ST_VALUE,ST_RAW>{TABS_AND_SPACES}*[;][^\r\n]*{NEWLINE} { /* Comment */
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	SCNG(lineno)++;
 | 
			
		||||
	return END_OF_LINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<INITIAL>{TABS_AND_SPACES}*[#][^\r\n]*{NEWLINE} { /* #Comment */
 | 
			
		||||
	zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno));
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	SCNG(lineno)++;
 | 
			
		||||
	return END_OF_LINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<ST_VALUE,ST_RAW>[^] { /* End of option value (if EOF is reached before EOL */
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	return END_OF_LINE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<*>[^] {
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user