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 %locations << 6 20 7 %{ 21 %{ 8 #include <stdio.h> 22 #include <stdio.h> 9 #include <inttypes.h> << 10 23 11 #include "dtc.h" 24 #include "dtc.h" 12 #include "srcpos.h" 25 #include "srcpos.h" 13 26 >> 27 YYLTYPE yylloc; >> 28 14 extern int yylex(void); 29 extern int yylex(void); >> 30 extern void print_error(char const *fmt, ...); 15 extern void yyerror(char const *s); 31 extern void yyerror(char const *s); 16 #define ERROR(loc, ...) \ << 17 do { \ << 18 srcpos_error((loc), "Error", _ << 19 treesource_error = true; \ << 20 } while (0) << 21 << 22 #define YYERROR_CALL(msg) yyerror(msg) << 23 << 24 extern struct dt_info *parser_output; << 25 extern bool treesource_error; << 26 32 27 static bool is_ref_relative(const char *ref) !! 33 extern struct boot_info *the_boot_info; 28 { !! 34 extern int treesource_error; 29 return ref[0] != '/' && strchr(&ref[1] << 30 } << 31 35 >> 36 static unsigned long long eval_literal(const char *s, int base, int bits); >> 37 static unsigned char eval_char_literal(const char *s); 32 %} 38 %} 33 39 34 %union { 40 %union { 35 char *propnodename; 41 char *propnodename; >> 42 char *literal; 36 char *labelref; 43 char *labelref; >> 44 unsigned int cbase; 37 uint8_t byte; 45 uint8_t byte; 38 struct data data; 46 struct data data; 39 47 40 struct { 48 struct { 41 struct data data; 49 struct data data; 42 int bits; 50 int bits; 43 } array; 51 } array; 44 52 45 struct property *prop; 53 struct property *prop; 46 struct property *proplist; 54 struct property *proplist; 47 struct node *node; 55 struct node *node; 48 struct node *nodelist; 56 struct node *nodelist; 49 struct reserve_info *re; 57 struct reserve_info *re; 50 uint64_t integer; 58 uint64_t integer; 51 unsigned int flags; << 52 } 59 } 53 60 54 %token DT_V1 61 %token DT_V1 55 %token DT_PLUGIN << 56 %token DT_MEMRESERVE 62 %token DT_MEMRESERVE 57 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ D 63 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR 58 %token DT_BITS 64 %token DT_BITS 59 %token DT_DEL_PROP 65 %token DT_DEL_PROP 60 %token DT_DEL_NODE 66 %token DT_DEL_NODE 61 %token DT_OMIT_NO_REF << 62 %token <propnodename> DT_PROPNODENAME 67 %token <propnodename> DT_PROPNODENAME 63 %token <integer> DT_LITERAL !! 68 %token <literal> DT_LITERAL 64 %token <integer> DT_CHAR_LITERAL !! 69 %token <literal> DT_CHAR_LITERAL >> 70 %token <cbase> DT_BASE 65 %token <byte> DT_BYTE 71 %token <byte> DT_BYTE 66 %token <data> DT_STRING 72 %token <data> DT_STRING 67 %token <labelref> DT_LABEL 73 %token <labelref> DT_LABEL 68 %token <labelref> DT_LABEL_REF !! 74 %token <labelref> DT_REF 69 %token <labelref> DT_PATH_REF << 70 %token DT_INCBIN 75 %token DT_INCBIN 71 76 72 %type <data> propdata 77 %type <data> propdata 73 %type <data> propdataprefix 78 %type <data> propdataprefix 74 %type <flags> header << 75 %type <flags> headers << 76 %type <re> memreserve 79 %type <re> memreserve 77 %type <re> memreserves 80 %type <re> memreserves 78 %type <array> arrayprefix 81 %type <array> arrayprefix 79 %type <data> bytestring 82 %type <data> bytestring 80 %type <prop> propdef 83 %type <prop> propdef 81 %type <proplist> proplist 84 %type <proplist> proplist 82 %type <labelref> dt_ref << 83 85 84 %type <node> devicetree 86 %type <node> devicetree 85 %type <node> nodedef 87 %type <node> nodedef 86 %type <node> subnode 88 %type <node> subnode 87 %type <nodelist> subnodes 89 %type <nodelist> subnodes 88 90 89 %type <integer> integer_prim 91 %type <integer> integer_prim 90 %type <integer> integer_unary 92 %type <integer> integer_unary 91 %type <integer> integer_mul 93 %type <integer> integer_mul 92 %type <integer> integer_add 94 %type <integer> integer_add 93 %type <integer> integer_shift 95 %type <integer> integer_shift 94 %type <integer> integer_rela 96 %type <integer> integer_rela 95 %type <integer> integer_eq 97 %type <integer> integer_eq 96 %type <integer> integer_bitand 98 %type <integer> integer_bitand 97 %type <integer> integer_bitxor 99 %type <integer> integer_bitxor 98 %type <integer> integer_bitor 100 %type <integer> integer_bitor 99 %type <integer> integer_and 101 %type <integer> integer_and 100 %type <integer> integer_or 102 %type <integer> integer_or 101 %type <integer> integer_trinary 103 %type <integer> integer_trinary 102 %type <integer> integer_expr 104 %type <integer> integer_expr 103 105 104 %% 106 %% 105 107 106 sourcefile: 108 sourcefile: 107 headers memreserves devicetree !! 109 DT_V1 ';' memreserves devicetree 108 { 110 { 109 parser_output = build_ !! 111 the_boot_info = build_boot_info($3, $4, 110 !! 112 guess_boot_cpuid($4)); 111 } << 112 ; << 113 << 114 header: << 115 DT_V1 ';' << 116 { << 117 $$ = DTSF_V1; << 118 } << 119 | DT_V1 ';' DT_PLUGIN ';' << 120 { << 121 $$ = DTSF_V1 | DTSF_PL << 122 } << 123 ; << 124 << 125 headers: << 126 header << 127 | header headers << 128 { << 129 if ($2 != $1) << 130 ERROR(&@2, "He << 131 $$ = $1; << 132 } 113 } 133 ; 114 ; 134 115 135 memreserves: 116 memreserves: 136 /* empty */ 117 /* empty */ 137 { 118 { 138 $$ = NULL; 119 $$ = NULL; 139 } 120 } 140 | memreserve memreserves 121 | memreserve memreserves 141 { 122 { 142 $$ = chain_reserve_ent 123 $$ = chain_reserve_entry($1, $2); 143 } 124 } 144 ; 125 ; 145 126 146 memreserve: 127 memreserve: 147 DT_MEMRESERVE integer_prim integer_p 128 DT_MEMRESERVE integer_prim integer_prim ';' 148 { 129 { 149 $$ = build_reserve_ent 130 $$ = build_reserve_entry($2, $3); 150 } 131 } 151 | DT_LABEL memreserve 132 | DT_LABEL memreserve 152 { 133 { 153 add_label(&$2->labels, 134 add_label(&$2->labels, $1); 154 $$ = $2; 135 $$ = $2; 155 } 136 } 156 ; 137 ; 157 138 158 dt_ref: DT_LABEL_REF | DT_PATH_REF; << 159 << 160 devicetree: 139 devicetree: 161 '/' nodedef 140 '/' nodedef 162 { 141 { 163 $$ = name_node($2, "") 142 $$ = name_node($2, ""); 164 } 143 } 165 | devicetree '/' nodedef 144 | devicetree '/' nodedef 166 { 145 { 167 $$ = merge_nodes($1, $ 146 $$ = merge_nodes($1, $3); 168 } 147 } 169 | dt_ref nodedef !! 148 | devicetree DT_REF nodedef 170 { << 171 /* << 172 * We rely on the rule << 173 * versioninfo plugi << 174 * so $-1 is what we w << 175 */ << 176 if (!($<flags>-1 & DTS << 177 ERROR(&@2, "La << 178 else if (is_ref_relati << 179 ERROR(&@2, "La << 180 $$ = add_orphan_node( << 181 name_n << 182 << 183 $2, $1 << 184 } << 185 | devicetree DT_LABEL dt_ref nodedef << 186 { << 187 struct node *target = << 188 << 189 if (($<flags>-1 & DTSF << 190 ERROR(&@2, "La << 191 << 192 if (target) { << 193 add_label(&tar << 194 merge_nodes(ta << 195 } else << 196 ERROR(&@3, "La << 197 $$ = $1; << 198 } << 199 | devicetree DT_PATH_REF nodedef << 200 { << 201 /* << 202 * We rely on the rule << 203 * versioninfo plugi << 204 * so $-1 is what we w << 205 */ << 206 if ($<flags>-1 & DTSF_ << 207 if (is_ref_rel << 208 ERROR( << 209 add_orphan_nod << 210 } else { << 211 struct node *t << 212 << 213 if (target) << 214 merge_ << 215 else << 216 ERROR( << 217 } << 218 $$ = $1; << 219 } << 220 | devicetree DT_LABEL_REF nodedef << 221 { 149 { 222 struct node *target = 150 struct node *target = get_node_by_ref($1, $2); 223 151 224 if (target) { << 225 merge_nodes(ta << 226 } else { << 227 /* << 228 * We rely on << 229 * versionin << 230 * so $-1 is w << 231 */ << 232 if ($<flags>-1 << 233 add_or << 234 else << 235 ERROR( << 236 } << 237 $$ = $1; << 238 } << 239 | devicetree DT_DEL_NODE dt_ref ';' << 240 { << 241 struct node *target = << 242 << 243 if (target) 152 if (target) 244 delete_node(ta !! 153 merge_nodes(target, $3); 245 else 154 else 246 ERROR(&@3, "La !! 155 print_error("label or path, '%s', not found", $2); 247 << 248 << 249 $$ = $1; 156 $$ = $1; 250 } 157 } 251 | devicetree DT_OMIT_NO_REF dt_ref ';' !! 158 | devicetree DT_DEL_NODE DT_REF ';' 252 { 159 { 253 struct node *target = 160 struct node *target = get_node_by_ref($1, $3); 254 161 255 if (target) !! 162 if (!target) 256 omit_node_if_u !! 163 print_error("label or path, '%s', not found", $3); 257 else 164 else 258 ERROR(&@3, "La !! 165 delete_node(target); 259 << 260 166 261 $$ = $1; 167 $$ = $1; 262 } 168 } 263 ; 169 ; 264 170 265 nodedef: 171 nodedef: 266 '{' proplist subnodes '}' ';' 172 '{' proplist subnodes '}' ';' 267 { 173 { 268 $$ = build_node($2, $3 !! 174 $$ = build_node($2, $3); 269 } 175 } 270 ; 176 ; 271 177 272 proplist: 178 proplist: 273 /* empty */ 179 /* empty */ 274 { 180 { 275 $$ = NULL; 181 $$ = NULL; 276 } 182 } 277 | proplist propdef 183 | proplist propdef 278 { 184 { 279 $$ = chain_property($2 185 $$ = chain_property($2, $1); 280 } 186 } 281 ; 187 ; 282 188 283 propdef: 189 propdef: 284 DT_PROPNODENAME '=' propdata ';' 190 DT_PROPNODENAME '=' propdata ';' 285 { 191 { 286 $$ = build_property($1 !! 192 $$ = build_property($1, $3); 287 free($1); << 288 } 193 } 289 | DT_PROPNODENAME ';' 194 | DT_PROPNODENAME ';' 290 { 195 { 291 $$ = build_property($1 !! 196 $$ = build_property($1, empty_data); 292 free($1); << 293 } 197 } 294 | DT_DEL_PROP DT_PROPNODENAME ';' 198 | DT_DEL_PROP DT_PROPNODENAME ';' 295 { 199 { 296 $$ = build_property_de 200 $$ = build_property_delete($2); 297 free($2); << 298 } 201 } 299 | DT_LABEL propdef 202 | DT_LABEL propdef 300 { 203 { 301 add_label(&$2->labels, 204 add_label(&$2->labels, $1); 302 $$ = $2; 205 $$ = $2; 303 } 206 } 304 ; 207 ; 305 208 306 propdata: 209 propdata: 307 propdataprefix DT_STRING 210 propdataprefix DT_STRING 308 { 211 { 309 $$ = data_merge($1, $2 212 $$ = data_merge($1, $2); 310 } 213 } 311 | propdataprefix arrayprefix '>' 214 | propdataprefix arrayprefix '>' 312 { 215 { 313 $$ = data_merge($1, $2 216 $$ = data_merge($1, $2.data); 314 } 217 } 315 | propdataprefix '[' bytestring ']' 218 | propdataprefix '[' bytestring ']' 316 { 219 { 317 $$ = data_merge($1, $3 220 $$ = data_merge($1, $3); 318 } 221 } 319 | propdataprefix dt_ref !! 222 | propdataprefix DT_REF 320 { 223 { 321 $1 = data_add_marker($ << 322 $$ = data_add_marker($ 224 $$ = data_add_marker($1, REF_PATH, $2); 323 } 225 } 324 | propdataprefix DT_INCBIN '(' DT_STRI 226 | propdataprefix DT_INCBIN '(' DT_STRING ',' integer_prim ',' integer_prim ')' 325 { 227 { 326 FILE *f = srcfile_rela 228 FILE *f = srcfile_relative_open($4.val, NULL); 327 struct data d; 229 struct data d; 328 230 329 if ($6 != 0) 231 if ($6 != 0) 330 if (fseek(f, $ 232 if (fseek(f, $6, SEEK_SET) != 0) 331 die("C !! 233 print_error("Couldn't seek to offset %llu in \"%s\": %s", 332 (u !! 234 (unsigned long long)$6, 333 st !! 235 $4.val, >> 236 strerror(errno)); 334 237 335 d = data_copy_file(f, 238 d = data_copy_file(f, $8); 336 239 337 $$ = data_merge($1, d) 240 $$ = data_merge($1, d); 338 fclose(f); 241 fclose(f); 339 } 242 } 340 | propdataprefix DT_INCBIN '(' DT_STRI 243 | propdataprefix DT_INCBIN '(' DT_STRING ')' 341 { 244 { 342 FILE *f = srcfile_rela 245 FILE *f = srcfile_relative_open($4.val, NULL); 343 struct data d = empty_ 246 struct data d = empty_data; 344 247 345 d = data_copy_file(f, 248 d = data_copy_file(f, -1); 346 249 347 $$ = data_merge($1, d) 250 $$ = data_merge($1, d); 348 fclose(f); 251 fclose(f); 349 } 252 } 350 | propdata DT_LABEL 253 | propdata DT_LABEL 351 { 254 { 352 $$ = data_add_marker($ 255 $$ = data_add_marker($1, LABEL, $2); 353 } 256 } 354 ; 257 ; 355 258 356 propdataprefix: 259 propdataprefix: 357 /* empty */ 260 /* empty */ 358 { 261 { 359 $$ = empty_data; 262 $$ = empty_data; 360 } 263 } 361 | propdata ',' 264 | propdata ',' 362 { 265 { 363 $$ = $1; 266 $$ = $1; 364 } 267 } 365 | propdataprefix DT_LABEL 268 | propdataprefix DT_LABEL 366 { 269 { 367 $$ = data_add_marker($ 270 $$ = data_add_marker($1, LABEL, $2); 368 } 271 } 369 ; 272 ; 370 273 371 arrayprefix: 274 arrayprefix: 372 DT_BITS DT_LITERAL '<' 275 DT_BITS DT_LITERAL '<' 373 { 276 { 374 unsigned long long bit !! 277 $$.data = empty_data; 375 enum markertype type = !! 278 $$.bits = eval_literal($2, 0, 7); 376 279 377 bits = $2; !! 280 if (($$.bits != 8) && 378 !! 281 ($$.bits != 16) && 379 switch (bits) { !! 282 ($$.bits != 32) && 380 case 8: type = TYPE_UI !! 283 ($$.bits != 64)) 381 case 16: type = TYPE_U !! 284 { 382 case 32: type = TYPE_U !! 285 print_error("Only 8, 16, 32 and 64-bit elements" 383 case 64: type = TYPE_U !! 286 " are currently supported"); 384 default: !! 287 $$.bits = 32; 385 ERROR(&@2, "Ar << 386 " 8, 16, << 387 bits = 32; << 388 } 288 } 389 << 390 $$.data = data_add_mar << 391 $$.bits = bits; << 392 } 289 } 393 | '<' 290 | '<' 394 { 291 { 395 $$.data = data_add_mar !! 292 $$.data = empty_data; 396 $$.bits = 32; 293 $$.bits = 32; 397 } 294 } 398 | arrayprefix integer_prim 295 | arrayprefix integer_prim 399 { 296 { 400 if ($1.bits < 64) { 297 if ($1.bits < 64) { 401 uint64_t mask 298 uint64_t mask = (1ULL << $1.bits) - 1; 402 /* 299 /* 403 * Bits above 300 * Bits above mask must either be all zero 404 * (positive w 301 * (positive within range of mask) or all one 405 * (negative a 302 * (negative and sign-extended). The second 406 * condition i 303 * condition is true if when we set all bits 407 * within the 304 * within the mask to one (i.e. | in the 408 * mask), all 305 * mask), all bits are one. 409 */ 306 */ 410 if (($2 > mask !! 307 if (($2 > mask) && (($2 | mask) != -1ULL)) 411 char * !! 308 print_error( 412 fprint !! 309 "integer value out of range " 413 !! 310 "%016lx (%d bits)", $1.bits); 414 << 415 << 416 free(l << 417 } << 418 } 311 } 419 312 420 $$.data = data_append_ 313 $$.data = data_append_integer($1.data, $2, $1.bits); 421 } 314 } 422 | arrayprefix dt_ref !! 315 | arrayprefix DT_REF 423 { 316 { 424 uint64_t val = ~0ULL > 317 uint64_t val = ~0ULL >> (64 - $1.bits); 425 318 426 if ($1.bits == 32) 319 if ($1.bits == 32) 427 $1.data = data 320 $1.data = data_add_marker($1.data, 428 321 REF_PHANDLE, 429 322 $2); 430 else 323 else 431 ERROR(&@2, "Re !! 324 print_error("References are only allowed in " 432 "a 325 "arrays with 32-bit elements."); 433 326 434 $$.data = data_append_ 327 $$.data = data_append_integer($1.data, val, $1.bits); 435 } 328 } 436 | arrayprefix DT_LABEL 329 | arrayprefix DT_LABEL 437 { 330 { 438 $$.data = data_add_mar 331 $$.data = data_add_marker($1.data, LABEL, $2); 439 } 332 } 440 ; 333 ; 441 334 442 integer_prim: 335 integer_prim: 443 DT_LITERAL 336 DT_LITERAL >> 337 { >> 338 $$ = eval_literal($1, 0, 64); >> 339 } 444 | DT_CHAR_LITERAL 340 | DT_CHAR_LITERAL >> 341 { >> 342 $$ = eval_char_literal($1); >> 343 } 445 | '(' integer_expr ')' 344 | '(' integer_expr ')' 446 { 345 { 447 $$ = $2; 346 $$ = $2; 448 } 347 } 449 ; 348 ; 450 349 451 integer_expr: 350 integer_expr: 452 integer_trinary 351 integer_trinary 453 ; 352 ; 454 353 455 integer_trinary: 354 integer_trinary: 456 integer_or 355 integer_or 457 | integer_or '?' integer_expr ':' inte 356 | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; } 458 ; 357 ; 459 358 460 integer_or: 359 integer_or: 461 integer_and 360 integer_and 462 | integer_or DT_OR integer_and { $$ = 361 | integer_or DT_OR integer_and { $$ = $1 || $3; } 463 ; 362 ; 464 363 465 integer_and: 364 integer_and: 466 integer_bitor 365 integer_bitor 467 | integer_and DT_AND integer_bitor { $ 366 | integer_and DT_AND integer_bitor { $$ = $1 && $3; } 468 ; 367 ; 469 368 470 integer_bitor: 369 integer_bitor: 471 integer_bitxor 370 integer_bitxor 472 | integer_bitor '|' integer_bitxor { $ 371 | integer_bitor '|' integer_bitxor { $$ = $1 | $3; } 473 ; 372 ; 474 373 475 integer_bitxor: 374 integer_bitxor: 476 integer_bitand 375 integer_bitand 477 | integer_bitxor '^' integer_bitand { 376 | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; } 478 ; 377 ; 479 378 480 integer_bitand: 379 integer_bitand: 481 integer_eq 380 integer_eq 482 | integer_bitand '&' integer_eq { $$ = 381 | integer_bitand '&' integer_eq { $$ = $1 & $3; } 483 ; 382 ; 484 383 485 integer_eq: 384 integer_eq: 486 integer_rela 385 integer_rela 487 | integer_eq DT_EQ integer_rela { $$ = 386 | integer_eq DT_EQ integer_rela { $$ = $1 == $3; } 488 | integer_eq DT_NE integer_rela { $$ = 387 | integer_eq DT_NE integer_rela { $$ = $1 != $3; } 489 ; 388 ; 490 389 491 integer_rela: 390 integer_rela: 492 integer_shift 391 integer_shift 493 | integer_rela '<' integer_shift { $$ 392 | integer_rela '<' integer_shift { $$ = $1 < $3; } 494 | integer_rela '>' integer_shift { $$ 393 | integer_rela '>' integer_shift { $$ = $1 > $3; } 495 | integer_rela DT_LE integer_shift { $ 394 | integer_rela DT_LE integer_shift { $$ = $1 <= $3; } 496 | integer_rela DT_GE integer_shift { $ 395 | integer_rela DT_GE integer_shift { $$ = $1 >= $3; } 497 ; 396 ; 498 397 499 integer_shift: 398 integer_shift: 500 integer_shift DT_LSHIFT integer_add !! 399 integer_shift DT_LSHIFT integer_add { $$ = $1 << $3; } 501 | integer_shift DT_RSHIFT integer_add !! 400 | integer_shift DT_RSHIFT integer_add { $$ = $1 >> $3; } 502 | integer_add 401 | integer_add 503 ; 402 ; 504 403 505 integer_add: 404 integer_add: 506 integer_add '+' integer_mul { $$ = $ 405 integer_add '+' integer_mul { $$ = $1 + $3; } 507 | integer_add '-' integer_mul { $$ = $ 406 | integer_add '-' integer_mul { $$ = $1 - $3; } 508 | integer_mul 407 | integer_mul 509 ; 408 ; 510 409 511 integer_mul: 410 integer_mul: 512 integer_mul '*' integer_unary { $$ = 411 integer_mul '*' integer_unary { $$ = $1 * $3; } 513 | integer_mul '/' integer_unary !! 412 | integer_mul '/' integer_unary { $$ = $1 / $3; } 514 { !! 413 | integer_mul '%' integer_unary { $$ = $1 % $3; } 515 if ($3 != 0) { << 516 $$ = $1 / $3; << 517 } else { << 518 ERROR(&@$, "Di << 519 $$ = 0; << 520 } << 521 } << 522 | integer_mul '%' integer_unary << 523 { << 524 if ($3 != 0) { << 525 $$ = $1 % $3; << 526 } else { << 527 ERROR(&@$, "Di << 528 $$ = 0; << 529 } << 530 } << 531 | integer_unary 414 | integer_unary 532 ; 415 ; 533 416 534 integer_unary: 417 integer_unary: 535 integer_prim 418 integer_prim 536 | '-' integer_unary { $$ = -$2; } 419 | '-' integer_unary { $$ = -$2; } 537 | '~' integer_unary { $$ = ~$2; } 420 | '~' integer_unary { $$ = ~$2; } 538 | '!' integer_unary { $$ = !$2; } 421 | '!' integer_unary { $$ = !$2; } 539 ; 422 ; 540 423 541 bytestring: 424 bytestring: 542 /* empty */ 425 /* empty */ 543 { 426 { 544 $$ = data_add_marker(e !! 427 $$ = empty_data; 545 } 428 } 546 | bytestring DT_BYTE 429 | bytestring DT_BYTE 547 { 430 { 548 $$ = data_append_byte( 431 $$ = data_append_byte($1, $2); 549 } 432 } 550 | bytestring DT_LABEL 433 | bytestring DT_LABEL 551 { 434 { 552 $$ = data_add_marker($ 435 $$ = data_add_marker($1, LABEL, $2); 553 } 436 } 554 ; 437 ; 555 438 556 subnodes: 439 subnodes: 557 /* empty */ 440 /* empty */ 558 { 441 { 559 $$ = NULL; 442 $$ = NULL; 560 } 443 } 561 | subnode subnodes 444 | subnode subnodes 562 { 445 { 563 $$ = chain_node($1, $2 446 $$ = chain_node($1, $2); 564 } 447 } 565 | subnode propdef 448 | subnode propdef 566 { 449 { 567 ERROR(&@2, "Properties !! 450 print_error("syntax error: properties must precede subnodes"); 568 YYERROR; 451 YYERROR; 569 } 452 } 570 ; 453 ; 571 454 572 subnode: 455 subnode: 573 DT_PROPNODENAME nodedef 456 DT_PROPNODENAME nodedef 574 { 457 { 575 $$ = name_node($2, $1) 458 $$ = name_node($2, $1); 576 free($1); << 577 } 459 } 578 | DT_DEL_NODE DT_PROPNODENAME ';' 460 | DT_DEL_NODE DT_PROPNODENAME ';' 579 { 461 { 580 $$ = name_node(build_n !! 462 $$ = name_node(build_node_delete(), $2); 581 free($2); << 582 } << 583 | DT_OMIT_NO_REF subnode << 584 { << 585 $$ = omit_node_if_unus << 586 } 463 } 587 | DT_LABEL subnode 464 | DT_LABEL subnode 588 { 465 { 589 add_label(&$2->labels, 466 add_label(&$2->labels, $1); 590 $$ = $2; 467 $$ = $2; 591 } 468 } 592 ; 469 ; 593 470 594 %% 471 %% 595 472 596 void yyerror(char const *s) !! 473 void print_error(char const *fmt, ...) >> 474 { >> 475 va_list va; >> 476 >> 477 va_start(va, fmt); >> 478 srcpos_verror(&yylloc, fmt, va); >> 479 va_end(va); >> 480 >> 481 treesource_error = 1; >> 482 } >> 483 >> 484 void yyerror(char const *s) { >> 485 print_error("%s", s); >> 486 } >> 487 >> 488 static unsigned long long eval_literal(const char *s, int base, int bits) 597 { 489 { 598 ERROR(&yylloc, "%s", s); !! 490 unsigned long long val; >> 491 char *e; >> 492 >> 493 errno = 0; >> 494 val = strtoull(s, &e, base); >> 495 if (*e) { >> 496 size_t uls = strspn(e, "UL"); >> 497 if (e[uls]) >> 498 print_error("bad characters in literal"); >> 499 } >> 500 if ((errno == ERANGE) >> 501 || ((bits < 64) && (val >= (1ULL << bits)))) >> 502 print_error("literal out of range"); >> 503 else if (errno != 0) >> 504 print_error("bad literal"); >> 505 return val; >> 506 } >> 507 >> 508 static unsigned char eval_char_literal(const char *s) >> 509 { >> 510 int i = 1; >> 511 char c = s[0]; >> 512 >> 513 if (c == '\0') >> 514 { >> 515 print_error("empty character literal"); >> 516 return 0; >> 517 } >> 518 >> 519 /* >> 520 * If the first character in the character literal is a \ then process >> 521 * the remaining characters as an escape encoding. If the first >> 522 * character is neither an escape or a terminator it should be the only >> 523 * character in the literal and will be returned. >> 524 */ >> 525 if (c == '\\') >> 526 c = get_escape_char(s, &i); >> 527 >> 528 if (s[i] != '\0') >> 529 print_error("malformed character literal"); >> 530 >> 531 return c; 599 } 532 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.