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