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