|
|
1.1 ! root 1: %{ ! 2: ! 3: /* ! 4: * Copyright (c) 1988 Regents of the University of California. ! 5: * All rights reserved. ! 6: * ! 7: * Redistribution and use in source and binary forms are permitted ! 8: * provided that the above copyright notice and this paragraph are ! 9: * duplicated in all such forms and that any documentation, ! 10: * advertising materials, and other materials related to such ! 11: * distribution and use acknowledge that the software was developed ! 12: * by the University of California, Berkeley. The name of the ! 13: * University may not be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: * ! 19: * @(#)mkmake.y 4.1 (Berkeley) 12/4/88 ! 20: */ ! 21: ! 22: typedef struct string { ! 23: int ! 24: hashval, ! 25: length; ! 26: char ! 27: *string; ! 28: struct string ! 29: *next; ! 30: } string_t; ! 31: ! 32: /* ! 33: * The deal with these is that they exist on various lists. ! 34: * ! 35: * First off, they are on a temporary list during the time they ! 36: * are in the active focus of the parser. ! 37: * ! 38: * Secondly, they live on one of three queues: ! 39: * 1. Variables ! 40: * 2. Targets ! 41: * 3. Actions ! 42: * (and, we restrict any given one to live on one and only one such list) ! 43: * ! 44: * Also, they may live on the list of values for someone else's variable, ! 45: * or as someone's dependancy. ! 46: */ ! 47: ! 48: typedef struct same { ! 49: string_t ! 50: *string; /* My name */ ! 51: struct same ! 52: *nexttoken, /* Next pointer */ ! 53: *lasttoken, /* Back pointer */ ! 54: *depend_list, /* If target, dependancies */ ! 55: *action_list, /* If target, actions */ ! 56: *value_list, /* If variable, value list */ ! 57: *shell_item; /* If a shell variable, current value */ ! 58: } same_t; ! 59: ! 60: %} ! 61: ! 62: %union { ! 63: string_t *string; ! 64: same_t *same; ! 65: int intval; ! 66: } ! 67: ! 68: %start makefile ! 69: %token <string> TOKEN QUOTED_STRING ! 70: %token <intval> FOR IN DO DONE ! 71: %token <intval> MACRO_CHAR NL WHITE_SPACE ! 72: %token <intval> ':' '=' '$' '{' '}' ';' '-' '@' '(' ')' ' ' '\t' ! 73: %type <same> target target1 assignment assign1 actions action ! 74: %type <same> command_list list list_element ! 75: %type <same> for_statement maybe_at_minus tokens token ! 76: %type <same> maybe_white_space ! 77: %type <intval> white_space macro_char ! 78: %% ! 79: ! 80: makefile : lines; ! 81: ! 82: lines : line ! 83: | lines line ! 84: ; ! 85: ! 86: line : NL ! 87: | assignment ! 88: | target_action ! 89: ; ! 90: ! 91: assignment : assign1 tokens NL ! 92: { ! 93: assign($1, $2); ! 94: } ! 95: | assign1 NL ! 96: { ! 97: assign($1, same_copy(null)); ! 98: } ! 99: ; ! 100: ! 101: assign1: token maybe_white_space '=' maybe_white_space ! 102: ; ! 103: ! 104: target_action: target actions ! 105: { ! 106: add_targets_actions($1, $2); ! 107: } ! 108: | target ! 109: { ! 110: add_targets_actions($1, 0); ! 111: } ! 112: ; ! 113: ! 114: target : target1 tokens NL ! 115: { ! 116: $$ = add_depends($1, $2); ! 117: } ! 118: | target1 NL ! 119: { ! 120: $$ = add_depends($1, same_copy(null)); ! 121: } ! 122: ; ! 123: ! 124: target1: tokens maybe_white_space ':' maybe_white_space ! 125: { ! 126: $$ = ws_merge($1); ! 127: } ! 128: ; ! 129: ! 130: actions: action ! 131: | actions action ! 132: { ! 133: $$ = same_cat(same_cat($1, same_copy(newline)), $2); ! 134: } ! 135: ; ! 136: ! 137: action: white_space command_list NL ! 138: { ! 139: $$ = $2; ! 140: } ! 141: | white_space for_statement do command_list semi_colon done NL ! 142: { ! 143: $$ = do_command($2, $4); ! 144: } ! 145: ; ! 146: ! 147: for_statement: maybe_at_minus FOR white_space token ! 148: in tokens semi_colon ! 149: { ! 150: $$ = for_statement($1, $4, ws_merge(expand_variables($6, 0))); ! 151: } ! 152: ; ! 153: ! 154: in: white_space IN white_space ! 155: do: white_space DO white_space ! 156: ; ! 157: ! 158: done: white_space DONE ! 159: ; ! 160: ! 161: semi_colon: ';' ! 162: ; ! 163: ! 164: command_list: list ! 165: | '(' list maybe_white_space ')' ! 166: { ! 167: $$ = same_cat($2, same_copy(cwd_line)); ! 168: } ! 169: ; ! 170: ! 171: list: token ! 172: | list list_element ! 173: { ! 174: $$ = same_cat($1, $2); ! 175: } ! 176: | list white_space list_element ! 177: { ! 178: $$ = same_cat($1, same_cat(same_copy(blank), $3)); ! 179: } ! 180: ; ! 181: ! 182: list_element: token ! 183: | semi_colon ! 184: { ! 185: $$ = same_copy(newline); ! 186: } ! 187: ; ! 188: ! 189: maybe_at_minus: /* empty */ ! 190: { ! 191: $$ = same_copy(null); ! 192: } ! 193: | '@' ! 194: { ! 195: char buffer[2]; ! 196: ! 197: buffer[0] = $1; ! 198: buffer[1] = 0; ! 199: $$ = same_item(string_lookup(buffer)); ! 200: } ! 201: | '-' ! 202: { ! 203: char buffer[2]; ! 204: ! 205: buffer[0] = $1; ! 206: buffer[1] = 0; ! 207: $$ = same_item(string_lookup(buffer)); ! 208: } ! 209: ; ! 210: ! 211: tokens : token ! 212: | tokens maybe_white_space token ! 213: { ! 214: $$ = same_cat($1, same_cat($2, $3)); ! 215: } ! 216: ; ! 217: ! 218: token: TOKEN ! 219: { ! 220: $$ = same_item($1); ! 221: } ! 222: | QUOTED_STRING ! 223: { ! 224: $$ = same_item($1); ! 225: } ! 226: | '$' macro_char ! 227: { ! 228: char buffer[3]; ! 229: ! 230: buffer[0] = '$'; ! 231: buffer[1] = $2; ! 232: buffer[2] = 0; ! 233: ! 234: $$ = same_item(string_lookup(buffer)); ! 235: } ! 236: | '$' '$' TOKEN ! 237: { ! 238: $$ = shell_variable(same_item($3)); ! 239: } ! 240: | MACRO_CHAR ! 241: { ! 242: $$ = same_char($1); ! 243: } ! 244: | '$' '{' TOKEN '}' ! 245: { ! 246: $$ = variable(same_item($3)); ! 247: } ! 248: | '$' '(' TOKEN ')' ! 249: { ! 250: $$ = variable(same_item($3)); ! 251: } ! 252: | '$' TOKEN ! 253: { ! 254: $$ = variable(same_item($2)); ! 255: } ! 256: | '-' ! 257: { ! 258: $$ = same_char('-'); ! 259: } ! 260: | '@' ! 261: { ! 262: $$ = same_char('@'); ! 263: } ! 264: ; ! 265: ! 266: macro_char: MACRO_CHAR ! 267: | '@' ! 268: ; ! 269: ! 270: maybe_white_space: ! 271: { ! 272: $$ = same_copy(null); ! 273: } ! 274: | white_space ! 275: { ! 276: $$ = same_char($1); ! 277: } ! 278: ; ! 279: ! 280: white_space : WHITE_SPACE ! 281: | white_space WHITE_SPACE ! 282: ; ! 283: %% ! 284: #include <stdio.h> ! 285: #include <ctype.h> ! 286: ! 287: static int last_char, last_saved = 0; ! 288: static int column = 0, lineno = 1; ! 289: ! 290: ! 291: static string_t ! 292: *strings = 0; ! 293: ! 294: static same_t ! 295: *shell_variables = 0, ! 296: *shell_special = 0, ! 297: *variables = 0, ! 298: *targets = 0, ! 299: *actions = 0; ! 300: ! 301: static same_t ! 302: *null, ! 303: *blank, ! 304: *cwd_line, ! 305: *newline; ! 306: ! 307: extern char *malloc(); ! 308: ! 309: static unsigned int ! 310: clock = -1; ! 311: ! 312: struct { ! 313: same_t *first; ! 314: int next; ! 315: } visit_stack[20]; /* 20 maximum */ ! 316: ! 317: #define visit(what,via) \ ! 318: (visit_stack[++clock].next = 0, visit_stack[clock].first = via = what) ! 319: #define visited(via) (visitcheck(via) || ((via) == 0) \ ! 320: || (visit_stack[clock].next && (via == visit_stack[clock].first))) ! 321: #define visit_next(via) (visit_stack[clock].next = 1, (via) = (via)->nexttoken) ! 322: #define visit_end() (clock--) ! 323: ! 324: yyerror(s) ! 325: char *s; ! 326: { ! 327: fprintf(stderr, "line %d, character %d: %s\n", lineno, column, s); ! 328: do_dump(); ! 329: } ! 330: ! 331: int ! 332: visitcheck(same) ! 333: same_t *same; ! 334: { ! 335: if (same->string == 0) { ! 336: yyerror("BUG - freed 'same' in use..."); ! 337: exit(1); ! 338: } ! 339: return 0; ! 340: } ! 341: ! 342: int ! 343: string_hashof(string, length) ! 344: char *string; ! 345: int length; ! 346: { ! 347: register int i = 0; ! 348: ! 349: while (length--) { ! 350: i = (i<<3) + *string ^ ((i>>28)&0x7); ! 351: } ! 352: return i; ! 353: } ! 354: ! 355: int ! 356: string_same(s1, s2) ! 357: string_t ! 358: *s1, *s2; ! 359: { ! 360: if ((s1->hashval == s2->hashval) && (s1->length == s2->length) ! 361: && (memcmp(s1->string, s2->string, s1->length) == 0)) { ! 362: return 1; ! 363: } else { ! 364: return 0; ! 365: } ! 366: } ! 367: ! 368: string_t * ! 369: string_lookup(string) ! 370: char *string; ! 371: { ! 372: string_t ours; ! 373: string_t *ptr; ! 374: ! 375: ours.length = strlen(string); ! 376: ours.hashval = string_hashof(string, ours.length); ! 377: ours.string = string; ! 378: ! 379: for (ptr = strings; ptr; ptr = ptr->next) { ! 380: if (string_same(&ours, ptr)) { ! 381: return ptr; ! 382: } ! 383: } ! 384: if ((ptr = (string_t *)malloc(sizeof *ptr)) == 0) { ! 385: fprintf(stderr, "No space to add string *%s*!\n", string); ! 386: exit(1); ! 387: } ! 388: ptr->hashval = ours.hashval; ! 389: ptr->length = ours.length; ! 390: if ((ptr->string = malloc(ours.length+1)) == 0) { ! 391: fprintf(stderr, "No space to add literal *%s*!\n", string); ! 392: exit(1); ! 393: } ! 394: memcpy(ptr->string, string, ours.length+1); ! 395: ptr->next = strings; ! 396: strings = ptr; ! 397: return ptr; ! 398: } ! 399: ! 400: #define same_singleton(s) ((s)->nexttoken == (s)) ! 401: ! 402: same_t * ! 403: same_search(list, token) ! 404: same_t ! 405: *list, ! 406: *token; ! 407: { ! 408: same_t *ptr; ! 409: ! 410: ptr = list; ! 411: for (visit(list, ptr); !visited(ptr); visit_next(ptr)) { ! 412: string_t *string; ! 413: ! 414: string = ptr->string; ! 415: if (string_same(string, token->string)) { ! 416: visit_end(); ! 417: return ptr; ! 418: } ! 419: } ! 420: visit_end(); ! 421: return 0; ! 422: } ! 423: ! 424: same_t * ! 425: same_cat(list, tokens) ! 426: same_t ! 427: *list, ! 428: *tokens; ! 429: { ! 430: same_t *last; ! 431: ! 432: if (tokens == 0) { ! 433: return list; ! 434: } ! 435: if (list) { ! 436: last = tokens->lasttoken; ! 437: tokens->lasttoken = list->lasttoken; ! 438: list->lasttoken = last; ! 439: tokens->lasttoken->nexttoken = tokens; ! 440: last->nexttoken = list; ! 441: return list; ! 442: } else { ! 443: return tokens; ! 444: } ! 445: } ! 446: ! 447: same_t * ! 448: same_item(string) ! 449: string_t *string; ! 450: { ! 451: same_t *ptr; ! 452: ! 453: if ((ptr = (same_t *)malloc(sizeof *ptr)) == 0) { ! 454: fprintf(stderr, "No more space for tokens!\n"); ! 455: exit(1); ! 456: } ! 457: memset((char *)ptr, 0, sizeof *ptr); ! 458: ptr->nexttoken = ptr->lasttoken = ptr; ! 459: ptr->string = string; ! 460: return ptr; ! 461: } ! 462: ! 463: same_t * ! 464: same_copy(same) ! 465: same_t *same; ! 466: { ! 467: same_t *head, *copy; ! 468: ! 469: head = 0; ! 470: for (visit(same, copy); !visited(copy); visit_next(copy)) { ! 471: same_t *ptr; ! 472: ! 473: ptr = same_item(copy->string); ! 474: head = same_cat(head, ptr); ! 475: } ! 476: visit_end(); ! 477: return head; ! 478: } ! 479: ! 480: ! 481: same_t * ! 482: same_merge(t1, t2) ! 483: same_t ! 484: *t1, ! 485: *t2; ! 486: { ! 487: if (same_singleton(t1) && same_singleton(t2)) { ! 488: int length = strlen(t1->string->string)+strlen(t2->string->string); ! 489: char *buffer = malloc(length+1); ! 490: same_t *value; ! 491: ! 492: if (buffer == 0) { ! 493: yyerror("No space to merge strings in same_merge!"); ! 494: exit(1); ! 495: } ! 496: strcpy(buffer, t1->string->string); ! 497: strcat(buffer, t2->string->string); ! 498: value = same_item(string_lookup(buffer)); ! 499: free(buffer); ! 500: return value; ! 501: } else { ! 502: yyerror("Internal error - same_merge with non-singletons"); ! 503: exit(1); ! 504: } ! 505: } ! 506: ! 507: ! 508: void ! 509: same_free(list) ! 510: same_t *list; ! 511: { ! 512: same_t *token, *ptr; ! 513: ! 514: if (list == 0) { ! 515: return; ! 516: } ! 517: ! 518: token = list; ! 519: do { ! 520: ptr = token->nexttoken; ! 521: token->string = 0; ! 522: (void) free((char *)token); ! 523: token = ptr; ! 524: } while (token != list); ! 525: } ! 526: ! 527: same_t * ! 528: same_unlink(token) ! 529: same_t ! 530: *token; ! 531: { ! 532: same_t *tmp; ! 533: ! 534: if (token == 0) { ! 535: return 0; ! 536: } ! 537: if ((tmp = token->nexttoken) == token) { ! 538: tmp = 0; ! 539: } ! 540: token->lasttoken->nexttoken = token->nexttoken; ! 541: token->nexttoken->lasttoken = token->lasttoken; ! 542: token->nexttoken = token->lasttoken = token; ! 543: return tmp; ! 544: } ! 545: ! 546: void ! 547: same_replace(old, new) ! 548: same_t ! 549: *old, ! 550: *new; ! 551: { ! 552: new->lasttoken->nexttoken = old->nexttoken; ! 553: old->nexttoken->lasttoken = new->lasttoken; ! 554: new->lasttoken = old->lasttoken; ! 555: /* rather than ! 556: * old->lasttoken->nexttoken = new ! 557: * we update in place (for the case where there isn't anything else) ! 558: */ ! 559: *old = *new; ! 560: } ! 561: ! 562: ! 563: same_t * ! 564: same_char(ch) ! 565: char ch; ! 566: { ! 567: char buffer[2]; ! 568: ! 569: buffer[0] = ch; ! 570: buffer[1] = 0; ! 571: ! 572: return same_item(string_lookup(buffer)); ! 573: } ! 574: ! 575: ! 576: void ! 577: add_target(target, actions) ! 578: same_t ! 579: *target, ! 580: *actions; ! 581: { ! 582: same_t *ptr; ! 583: ! 584: if ((ptr = same_search(targets, target)) == 0) { ! 585: targets = same_cat(targets, target); ! 586: ptr = target; ! 587: } else { ! 588: ptr->depend_list = same_cat(ptr->depend_list, target->depend_list); ! 589: } ! 590: if (actions) { ! 591: if (ptr->action_list) { ! 592: same_free(ptr->action_list); ! 593: } ! 594: ptr->action_list = same_copy(actions); ! 595: } ! 596: } ! 597: ! 598: ! 599: same_t * ! 600: add_targets_actions(target, actions) ! 601: same_t ! 602: *target, ! 603: *actions; ! 604: { ! 605: same_t *ptr; ! 606: ! 607: if (target == 0) { ! 608: return 0; ! 609: } ! 610: do { ! 611: ptr = same_unlink(target); ! 612: add_target(target, actions); ! 613: target = ptr; ! 614: } while (target); ! 615: ! 616: same_free(actions); ! 617: return 0; ! 618: } ! 619: ! 620: same_t * ! 621: add_depends(target, depends) ! 622: same_t ! 623: *target, ! 624: *depends; ! 625: { ! 626: same_t *original = target; ! 627: ! 628: depends = same_cat(depends, same_copy(blank)); /* Separator */ ! 629: ! 630: for (visit(original, target); !visited(target); visit_next(target)) { ! 631: target->depend_list = same_cat(target->depend_list, same_copy(depends)); ! 632: } ! 633: visit_end(); ! 634: same_free(depends); ! 635: ! 636: return original; ! 637: } ! 638: ! 639: ! 640: /* ! 641: * We know that variable is a singleton ! 642: */ ! 643: ! 644: void ! 645: assign(variable, value) ! 646: same_t ! 647: *variable, ! 648: *value; ! 649: { ! 650: same_t *ptr; ! 651: ! 652: if ((ptr = same_search(variables, variable)) != 0) { ! 653: same_free(ptr->value_list); ! 654: variables = same_unlink(ptr); ! 655: same_free(ptr); ! 656: } ! 657: variable->value_list = value; ! 658: variables = same_cat(variables, variable); ! 659: } ! 660: ! 661: same_t * ! 662: value_of(variable) ! 663: same_t *variable; ! 664: { ! 665: same_t *ptr = same_search(variables, variable); ! 666: ! 667: if (ptr == 0) { ! 668: return same_copy(null); ! 669: } else { ! 670: return same_copy(ptr->value_list); ! 671: } ! 672: } ! 673: ! 674: ! 675: same_t * ! 676: expand_variables(token, free) ! 677: same_t *token; ! 678: int free; ! 679: { ! 680: same_t *head = 0; ! 681: ! 682: if (!free) { ! 683: token = same_copy(token); /* Get our private copy */ ! 684: } ! 685: ! 686: while (token) { ! 687: char *string = token->string->string; ! 688: same_t *tmp = same_unlink(token); ! 689: ! 690: if ((string[0] == '$') && (string[1] == '{')) { /* Expand time */ ! 691: int len = strlen(string); ! 692: ! 693: string[len-1] = 0; ! 694: head = same_cat(head, expand_variables( ! 695: value_of(same_item(string_lookup(string+2))), 1)); ! 696: string[len-1] = '}'; ! 697: } else { ! 698: head = same_cat(head, token); ! 699: } ! 700: token = tmp; ! 701: } ! 702: return head; ! 703: } ! 704: ! 705: ! 706: same_t * ! 707: ws_merge(list) ! 708: same_t *list; ! 709: { ! 710: same_t *newlist = 0, *item; ! 711: int what = 0; ! 712: ! 713: while (list) { ! 714: switch (what) { ! 715: case 0: ! 716: if (isspace(list->string->string[0])) { ! 717: ; ! 718: } else { ! 719: item = same_item(list->string); ! 720: what = 1; ! 721: } ! 722: break; ! 723: case 1: ! 724: if (isspace(list->string->string[0])) { ! 725: newlist = same_cat(newlist, item); ! 726: item = 0; ! 727: what = 0; ! 728: } else { ! 729: item = same_merge(item, same_item(list->string)); ! 730: what = 1; ! 731: } ! 732: break; ! 733: } ! 734: list = same_unlink(list); ! 735: } ! 736: return same_cat(newlist, item); ! 737: } ! 738: ! 739: ! 740: same_t * ! 741: variable(var_name) ! 742: same_t *var_name; ! 743: { ! 744: int length = strlen(var_name->string->string); ! 745: same_t *resolved; ! 746: char *newname; ! 747: ! 748: if ((newname = malloc(length+1+3)) == 0) { ! 749: fprintf("Out of space for a variable name.\n"); ! 750: exit(1); ! 751: } ! 752: newname[0] = '$'; ! 753: newname[1] = '{'; ! 754: strcpy(newname+2, var_name->string->string); ! 755: strcat(newname, "}"); ! 756: resolved = same_item(string_lookup(newname)); ! 757: free(newname); ! 758: ! 759: return resolved; ! 760: } ! 761: ! 762: ! 763: same_t * ! 764: shell_variable(var_name) ! 765: same_t *var_name; ! 766: { ! 767: int length = strlen(var_name->string->string); ! 768: same_t *resolved; ! 769: char *newname; ! 770: ! 771: if ((newname = malloc(length+1+2)) == 0) { ! 772: fprintf("Out of space for a variable name.\n"); ! 773: exit(1); ! 774: } ! 775: newname[0] = '$'; ! 776: newname[1] = '$'; ! 777: strcpy(newname+2, var_name->string->string); ! 778: resolved = same_item(string_lookup(newname)); ! 779: free(newname); ! 780: ! 781: return resolved; ! 782: } ! 783: ! 784: same_t * ! 785: for_statement(special, variable, list) ! 786: same_t ! 787: *special, ! 788: *variable, ! 789: *list; ! 790: { ! 791: variable->shell_item = special; ! 792: variable->value_list = list; ! 793: return variable; ! 794: } ! 795: ! 796: same_t * ! 797: do_command(forlist, commands) ! 798: same_t ! 799: *forlist, ! 800: *commands; ! 801: { ! 802: same_t ! 803: *special, ! 804: *command_list = 0, ! 805: *new_commands, ! 806: *tmp, ! 807: *shell_item, ! 808: *value_list = forlist->value_list; ! 809: char ! 810: *tmpstr, ! 811: *variable_name = forlist->string->string; ! 812: ! 813: special = forlist->shell_item; ! 814: if (same_unlink(forlist->shell_item) != 0) { ! 815: yyerror("Unexpected second item in special part of do_command"); ! 816: exit(1); ! 817: } ! 818: ! 819: while ((shell_item = value_list) != 0) { ! 820: value_list = same_unlink(shell_item); ! 821: /* Visit each item in commands. For each shell variable which ! 822: * matches ours, replace it with ours. ! 823: */ ! 824: new_commands = same_copy(commands); ! 825: for (visit(new_commands, tmp); !visited(tmp); visit_next(tmp)) { ! 826: tmpstr = tmp->string->string; ! 827: if ((tmpstr[0] == '$') && (tmpstr[1] == '$')) { ! 828: if (strcmp(tmpstr+2, variable_name) == 0) { ! 829: same_replace(tmp, same_copy(shell_item)); ! 830: } ! 831: } ! 832: } ! 833: visit_end(); ! 834: command_list = same_cat(command_list, new_commands); ! 835: } ! 836: return same_cat(command_list, same_copy(newline)); ! 837: } ! 838: ! 839: ! 840: int ! 841: Getchar() ! 842: { ! 843: if (last_saved) { ! 844: last_saved = 0; ! 845: return last_char; ! 846: } else { ! 847: int c; ! 848: c = getchar(); ! 849: switch (c) { ! 850: case '\n': ! 851: lineno++; ! 852: column = 0; ! 853: break; ! 854: default: ! 855: column++; ! 856: } ! 857: return c; ! 858: } ! 859: } ! 860: ! 861: ! 862: int ! 863: token_type(string) ! 864: char *string; ! 865: { ! 866: switch (string[0]) { ! 867: case 'f': ! 868: if (strcmp(string, "for") == 0) { ! 869: return FOR; ! 870: } ! 871: break; ! 872: case 'd': ! 873: if (string[1] == 'o') { ! 874: if (strcmp(string, "do") == 0) { ! 875: return DO; ! 876: } else if (strcmp(string, "done") == 0) { ! 877: return DONE; ! 878: } ! 879: } ! 880: break; ! 881: case 'i': ! 882: if (strcmp(string, "in") == 0) { ! 883: return IN; ! 884: } ! 885: break; ! 886: default: ! 887: break; ! 888: } ! 889: return TOKEN; ! 890: } ! 891: ! 892: ! 893: yylex() ! 894: { ! 895: #define ret_token(c) if (bufptr != buffer) { \ ! 896: save(c); \ ! 897: *bufptr = 0; \ ! 898: bufptr = buffer; \ ! 899: yylval.string = string_lookup(buffer); \ ! 900: return token_type(buffer); \ ! 901: } ! 902: #define save(c) { last_char = c; last_saved = 1; } ! 903: #if defined(YYDEBUG) ! 904: #define Return(c) if (yydebug) { \ ! 905: printf("[%d]", c); \ ! 906: fflush(stdout); \ ! 907: } \ ! 908: yyval.intval = c; \ ! 909: return c; ! 910: #else /* defined(YYDEBUG) */ ! 911: #define Return(y,c) { yylval.intval = c; return y; } ! 912: #endif /* defined(YYDEBUG) */ ! 913: ! 914: ! 915: static char buffer[500], *bufptr = buffer; ! 916: static int eof_found = 0; ! 917: int c; ! 918: ! 919: if (eof_found != 0) { ! 920: eof_found++; ! 921: if (eof_found > 2) { ! 922: fprintf(stderr, "End of file ignored.\n"); ! 923: exit(1); ! 924: } ! 925: Return(EOF,0); ! 926: } ! 927: while ((c = Getchar()) != EOF) { ! 928: switch (c) { ! 929: case '#': ! 930: ret_token(c); ! 931: while (((c = Getchar()) != EOF) && (c != '\n')) { ! 932: ; ! 933: } ! 934: save(c); ! 935: break; ! 936: case '<': ! 937: case '?': ! 938: ret_token(c); ! 939: Return(MACRO_CHAR, c); ! 940: case '\t': ! 941: case ' ': ! 942: ret_token(c); ! 943: Return(WHITE_SPACE, c); ! 944: case '-': ! 945: case '@': ! 946: case ':': ! 947: case ';': ! 948: case '=': ! 949: case '$': ! 950: case '{': ! 951: case '}': ! 952: case '(': ! 953: case ')': ! 954: ret_token(c); ! 955: Return(c,c); ! 956: case '\'': ! 957: case '"': ! 958: if (bufptr != buffer) { ! 959: if (bufptr[-1] == '\\') { ! 960: bufptr[-1] = c; ! 961: } ! 962: break; ! 963: } else { ! 964: int newc; ! 965: ! 966: ret_token(c); ! 967: *bufptr++ = c; ! 968: while (((newc = Getchar()) != EOF) && (newc != c)) { ! 969: *bufptr++ = newc; ! 970: } ! 971: *bufptr++ = c; ! 972: *bufptr = 0; ! 973: bufptr = buffer; ! 974: yylval.string = string_lookup(buffer); ! 975: return QUOTED_STRING; ! 976: } ! 977: case '\n': ! 978: if (bufptr != buffer) { ! 979: if (bufptr[-1] == '\\') { ! 980: bufptr--; ! 981: if ((c = Getchar()) != '\t') { ! 982: yyerror("continuation line doesn't begin with a tab"); ! 983: save(c); ! 984: } ! 985: ret_token(c); ! 986: Return(WHITE_SPACE, c); ! 987: } ! 988: } ! 989: ret_token(c); ! 990: Return(NL, 0); ! 991: default: ! 992: *bufptr++ = c; ! 993: break; ! 994: } ! 995: } ! 996: ! 997: eof_found = 1; ! 998: ! 999: ret_token(' '); ! 1000: Return(EOF, 0); ! 1001: } ! 1002: ! 1003: #ifndef lint ! 1004: static char sccsid[] = "@(#)mkmake.y 4.1 (Berkeley) 12/4/88"; ! 1005: #endif /* not lint */ ! 1006: ! 1007: main() ! 1008: { ! 1009: #define YYDEBUG ! 1010: extern int yydebug; ! 1011: ! 1012: null = same_item(string_lookup("")); ! 1013: newline = same_item(string_lookup("\n")); ! 1014: blank = same_item(string_lookup(" ")); ! 1015: cwd_line = same_cat(same_copy(newline), ! 1016: same_cat(same_item(string_lookup("cd ${CWD}")), ! 1017: same_copy(newline))); ! 1018: ! 1019: yyparse(); ! 1020: ! 1021: do_dump(); ! 1022: ! 1023: return 0; ! 1024: } ! 1025: ! 1026: #if defined(YYDEBUG) ! 1027: dump_same(same) ! 1028: same_t *same; ! 1029: { ! 1030: same_t *same2; ! 1031: ! 1032: for (visit(same, same2); !visited(same2); visit_next(same2)) { ! 1033: printf(same2->string->string); ! 1034: } ! 1035: visit_end(); ! 1036: } ! 1037: #endif /* YYDEBUG */ ! 1038: ! 1039: do_dump() ! 1040: { ! 1041: string_t *string; ! 1042: same_t *same, *same2; ! 1043: ! 1044: if (yydebug > 1) { ! 1045: printf("strings...\n"); ! 1046: for (string = strings; string; string = string->next) { ! 1047: printf("\t%s\n", string->string); ! 1048: } ! 1049: } ! 1050: ! 1051: printf("# variables...\n"); ! 1052: for (visit(variables, same); !visited(same); visit_next(same)) { ! 1053: printf("%s =\t", same->string->string); ! 1054: for (visit(same->value_list, same2); !visited(same2); ! 1055: visit_next(same2)) { ! 1056: printf(same2->string->string); ! 1057: } ! 1058: visit_end(); ! 1059: printf("\n"); ! 1060: } ! 1061: visit_end(); ! 1062: ! 1063: printf("\n\n#targets...\n"); ! 1064: for (visit(targets, same); !visited(same); visit_next(same)) { ! 1065: printf("\n%s:\t", same->string->string); ! 1066: for (visit(same->depend_list, same2); !visited(same2); ! 1067: visit_next(same2)) { ! 1068: printf(same2->string->string); ! 1069: } ! 1070: visit_end(); ! 1071: printf("\n\t"); ! 1072: for (visit(same->action_list, same2); !visited(same2); ! 1073: visit_next(same2)) { ! 1074: printf(same2->string->string); ! 1075: if (same2->string->string[0] == '\n') { ! 1076: printf("\t"); ! 1077: } ! 1078: } ! 1079: visit_end(); ! 1080: printf("\n"); ! 1081: } ! 1082: visit_end(); ! 1083: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.