clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name rpc_parse.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/rpcgen/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/rpcgen/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/rpcgen/rpc_parse.c
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | #include <stdio.h> |
| 39 | #include <stdlib.h> |
| 40 | #include <string.h> |
| 41 | #include "rpc/types.h" |
| 42 | #include "rpc_scan.h" |
| 43 | #include "rpc_parse.h" |
| 44 | #include "rpc_util.h" |
| 45 | |
| 46 | #define ARGNAME "arg" |
| 47 | |
| 48 | static void isdefined(definition *); |
| 49 | static void def_struct(definition *); |
| 50 | static void def_program(definition *); |
| 51 | static void def_enum(definition *); |
| 52 | static void def_const(definition *); |
| 53 | static void def_union(definition *); |
| 54 | static void def_typedef(definition *); |
| 55 | static void get_declaration(declaration *, defkind); |
| 56 | static void get_prog_declaration(declaration *, defkind, int); |
| 57 | static void get_type(char **, char **, defkind); |
| 58 | static void unsigned_dec(char **); |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | definition * |
| 64 | get_definition(void) |
| 65 | { |
| 66 | definition *defp; |
| 67 | token tok; |
| 68 | |
| 69 | defp = malloc(sizeof(definition)); |
| 70 | get_token(&tok); |
| 71 | switch (tok.kind) { |
| 1 | Control jumps to 'case TOK_TYPEDEF:' at line 78 | |
|
| 72 | case TOK_STRUCT: |
| 73 | def_struct(defp); |
| 74 | break; |
| 75 | case TOK_UNION: |
| 76 | def_union(defp); |
| 77 | break; |
| 78 | case TOK_TYPEDEF: |
| 79 | def_typedef(defp); |
| |
| 80 | break; |
| 81 | case TOK_ENUM: |
| 82 | def_enum(defp); |
| 83 | break; |
| 84 | case TOK_PROGRAM: |
| 85 | def_program(defp); |
| 86 | break; |
| 87 | case TOK_CONST: |
| 88 | def_const(defp); |
| 89 | break; |
| 90 | case TOK_EOF: |
| 91 | free(defp); |
| 92 | return (NULL); |
| 93 | default: |
| 94 | error("definition keyword expected"); |
| 95 | } |
| 96 | scan(TOK_SEMICOLON, &tok); |
| 97 | isdefined(defp); |
| 98 | return (defp); |
| 99 | } |
| 100 | |
| 101 | static void |
| 102 | isdefined(defp) |
| 103 | definition *defp; |
| 104 | { |
| 105 | STOREVAL(&defined, defp); |
| 106 | } |
| 107 | |
| 108 | static void |
| 109 | def_struct(defp) |
| 110 | definition *defp; |
| 111 | { |
| 112 | token tok; |
| 113 | declaration dec; |
| 114 | decl_list *decls; |
| 115 | decl_list **tailp; |
| 116 | |
| 117 | defp->def_kind = DEF_STRUCT; |
| 118 | |
| 119 | scan(TOK_IDENT, &tok); |
| 120 | defp->def_name = tok.str; |
| 121 | scan(TOK_LBRACE, &tok); |
| 122 | tailp = &defp->def.st.decls; |
| 123 | do { |
| 124 | get_declaration(&dec, DEF_STRUCT); |
| 125 | decls = malloc(sizeof(decl_list)); |
| 126 | decls->decl = dec; |
| 127 | *tailp = decls; |
| 128 | tailp = &decls->next; |
| 129 | scan(TOK_SEMICOLON, &tok); |
| 130 | peek(&tok); |
| 131 | } while (tok.kind != TOK_RBRACE); |
| 132 | get_token(&tok); |
| 133 | *tailp = NULL; |
| 134 | } |
| 135 | |
| 136 | static void |
| 137 | def_program(defp) |
| 138 | definition *defp; |
| 139 | { |
| 140 | token tok; |
| 141 | declaration dec; |
| 142 | decl_list *decls; |
| 143 | decl_list **tailp; |
| 144 | version_list *vlist; |
| 145 | version_list **vtailp; |
| 146 | proc_list *plist; |
| 147 | proc_list **ptailp; |
| 148 | int num_args; |
| 149 | bool_t isvoid = FALSE; |
| 150 | defp->def_kind = DEF_PROGRAM; |
| 151 | scan(TOK_IDENT, &tok); |
| 152 | defp->def_name = tok.str; |
| 153 | scan(TOK_LBRACE, &tok); |
| 154 | vtailp = &defp->def.pr.versions; |
| 155 | tailp = &defp->def.st.decls; |
| 156 | scan(TOK_VERSION, &tok); |
| 157 | do { |
| 158 | scan(TOK_IDENT, &tok); |
| 159 | vlist = malloc(sizeof(version_list)); |
| 160 | vlist->vers_name = tok.str; |
| 161 | scan(TOK_LBRACE, &tok); |
| 162 | ptailp = &vlist->procs; |
| 163 | do { |
| 164 | |
| 165 | plist = malloc(sizeof(proc_list)); |
| 166 | get_type(&plist->res_prefix, &plist->res_type, |
| 167 | DEF_PROGRAM); |
| 168 | if (streq(plist->res_type, "opaque")) { |
| 169 | error("illegal result type"); |
| 170 | } |
| 171 | scan(TOK_IDENT, &tok); |
| 172 | plist->proc_name = tok.str; |
| 173 | scan(TOK_LPAREN, &tok); |
| 174 | |
| 175 | num_args = 1; |
| 176 | isvoid = FALSE; |
| 177 | |
| 178 | |
| 179 | |
| 180 | |
| 181 | get_prog_declaration(&dec, DEF_PROGRAM, num_args); |
| 182 | if (streq(dec.type, "void")) |
| 183 | isvoid = TRUE; |
| 184 | decls = malloc(sizeof(decl_list)); |
| 185 | plist->args.decls = decls; |
| 186 | decls->decl = dec; |
| 187 | tailp = &decls->next; |
| 188 | |
| 189 | while (peekscan(TOK_COMMA, &tok)) { |
| 190 | num_args++; |
| 191 | get_prog_declaration(&dec, DEF_STRUCT, |
| 192 | num_args); |
| 193 | decls = malloc(sizeof(decl_list)); |
| 194 | decls->decl = dec; |
| 195 | *tailp = decls; |
| 196 | if (streq(dec.type, "void")) |
| 197 | isvoid = TRUE; |
| 198 | tailp = &decls->next; |
| 199 | } |
| 200 | |
| 201 | if (!newstyle && num_args > 1) { |
| 202 | error("only one argument is allowed"); |
| 203 | } |
| 204 | if (isvoid && num_args > 1) { |
| 205 | error("illegal use of void in program definition"); |
| 206 | } |
| 207 | *tailp = NULL; |
| 208 | scan(TOK_RPAREN, &tok); |
| 209 | scan(TOK_EQUAL, &tok); |
| 210 | scan_num(&tok); |
| 211 | scan(TOK_SEMICOLON, &tok); |
| 212 | plist->proc_num = tok.str; |
| 213 | plist->arg_num = num_args; |
| 214 | *ptailp = plist; |
| 215 | ptailp = &plist->next; |
| 216 | peek(&tok); |
| 217 | } while (tok.kind != TOK_RBRACE); |
| 218 | *ptailp = NULL; |
| 219 | *vtailp = vlist; |
| 220 | vtailp = &vlist->next; |
| 221 | scan(TOK_RBRACE, &tok); |
| 222 | scan(TOK_EQUAL, &tok); |
| 223 | scan_num(&tok); |
| 224 | vlist->vers_num = tok.str; |
| 225 | |
| 226 | for (plist = vlist->procs; plist != NULL; |
| 227 | plist = plist->next) { |
| 228 | plist->args.argname = make_argname(plist->proc_name, |
| 229 | vlist->vers_num); |
| 230 | |
| 231 | } |
| 232 | scan(TOK_SEMICOLON, &tok); |
| 233 | scan2(TOK_VERSION, TOK_RBRACE, &tok); |
| 234 | } while (tok.kind == TOK_VERSION); |
| 235 | scan(TOK_EQUAL, &tok); |
| 236 | scan_num(&tok); |
| 237 | defp->def.pr.prog_num = tok.str; |
| 238 | *vtailp = NULL; |
| 239 | } |
| 240 | |
| 241 | |
| 242 | static void |
| 243 | def_enum(defp) |
| 244 | definition *defp; |
| 245 | { |
| 246 | token tok; |
| 247 | enumval_list *elist; |
| 248 | enumval_list **tailp; |
| 249 | |
| 250 | defp->def_kind = DEF_ENUM; |
| 251 | scan(TOK_IDENT, &tok); |
| 252 | defp->def_name = tok.str; |
| 253 | scan(TOK_LBRACE, &tok); |
| 254 | tailp = &defp->def.en.vals; |
| 255 | do { |
| 256 | scan(TOK_IDENT, &tok); |
| 257 | elist = malloc(sizeof(enumval_list)); |
| 258 | elist->name = tok.str; |
| 259 | elist->assignment = NULL; |
| 260 | scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok); |
| 261 | if (tok.kind == TOK_EQUAL) { |
| 262 | scan_num(&tok); |
| 263 | elist->assignment = tok.str; |
| 264 | scan2(TOK_COMMA, TOK_RBRACE, &tok); |
| 265 | } |
| 266 | *tailp = elist; |
| 267 | tailp = &elist->next; |
| 268 | } while (tok.kind != TOK_RBRACE); |
| 269 | *tailp = NULL; |
| 270 | } |
| 271 | |
| 272 | static void |
| 273 | def_const(defp) |
| 274 | definition *defp; |
| 275 | { |
| 276 | token tok; |
| 277 | |
| 278 | defp->def_kind = DEF_CONST; |
| 279 | scan(TOK_IDENT, &tok); |
| 280 | defp->def_name = tok.str; |
| 281 | scan(TOK_EQUAL, &tok); |
| 282 | scan2(TOK_IDENT, TOK_STRCONST, &tok); |
| 283 | defp->def.co = tok.str; |
| 284 | } |
| 285 | |
| 286 | static void |
| 287 | def_union(defp) |
| 288 | definition *defp; |
| 289 | { |
| 290 | token tok; |
| 291 | declaration dec; |
| 292 | case_list *cases; |
| 293 | case_list **tailp; |
| 294 | int flag; |
| 295 | |
| 296 | defp->def_kind = DEF_UNION; |
| 297 | scan(TOK_IDENT, &tok); |
| 298 | defp->def_name = tok.str; |
| 299 | scan(TOK_SWITCH, &tok); |
| 300 | scan(TOK_LPAREN, &tok); |
| 301 | get_declaration(&dec, DEF_UNION); |
| 302 | defp->def.un.enum_decl = dec; |
| 303 | tailp = &defp->def.un.cases; |
| 304 | scan(TOK_RPAREN, &tok); |
| 305 | scan(TOK_LBRACE, &tok); |
| 306 | scan(TOK_CASE, &tok); |
| 307 | while (tok.kind == TOK_CASE) { |
| 308 | scan2(TOK_IDENT, TOK_CHARCONST, &tok); |
| 309 | cases = malloc(sizeof(case_list)); |
| 310 | cases->case_name = tok.str; |
| 311 | scan(TOK_COLON, &tok); |
| 312 | |
| 313 | flag=0; |
| 314 | if (peekscan(TOK_CASE,&tok)) { |
| 315 | do { |
| 316 | scan2(TOK_IDENT, TOK_CHARCONST, &tok); |
| 317 | cases->contflag=1; |
| 318 | *tailp = cases; |
| 319 | tailp = &cases->next; |
| 320 | cases = malloc(sizeof(case_list)); |
| 321 | cases->case_name = tok.str; |
| 322 | scan(TOK_COLON, &tok); |
| 323 | } while (peekscan(TOK_CASE,&tok)); |
| 324 | } else if (flag) { |
| 325 | *tailp = cases; |
| 326 | tailp = &cases->next; |
| 327 | cases = malloc(sizeof(case_list)); |
| 328 | } |
| 329 | get_declaration(&dec, DEF_UNION); |
| 330 | cases->case_decl = dec; |
| 331 | cases->contflag=0; |
| 332 | *tailp = cases; |
| 333 | tailp = &cases->next; |
| 334 | scan(TOK_SEMICOLON, &tok); |
| 335 | |
| 336 | scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok); |
| 337 | } |
| 338 | *tailp = NULL; |
| 339 | |
| 340 | if (tok.kind == TOK_DEFAULT) { |
| 341 | scan(TOK_COLON, &tok); |
| 342 | get_declaration(&dec, DEF_UNION); |
| 343 | defp->def.un.default_decl = malloc(sizeof(declaration)); |
| 344 | *defp->def.un.default_decl = dec; |
| 345 | scan(TOK_SEMICOLON, &tok); |
| 346 | scan(TOK_RBRACE, &tok); |
| 347 | } else { |
| 348 | defp->def.un.default_decl = NULL; |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | static char *reserved_words[] = { |
| 353 | "array", |
| 354 | "bytes", |
| 355 | "destroy", |
| 356 | "free", |
| 357 | "getpos", |
| 358 | "inline", |
| 359 | "pointer", |
| 360 | "reference", |
| 361 | "setpos", |
| 362 | "sizeof", |
| 363 | "union", |
| 364 | "vector", |
| 365 | NULL |
| 366 | }; |
| 367 | |
| 368 | static char *reserved_types[] = { |
| 369 | "opaque", |
| 370 | "string", |
| 371 | NULL |
| 372 | }; |
| 373 | |
| 374 | |
| 375 | |
| 376 | static void |
| 377 | check_type_name(char *name, int new_type) |
| 378 | { |
| 379 | int i; |
| 380 | char tmp[100]; |
| 381 | |
| 382 | for (i = 0; reserved_words[i] != NULL; i++) { |
| 383 | if (strcmp(name, reserved_words[i]) == 0) { |
| 384 | snprintf(tmp, sizeof tmp, |
| 385 | "illegal (reserved) name :\'%s\' in type definition", name); |
| 386 | error(tmp); |
| 387 | } |
| 388 | } |
| 389 | if (new_type) { |
| 390 | for (i = 0; reserved_types[i] != NULL; i++) { |
| 391 | if (strcmp(name, reserved_types[i]) == 0) { |
| 392 | snprintf(tmp, sizeof tmp, |
| 393 | "illegal (reserved) name :\'%s\' in" |
| 394 | " type definition", name); |
| 395 | error(tmp); |
| 396 | } |
| 397 | } |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | static void |
| 402 | def_typedef(defp) |
| 403 | definition *defp; |
| 404 | { |
| 405 | declaration dec; |
| 406 | |
| 407 | defp->def_kind = DEF_TYPEDEF; |
| 408 | get_declaration(&dec, DEF_TYPEDEF); |
| 3 | | Calling 'get_declaration' | |
|
| 17 | | Returning from 'get_declaration' | |
|
| 409 | defp->def_name = dec.name; |
| 410 | check_type_name(dec.name, 1); |
| 411 | defp->def.ty.old_prefix = dec.prefix; |
| 412 | defp->def.ty.old_type = dec.type; |
| 413 | defp->def.ty.rel = dec.rel; |
| 414 | defp->def.ty.array_max = dec.array_max; |
| 18 | | Assigned value is garbage or undefined |
|
| 415 | } |
| 416 | |
| 417 | static void |
| 418 | get_declaration(dec, dkind) |
| 419 | declaration *dec; |
| 420 | defkind dkind; |
| 421 | { |
| 422 | token tok; |
| 423 | |
| 424 | get_type(&dec->prefix, &dec->type, dkind); |
| 425 | dec->rel = REL_ALIAS; |
| 426 | if (streq(dec->type, "void")) { |
| 4 | | Assuming the condition is false | |
|
| |
| 427 | return; |
| 428 | } |
| 429 | |
| 430 | check_type_name(dec->type, 0); |
| 431 | |
| 432 | scan2(TOK_STAR, TOK_IDENT, &tok); |
| 433 | if (tok.kind == TOK_STAR) { |
| 6 | | Assuming field 'kind' is not equal to TOK_STAR | |
|
| |
| 434 | dec->rel = REL_POINTER; |
| 435 | scan(TOK_IDENT, &tok); |
| 436 | } |
| 437 | dec->name = tok.str; |
| 438 | if (peekscan(TOK_LBRACKET, &tok)) { |
| 8 | | Assuming the condition is false | |
|
| |
| 439 | if (dec->rel == REL_POINTER) { |
| 440 | error("no array-of-pointer declarations -- use typedef"); |
| 441 | } |
| 442 | dec->rel = REL_VECTOR; |
| 443 | scan_num(&tok); |
| 444 | dec->array_max = tok.str; |
| 445 | scan(TOK_RBRACKET, &tok); |
| 446 | } else if (peekscan(TOK_LANGLE, &tok)) { |
| 10 | | Assuming the condition is false | |
|
| |
| 447 | if (dec->rel == REL_POINTER) { |
| 448 | error("no array-of-pointer declarations -- use typedef"); |
| 449 | } |
| 450 | dec->rel = REL_ARRAY; |
| 451 | if (peekscan(TOK_RANGLE, &tok)) { |
| 452 | dec->array_max = "~0"; |
| 453 | } else { |
| 454 | scan_num(&tok); |
| 455 | dec->array_max = tok.str; |
| 456 | scan(TOK_RANGLE, &tok); |
| 457 | } |
| 458 | } |
| 459 | if (streq(dec->type, "opaque")) { |
| 12 | | Assuming the condition is false | |
|
| |
| 460 | if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) { |
| 461 | error("array declaration expected"); |
| 462 | } |
| 463 | } else if (streq(dec->type, "string")) { |
| 14 | | Assuming the condition is false | |
|
| |
| 464 | if (dec->rel != REL_ARRAY) { |
| 465 | error("variable-length array declaration expected"); |
| 466 | } |
| 467 | } |
| 468 | } |
| 16 | | Returning without writing to 'dec->array_max' | |
|
| 469 | |
| 470 | static void |
| 471 | get_prog_declaration(dec, dkind, num) |
| 472 | declaration *dec; |
| 473 | defkind dkind; |
| 474 | int num; |
| 475 | { |
| 476 | token tok; |
| 477 | |
| 478 | if (dkind == DEF_PROGRAM) { |
| 479 | peek(&tok); |
| 480 | if (tok.kind == TOK_RPAREN) { |
| 481 | dec->rel = REL_ALIAS; |
| 482 | dec->type = "void"; |
| 483 | dec->prefix = NULL; |
| 484 | dec->name = NULL; |
| 485 | return; |
| 486 | } |
| 487 | } |
| 488 | get_type(&dec->prefix, &dec->type, dkind); |
| 489 | dec->rel = REL_ALIAS; |
| 490 | if (peekscan(TOK_IDENT, &tok)) { |
| 491 | dec->name = (char *)strdup(tok.str); |
| 492 | if (dec->name == NULL) |
| 493 | error("out of memory"); |
| 494 | } else { |
| 495 | |
| 496 | if (asprintf(&dec->name, "%s%d", ARGNAME, num) == -1) |
| 497 | error("out of memory"); |
| 498 | } |
| 499 | |
| 500 | if (streq(dec->type, "void")) |
| 501 | return; |
| 502 | |
| 503 | if (streq(dec->type, "opaque")) |
| 504 | error("opaque -- illegal argument type"); |
| 505 | |
| 506 | if (peekscan(TOK_STAR, &tok)) { |
| 507 | if (streq(dec->type, "string")) |
| 508 | error("pointer to string not allowed in program arguments\n"); |
| 509 | |
| 510 | dec->rel = REL_POINTER; |
| 511 | if (peekscan(TOK_IDENT, &tok)) { |
| 512 | dec->name = (char *)strdup(tok.str); |
| 513 | if (dec->name == NULL) |
| 514 | error("out of memory"); |
| 515 | } |
| 516 | } |
| 517 | if (peekscan(TOK_LANGLE, &tok)) { |
| 518 | if (!streq(dec->type, "string")) |
| 519 | error("arrays cannot be declared as arguments to " |
| 520 | "procedures -- use typedef"); |
| 521 | dec->rel = REL_ARRAY; |
| 522 | if (peekscan(TOK_RANGLE, &tok)) { |
| 523 | dec->array_max = "~0"; |
| 524 | } else { |
| 525 | scan_num(&tok); |
| 526 | dec->array_max = tok.str; |
| 527 | scan(TOK_RANGLE, &tok); |
| 528 | } |
| 529 | } |
| 530 | if (streq(dec->type, "string")) { |
| 531 | |
| 532 | |
| 533 | |
| 534 | |
| 535 | if (dec->rel != REL_ARRAY) { |
| 536 | dec->rel = REL_ARRAY; |
| 537 | dec->array_max = "~0"; |
| 538 | } |
| 539 | } |
| 540 | } |
| 541 | |
| 542 | static void |
| 543 | get_type(prefixp, typep, dkind) |
| 544 | char **prefixp; |
| 545 | char **typep; |
| 546 | defkind dkind; |
| 547 | { |
| 548 | token tok; |
| 549 | |
| 550 | *prefixp = NULL; |
| 551 | get_token(&tok); |
| 552 | switch (tok.kind) { |
| 553 | case TOK_IDENT: |
| 554 | *typep = tok.str; |
| 555 | break; |
| 556 | case TOK_STRUCT: |
| 557 | case TOK_ENUM: |
| 558 | case TOK_UNION: |
| 559 | *prefixp = tok.str; |
| 560 | scan(TOK_IDENT, &tok); |
| 561 | *typep = tok.str; |
| 562 | break; |
| 563 | case TOK_UNSIGNED: |
| 564 | unsigned_dec(typep); |
| 565 | break; |
| 566 | case TOK_SHORT: |
| 567 | *typep = "short"; |
| 568 | (void) peekscan(TOK_INT, &tok); |
| 569 | break; |
| 570 | case TOK_LONG: |
| 571 | *typep = "long"; |
| 572 | (void) peekscan(TOK_INT, &tok); |
| 573 | break; |
| 574 | case TOK_HYPER: |
| 575 | *typep = "int64_t"; |
| 576 | (void) peekscan(TOK_INT, &tok); |
| 577 | break; |
| 578 | case TOK_VOID: |
| 579 | if (dkind != DEF_UNION && dkind != DEF_PROGRAM) { |
| 580 | error("voids allowed only inside union and program definitions with one argument"); |
| 581 | } |
| 582 | *typep = tok.str; |
| 583 | break; |
| 584 | case TOK_STRING: |
| 585 | case TOK_OPAQUE: |
| 586 | case TOK_CHAR: |
| 587 | case TOK_INT: |
| 588 | case TOK_FLOAT: |
| 589 | case TOK_DOUBLE: |
| 590 | case TOK_QUAD: |
| 591 | case TOK_BOOL: |
| 592 | *typep = tok.str; |
| 593 | break; |
| 594 | default: |
| 595 | error("expected type specifier"); |
| 596 | } |
| 597 | } |
| 598 | |
| 599 | static void |
| 600 | unsigned_dec(typep) |
| 601 | char **typep; |
| 602 | { |
| 603 | token tok; |
| 604 | |
| 605 | peek(&tok); |
| 606 | switch (tok.kind) { |
| 607 | case TOK_CHAR: |
| 608 | get_token(&tok); |
| 609 | *typep = "u_char"; |
| 610 | break; |
| 611 | case TOK_SHORT: |
| 612 | get_token(&tok); |
| 613 | *typep = "u_short"; |
| 614 | (void) peekscan(TOK_INT, &tok); |
| 615 | break; |
| 616 | case TOK_LONG: |
| 617 | get_token(&tok); |
| 618 | *typep = "u_long"; |
| 619 | (void) peekscan(TOK_INT, &tok); |
| 620 | break; |
| 621 | case TOK_HYPER: |
| 622 | get_token(&tok); |
| 623 | *typep = "u_int64_t"; |
| 624 | (void) peekscan(TOK_INT, &tok); |
| 625 | break; |
| 626 | case TOK_INT: |
| 627 | get_token(&tok); |
| 628 | *typep = "u_int"; |
| 629 | break; |
| 630 | default: |
| 631 | *typep = "u_int"; |
| 632 | break; |
| 633 | } |
| 634 | } |