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