xref: /illumos-gate/usr/src/cmd/tic/tic_parse.c (revision 2587b3a0)
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 
3213cfc972SYuri Pankov /*
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
3613cfc972SYuri Pankov  *
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 
125*2587b3a0SRichard Lowe 
126*2587b3a0SRichard Lowe extern int get_token(void);
127*2587b3a0SRichard Lowe extern int must_swap(void);
128*2587b3a0SRichard Lowe extern void check_dir(char);
129*2587b3a0SRichard Lowe extern void err_abort(char *, ...);
130*2587b3a0SRichard Lowe extern void panic_mode(char);
131*2587b3a0SRichard Lowe extern int read_entry(char *, struct _bool_struct *, struct _num_struct *,
132*2587b3a0SRichard Lowe     struct _str_struct *);
133*2587b3a0SRichard Lowe extern void reset_input(void);
134*2587b3a0SRichard Lowe extern void syserr_abort(char *, ...);
135*2587b3a0SRichard Lowe extern void warning(char *, ...);
136*2587b3a0SRichard Lowe 
137*2587b3a0SRichard Lowe int do_entry(struct use_item *);
138*2587b3a0SRichard Lowe int handle_use(struct use_item *, long, short *, short *, short *);
139*2587b3a0SRichard Lowe int save_str(char *);
140*2587b3a0SRichard Lowe int write_object(FILE *, short *, short *, short *);
141d2117003Sdp void dequeue(struct use_item *);
142*2587b3a0SRichard Lowe void dump_structure(short *, short *, short *);
143*2587b3a0SRichard Lowe void init_structure(short *, short *, short *);
144d2117003Sdp 
1457c478bd9Sstevel@tonic-gate /*
1467c478bd9Sstevel@tonic-gate  *  The use_list is a doubly-linked list with NULLs terminating the lists:
1477c478bd9Sstevel@tonic-gate  *
1487c478bd9Sstevel@tonic-gate  *	   use_item    use_item    use_item
1497c478bd9Sstevel@tonic-gate  *	  ---------   ---------   ---------
1507c478bd9Sstevel@tonic-gate  *	  |       |   |       |   |       |   offset
1517c478bd9Sstevel@tonic-gate  *        |-------|   |-------|   |-------|
1527c478bd9Sstevel@tonic-gate  *	  |   ----+-->|   ----+-->|  NULL |   fptr
1537c478bd9Sstevel@tonic-gate  *	  |-------|   |-------|   |-------|
1547c478bd9Sstevel@tonic-gate  *	  |  NULL |<--+----   |<--+----   |   bptr
1557c478bd9Sstevel@tonic-gate  *	  ---------   ---------   ---------
1567c478bd9Sstevel@tonic-gate  *	  ^                       ^
1577c478bd9Sstevel@tonic-gate  *	  |  ------------------   |
1587c478bd9Sstevel@tonic-gate  *	  |  |       |        |   |
1597c478bd9Sstevel@tonic-gate  *	  +--+----   |    ----+---+
1607c478bd9Sstevel@tonic-gate  *	     |       |        |
1617c478bd9Sstevel@tonic-gate  *	     ------------------
1627c478bd9Sstevel@tonic-gate  *	       head     tail
1637c478bd9Sstevel@tonic-gate  *	          use_list
1647c478bd9Sstevel@tonic-gate  *
1657c478bd9Sstevel@tonic-gate  */
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate /*
1697c478bd9Sstevel@tonic-gate  *	compile()
1707c478bd9Sstevel@tonic-gate  *
1717c478bd9Sstevel@tonic-gate  *	Main loop of the compiler.
1727c478bd9Sstevel@tonic-gate  *
1737c478bd9Sstevel@tonic-gate  *	get_token()
1747c478bd9Sstevel@tonic-gate  *	if curr_token != NAMES
1757c478bd9Sstevel@tonic-gate  *	    err_abort()
1767c478bd9Sstevel@tonic-gate  *	while (not at end of file)
1777c478bd9Sstevel@tonic-gate  *	    do an entry
1787c478bd9Sstevel@tonic-gate  *
1797c478bd9Sstevel@tonic-gate  */
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate void
compile()1827c478bd9Sstevel@tonic-gate compile()
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate 	char			line[1024];
1857c478bd9Sstevel@tonic-gate 	int			token_type;
1867c478bd9Sstevel@tonic-gate 	struct use_item	*ptr;
1877c478bd9Sstevel@tonic-gate 	int			old_use_count;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	token_type = get_token();
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 	if (token_type != NAMES)
1927c478bd9Sstevel@tonic-gate 		err_abort(
1937c478bd9Sstevel@tonic-gate "File does not start with terminal names in column one");
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	while (token_type != EOF)
1967c478bd9Sstevel@tonic-gate 		token_type = do_entry((struct use_item *)NULL);
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	DEBUG(2, "Starting handling of forward USE's\n", "");
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 	for (part2 = 0; part2 < 2; part2++) {
2017c478bd9Sstevel@tonic-gate 		old_use_count = -1;
2027c478bd9Sstevel@tonic-gate 		DEBUG(2, "\n\nPART %d\n\n", part2);
2037c478bd9Sstevel@tonic-gate 		while (use_list.head != NULL && old_use_count != use_count) {
2047c478bd9Sstevel@tonic-gate 			old_use_count = use_count;
2057c478bd9Sstevel@tonic-gate 			for (ptr = use_list.tail; ptr != NULL;
20613cfc972SYuri Pankov 			    ptr = ptr->bptr) {
2077c478bd9Sstevel@tonic-gate 				fseek(stdin, ptr->offset, 0);
2087c478bd9Sstevel@tonic-gate 				reset_input();
2097c478bd9Sstevel@tonic-gate 				if ((token_type = get_token()) != NAMES)
2107c478bd9Sstevel@tonic-gate 					syserr_abort(
2117c478bd9Sstevel@tonic-gate "Token after a seek not NAMES");
2127c478bd9Sstevel@tonic-gate 				(void) do_entry(ptr);
2137c478bd9Sstevel@tonic-gate 				if (complete)
2147c478bd9Sstevel@tonic-gate 					dequeue(ptr);
2157c478bd9Sstevel@tonic-gate 			}
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 			for (ptr = use_list.head; ptr != NULL;
21813cfc972SYuri Pankov 			    ptr = ptr->fptr) {
2197c478bd9Sstevel@tonic-gate 				fseek(stdin, ptr->offset, 0);
2207c478bd9Sstevel@tonic-gate 				reset_input();
2217c478bd9Sstevel@tonic-gate 				if ((token_type = get_token()) != NAMES)
2227c478bd9Sstevel@tonic-gate 					syserr_abort(
2237c478bd9Sstevel@tonic-gate "Token after a seek not NAMES");
2247c478bd9Sstevel@tonic-gate 				(void) do_entry(ptr);
2257c478bd9Sstevel@tonic-gate 				if (complete)
2267c478bd9Sstevel@tonic-gate 					dequeue(ptr);
2277c478bd9Sstevel@tonic-gate 			}
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 			DEBUG(2,
2307c478bd9Sstevel@tonic-gate "Finished a pass through enqueued forward USE's\n", "");
2317c478bd9Sstevel@tonic-gate 		}
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	if (use_list.head != NULL && !check_only) {
2357c478bd9Sstevel@tonic-gate 		fprintf(stderr,
23613cfc972SYuri Pankov "\nError in following use-links. Either there is a loop in the links\n"
23713cfc972SYuri Pankov "or they reference non-existent terminals. The following is a list of\n"
23813cfc972SYuri Pankov "the entries involved:\n\n");
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 		for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
2417c478bd9Sstevel@tonic-gate 			fseek(stdin, ptr->offset, 0);
2427c478bd9Sstevel@tonic-gate 			fgets(line, 1024, stdin);
2437c478bd9Sstevel@tonic-gate 			fprintf(stderr, "%s", line);
2447c478bd9Sstevel@tonic-gate 		}
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 		exit(1);
2477c478bd9Sstevel@tonic-gate 	}
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate 
250d2117003Sdp void
dump_list(char * str)251d2117003Sdp dump_list(char *str)
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate 	struct use_item *ptr;
25409a48d4cSRichard Lowe 	char line[1024];
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	fprintf(stderr, "dump_list %s\n", str);
2577c478bd9Sstevel@tonic-gate 	for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
2587c478bd9Sstevel@tonic-gate 		fseek(stdin, ptr->offset, 0);
2597c478bd9Sstevel@tonic-gate 		fgets(line, 1024, stdin);
2607c478bd9Sstevel@tonic-gate 		fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s",
26113cfc972SYuri Pankov 		    ptr, ptr->offset, ptr->bptr, ptr->fptr, line);
2627c478bd9Sstevel@tonic-gate 	}
2637c478bd9Sstevel@tonic-gate 	fprintf(stderr, "\n");
2647c478bd9Sstevel@tonic-gate }
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  *	int
2687c478bd9Sstevel@tonic-gate  *	do_entry(item_ptr)
2697c478bd9Sstevel@tonic-gate  *
2707c478bd9Sstevel@tonic-gate  *	Compile one entry.  During the first pass, item_ptr is NULL.  In pass
2717c478bd9Sstevel@tonic-gate  *	two, item_ptr points to the current entry in the use_list.
2727c478bd9Sstevel@tonic-gate  *
2737c478bd9Sstevel@tonic-gate  *	found-forward-use = FALSE
2747c478bd9Sstevel@tonic-gate  *	re-initialise internal arrays
2757c478bd9Sstevel@tonic-gate  *	save names in string_table
2767c478bd9Sstevel@tonic-gate  *	get_token()
2777c478bd9Sstevel@tonic-gate  *	while (not EOF and not NAMES)
2787c478bd9Sstevel@tonic-gate  *	    if found-forward-use
2797c478bd9Sstevel@tonic-gate  *		do nothing
2807c478bd9Sstevel@tonic-gate  *	    else if 'use'
2817c478bd9Sstevel@tonic-gate  *		if handle_use() < 0
2827c478bd9Sstevel@tonic-gate  *		    found-forward-use = TRUE
2837c478bd9Sstevel@tonic-gate  *          else
2847c478bd9Sstevel@tonic-gate  *	        check for existance and type-correctness
2857c478bd9Sstevel@tonic-gate  *	        enter cap into structure
2867c478bd9Sstevel@tonic-gate  *	        if STRING
2877c478bd9Sstevel@tonic-gate  *	            save string in string_table
2887c478bd9Sstevel@tonic-gate  *	    get_token()
2897c478bd9Sstevel@tonic-gate  *      if ! found-forward-use
2907c478bd9Sstevel@tonic-gate  *	    dump compiled entry into filesystem
2917c478bd9Sstevel@tonic-gate  *
2927c478bd9Sstevel@tonic-gate  */
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate int
do_entry(struct use_item * item_ptr)295*2587b3a0SRichard Lowe do_entry(struct use_item *item_ptr)
2967c478bd9Sstevel@tonic-gate {
2977c478bd9Sstevel@tonic-gate 	long					entry_offset;
298d2117003Sdp 	int					token_type;
299d2117003Sdp 	struct name_table_entry			*entry_ptr;
3007c478bd9Sstevel@tonic-gate 	int					found_forward_use = FALSE;
3017c478bd9Sstevel@tonic-gate 	short					Booleans[MAXBOOLS],
3027c478bd9Sstevel@tonic-gate 						Numbers[MAXNUMS],
3037c478bd9Sstevel@tonic-gate 						Strings[MAXSTRINGS];
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	init_structure(Booleans, Numbers, Strings);
3067c478bd9Sstevel@tonic-gate 	complete = 0;
3077c478bd9Sstevel@tonic-gate 	term_names = save_str(curr_token.tk_name);
3087c478bd9Sstevel@tonic-gate 	DEBUG(2, "Starting '%s'\n", curr_token.tk_name);
3097c478bd9Sstevel@tonic-gate 	entry_offset = curr_file_pos;
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	for (token_type = get_token();
3127c478bd9Sstevel@tonic-gate 				token_type != EOF && token_type != NAMES;
3137c478bd9Sstevel@tonic-gate 				token_type = get_token()) {
3147c478bd9Sstevel@tonic-gate 		if (found_forward_use)
3157c478bd9Sstevel@tonic-gate 			/* do nothing */;
3167c478bd9Sstevel@tonic-gate 		else if (strcmp(curr_token.tk_name, "use") == 0) {
3177c478bd9Sstevel@tonic-gate 			if (handle_use(item_ptr, entry_offset,
3187c478bd9Sstevel@tonic-gate 					Booleans, Numbers, Strings) < 0)
3197c478bd9Sstevel@tonic-gate 				found_forward_use = TRUE;
3207c478bd9Sstevel@tonic-gate 		} else {
3217c478bd9Sstevel@tonic-gate 			entry_ptr = find_entry(curr_token.tk_name);
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 			if (entry_ptr == NOTFOUND) {
3247c478bd9Sstevel@tonic-gate 				warning("Unknown Capability - '%s'",
3257c478bd9Sstevel@tonic-gate 							curr_token.tk_name);
3267c478bd9Sstevel@tonic-gate 				continue;
3277c478bd9Sstevel@tonic-gate 			}
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 			if (token_type != CANCEL &&
3317c478bd9Sstevel@tonic-gate 					entry_ptr->nte_type != token_type)
3327c478bd9Sstevel@tonic-gate 				warning("Wrong type used for capability '%s'",
3337c478bd9Sstevel@tonic-gate 							curr_token.tk_name);
3347c478bd9Sstevel@tonic-gate 			switch (token_type) {
3357c478bd9Sstevel@tonic-gate 			case CANCEL:
3367c478bd9Sstevel@tonic-gate 				switch (entry_ptr->nte_type) {
3377c478bd9Sstevel@tonic-gate 				case BOOLEAN:
3387c478bd9Sstevel@tonic-gate 					Booleans[entry_ptr->nte_index] = -2;
3397c478bd9Sstevel@tonic-gate 					break;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 				case NUMBER:
3427c478bd9Sstevel@tonic-gate 					Numbers[entry_ptr->nte_index] = -2;
3437c478bd9Sstevel@tonic-gate 					break;
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 				case STRING:
3467c478bd9Sstevel@tonic-gate 					Strings[entry_ptr->nte_index] = -2;
3477c478bd9Sstevel@tonic-gate 					break;
3487c478bd9Sstevel@tonic-gate 				}
3497c478bd9Sstevel@tonic-gate 				break;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 			case BOOLEAN:
3527c478bd9Sstevel@tonic-gate 				if (Booleans[entry_ptr->nte_index] == 0)
3537c478bd9Sstevel@tonic-gate 					Booleans[entry_ptr->nte_index] = TRUE;
3547c478bd9Sstevel@tonic-gate 				break;
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 			case NUMBER:
3577c478bd9Sstevel@tonic-gate 				if (Numbers[entry_ptr->nte_index] == -1)
3587c478bd9Sstevel@tonic-gate 					Numbers[entry_ptr->nte_index] =
3597c478bd9Sstevel@tonic-gate 						curr_token.tk_valnumber;
3607c478bd9Sstevel@tonic-gate 				break;
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 			case STRING:
3637c478bd9Sstevel@tonic-gate 				if (Strings[entry_ptr->nte_index] == -1)
3647c478bd9Sstevel@tonic-gate 					Strings[entry_ptr->nte_index] =
3657c478bd9Sstevel@tonic-gate 					    save_str(curr_token.tk_valstring);
3667c478bd9Sstevel@tonic-gate 				break;
3677c478bd9Sstevel@tonic-gate 
3687c478bd9Sstevel@tonic-gate 			default:
3697c478bd9Sstevel@tonic-gate 				warning("Unknown token type");
3707c478bd9Sstevel@tonic-gate 				panic_mode(',');
3717c478bd9Sstevel@tonic-gate 				continue;
3727c478bd9Sstevel@tonic-gate 			}
3737c478bd9Sstevel@tonic-gate 		} /* end else cur_token.name != "use" */
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 	} /* endwhile (not EOF and not NAMES) */
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate 	if (found_forward_use)
3787c478bd9Sstevel@tonic-gate 		return (token_type);
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 	dump_structure(Booleans, Numbers, Strings);
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	complete = 1;
3837c478bd9Sstevel@tonic-gate 	return (token_type);
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate /*
38713cfc972SYuri Pankov  * Change all cancellations to a non-entry.
38813cfc972SYuri Pankov  * For booleans, @ -> false
38913cfc972SYuri Pankov  * For nums, @ -> -1
39013cfc972SYuri Pankov  * For strings, @ -> -1
39113cfc972SYuri Pankov  *
39213cfc972SYuri Pankov  * This only has to be done for entries which
39313cfc972SYuri Pankov  * have to be compatible with the pre-Vr3 format.
39413cfc972SYuri Pankov  */
3957c478bd9Sstevel@tonic-gate #ifndef NOCANCELCOMPAT
396d2117003Sdp void
elim_cancellations(short Booleans[],short Numbers[],short Strings[])397d2117003Sdp elim_cancellations(short Booleans[], short Numbers[], short Strings[])
3987c478bd9Sstevel@tonic-gate {
399d2117003Sdp 	int i;
4007c478bd9Sstevel@tonic-gate 	for (i = 0; i < BoolCount; i++) {
4017c478bd9Sstevel@tonic-gate 		if (Booleans[i] == -2)
4027c478bd9Sstevel@tonic-gate 			Booleans[i] = FALSE;
4037c478bd9Sstevel@tonic-gate 	}
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	for (i = 0; i < NumCount; i++) {
4067c478bd9Sstevel@tonic-gate 		if (Numbers[i] == -2)
4077c478bd9Sstevel@tonic-gate 			Numbers[i] = -1;
4087c478bd9Sstevel@tonic-gate 	}
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	for (i = 0; i < StrCount; i++) {
4117c478bd9Sstevel@tonic-gate 		if (Strings[i] == -2)
4127c478bd9Sstevel@tonic-gate 			Strings[i] = -1;
4137c478bd9Sstevel@tonic-gate 	}
4147c478bd9Sstevel@tonic-gate }
4157c478bd9Sstevel@tonic-gate #endif /* NOCANCELCOMPAT */
4167c478bd9Sstevel@tonic-gate /*
41713cfc972SYuri Pankov  * Change the cancellation signal from the -2 used internally to
41813cfc972SYuri Pankov  * the 2 used within the binary.
41913cfc972SYuri Pankov  */
420d2117003Sdp void
change_cancellations(short Booleans[])421d2117003Sdp change_cancellations(short Booleans[])
4227c478bd9Sstevel@tonic-gate {
423d2117003Sdp 	int i;
4247c478bd9Sstevel@tonic-gate 	for (i = 0; i < BoolCount; i++) {
4257c478bd9Sstevel@tonic-gate 		if (Booleans[i] == -2)
4267c478bd9Sstevel@tonic-gate 			Booleans[i] = 2;
4277c478bd9Sstevel@tonic-gate 	}
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate }
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate /*
4327c478bd9Sstevel@tonic-gate  *	enqueue(offset)
4337c478bd9Sstevel@tonic-gate  *
4347c478bd9Sstevel@tonic-gate  *      Put a record of the given offset onto the use-list.
4357c478bd9Sstevel@tonic-gate  *
4367c478bd9Sstevel@tonic-gate  */
4377c478bd9Sstevel@tonic-gate 
438d2117003Sdp void
enqueue(long offset)439d2117003Sdp enqueue(long offset)
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@tonic-gate 	struct use_item	*item;
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	item = (struct use_item *)malloc(sizeof (struct use_item));
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 	if (item == NULL)
4467c478bd9Sstevel@tonic-gate 		syserr_abort("Not enough memory for use_list element");
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	item->offset = offset;
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	if (use_list.head != NULL) {
4517c478bd9Sstevel@tonic-gate 		item->bptr = use_list.tail;
4527c478bd9Sstevel@tonic-gate 		use_list.tail->fptr = item;
4537c478bd9Sstevel@tonic-gate 		item->fptr = NULL;
4547c478bd9Sstevel@tonic-gate 		use_list.tail = item;
4557c478bd9Sstevel@tonic-gate 	} else {
4567c478bd9Sstevel@tonic-gate 		use_list.tail = use_list.head = item;
4577c478bd9Sstevel@tonic-gate 		item->fptr = item->bptr = NULL;
4587c478bd9Sstevel@tonic-gate 	}
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	use_count ++;
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate 
4637c478bd9Sstevel@tonic-gate /*
4647c478bd9Sstevel@tonic-gate  *	dequeue(ptr)
4657c478bd9Sstevel@tonic-gate  *
4667c478bd9Sstevel@tonic-gate  *	remove the pointed-to item from the use_list
4677c478bd9Sstevel@tonic-gate  *
4687c478bd9Sstevel@tonic-gate  */
4697c478bd9Sstevel@tonic-gate 
470d2117003Sdp void
dequeue(struct use_item * ptr)471d2117003Sdp dequeue(struct use_item *ptr)
4727c478bd9Sstevel@tonic-gate {
4737c478bd9Sstevel@tonic-gate 	if (ptr->fptr == NULL)
4747c478bd9Sstevel@tonic-gate 		use_list.tail = ptr->bptr;
4757c478bd9Sstevel@tonic-gate 	else
4767c478bd9Sstevel@tonic-gate 		(ptr->fptr)->bptr = ptr->bptr;
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	if (ptr->bptr == NULL)
4797c478bd9Sstevel@tonic-gate 		use_list.head = ptr->fptr;
4807c478bd9Sstevel@tonic-gate 	else
4817c478bd9Sstevel@tonic-gate 		(ptr->bptr)->fptr = ptr->fptr;
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 	use_count --;
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate /*
4877c478bd9Sstevel@tonic-gate  *	invalid_term_name(name)
4887c478bd9Sstevel@tonic-gate  *
4897c478bd9Sstevel@tonic-gate  *	Look for invalid characters in a term name. These include
4907c478bd9Sstevel@tonic-gate  *	space, tab and '/'.
4917c478bd9Sstevel@tonic-gate  *
4927c478bd9Sstevel@tonic-gate  *	Generate an error message if given name does not begin with a
4937c478bd9Sstevel@tonic-gate  *	digit or letter, then exit.
4947c478bd9Sstevel@tonic-gate  *
4957c478bd9Sstevel@tonic-gate  *	return TRUE if name is invalid.
4967c478bd9Sstevel@tonic-gate  *
4977c478bd9Sstevel@tonic-gate  */
4987c478bd9Sstevel@tonic-gate 
499d2117003Sdp static int
invalid_term_name(char * name)500d2117003Sdp invalid_term_name(char *name)
5017c478bd9Sstevel@tonic-gate {
5027c478bd9Sstevel@tonic-gate 	int error = 0;
5037c478bd9Sstevel@tonic-gate 	if (! isdigit(*name) && ! islower(*name) && ! isupper(*name))
5047c478bd9Sstevel@tonic-gate 		error++;
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	for (; *name; name++)
5077c478bd9Sstevel@tonic-gate 		if (isalnum(*name))
5087c478bd9Sstevel@tonic-gate 			continue;
5097c478bd9Sstevel@tonic-gate 		else if (isspace(*name) || (*name == '/'))
5107c478bd9Sstevel@tonic-gate 			return (1);
5117c478bd9Sstevel@tonic-gate 	if (error) {
5127c478bd9Sstevel@tonic-gate 		fprintf(stderr, "%s: Line %d: Illegal terminal name - '%s'\n",
51313cfc972SYuri Pankov 		    progname, curr_line, name);
5147c478bd9Sstevel@tonic-gate 		fprintf(stderr,
51513cfc972SYuri Pankov 		    "Terminal names must start with a letter or digit\n");
5167c478bd9Sstevel@tonic-gate 		exit(1);
5177c478bd9Sstevel@tonic-gate 	}
5187c478bd9Sstevel@tonic-gate 	return (0);
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate /*
5227c478bd9Sstevel@tonic-gate  *	dump_structure()
5237c478bd9Sstevel@tonic-gate  *
5247c478bd9Sstevel@tonic-gate  *	Save the compiled version of a description in the filesystem.
5257c478bd9Sstevel@tonic-gate  *
5267c478bd9Sstevel@tonic-gate  *	make a copy of the name-list
5277c478bd9Sstevel@tonic-gate  *	break it up into first-name and all-but-last-name
5287c478bd9Sstevel@tonic-gate  *	if necessary
5297c478bd9Sstevel@tonic-gate  *	    clear CANCELS out of the structure
5307c478bd9Sstevel@tonic-gate  *	creat(first-name)
5317c478bd9Sstevel@tonic-gate  *	write object information to first-name
5327c478bd9Sstevel@tonic-gate  *	close(first-name)
5337c478bd9Sstevel@tonic-gate  *      for each valid name
5347c478bd9Sstevel@tonic-gate  *	    link to first-name
5357c478bd9Sstevel@tonic-gate  *
5367c478bd9Sstevel@tonic-gate  */
5377c478bd9Sstevel@tonic-gate 
538d2117003Sdp void
dump_structure(short Booleans[],short Numbers[],short Strings[])539d2117003Sdp dump_structure(short Booleans[], short Numbers[], short Strings[])
5407c478bd9Sstevel@tonic-gate {
5417c478bd9Sstevel@tonic-gate 	struct stat64	statbuf;
542*2587b3a0SRichard Lowe 	FILE		*fp = NULL;
5437c478bd9Sstevel@tonic-gate 	char		name_list[1024];
544d2117003Sdp 	char		*first_name, *other_names, *cur_name;
5457c478bd9Sstevel@tonic-gate 	char		filename[128 + 2 + 1];
5467c478bd9Sstevel@tonic-gate 	char		linkname[128 + 2 + 1];
5477c478bd9Sstevel@tonic-gate 	int		len;
5487c478bd9Sstevel@tonic-gate 	int		alphastart = 0;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	strcpy(name_list, term_names + string_table);
5517c478bd9Sstevel@tonic-gate 	DEBUG(7, "Name list = '%s'\n", name_list);
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	first_name = name_list;
5547c478bd9Sstevel@tonic-gate 	/* Set othernames to 1 past first '|' in the list. */
5557c478bd9Sstevel@tonic-gate 	/* Null out that '|' in the process. */
5567c478bd9Sstevel@tonic-gate 	other_names = strchr(first_name, '|');
5577c478bd9Sstevel@tonic-gate 	if (other_names)
5587c478bd9Sstevel@tonic-gate 		*other_names++ = '\0';
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 	if (invalid_term_name(first_name))
5617c478bd9Sstevel@tonic-gate 		warning("'%s': bad first term name.", first_name);
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 	DEBUG(7, "First name = '%s'\n", first_name);
5657c478bd9Sstevel@tonic-gate 	DEBUG(7, "Other names = '%s'\n", other_names ? other_names : "NULL");
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	if ((len = strlen(first_name)) > 128)
5687c478bd9Sstevel@tonic-gate 		warning("'%s': terminal name too long.", first_name);
5697c478bd9Sstevel@tonic-gate 	else if (len == 1)
5707c478bd9Sstevel@tonic-gate 		warning("'%s': terminal name too short.", first_name);
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 	check_dir(first_name[0]);
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	sprintf(filename, "%c/%s", first_name[0], first_name);
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	if (stat64(filename, &statbuf) >= 0 && statbuf.st_mtime >= start_time) {
5777c478bd9Sstevel@tonic-gate 		warning("'%s' defined in more than one entry.", first_name);
5787c478bd9Sstevel@tonic-gate 		fprintf(stderr, "Entry being used is '%s'.\n",
57913cfc972SYuri Pankov 		    (unsigned)term_names + string_table);
5807c478bd9Sstevel@tonic-gate 	}
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	if (!check_only) {
5837c478bd9Sstevel@tonic-gate 		unlink(filename);
5847c478bd9Sstevel@tonic-gate 		fp = fopen(filename, "w");
5857c478bd9Sstevel@tonic-gate 		if (fp == NULL) {
5867c478bd9Sstevel@tonic-gate 			perror(filename);
58713cfc972SYuri Pankov 			syserr_abort("Can't open %s/%s\n", destination,
58813cfc972SYuri Pankov 			    filename);
5897c478bd9Sstevel@tonic-gate 		}
59013cfc972SYuri Pankov 		DEBUG(1, "Created %s\n", filename);
59113cfc972SYuri Pankov 	} else DEBUG(1, "Would have created %s\n", filename);
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate #ifndef NOCANCELCOMPAT
59413cfc972SYuri Pankov 	/* eliminate cancellation markings if there is no '+' in the name */
5957c478bd9Sstevel@tonic-gate 	if (strchr(first_name, '+') == 0)
5967c478bd9Sstevel@tonic-gate 		elim_cancellations(Booleans, Numbers, Strings);
5977c478bd9Sstevel@tonic-gate 	else
5987c478bd9Sstevel@tonic-gate #endif /* NOCANCELCOMPAT */
5997c478bd9Sstevel@tonic-gate 		change_cancellations(Booleans);
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	if (!check_only) {
6027c478bd9Sstevel@tonic-gate 		if (write_object(fp, Booleans, Numbers, Strings) < 0) {
60313cfc972SYuri Pankov 			syserr_abort("Error writing %s/%s", destination,
60413cfc972SYuri Pankov 			    filename);
6057c478bd9Sstevel@tonic-gate 		}
6067c478bd9Sstevel@tonic-gate 		fclose(fp);
6077c478bd9Sstevel@tonic-gate 	}
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate 	alphastart = isalpha(first_name[0]);
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	while (other_names) {
6127c478bd9Sstevel@tonic-gate 		cur_name = other_names;
6137c478bd9Sstevel@tonic-gate 		other_names = strchr(cur_name, '|');
6147c478bd9Sstevel@tonic-gate 		if (other_names)
6157c478bd9Sstevel@tonic-gate 			*other_names++ = '\0';
6167c478bd9Sstevel@tonic-gate 		if (*cur_name == '\0')
6177c478bd9Sstevel@tonic-gate 			continue;
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 		if ((len = strlen(cur_name)) > 128) {
6207c478bd9Sstevel@tonic-gate 			warning("'%s': terminal name too long.", cur_name);
6217c478bd9Sstevel@tonic-gate 			continue;
6227c478bd9Sstevel@tonic-gate 		} else if (len == 1) {
6237c478bd9Sstevel@tonic-gate 			warning("'%s': terminal name too short.", first_name);
6247c478bd9Sstevel@tonic-gate 			continue;
6257c478bd9Sstevel@tonic-gate 		}
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 		if (invalid_term_name(cur_name)) {
6287c478bd9Sstevel@tonic-gate 			if (other_names)
6297c478bd9Sstevel@tonic-gate 				warning("'%s': bad term name found in list.",
63013cfc972SYuri Pankov 				    cur_name);
6317c478bd9Sstevel@tonic-gate 			continue;
6327c478bd9Sstevel@tonic-gate 		}
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 		check_dir(cur_name[0]);
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 		sprintf(linkname, "%c/%s", cur_name[0], cur_name);
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 		alphastart |= isalpha(cur_name[0]);
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate 		if (strcmp(first_name, cur_name) == 0) {
6417c478bd9Sstevel@tonic-gate 			warning("Terminal name '%s' synonym for itself",
64213cfc972SYuri Pankov 			    first_name);
6437c478bd9Sstevel@tonic-gate 		} else  {
6447c478bd9Sstevel@tonic-gate 			if (!check_only) {
6457c478bd9Sstevel@tonic-gate 				if (stat64(linkname, &statbuf) >= 0 &&
64613cfc972SYuri Pankov 				    statbuf.st_mtime >= start_time) {
6477c478bd9Sstevel@tonic-gate 					warning(
6487c478bd9Sstevel@tonic-gate "'%s' defined in more than one entry.", cur_name);
6497c478bd9Sstevel@tonic-gate 					fprintf(stderr,
6507c478bd9Sstevel@tonic-gate 					    "Entry being used is '%s'.\n",
6517c478bd9Sstevel@tonic-gate 					    (unsigned)term_names +
65213cfc972SYuri Pankov 					    string_table);
6537c478bd9Sstevel@tonic-gate 				}
6547c478bd9Sstevel@tonic-gate 				unlink(linkname);
6557c478bd9Sstevel@tonic-gate 				if (link(filename, linkname) < 0)
6567c478bd9Sstevel@tonic-gate 					syserr_abort("Can't link %s to %s",
65713cfc972SYuri Pankov 					    filename, linkname);
65813cfc972SYuri Pankov 				DEBUG(1, "Linked %s\n", linkname);
65913cfc972SYuri Pankov 			} else DEBUG(1, "Would have linked %s\n", linkname);
6607c478bd9Sstevel@tonic-gate 		}
6617c478bd9Sstevel@tonic-gate 	}
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 	if (!alphastart) {
6647c478bd9Sstevel@tonic-gate 		warning("At least one synonym should begin with a letter.");
6657c478bd9Sstevel@tonic-gate 	}
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate /*
6697c478bd9Sstevel@tonic-gate  *	int
6707c478bd9Sstevel@tonic-gate  *	write_object(fp, Booleans, Numbers, Strings)
6717c478bd9Sstevel@tonic-gate  *
6727c478bd9Sstevel@tonic-gate  *	Write out the compiled entry to the given file.
6737c478bd9Sstevel@tonic-gate  *	Return 0 if OK or -1 if not.
6747c478bd9Sstevel@tonic-gate  *
6757c478bd9Sstevel@tonic-gate  */
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate #define	swap(x)		(((x >> 8) & 0377) + 256 * (x & 0377))
6787c478bd9Sstevel@tonic-gate 
6797c478bd9Sstevel@tonic-gate #define	might_swap(x)	(must_swap()  ?  swap(x)  :  (x))
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate int
write_object(FILE * fp,short Booleans[],short Numbers[],short Strings[])683*2587b3a0SRichard Lowe write_object(FILE *fp, short Booleans[], short Numbers[], short Strings[])
6847c478bd9Sstevel@tonic-gate {
6857c478bd9Sstevel@tonic-gate 	struct header	header;
6867c478bd9Sstevel@tonic-gate 	char		*namelist;
6877c478bd9Sstevel@tonic-gate 	short		namelen;
6887c478bd9Sstevel@tonic-gate 	char		zero = '\0';
689d2117003Sdp 	int		i;
6907c478bd9Sstevel@tonic-gate 	char		cBooleans[MAXBOOLS];
691d2117003Sdp 	int		l_next_free;
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	namelist = term_names + string_table;
6947c478bd9Sstevel@tonic-gate 	namelen = strlen(namelist) + 1;
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 	l_next_free = next_free;
6977c478bd9Sstevel@tonic-gate 	if (l_next_free % 256 == 255)
6987c478bd9Sstevel@tonic-gate 		l_next_free++;
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	if (must_swap()) {
7017c478bd9Sstevel@tonic-gate 		header.magic = swap(MAGIC);
7027c478bd9Sstevel@tonic-gate 		header.name_size = swap(namelen);
7037c478bd9Sstevel@tonic-gate 		header.bool_count = swap(BoolCount);
7047c478bd9Sstevel@tonic-gate 		header.num_count = swap(NumCount);
7057c478bd9Sstevel@tonic-gate 		header.str_count = swap(StrCount);
7067c478bd9Sstevel@tonic-gate 		header.str_size = swap(l_next_free);
7077c478bd9Sstevel@tonic-gate 	} else {
7087c478bd9Sstevel@tonic-gate 		header.magic = MAGIC;
7097c478bd9Sstevel@tonic-gate 		header.name_size = namelen;
7107c478bd9Sstevel@tonic-gate 		header.bool_count = BoolCount;
7117c478bd9Sstevel@tonic-gate 		header.num_count = NumCount;
7127c478bd9Sstevel@tonic-gate 		header.str_count = StrCount;
7137c478bd9Sstevel@tonic-gate 		header.str_size = l_next_free;
7147c478bd9Sstevel@tonic-gate 	}
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate 	for (i = 0; i < BoolCount; i++)
7177c478bd9Sstevel@tonic-gate 		cBooleans[i] = Booleans[i];
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	if (fwrite(&header, sizeof (header), 1, fp) != 1 ||
720*2587b3a0SRichard Lowe 	    fwrite(namelist, sizeof (char), namelen, fp) != namelen ||
721*2587b3a0SRichard Lowe 	    fwrite(cBooleans, sizeof (char), BoolCount, fp) != BoolCount)
7227c478bd9Sstevel@tonic-gate 		return (-1);
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 	if ((namelen+BoolCount) % 2 != 0 &&
7257c478bd9Sstevel@tonic-gate 				fwrite(&zero, sizeof (char), 1, fp) != 1)
7267c478bd9Sstevel@tonic-gate 		return (-1);
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 	if (must_swap()) {
7297c478bd9Sstevel@tonic-gate 		for (i = 0; i < NumCount; i++)
7307c478bd9Sstevel@tonic-gate 			Numbers[i] = swap(Numbers[i]);
7317c478bd9Sstevel@tonic-gate 		for (i = 0; i < StrCount; i++)
7327c478bd9Sstevel@tonic-gate 			Strings[i] = swap(Strings[i]);
7337c478bd9Sstevel@tonic-gate 	}
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	if (fwrite((char *)Numbers, sizeof (short), NumCount, fp) != NumCount ||
7367c478bd9Sstevel@tonic-gate 		    fwrite((char *)Strings, sizeof (short), StrCount, fp)
7377c478bd9Sstevel@tonic-gate 							!= StrCount ||
7387c478bd9Sstevel@tonic-gate 		    fwrite(string_table, sizeof (char), l_next_free, fp)
7397c478bd9Sstevel@tonic-gate 							!= l_next_free)
7407c478bd9Sstevel@tonic-gate 		return (-1);
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	return (0);
7437c478bd9Sstevel@tonic-gate }
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate /*
7467c478bd9Sstevel@tonic-gate  *	int
7477c478bd9Sstevel@tonic-gate  *	save_str(string)
7487c478bd9Sstevel@tonic-gate  *
7497c478bd9Sstevel@tonic-gate  *	copy string into next free part of string_table, doing a realloc()
7507c478bd9Sstevel@tonic-gate  *	if necessary.  return offset of beginning of string from start of
7517c478bd9Sstevel@tonic-gate  *	string_table.
7527c478bd9Sstevel@tonic-gate  *
7537c478bd9Sstevel@tonic-gate  */
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate int
save_str(char * string)756*2587b3a0SRichard Lowe save_str(char *string)
7577c478bd9Sstevel@tonic-gate {
7587c478bd9Sstevel@tonic-gate 	int	old_next_free;
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 	/* Do not let an offset be 255. It reads as -1 in Vr2 binaries. */
7617c478bd9Sstevel@tonic-gate 	if (next_free % 256 == 255)
762*2587b3a0SRichard Lowe 		string_table[next_free++] = '\0';
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate 	old_next_free = next_free;
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate 	if (table_size == 0) {
7677c478bd9Sstevel@tonic-gate 		if ((string_table = malloc(1024)) == NULL)
7687c478bd9Sstevel@tonic-gate 			syserr_abort("Out of memory");
7697c478bd9Sstevel@tonic-gate 		table_size = 1024;
7707c478bd9Sstevel@tonic-gate 		DEBUG(5, "Made initial string table allocation.  Size is %u\n",
7717c478bd9Sstevel@tonic-gate 							    table_size);
7727c478bd9Sstevel@tonic-gate 	}
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate 	while (table_size <= next_free + strlen(string)) {
7757c478bd9Sstevel@tonic-gate 		if ((string_table = realloc(string_table, table_size + 1024))
7767c478bd9Sstevel@tonic-gate 								== NULL)
7777c478bd9Sstevel@tonic-gate 			syserr_abort("Out of memory");
7787c478bd9Sstevel@tonic-gate 		table_size += 1024;
7797c478bd9Sstevel@tonic-gate 		DEBUG(5, "Extended string table.  Size now %u\n", table_size);
7807c478bd9Sstevel@tonic-gate 	}
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate 	strcpy(&string_table[next_free], string);
7837c478bd9Sstevel@tonic-gate 	DEBUG(7, "Saved string '%s' ", string);
7847c478bd9Sstevel@tonic-gate 	DEBUG(7, "at location %d\n", next_free);
7857c478bd9Sstevel@tonic-gate 	next_free += strlen(string) + 1;
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate 	return (old_next_free);
7887c478bd9Sstevel@tonic-gate }
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate /*
7917c478bd9Sstevel@tonic-gate  *	init_structure(Booleans, Numbers, Strings)
7927c478bd9Sstevel@tonic-gate  *
7937c478bd9Sstevel@tonic-gate  *	Initialise the given arrays
7947c478bd9Sstevel@tonic-gate  *	Reset the next_free counter to zero.
7957c478bd9Sstevel@tonic-gate  *
7967c478bd9Sstevel@tonic-gate  */
7977c478bd9Sstevel@tonic-gate 
798d2117003Sdp void
init_structure(short Booleans[],short Numbers[],short Strings[])799d2117003Sdp init_structure(short Booleans[], short Numbers[], short Strings[])
8007c478bd9Sstevel@tonic-gate {
8017c478bd9Sstevel@tonic-gate 	int	i;
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	for (i = 0; i < BoolCount; i++)
8047c478bd9Sstevel@tonic-gate 		Booleans[i] = FALSE;
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	for (i = 0; i < NumCount; i++)
8077c478bd9Sstevel@tonic-gate 		Numbers[i] = -1;
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 	for (i = 0; i < StrCount; i++)
8107c478bd9Sstevel@tonic-gate 		Strings[i] = -1;
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 	next_free = 0;
8137c478bd9Sstevel@tonic-gate }
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate /*
8167c478bd9Sstevel@tonic-gate  *	int
8177c478bd9Sstevel@tonic-gate  *	handle_use(item_ptr, entry_offset, Booleans, Numbers, Strings)
8187c478bd9Sstevel@tonic-gate  *
8197c478bd9Sstevel@tonic-gate  *	Merge the compiled file whose name is in cur_token.valstring
8207c478bd9Sstevel@tonic-gate  *	with the current entry.
8217c478bd9Sstevel@tonic-gate  *
8227c478bd9Sstevel@tonic-gate  *		if it's a forward use-link
8237c478bd9Sstevel@tonic-gate  *		    if item_ptr == NULL
8247c478bd9Sstevel@tonic-gate  *		        queue it up for later handling
8257c478bd9Sstevel@tonic-gate  *	            else
8267c478bd9Sstevel@tonic-gate  *		        ignore it (we're already going through the queue)
8277c478bd9Sstevel@tonic-gate  *	        else it's a backward use-link
8287c478bd9Sstevel@tonic-gate  *	            read in the object file for that terminal
8297c478bd9Sstevel@tonic-gate  *	            merge contents with current structure
8307c478bd9Sstevel@tonic-gate  *
8317c478bd9Sstevel@tonic-gate  *	Returned value is 0 if it was a backward link and we
8327c478bd9Sstevel@tonic-gate  *	successfully read it in, -1 if a forward link.
8337c478bd9Sstevel@tonic-gate  */
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate int
handle_use(struct use_item * item_ptr,long entry_offset,short Booleans[],short Numbers[],short Strings[])836*2587b3a0SRichard Lowe handle_use(struct use_item *item_ptr, long entry_offset,
837*2587b3a0SRichard Lowe     short Booleans[], short Numbers[], short Strings[])
8387c478bd9Sstevel@tonic-gate {
8397c478bd9Sstevel@tonic-gate 	struct _bool_struct	use_bools;
8407c478bd9Sstevel@tonic-gate 	struct _num_struct	use_nums;
8417c478bd9Sstevel@tonic-gate 	struct _str_struct	use_strs;
8427c478bd9Sstevel@tonic-gate 	struct stat64	statbuf;
8437c478bd9Sstevel@tonic-gate 	char		filename[50];
8447c478bd9Sstevel@tonic-gate 	int		i;
8457c478bd9Sstevel@tonic-gate 	char  *UB = &use_bools._auto_left_margin;	/* first bool */
8467c478bd9Sstevel@tonic-gate 	short *UN = &use_nums._columns;			/* first num */
8477c478bd9Sstevel@tonic-gate 	char **US = &use_strs.strs._back_tab;		/* first str */
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	if (invalid_term_name(curr_token.tk_valstring))
8507c478bd9Sstevel@tonic-gate 		warning("%s: bad term name", curr_token.tk_valstring);
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate 	sprintf(filename, "%c/%s", curr_token.tk_valstring[0],
8537c478bd9Sstevel@tonic-gate 						curr_token.tk_valstring);
8547c478bd9Sstevel@tonic-gate 
855*2587b3a0SRichard Lowe 	if ((stat64(filename, &statbuf) < 0) ||
856*2587b3a0SRichard Lowe 	    (part2 == 0 && statbuf.st_mtime < start_time)) {
8577c478bd9Sstevel@tonic-gate 		DEBUG(2, "Forward USE to %s", curr_token.tk_valstring);
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate 		if (item_ptr == NULL) {
8607c478bd9Sstevel@tonic-gate 			DEBUG(2, " (enqueued)\n", "");
8617c478bd9Sstevel@tonic-gate 			enqueue(entry_offset);
8627c478bd9Sstevel@tonic-gate 		} else DEBUG(2, " (skipped)\n", "");
8637c478bd9Sstevel@tonic-gate 
8647c478bd9Sstevel@tonic-gate 		return (-1);
8657c478bd9Sstevel@tonic-gate 	} else {
8667c478bd9Sstevel@tonic-gate 		DEBUG(2, "Backward USE to %s\n", curr_token.tk_valstring);
8677c478bd9Sstevel@tonic-gate 		if (read_entry(filename, &use_bools, &use_nums, &use_strs) < 0)
8687c478bd9Sstevel@tonic-gate 			syserr_abort("Error in re-reading compiled file %s",
8697c478bd9Sstevel@tonic-gate 								filename);
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 		for (i = 0; i < BoolCount; i++) {
872*2587b3a0SRichard Lowe 			if (Booleans[i] == FALSE) {
873*2587b3a0SRichard Lowe 				if (UB[i] == TRUE) {		/* now true */
8747c478bd9Sstevel@tonic-gate 					Booleans[i] = TRUE;
875*2587b3a0SRichard Lowe 				} else if (UB[i] > TRUE) {	/* cancelled */
8767c478bd9Sstevel@tonic-gate 					Booleans[i] = -2;
877*2587b3a0SRichard Lowe 				}
878*2587b3a0SRichard Lowe 			}
8797c478bd9Sstevel@tonic-gate 		}
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate 		for (i = 0; i < NumCount; i++) {
8827c478bd9Sstevel@tonic-gate 			if (Numbers[i] == -1)
8837c478bd9Sstevel@tonic-gate 				Numbers[i] = UN[i];
8847c478bd9Sstevel@tonic-gate 		}
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 		for (i = 0; i < StrCount; i++) {
887*2587b3a0SRichard Lowe 			if (Strings[i] == -1) {
888*2587b3a0SRichard Lowe 				if (US[i] == (char *)-1) {
8897c478bd9Sstevel@tonic-gate 					Strings[i] = -2;
890*2587b3a0SRichard Lowe 				} else if (US[i] != (char *)0) {
8917c478bd9Sstevel@tonic-gate 					Strings[i] = save_str(US[i]);
892*2587b3a0SRichard Lowe 				}
893*2587b3a0SRichard Lowe 			}
8947c478bd9Sstevel@tonic-gate 		}
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 	}
8977c478bd9Sstevel@tonic-gate 	return (0);
8987c478bd9Sstevel@tonic-gate }
899