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