1 /* SPDX-License-Identifier: GPL-2.0-or-later * << 2 /* 1 /* 3 * (C) Copyright David Gibson <dwg@au1.ibm.com> 2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. >> 3 * >> 4 * >> 5 * This program is free software; you can redistribute it and/or >> 6 * modify it under the terms of the GNU General Public License as >> 7 * published by the Free Software Foundation; either version 2 of the >> 8 * License, or (at your option) any later version. >> 9 * >> 10 * This program is distributed in the hope that it will be useful, >> 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of >> 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> 13 * General Public License for more details. >> 14 * >> 15 * You should have received a copy of the GNU General Public License >> 16 * along with this program; if not, write to the Free Software >> 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 >> 18 * USA 4 */ 19 */ 5 20 6 %option noyywrap nounput noinput never-interac !! 21 %option noyywrap noinput nounput yylineno 7 22 >> 23 %x INCLUDE 8 %x BYTESTRING 24 %x BYTESTRING 9 %x PROPNODENAME 25 %x PROPNODENAME 10 %s V1 26 %s V1 11 27 12 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 28 PROPNODECHAR [a-zA-Z0-9,._+*#?@-] 13 PATHCHAR ({PROPNODECHAR}|[/]) 29 PATHCHAR ({PROPNODECHAR}|[/]) 14 LABEL [a-zA-Z_][a-zA-Z0-9_]* 30 LABEL [a-zA-Z_][a-zA-Z0-9_]* 15 STRING \"([^\\"]|\\.)*\" 31 STRING \"([^\\"]|\\.)*\" 16 CHAR_LITERAL '([^']|\\')*' << 17 WS [[:space:]] 32 WS [[:space:]] 18 COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 33 COMMENT "/*"([^*]|\*+[^*/])*\*+"/" 19 LINECOMMENT "//".*\n 34 LINECOMMENT "//".*\n 20 35 21 %{ 36 %{ 22 #include "dtc.h" 37 #include "dtc.h" 23 #include "srcpos.h" 38 #include "srcpos.h" 24 #include "dtc-parser.tab.h" 39 #include "dtc-parser.tab.h" 25 40 26 extern bool treesource_error; << 27 << 28 /* CAUTION: this will stop working if we ever << 29 #define YY_USER_ACTION \ << 30 { \ << 31 srcpos_update(&yylloc, yytext, << 32 } << 33 41 34 /*#define LEXDEBUG 1*/ 42 /*#define LEXDEBUG 1*/ 35 43 36 #ifdef LEXDEBUG 44 #ifdef LEXDEBUG 37 #define DPRINT(fmt, ...) fprintf(stderr 45 #define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) 38 #else 46 #else 39 #define DPRINT(fmt, ...) do { } while ( 47 #define DPRINT(fmt, ...) do { } while (0) 40 #endif 48 #endif 41 49 42 static int dts_version = 1; !! 50 static int dts_version; /* = 0 */ 43 51 44 #define BEGIN_DEFAULT() DPRINT("<V1>\n !! 52 #define BEGIN_DEFAULT() if (dts_version == 0) { \ >> 53 DPRINT("<INITIAL>\n"); \ >> 54 BEGIN(INITIAL); \ >> 55 } else { \ >> 56 DPRINT("<V1>\n"); \ 45 BEGIN(V1); \ 57 BEGIN(V1); \ >> 58 } 46 59 47 static void push_input_file(const char *filena 60 static void push_input_file(const char *filename); 48 static bool pop_input_file(void); !! 61 static int pop_input_file(void); 49 static void PRINTF(1, 2) lexical_error(const c << 50 << 51 %} 62 %} 52 63 53 %% 64 %% 54 <*>"/include/"{WS}*{STRING} { 65 <*>"/include/"{WS}*{STRING} { 55 char *name = strchr(yy 66 char *name = strchr(yytext, '\"') + 1; 56 yytext[yyleng-1] = '\0 67 yytext[yyleng-1] = '\0'; 57 push_input_file(name); 68 push_input_file(name); 58 } 69 } 59 70 60 <*>^"#"(line)?[ \t]+[0-9]+[ \t]+{STRING}([ \t] << 61 char *line, *fnstart, << 62 struct data fn; << 63 /* skip text before li << 64 line = yytext; << 65 while (!isdigit((unsig << 66 line++; << 67 << 68 /* regexp ensures that << 69 * in the whole yytext << 70 * beginning and end o << 71 fnstart = memchr(yytex << 72 for (fnend = yytext + << 73 *fnend != '"'; fn << 74 ; << 75 assert(fnstart && fnen << 76 << 77 fn = data_copy_escape_ << 78 << 79 << 80 /* Don't allow nuls in << 81 if (memchr(fn.val, '\0 << 82 lexical_error( << 83 << 84 /* -1 since #line is t << 85 srcpos_set_line(xstrdu << 86 data_free(fn); << 87 } << 88 << 89 <*><<EOF>> { 71 <*><<EOF>> { 90 if (!pop_input_file()) 72 if (!pop_input_file()) { 91 yyterminate(); 73 yyterminate(); 92 } 74 } 93 } 75 } 94 76 95 <*>{STRING} { 77 <*>{STRING} { >> 78 yylloc.file = srcpos_file; >> 79 yylloc.first_line = yylineno; 96 DPRINT("String: %s\n", 80 DPRINT("String: %s\n", yytext); 97 yylval.data = data_cop 81 yylval.data = data_copy_escape_string(yytext+1, 98 yyleng 82 yyleng-2); >> 83 yylloc.first_line = yylineno; 99 return DT_STRING; 84 return DT_STRING; 100 } 85 } 101 86 102 <*>"/dts-v1/" { 87 <*>"/dts-v1/" { >> 88 yylloc.file = srcpos_file; >> 89 yylloc.first_line = yylineno; 103 DPRINT("Keyword: /dts- 90 DPRINT("Keyword: /dts-v1/\n"); 104 dts_version = 1; 91 dts_version = 1; 105 BEGIN_DEFAULT(); 92 BEGIN_DEFAULT(); 106 return DT_V1; 93 return DT_V1; 107 } 94 } 108 95 109 <*>"/plugin/" { << 110 DPRINT("Keyword: /plug << 111 return DT_PLUGIN; << 112 } << 113 << 114 <*>"/memreserve/" { 96 <*>"/memreserve/" { >> 97 yylloc.file = srcpos_file; >> 98 yylloc.first_line = yylineno; 115 DPRINT("Keyword: /memr 99 DPRINT("Keyword: /memreserve/\n"); 116 BEGIN_DEFAULT(); 100 BEGIN_DEFAULT(); 117 return DT_MEMRESERVE; 101 return DT_MEMRESERVE; 118 } 102 } 119 103 120 <*>"/bits/" { << 121 DPRINT("Keyword: /bits << 122 BEGIN_DEFAULT(); << 123 return DT_BITS; << 124 } << 125 << 126 <*>"/delete-property/" { << 127 DPRINT("Keyword: /dele << 128 DPRINT("<PROPNODENAME> << 129 BEGIN(PROPNODENAME); << 130 return DT_DEL_PROP; << 131 } << 132 << 133 <*>"/delete-node/" { << 134 DPRINT("Keyword: /dele << 135 DPRINT("<PROPNODENAME> << 136 BEGIN(PROPNODENAME); << 137 return DT_DEL_NODE; << 138 } << 139 << 140 <*>"/omit-if-no-ref/" { << 141 DPRINT("Keyword: /omit << 142 DPRINT("<PROPNODENAME> << 143 BEGIN(PROPNODENAME); << 144 return DT_OMIT_NO_REF; << 145 } << 146 << 147 <*>{LABEL}: { 104 <*>{LABEL}: { >> 105 yylloc.file = srcpos_file; >> 106 yylloc.first_line = yylineno; 148 DPRINT("Label: %s\n", 107 DPRINT("Label: %s\n", yytext); 149 yylval.labelref = xstr !! 108 yylval.labelref = strdup(yytext); 150 yylval.labelref[yyleng 109 yylval.labelref[yyleng-1] = '\0'; 151 return DT_LABEL; 110 return DT_LABEL; 152 } 111 } 153 112 154 <V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? !! 113 <INITIAL>[bodh]# { 155 char *e; !! 114 yylloc.file = srcpos_file; 156 DPRINT("Integer Litera !! 115 yylloc.first_line = yylineno; 157 !! 116 if (*yytext == 'b') 158 errno = 0; !! 117 yylval.cbase = 2; 159 yylval.integer = strto !! 118 else if (*yytext == 'o') 160 !! 119 yylval.cbase = 8; 161 if (*e && e[strspn(e, !! 120 else if (*yytext == 'd') 162 lexical_error( !! 121 yylval.cbase = 10; 163 << 164 } << 165 << 166 if (errno == ERANGE) << 167 lexical_error( << 168 << 169 else 122 else 170 /* ERANGE is t !! 123 yylval.cbase = 16; 171 * by strings !! 124 DPRINT("Base: %d\n", yylval.cbase); 172 assert(errno = !! 125 return DT_BASE; >> 126 } >> 127 >> 128 <INITIAL>[0-9a-fA-F]+ { >> 129 yylloc.file = srcpos_file; >> 130 yylloc.first_line = yylineno; >> 131 yylval.literal = strdup(yytext); >> 132 DPRINT("Literal: '%s'\n", yylval.literal); >> 133 return DT_LEGACYLITERAL; >> 134 } >> 135 >> 136 <V1>[0-9]+|0[xX][0-9a-fA-F]+ { >> 137 yylloc.file = srcpos_file; >> 138 yylloc.first_line = yylineno; >> 139 yylval.literal = strdup(yytext); >> 140 DPRINT("Literal: '%s'\n", yylval.literal); 173 return DT_LITERAL; 141 return DT_LITERAL; 174 } 142 } 175 143 176 <*>{CHAR_LITERAL} { !! 144 \&{LABEL} { /* label reference */ 177 struct data d; !! 145 yylloc.file = srcpos_file; 178 DPRINT("Character lite !! 146 yylloc.first_line = yylineno; 179 << 180 d = data_copy_escape_s << 181 if (d.len == 1) { << 182 lexical_error( << 183 yylval.integer << 184 } else { << 185 yylval.integer << 186 << 187 if (d.len > 2) << 188 lexica << 189 << 190 << 191 } << 192 << 193 data_free(d); << 194 return DT_CHAR_LITERAL << 195 } << 196 << 197 <*>\&{LABEL} { /* label reference */ << 198 DPRINT("Ref: %s\n", yy 147 DPRINT("Ref: %s\n", yytext+1); 199 yylval.labelref = xstr !! 148 yylval.labelref = strdup(yytext+1); 200 return DT_LABEL_REF; !! 149 return DT_REF; 201 } 150 } 202 151 203 <*>"&{"{PATHCHAR}*\} { /* new-style p !! 152 "&{/"{PATHCHAR}+\} { /* new-style path reference */ >> 153 yylloc.file = srcpos_file; >> 154 yylloc.first_line = yylineno; 204 yytext[yyleng-1] = '\0 155 yytext[yyleng-1] = '\0'; 205 DPRINT("Ref: %s\n", yy 156 DPRINT("Ref: %s\n", yytext+2); 206 yylval.labelref = xstr !! 157 yylval.labelref = strdup(yytext+2); 207 return DT_PATH_REF; !! 158 return DT_REF; >> 159 } >> 160 >> 161 <INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */ >> 162 yylloc.file = srcpos_file; >> 163 yylloc.first_line = yylineno; >> 164 DPRINT("Ref: %s\n", yytext+1); >> 165 yylval.labelref = strdup(yytext+1); >> 166 return DT_REF; 208 } 167 } 209 168 210 <BYTESTRING>[0-9a-fA-F]{2} { 169 <BYTESTRING>[0-9a-fA-F]{2} { >> 170 yylloc.file = srcpos_file; >> 171 yylloc.first_line = yylineno; 211 yylval.byte = strtol(y 172 yylval.byte = strtol(yytext, NULL, 16); 212 DPRINT("Byte: %02x\n", 173 DPRINT("Byte: %02x\n", (int)yylval.byte); 213 return DT_BYTE; 174 return DT_BYTE; 214 } 175 } 215 176 216 <BYTESTRING>"]" { 177 <BYTESTRING>"]" { >> 178 yylloc.file = srcpos_file; >> 179 yylloc.first_line = yylineno; 217 DPRINT("/BYTESTRING\n" 180 DPRINT("/BYTESTRING\n"); 218 BEGIN_DEFAULT(); 181 BEGIN_DEFAULT(); 219 return ']'; 182 return ']'; 220 } 183 } 221 184 222 <PROPNODENAME>\\?{PROPNODECHAR}+ { !! 185 <PROPNODENAME>{PROPNODECHAR}+ { >> 186 yylloc.file = srcpos_file; >> 187 yylloc.first_line = yylineno; 223 DPRINT("PropNodeName: 188 DPRINT("PropNodeName: %s\n", yytext); 224 yylval.propnodename = !! 189 yylval.propnodename = strdup(yytext); 225 << 226 BEGIN_DEFAULT(); 190 BEGIN_DEFAULT(); 227 return DT_PROPNODENAME 191 return DT_PROPNODENAME; 228 } 192 } 229 193 230 "/incbin/" { 194 "/incbin/" { >> 195 yylloc.file = srcpos_file; >> 196 yylloc.first_line = yylineno; 231 DPRINT("Binary Include 197 DPRINT("Binary Include\n"); 232 return DT_INCBIN; 198 return DT_INCBIN; 233 } 199 } 234 200 235 <*>{WS}+ /* eat whitespace */ 201 <*>{WS}+ /* eat whitespace */ 236 <*>{COMMENT}+ /* eat C-style comments */ 202 <*>{COMMENT}+ /* eat C-style comments */ 237 <*>{LINECOMMENT}+ /* eat C++-style comments */ 203 <*>{LINECOMMENT}+ /* eat C++-style comments */ 238 204 239 <*>"<<" { return DT_LSHIFT; }; << 240 <*>">>" { return DT_RSHIFT; }; << 241 <*>"<=" { return DT_LE; }; << 242 <*>">=" { return DT_GE; }; << 243 <*>"==" { return DT_EQ; }; << 244 <*>"!=" { return DT_NE; }; << 245 <*>"&&" { return DT_AND; }; << 246 <*>"||" { return DT_OR; }; << 247 << 248 <*>. { 205 <*>. { >> 206 yylloc.file = srcpos_file; >> 207 yylloc.first_line = yylineno; 249 DPRINT("Char: %c (\\x% 208 DPRINT("Char: %c (\\x%02x)\n", yytext[0], 250 (unsigned)yyte 209 (unsigned)yytext[0]); 251 if (yytext[0] == '[') 210 if (yytext[0] == '[') { 252 DPRINT("<BYTES 211 DPRINT("<BYTESTRING>\n"); 253 BEGIN(BYTESTRI 212 BEGIN(BYTESTRING); 254 } 213 } 255 if ((yytext[0] == '{') 214 if ((yytext[0] == '{') 256 || (yytext[0] == ' 215 || (yytext[0] == ';')) { 257 DPRINT("<PROPN 216 DPRINT("<PROPNODENAME>\n"); 258 BEGIN(PROPNODE 217 BEGIN(PROPNODENAME); 259 } 218 } 260 return yytext[0]; 219 return yytext[0]; 261 } 220 } 262 221 263 %% 222 %% 264 223 >> 224 >> 225 /* >> 226 * Stack of nested include file contexts. >> 227 */ >> 228 >> 229 struct incl_file { >> 230 struct dtc_file *file; >> 231 YY_BUFFER_STATE yy_prev_buf; >> 232 int yy_prev_lineno; >> 233 struct incl_file *prev; >> 234 }; >> 235 >> 236 static struct incl_file *incl_file_stack; >> 237 >> 238 >> 239 /* >> 240 * Detect infinite include recursion. >> 241 */ >> 242 #define MAX_INCLUDE_DEPTH (100) >> 243 >> 244 static int incl_depth = 0; >> 245 >> 246 265 static void push_input_file(const char *filena 247 static void push_input_file(const char *filename) 266 { 248 { >> 249 struct incl_file *incl_file; >> 250 struct dtc_file *newfile; >> 251 struct search_path search, *searchptr = NULL; >> 252 267 assert(filename); 253 assert(filename); 268 254 269 srcfile_push(filename); !! 255 if (incl_depth++ >= MAX_INCLUDE_DEPTH) >> 256 die("Includes nested too deeply"); 270 257 271 yyin = current_srcfile->f; !! 258 if (srcpos_file) { >> 259 search.dir = srcpos_file->dir; >> 260 search.next = NULL; >> 261 search.prev = NULL; >> 262 searchptr = &search; >> 263 } 272 264 273 yypush_buffer_state(yy_create_buffer(y !! 265 newfile = dtc_open_file(filename, searchptr); >> 266 >> 267 incl_file = xmalloc(sizeof(struct incl_file)); >> 268 >> 269 /* >> 270 * Save current context. >> 271 */ >> 272 incl_file->yy_prev_buf = YY_CURRENT_BUFFER; >> 273 incl_file->yy_prev_lineno = yylineno; >> 274 incl_file->file = srcpos_file; >> 275 incl_file->prev = incl_file_stack; >> 276 >> 277 incl_file_stack = incl_file; >> 278 >> 279 /* >> 280 * Establish new context. >> 281 */ >> 282 srcpos_file = newfile; >> 283 yylineno = 1; >> 284 yyin = newfile->file; >> 285 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); 274 } 286 } 275 287 276 288 277 static bool pop_input_file(void) !! 289 static int pop_input_file(void) 278 { 290 { 279 if (srcfile_pop() == 0) !! 291 struct incl_file *incl_file; 280 return false; << 281 292 282 yypop_buffer_state(); !! 293 if (incl_file_stack == 0) 283 yyin = current_srcfile->f; !! 294 return 0; 284 295 285 return true; !! 296 dtc_close_file(srcpos_file); 286 } << 287 << 288 static void lexical_error(const char *fmt, ... << 289 { << 290 va_list ap; << 291 297 292 va_start(ap, fmt); !! 298 /* 293 srcpos_verror(&yylloc, "Lexical error" !! 299 * Pop. 294 va_end(ap); !! 300 */ >> 301 --incl_depth; >> 302 incl_file = incl_file_stack; >> 303 incl_file_stack = incl_file->prev; >> 304 >> 305 /* >> 306 * Recover old context. >> 307 */ >> 308 yy_delete_buffer(YY_CURRENT_BUFFER); >> 309 yy_switch_to_buffer(incl_file->yy_prev_buf); >> 310 yylineno = incl_file->yy_prev_lineno; >> 311 srcpos_file = incl_file->file; >> 312 yyin = incl_file->file ? incl_file->file->file : NULL; >> 313 >> 314 /* >> 315 * Free old state. >> 316 */ >> 317 free(incl_file); 295 318 296 treesource_error = true; !! 319 return 1; 297 } 320 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.