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