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
compile()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
dump_list(char * str)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
do_entry(item_ptr)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
elim_cancellations(short Booleans[],short Numbers[],short Strings[])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
change_cancellations(short Booleans[])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
enqueue(long offset)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
dequeue(struct use_item * ptr)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
invalid_term_name(char * name)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
dump_structure(short Booleans[],short Numbers[],short Strings[])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
write_object(fp,Booleans,Numbers,Strings)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
save_str(string)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
init_structure(short Booleans[],short Numbers[],short Strings[])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
handle_use(item_ptr,entry_offset,Booleans,Numbers,Strings)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