PulkoMandy | 17fc759 | 2022-07-28 18:27:54 +0200 | [diff] [blame^] | 1 | /* TODO: |
| 2 | |
| 3 | ---- HIGHEST PRIORITY ---- |
| 4 | |
| 5 | * #ifndef |
| 6 | |
| 7 | * #if/#elif - Bearbeitung |
| 8 | |
| 9 | * leere argument-/tokenlists erlauben |
| 10 | |
| 11 | * Anzahl der Argumente checken (auch zuviele ergeben einen Error) |
| 12 | |
| 13 | * bei REDEFINING und allowredefinition=0 tokenlist genau ueberpruefen |
| 14 | |
| 15 | * Aufteilen in mehrere Sourcen main.c pplists.c etc. |
| 16 | * Einige Variablen umbenennen (x,y,i,j,l,n etc =8) |
| 17 | |
| 18 | ----------------------------------------------------------------- |
| 19 | |
| 20 | * Verbesserungen: |
| 21 | * - Nach malloc()/vor free() ueberpruefen ob NULL-Pointer |
| 22 | * - Statt per dlen per Ptr2EOL abfragen.. |
| 23 | |
| 24 | * Fragen an Volker: |
| 25 | * - _ alleine ein Identifier ? Ja |
| 26 | |
| 27 | ---- LOWEST PRIORITY ---- |
| 28 | |
| 29 | * - Token loeschen, wenn nur noch TokenList benutzt wird. |
| 30 | |
| 31 | * - ParseIdent.. optimieren |
| 32 | |
| 33 | * - Rest optimieren =8) |
| 34 | |
| 35 | * - PreParsing umschreiben.. __LINE__ muss mit der echten |
| 36 | * Zeilennummer uebereinstimmen (die LFs drinlassen) |
| 37 | */ |
| 38 | |
| 39 | /* |
| 40 | * PreProcessor |
| 41 | * $VER: VBPP V0.00 (19 Sep 1995) |
| 42 | * (w) 1995 by Thorsten Schaaps |
| 43 | */ |
| 44 | |
| 45 | #include <time.h> |
| 46 | |
| 47 | #include "vbc.h" |
| 48 | #include "vbpp.h" |
| 49 | |
| 50 | /*vb: */ |
| 51 | static char FILE_[]=__FILE__; |
| 52 | |
| 53 | /*vb: */ |
| 54 | char pp_version[] = "vbpp V0.00 (w) 1995 by Thorsten Schaaps"; |
| 55 | |
| 56 | /* #define MAXIFNESTING 1024 *//*vb: ifnesting==incnesting */ |
| 57 | |
| 58 | FILE *in[MAXINCNESTING]; /* Sourcefiles */ |
| 59 | int zn[MAXINCNESTING]; /* Zeilennummern */ |
| 60 | char *filenames[MAXINCNESTING]; /* Filenamen */ |
| 61 | int incnesting; /* aktuelle Verschachtelungstiefe */ |
| 62 | unsigned long linenr; /* Zeilennummer */ |
| 63 | |
| 64 | char *incpath[MAXINCPATHS] = |
| 65 | {"vinclude:"}; /* Includepfade */ |
| 66 | |
| 67 | int incpathc = 1; /* Anzahl der Includepfade */ |
| 68 | |
| 69 | char ppstring[MAXPPINPUT]; |
| 70 | |
| 71 | int cmtnesting = 0; /* aktuelle Kommentar-Versch.-Tiefe */ |
| 72 | |
| 73 | /*int ifnesting; *//*vb: *//* aktuelle IF-Tiefe */ |
| 74 | /*vb: ifnesting==incnesting */ |
| 75 | short ifstatus[MAXINCNESTING]; /* Array fuer Status-Verschachtelung */ |
| 76 | int if_cnt; /* Zaehler fuer #if's waehrend do_output=0 */ |
| 77 | int abs_if_cnt; /* zaehlt auch waehrend do_output */ |
| 78 | |
| 79 | int do_output = 1; /* Flag zur Erzeugung eines Outputs */ |
| 80 | |
| 81 | struct strnode *strlist; |
| 82 | |
| 83 | struct mnode *mlist; |
| 84 | |
| 85 | int did_expand; |
| 86 | |
| 87 | /* Temporaere Debugging-Routinen */ |
| 88 | void PrintSN(struct strnode *tl) |
| 89 | { |
| 90 | switch (tl->type) { |
| 91 | case NORMAL: |
| 92 | printf(" Normal........:"); |
| 93 | break; |
| 94 | case PP_IDENT: |
| 95 | printf(" Identifier....:"); |
| 96 | break; |
| 97 | case ARGUMENT: |
| 98 | printf(" Argument Nr.%2d:", tl->number); |
| 99 | break; |
| 100 | case NUMBER: |
| 101 | printf(" Number........:"); |
| 102 | break; |
| 103 | case PP_STR: |
| 104 | printf(" String........:"); |
| 105 | break; |
| 106 | case SPACE: |
| 107 | printf(" Space.........:"); |
| 108 | break; |
| 109 | case SPECIAL: |
| 110 | printf(" Special..Nr.%2d:", tl->flags); |
| 111 | break; |
| 112 | default: |
| 113 | printf(" unknown..Nr.%2d:", tl->type); |
| 114 | break; |
| 115 | } |
| 116 | printf(" %s\n", tl->str); |
| 117 | } |
| 118 | void PrintTL(struct strnode *tl) |
| 119 | { |
| 120 | |
| 121 | #ifdef bla |
| 122 | |
| 123 | if (tl) { |
| 124 | printf("TokenList:\n"); |
| 125 | while (tl) { |
| 126 | PrintSN(tl); |
| 127 | tl = tl->next; |
| 128 | } |
| 129 | } |
| 130 | #endif |
| 131 | |
| 132 | } |
| 133 | |
| 134 | |
| 135 | /* ******* Listen-Funktionen ******* */ |
| 136 | |
| 137 | /* AddMakroNode - Fuegt eine Node an den Anfang einer Liste ein */ |
| 138 | void AddMakroNode(struct mnode **list, struct mnode *node) |
| 139 | { |
| 140 | |
| 141 | if (DEBUG & 32) |
| 142 | puts("AddMakroNode"); |
| 143 | |
| 144 | if (node) { |
| 145 | node->prev = NULL; |
| 146 | node->next = *list; |
| 147 | *list = node; |
| 148 | if (node->next) |
| 149 | node->next->prev = node; |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | |
| 154 | /* AddStrNode - Fuegt eine Node in die Liste ein */ |
| 155 | void AddStrNode(struct strnode **list, struct strnode *node, char *str) |
| 156 | { |
| 157 | |
| 158 | if (DEBUG & 32) |
| 159 | puts("AddStrNode"); |
| 160 | |
| 161 | |
| 162 | if (node || str) { |
| 163 | if (!node) |
| 164 | node = (struct strnode *) malloc(sizeof(struct strnode)); |
| 165 | /* HIER: Rueckgabewert wegen Fehler ! */ |
| 166 | if (!node) { |
| 167 | error(196); |
| 168 | } else { |
| 169 | node->prev = NULL; |
| 170 | node->next = *list; |
| 171 | if (str) |
| 172 | node->str = str; |
| 173 | *list = node; |
| 174 | if (node->next) |
| 175 | node->next->prev = node; |
| 176 | } |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | |
| 181 | /* AddStrNodeBehind - Fuegt eine Node ans Ende der Liste ein */ |
| 182 | void AddStrNodeBehind(struct strnode **list, struct strnode *node, char *str) |
| 183 | { |
| 184 | struct strnode *listnode; |
| 185 | |
| 186 | if (DEBUG & 32) |
| 187 | puts("AddStrNodeBehind"); |
| 188 | |
| 189 | |
| 190 | if (node || str) { |
| 191 | if (!node) |
| 192 | node = (struct strnode *) malloc(sizeof(struct strnode)); |
| 193 | if (!node) { |
| 194 | error(196); |
| 195 | } else { |
| 196 | if (!*list) { |
| 197 | node->prev = NULL; |
| 198 | node->next = NULL; |
| 199 | *list = node; |
| 200 | } else { |
| 201 | listnode = *list; |
| 202 | while (listnode->next) { |
| 203 | listnode = listnode->next; |
| 204 | } |
| 205 | node->prev = listnode; |
| 206 | node->next = NULL; |
| 207 | listnode->next = node; |
| 208 | } |
| 209 | if (str) |
| 210 | node->str = str; |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | |
| 216 | /* RemMakroNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */ |
| 217 | void RemMakroNode(struct mnode **list, struct mnode *node) |
| 218 | { |
| 219 | |
| 220 | if (DEBUG & 32) |
| 221 | puts("RemMakroNode"); |
| 222 | |
| 223 | |
| 224 | if (node->prev) { |
| 225 | if (node->next) |
| 226 | node->next->prev = node->prev; |
| 227 | node->prev->next = node->next; |
| 228 | } else { |
| 229 | if (node->next) |
| 230 | node->next->prev = NULL; |
| 231 | *list = node->next; |
| 232 | } |
| 233 | node->next = node->prev = NULL; |
| 234 | } |
| 235 | |
| 236 | /* InsertMakroNode - Setzt eine Node hinter einer anderen ein */ |
| 237 | void InsertMakroNode(struct mnode **list, struct mnode *node, struct mnode *behind) |
| 238 | { |
| 239 | |
| 240 | if (DEBUG & 32) |
| 241 | puts("InsertMakroNode"); |
| 242 | |
| 243 | |
| 244 | if (behind) { |
| 245 | node->prev = behind; |
| 246 | node->next = behind->next; |
| 247 | behind->next = node; |
| 248 | if (node->next) |
| 249 | node->next->prev = node; |
| 250 | } else |
| 251 | AddMakroNode(list, node); |
| 252 | } |
| 253 | |
| 254 | /* RemStrNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */ |
| 255 | void RemStrNode(struct strnode **list, struct strnode *node) |
| 256 | { |
| 257 | |
| 258 | if (DEBUG & 32) |
| 259 | puts("RemStrNode"); |
| 260 | |
| 261 | |
| 262 | if (node->prev) { |
| 263 | if (node->next) |
| 264 | node->next->prev = node->prev; |
| 265 | node->prev->next = node->next; |
| 266 | } else { |
| 267 | if (node->next) |
| 268 | node->next->prev = NULL; |
| 269 | *list = node->next; |
| 270 | } |
| 271 | node->next = node->prev = NULL; |
| 272 | } |
| 273 | |
| 274 | |
| 275 | /* FindMakroNode - sucht den passenden Eintrag in der Liste |
| 276 | * len=0 - der gesamte String muss uebereinstimmen |
| 277 | * len>0 - die ersten len Zeichen muessen stimmen |
| 278 | */ |
| 279 | struct mnode *FindMakroNode(struct mnode *list, char *str, int len) |
| 280 | { |
| 281 | |
| 282 | if (DEBUG & 32) |
| 283 | puts("FindMakroNode"); |
| 284 | |
| 285 | while (list) { |
| 286 | if (len) { |
| 287 | if ((strlen(list->name) == len) && (!strncmp(list->name, str, len))) |
| 288 | return (list); |
| 289 | } else { |
| 290 | if (!strcmp(list->name, str)) |
| 291 | return (list); |
| 292 | } |
| 293 | list = list->next; |
| 294 | } |
| 295 | return (0); |
| 296 | } |
| 297 | |
| 298 | |
| 299 | /* DelMakroNode - gibt den gesamten Speicher einer Node frei, ist list#NULL |
| 300 | * wird die Node vorher aus der Liste entfernt |
| 301 | */ |
| 302 | void DelMakroNode(struct mnode **list, struct mnode *node) |
| 303 | { |
| 304 | |
| 305 | if (DEBUG & 32) |
| 306 | puts("DelMakroNode"); |
| 307 | |
| 308 | |
| 309 | if (node) { |
| 310 | if (list && *list) |
| 311 | RemMakroNode(list, node); |
| 312 | if (node->name) |
| 313 | free(node->name); |
| 314 | if (node->args) |
| 315 | free(node->args); |
| 316 | if (node->token) |
| 317 | free(node->token); |
| 318 | if (node->tokenlist) |
| 319 | DelStrList(&node->tokenlist); |
| 320 | free(node); |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | |
| 325 | /* DelStrNode - gibt den gesamten Speicher einer Node frei, ist list#NULL |
| 326 | * wird die Node vorher aus der Liste entfernt |
| 327 | */ |
| 328 | void DelStrNode(struct strnode **list, struct strnode *node) |
| 329 | { |
| 330 | |
| 331 | if (DEBUG & 32) |
| 332 | puts("DelStrNode"); |
| 333 | |
| 334 | |
| 335 | if (node) { |
| 336 | if (list && *list) |
| 337 | RemStrNode(list, node); |
| 338 | if (node->str) |
| 339 | free(node->str); |
| 340 | free(node); |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | void MergeStrNodes(struct strnode *prev, struct strnode *next) |
| 345 | { |
| 346 | /* next will now be deleted and prev->str will be */ |
| 347 | /* the joined strings from prev&next */ |
| 348 | char *newstr; |
| 349 | /*vb: */ |
| 350 | char c, *s, *d; |
| 351 | |
| 352 | if (DEBUG & 32) |
| 353 | puts("MergeStrNodes"); |
| 354 | |
| 355 | |
| 356 | newstr = (char *) malloc(prev->len + next->len + 1); |
| 357 | /*vb: string-Routinen ersetzt (hoffentlich schneller) |
| 358 | strcpy(newstr,prev->str); |
| 359 | strcat(newstr,next->str); |
| 360 | */ |
| 361 | d = newstr; |
| 362 | s = prev->str; |
| 363 | do { |
| 364 | c = *s++; |
| 365 | *d++ = c; |
| 366 | } while (c); |
| 367 | d--; |
| 368 | s = next->str; |
| 369 | do { |
| 370 | c = *s++; |
| 371 | *d++ = c; |
| 372 | } while (c); |
| 373 | |
| 374 | if (prev->str) |
| 375 | free(prev->str); /*vb: wenn prev->str==0 knallts doch schon oben? */ |
| 376 | prev->str = newstr; |
| 377 | prev->len += next->len; |
| 378 | DelStrNode(NULL, next); |
| 379 | } |
| 380 | |
| 381 | /* DelMakroList - loescht eine gesamte Liste */ |
| 382 | void DelMakroList(struct mnode **list) |
| 383 | { |
| 384 | |
| 385 | if (DEBUG & 32) |
| 386 | puts("DelMakroList"); |
| 387 | |
| 388 | |
| 389 | while (*list) |
| 390 | DelMakroNode(list, *list); |
| 391 | /* *list=NULL; *//*vb: *list==0 */ |
| 392 | } |
| 393 | |
| 394 | |
| 395 | /* DelStrList - loescht eine gesamte Liste samt der Nodes/Strings */ |
| 396 | void DelStrList(struct strnode **list) |
| 397 | { |
| 398 | |
| 399 | if (DEBUG & 32) |
| 400 | puts("DelStrList"); |
| 401 | |
| 402 | |
| 403 | while (*list) |
| 404 | DelStrNode(list, *list); |
| 405 | /* *list=NULL; *//*vb: *list==0 */ |
| 406 | } |
| 407 | |
| 408 | /* AllocSpace - erzeugt eine StrNode vom Typ Space */ |
| 409 | struct strnode *AllocSpace() |
| 410 | { |
| 411 | struct strnode *newnode; |
| 412 | char *newstr; |
| 413 | |
| 414 | |
| 415 | if (DEBUG & 32) |
| 416 | puts("AllocSpace"); |
| 417 | |
| 418 | |
| 419 | newstr = (char *) malloc(2); |
| 420 | if (newstr) { |
| 421 | newstr[0] = ' '; |
| 422 | newstr[1] = 0; |
| 423 | newnode = (struct strnode *) malloc(sizeof(struct strnode)); |
| 424 | if (newnode) { |
| 425 | newnode->str = newstr; |
| 426 | newnode->type = SPACE; |
| 427 | newnode->len = 1; |
| 428 | newnode->next = newnode->prev = NULL; |
| 429 | newnode->flags = newnode->number = 0; |
| 430 | return (newnode); |
| 431 | } |
| 432 | } |
| 433 | return (NULL); |
| 434 | } |
| 435 | |
| 436 | |
| 437 | /* CloneStrList - erstellt eine exakte Kopie der Liste oder eines Ausschnittes */ |
| 438 | /* wenn listend#NULL */ |
| 439 | struct strnode *CloneStrList(struct strnode *list, struct strnode *listend) |
| 440 | { |
| 441 | struct strnode *prevnode = NULL, *newnode, *newlist = NULL; |
| 442 | char *newstr; |
| 443 | |
| 444 | if (DEBUG & 32) |
| 445 | puts("CloneStrList"); |
| 446 | |
| 447 | |
| 448 | while (list) { |
| 449 | newnode = (struct strnode *) malloc(sizeof(struct strnode)); |
| 450 | if (!newnode) { |
| 451 | DelStrList(&newlist); |
| 452 | return (NULL); |
| 453 | } |
| 454 | newstr = (char *) malloc(list->len + 1); |
| 455 | if (!newstr) { |
| 456 | free(newnode); |
| 457 | DelStrList(&newlist); |
| 458 | return (NULL); |
| 459 | } |
| 460 | strcpy(newstr, list->str); |
| 461 | newnode->str = newstr; |
| 462 | newnode->len = list->len; |
| 463 | newnode->flags = list->flags; |
| 464 | newnode->type = list->type; |
| 465 | newnode->number = list->number; |
| 466 | newnode->next = NULL; |
| 467 | newnode->prev = prevnode; |
| 468 | |
| 469 | if (prevnode) |
| 470 | prevnode->next = newnode; |
| 471 | else |
| 472 | newlist = newnode; |
| 473 | prevnode = newnode; |
| 474 | |
| 475 | if (listend && list == listend) |
| 476 | list = NULL; |
| 477 | else |
| 478 | list = list->next; |
| 479 | } |
| 480 | return (newlist); |
| 481 | } |
| 482 | |
| 483 | |
| 484 | /* DoMakroFunction - erstellt eine StrList entsprechend des Function-Makros */ |
| 485 | struct strnode *DoMakroFunction(struct mnode *makro) |
| 486 | { |
| 487 | struct strnode *result = NULL; |
| 488 | char *newstr = NULL, *timestr = NULL; |
| 489 | int len, type; |
| 490 | time_t timevalue; |
| 491 | |
| 492 | if (DEBUG & 32) |
| 493 | puts("DoMakroFunction"); |
| 494 | |
| 495 | |
| 496 | if (makro->flags & FUNCTION) { |
| 497 | switch (makro->funcnum) { |
| 498 | case FUNCLINE: |
| 499 | newstr = (char *) malloc(11); |
| 500 | if (!newstr) |
| 501 | return (NULL); |
| 502 | sprintf(newstr, "%lu", linenr); |
| 503 | len = strlen(newstr); |
| 504 | type = NUMBER; |
| 505 | break; |
| 506 | case FUNCFILE: |
| 507 | len = strlen(filenames[incnesting]); |
| 508 | newstr = (char *) malloc(len + 1 + 2); |
| 509 | if (!newstr) |
| 510 | return (NULL); |
| 511 | *newstr = '\"'; |
| 512 | strcpy((newstr + 1), filenames[incnesting]); |
| 513 | strcat(newstr, "\""); |
| 514 | type = PP_STR; |
| 515 | break; |
| 516 | case FUNCDATE: |
| 517 | type = PP_STR; |
| 518 | newstr = (char *) malloc(14); |
| 519 | if (!newstr) |
| 520 | return (NULL); |
| 521 | timevalue = time(0); |
| 522 | timestr = ctime(&timevalue); |
| 523 | newstr[0] = '\"'; |
| 524 | strncpy(newstr + 1, timestr + 4, 7); /* copy 'Mmm dd ' */ |
| 525 | strcpy(newstr + 8, timestr + 20); /* copy 'yyyy' */ |
| 526 | newstr[12] = '\"'; |
| 527 | newstr[13] = 0; |
| 528 | len = 13; |
| 529 | break; |
| 530 | case FUNCTIME: |
| 531 | type = PP_STR; |
| 532 | newstr = (char *) malloc(11); |
| 533 | if (!newstr) |
| 534 | return (NULL); |
| 535 | timevalue = time(0); |
| 536 | timestr = ctime(&timevalue); |
| 537 | newstr[0] = '\"'; |
| 538 | strncpy(newstr + 1, timestr + 11, 8); /* copy 'hh:mm:ss' */ |
| 539 | newstr[9] = '\"'; |
| 540 | newstr[10] = 0; |
| 541 | len = 10; |
| 542 | break; |
| 543 | default: |
| 544 | return (NULL); |
| 545 | break; |
| 546 | } |
| 547 | result = (struct strnode *) malloc(sizeof(struct strnode)); |
| 548 | if (!result) { |
| 549 | if (newstr) |
| 550 | free(newstr); |
| 551 | return (NULL); |
| 552 | } |
| 553 | result->prev = result->next = NULL; |
| 554 | result->str = newstr; |
| 555 | result->len = len; |
| 556 | result->number = result->flags = 0; |
| 557 | result->type = type; |
| 558 | } |
| 559 | return (result); |
| 560 | } |
| 561 | |
| 562 | |
| 563 | /* ******* String-Funktionen ****** */ |
| 564 | |
| 565 | /* Str2List - parsed einen String in eine StrList */ |
| 566 | struct strnode *Str2List(char *str) |
| 567 | { |
| 568 | struct strnode *newlist = NULL, *newnode = NULL; |
| 569 | char *temp, *string; |
| 570 | int length, type, flags; |
| 571 | |
| 572 | if (DEBUG & 32) |
| 573 | puts("Str2List"); |
| 574 | |
| 575 | while (*str) { |
| 576 | flags = 0; |
| 577 | /*vb: casts eingefuegt */ |
| 578 | if (isspace((unsigned char) *str)) { /* Spaces parsen */ |
| 579 | temp = str + 1; |
| 580 | length = 1; |
| 581 | while (*temp && isspace((unsigned char) *temp)) { |
| 582 | temp++; |
| 583 | length++; |
| 584 | } |
| 585 | type = SPACE; |
| 586 | } else if (*str == '\"') { /* String parsen */ |
| 587 | temp = str + 1; |
| 588 | length = 2; |
| 589 | while (*temp && *temp != '\"') |
| 590 | if (*temp == '\\') { |
| 591 | temp += 2; |
| 592 | length += 2; |
| 593 | } else { |
| 594 | temp++; |
| 595 | length++; |
| 596 | } |
| 597 | type = PP_STR; |
| 598 | } else if (*str == '\'') { /* String parsen */ |
| 599 | temp = str + 1; |
| 600 | length = 2; |
| 601 | while (*temp && *temp != '\'') |
| 602 | if (*temp == '\\') { |
| 603 | temp += 2; |
| 604 | length += 2; |
| 605 | } else { |
| 606 | temp++; |
| 607 | length++; |
| 608 | } |
| 609 | type = PP_STR; |
| 610 | } else if (isdigit((unsigned char) *str) || (*str == '.' && isdigit((unsigned char) *(str + 1)))) { |
| 611 | /* Zahlen parsen */ |
| 612 | temp = str; |
| 613 | length = 0; |
| 614 | while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) { |
| 615 | temp++; |
| 616 | length++; |
| 617 | } |
| 618 | if (*temp == '.') { |
| 619 | temp++; |
| 620 | length++; |
| 621 | if (isdigit((unsigned char) *temp) || *temp == 'e' || *temp == 'E') |
| 622 | while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) { |
| 623 | temp++; |
| 624 | length++; |
| 625 | } |
| 626 | } |
| 627 | if (*(temp - 1) == 'e' || *(temp - 1) == 'E') |
| 628 | if (isdigit((unsigned char) *temp) || *temp == '+' || *temp == '-') { |
| 629 | temp++; |
| 630 | length++; |
| 631 | while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) { |
| 632 | temp++; |
| 633 | length++; |
| 634 | } |
| 635 | } |
| 636 | type = NUMBER; |
| 637 | } else if (isalpha((unsigned char) *str) || *str == '_') { /* moegl. Identifier parsen */ |
| 638 | temp = str + 1; |
| 639 | length = 1; |
| 640 | while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) { |
| 641 | temp++; |
| 642 | length++; |
| 643 | } |
| 644 | type = PP_IDENT; |
| 645 | } else if (*str) { /* alles andere als einzelne Zeichen */ |
| 646 | length = 1; |
| 647 | type = NORMAL; |
| 648 | } |
| 649 | string = (char *) malloc(length + 1); |
| 650 | if (!string) { |
| 651 | error(196); |
| 652 | DelStrList(&newlist); |
| 653 | return (NULL); |
| 654 | } |
| 655 | strncpy(string, str, length); |
| 656 | string[length] = 0; |
| 657 | str += length; |
| 658 | |
| 659 | newnode = (struct strnode *) malloc(sizeof(struct strnode)); |
| 660 | if (!newnode) { |
| 661 | error(196); |
| 662 | if (string) |
| 663 | free(string); |
| 664 | return (NULL); |
| 665 | } |
| 666 | newnode->str = string; |
| 667 | newnode->len = length; |
| 668 | newnode->flags = flags; |
| 669 | newnode->type = type; |
| 670 | |
| 671 | AddStrNodeBehind(&newlist, newnode, NULL); |
| 672 | } |
| 673 | return (newlist); |
| 674 | } |
| 675 | |
| 676 | /* List2Str - schreibt eine Liste als String zurueck */ |
| 677 | int List2Str(struct strnode *list, char *str, int maxchars) |
| 678 | { |
| 679 | int len = 0; |
| 680 | char c, *p; |
| 681 | |
| 682 | if (DEBUG & 32) |
| 683 | puts("List2Str"); |
| 684 | |
| 685 | |
| 686 | *str = 0; |
| 687 | if (list) { |
| 688 | while (list) { |
| 689 | if ((len + (list->len)) > (maxchars - 1)) { |
| 690 | error(177); |
| 691 | return (0); |
| 692 | } else { |
| 693 | /*vb: */ |
| 694 | p = list->str; |
| 695 | do { |
| 696 | c = *p++; |
| 697 | *str++ = c; |
| 698 | } while (c); |
| 699 | str--; |
| 700 | /* strcat(str,list->str); */ |
| 701 | len += list->len; |
| 702 | } |
| 703 | list = list->next; |
| 704 | } |
| 705 | return (len + 1); |
| 706 | } else { |
| 707 | *str = 0; |
| 708 | return (1); |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | /* ListLen - ermittelt die Laenge einer Str-Liste (in Zeichen) */ |
| 713 | int ListLen(struct strnode *list) |
| 714 | { |
| 715 | int len = 0; |
| 716 | while (list) { |
| 717 | len += list->len; |
| 718 | list = list->next; |
| 719 | } |
| 720 | return (len); |
| 721 | } |
| 722 | |
| 723 | /* ListStrLen - ermittelt die Laenge einer Str-List als String */ |
| 724 | /* d.h. mit " am Anfang und Ende, sowie einem \ vor */ |
| 725 | /* jedem \ und " */ |
| 726 | int ListStrLen(struct strnode *list) |
| 727 | { |
| 728 | int len = 2; |
| 729 | while (list) { |
| 730 | if (list->type == SPACE) |
| 731 | len++; |
| 732 | else { |
| 733 | len += list->len; |
| 734 | if (list->type == PP_STR && list->str[0] == '\"') |
| 735 | len += 2; |
| 736 | else if (list->type == NORMAL && list->str[0] == '\\') |
| 737 | len++; |
| 738 | } |
| 739 | list = list->next; |
| 740 | } |
| 741 | return (len); |
| 742 | } |
| 743 | |
| 744 | /* CopyList2StrStr - kopiert eine Str-List als String um */ |
| 745 | /* d.h. mit " am Anfang und Ende, sowie einem \ vor */ |
| 746 | /* jedem \ und " */ |
| 747 | CopyList2StrStr(struct strnode * list, char *str) |
| 748 | { |
| 749 | int len; |
| 750 | |
| 751 | if (DEBUG & 32) |
| 752 | puts("CopyList2StrStr"); |
| 753 | |
| 754 | |
| 755 | str[0] = 0; |
| 756 | if (list) { |
| 757 | strcpy(str, "\""); |
| 758 | len = 1; |
| 759 | while (list) { |
| 760 | if (list->type == SPACE) { |
| 761 | len++; |
| 762 | strcat(str, " "); |
| 763 | } else { |
| 764 | len += list->len; |
| 765 | if (list->type == PP_STR && list->str[0] == '\"') { |
| 766 | strcat(str, "\\"); |
| 767 | strncat(str, list->str, list->len - 1); |
| 768 | strcat(str, "\\\""); |
| 769 | } else if (list->type == NORMAL && list->str[0] == '\\') { |
| 770 | strcat(str, "\\"); |
| 771 | strcat(str, list->str); |
| 772 | } else |
| 773 | strcat(str, list->str); |
| 774 | } |
| 775 | list = list->next; |
| 776 | } |
| 777 | strcat(str, "\""); |
| 778 | len++; |
| 779 | } |
| 780 | return (len); |
| 781 | } |
| 782 | |
| 783 | /* NextToSpecial - checked, ob die StrNode neben einem # oder ## steht */ |
| 784 | int NextToSpecial(struct strnode *node) |
| 785 | { |
| 786 | struct strnode *search; |
| 787 | |
| 788 | if (DEBUG & 32) |
| 789 | puts("NextToSpecial"); |
| 790 | |
| 791 | |
| 792 | if (node->prev) { |
| 793 | search = node->prev; |
| 794 | while (search && search->type == SPACE) |
| 795 | search = search->prev; |
| 796 | if (search && search->type == SPECIAL) |
| 797 | return (search->flags); |
| 798 | } |
| 799 | if (node->next) { |
| 800 | search = node->next; |
| 801 | while (search && search->type == SPACE) |
| 802 | search = search->next; |
| 803 | /* Hinter der Node ist ein # (ToString) ohne Bedeutung */ |
| 804 | if (search && search->type == SPECIAL |
| 805 | && search->flags == KILLSPACES) |
| 806 | return (KILLSPACES); |
| 807 | } |
| 808 | return (NONE); |
| 809 | } |
| 810 | |
| 811 | /* FindBracket - sucht das passende Gegenstueck zu der (, auf die Node zeigt */ |
| 812 | /* dabei werden verschachtelte Klammern beachtet */ |
| 813 | struct strnode *FindBracket(struct strnode *node) |
| 814 | { |
| 815 | |
| 816 | if (DEBUG & 32) |
| 817 | puts("FindBracket"); |
| 818 | |
| 819 | |
| 820 | if (node && node->next && node->type == NORMAL && node->str[0] == '(') { |
| 821 | do { |
| 822 | node = node->next; |
| 823 | if (node && node->type == NORMAL) { |
| 824 | if (node->str[0] == ')') |
| 825 | return (node); |
| 826 | if (node->str[0] == '(') |
| 827 | node = FindBracket(node); |
| 828 | } |
| 829 | } while (node); |
| 830 | return (NULL); |
| 831 | } else |
| 832 | return (NULL); |
| 833 | } |
| 834 | |
| 835 | /* CloneArg - gibt eine Liste zurueck, die das n. Argument des Makros enthaelt */ |
| 836 | struct strnode *CloneArg(struct strnode *list, int n, int *error) |
| 837 | { |
| 838 | int argnum = 0; |
| 839 | struct strnode *start; |
| 840 | |
| 841 | if (error) |
| 842 | *error = OK; |
| 843 | |
| 844 | if (list) { |
| 845 | if (DEBUG & 32) |
| 846 | printf("CloneArg\n"); |
| 847 | if (list->type == PP_IDENT) |
| 848 | list = list->next; |
| 849 | while (list && list->type == SPACE) |
| 850 | list = list->next; |
| 851 | |
| 852 | if (list && list->type == NORMAL && list->str[0] == '(') { |
| 853 | list = list->next; /* Skip ( */ |
| 854 | |
| 855 | if (DEBUG & 32) |
| 856 | printf("- IDENT skipped, ( found\n"); |
| 857 | |
| 858 | while (list && (argnum < n)) { |
| 859 | if (list->type == NORMAL) { |
| 860 | if (list->str[0] == ')') |
| 861 | list = NULL; |
| 862 | if (list && list->str[0] == '(') |
| 863 | list = (FindBracket(list))->next; |
| 864 | if (list && list->str[0] == ',') |
| 865 | argnum++; |
| 866 | } |
| 867 | if (list) |
| 868 | list = list->next; |
| 869 | } |
| 870 | |
| 871 | while (list && list->type == SPACE) |
| 872 | list = list->next; |
| 873 | |
| 874 | if (list) { |
| 875 | if (list->type == NORMAL && (list->str[0] == ')' || list->str[0] == ',')) { /* HIER evtl. ein Space erzeugen */ |
| 876 | return (NULL); |
| 877 | } |
| 878 | start = list; |
| 879 | } else { |
| 880 | if (error) |
| 881 | *error = ARG_EXPECTED; |
| 882 | return (NULL); |
| 883 | } |
| 884 | |
| 885 | if (DEBUG & 32) |
| 886 | printf("- Okay, Arg-Start found: %s\n", start->str); |
| 887 | |
| 888 | while (list && (argnum == n)) { |
| 889 | if (list->type == NORMAL) { |
| 890 | switch (list->str[0]) { |
| 891 | case ')': |
| 892 | case ',': |
| 893 | argnum++; |
| 894 | list = list->prev; |
| 895 | break; |
| 896 | case '(': |
| 897 | list = FindBracket(list); |
| 898 | default: |
| 899 | if (list) |
| 900 | list = list->next; |
| 901 | break; |
| 902 | } |
| 903 | } else if (list) |
| 904 | list = list->next; |
| 905 | } |
| 906 | |
| 907 | while (list && list->type == SPACE) |
| 908 | list = list->prev; |
| 909 | |
| 910 | if (DEBUG & 32) |
| 911 | printf("- Okay, Arg-End found: %s\n", list->str); |
| 912 | return (CloneStrList(start, list)); |
| 913 | |
| 914 | } else { |
| 915 | if (error) |
| 916 | *error = ARG_EXPECTED; |
| 917 | return (NULL); |
| 918 | } |
| 919 | } else |
| 920 | return (NULL); |
| 921 | } |
| 922 | |
| 923 | /* ExpandArgMakro - ersetzt ein Makro mit Argumenten */ |
| 924 | int ExpandArgMakro(struct mnode *makro, struct strnode **list, |
| 925 | struct strnode **pos) |
| 926 | { |
| 927 | struct strnode *clone, *temp, *temp1, *arg, *new; |
| 928 | struct strnode *prev, *next; |
| 929 | struct mnode *prevmakro; |
| 930 | char *newstr; |
| 931 | int spec, len, x; |
| 932 | |
| 933 | clone = CloneStrList(makro->tokenlist, NULL); |
| 934 | if (!clone) |
| 935 | return (OUT_OF_MEM); |
| 936 | |
| 937 | if (DEBUG & 32) |
| 938 | printf("ExpandArgMakro - Clone build.\n"); |
| 939 | |
| 940 | temp = clone; |
| 941 | while (temp) { |
| 942 | if (temp->type == ARGUMENT) { |
| 943 | arg = CloneArg(*pos, temp->number, &x); |
| 944 | if (!arg) { |
| 945 | DelStrList(&clone); |
| 946 | return (x); |
| 947 | } |
| 948 | if (DEBUG & 32) { |
| 949 | printf("ARGUMENT:\n"); |
| 950 | PrintTL(arg); |
| 951 | printf("Argument found - "); |
| 952 | } |
| 953 | if (spec = NextToSpecial(temp)) { |
| 954 | /* nicht expandieren, nur einsetzen */ |
| 955 | if (spec == TOSTRING) { |
| 956 | |
| 957 | if (DEBUG & 32) |
| 958 | printf("next to #\n"); |
| 959 | /* als String einsetzen */ |
| 960 | new = (struct strnode *) malloc(sizeof(struct strnode)); |
| 961 | if (!new) { |
| 962 | DelStrList(&clone); |
| 963 | DelStrList(&arg); |
| 964 | return (OUT_OF_MEM); |
| 965 | } |
| 966 | len = ListStrLen(arg); |
| 967 | newstr = (char *) malloc(len + 1); |
| 968 | if (!newstr) { |
| 969 | DelStrList(&clone); |
| 970 | DelStrList(&arg); |
| 971 | if (new) |
| 972 | free(new); |
| 973 | return (OUT_OF_MEM); |
| 974 | } |
| 975 | CopyList2StrStr(arg, newstr); |
| 976 | DelStrList(&arg); |
| 977 | new->len = len + 2; |
| 978 | new->flags = new->number = 0; |
| 979 | new->type = PP_STR; |
| 980 | new->str = newstr; |
| 981 | |
| 982 | prev = temp->prev; |
| 983 | next = temp->next; |
| 984 | DelStrNode(NULL, temp); /* Argument */ |
| 985 | |
| 986 | while (prev && prev->type == SPACE) { |
| 987 | temp = prev->prev; |
| 988 | DelStrNode(&clone, prev); |
| 989 | prev = temp; |
| 990 | } |
| 991 | |
| 992 | if (prev && prev->type == SPECIAL && prev->flags == TOSTRING) { |
| 993 | temp = prev->prev; |
| 994 | DelStrNode(&clone, prev); |
| 995 | prev = temp; |
| 996 | } else |
| 997 | ierror(0); |
| 998 | |
| 999 | new->prev = prev; |
| 1000 | if (prev) |
| 1001 | prev->next = new; |
| 1002 | else |
| 1003 | clone = new; |
| 1004 | new->next = next; |
| 1005 | if (next) |
| 1006 | next->prev = new; |
| 1007 | temp = new; |
| 1008 | } else { |
| 1009 | /* Einfach nur einsetzen */ |
| 1010 | if (DEBUG & 32) |
| 1011 | printf("next to ##\n"); |
| 1012 | prev = temp->prev; |
| 1013 | next = temp->next; |
| 1014 | DelStrNode(NULL, temp); |
| 1015 | arg->prev = prev; |
| 1016 | if (prev) |
| 1017 | prev->next = arg; |
| 1018 | else |
| 1019 | clone = arg; |
| 1020 | while (arg->next) |
| 1021 | arg = arg->next; |
| 1022 | arg->next = next; |
| 1023 | if (next) |
| 1024 | next->prev = arg; |
| 1025 | temp = arg; |
| 1026 | } |
| 1027 | } else { |
| 1028 | /* expandieren und einsetzen */ |
| 1029 | if (DEBUG & 32) |
| 1030 | printf("normal arg\n"); |
| 1031 | if (x = ExpandList(&arg)) { |
| 1032 | DelStrList(&clone); |
| 1033 | DelStrList(&arg); |
| 1034 | return (x); |
| 1035 | } |
| 1036 | if (DEBUG & 32) { |
| 1037 | printf("expanded arg:\n"); |
| 1038 | PrintTL(arg); |
| 1039 | } |
| 1040 | prev = temp->prev; |
| 1041 | next = temp->next; |
| 1042 | DelStrNode(NULL, temp); |
| 1043 | arg->prev = prev; |
| 1044 | if (prev) |
| 1045 | prev->next = arg; |
| 1046 | else |
| 1047 | clone = arg; |
| 1048 | while (arg->next) |
| 1049 | arg = arg->next; |
| 1050 | arg->next = next; |
| 1051 | if (next) |
| 1052 | next->prev = arg; |
| 1053 | temp = arg; |
| 1054 | } /* of N2Special */ |
| 1055 | } |
| 1056 | if (temp) |
| 1057 | temp = temp->next; |
| 1058 | } |
| 1059 | |
| 1060 | if (DEBUG & 32) |
| 1061 | printf("Arguments expanded.\n"); |
| 1062 | |
| 1063 | temp = clone; |
| 1064 | while (temp) { |
| 1065 | if (temp->type == SPECIAL && temp->flags == KILLSPACES) { |
| 1066 | prev = temp->prev; |
| 1067 | next = temp->next; |
| 1068 | if ((prev->type == PP_IDENT || prev->type == NUMBER)) { |
| 1069 | switch (next->type) { |
| 1070 | case NUMBER: /* merge -> ident */ |
| 1071 | case PP_IDENT: |
| 1072 | RemStrNode(&clone, next); |
| 1073 | MergeStrNodes(prev, next); |
| 1074 | next = temp->next; |
| 1075 | /* next will now be deleted and prev->str will be */ |
| 1076 | /* the joined strings from prev&next */ |
| 1077 | default: /* no merge / del ## */ |
| 1078 | DelStrNode(&clone, temp); |
| 1079 | temp = next; |
| 1080 | break; |
| 1081 | } /* of switch */ |
| 1082 | } else { |
| 1083 | DelStrNode(&clone, temp); |
| 1084 | temp = next; |
| 1085 | } |
| 1086 | } |
| 1087 | if (temp) |
| 1088 | temp = temp->next; |
| 1089 | } |
| 1090 | |
| 1091 | /* 'makro' aus mlist ausklinken */ |
| 1092 | prevmakro = makro->prev; |
| 1093 | RemMakroNode(&mlist, makro); |
| 1094 | |
| 1095 | /* alles expandieren */ |
| 1096 | if (!(x = ExpandList(&clone))) { |
| 1097 | /* akt. StrNode durch clone-Liste ersetzen */ |
| 1098 | |
| 1099 | if (DEBUG & 32) { |
| 1100 | printf("Complete Makro expanded\n"); |
| 1101 | PrintTL(clone); |
| 1102 | } |
| 1103 | /* clone anstelle von pos in list einsetzen */ |
| 1104 | prev = (*pos)->prev; |
| 1105 | next = (*pos)->next; |
| 1106 | |
| 1107 | DelStrNode(NULL, *pos); |
| 1108 | |
| 1109 | #ifdef bla |
| 1110 | while (next && next->type == SPACE) { |
| 1111 | temp = next->next; |
| 1112 | DelStrNode(NULL, next); /* SPACE zwischen Makro und Args loeschen */ |
| 1113 | next = temp; |
| 1114 | } |
| 1115 | #endif |
| 1116 | while (next && next->type == SPACE) |
| 1117 | next = next->next; |
| 1118 | /* SPACE hinter Makro ueberspringen */ |
| 1119 | |
| 1120 | if (next && next->type == NORMAL && next->str[0] == '(') { |
| 1121 | temp = next; |
| 1122 | next = FindBracket(temp); |
| 1123 | if (next) |
| 1124 | next = next->next; |
| 1125 | do { |
| 1126 | temp1 = temp->next; |
| 1127 | DelStrNode(NULL, temp); /* ARG-List hinter Makro loeschen */ |
| 1128 | temp = temp1; |
| 1129 | } while (temp != next); |
| 1130 | } else { |
| 1131 | ierror(0); |
| 1132 | } |
| 1133 | |
| 1134 | |
| 1135 | /* vor clone ein SPACE einsetzen, wenn nicht PREV==SPACE */ |
| 1136 | /*vb: hier !prev|| wegen Enforcerhit eingesetzt; waere prev&& besser? */ |
| 1137 | if (!prev || prev->type != SPACE) { |
| 1138 | if (temp = AllocSpace()) { |
| 1139 | temp->next = clone; |
| 1140 | if (clone) |
| 1141 | clone->prev = temp; |
| 1142 | clone = temp; |
| 1143 | } |
| 1144 | } |
| 1145 | clone->prev = prev; |
| 1146 | if (prev) |
| 1147 | prev->next = clone; |
| 1148 | else |
| 1149 | *list = clone; |
| 1150 | |
| 1151 | while (clone->next) |
| 1152 | clone = clone->next; |
| 1153 | /* nach clone ein SPACE einsetzen, wenn nicht NEXT==SPACE */ |
| 1154 | /*vb: hier !next|| wegen Enforcerhit eingesetzt; waere next&& besser? */ |
| 1155 | if (!next || next->type != SPACE) { |
| 1156 | if (temp = AllocSpace()) { |
| 1157 | temp->prev = clone; |
| 1158 | if (clone) |
| 1159 | clone->next = temp; |
| 1160 | clone = temp; |
| 1161 | } |
| 1162 | } |
| 1163 | *pos = clone; |
| 1164 | clone->next = next; |
| 1165 | if (next) |
| 1166 | next->prev = clone; |
| 1167 | |
| 1168 | /* 'makro' wieder einsetzen */ |
| 1169 | InsertMakroNode(&mlist, makro, prevmakro); |
| 1170 | return (OK); |
| 1171 | } else { |
| 1172 | InsertMakroNode(&mlist, makro, prevmakro); |
| 1173 | return (x); |
| 1174 | } |
| 1175 | |
| 1176 | } |
| 1177 | |
| 1178 | /* ExpandList - ersetzt alle Makros in der Liste */ |
| 1179 | int ExpandList(struct strnode **list) |
| 1180 | { |
| 1181 | struct mnode *found, *before; |
| 1182 | struct strnode *clone, *beforestr, *afterstr, *listtemp, *temp2, |
| 1183 | *temp3; |
| 1184 | int result = OK; |
| 1185 | |
| 1186 | if (DEBUG & 32) |
| 1187 | puts("ExpandList"); |
| 1188 | |
| 1189 | |
| 1190 | listtemp = *list; |
| 1191 | while (listtemp) { |
| 1192 | |
| 1193 | if (listtemp->type == PP_IDENT) { |
| 1194 | |
| 1195 | found = FindMakroNode(mlist, listtemp->str, 0); |
| 1196 | if (found) { |
| 1197 | /*vb: merken, ob mind. ein Makro expandiert wurde */ |
| 1198 | did_expand = 1; |
| 1199 | if (found->flags & PARAMETER) { |
| 1200 | /* Makro mit Argument(en) */ |
| 1201 | if (DEBUG & 32) |
| 1202 | printf("Makro with args\n"); |
| 1203 | |
| 1204 | temp2 = listtemp->next; |
| 1205 | while (temp2 && temp2->type == SPACE) |
| 1206 | temp2 = temp2->next; |
| 1207 | |
| 1208 | if (temp2 && temp2->type == NORMAL && temp2->str[0] == '(') |
| 1209 | if (result = ExpandArgMakro(found, list, &listtemp)) |
| 1210 | return (result); |
| 1211 | |
| 1212 | } else { |
| 1213 | |
| 1214 | /* Makro ohne Argument */ |
| 1215 | |
| 1216 | /* ExpandNormMakro - expandiert ein Makro ohne Argumente */ |
| 1217 | /* Parameter: s.o. */ |
| 1218 | |
| 1219 | if (found->flags & FUNCTION) { |
| 1220 | clone = DoMakroFunction(found); |
| 1221 | } else { |
| 1222 | clone = CloneStrList(found->tokenlist, NULL); |
| 1223 | } |
| 1224 | if (!clone) |
| 1225 | return (OUT_OF_MEM); |
| 1226 | /* akt. MakroNode ausklinken um rekursive Exp. zu verhindern */ |
| 1227 | before = found->prev; |
| 1228 | RemMakroNode(&mlist, found); |
| 1229 | if (!(result = ExpandList(&clone))) { |
| 1230 | /* akt. StrNode durch clone-Liste ersetzen */ |
| 1231 | beforestr = listtemp->prev; |
| 1232 | afterstr = listtemp->next; |
| 1233 | DelStrNode(NULL, listtemp); |
| 1234 | listtemp = afterstr; |
| 1235 | clone->prev = beforestr; |
| 1236 | if (beforestr) |
| 1237 | beforestr->next = clone; |
| 1238 | else |
| 1239 | *list = clone; |
| 1240 | while (clone->next) |
| 1241 | clone = clone->next; |
| 1242 | clone->next = afterstr; |
| 1243 | if (afterstr) |
| 1244 | afterstr->prev = clone; |
| 1245 | /* akt. Makronode wieder einsetzen */ |
| 1246 | InsertMakroNode(&mlist, found, before); |
| 1247 | } else { |
| 1248 | /* akt. Makronode wieder einsetzen */ |
| 1249 | InsertMakroNode(&mlist, found, before); |
| 1250 | return (result); |
| 1251 | } |
| 1252 | } |
| 1253 | } |
| 1254 | } |
| 1255 | if (listtemp) |
| 1256 | listtemp = listtemp->next; |
| 1257 | } |
| 1258 | |
| 1259 | return (OK); |
| 1260 | } |
| 1261 | |
| 1262 | |
| 1263 | /* ParseIdentifier - parsed den Input-Define-String und haengt das Makro */ |
| 1264 | /* in die Liste */ |
| 1265 | |
| 1266 | struct mnode *ParseIdentifier(char *str) |
| 1267 | { |
| 1268 | int x, numargs = 0, flags = 0, len = 0; |
| 1269 | char *name = NULL, *args = NULL, *token = NULL, *temp, *temp2, *argtemp; |
| 1270 | struct mnode *newmakro, *found; |
| 1271 | struct strnode *tokenlist = NULL, *templist, *arglist = NULL, *templist2; |
| 1272 | struct strnode *next, *prev; |
| 1273 | |
| 1274 | if (DEBUG & 32) |
| 1275 | puts("ParseIdentifier"); |
| 1276 | |
| 1277 | /*vb: casts eingefuegt */ |
| 1278 | while (isspace((unsigned char) *str)) { |
| 1279 | str++; |
| 1280 | } |
| 1281 | if (!(isalpha((unsigned char) *str) || *str == '_')) { |
| 1282 | error(178); |
| 1283 | return (0); |
| 1284 | } |
| 1285 | temp = str; |
| 1286 | while (isalnum((unsigned char) *temp) || (*temp == '_')) { |
| 1287 | temp++; |
| 1288 | len++; |
| 1289 | } |
| 1290 | |
| 1291 | /* auf schon vorhandene (evtl. FESTE) Definition suchen */ |
| 1292 | found = FindMakroNode(mlist, str, len); |
| 1293 | if (found && (found->flags & NOREDEF)) { |
| 1294 | error(179); |
| 1295 | return (0); |
| 1296 | } |
| 1297 | /*vb: */ |
| 1298 | if (1) { |
| 1299 | /* Okay, ist egal, wie das alte Makro aussah */ |
| 1300 | |
| 1301 | /*vb: */ |
| 1302 | if (found && !(c_flags[15] & USEDFLAG)) { |
| 1303 | error(197); |
| 1304 | } |
| 1305 | temp = name = (char *) malloc(len + 1); /* Speicher fuer Name-String belegen */ |
| 1306 | if (!name) { |
| 1307 | error(196); |
| 1308 | return (0); |
| 1309 | } |
| 1310 | for (x = 0; x < len; x++) { |
| 1311 | *temp++ = *str++; |
| 1312 | } /* Namen kopieren */ |
| 1313 | *temp = 0; |
| 1314 | |
| 1315 | if (*str == '(') { |
| 1316 | flags |= PARAMETER; |
| 1317 | str++; /* jump over '(' */ |
| 1318 | temp = str; |
| 1319 | len = 0; |
| 1320 | /*vb: casts eingefuegt */ |
| 1321 | while (*temp && (*temp != ')')) |
| 1322 | if (!(isspace((unsigned char) *temp))) { |
| 1323 | len++; |
| 1324 | temp++; |
| 1325 | } else { |
| 1326 | temp++; |
| 1327 | } |
| 1328 | if (*temp == 0) { |
| 1329 | error(180); |
| 1330 | if (name) |
| 1331 | free(name); |
| 1332 | return (0); |
| 1333 | } |
| 1334 | args = temp = (char *) malloc(len + 1); |
| 1335 | if (!args) { |
| 1336 | error(196); |
| 1337 | if (name) |
| 1338 | free(name); |
| 1339 | return (0); |
| 1340 | } |
| 1341 | for (x = 0; x < len;) |
| 1342 | if (!(isspace((unsigned char) *str))) { |
| 1343 | x++; |
| 1344 | *temp++ = *str++; |
| 1345 | } else { |
| 1346 | str++; |
| 1347 | } |
| 1348 | *temp = 0; |
| 1349 | str++; /* jump over ')' */ |
| 1350 | |
| 1351 | /* Argumentliste parsen und auf Fehler pruefen */ |
| 1352 | temp = args; |
| 1353 | while (*temp && (isalpha((unsigned char) *temp) || *temp == '_')) { |
| 1354 | temp++; |
| 1355 | while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) { |
| 1356 | temp++; |
| 1357 | } |
| 1358 | if (!(*temp) || *temp == ',') { |
| 1359 | numargs++; |
| 1360 | if ((*temp == ',') && (isalpha((unsigned char) *(temp + 1)) || *(temp + 1) == '_')) |
| 1361 | temp++; |
| 1362 | } |
| 1363 | } |
| 1364 | if (*temp) { |
| 1365 | if (args) |
| 1366 | free(args); |
| 1367 | if (name) |
| 1368 | free(name); |
| 1369 | if (*temp == ',') { |
| 1370 | error(181); |
| 1371 | } else { |
| 1372 | error(182); |
| 1373 | } |
| 1374 | return (0); |
| 1375 | } |
| 1376 | } |
| 1377 | while (isspace((unsigned char) *str)) |
| 1378 | str++; /* Skip Spaces */ |
| 1379 | /* HIER: pruefen, ob tokenlist erstellt werden konnte (leere tokenlist->ok) */ |
| 1380 | tokenlist = Str2List(str); |
| 1381 | if (DEBUG & 32) |
| 1382 | printf(" - build TokenList\n"); |
| 1383 | templist = tokenlist; |
| 1384 | while (templist) { |
| 1385 | if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) { |
| 1386 | |
| 1387 | if ((templist->next) && (templist->next->type == NORMAL) |
| 1388 | && (!strcmp(templist->next->str, "#"))) { |
| 1389 | /* ## KILLSPACES */ |
| 1390 | if ((templist->prev) && (templist->next->next)) { |
| 1391 | templist->type = SPECIAL; |
| 1392 | templist->flags = KILLSPACES; |
| 1393 | DelStrNode(&tokenlist, templist->next); |
| 1394 | } else { |
| 1395 | error(183); |
| 1396 | if (name) |
| 1397 | free(name); |
| 1398 | if (args) |
| 1399 | free(args); |
| 1400 | if (tokenlist) |
| 1401 | DelStrList(&tokenlist); |
| 1402 | return (0); |
| 1403 | } |
| 1404 | } |
| 1405 | } |
| 1406 | templist = templist->next; |
| 1407 | } |
| 1408 | |
| 1409 | /* Token parsen/kopieren */ |
| 1410 | if ((flags & PARAMETER)) { /* Argumente parsen */ |
| 1411 | arglist = NULL; |
| 1412 | temp = temp2 = args; |
| 1413 | while (*temp) { |
| 1414 | len = 0; |
| 1415 | while (*temp && *temp != ',') { |
| 1416 | temp++; |
| 1417 | len++; |
| 1418 | } |
| 1419 | if (*temp == ',') |
| 1420 | temp++; |
| 1421 | argtemp = (char *) malloc(len + 1); |
| 1422 | if (!argtemp) { |
| 1423 | error(196); |
| 1424 | if (name) |
| 1425 | free(name); |
| 1426 | if (args) |
| 1427 | free(args); |
| 1428 | if (arglist) |
| 1429 | DelStrList(&arglist); |
| 1430 | if (tokenlist) |
| 1431 | DelStrList(&tokenlist); |
| 1432 | return (0); |
| 1433 | } |
| 1434 | strncpy(argtemp, temp2, len); |
| 1435 | temp2 = temp; |
| 1436 | *(argtemp + len) = 0; |
| 1437 | AddStrNodeBehind(&arglist, NULL, argtemp); |
| 1438 | } |
| 1439 | templist = tokenlist; |
| 1440 | while (templist) { |
| 1441 | if (templist->type == PP_IDENT) { |
| 1442 | x = 0; |
| 1443 | templist2 = arglist; |
| 1444 | while (templist2) { |
| 1445 | if (!strcmp(templist->str, templist2->str)) { |
| 1446 | templist->type = ARGUMENT; |
| 1447 | templist->number = x; |
| 1448 | } |
| 1449 | x++; |
| 1450 | templist2 = templist2->next; |
| 1451 | } |
| 1452 | } |
| 1453 | templist = templist->next; |
| 1454 | } |
| 1455 | DelStrList(&arglist); |
| 1456 | if (DEBUG & 32) |
| 1457 | printf(" - Arguments found.\n"); |
| 1458 | /* #-Specials korrigieren, nachdem die Argumente erkannt wurden */ |
| 1459 | templist = tokenlist; |
| 1460 | while (templist) { |
| 1461 | if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) { |
| 1462 | if ((templist->next) && (templist->next->type == ARGUMENT)) { |
| 1463 | templist->type = SPECIAL; |
| 1464 | templist->flags = TOSTRING; |
| 1465 | } else { |
| 1466 | error(184); |
| 1467 | if (name) |
| 1468 | free(name); |
| 1469 | if (args) |
| 1470 | free(args); |
| 1471 | if (arglist) |
| 1472 | DelStrList(&arglist); |
| 1473 | if (tokenlist) |
| 1474 | DelStrList(&tokenlist); |
| 1475 | return (0); |
| 1476 | } |
| 1477 | } |
| 1478 | templist = templist->next; |
| 1479 | } |
| 1480 | if (DEBUG & 32) |
| 1481 | printf(" - Special-# corrected.\n"); |
| 1482 | } else { /* Token kopieren */ |
| 1483 | temp = str; |
| 1484 | len = 0; |
| 1485 | while ((*temp) && (*temp != '\n')) { |
| 1486 | temp++; |
| 1487 | len++; |
| 1488 | } |
| 1489 | temp = token = (char *) malloc(len + 1); |
| 1490 | if (!token) { |
| 1491 | error(196); |
| 1492 | if (name) |
| 1493 | free(name); |
| 1494 | if (args) |
| 1495 | free(args); |
| 1496 | if (tokenlist) |
| 1497 | DelStrList(&tokenlist); |
| 1498 | return (0); |
| 1499 | } |
| 1500 | for (x = 0; x < len; x++) { |
| 1501 | *temp++ = *str++; |
| 1502 | } |
| 1503 | *temp = 0; |
| 1504 | } |
| 1505 | |
| 1506 | |
| 1507 | templist = tokenlist; |
| 1508 | while (templist) { |
| 1509 | if (templist->type == SPECIAL && templist->flags == KILLSPACES) { |
| 1510 | next = templist->next; |
| 1511 | prev = templist->prev; |
| 1512 | |
| 1513 | /* Kill Spaces before/after ## */ |
| 1514 | while (prev && prev->type == SPACE) { |
| 1515 | templist2 = prev->prev; |
| 1516 | DelStrNode(&tokenlist, prev); |
| 1517 | prev = templist2; |
| 1518 | } |
| 1519 | while (next && next->type == SPACE) { |
| 1520 | templist2 = next->next; |
| 1521 | DelStrNode(&tokenlist, next); |
| 1522 | next = templist2; |
| 1523 | } |
| 1524 | if ((!next) || (!prev)) |
| 1525 | ierror(0); |
| 1526 | |
| 1527 | if (next->type != ARGUMENT && prev->type != ARGUMENT) { |
| 1528 | if ((prev->type == PP_IDENT || prev->type == NUMBER)) { |
| 1529 | switch (next->type) { |
| 1530 | case NUMBER: /* merge -> ident */ |
| 1531 | case PP_IDENT: |
| 1532 | RemStrNode(&tokenlist, next); |
| 1533 | MergeStrNodes(prev, next); |
| 1534 | next = templist->next; |
| 1535 | /* next will now be deleted and prev->str will be */ |
| 1536 | /* the joined strings from prev&next */ |
| 1537 | default: /* no merge / del ## */ |
| 1538 | DelStrNode(&tokenlist, templist); |
| 1539 | templist = next; |
| 1540 | break; |
| 1541 | } /* of switch */ |
| 1542 | } else { |
| 1543 | DelStrNode(&tokenlist, templist); |
| 1544 | templist = next; |
| 1545 | } |
| 1546 | } |
| 1547 | } |
| 1548 | if (templist) |
| 1549 | templist = templist->next; |
| 1550 | } |
| 1551 | |
| 1552 | |
| 1553 | /* erst HIER bei allowredefinition=0 abfragen ?? */ |
| 1554 | |
| 1555 | if (newmakro = (struct mnode *) malloc(sizeof(struct mnode))) { |
| 1556 | newmakro->name = name; |
| 1557 | newmakro->args = args; |
| 1558 | newmakro->token = token; |
| 1559 | newmakro->tokenlist = tokenlist; |
| 1560 | newmakro->flags = flags; |
| 1561 | newmakro->funcnum = 0; |
| 1562 | AddMakroNode(&mlist, newmakro); |
| 1563 | } else { |
| 1564 | error(196); |
| 1565 | if (name) |
| 1566 | free(name); |
| 1567 | if (token) |
| 1568 | free(token); |
| 1569 | if (args) |
| 1570 | free(args); |
| 1571 | if (tokenlist) |
| 1572 | DelStrList(&tokenlist); |
| 1573 | } |
| 1574 | return (newmakro); |
| 1575 | |
| 1576 | } else { |
| 1577 | /*vb: das ist irgendwie Unsinn hier, glaube ich */ |
| 1578 | ierror(0); |
| 1579 | /* HIER: ueberpruefen, ob Macrodefinitionen uebereinstimmen, sonst Error */ |
| 1580 | if (*temp == '(') { |
| 1581 | if (found->flags & PARAMETER) { |
| 1582 | temp++; /* skip ( */ |
| 1583 | |
| 1584 | |
| 1585 | |
| 1586 | } else { |
| 1587 | error(185); |
| 1588 | return (NULL); |
| 1589 | } |
| 1590 | } |
| 1591 | /* HIER nur noch tokenlisten vergleichen */ |
| 1592 | |
| 1593 | } |
| 1594 | if (DEBUG & 32) |
| 1595 | printf("ParseIdent falls of\n"); |
| 1596 | } |
| 1597 | |
| 1598 | |
| 1599 | /* PreParse - 3-Zeichen-Folgen ersetzen, \+CR Zeilen anhaengen, usw.. */ |
| 1600 | |
| 1601 | int PreParse() |
| 1602 | { |
| 1603 | char *src, *dest, *dest2; |
| 1604 | int slen, dlen = 0; |
| 1605 | int cat = 0; /*vb: um zu merken, ob Zeilen mit \ verbunden werden */ |
| 1606 | dest2 = string; |
| 1607 | |
| 1608 | if (DEBUG & 32) |
| 1609 | puts("PreParse"); |
| 1610 | |
| 1611 | |
| 1612 | if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) { |
| 1613 | if (cmtnesting) |
| 1614 | error(186); |
| 1615 | /*vb: */ |
| 1616 | /* if(ifstatus[incnesting]) error(186); */ |
| 1617 | /* ifnesting--; */ |
| 1618 | if (DEBUG & 32) |
| 1619 | printf("-- end of file ifnesting-1:%d\n\n", incnesting); |
| 1620 | if (incnesting) { |
| 1621 | fclose(in[incnesting]); |
| 1622 | incnesting--; |
| 1623 | return (pp_nextline()); |
| 1624 | } else |
| 1625 | return (0); |
| 1626 | } else if (DEBUG & 32) |
| 1627 | printf("gets1:%s\n", ppstring); /*vb: */ |
| 1628 | |
| 1629 | if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) { |
| 1630 | error(177); |
| 1631 | return (0); |
| 1632 | } |
| 1633 | zn[incnesting]++; |
| 1634 | linenr = zn[incnesting]; |
| 1635 | |
| 1636 | do { |
| 1637 | /* Zeilen einlesen, bis kein Kommentar mehr */ |
| 1638 | |
| 1639 | /* Zeilen einlesen bis kein \ mehr am Ende */ |
| 1640 | do { |
| 1641 | /* Source-String an Dest-String anhaengen und ??x-Folgen ersetzen */ |
| 1642 | /*vb: das killt sonst das angehaengte wieder */ |
| 1643 | if (cat == 0) { |
| 1644 | dest = src = ppstring; |
| 1645 | slen = 0; |
| 1646 | } |
| 1647 | do { |
| 1648 | if (*src != '\n') { |
| 1649 | |
| 1650 | if ((*src == '?') && (*(src + 1) == '?') && !(c_flags[16] & USEDFLAG)) { |
| 1651 | switch (*(src + 2)) { |
| 1652 | case '=': |
| 1653 | *dest++ = '#'; |
| 1654 | src += 2; |
| 1655 | break; |
| 1656 | case '/': |
| 1657 | *dest++ = '\\'; |
| 1658 | src += 2; |
| 1659 | break; |
| 1660 | case '\'': |
| 1661 | *dest++ = '^'; |
| 1662 | src += 2; |
| 1663 | break; |
| 1664 | case '(': |
| 1665 | *dest++ = '['; |
| 1666 | src += 2; |
| 1667 | break; |
| 1668 | case ')': |
| 1669 | *dest++ = ']'; |
| 1670 | src += 2; |
| 1671 | break; |
| 1672 | case '!': |
| 1673 | *dest++ = '|'; |
| 1674 | src += 2; |
| 1675 | break; |
| 1676 | case '<': |
| 1677 | *dest++ = '{'; |
| 1678 | src += 2; |
| 1679 | break; |
| 1680 | case '>': |
| 1681 | *dest++ = '}'; |
| 1682 | src += 2; |
| 1683 | break; |
| 1684 | case '-': |
| 1685 | *dest++ = '~'; |
| 1686 | src += 2; |
| 1687 | break; |
| 1688 | default: |
| 1689 | *dest++ = *src; |
| 1690 | break; |
| 1691 | } /* of switch */ |
| 1692 | } else { |
| 1693 | *dest++ = *src; |
| 1694 | } |
| 1695 | |
| 1696 | if (slen < MAXPPINPUT) { |
| 1697 | slen++; |
| 1698 | } else { |
| 1699 | error(177); |
| 1700 | return (0); |
| 1701 | } |
| 1702 | } |
| 1703 | } while (*src++); |
| 1704 | |
| 1705 | src = dest; |
| 1706 | /* dest->lastchar+2/NULL+1 (dest-1)-> 0 (dest-2)->lastchar */ |
| 1707 | if (*(dest - 2) == '\\') { |
| 1708 | /*vb: sollte das slen statt dlen sein? */ |
| 1709 | if (fgets(src, MAXPPINPUT - dlen, in[incnesting])) { |
| 1710 | if (DEBUG & 32) |
| 1711 | printf("gets2:%s\n", src); /*vb: */ |
| 1712 | /* Hier auf LF+0 abfragen */ |
| 1713 | dest -= 2; |
| 1714 | zn[incnesting]++; |
| 1715 | cat = 1; /*vb: merken, dass Zeilen verbunden wurden */ |
| 1716 | } |
| 1717 | } |
| 1718 | } while (*dest == '\\'); |
| 1719 | |
| 1720 | src = ppstring; |
| 1721 | while (*src) { |
| 1722 | /* ' Strings ueberlesen */ |
| 1723 | if ((*src == '\'') && (!cmtnesting)) { |
| 1724 | if (dlen < MAXINPUT) { |
| 1725 | *dest2++ = *src++; |
| 1726 | dlen++; |
| 1727 | } else { |
| 1728 | error(177); |
| 1729 | return (0); |
| 1730 | } |
| 1731 | while (*src && *src != '\'') { |
| 1732 | if (*src == '\\') { |
| 1733 | *dest2++ = *src++; |
| 1734 | dlen++; |
| 1735 | }; |
| 1736 | if (dlen < MAXINPUT) { |
| 1737 | *dest2++ = *src++; |
| 1738 | dlen++; |
| 1739 | } else { |
| 1740 | error(177); |
| 1741 | return (0); |
| 1742 | } |
| 1743 | } |
| 1744 | if (dlen < MAXINPUT) { |
| 1745 | *dest2++ = *src++; |
| 1746 | dlen++; |
| 1747 | } else { |
| 1748 | error(177); |
| 1749 | return (0); |
| 1750 | } |
| 1751 | } |
| 1752 | /* " Strings ueberlesen */ |
| 1753 | if ((*src == '\"') && (!cmtnesting)) { |
| 1754 | *dest2++ = *src++; |
| 1755 | dlen++; |
| 1756 | while (*src && *src != '\"') { |
| 1757 | if (*src == '\\') { |
| 1758 | *dest2++ = *src++; |
| 1759 | dlen++; |
| 1760 | }; |
| 1761 | if (dlen < MAXINPUT) { |
| 1762 | *dest2++ = *src++; |
| 1763 | dlen++; |
| 1764 | } else { |
| 1765 | error(177); |
| 1766 | return (0); |
| 1767 | } |
| 1768 | } |
| 1769 | if (dlen < MAXINPUT) { |
| 1770 | *dest2++ = *src++; |
| 1771 | dlen++; |
| 1772 | } else { |
| 1773 | error(177); |
| 1774 | return (0); |
| 1775 | } |
| 1776 | } |
| 1777 | /* Kommentare weglassen */ |
| 1778 | if ((*src == '/') && (*(src + 1) == '*')) { |
| 1779 | src += 2; |
| 1780 | if (dlen < MAXINPUT) { |
| 1781 | *dest2++ = ' '; |
| 1782 | dlen++; |
| 1783 | } else { |
| 1784 | error(177); |
| 1785 | return (0); |
| 1786 | } |
| 1787 | if ((cmtnesting && (c_flags[13] & USEDFLAG)) || (!cmtnesting)) |
| 1788 | cmtnesting++; |
| 1789 | else |
| 1790 | error(198); |
| 1791 | } else { |
| 1792 | if ((*src == '*') && (*(src + 1) == '/') && cmtnesting) { |
| 1793 | src += 2; |
| 1794 | cmtnesting--; |
| 1795 | } |
| 1796 | } |
| 1797 | |
| 1798 | /* C++-Comment weglassen */ |
| 1799 | if ((!cmtnesting) && (*src == '/') && (*(src + 1) == '/') && (c_flags[14] & USEDFLAG)) |
| 1800 | *src = 0; |
| 1801 | |
| 1802 | if (!cmtnesting) { |
| 1803 | if (*src) { |
| 1804 | *dest2++ = *src++; |
| 1805 | } |
| 1806 | if (dlen < MAXINPUT) { |
| 1807 | dlen++; |
| 1808 | } else { |
| 1809 | error(177); |
| 1810 | return (0); |
| 1811 | } |
| 1812 | } else { |
| 1813 | if (*src) |
| 1814 | src++; |
| 1815 | } |
| 1816 | } |
| 1817 | |
| 1818 | if (cmtnesting) { |
| 1819 | if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) { |
| 1820 | if (cmtnesting) |
| 1821 | error(186); |
| 1822 | if (incnesting) { |
| 1823 | fclose(in[incnesting]); |
| 1824 | incnesting--; |
| 1825 | return (pp_nextline()); |
| 1826 | } else |
| 1827 | return (0); |
| 1828 | } else if (DEBUG & 32) |
| 1829 | printf("gets2:%s\n", ppstring); /*vb: */ |
| 1830 | |
| 1831 | if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) { |
| 1832 | error(177); |
| 1833 | return (0); |
| 1834 | } |
| 1835 | zn[incnesting]++; |
| 1836 | } |
| 1837 | } while (cmtnesting); |
| 1838 | |
| 1839 | /*vb: das ueberschreibt den Speicher */ |
| 1840 | #if 0 |
| 1841 | *dest2-- = 0; |
| 1842 | while (isspace(*dest2)) |
| 1843 | *dest2-- = 0; /* Spaces killen */ |
| 1844 | #endif |
| 1845 | |
| 1846 | /*vb: hoffe, das ist besser */ |
| 1847 | *dest2 = 0; |
| 1848 | while (dest2 > string && isspace((unsigned char) *--dest2)) |
| 1849 | *dest2 = 0; |
| 1850 | |
| 1851 | |
| 1852 | return (1); |
| 1853 | } |
| 1854 | |
| 1855 | /* **************** PreProcessor ***************** */ |
| 1856 | |
| 1857 | int pp_init(void) |
| 1858 | { |
| 1859 | char *macroname; |
| 1860 | struct mnode *macronode; |
| 1861 | |
| 1862 | if (!(c_flags[6] & USEDFLAG)) |
| 1863 | printf("%s\n", pp_version); |
| 1864 | |
| 1865 | incnesting = /*ifnesting= */ -1; /*vb: */ |
| 1866 | cmtnesting = if_cnt = abs_if_cnt = 0; |
| 1867 | mlist = NULL; |
| 1868 | strlist = NULL; |
| 1869 | |
| 1870 | macroname = (char *) malloc(9); |
| 1871 | if (!macroname) |
| 1872 | return (0); |
| 1873 | strcpy(macroname, "__LINE__"); |
| 1874 | macronode = (struct mnode *) malloc(sizeof(struct mnode)); |
| 1875 | if (!macronode) { |
| 1876 | if (macroname) |
| 1877 | free(macroname); |
| 1878 | return (0); |
| 1879 | } |
| 1880 | macronode->name = macroname; |
| 1881 | macronode->args = macronode->token = NULL; |
| 1882 | macronode->tokenlist = NULL; |
| 1883 | macronode->flags = FUNCTION | NODELETE | NOREDEF; |
| 1884 | macronode->funcnum = FUNCLINE; |
| 1885 | AddMakroNode(&mlist, macronode); |
| 1886 | |
| 1887 | macroname = (char *) malloc(9); |
| 1888 | if (!macroname) |
| 1889 | return (0); |
| 1890 | strcpy(macroname, "__FILE__"); |
| 1891 | macronode = (struct mnode *) malloc(sizeof(struct mnode)); |
| 1892 | if (!macronode) { |
| 1893 | if (macroname) |
| 1894 | free(macroname); |
| 1895 | DelMakroList(&mlist); |
| 1896 | return (0); |
| 1897 | } |
| 1898 | macronode->name = macroname; |
| 1899 | macronode->args = macronode->token = NULL; |
| 1900 | macronode->tokenlist = NULL; |
| 1901 | macronode->flags = FUNCTION | NODELETE | NOREDEF; |
| 1902 | macronode->funcnum = FUNCFILE; |
| 1903 | AddMakroNode(&mlist, macronode); |
| 1904 | |
| 1905 | macroname = (char *) malloc(9); |
| 1906 | if (!macroname) |
| 1907 | return (0); |
| 1908 | strcpy(macroname, "__DATE__"); |
| 1909 | macronode = (struct mnode *) malloc(sizeof(struct mnode)); |
| 1910 | if (!macronode) { |
| 1911 | if (macroname) |
| 1912 | free(macroname); |
| 1913 | DelMakroList(&mlist); |
| 1914 | return (0); |
| 1915 | } |
| 1916 | macronode->name = macroname; |
| 1917 | macronode->args = macronode->token = NULL; |
| 1918 | macronode->tokenlist = NULL; |
| 1919 | macronode->flags = FUNCTION | NODELETE | NOREDEF; |
| 1920 | macronode->funcnum = FUNCDATE; |
| 1921 | AddMakroNode(&mlist, macronode); |
| 1922 | |
| 1923 | macroname = (char *) malloc(9); |
| 1924 | if (!macroname) |
| 1925 | return (0); |
| 1926 | strcpy(macroname, "__TIME__"); |
| 1927 | macronode = (struct mnode *) malloc(sizeof(struct mnode)); |
| 1928 | if (!macronode) { |
| 1929 | if (macroname) |
| 1930 | free(macroname); |
| 1931 | DelMakroList(&mlist); |
| 1932 | return (0); |
| 1933 | } |
| 1934 | macronode->name = macroname; |
| 1935 | macronode->args = macronode->token = NULL; |
| 1936 | macronode->tokenlist = NULL; |
| 1937 | macronode->flags = FUNCTION | NODELETE | NOREDEF; |
| 1938 | macronode->funcnum = FUNCTIME; |
| 1939 | AddMakroNode(&mlist, macronode); |
| 1940 | |
| 1941 | macroname = (char *) malloc(9); |
| 1942 | if (!macroname) |
| 1943 | return (0); |
| 1944 | strcpy(macroname, "__STDC__"); |
| 1945 | macronode = (struct mnode *) malloc(sizeof(struct mnode)); |
| 1946 | if (!macronode) { |
| 1947 | if (macroname) |
| 1948 | free(macroname); |
| 1949 | DelMakroList(&mlist); |
| 1950 | return (0); |
| 1951 | } |
| 1952 | macronode->name = macroname; |
| 1953 | macronode->args = NULL; |
| 1954 | macroname = (char *) malloc(2); |
| 1955 | if (!macroname) { |
| 1956 | if (macronode->name) |
| 1957 | free(macronode->name); |
| 1958 | if (macronode) |
| 1959 | free(macronode); |
| 1960 | DelMakroList(&mlist); |
| 1961 | return (0); |
| 1962 | } |
| 1963 | strcpy(macroname, "1"); |
| 1964 | macronode->token = macroname; |
| 1965 | macronode->tokenlist = Str2List(macroname); |
| 1966 | if (!macronode->tokenlist) { |
| 1967 | if (macronode->name) |
| 1968 | free(macronode->name); |
| 1969 | if (macronode->token) |
| 1970 | free(macronode->token); |
| 1971 | if (macronode) |
| 1972 | free(macronode); |
| 1973 | DelMakroList(&mlist); |
| 1974 | return (0); |
| 1975 | } |
| 1976 | macronode->flags = NODELETE; |
| 1977 | macronode->funcnum = 0; |
| 1978 | AddMakroNode(&mlist, macronode); |
| 1979 | |
| 1980 | return (1); |
| 1981 | } |
| 1982 | |
| 1983 | |
| 1984 | void pp_free(void) |
| 1985 | { |
| 1986 | int i; |
| 1987 | |
| 1988 | if (DEBUG & 32) |
| 1989 | puts("pp_free"); |
| 1990 | |
| 1991 | /*vb: Schleifenindex korrekt gesetzt */ |
| 1992 | for (i = incnesting; i >= 0; i--) |
| 1993 | if (in[i]) |
| 1994 | fclose(in[i]); |
| 1995 | DelMakroList(&mlist); |
| 1996 | DelStrList(&strlist); |
| 1997 | } |
| 1998 | |
| 1999 | int pp_include(char *f) |
| 2000 | { |
| 2001 | if (DEBUG & 32) |
| 2002 | printf("trying to include %s\n", f); /*vb: */ |
| 2003 | |
| 2004 | if (incnesting >= MAXINCNESTING - 1) { |
| 2005 | error(187); |
| 2006 | return (0); |
| 2007 | } |
| 2008 | /*vb: */ |
| 2009 | /* if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #ifs or #includes",0);return(0);} */ |
| 2010 | incnesting++; |
| 2011 | /* ifnesting++; *//*vb: */ |
| 2012 | ifstatus[incnesting] = 0; /*vb: */ |
| 2013 | |
| 2014 | if (DEBUG & 32) |
| 2015 | printf("-- include: ifnesting:%d ifstatus:0 \n\n", incnesting); |
| 2016 | |
| 2017 | in[incnesting] = fopen(f, "r"); |
| 2018 | if (!in[incnesting]) { |
| 2019 | incnesting--; |
| 2020 | return (0); |
| 2021 | } |
| 2022 | filenames[incnesting] = f; |
| 2023 | zn[incnesting] = linenr = 0; |
| 2024 | return (1); |
| 2025 | } |
| 2026 | |
| 2027 | |
| 2028 | |
| 2029 | /* ********************** Main-Function ******************* */ |
| 2030 | int pp_nextline(void) |
| 2031 | { |
| 2032 | char *src, *dest, *temp; |
| 2033 | int complete_len, len, i, result; |
| 2034 | struct mnode *makro; |
| 2035 | struct strnode *linelist, *inclinelist; |
| 2036 | |
| 2037 | if (DEBUG & 32) |
| 2038 | puts("pp_nextline"); |
| 2039 | |
| 2040 | dest = string; |
| 2041 | dest[0] = 0; |
| 2042 | |
| 2043 | /* String vorbereiten, 3ZF ersetzen, \-Zeilen anhaengen, Kommentare loeschen */ |
| 2044 | if (!PreParse()) |
| 2045 | return (0); |
| 2046 | |
| 2047 | /* Ueberpruefung auf PreProcessor-Commands */ |
| 2048 | src = string; |
| 2049 | /*vb: casts eingefuegt */ |
| 2050 | while (isspace((unsigned char) *src)) { |
| 2051 | src++; |
| 2052 | } /* SkipSpaces */ |
| 2053 | |
| 2054 | if (*src == '#') { /* #-Direktive gefunden */ |
| 2055 | src++; /* # ueberlesen */ |
| 2056 | |
| 2057 | while (isspace((unsigned char) *src)) { |
| 2058 | src++; |
| 2059 | } /* SkipSpaces */ |
| 2060 | |
| 2061 | /*vb: Direktiven, die nichts mit #if etc. zu tun haben, nach hinten */ |
| 2062 | |
| 2063 | |
| 2064 | /* IFDEF */ |
| 2065 | if (!strncmp(src, "ifdef", 5)) { |
| 2066 | src += 5; |
| 2067 | abs_if_cnt++; /*vb: */ |
| 2068 | if (isspace((unsigned char) *src)) { |
| 2069 | while (isspace((unsigned char) *src)) { |
| 2070 | src++; |
| 2071 | } |
| 2072 | /* identifier suchen */ |
| 2073 | if (do_output) { |
| 2074 | /*vb: */ |
| 2075 | /* if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */ |
| 2076 | /* ifnesting++; */ |
| 2077 | temp = src; |
| 2078 | len = 0; |
| 2079 | while ((isalnum((unsigned char) *temp)) || (*temp == '_')) { |
| 2080 | temp++; |
| 2081 | len++; |
| 2082 | } |
| 2083 | makro = FindMakroNode(mlist, src, len); |
| 2084 | if (DEBUG & 32) |
| 2085 | printf("-- #ifdef found, "); |
| 2086 | if (makro) { |
| 2087 | /*vb: */ |
| 2088 | ifstatus[incnesting] = 1; /* Bedingung == TRUE */ |
| 2089 | if (DEBUG & 32) |
| 2090 | printf(" condition '%s' found (TRUE)\n", makro->name); |
| 2091 | } else { |
| 2092 | /*vb: */ |
| 2093 | ifstatus[incnesting] = 2; /* Bedingung == FALSE */ |
| 2094 | do_output = 0; |
| 2095 | if (DEBUG & 32) |
| 2096 | printf(" condition not found (FALSE)\n\n"); |
| 2097 | } |
| 2098 | } else { |
| 2099 | if_cnt++; |
| 2100 | if (DEBUG & 32) |
| 2101 | printf("-- #ifdef found and if_cnt increased\n\n"); |
| 2102 | } |
| 2103 | string[0] = 0; /*vb: yo */ |
| 2104 | return (1); |
| 2105 | } |
| 2106 | } /* EO IFDEF */ |
| 2107 | /* IFNDEF */ |
| 2108 | if (!strncmp(src, "ifndef", 6)) { |
| 2109 | src += 6; |
| 2110 | abs_if_cnt++; /*vb: */ |
| 2111 | if (isspace((unsigned char) *src)) { |
| 2112 | while (isspace((unsigned char) *src)) { |
| 2113 | src++; |
| 2114 | } |
| 2115 | |
| 2116 | /* identifier suchen */ |
| 2117 | if (do_output) { |
| 2118 | /*vb: */ |
| 2119 | /* if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */ |
| 2120 | /* ifnesting++; */ |
| 2121 | temp = src; |
| 2122 | len = 0; |
| 2123 | while ((isalnum((unsigned char) *temp)) || (*temp == '_')) { |
| 2124 | temp++; |
| 2125 | len++; |
| 2126 | } |
| 2127 | if (DEBUG & 32) |
| 2128 | printf("-- FindMakroNode: len=%d temp=%p\n", len, (void*)temp); |
| 2129 | makro = FindMakroNode(mlist, src, len); |
| 2130 | if (DEBUG & 32) |
| 2131 | printf("-- #ifndef found, "); |
| 2132 | if (!makro) { |
| 2133 | /*vb: */ |
| 2134 | ifstatus[incnesting] = 1; /* Bedingung == TRUE (Makro not existing) */ |
| 2135 | if (DEBUG & 32) |
| 2136 | printf(" condition not found (TRUE)\n\n"); |
| 2137 | } else { |
| 2138 | /*vb: */ |
| 2139 | ifstatus[incnesting] = 2; /* Bedingung == FALSE */ |
| 2140 | do_output = 0; |
| 2141 | if (DEBUG & 32) |
| 2142 | printf(" condition '%s' found (FALSE)\n\n", makro->name); |
| 2143 | } |
| 2144 | /* HIER: string[0]=0; */ |
| 2145 | } else { |
| 2146 | if_cnt++; |
| 2147 | if (DEBUG & 32) |
| 2148 | printf("-- #ifndef found and if_cnt increased\n\n"); |
| 2149 | } |
| 2150 | string[0] = 0; /*vb: */ |
| 2151 | return (1); |
| 2152 | } |
| 2153 | } /* EO IFNDEF */ |
| 2154 | /* IF */ |
| 2155 | if (!strncmp(src, "if", 2)) { |
| 2156 | src += 2; |
| 2157 | abs_if_cnt++; /*vb: */ |
| 2158 | if (isspace((unsigned char) *src)) { |
| 2159 | while (isspace((unsigned char) *src)) { |
| 2160 | src++; |
| 2161 | } |
| 2162 | /* Bedingung auswerten */ |
| 2163 | |
| 2164 | |
| 2165 | |
| 2166 | printf("****** WARNING ******* #if is not yet implemented\n"); |
| 2167 | |
| 2168 | |
| 2169 | string[0] = 0; /*vb: */ |
| 2170 | return (1); |
| 2171 | } |
| 2172 | } /* EO IF */ |
| 2173 | /* ELIF */ |
| 2174 | if (!strncmp(src, "elif", 4)) { |
| 2175 | src += 4; |
| 2176 | if (isspace((unsigned char) *src)) { |
| 2177 | while (isspace((unsigned char) *src)) { |
| 2178 | src++; |
| 2179 | } |
| 2180 | /* Bedingung auswerten */ |
| 2181 | |
| 2182 | |
| 2183 | |
| 2184 | |
| 2185 | |
| 2186 | printf("****** WARNING ******* #elif is not yet implemented\n"); |
| 2187 | |
| 2188 | |
| 2189 | |
| 2190 | |
| 2191 | string[0] = 0; /*vb: */ |
| 2192 | return (1); |
| 2193 | } |
| 2194 | } /* EO ELIF */ |
| 2195 | /* ELSE */ |
| 2196 | if (!strncmp(src, "else", 4)) { |
| 2197 | src += 4; |
| 2198 | if (isspace((unsigned char) *src) || *src == 0) { |
| 2199 | while (isspace((unsigned char) *src)) { |
| 2200 | src++; |
| 2201 | } |
| 2202 | |
| 2203 | if (!if_cnt) { |
| 2204 | switch (ifstatus[incnesting]) { /*vb: */ |
| 2205 | case 0: |
| 2206 | error(188); |
| 2207 | return (0); |
| 2208 | break; |
| 2209 | case 1: |
| 2210 | do_output = 0; |
| 2211 | /* HIER: auf #endif suchen SearchENDIF(); */ |
| 2212 | /* HIER: ifnesting--; do_output=1; */ |
| 2213 | break; |
| 2214 | case 2: |
| 2215 | ifstatus[incnesting] = 3; /*vb: */ |
| 2216 | do_output = 1; |
| 2217 | break; |
| 2218 | case 3: |
| 2219 | error(189); |
| 2220 | return (0); |
| 2221 | break; |
| 2222 | } |
| 2223 | } |
| 2224 | string[0] = 0; /*vb: */ |
| 2225 | return (1); |
| 2226 | } |
| 2227 | } /* EO ELSE */ |
| 2228 | /* ENDIF */ |
| 2229 | if (!strncmp(src, "endif", 5)) { |
| 2230 | src += 5; |
| 2231 | abs_if_cnt--; /*vb: */ |
| 2232 | if (isspace((unsigned char) *src) || *src == 0) { |
| 2233 | while (isspace((unsigned char) *src)) { |
| 2234 | src++; |
| 2235 | } |
| 2236 | /* HIER: Auf Zeilenende testen */ |
| 2237 | |
| 2238 | if (DEBUG & 32) |
| 2239 | printf("-- #endif found, "); |
| 2240 | |
| 2241 | if (if_cnt) { |
| 2242 | if_cnt--; |
| 2243 | if (DEBUG & 32) |
| 2244 | printf("if_cnt decreased (to %d)\n", if_cnt); |
| 2245 | } else { |
| 2246 | if (DEBUG & 32) |
| 2247 | printf("ifnesting: %d ifstatus: %d\n", incnesting, ifstatus[incnesting]); |
| 2248 | if (abs_if_cnt < 0 /*(incnesting==-1)||ifstatus[incnesting]==0 */ ) { /*vb: */ |
| 2249 | error(190); |
| 2250 | return (0); |
| 2251 | } |
| 2252 | /* ifnesting--; *//*vb: */ |
| 2253 | /* HIER: evtl. do_output entsprechend ifstatus[] setzen */ |
| 2254 | /*vb: natuerlich */ |
| 2255 | do_output = 1; |
| 2256 | ifstatus[incnesting] = abs_if_cnt > 0; /*vb: 1 oder 0 */ |
| 2257 | } |
| 2258 | string[0] = 0; /*vb: ja */ |
| 2259 | return (1); |
| 2260 | } |
| 2261 | } /* EO ENDIF */ |
| 2262 | /*vb: andere Direktiven gegebenenfalls ueberspringen */ |
| 2263 | if (!do_output) { |
| 2264 | if (DEBUG & 32) |
| 2265 | printf("do_output==0 => skipping: %s\n", src); |
| 2266 | string[0] = 0; |
| 2267 | return (1); |
| 2268 | } |
| 2269 | /* DEFINE */ |
| 2270 | if ( /*(do_output)&& */ (!strncmp(src, "define", 6))) { /*vb: */ |
| 2271 | if (DEBUG & 32) |
| 2272 | printf("#define found\n"); |
| 2273 | src += 6; |
| 2274 | if (isspace((unsigned char) *src)) { |
| 2275 | while (isspace((unsigned char) *src)) { |
| 2276 | src++; |
| 2277 | } |
| 2278 | if (ParseIdentifier(src)) { |
| 2279 | string[0] = 0; |
| 2280 | return (1); |
| 2281 | } else { |
| 2282 | if (DEBUG & 32) |
| 2283 | printf("ParseIdent returned 0\n"); |
| 2284 | return (0); |
| 2285 | } |
| 2286 | } |
| 2287 | } /* EO DEFINE */ |
| 2288 | /* UNDEF */ |
| 2289 | if ( /*(do_output)&& */ (!strncmp(src, "undef", 5))) { /*vb: */ |
| 2290 | src += 5; |
| 2291 | if (isspace((unsigned char) *src)) { |
| 2292 | while (isspace((unsigned char) *src)) { |
| 2293 | src++; |
| 2294 | } |
| 2295 | temp = src; |
| 2296 | len = 0; |
| 2297 | while ((isalnum((unsigned char) *temp)) || (*temp == '_')) { |
| 2298 | temp++; |
| 2299 | len++; |
| 2300 | } |
| 2301 | makro = FindMakroNode(mlist, src, len); |
| 2302 | if (makro->flags & NODELETE) { |
| 2303 | error(199); |
| 2304 | } else { |
| 2305 | DelMakroNode(&mlist, makro); |
| 2306 | } |
| 2307 | while (isspace((unsigned char) *temp)) { |
| 2308 | temp++; |
| 2309 | } |
| 2310 | if (*temp != 0 && *temp != '\n') { |
| 2311 | error(200); |
| 2312 | } |
| 2313 | string[0] = 0; |
| 2314 | return (1); |
| 2315 | } |
| 2316 | } /* EO UNDEF */ |
| 2317 | /* INCLUDE */ |
| 2318 | if ( /*(do_output)&& */ (!strncmp(src, "include", 7))) { /*vb: */ |
| 2319 | src += 7; |
| 2320 | if (isspace((unsigned char) *src)) { |
| 2321 | while (isspace((unsigned char) *src)) { |
| 2322 | src++; |
| 2323 | } |
| 2324 | if (*src != '<' && *src != '\"') { |
| 2325 | /* Versuchen den Rest zu expandieren */ |
| 2326 | inclinelist = Str2List(src); |
| 2327 | if (!ExpandList(&inclinelist)) { |
| 2328 | if (List2Str(inclinelist, src, MAXINPUT - (src - string))) { |
| 2329 | /* HIER exit ? */ |
| 2330 | } |
| 2331 | } else { |
| 2332 | error(191); /* HIER exit ? */ |
| 2333 | } |
| 2334 | } |
| 2335 | /*vb: geaendert, so dass #include "..." auch noch im Standardpfad sucht */ |
| 2336 | if (DEBUG & 32) |
| 2337 | printf("includename=%s\n", src); |
| 2338 | if (*src == '<' || *src == '\"') { |
| 2339 | char *m = src, c; |
| 2340 | if (*src == '<') |
| 2341 | c = '>'; |
| 2342 | else |
| 2343 | c = '\"'; |
| 2344 | if (*src == '\"') { |
| 2345 | /* im aktuellen Verzeichnis suchen und includen */ |
| 2346 | src++; |
| 2347 | temp = src; |
| 2348 | len = 0; |
| 2349 | while (*temp != '\"') { |
| 2350 | temp++; |
| 2351 | len++; |
| 2352 | } |
| 2353 | temp++; |
| 2354 | while (isspace((unsigned char) *temp)) |
| 2355 | temp++; |
| 2356 | if (*temp) { |
| 2357 | error(200); |
| 2358 | } |
| 2359 | temp = (char *) malloc(len + 1); |
| 2360 | if (temp) { |
| 2361 | strncpy(temp, src, len); |
| 2362 | *(temp + len) = 0; |
| 2363 | if (pp_include(temp)) { |
| 2364 | AddStrNode(&strlist, NULL, temp); |
| 2365 | string[0] = 0; |
| 2366 | return (1); |
| 2367 | } else { |
| 2368 | if (temp) |
| 2369 | free(temp); |
| 2370 | /*vb: |
| 2371 | error("pp: cannot open file to include",0); |
| 2372 | return(0); */ |
| 2373 | } |
| 2374 | } else { |
| 2375 | error(196); |
| 2376 | } /* HIER: Exit? */ |
| 2377 | } |
| 2378 | /* in den Standard-Verzeichnissen suchen und includen */ |
| 2379 | src = m; |
| 2380 | src++; |
| 2381 | temp = src; |
| 2382 | len = 0; |
| 2383 | while (*temp != c && *temp != 0) { |
| 2384 | temp++; |
| 2385 | len++; |
| 2386 | } /*vb: sicherer */ |
| 2387 | temp++; |
| 2388 | while (isspace((unsigned char) *temp)) |
| 2389 | temp++; |
| 2390 | if (*temp) { |
| 2391 | error(200); |
| 2392 | } |
| 2393 | temp = NULL; |
| 2394 | for (i = 0; i < incpathc; i++) { |
| 2395 | complete_len = strlen(incpath[i]) + len; |
| 2396 | temp = (char *) malloc(complete_len + 1); |
| 2397 | if (temp) { |
| 2398 | strcpy(temp, incpath[i]); |
| 2399 | strncat(temp, src, len); |
| 2400 | *(temp + complete_len) = 0; |
| 2401 | if (pp_include(temp)) { |
| 2402 | AddStrNode(&strlist, NULL, temp); |
| 2403 | if (DEBUG & 32) |
| 2404 | printf("include <%s> found\n", temp); |
| 2405 | string[0] = 0; |
| 2406 | return (1); |
| 2407 | } else { |
| 2408 | if (temp) |
| 2409 | free(temp); |
| 2410 | } |
| 2411 | } else { |
| 2412 | error(196); |
| 2413 | } /* HIER: Exit ? */ |
| 2414 | } /* of FOR i */ |
| 2415 | error(191); |
| 2416 | return (0); |
| 2417 | } else { |
| 2418 | error(192); |
| 2419 | return (0); |
| 2420 | } |
| 2421 | } else { |
| 2422 | error(193); |
| 2423 | return (0); |
| 2424 | } |
| 2425 | } /* EO INCLUDE */ |
| 2426 | /* LINE */ |
| 2427 | if (!strncmp(src, "line", 4)) { |
| 2428 | src += 4; |
| 2429 | if (isspace((unsigned char) *src)) { |
| 2430 | return (1); /* Ignorieren und an Compiler weiterreichen */ |
| 2431 | } |
| 2432 | } /* EO LINE */ |
| 2433 | /* ERROR */ |
| 2434 | if (!strncmp(src, "error", 5)) { |
| 2435 | src += 5; |
| 2436 | if (isspace((unsigned char) *src)) { |
| 2437 | while (isspace((unsigned char) *src)) { |
| 2438 | src++; |
| 2439 | } |
| 2440 | |
| 2441 | return (1); |
| 2442 | } |
| 2443 | } /* EO ERROR */ |
| 2444 | /* PRAGMA */ |
| 2445 | if (!strncmp(src, "pragma", 6)) { |
| 2446 | src += 6; |
| 2447 | if (isspace((unsigned char) *src)) { |
| 2448 | while (isspace((unsigned char) *src)) { |
| 2449 | src++; |
| 2450 | } |
| 2451 | |
| 2452 | return (1); |
| 2453 | } |
| 2454 | } /* EO PRAGMA */ |
| 2455 | /* Unknown */ |
| 2456 | /* if(do_output){ */ |
| 2457 | /*vb: */ |
| 2458 | error(193); |
| 2459 | return (0); |
| 2460 | /* } *//*vb: */ |
| 2461 | } else if (do_output) { |
| 2462 | /* Normale Anweisung. Komplette Zeile expandieren */ |
| 2463 | |
| 2464 | /*vb: */ |
| 2465 | |
| 2466 | linelist = Str2List(string); |
| 2467 | |
| 2468 | if (DEBUG & 32) |
| 2469 | PrintTL(linelist); |
| 2470 | |
| 2471 | /*vb: */ |
| 2472 | did_expand = 0; |
| 2473 | |
| 2474 | if (result = ExpandList(&linelist)) { |
| 2475 | switch (result) { |
| 2476 | case OUT_OF_MEM: |
| 2477 | error(196); |
| 2478 | break; |
| 2479 | case NUM_OF_ARGS: |
| 2480 | error(194); |
| 2481 | break; |
| 2482 | case ARG_EXPECTED: |
| 2483 | error(195); |
| 2484 | break; |
| 2485 | default: |
| 2486 | ierror(0); |
| 2487 | break; |
| 2488 | } |
| 2489 | DelStrList(&linelist); |
| 2490 | return (0); |
| 2491 | } |
| 2492 | if (DEBUG & 32) |
| 2493 | PrintTL(linelist); |
| 2494 | |
| 2495 | /*vb: List2Str nur aufrufen, falls etwas expandiert wurde */ |
| 2496 | if (did_expand && !List2Str(linelist, string, MAXINPUT)) { |
| 2497 | DelStrList(&linelist); |
| 2498 | return (0); |
| 2499 | } |
| 2500 | DelStrList(&linelist); |
| 2501 | |
| 2502 | /*vb: */ |
| 2503 | } else |
| 2504 | string[0] = 0; |
| 2505 | return (1); |
| 2506 | } |