17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23d2117003Sdp * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24d2117003Sdp * Use is subject to license terms. 2513cfc972SYuri Pankov * 2613cfc972SYuri Pankov * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 297c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 347c478bd9Sstevel@tonic-gate * The Regents of the University of California 357c478bd9Sstevel@tonic-gate * All Rights Reserved 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 387c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 397c478bd9Sstevel@tonic-gate * contributors. 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate /* 437c478bd9Sstevel@tonic-gate * ******************************************************************* 447c478bd9Sstevel@tonic-gate * COPYRIGHT NOTICE * 457c478bd9Sstevel@tonic-gate * ******************************************************************** 467c478bd9Sstevel@tonic-gate * This software is copyright (C) 1982 by Pavel Curtis * 477c478bd9Sstevel@tonic-gate * * 487c478bd9Sstevel@tonic-gate * Permission is granted to reproduce and distribute * 497c478bd9Sstevel@tonic-gate * this file by any means so long as no fee is charged * 507c478bd9Sstevel@tonic-gate * above a nominal handling fee and so long as this * 517c478bd9Sstevel@tonic-gate * notice is always included in the copies. * 527c478bd9Sstevel@tonic-gate * * 537c478bd9Sstevel@tonic-gate * Other rights are reserved except as explicitly granted * 547c478bd9Sstevel@tonic-gate * by written permission of the author. * 557c478bd9Sstevel@tonic-gate * Pavel Curtis * 567c478bd9Sstevel@tonic-gate * Computer Science Dept. * 577c478bd9Sstevel@tonic-gate * 405 Upson Hall * 587c478bd9Sstevel@tonic-gate * Cornell University * 597c478bd9Sstevel@tonic-gate * Ithaca, NY 14853 * 607c478bd9Sstevel@tonic-gate * * 617c478bd9Sstevel@tonic-gate * Ph- (607) 256-4934 * 627c478bd9Sstevel@tonic-gate * * 637c478bd9Sstevel@tonic-gate * Pavel.Cornell@Udel-Relay (ARPAnet) * 647c478bd9Sstevel@tonic-gate * decvax!cornell!pavel (UUCPnet) * 657c478bd9Sstevel@tonic-gate * ******************************************************************** 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * comp_parse.c -- The high-level (ha!) parts of the compiler, 707c478bd9Sstevel@tonic-gate * that is, the routines which drive the scanner, 717c478bd9Sstevel@tonic-gate * etc. 727c478bd9Sstevel@tonic-gate * 737c478bd9Sstevel@tonic-gate * $Log: RCS/comp_parse.v $ 747c478bd9Sstevel@tonic-gate * Revision 2.1 82/10/25 14:45:43 pavel 757c478bd9Sstevel@tonic-gate * Added Copyright Notice 767c478bd9Sstevel@tonic-gate * 777c478bd9Sstevel@tonic-gate * Revision 2.0 82/10/24 15:16:39 pavel 787c478bd9Sstevel@tonic-gate * Beta-one Test Release 797c478bd9Sstevel@tonic-gate * 807c478bd9Sstevel@tonic-gate * Revision 1.3 82/08/23 22:29:39 pavel 817c478bd9Sstevel@tonic-gate * The REAL Alpha-one Release Version 827c478bd9Sstevel@tonic-gate * 837c478bd9Sstevel@tonic-gate * Revision 1.2 82/08/19 19:09:53 pavel 847c478bd9Sstevel@tonic-gate * Alpha Test Release One 857c478bd9Sstevel@tonic-gate * 867c478bd9Sstevel@tonic-gate * Revision 1.1 82/08/12 18:37:12 pavel 877c478bd9Sstevel@tonic-gate * Initial revision 887c478bd9Sstevel@tonic-gate * 897c478bd9Sstevel@tonic-gate * 907c478bd9Sstevel@tonic-gate */ 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate #include <sys/types.h> 937c478bd9Sstevel@tonic-gate #include <sys/stat.h> 947c478bd9Sstevel@tonic-gate #include <stdio.h> 957c478bd9Sstevel@tonic-gate #include <ctype.h> 967c478bd9Sstevel@tonic-gate #include <stdlib.h> 97d2117003Sdp #include <strings.h> 98d2117003Sdp #include <unistd.h> 997c478bd9Sstevel@tonic-gate #include "curses_inc.h" 1007c478bd9Sstevel@tonic-gate #include "compiler.h" 1017c478bd9Sstevel@tonic-gate #include "object.h" 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate extern char check_only; 1047c478bd9Sstevel@tonic-gate extern char *progname; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate char *string_table; 1077c478bd9Sstevel@tonic-gate int next_free; /* next free character in string_table */ 1087c478bd9Sstevel@tonic-gate unsigned int table_size = 0; /* current string_table size */ 1097c478bd9Sstevel@tonic-gate short term_names; /* string table offset - current terminal */ 1107c478bd9Sstevel@tonic-gate int part2 = 0; /* set to allow old compiled defns to be used */ 1117c478bd9Sstevel@tonic-gate int complete = 0; /* 1 if entry done with no forward uses */ 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate struct use_item { 1147c478bd9Sstevel@tonic-gate long offset; 1157c478bd9Sstevel@tonic-gate struct use_item *fptr, *bptr; 1167c478bd9Sstevel@tonic-gate }; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate struct use_header { 1197c478bd9Sstevel@tonic-gate struct use_item *head, *tail; 1207c478bd9Sstevel@tonic-gate }; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate struct use_header use_list = {NULL, NULL}; 1237c478bd9Sstevel@tonic-gate int use_count = 0; 1247c478bd9Sstevel@tonic-gate 125d2117003Sdp void dequeue(struct use_item *); 126d2117003Sdp void init_structure(short Booleans[], short Numbers[], short Strings[]); 127d2117003Sdp void dump_structure(short Booleans[], short Numbers[], short Strings[]); 128d2117003Sdp 1297c478bd9Sstevel@tonic-gate /* 1307c478bd9Sstevel@tonic-gate * The use_list is a doubly-linked list with NULLs terminating the lists: 1317c478bd9Sstevel@tonic-gate * 1327c478bd9Sstevel@tonic-gate * use_item use_item use_item 1337c478bd9Sstevel@tonic-gate * --------- --------- --------- 1347c478bd9Sstevel@tonic-gate * | | | | | | offset 1357c478bd9Sstevel@tonic-gate * |-------| |-------| |-------| 1367c478bd9Sstevel@tonic-gate * | ----+-->| ----+-->| NULL | fptr 1377c478bd9Sstevel@tonic-gate * |-------| |-------| |-------| 1387c478bd9Sstevel@tonic-gate * | NULL |<--+---- |<--+---- | bptr 1397c478bd9Sstevel@tonic-gate * --------- --------- --------- 1407c478bd9Sstevel@tonic-gate * ^ ^ 1417c478bd9Sstevel@tonic-gate * | ------------------ | 1427c478bd9Sstevel@tonic-gate * | | | | | 1437c478bd9Sstevel@tonic-gate * +--+---- | ----+---+ 1447c478bd9Sstevel@tonic-gate * | | | 1457c478bd9Sstevel@tonic-gate * ------------------ 1467c478bd9Sstevel@tonic-gate * head tail 1477c478bd9Sstevel@tonic-gate * use_list 1487c478bd9Sstevel@tonic-gate * 1497c478bd9Sstevel@tonic-gate */ 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate /* 1537c478bd9Sstevel@tonic-gate * compile() 1547c478bd9Sstevel@tonic-gate * 1557c478bd9Sstevel@tonic-gate * Main loop of the compiler. 1567c478bd9Sstevel@tonic-gate * 1577c478bd9Sstevel@tonic-gate * get_token() 1587c478bd9Sstevel@tonic-gate * if curr_token != NAMES 1597c478bd9Sstevel@tonic-gate * err_abort() 1607c478bd9Sstevel@tonic-gate * while (not at end of file) 1617c478bd9Sstevel@tonic-gate * do an entry 1627c478bd9Sstevel@tonic-gate * 1637c478bd9Sstevel@tonic-gate */ 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate void 1667c478bd9Sstevel@tonic-gate compile() 1677c478bd9Sstevel@tonic-gate { 1687c478bd9Sstevel@tonic-gate char line[1024]; 1697c478bd9Sstevel@tonic-gate int token_type; 1707c478bd9Sstevel@tonic-gate struct use_item *ptr; 1717c478bd9Sstevel@tonic-gate int old_use_count; 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate token_type = get_token(); 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate if (token_type != NAMES) 1767c478bd9Sstevel@tonic-gate err_abort( 1777c478bd9Sstevel@tonic-gate "File does not start with terminal names in column one"); 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate while (token_type != EOF) 1807c478bd9Sstevel@tonic-gate token_type = do_entry((struct use_item *)NULL); 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate DEBUG(2, "Starting handling of forward USE's\n", ""); 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate for (part2 = 0; part2 < 2; part2++) { 1857c478bd9Sstevel@tonic-gate old_use_count = -1; 1867c478bd9Sstevel@tonic-gate DEBUG(2, "\n\nPART %d\n\n", part2); 1877c478bd9Sstevel@tonic-gate while (use_list.head != NULL && old_use_count != use_count) { 1887c478bd9Sstevel@tonic-gate old_use_count = use_count; 1897c478bd9Sstevel@tonic-gate for (ptr = use_list.tail; ptr != NULL; 1907c478bd9Sstevel@tonic-gate ptr = ptr->bptr) { 1917c478bd9Sstevel@tonic-gate fseek(stdin, ptr->offset, 0); 1927c478bd9Sstevel@tonic-gate reset_input(); 1937c478bd9Sstevel@tonic-gate if ((token_type = get_token()) != NAMES) 1947c478bd9Sstevel@tonic-gate syserr_abort( 1957c478bd9Sstevel@tonic-gate "Token after a seek not NAMES"); 1967c478bd9Sstevel@tonic-gate (void) do_entry(ptr); 1977c478bd9Sstevel@tonic-gate if (complete) 1987c478bd9Sstevel@tonic-gate dequeue(ptr); 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate for (ptr = use_list.head; ptr != NULL; 2027c478bd9Sstevel@tonic-gate ptr = ptr->fptr) { 2037c478bd9Sstevel@tonic-gate fseek(stdin, ptr->offset, 0); 2047c478bd9Sstevel@tonic-gate reset_input(); 2057c478bd9Sstevel@tonic-gate if ((token_type = get_token()) != NAMES) 2067c478bd9Sstevel@tonic-gate syserr_abort( 2077c478bd9Sstevel@tonic-gate "Token after a seek not NAMES"); 2087c478bd9Sstevel@tonic-gate (void) do_entry(ptr); 2097c478bd9Sstevel@tonic-gate if (complete) 2107c478bd9Sstevel@tonic-gate dequeue(ptr); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate DEBUG(2, 2147c478bd9Sstevel@tonic-gate "Finished a pass through enqueued forward USE's\n", ""); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate if (use_list.head != NULL && !check_only) { 2197c478bd9Sstevel@tonic-gate fprintf(stderr, 22013cfc972SYuri Pankov "\nError in following use-links. Either there is a loop in the links\n" 22113cfc972SYuri Pankov "or they reference non-existent terminals. The following is a list of\n" 22213cfc972SYuri Pankov "the entries involved:\n\n"); 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) { 2257c478bd9Sstevel@tonic-gate fseek(stdin, ptr->offset, 0); 2267c478bd9Sstevel@tonic-gate fgets(line, 1024, stdin); 2277c478bd9Sstevel@tonic-gate fprintf(stderr, "%s", line); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate exit(1); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate 234d2117003Sdp void 235d2117003Sdp dump_list(char *str) 2367c478bd9Sstevel@tonic-gate { 2377c478bd9Sstevel@tonic-gate struct use_item *ptr; 238*09a48d4cSRichard Lowe char line[1024]; 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate fprintf(stderr, "dump_list %s\n", str); 2417c478bd9Sstevel@tonic-gate for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) { 2427c478bd9Sstevel@tonic-gate fseek(stdin, ptr->offset, 0); 2437c478bd9Sstevel@tonic-gate fgets(line, 1024, stdin); 2447c478bd9Sstevel@tonic-gate fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s", 2457c478bd9Sstevel@tonic-gate ptr, ptr->offset, ptr->bptr, ptr->fptr, line); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate /* 2517c478bd9Sstevel@tonic-gate * int 2527c478bd9Sstevel@tonic-gate * do_entry(item_ptr) 2537c478bd9Sstevel@tonic-gate * 2547c478bd9Sstevel@tonic-gate * Compile one entry. During the first pass, item_ptr is NULL. In pass 2557c478bd9Sstevel@tonic-gate * two, item_ptr points to the current entry in the use_list. 2567c478bd9Sstevel@tonic-gate * 2577c478bd9Sstevel@tonic-gate * found-forward-use = FALSE 2587c478bd9Sstevel@tonic-gate * re-initialise internal arrays 2597c478bd9Sstevel@tonic-gate * save names in string_table 2607c478bd9Sstevel@tonic-gate * get_token() 2617c478bd9Sstevel@tonic-gate * while (not EOF and not NAMES) 2627c478bd9Sstevel@tonic-gate * if found-forward-use 2637c478bd9Sstevel@tonic-gate * do nothing 2647c478bd9Sstevel@tonic-gate * else if 'use' 2657c478bd9Sstevel@tonic-gate * if handle_use() < 0 2667c478bd9Sstevel@tonic-gate * found-forward-use = TRUE 2677c478bd9Sstevel@tonic-gate * else 2687c478bd9Sstevel@tonic-gate * check for existance and type-correctness 2697c478bd9Sstevel@tonic-gate * enter cap into structure 2707c478bd9Sstevel@tonic-gate * if STRING 2717c478bd9Sstevel@tonic-gate * save string in string_table 2727c478bd9Sstevel@tonic-gate * get_token() 2737c478bd9Sstevel@tonic-gate * if ! found-forward-use 2747c478bd9Sstevel@tonic-gate * dump compiled entry into filesystem 2757c478bd9Sstevel@tonic-gate * 2767c478bd9Sstevel@tonic-gate */ 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate int 2797c478bd9Sstevel@tonic-gate do_entry(item_ptr) 2807c478bd9Sstevel@tonic-gate struct use_item *item_ptr; 2817c478bd9Sstevel@tonic-gate { 2827c478bd9Sstevel@tonic-gate long entry_offset; 283d2117003Sdp int token_type; 284d2117003Sdp struct name_table_entry *entry_ptr; 2857c478bd9Sstevel@tonic-gate int found_forward_use = FALSE; 2867c478bd9Sstevel@tonic-gate short Booleans[MAXBOOLS], 2877c478bd9Sstevel@tonic-gate Numbers[MAXNUMS], 2887c478bd9Sstevel@tonic-gate Strings[MAXSTRINGS]; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate init_structure(Booleans, Numbers, Strings); 2917c478bd9Sstevel@tonic-gate complete = 0; 2927c478bd9Sstevel@tonic-gate term_names = save_str(curr_token.tk_name); 2937c478bd9Sstevel@tonic-gate DEBUG(2, "Starting '%s'\n", curr_token.tk_name); 2947c478bd9Sstevel@tonic-gate entry_offset = curr_file_pos; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate for (token_type = get_token(); 2977c478bd9Sstevel@tonic-gate token_type != EOF && token_type != NAMES; 2987c478bd9Sstevel@tonic-gate token_type = get_token()) { 2997c478bd9Sstevel@tonic-gate if (found_forward_use) 3007c478bd9Sstevel@tonic-gate /* do nothing */; 3017c478bd9Sstevel@tonic-gate else if (strcmp(curr_token.tk_name, "use") == 0) { 3027c478bd9Sstevel@tonic-gate if (handle_use(item_ptr, entry_offset, 3037c478bd9Sstevel@tonic-gate Booleans, Numbers, Strings) < 0) 3047c478bd9Sstevel@tonic-gate found_forward_use = TRUE; 3057c478bd9Sstevel@tonic-gate } else { 3067c478bd9Sstevel@tonic-gate entry_ptr = find_entry(curr_token.tk_name); 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate if (entry_ptr == NOTFOUND) { 3097c478bd9Sstevel@tonic-gate warning("Unknown Capability - '%s'", 3107c478bd9Sstevel@tonic-gate curr_token.tk_name); 3117c478bd9Sstevel@tonic-gate continue; 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate if (token_type != CANCEL && 3167c478bd9Sstevel@tonic-gate entry_ptr->nte_type != token_type) 3177c478bd9Sstevel@tonic-gate warning("Wrong type used for capability '%s'", 3187c478bd9Sstevel@tonic-gate curr_token.tk_name); 3197c478bd9Sstevel@tonic-gate switch (token_type) { 3207c478bd9Sstevel@tonic-gate case CANCEL: 3217c478bd9Sstevel@tonic-gate switch (entry_ptr->nte_type) { 3227c478bd9Sstevel@tonic-gate case BOOLEAN: 3237c478bd9Sstevel@tonic-gate Booleans[entry_ptr->nte_index] = -2; 3247c478bd9Sstevel@tonic-gate break; 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate case NUMBER: 3277c478bd9Sstevel@tonic-gate Numbers[entry_ptr->nte_index] = -2; 3287c478bd9Sstevel@tonic-gate break; 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate case STRING: 3317c478bd9Sstevel@tonic-gate Strings[entry_ptr->nte_index] = -2; 3327c478bd9Sstevel@tonic-gate break; 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate break; 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate case BOOLEAN: 3377c478bd9Sstevel@tonic-gate if (Booleans[entry_ptr->nte_index] == 0) 3387c478bd9Sstevel@tonic-gate Booleans[entry_ptr->nte_index] = TRUE; 3397c478bd9Sstevel@tonic-gate break; 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate case NUMBER: 3427c478bd9Sstevel@tonic-gate if (Numbers[entry_ptr->nte_index] == -1) 3437c478bd9Sstevel@tonic-gate Numbers[entry_ptr->nte_index] = 3447c478bd9Sstevel@tonic-gate curr_token.tk_valnumber; 3457c478bd9Sstevel@tonic-gate break; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate case STRING: 3487c478bd9Sstevel@tonic-gate if (Strings[entry_ptr->nte_index] == -1) 3497c478bd9Sstevel@tonic-gate Strings[entry_ptr->nte_index] = 3507c478bd9Sstevel@tonic-gate save_str(curr_token.tk_valstring); 3517c478bd9Sstevel@tonic-gate break; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate default: 3547c478bd9Sstevel@tonic-gate warning("Unknown token type"); 3557c478bd9Sstevel@tonic-gate panic_mode(','); 3567c478bd9Sstevel@tonic-gate continue; 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate } /* end else cur_token.name != "use" */ 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate } /* endwhile (not EOF and not NAMES) */ 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate if (found_forward_use) 3637c478bd9Sstevel@tonic-gate return (token_type); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate dump_structure(Booleans, Numbers, Strings); 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate complete = 1; 3687c478bd9Sstevel@tonic-gate return (token_type); 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate /* 37213cfc972SYuri Pankov * Change all cancellations to a non-entry. 37313cfc972SYuri Pankov * For booleans, @ -> false 37413cfc972SYuri Pankov * For nums, @ -> -1 37513cfc972SYuri Pankov * For strings, @ -> -1 37613cfc972SYuri Pankov * 37713cfc972SYuri Pankov * This only has to be done for entries which 37813cfc972SYuri Pankov * have to be compatible with the pre-Vr3 format. 3797c478bd9Sstevel@tonic-gate */ 3807c478bd9Sstevel@tonic-gate #ifndef NOCANCELCOMPAT 381d2117003Sdp void 382d2117003Sdp elim_cancellations(short Booleans[], short Numbers[], short Strings[]) 3837c478bd9Sstevel@tonic-gate { 384d2117003Sdp int i; 3857c478bd9Sstevel@tonic-gate for (i = 0; i < BoolCount; i++) { 3867c478bd9Sstevel@tonic-gate if (Booleans[i] == -2) 3877c478bd9Sstevel@tonic-gate Booleans[i] = FALSE; 3887c478bd9Sstevel@tonic-gate } 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate for (i = 0; i < NumCount; i++) { 3917c478bd9Sstevel@tonic-gate if (Numbers[i] == -2) 3927c478bd9Sstevel@tonic-gate Numbers[i] = -1; 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate for (i = 0; i < StrCount; i++) { 3967c478bd9Sstevel@tonic-gate if (Strings[i] == -2) 3977c478bd9Sstevel@tonic-gate Strings[i] = -1; 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate #endif /* NOCANCELCOMPAT */ 4017c478bd9Sstevel@tonic-gate /* 40213cfc972SYuri Pankov * Change the cancellation signal from the -2 used internally to 40313cfc972SYuri Pankov * the 2 used within the binary. 4047c478bd9Sstevel@tonic-gate */ 405d2117003Sdp void 406d2117003Sdp change_cancellations(short Booleans[]) 4077c478bd9Sstevel@tonic-gate { 408d2117003Sdp int i; 4097c478bd9Sstevel@tonic-gate for (i = 0; i < BoolCount; i++) { 4107c478bd9Sstevel@tonic-gate if (Booleans[i] == -2) 4117c478bd9Sstevel@tonic-gate Booleans[i] = 2; 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate * enqueue(offset) 4187c478bd9Sstevel@tonic-gate * 4197c478bd9Sstevel@tonic-gate * Put a record of the given offset onto the use-list. 4207c478bd9Sstevel@tonic-gate * 4217c478bd9Sstevel@tonic-gate */ 4227c478bd9Sstevel@tonic-gate 423d2117003Sdp void 424d2117003Sdp enqueue(long offset) 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate struct use_item *item; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate item = (struct use_item *)malloc(sizeof (struct use_item)); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate if (item == NULL) 4317c478bd9Sstevel@tonic-gate syserr_abort("Not enough memory for use_list element"); 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate item->offset = offset; 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate if (use_list.head != NULL) { 4367c478bd9Sstevel@tonic-gate item->bptr = use_list.tail; 4377c478bd9Sstevel@tonic-gate use_list.tail->fptr = item; 4387c478bd9Sstevel@tonic-gate item->fptr = NULL; 4397c478bd9Sstevel@tonic-gate use_list.tail = item; 4407c478bd9Sstevel@tonic-gate } else { 4417c478bd9Sstevel@tonic-gate use_list.tail = use_list.head = item; 4427c478bd9Sstevel@tonic-gate item->fptr = item->bptr = NULL; 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate use_count ++; 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate /* 4497c478bd9Sstevel@tonic-gate * dequeue(ptr) 4507c478bd9Sstevel@tonic-gate * 4517c478bd9Sstevel@tonic-gate * remove the pointed-to item from the use_list 4527c478bd9Sstevel@tonic-gate * 4537c478bd9Sstevel@tonic-gate */ 4547c478bd9Sstevel@tonic-gate 455d2117003Sdp void 456d2117003Sdp dequeue(struct use_item *ptr) 4577c478bd9Sstevel@tonic-gate { 4587c478bd9Sstevel@tonic-gate if (ptr->fptr == NULL) 4597c478bd9Sstevel@tonic-gate use_list.tail = ptr->bptr; 4607c478bd9Sstevel@tonic-gate else 4617c478bd9Sstevel@tonic-gate (ptr->fptr)->bptr = ptr->bptr; 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate if (ptr->bptr == NULL) 4647c478bd9Sstevel@tonic-gate use_list.head = ptr->fptr; 4657c478bd9Sstevel@tonic-gate else 4667c478bd9Sstevel@tonic-gate (ptr->bptr)->fptr = ptr->fptr; 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate use_count --; 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate /* 4727c478bd9Sstevel@tonic-gate * invalid_term_name(name) 4737c478bd9Sstevel@tonic-gate * 4747c478bd9Sstevel@tonic-gate * Look for invalid characters in a term name. These include 4757c478bd9Sstevel@tonic-gate * space, tab and '/'. 4767c478bd9Sstevel@tonic-gate * 4777c478bd9Sstevel@tonic-gate * Generate an error message if given name does not begin with a 4787c478bd9Sstevel@tonic-gate * digit or letter, then exit. 4797c478bd9Sstevel@tonic-gate * 4807c478bd9Sstevel@tonic-gate * return TRUE if name is invalid. 4817c478bd9Sstevel@tonic-gate * 4827c478bd9Sstevel@tonic-gate */ 4837c478bd9Sstevel@tonic-gate 484d2117003Sdp static int 485d2117003Sdp invalid_term_name(char *name) 4867c478bd9Sstevel@tonic-gate { 4877c478bd9Sstevel@tonic-gate int error = 0; 4887c478bd9Sstevel@tonic-gate if (! isdigit(*name) && ! islower(*name) && ! isupper(*name)) 4897c478bd9Sstevel@tonic-gate error++; 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate for (; *name; name++) 4927c478bd9Sstevel@tonic-gate if (isalnum(*name)) 4937c478bd9Sstevel@tonic-gate continue; 4947c478bd9Sstevel@tonic-gate else if (isspace(*name) || (*name == '/')) 4957c478bd9Sstevel@tonic-gate return (1); 4967c478bd9Sstevel@tonic-gate if (error) { 4977c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Line %d: Illegal terminal name - '%s'\n", 4987c478bd9Sstevel@tonic-gate progname, curr_line, name); 4997c478bd9Sstevel@tonic-gate fprintf(stderr, 5007c478bd9Sstevel@tonic-gate "Terminal names must start with a letter or digit\n"); 5017c478bd9Sstevel@tonic-gate exit(1); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate return (0); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /* 5077c478bd9Sstevel@tonic-gate * dump_structure() 5087c478bd9Sstevel@tonic-gate * 5097c478bd9Sstevel@tonic-gate * Save the compiled version of a description in the filesystem. 5107c478bd9Sstevel@tonic-gate * 5117c478bd9Sstevel@tonic-gate * make a copy of the name-list 5127c478bd9Sstevel@tonic-gate * break it up into first-name and all-but-last-name 5137c478bd9Sstevel@tonic-gate * if necessary 5147c478bd9Sstevel@tonic-gate * clear CANCELS out of the structure 5157c478bd9Sstevel@tonic-gate * creat(first-name) 5167c478bd9Sstevel@tonic-gate * write object information to first-name 5177c478bd9Sstevel@tonic-gate * close(first-name) 5187c478bd9Sstevel@tonic-gate * for each valid name 5197c478bd9Sstevel@tonic-gate * link to first-name 5207c478bd9Sstevel@tonic-gate * 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate 523d2117003Sdp void 524d2117003Sdp dump_structure(short Booleans[], short Numbers[], short Strings[]) 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate struct stat64 statbuf; 5277c478bd9Sstevel@tonic-gate FILE *fp; 5287c478bd9Sstevel@tonic-gate char name_list[1024]; 529d2117003Sdp char *first_name, *other_names, *cur_name; 5307c478bd9Sstevel@tonic-gate char filename[128 + 2 + 1]; 5317c478bd9Sstevel@tonic-gate char linkname[128 + 2 + 1]; 5327c478bd9Sstevel@tonic-gate int len; 5337c478bd9Sstevel@tonic-gate int alphastart = 0; 5347c478bd9Sstevel@tonic-gate extern char *strchr(), *strrchr(); 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate strcpy(name_list, term_names + string_table); 5377c478bd9Sstevel@tonic-gate DEBUG(7, "Name list = '%s'\n", name_list); 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate first_name = name_list; 5407c478bd9Sstevel@tonic-gate /* Set othernames to 1 past first '|' in the list. */ 5417c478bd9Sstevel@tonic-gate /* Null out that '|' in the process. */ 5427c478bd9Sstevel@tonic-gate other_names = strchr(first_name, '|'); 5437c478bd9Sstevel@tonic-gate if (other_names) 5447c478bd9Sstevel@tonic-gate *other_names++ = '\0'; 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate if (invalid_term_name(first_name)) 5477c478bd9Sstevel@tonic-gate warning("'%s': bad first term name.", first_name); 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate DEBUG(7, "First name = '%s'\n", first_name); 5517c478bd9Sstevel@tonic-gate DEBUG(7, "Other names = '%s'\n", other_names ? other_names : "NULL"); 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate if ((len = strlen(first_name)) > 128) 5547c478bd9Sstevel@tonic-gate warning("'%s': terminal name too long.", first_name); 5557c478bd9Sstevel@tonic-gate else if (len == 1) 5567c478bd9Sstevel@tonic-gate warning("'%s': terminal name too short.", first_name); 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate check_dir(first_name[0]); 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate sprintf(filename, "%c/%s", first_name[0], first_name); 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate if (stat64(filename, &statbuf) >= 0 && statbuf.st_mtime >= start_time) { 5637c478bd9Sstevel@tonic-gate warning("'%s' defined in more than one entry.", first_name); 5647c478bd9Sstevel@tonic-gate fprintf(stderr, "Entry being used is '%s'.\n", 5657c478bd9Sstevel@tonic-gate (unsigned)term_names + string_table); 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate if (!check_only) { 5697c478bd9Sstevel@tonic-gate unlink(filename); 5707c478bd9Sstevel@tonic-gate fp = fopen(filename, "w"); 5717c478bd9Sstevel@tonic-gate if (fp == NULL) { 5727c478bd9Sstevel@tonic-gate perror(filename); 57313cfc972SYuri Pankov syserr_abort("Can't open %s/%s\n", destination, 57413cfc972SYuri Pankov filename); 5757c478bd9Sstevel@tonic-gate } 57613cfc972SYuri Pankov DEBUG(1, "Created %s\n", filename); 57713cfc972SYuri Pankov } else DEBUG(1, "Would have created %s\n", filename); 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate #ifndef NOCANCELCOMPAT 58013cfc972SYuri Pankov /* eliminate cancellation markings if there is no '+' in the name */ 5817c478bd9Sstevel@tonic-gate if (strchr(first_name, '+') == 0) 5827c478bd9Sstevel@tonic-gate elim_cancellations(Booleans, Numbers, Strings); 5837c478bd9Sstevel@tonic-gate else 5847c478bd9Sstevel@tonic-gate #endif /* NOCANCELCOMPAT */ 5857c478bd9Sstevel@tonic-gate change_cancellations(Booleans); 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate if (!check_only) { 5887c478bd9Sstevel@tonic-gate if (write_object(fp, Booleans, Numbers, Strings) < 0) { 58913cfc972SYuri Pankov syserr_abort("Error writing %s/%s", destination, 59013cfc972SYuri Pankov filename); 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate fclose(fp); 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate alphastart = isalpha(first_name[0]); 5967c478bd9Sstevel@tonic-gate 5977c478bd9Sstevel@tonic-gate while (other_names) { 5987c478bd9Sstevel@tonic-gate cur_name = other_names; 5997c478bd9Sstevel@tonic-gate other_names = strchr(cur_name, '|'); 6007c478bd9Sstevel@tonic-gate if (other_names) 6017c478bd9Sstevel@tonic-gate *other_names++ = '\0'; 6027c478bd9Sstevel@tonic-gate if (*cur_name == '\0') 6037c478bd9Sstevel@tonic-gate continue; 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate if ((len = strlen(cur_name)) > 128) { 6067c478bd9Sstevel@tonic-gate warning("'%s': terminal name too long.", cur_name); 6077c478bd9Sstevel@tonic-gate continue; 6087c478bd9Sstevel@tonic-gate } else if (len == 1) { 6097c478bd9Sstevel@tonic-gate warning("'%s': terminal name too short.", first_name); 6107c478bd9Sstevel@tonic-gate continue; 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate 6137c478bd9Sstevel@tonic-gate if (invalid_term_name(cur_name)) { 6147c478bd9Sstevel@tonic-gate if (other_names) 6157c478bd9Sstevel@tonic-gate warning("'%s': bad term name found in list.", 6167c478bd9Sstevel@tonic-gate cur_name); 6177c478bd9Sstevel@tonic-gate continue; 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate 6207c478bd9Sstevel@tonic-gate check_dir(cur_name[0]); 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate sprintf(linkname, "%c/%s", cur_name[0], cur_name); 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate alphastart |= isalpha(cur_name[0]); 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate if (strcmp(first_name, cur_name) == 0) { 6277c478bd9Sstevel@tonic-gate warning("Terminal name '%s' synonym for itself", 6287c478bd9Sstevel@tonic-gate first_name); 6297c478bd9Sstevel@tonic-gate } else { 6307c478bd9Sstevel@tonic-gate if (!check_only) { 6317c478bd9Sstevel@tonic-gate if (stat64(linkname, &statbuf) >= 0 && 6327c478bd9Sstevel@tonic-gate statbuf.st_mtime >= start_time) { 6337c478bd9Sstevel@tonic-gate warning( 6347c478bd9Sstevel@tonic-gate "'%s' defined in more than one entry.", cur_name); 6357c478bd9Sstevel@tonic-gate fprintf(stderr, 6367c478bd9Sstevel@tonic-gate "Entry being used is '%s'.\n", 6377c478bd9Sstevel@tonic-gate (unsigned)term_names + 6387c478bd9Sstevel@tonic-gate string_table); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate unlink(linkname); 6417c478bd9Sstevel@tonic-gate if (link(filename, linkname) < 0) 6427c478bd9Sstevel@tonic-gate syserr_abort("Can't link %s to %s", 6437c478bd9Sstevel@tonic-gate filename, linkname); 64413cfc972SYuri Pankov DEBUG(1, "Linked %s\n", linkname); 64513cfc972SYuri Pankov } else DEBUG(1, "Would have linked %s\n", linkname); 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate if (!alphastart) { 6507c478bd9Sstevel@tonic-gate warning("At least one synonym should begin with a letter."); 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate /* 6557c478bd9Sstevel@tonic-gate * int 6567c478bd9Sstevel@tonic-gate * write_object(fp, Booleans, Numbers, Strings) 6577c478bd9Sstevel@tonic-gate * 6587c478bd9Sstevel@tonic-gate * Write out the compiled entry to the given file. 6597c478bd9Sstevel@tonic-gate * Return 0 if OK or -1 if not. 6607c478bd9Sstevel@tonic-gate * 6617c478bd9Sstevel@tonic-gate */ 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate #define swap(x) (((x >> 8) & 0377) + 256 * (x & 0377)) 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate #define might_swap(x) (must_swap() ? swap(x) : (x)) 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate int 6697c478bd9Sstevel@tonic-gate write_object(fp, Booleans, Numbers, Strings) 6707c478bd9Sstevel@tonic-gate FILE *fp; 6717c478bd9Sstevel@tonic-gate short Booleans[]; 6727c478bd9Sstevel@tonic-gate short Numbers[]; 6737c478bd9Sstevel@tonic-gate short Strings[]; 6747c478bd9Sstevel@tonic-gate { 6757c478bd9Sstevel@tonic-gate struct header header; 6767c478bd9Sstevel@tonic-gate char *namelist; 6777c478bd9Sstevel@tonic-gate short namelen; 6787c478bd9Sstevel@tonic-gate char zero = '\0'; 679d2117003Sdp int i; 6807c478bd9Sstevel@tonic-gate char cBooleans[MAXBOOLS]; 681d2117003Sdp int l_next_free; 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate namelist = term_names + string_table; 6847c478bd9Sstevel@tonic-gate namelen = strlen(namelist) + 1; 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate l_next_free = next_free; 6877c478bd9Sstevel@tonic-gate if (l_next_free % 256 == 255) 6887c478bd9Sstevel@tonic-gate l_next_free++; 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate if (must_swap()) { 6917c478bd9Sstevel@tonic-gate header.magic = swap(MAGIC); 6927c478bd9Sstevel@tonic-gate header.name_size = swap(namelen); 6937c478bd9Sstevel@tonic-gate header.bool_count = swap(BoolCount); 6947c478bd9Sstevel@tonic-gate header.num_count = swap(NumCount); 6957c478bd9Sstevel@tonic-gate header.str_count = swap(StrCount); 6967c478bd9Sstevel@tonic-gate header.str_size = swap(l_next_free); 6977c478bd9Sstevel@tonic-gate } else { 6987c478bd9Sstevel@tonic-gate header.magic = MAGIC; 6997c478bd9Sstevel@tonic-gate header.name_size = namelen; 7007c478bd9Sstevel@tonic-gate header.bool_count = BoolCount; 7017c478bd9Sstevel@tonic-gate header.num_count = NumCount; 7027c478bd9Sstevel@tonic-gate header.str_count = StrCount; 7037c478bd9Sstevel@tonic-gate header.str_size = l_next_free; 7047c478bd9Sstevel@tonic-gate } 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate for (i = 0; i < BoolCount; i++) 7077c478bd9Sstevel@tonic-gate cBooleans[i] = Booleans[i]; 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate if (fwrite(&header, sizeof (header), 1, fp) != 1 || 7107c478bd9Sstevel@tonic-gate fwrite(namelist, sizeof (char), namelen, fp) != namelen || 7117c478bd9Sstevel@tonic-gate fwrite(cBooleans, sizeof (char), BoolCount, fp) != 7127c478bd9Sstevel@tonic-gate BoolCount) 7137c478bd9Sstevel@tonic-gate return (-1); 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate if ((namelen+BoolCount) % 2 != 0 && 7167c478bd9Sstevel@tonic-gate fwrite(&zero, sizeof (char), 1, fp) != 1) 7177c478bd9Sstevel@tonic-gate return (-1); 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate if (must_swap()) { 7207c478bd9Sstevel@tonic-gate for (i = 0; i < NumCount; i++) 7217c478bd9Sstevel@tonic-gate Numbers[i] = swap(Numbers[i]); 7227c478bd9Sstevel@tonic-gate for (i = 0; i < StrCount; i++) 7237c478bd9Sstevel@tonic-gate Strings[i] = swap(Strings[i]); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate if (fwrite((char *)Numbers, sizeof (short), NumCount, fp) != NumCount || 7277c478bd9Sstevel@tonic-gate fwrite((char *)Strings, sizeof (short), StrCount, fp) 7287c478bd9Sstevel@tonic-gate != StrCount || 7297c478bd9Sstevel@tonic-gate fwrite(string_table, sizeof (char), l_next_free, fp) 7307c478bd9Sstevel@tonic-gate != l_next_free) 7317c478bd9Sstevel@tonic-gate return (-1); 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate return (0); 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate /* 7377c478bd9Sstevel@tonic-gate * int 7387c478bd9Sstevel@tonic-gate * save_str(string) 7397c478bd9Sstevel@tonic-gate * 7407c478bd9Sstevel@tonic-gate * copy string into next free part of string_table, doing a realloc() 7417c478bd9Sstevel@tonic-gate * if necessary. return offset of beginning of string from start of 7427c478bd9Sstevel@tonic-gate * string_table. 7437c478bd9Sstevel@tonic-gate * 7447c478bd9Sstevel@tonic-gate */ 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate int 7477c478bd9Sstevel@tonic-gate save_str(string) 7487c478bd9Sstevel@tonic-gate char *string; 7497c478bd9Sstevel@tonic-gate { 7507c478bd9Sstevel@tonic-gate int old_next_free; 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate /* Do not let an offset be 255. It reads as -1 in Vr2 binaries. */ 7537c478bd9Sstevel@tonic-gate if (next_free % 256 == 255) 7547c478bd9Sstevel@tonic-gate next_free++; 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate old_next_free = next_free; 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate if (table_size == 0) { 7597c478bd9Sstevel@tonic-gate if ((string_table = malloc(1024)) == NULL) 7607c478bd9Sstevel@tonic-gate syserr_abort("Out of memory"); 7617c478bd9Sstevel@tonic-gate table_size = 1024; 7627c478bd9Sstevel@tonic-gate DEBUG(5, "Made initial string table allocation. Size is %u\n", 7637c478bd9Sstevel@tonic-gate table_size); 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate while (table_size <= next_free + strlen(string)) { 7677c478bd9Sstevel@tonic-gate if ((string_table = realloc(string_table, table_size + 1024)) 7687c478bd9Sstevel@tonic-gate == NULL) 7697c478bd9Sstevel@tonic-gate syserr_abort("Out of memory"); 7707c478bd9Sstevel@tonic-gate table_size += 1024; 7717c478bd9Sstevel@tonic-gate DEBUG(5, "Extended string table. Size now %u\n", table_size); 7727c478bd9Sstevel@tonic-gate } 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate strcpy(&string_table[next_free], string); 7757c478bd9Sstevel@tonic-gate DEBUG(7, "Saved string '%s' ", string); 7767c478bd9Sstevel@tonic-gate DEBUG(7, "at location %d\n", next_free); 7777c478bd9Sstevel@tonic-gate next_free += strlen(string) + 1; 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate return (old_next_free); 7807c478bd9Sstevel@tonic-gate } 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate /* 7837c478bd9Sstevel@tonic-gate * init_structure(Booleans, Numbers, Strings) 7847c478bd9Sstevel@tonic-gate * 7857c478bd9Sstevel@tonic-gate * Initialise the given arrays 7867c478bd9Sstevel@tonic-gate * Reset the next_free counter to zero. 7877c478bd9Sstevel@tonic-gate * 7887c478bd9Sstevel@tonic-gate */ 7897c478bd9Sstevel@tonic-gate 790d2117003Sdp void 791d2117003Sdp init_structure(short Booleans[], short Numbers[], short Strings[]) 7927c478bd9Sstevel@tonic-gate { 7937c478bd9Sstevel@tonic-gate int i; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate for (i = 0; i < BoolCount; i++) 7967c478bd9Sstevel@tonic-gate Booleans[i] = FALSE; 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate for (i = 0; i < NumCount; i++) 7997c478bd9Sstevel@tonic-gate Numbers[i] = -1; 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate for (i = 0; i < StrCount; i++) 8027c478bd9Sstevel@tonic-gate Strings[i] = -1; 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate next_free = 0; 8057c478bd9Sstevel@tonic-gate } 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate /* 8087c478bd9Sstevel@tonic-gate * int 8097c478bd9Sstevel@tonic-gate * handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings) 8107c478bd9Sstevel@tonic-gate * 8117c478bd9Sstevel@tonic-gate * Merge the compiled file whose name is in cur_token.valstring 8127c478bd9Sstevel@tonic-gate * with the current entry. 8137c478bd9Sstevel@tonic-gate * 8147c478bd9Sstevel@tonic-gate * if it's a forward use-link 8157c478bd9Sstevel@tonic-gate * if item_ptr == NULL 8167c478bd9Sstevel@tonic-gate * queue it up for later handling 8177c478bd9Sstevel@tonic-gate * else 8187c478bd9Sstevel@tonic-gate * ignore it (we're already going through the queue) 8197c478bd9Sstevel@tonic-gate * else it's a backward use-link 8207c478bd9Sstevel@tonic-gate * read in the object file for that terminal 8217c478bd9Sstevel@tonic-gate * merge contents with current structure 8227c478bd9Sstevel@tonic-gate * 8237c478bd9Sstevel@tonic-gate * Returned value is 0 if it was a backward link and we 8247c478bd9Sstevel@tonic-gate * successfully read it in, -1 if a forward link. 8257c478bd9Sstevel@tonic-gate */ 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate int 8287c478bd9Sstevel@tonic-gate handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings) 8297c478bd9Sstevel@tonic-gate long entry_offset; 8307c478bd9Sstevel@tonic-gate struct use_item *item_ptr; 8317c478bd9Sstevel@tonic-gate short Booleans[]; 8327c478bd9Sstevel@tonic-gate short Numbers[]; 8337c478bd9Sstevel@tonic-gate short Strings[]; 8347c478bd9Sstevel@tonic-gate { 8357c478bd9Sstevel@tonic-gate struct _bool_struct use_bools; 8367c478bd9Sstevel@tonic-gate struct _num_struct use_nums; 8377c478bd9Sstevel@tonic-gate struct _str_struct use_strs; 8387c478bd9Sstevel@tonic-gate struct stat64 statbuf; 8397c478bd9Sstevel@tonic-gate char filename[50]; 8407c478bd9Sstevel@tonic-gate int i; 8417c478bd9Sstevel@tonic-gate char *UB = &use_bools._auto_left_margin; /* first bool */ 8427c478bd9Sstevel@tonic-gate short *UN = &use_nums._columns; /* first num */ 8437c478bd9Sstevel@tonic-gate char **US = &use_strs.strs._back_tab; /* first str */ 8447c478bd9Sstevel@tonic-gate 8457c478bd9Sstevel@tonic-gate if (invalid_term_name(curr_token.tk_valstring)) 8467c478bd9Sstevel@tonic-gate warning("%s: bad term name", curr_token.tk_valstring); 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate sprintf(filename, "%c/%s", curr_token.tk_valstring[0], 8497c478bd9Sstevel@tonic-gate curr_token.tk_valstring); 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate if (stat64(filename, &statbuf) < 0 || 8527c478bd9Sstevel@tonic-gate part2 == 0 && statbuf.st_mtime < start_time) { 8537c478bd9Sstevel@tonic-gate DEBUG(2, "Forward USE to %s", curr_token.tk_valstring); 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate if (item_ptr == NULL) { 8567c478bd9Sstevel@tonic-gate DEBUG(2, " (enqueued)\n", ""); 8577c478bd9Sstevel@tonic-gate enqueue(entry_offset); 8587c478bd9Sstevel@tonic-gate } else DEBUG(2, " (skipped)\n", ""); 8597c478bd9Sstevel@tonic-gate 8607c478bd9Sstevel@tonic-gate return (-1); 8617c478bd9Sstevel@tonic-gate } else { 8627c478bd9Sstevel@tonic-gate DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring); 8637c478bd9Sstevel@tonic-gate if (read_entry(filename, &use_bools, &use_nums, &use_strs) < 0) 8647c478bd9Sstevel@tonic-gate syserr_abort("Error in re-reading compiled file %s", 8657c478bd9Sstevel@tonic-gate filename); 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate for (i = 0; i < BoolCount; i++) { 8687c478bd9Sstevel@tonic-gate if (Booleans[i] == FALSE) 8697c478bd9Sstevel@tonic-gate if (UB[i] == TRUE) /* now true */ 8707c478bd9Sstevel@tonic-gate Booleans[i] = TRUE; 8717c478bd9Sstevel@tonic-gate else if (UB[i] > TRUE) /* cancelled */ 8727c478bd9Sstevel@tonic-gate Booleans[i] = -2; 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate for (i = 0; i < NumCount; i++) { 8767c478bd9Sstevel@tonic-gate if (Numbers[i] == -1) 8777c478bd9Sstevel@tonic-gate Numbers[i] = UN[i]; 8787c478bd9Sstevel@tonic-gate } 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate for (i = 0; i < StrCount; i++) { 8817c478bd9Sstevel@tonic-gate if (Strings[i] == -1) 8827c478bd9Sstevel@tonic-gate if (US[i] == (char *)-1) 8837c478bd9Sstevel@tonic-gate Strings[i] = -2; 8847c478bd9Sstevel@tonic-gate else if (US[i] != (char *)0) 8857c478bd9Sstevel@tonic-gate Strings[i] = save_str(US[i]); 8867c478bd9Sstevel@tonic-gate } 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate return (0); 8907c478bd9Sstevel@tonic-gate } 891