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