aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dtc/dtc-lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/dtc/dtc-lexer.l')
-rw-r--r--scripts/dtc/dtc-lexer.l65
1 files changed, 52 insertions, 13 deletions
diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
index 3b41bfca636c..0ee1caf03dd0 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -20,7 +20,6 @@
20 20
21%option noyywrap nounput noinput never-interactive 21%option noyywrap nounput noinput never-interactive
22 22
23%x INCLUDE
24%x BYTESTRING 23%x BYTESTRING
25%x PROPNODENAME 24%x PROPNODENAME
26%s V1 25%s V1
@@ -40,6 +39,7 @@ LINECOMMENT "//".*\n
40#include "dtc-parser.tab.h" 39#include "dtc-parser.tab.h"
41 40
42YYLTYPE yylloc; 41YYLTYPE yylloc;
42extern bool treesource_error;
43 43
44/* CAUTION: this will stop working if we ever use yyless() or yyunput() */ 44/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
45#define YY_USER_ACTION \ 45#define YY_USER_ACTION \
@@ -61,7 +61,8 @@ static int dts_version = 1;
61 BEGIN(V1); \ 61 BEGIN(V1); \
62 62
63static void push_input_file(const char *filename); 63static void push_input_file(const char *filename);
64static int pop_input_file(void); 64static bool pop_input_file(void);
65static void lexical_error(const char *fmt, ...);
65%} 66%}
66 67
67%% 68%%
@@ -75,11 +76,11 @@ static int pop_input_file(void);
75 char *line, *tmp, *fn; 76 char *line, *tmp, *fn;
76 /* skip text before line # */ 77 /* skip text before line # */
77 line = yytext; 78 line = yytext;
78 while (!isdigit(*line)) 79 while (!isdigit((unsigned char)*line))
79 line++; 80 line++;
80 /* skip digits in line # */ 81 /* skip digits in line # */
81 tmp = line; 82 tmp = line;
82 while (!isspace(*tmp)) 83 while (!isspace((unsigned char)*tmp))
83 tmp++; 84 tmp++;
84 /* "NULL"-terminate line # */ 85 /* "NULL"-terminate line # */
85 *tmp = '\0'; 86 *tmp = '\0';
@@ -146,15 +147,42 @@ static int pop_input_file(void);
146 } 147 }
147 148
148<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? { 149<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
149 yylval.literal = xstrdup(yytext); 150 char *e;
150 DPRINT("Literal: '%s'\n", yylval.literal); 151 DPRINT("Integer Literal: '%s'\n", yytext);
152
153 errno = 0;
154 yylval.integer = strtoull(yytext, &e, 0);
155
156 assert(!(*e) || !e[strspn(e, "UL")]);
157
158 if (errno == ERANGE)
159 lexical_error("Integer literal '%s' out of range",
160 yytext);
161 else
162 /* ERANGE is the only strtoull error triggerable
163 * by strings matching the pattern */
164 assert(errno == 0);
151 return DT_LITERAL; 165 return DT_LITERAL;
152 } 166 }
153 167
154<*>{CHAR_LITERAL} { 168<*>{CHAR_LITERAL} {
155 yytext[yyleng-1] = '\0'; 169 struct data d;
156 yylval.literal = xstrdup(yytext+1); 170 DPRINT("Character literal: %s\n", yytext);
157 DPRINT("Character literal: %s\n", yylval.literal); 171
172 d = data_copy_escape_string(yytext+1, yyleng-2);
173 if (d.len == 1) {
174 lexical_error("Empty character literal");
175 yylval.integer = 0;
176 return DT_CHAR_LITERAL;
177 }
178
179 yylval.integer = (unsigned char)d.val[0];
180
181 if (d.len > 2)
182 lexical_error("Character literal has %d"
183 " characters instead of 1",
184 d.len - 1);
185
158 return DT_CHAR_LITERAL; 186 return DT_CHAR_LITERAL;
159 } 187 }
160 188
@@ -164,7 +192,7 @@ static int pop_input_file(void);
164 return DT_REF; 192 return DT_REF;
165 } 193 }
166 194
167<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */ 195<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
168 yytext[yyleng-1] = '\0'; 196 yytext[yyleng-1] = '\0';
169 DPRINT("Ref: %s\n", yytext+2); 197 DPRINT("Ref: %s\n", yytext+2);
170 yylval.labelref = xstrdup(yytext+2); 198 yylval.labelref = xstrdup(yytext+2);
@@ -238,13 +266,24 @@ static void push_input_file(const char *filename)
238} 266}
239 267
240 268
241static int pop_input_file(void) 269static bool pop_input_file(void)
242{ 270{
243 if (srcfile_pop() == 0) 271 if (srcfile_pop() == 0)
244 return 0; 272 return false;
245 273
246 yypop_buffer_state(); 274 yypop_buffer_state();
247 yyin = current_srcfile->f; 275 yyin = current_srcfile->f;
248 276
249 return 1; 277 return true;
278}
279
280static void lexical_error(const char *fmt, ...)
281{
282 va_list ap;
283
284 va_start(ap, fmt);
285 srcpos_verror(&yylloc, "Lexical error", fmt, ap);
286 va_end(ap);
287
288 treesource_error = true;
250} 289}