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