diff options
Diffstat (limited to 'scripts/dtc/dtc-lexer.l')
| -rw-r--r-- | scripts/dtc/dtc-lexer.l | 65 |
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 | ||
| 42 | YYLTYPE yylloc; | 41 | YYLTYPE yylloc; |
| 42 | extern 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 | ||
| 63 | static void push_input_file(const char *filename); | 63 | static void push_input_file(const char *filename); |
| 64 | static int pop_input_file(void); | 64 | static bool pop_input_file(void); |
| 65 | static 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 | ||
| 241 | static int pop_input_file(void) | 269 | static 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 | |||
| 280 | static 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 | } |
