|
|
1.1 ! root 1: /********************************************************************* ! 2: * COPYRIGHT NOTICE * ! 3: ********************************************************************** ! 4: * This software is copyright (C) 1982 by Pavel Curtis * ! 5: * * ! 6: * Permission is granted to reproduce and distribute * ! 7: * this file by any means so long as no fee is charged * ! 8: * above a nominal handling fee and so long as this * ! 9: * notice is always included in the copies. * ! 10: * * ! 11: * Other rights are reserved except as explicitly granted * ! 12: * by written permission of the author. * ! 13: * Pavel Curtis * ! 14: * Computer Science Dept. * ! 15: * 405 Upson Hall * ! 16: * Cornell University * ! 17: * Ithaca, NY 14853 * ! 18: * * ! 19: * Ph- (607) 256-4934 * ! 20: * * ! 21: * Pavel.Cornell@Udel-Relay (ARPAnet) * ! 22: * decvax!cornell!pavel (UUCPnet) * ! 23: *********************************************************************/ ! 24: ! 25: /* ! 26: * comp_parse.c -- The high-level (ha!) parts of the compiler, ! 27: * that is, the routines which drive the scanner, ! 28: * etc. ! 29: * ! 30: * $Log: comp_parse.c,v $ ! 31: * Revision 1.1 92/03/13 10:45:43 bin ! 32: * Initial revision ! 33: * ! 34: * Revision 3.2 91/07/28 13:59:10 munk ! 35: * Made all the large arrays static ! 36: * ! 37: * Revision 3.1 84/12/13 11:19:32 john ! 38: * Revisions by Mark Horton ! 39: * ! 40: * Revision 2.1 82/10/25 14:45:43 pavel ! 41: * Added Copyright Notice ! 42: * ! 43: * Revision 2.0 82/10/24 15:16:39 pavel ! 44: * Beta-one Test Release ! 45: * ! 46: * Revision 1.3 82/08/23 22:29:39 pavel ! 47: * The REAL Alpha-one Release Version ! 48: * ! 49: * Revision 1.2 82/08/19 19:09:53 pavel ! 50: * Alpha Test Release One ! 51: * ! 52: * Revision 1.1 82/08/12 18:37:12 pavel ! 53: * Initial revision ! 54: * ! 55: * ! 56: */ ! 57: ! 58: #ifndef COHERENT ! 59: static char RCSid[] = ! 60: "$Header: /src386/usr/bin/tic/RCS/comp_parse.c,v 1.1 92/03/13 10:45:43 bin Exp $"; ! 61: #endif ! 62: ! 63: #include <sys/types.h> ! 64: #include <sys/stat.h> ! 65: #include <stdio.h> ! 66: #include <ctype.h> ! 67: #include "compiler.h" ! 68: #include "term.h" ! 69: #include "object.h" ! 70: ! 71: ! 72: char *string_table; ! 73: int next_free; /* next free character in string_table */ ! 74: int table_size = 0; /* current string_table size */ ! 75: short term_names; /* string table offset - current terminal */ ! 76: int part2 = 0; /* set to allow old compiled defns to be used */ ! 77: int complete = 0; /* 1 if entry done with no forward uses */ ! 78: ! 79: struct use_item ! 80: { ! 81: long offset; ! 82: struct use_item *fptr, *bptr; ! 83: }; ! 84: ! 85: struct use_header ! 86: { ! 87: struct use_item *head, *tail; ! 88: }; ! 89: ! 90: struct use_header use_list = {NULL, NULL}; ! 91: int use_count = 0; ! 92: ! 93: /* ! 94: * The use_list is a doubly-linked list with NULLs terminating the lists: ! 95: * ! 96: * use_item use_item use_item ! 97: * --------- --------- --------- ! 98: * | | | | | | offset ! 99: * |-------| |-------| |-------| ! 100: * | ----+-->| ----+-->| NULL | fptr ! 101: * |-------| |-------| |-------| ! 102: * | NULL |<--+---- |<--+---- | bptr ! 103: * --------- --------- --------- ! 104: * ^ ^ ! 105: * | ------------------ | ! 106: * | | | | | ! 107: * +--+---- | ----+---+ ! 108: * | | | ! 109: * ------------------ ! 110: * head tail ! 111: * use_list ! 112: * ! 113: */ ! 114: ! 115: ! 116: /* ! 117: * compile() ! 118: * ! 119: * Main loop of the compiler. ! 120: * ! 121: * get_token() ! 122: * if curr_token != NAMES ! 123: * err_abort() ! 124: * while (not at end of file) ! 125: * do an entry ! 126: * ! 127: */ ! 128: ! 129: compile() ! 130: { ! 131: static char line[1024]; ! 132: int token_type; ! 133: struct use_item *ptr; ! 134: int old_use_count; ! 135: ! 136: token_type = get_token(); ! 137: ! 138: if (token_type != NAMES) ! 139: err_abort("File does not start with terminal names in column one"); ! 140: ! 141: while (token_type != EOF) ! 142: token_type = do_entry(NULL); ! 143: ! 144: DEBUG(2, "Starting handling of forward USE's\n", ""); ! 145: ! 146: for (part2=0; part2<2; part2++) { ! 147: old_use_count = -1; ! 148: DEBUG(2, "\n\nPART %d\n\n", part2); ! 149: while (use_list.head != NULL && old_use_count != use_count) ! 150: { ! 151: old_use_count = use_count; ! 152: for (ptr = use_list.tail; ptr != NULL; ptr = ptr->bptr) ! 153: { ! 154: fseek(stdin, ptr->offset, 0); ! 155: reset_input(); ! 156: if ((token_type = get_token()) != NAMES) ! 157: syserr_abort("Token after a seek not NAMES"); ! 158: (void) do_entry(ptr); ! 159: if (complete) ! 160: dequeue(ptr); ! 161: } ! 162: ! 163: for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) ! 164: { ! 165: fseek(stdin, ptr->offset, 0); ! 166: reset_input(); ! 167: if ((token_type = get_token()) != NAMES) ! 168: syserr_abort("Token after a seek not NAMES"); ! 169: (void) do_entry(ptr); ! 170: if (complete) ! 171: dequeue(ptr); ! 172: } ! 173: ! 174: DEBUG(2, "Finished a pass through enqueued forward USE's\n", ""); ! 175: } ! 176: } ! 177: ! 178: if (use_list.head != NULL) ! 179: { ! 180: fprintf(stderr, "\nError in following up use-links. Either there is\n"); ! 181: fprintf(stderr, "a loop in the links or they reference non-existant\n"); ! 182: fprintf(stderr, "terminals. The following is a list of the entries\n"); ! 183: fprintf(stderr, "involved:\n\n"); ! 184: ! 185: for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) ! 186: { ! 187: fseek(stdin, ptr->offset, 0); ! 188: fgets(line, 1024, stdin); ! 189: fprintf(stderr, "%s", line); ! 190: } ! 191: ! 192: exit(1); ! 193: } ! 194: } ! 195: ! 196: dump_list(str) ! 197: char *str; ! 198: { ! 199: struct use_item *ptr; ! 200: static char line[512]; ! 201: ! 202: fprintf(stderr, "dump_list %s\n", str); ! 203: for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) ! 204: { ! 205: fseek(stdin, ptr->offset, 0); ! 206: fgets(line, 1024, stdin); ! 207: fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s", ! 208: ptr, ptr->offset, ptr->bptr, ptr->fptr, line); ! 209: } ! 210: fprintf(stderr, "\n"); ! 211: } ! 212: ! 213: ! 214: ! 215: /* ! 216: * int ! 217: * do_entry(item_ptr) ! 218: * ! 219: * Compile one entry. During the first pass, item_ptr is NULL. In pass ! 220: * two, item_ptr points to the current entry in the use_list. ! 221: * ! 222: * found-forward-use = FALSE ! 223: * re-initialise internal arrays ! 224: * save names in string_table ! 225: * get_token() ! 226: * while (not EOF and not NAMES) ! 227: * if found-forward-use ! 228: * do nothing ! 229: * else if 'use' ! 230: * if handle_use() < 0 ! 231: * found-forward-use = TRUE ! 232: * else ! 233: * check for existance and type-correctness ! 234: * enter cap into structure ! 235: * if STRING ! 236: * save string in string_table ! 237: * get_token() ! 238: * if ! found-forward-use ! 239: * clear CANCELS out of the structure ! 240: * dump compiled entry into filesystem ! 241: * ! 242: */ ! 243: ! 244: int ! 245: do_entry(item_ptr) ! 246: struct use_item *item_ptr; ! 247: { ! 248: long entry_offset; ! 249: int i; ! 250: register int token_type; ! 251: register struct name_table_entry *entry_ptr; ! 252: int found_forward_use = FALSE; ! 253: static char Booleans[BOOLCOUNT]; ! 254: static short Numbers[NUMCOUNT], ! 255: Strings[STRCOUNT]; ! 256: ! 257: init_structure(Booleans, Numbers, Strings); ! 258: complete = 0; ! 259: term_names = save_str(curr_token.tk_name); ! 260: DEBUG(2, "Starting '%s'\n", curr_token.tk_name); ! 261: entry_offset = curr_file_pos; ! 262: ! 263: for (token_type = get_token(); ! 264: token_type != EOF && token_type != NAMES; ! 265: token_type = get_token()) ! 266: { ! 267: if (found_forward_use) ! 268: /* do nothing */ ; ! 269: else if (strcmp(curr_token.tk_name, "use") == 0) ! 270: { ! 271: if (handle_use(item_ptr, entry_offset, ! 272: Booleans, Numbers, Strings) < 0) ! 273: found_forward_use = TRUE; ! 274: } ! 275: else ! 276: { ! 277: entry_ptr = find_entry(curr_token.tk_name); ! 278: ! 279: if (entry_ptr == NOTFOUND) { ! 280: warning("Unknown Capability - '%s'", ! 281: curr_token.tk_name); ! 282: continue; ! 283: } ! 284: ! 285: ! 286: if (token_type != CANCEL ! 287: && entry_ptr->nte_type != token_type) ! 288: warning("Wrong type used for capability '%s'", ! 289: curr_token.tk_name); ! 290: switch (token_type) ! 291: { ! 292: case CANCEL: ! 293: switch (entry_ptr->nte_type) ! 294: { ! 295: case BOOLEAN: ! 296: Booleans[entry_ptr->nte_index] = -2; ! 297: break; ! 298: ! 299: case NUMBER: ! 300: Numbers[entry_ptr->nte_index] = -2; ! 301: break; ! 302: ! 303: case STRING: ! 304: Strings[entry_ptr->nte_index] = -2; ! 305: break; ! 306: } ! 307: break; ! 308: ! 309: case BOOLEAN: ! 310: Booleans[entry_ptr->nte_index] = TRUE; ! 311: break; ! 312: ! 313: case NUMBER: ! 314: Numbers[entry_ptr->nte_index] = ! 315: curr_token.tk_valnumber; ! 316: break; ! 317: ! 318: case STRING: ! 319: Strings[entry_ptr->nte_index] = ! 320: save_str(curr_token.tk_valstring); ! 321: break; ! 322: ! 323: default: ! 324: warning("Unknown token type"); ! 325: panic_mode(','); ! 326: continue; ! 327: } ! 328: } /* end else cur_token.name != "use" */ ! 329: ! 330: } /* endwhile (not EOF and not NAMES) */ ! 331: ! 332: if (found_forward_use) ! 333: return(token_type); ! 334: ! 335: for (i=0; i < BOOLCOUNT; i++) ! 336: { ! 337: if (Booleans[i] == -2) ! 338: Booleans[i] = FALSE; ! 339: } ! 340: ! 341: for (i=0; i < NUMCOUNT; i++) ! 342: { ! 343: if (Numbers[i] == -2) ! 344: Numbers[i] = -1; ! 345: } ! 346: ! 347: for (i=0; i < STRCOUNT; i++) ! 348: { ! 349: if (Strings[i] == -2) ! 350: Strings[i] = -1; ! 351: } ! 352: ! 353: dump_structure(term_names, Booleans, Numbers, Strings); ! 354: ! 355: complete = 1; ! 356: return(token_type); ! 357: } ! 358: ! 359: ! 360: ! 361: ! 362: /* ! 363: * enqueue(offset) ! 364: * ! 365: * Put a record of the given offset onto the use-list. ! 366: * ! 367: */ ! 368: ! 369: enqueue(offset) ! 370: long offset; ! 371: { ! 372: struct use_item *item; ! 373: char *malloc(); ! 374: ! 375: item = (struct use_item *) malloc(sizeof(struct use_item)); ! 376: ! 377: if (item == NULL) ! 378: syserr_abort("Not enough memory for use_list element"); ! 379: ! 380: item->offset = offset; ! 381: ! 382: if (use_list.head != NULL) ! 383: { ! 384: item->bptr = use_list.tail; ! 385: use_list.tail->fptr = item; ! 386: item->fptr = NULL; ! 387: use_list.tail = item; ! 388: } ! 389: else ! 390: { ! 391: use_list.tail = use_list.head = item; ! 392: item->fptr = item->bptr = NULL; ! 393: } ! 394: ! 395: use_count ++; ! 396: } ! 397: ! 398: ! 399: ! 400: ! 401: /* ! 402: * dequeue(ptr) ! 403: * ! 404: * remove the pointed-to item from the use_list ! 405: * ! 406: */ ! 407: ! 408: dequeue(ptr) ! 409: struct use_item *ptr; ! 410: { ! 411: if (ptr->fptr == NULL) ! 412: use_list.tail = ptr->bptr; ! 413: else ! 414: (ptr->fptr)->bptr = ptr->bptr; ! 415: ! 416: if (ptr->bptr == NULL) ! 417: use_list.head = ptr->fptr; ! 418: else ! 419: (ptr->bptr)->fptr = ptr->fptr; ! 420: ! 421: use_count --; ! 422: } ! 423: ! 424: ! 425: ! 426: /* ! 427: * dump_structure() ! 428: * ! 429: * Save the compiled version of a description in the filesystem. ! 430: * ! 431: * make a copy of the name-list ! 432: * break it up into first-name and all-but-last-name ! 433: * creat(first-name) ! 434: * write object information to first-name ! 435: * close(first-name) ! 436: * for each name in all-but-last-name ! 437: * link to first-name ! 438: * ! 439: */ ! 440: ! 441: dump_structure(term_names, Booleans, Numbers, Strings) ! 442: short term_names; ! 443: char Booleans[]; ! 444: short Numbers[]; ! 445: short Strings[]; ! 446: { ! 447: struct stat statbuf; ! 448: FILE *fp; ! 449: static char name_list[1024]; ! 450: register char *first_name, *other_names; ! 451: register char *ptr; ! 452: static char filename[50]; ! 453: static char linkname[50]; ! 454: extern char check_only; ! 455: ! 456: strcpy(name_list, term_names + string_table); ! 457: DEBUG(7, "Name list = '%s'\n", name_list); ! 458: ! 459: first_name = name_list; ! 460: ! 461: ptr = &name_list[strlen(name_list) - 1]; ! 462: other_names = ptr + 1; ! 463: ! 464: while (ptr > name_list && *ptr != '|') ! 465: ptr--; ! 466: ! 467: if (ptr != name_list) ! 468: { ! 469: *ptr = '\0'; ! 470: ! 471: for (ptr = name_list; *ptr != '\0' && *ptr != '|'; ptr++) ! 472: ; ! 473: ! 474: if (*ptr == '\0') ! 475: other_names = ptr; ! 476: else ! 477: { ! 478: *ptr = '\0'; ! 479: other_names = ptr + 1; ! 480: } ! 481: } ! 482: ! 483: if (check_only) { ! 484: DEBUG(1, "Checked %s\n", first_name); ! 485: return; ! 486: } ! 487: ! 488: DEBUG(7, "First name = '%s'\n", first_name); ! 489: DEBUG(7, "Other names = '%s'\n", other_names); ! 490: ! 491: if (strlen(first_name) > 100) ! 492: warning("'%s': terminal name too long.", first_name); ! 493: ! 494: check_name(first_name); ! 495: ! 496: sprintf(filename, "%c/%s", first_name[0], first_name); ! 497: ! 498: if (stat(filename, &statbuf) >= 0 && statbuf.st_mtime >= start_time) ! 499: { ! 500: warning("'%s' defined in more than one entry.", first_name); ! 501: fprintf(stderr, "Entry being used is '%s'.\n", ! 502: (unsigned) term_names + string_table); ! 503: } ! 504: ! 505: unlink(filename); ! 506: fp = fopen(filename, "w"); ! 507: if (fp == NULL) ! 508: { ! 509: perror(filename); ! 510: syserr_abort("Can't open %s/%s\n", destination, filename); ! 511: } ! 512: DEBUG(1, "Created %s\n", filename); ! 513: ! 514: if (write_object(fp, term_names, Booleans, Numbers, Strings) < 0) ! 515: { ! 516: syserr_abort("Error in writing %s/%s", destination, filename); ! 517: } ! 518: fclose(fp); ! 519: ! 520: while (*other_names != '\0') ! 521: { ! 522: ptr = other_names++; ! 523: while (*other_names != '|' && *other_names != '\0') ! 524: other_names++; ! 525: ! 526: if (*other_names != '\0') ! 527: *(other_names++) = '\0'; ! 528: ! 529: if (strlen(ptr) > 100) ! 530: { ! 531: warning("'%s': terminal name too long.", ptr); ! 532: continue; ! 533: } ! 534: ! 535: sprintf(linkname, "%c/%s", ptr[0], ptr); ! 536: ! 537: if (strcmp(filename, linkname) == 0) ! 538: { ! 539: warning("Terminal name '%s' synonym for itself", first_name); ! 540: } ! 541: else if (stat(linkname, &statbuf) >= 0 && ! 542: statbuf.st_mtime >= start_time) ! 543: { ! 544: warning("'%s' defined in more than one entry.", ptr); ! 545: fprintf(stderr, "Entry being used is '%s'.\n", ! 546: (unsigned) term_names + string_table); ! 547: } ! 548: else ! 549: { ! 550: unlink(linkname); ! 551: if (link(filename, linkname) < 0) ! 552: syserr_abort("Can't link %s to %s", filename, linkname); ! 553: DEBUG(1, "Linked %s\n", linkname); ! 554: } ! 555: } ! 556: } ! 557: ! 558: ! 559: ! 560: ! 561: /* ! 562: * int ! 563: * write_object(fp, term_names, Booleans, Numbers, Strings) ! 564: * ! 565: * Write out the compiled entry to the given file. ! 566: * Return 0 if OK or -1 if not. ! 567: * ! 568: */ ! 569: ! 570: #define swap(x) (((x >> 8) & 0377) + 256 * (x & 0377)) ! 571: ! 572: #define might_swap(x) (must_swap() ? swap(x) : (x)) ! 573: ! 574: ! 575: int ! 576: write_object(fp, term_names, Booleans, Numbers, Strings) ! 577: FILE *fp; ! 578: short term_names; ! 579: char Booleans[]; ! 580: short Numbers[]; ! 581: short Strings[]; ! 582: { ! 583: struct header header; ! 584: char *namelist; ! 585: short namelen; ! 586: char zero = '\0'; ! 587: int i; ! 588: ! 589: namelist = term_names + string_table; ! 590: namelen = strlen(namelist) + 1; ! 591: ! 592: if (must_swap()) ! 593: { ! 594: header.magic = swap(MAGIC); ! 595: header.name_size = swap(namelen); ! 596: header.bool_count = swap(BOOLCOUNT); ! 597: header.num_count = swap(NUMCOUNT); ! 598: header.str_count = swap(STRCOUNT); ! 599: header.str_size = swap(next_free); ! 600: } ! 601: else ! 602: { ! 603: header.magic = MAGIC; ! 604: header.name_size = namelen; ! 605: header.bool_count = BOOLCOUNT; ! 606: header.num_count = NUMCOUNT; ! 607: header.str_count = STRCOUNT; ! 608: header.str_size = next_free; ! 609: } ! 610: ! 611: if (fwrite(&header, sizeof(header), 1, fp) != 1 ! 612: || fwrite(namelist, sizeof(char), namelen, fp) != namelen ! 613: || fwrite(Booleans, sizeof(char), BOOLCOUNT, fp) != BOOLCOUNT) ! 614: return(-1); ! 615: ! 616: if ((namelen+BOOLCOUNT) % 2 != 0 && fwrite(&zero, sizeof(char), 1, fp) != 1) ! 617: return(-1); ! 618: ! 619: if (must_swap()) ! 620: { ! 621: for (i=0; i < NUMCOUNT; i++) ! 622: Numbers[i] = swap(Numbers[i]); ! 623: for (i=0; i < STRCOUNT; i++) ! 624: Strings[i] = swap(Strings[i]); ! 625: } ! 626: ! 627: if (fwrite(Numbers, sizeof(short), NUMCOUNT, fp) != NUMCOUNT ! 628: || fwrite(Strings, sizeof(short), STRCOUNT, fp) != STRCOUNT ! 629: || fwrite(string_table, sizeof(char), next_free, fp) ! 630: != next_free) ! 631: return(-1); ! 632: ! 633: } ! 634: ! 635: ! 636: ! 637: /* ! 638: * check_name(name) ! 639: * ! 640: * Generate an error message if given name does not begin with a ! 641: * digit or letter (should be lower-case letter, but SV likes capital) ! 642: * Vlad 3-11-92 ! 643: */ ! 644: ! 645: check_name(name) ! 646: char *name; ! 647: { ! 648: if (!isalnum(name[0])) ! 649: { ! 650: fprintf(stderr, "tic: Line %d: Illegal terminal name - '%s'\n", ! 651: curr_line, name); ! 652: fprintf(stderr, ! 653: "Terminal names must start with letter or digit\n"); ! 654: exit(1); ! 655: } ! 656: } ! 657: ! 658: ! 659: ! 660: /* ! 661: * int ! 662: * save_str(string) ! 663: * ! 664: * copy string into next free part of string_table, doing a realloc() ! 665: * if necessary. return offset of beginning of string from start of ! 666: * string_table. ! 667: * ! 668: */ ! 669: ! 670: int ! 671: save_str(string) ! 672: char *string; ! 673: { ! 674: char *malloc(), *realloc(); ! 675: int old_next_free = next_free; ! 676: ! 677: if (table_size == 0) ! 678: { ! 679: if ((string_table = malloc(1024)) == NULL) ! 680: syserr_abort("Out of memory"); ! 681: table_size = 1024; ! 682: DEBUG(5, "Made initial string table allocation. Size is %d\n", ! 683: table_size); ! 684: } ! 685: ! 686: while (table_size < next_free + strlen(string)) ! 687: { ! 688: if ((string_table = realloc(string_table, table_size + 1024)) ! 689: == NULL) ! 690: syserr_abort("Out of memory"); ! 691: table_size += 1024; ! 692: DEBUG(5, "Extended string table. Size now %d\n", table_size); ! 693: } ! 694: ! 695: strcpy(&string_table[next_free], string); ! 696: DEBUG(7, "Saved string '%s' ", string); ! 697: DEBUG(7, "at location %d\n", next_free); ! 698: next_free += strlen(string) + 1; ! 699: ! 700: return(old_next_free); ! 701: } ! 702: ! 703: ! 704: ! 705: /* ! 706: * init_structure(Booleans, Numbers, Strings) ! 707: * ! 708: * Initialise the given arrays ! 709: * Reset the next_free counter to zero. ! 710: * ! 711: */ ! 712: ! 713: init_structure(Booleans, Numbers, Strings) ! 714: char Booleans[]; ! 715: short Numbers[], Strings[]; ! 716: { ! 717: int i; ! 718: ! 719: for (i=0; i < BOOLCOUNT; i++) ! 720: Booleans[i] = FALSE; ! 721: ! 722: for (i=0; i < NUMCOUNT; i++) ! 723: Numbers[i] = -1; ! 724: ! 725: for (i=0; i < STRCOUNT; i++) ! 726: Strings[i] = -1; ! 727: ! 728: next_free = 0; ! 729: } ! 730: ! 731: ! 732: ! 733: /* ! 734: ** int ! 735: ** handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings) ! 736: ** ! 737: ** Merge the compiled file whose name is in cur_token.valstring ! 738: ** with the current entry. ! 739: ** ! 740: ** if it's a forward use-link ! 741: ** if item_ptr == NULL ! 742: ** queue it up for later handling ! 743: ** else ! 744: ** ignore it (we're already going through the queue) ! 745: ** else it's a backward use-link ! 746: ** read in the object file for that terminal ! 747: ** merge contents with current structure ! 748: ** ! 749: ** Returned value is 0 if it was a backward link and we ! 750: ** successfully read it in, -1 if a forward link. ! 751: */ ! 752: ! 753: int ! 754: handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings) ! 755: long entry_offset; ! 756: struct use_item *item_ptr; ! 757: char Booleans[]; ! 758: short Numbers[]; ! 759: short Strings[]; ! 760: { ! 761: struct term use_term; ! 762: struct stat statbuf; ! 763: static char filename[50]; ! 764: int i; ! 765: ! 766: check_name(curr_token.tk_valstring); ! 767: ! 768: sprintf(filename, "%c/%s", curr_token.tk_valstring[0], ! 769: curr_token.tk_valstring); ! 770: ! 771: if (stat(filename, &statbuf) < 0 || part2==0 && statbuf.st_mtime < start_time) ! 772: { ! 773: DEBUG(2, "Forward USE to %s", curr_token.tk_valstring); ! 774: ! 775: if (item_ptr == NULL) ! 776: { ! 777: DEBUG(2, " (enqueued)\n", ""); ! 778: enqueue(entry_offset); ! 779: } ! 780: else ! 781: DEBUG(2, " (skipped)\n", ""); ! 782: ! 783: return(-1); ! 784: } ! 785: else ! 786: { ! 787: DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring); ! 788: if (read_entry(filename, &use_term) < 0) ! 789: syserr_abort("Error in re-reading compiled file %s", filename); ! 790: ! 791: for (i=0; i < BOOLCOUNT; i++) ! 792: { ! 793: if (Booleans[i] == FALSE && use_term.Booleans[i] == TRUE) ! 794: Booleans[i] = TRUE; ! 795: } ! 796: ! 797: for (i=0; i < NUMCOUNT; i++) ! 798: { ! 799: if (Numbers[i] == -1 && use_term.Numbers[i] != -1) ! 800: Numbers[i] = use_term.Numbers[i]; ! 801: } ! 802: ! 803: for (i=0; i < STRCOUNT; i++) ! 804: { ! 805: if (Strings[i] == -1 && use_term.Strings[i] != (char *) 0) ! 806: Strings[i] = save_str(use_term.Strings[i]); ! 807: } ! 808: ! 809: } ! 810: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.