summaryrefslogtreecommitdiff
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 3b41bfca6..0ee1caf03 100644
--- a/scripts/dtc/dtc-lexer.l
+++ b/scripts/dtc/dtc-lexer.l
@@ -20,7 +20,6 @@
%option noyywrap nounput noinput never-interactive
-%x INCLUDE
%x BYTESTRING
%x PROPNODENAME
%s V1
@@ -40,6 +39,7 @@ LINECOMMENT "//".*\n
#include "dtc-parser.tab.h"
YYLTYPE yylloc;
+extern bool treesource_error;
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
#define YY_USER_ACTION \
@@ -61,7 +61,8 @@ static int dts_version = 1;
BEGIN(V1); \
static void push_input_file(const char *filename);
-static int pop_input_file(void);
+static bool pop_input_file(void);
+static void lexical_error(const char *fmt, ...);
%}
%%
@@ -75,11 +76,11 @@ static int pop_input_file(void);
char *line, *tmp, *fn;
/* skip text before line # */
line = yytext;
- while (!isdigit(*line))
+ while (!isdigit((unsigned char)*line))
line++;
/* skip digits in line # */
tmp = line;
- while (!isspace(*tmp))
+ while (!isspace((unsigned char)*tmp))
tmp++;
/* "NULL"-terminate line # */
*tmp = '\0';
@@ -146,15 +147,42 @@ static int pop_input_file(void);
}
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
- yylval.literal = xstrdup(yytext);
- DPRINT("Literal: '%s'\n", yylval.literal);
+ char *e;
+ DPRINT("Integer Literal: '%s'\n", yytext);
+
+ errno = 0;
+ yylval.integer = strtoull(yytext, &e, 0);
+
+ assert(!(*e) || !e[strspn(e, "UL")]);
+
+ if (errno == ERANGE)
+ lexical_error("Integer literal '%s' out of range",
+ yytext);
+ else
+ /* ERANGE is the only strtoull error triggerable
+ * by strings matching the pattern */
+ assert(errno == 0);
return DT_LITERAL;
}
<*>{CHAR_LITERAL} {
- yytext[yyleng-1] = '\0';
- yylval.literal = xstrdup(yytext+1);
- DPRINT("Character literal: %s\n", yylval.literal);
+ struct data d;
+ DPRINT("Character literal: %s\n", yytext);
+
+ d = data_copy_escape_string(yytext+1, yyleng-2);
+ if (d.len == 1) {
+ lexical_error("Empty character literal");
+ yylval.integer = 0;
+ return DT_CHAR_LITERAL;
+ }
+
+ yylval.integer = (unsigned char)d.val[0];
+
+ if (d.len > 2)
+ lexical_error("Character literal has %d"
+ " characters instead of 1",
+ d.len - 1);
+
return DT_CHAR_LITERAL;
}
@@ -164,7 +192,7 @@ static int pop_input_file(void);
return DT_REF;
}
-<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */
+<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2);
@@ -238,13 +266,24 @@ static void push_input_file(const char *filename)
}
-static int pop_input_file(void)
+static bool pop_input_file(void)
{
if (srcfile_pop() == 0)
- return 0;
+ return false;
yypop_buffer_state();
yyin = current_srcfile->f;
- return 1;
+ return true;
+}
+
+static void lexical_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ srcpos_verror(&yylloc, "Lexical error", fmt, ap);
+ va_end(ap);
+
+ treesource_error = true;
}