xref: /aosp_15_r20/external/libconfig/lib/scanner.l (revision 2e9d491483b805f09ea864149eadd5680efcc72a)
1*2e9d4914SAndroid Build Coastguard Worker /* -*- mode: C -*- */
2*2e9d4914SAndroid Build Coastguard Worker /* --------------------------------------------------------------------------
3*2e9d4914SAndroid Build Coastguard Worker    libconfig - A library for processing structured configuration files
4*2e9d4914SAndroid Build Coastguard Worker    Copyright (C) 2005-2020  Mark A Lindner
5*2e9d4914SAndroid Build Coastguard Worker 
6*2e9d4914SAndroid Build Coastguard Worker    This file is part of libconfig.
7*2e9d4914SAndroid Build Coastguard Worker 
8*2e9d4914SAndroid Build Coastguard Worker    This library is free software; you can redistribute it and/or
9*2e9d4914SAndroid Build Coastguard Worker    modify it under the terms of the GNU Lesser General Public License
10*2e9d4914SAndroid Build Coastguard Worker    as published by the Free Software Foundation; either version 2.1 of
11*2e9d4914SAndroid Build Coastguard Worker    the License, or (at your option) any later version.
12*2e9d4914SAndroid Build Coastguard Worker 
13*2e9d4914SAndroid Build Coastguard Worker    This library is distributed in the hope that it will be useful, but
14*2e9d4914SAndroid Build Coastguard Worker    WITHOUT ANY WARRANTY; without even the implied warranty of
15*2e9d4914SAndroid Build Coastguard Worker    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*2e9d4914SAndroid Build Coastguard Worker    Lesser General Public License for more details.
17*2e9d4914SAndroid Build Coastguard Worker 
18*2e9d4914SAndroid Build Coastguard Worker    You should have received a copy of the GNU Library General Public
19*2e9d4914SAndroid Build Coastguard Worker    License along with this library; if not, see
20*2e9d4914SAndroid Build Coastguard Worker    <http://www.gnu.org/licenses/>.
21*2e9d4914SAndroid Build Coastguard Worker    ----------------------------------------------------------------------------
22*2e9d4914SAndroid Build Coastguard Worker */
23*2e9d4914SAndroid Build Coastguard Worker 
24*2e9d4914SAndroid Build Coastguard Worker %option nounistd
25*2e9d4914SAndroid Build Coastguard Worker %option never-interactive
26*2e9d4914SAndroid Build Coastguard Worker %option reentrant
27*2e9d4914SAndroid Build Coastguard Worker %option noyywrap
28*2e9d4914SAndroid Build Coastguard Worker %option yylineno
29*2e9d4914SAndroid Build Coastguard Worker %option nounput
30*2e9d4914SAndroid Build Coastguard Worker %option bison-bridge
31*2e9d4914SAndroid Build Coastguard Worker %option header-file="scanner.h"
32*2e9d4914SAndroid Build Coastguard Worker %option outfile="lex.yy.c"
33*2e9d4914SAndroid Build Coastguard Worker %option extra-type="struct scan_context *"
34*2e9d4914SAndroid Build Coastguard Worker 
35*2e9d4914SAndroid Build Coastguard Worker %{
36*2e9d4914SAndroid Build Coastguard Worker 
37*2e9d4914SAndroid Build Coastguard Worker #ifdef _MSC_VER
38*2e9d4914SAndroid Build Coastguard Worker #pragma warning (disable: 4996)
39*2e9d4914SAndroid Build Coastguard Worker #endif
40*2e9d4914SAndroid Build Coastguard Worker 
41*2e9d4914SAndroid Build Coastguard Worker #include <stdlib.h>
42*2e9d4914SAndroid Build Coastguard Worker #include <errno.h>
43*2e9d4914SAndroid Build Coastguard Worker #include <ctype.h>
44*2e9d4914SAndroid Build Coastguard Worker #include <string.h>
45*2e9d4914SAndroid Build Coastguard Worker #include <limits.h>
46*2e9d4914SAndroid Build Coastguard Worker 
47*2e9d4914SAndroid Build Coastguard Worker #include "parsectx.h"
48*2e9d4914SAndroid Build Coastguard Worker #include "scanctx.h"
49*2e9d4914SAndroid Build Coastguard Worker #include "grammar.h"
50*2e9d4914SAndroid Build Coastguard Worker #include "wincompat.h"
51*2e9d4914SAndroid Build Coastguard Worker #include "util.h"
52*2e9d4914SAndroid Build Coastguard Worker 
53*2e9d4914SAndroid Build Coastguard Worker #define YY_NO_INPUT // Suppress generation of useless input() function
54*2e9d4914SAndroid Build Coastguard Worker 
55*2e9d4914SAndroid Build Coastguard Worker %}
56*2e9d4914SAndroid Build Coastguard Worker 
57*2e9d4914SAndroid Build Coastguard Worker true              [Tt][Rr][Uu][Ee]
58*2e9d4914SAndroid Build Coastguard Worker false             [Ff][Aa][Ll][Ss][Ee]
59*2e9d4914SAndroid Build Coastguard Worker name              [A-Za-z\*][-A-Za-z0-9_\*]*
60*2e9d4914SAndroid Build Coastguard Worker integer           [-+]?[0-9]+
61*2e9d4914SAndroid Build Coastguard Worker integer64         [-+]?[0-9]+L(L)?
62*2e9d4914SAndroid Build Coastguard Worker hex               0[Xx][0-9A-Fa-f]+
63*2e9d4914SAndroid Build Coastguard Worker hex64             0[Xx][0-9A-Fa-f]+L(L)?
64*2e9d4914SAndroid Build Coastguard Worker hexchar           \\[Xx][0-9A-Fa-f]{2}
65*2e9d4914SAndroid Build Coastguard Worker float             ([-+]?([0-9]*)?\.[0-9]*([eE][-+]?[0-9]+)?)|([-+]?([0-9]+)(\.[0-9]*)?[eE][-+]?[0-9]+)
66*2e9d4914SAndroid Build Coastguard Worker include_open ^[ \t]*@include[ \t]+\"
67*2e9d4914SAndroid Build Coastguard Worker 
68*2e9d4914SAndroid Build Coastguard Worker %x SINGLE_LINE_COMMENT MULTI_LINE_COMMENT STRING INCLUDE
69*2e9d4914SAndroid Build Coastguard Worker 
70*2e9d4914SAndroid Build Coastguard Worker %%
71*2e9d4914SAndroid Build Coastguard Worker 
72*2e9d4914SAndroid Build Coastguard Worker (#|\/\/)                     { BEGIN SINGLE_LINE_COMMENT; }
73*2e9d4914SAndroid Build Coastguard Worker <SINGLE_LINE_COMMENT>\n      { BEGIN INITIAL; }
74*2e9d4914SAndroid Build Coastguard Worker <SINGLE_LINE_COMMENT>.       { /* ignore */ }
75*2e9d4914SAndroid Build Coastguard Worker 
76*2e9d4914SAndroid Build Coastguard Worker \/\*                         { BEGIN MULTI_LINE_COMMENT; }
77*2e9d4914SAndroid Build Coastguard Worker <MULTI_LINE_COMMENT>\*\/     { BEGIN INITIAL; }
78*2e9d4914SAndroid Build Coastguard Worker <MULTI_LINE_COMMENT>.        { /* ignore */ }
79*2e9d4914SAndroid Build Coastguard Worker <MULTI_LINE_COMMENT>\n       { /* ignore */ }
80*2e9d4914SAndroid Build Coastguard Worker 
81*2e9d4914SAndroid Build Coastguard Worker \"                { BEGIN STRING; }
82*2e9d4914SAndroid Build Coastguard Worker <STRING>[^\"\\]+  { libconfig_scanctx_append_string(yyextra, yytext); }
83*2e9d4914SAndroid Build Coastguard Worker <STRING>\\n       { libconfig_scanctx_append_char(yyextra, '\n'); }
84*2e9d4914SAndroid Build Coastguard Worker <STRING>\\r       { libconfig_scanctx_append_char(yyextra, '\r'); }
85*2e9d4914SAndroid Build Coastguard Worker <STRING>\\t       { libconfig_scanctx_append_char(yyextra, '\t'); }
86*2e9d4914SAndroid Build Coastguard Worker <STRING>\\f       { libconfig_scanctx_append_char(yyextra, '\f'); }
87*2e9d4914SAndroid Build Coastguard Worker <STRING>\\\\      { libconfig_scanctx_append_char(yyextra, '\\'); }
88*2e9d4914SAndroid Build Coastguard Worker <STRING>\\\"      { libconfig_scanctx_append_char(yyextra, '\"'); }
89*2e9d4914SAndroid Build Coastguard Worker <STRING>{hexchar} {
90*2e9d4914SAndroid Build Coastguard Worker                     char c = (char)(strtol(yytext + 2, NULL, 16) & 0xFF);
91*2e9d4914SAndroid Build Coastguard Worker                     libconfig_scanctx_append_char(yyextra, c);
92*2e9d4914SAndroid Build Coastguard Worker                   }
93*2e9d4914SAndroid Build Coastguard Worker <STRING>\\        { libconfig_scanctx_append_char(yyextra, '\\'); }
94*2e9d4914SAndroid Build Coastguard Worker <STRING>\"        {
95*2e9d4914SAndroid Build Coastguard Worker                     yylval->sval = libconfig_scanctx_take_string(yyextra);
96*2e9d4914SAndroid Build Coastguard Worker                     BEGIN INITIAL;
97*2e9d4914SAndroid Build Coastguard Worker                     return(TOK_STRING);
98*2e9d4914SAndroid Build Coastguard Worker                   }
99*2e9d4914SAndroid Build Coastguard Worker 
100*2e9d4914SAndroid Build Coastguard Worker {include_open}    { BEGIN INCLUDE; }
101*2e9d4914SAndroid Build Coastguard Worker <INCLUDE>[^\"\\]+ { libconfig_scanctx_append_string(yyextra, yytext); }
102*2e9d4914SAndroid Build Coastguard Worker <INCLUDE>\\\\     { libconfig_scanctx_append_char(yyextra, '\\'); }
103*2e9d4914SAndroid Build Coastguard Worker <INCLUDE>\\\"     { libconfig_scanctx_append_char(yyextra, '\"'); }
104*2e9d4914SAndroid Build Coastguard Worker <INCLUDE>\"       {
105*2e9d4914SAndroid Build Coastguard Worker   const char *error = NULL;
106*2e9d4914SAndroid Build Coastguard Worker   const char *path = libconfig_scanctx_take_string(yyextra);
107*2e9d4914SAndroid Build Coastguard Worker   FILE *fp = libconfig_scanctx_push_include(yyextra, (void *)YY_CURRENT_BUFFER,
108*2e9d4914SAndroid Build Coastguard Worker                                             path, &error);
109*2e9d4914SAndroid Build Coastguard Worker   __delete(path);
110*2e9d4914SAndroid Build Coastguard Worker 
111*2e9d4914SAndroid Build Coastguard Worker   if(fp)
112*2e9d4914SAndroid Build Coastguard Worker   {
113*2e9d4914SAndroid Build Coastguard Worker     yyin = fp;
114*2e9d4914SAndroid Build Coastguard Worker     yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
115*2e9d4914SAndroid Build Coastguard Worker                         yyscanner);
116*2e9d4914SAndroid Build Coastguard Worker   }
117*2e9d4914SAndroid Build Coastguard Worker   else if(error)
118*2e9d4914SAndroid Build Coastguard Worker   {
119*2e9d4914SAndroid Build Coastguard Worker     yyextra->config->error_text = error;
120*2e9d4914SAndroid Build Coastguard Worker     yyextra->config->error_file = libconfig_scanctx_current_filename(yyextra);
121*2e9d4914SAndroid Build Coastguard Worker     yyextra->config->error_line = libconfig_yyget_lineno(yyscanner);
122*2e9d4914SAndroid Build Coastguard Worker     return TOK_ERROR;
123*2e9d4914SAndroid Build Coastguard Worker   }
124*2e9d4914SAndroid Build Coastguard Worker   BEGIN INITIAL;
125*2e9d4914SAndroid Build Coastguard Worker }
126*2e9d4914SAndroid Build Coastguard Worker 
127*2e9d4914SAndroid Build Coastguard Worker \n|\r|\f          { /* ignore */ }
128*2e9d4914SAndroid Build Coastguard Worker [ \t]+            { /* ignore */ }
129*2e9d4914SAndroid Build Coastguard Worker 
130*2e9d4914SAndroid Build Coastguard Worker \=|\:             { return(TOK_EQUALS); }
131*2e9d4914SAndroid Build Coastguard Worker ,                 { return(TOK_COMMA); }
132*2e9d4914SAndroid Build Coastguard Worker \{                { return(TOK_GROUP_START); }
133*2e9d4914SAndroid Build Coastguard Worker \}                { return(TOK_GROUP_END); }
134*2e9d4914SAndroid Build Coastguard Worker {true}            { yylval->ival = 1; return(TOK_BOOLEAN); }
135*2e9d4914SAndroid Build Coastguard Worker {false}           { yylval->ival = 0; return(TOK_BOOLEAN); }
136*2e9d4914SAndroid Build Coastguard Worker {name}            { yylval->sval = yytext; return(TOK_NAME); }
137*2e9d4914SAndroid Build Coastguard Worker {float}           { yylval->fval = atof(yytext); return(TOK_FLOAT); }
138*2e9d4914SAndroid Build Coastguard Worker {integer}         {
139*2e9d4914SAndroid Build Coastguard Worker                     int ok;
140*2e9d4914SAndroid Build Coastguard Worker                     long long llval = libconfig_parse_integer(yytext, &ok);
141*2e9d4914SAndroid Build Coastguard Worker                     if(!ok)
142*2e9d4914SAndroid Build Coastguard Worker                       return(TOK_ERROR);
143*2e9d4914SAndroid Build Coastguard Worker 
144*2e9d4914SAndroid Build Coastguard Worker                     if((llval < INT_MIN) || (llval > INT_MAX))
145*2e9d4914SAndroid Build Coastguard Worker                     {
146*2e9d4914SAndroid Build Coastguard Worker                       yylval->llval = llval;
147*2e9d4914SAndroid Build Coastguard Worker                       return(TOK_INTEGER64);
148*2e9d4914SAndroid Build Coastguard Worker                     }
149*2e9d4914SAndroid Build Coastguard Worker                     else
150*2e9d4914SAndroid Build Coastguard Worker                     {
151*2e9d4914SAndroid Build Coastguard Worker                       yylval->ival = (int)llval;
152*2e9d4914SAndroid Build Coastguard Worker                       return(TOK_INTEGER);
153*2e9d4914SAndroid Build Coastguard Worker                     }
154*2e9d4914SAndroid Build Coastguard Worker                   }
155*2e9d4914SAndroid Build Coastguard Worker {integer64}       { yylval->llval = atoll(yytext); return(TOK_INTEGER64); }
156*2e9d4914SAndroid Build Coastguard Worker {hex}             {
157*2e9d4914SAndroid Build Coastguard Worker                     yylval->ival = strtoul(yytext, NULL, 16);
158*2e9d4914SAndroid Build Coastguard Worker                     return(TOK_HEX);
159*2e9d4914SAndroid Build Coastguard Worker                   }
160*2e9d4914SAndroid Build Coastguard Worker {hex64}           {
161*2e9d4914SAndroid Build Coastguard Worker                     yylval->llval = libconfig_parse_hex64(yytext);
162*2e9d4914SAndroid Build Coastguard Worker                     return(TOK_HEX64);
163*2e9d4914SAndroid Build Coastguard Worker                   }
164*2e9d4914SAndroid Build Coastguard Worker \[                { return(TOK_ARRAY_START); }
165*2e9d4914SAndroid Build Coastguard Worker \]                { return(TOK_ARRAY_END); }
166*2e9d4914SAndroid Build Coastguard Worker \(                { return(TOK_LIST_START); }
167*2e9d4914SAndroid Build Coastguard Worker \)                { return(TOK_LIST_END); }
168*2e9d4914SAndroid Build Coastguard Worker ;                 { return(TOK_SEMICOLON); }
169*2e9d4914SAndroid Build Coastguard Worker .                 { return(TOK_GARBAGE); }
170*2e9d4914SAndroid Build Coastguard Worker 
171*2e9d4914SAndroid Build Coastguard Worker <<EOF>>           {
172*2e9d4914SAndroid Build Coastguard Worker   const char *error = NULL;
173*2e9d4914SAndroid Build Coastguard Worker   FILE *fp;
174*2e9d4914SAndroid Build Coastguard Worker 
175*2e9d4914SAndroid Build Coastguard Worker   fp = libconfig_scanctx_next_include_file(yyextra, &error);
176*2e9d4914SAndroid Build Coastguard Worker   if(fp)
177*2e9d4914SAndroid Build Coastguard Worker   {
178*2e9d4914SAndroid Build Coastguard Worker     yyin = fp;
179*2e9d4914SAndroid Build Coastguard Worker     yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
180*2e9d4914SAndroid Build Coastguard Worker     yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner),
181*2e9d4914SAndroid Build Coastguard Worker                         yyscanner);
182*2e9d4914SAndroid Build Coastguard Worker   }
183*2e9d4914SAndroid Build Coastguard Worker   else if(error)
184*2e9d4914SAndroid Build Coastguard Worker   {
185*2e9d4914SAndroid Build Coastguard Worker     yyextra->config->error_text = error;
186*2e9d4914SAndroid Build Coastguard Worker     yyextra->config->error_file = libconfig_scanctx_current_filename(yyextra);
187*2e9d4914SAndroid Build Coastguard Worker     yyextra->config->error_line = libconfig_yyget_lineno(yyscanner);
188*2e9d4914SAndroid Build Coastguard Worker     return TOK_ERROR;
189*2e9d4914SAndroid Build Coastguard Worker   }
190*2e9d4914SAndroid Build Coastguard Worker   else
191*2e9d4914SAndroid Build Coastguard Worker   {
192*2e9d4914SAndroid Build Coastguard Worker     /* No more files in the current include list. */
193*2e9d4914SAndroid Build Coastguard Worker     YY_BUFFER_STATE buf = (YY_BUFFER_STATE)libconfig_scanctx_pop_include(yyextra);
194*2e9d4914SAndroid Build Coastguard Worker     if(buf)
195*2e9d4914SAndroid Build Coastguard Worker     {
196*2e9d4914SAndroid Build Coastguard Worker       yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
197*2e9d4914SAndroid Build Coastguard Worker       yy_switch_to_buffer(buf, yyscanner);
198*2e9d4914SAndroid Build Coastguard Worker     }
199*2e9d4914SAndroid Build Coastguard Worker     else
200*2e9d4914SAndroid Build Coastguard Worker       yyterminate();
201*2e9d4914SAndroid Build Coastguard Worker   }
202*2e9d4914SAndroid Build Coastguard Worker }
203