usr/src/cmd/tic/tic_parse.c
changeset 13444 c1ed50709bff
parent 350 06f97f931994
child 13679 1b5898b11b55
equal deleted inserted replaced
13443:76ab5b799560 13444:c1ed50709bff
    20  * CDDL HEADER END
    20  * CDDL HEADER END
    21  */
    21  */
    22 /*
    22 /*
    23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
    23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
    24  * Use is subject to license terms.
    24  * Use is subject to license terms.
       
    25  *
       
    26  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
    25  */
    27  */
    26 /*	Copyright (c) 1988 AT&T	*/
    28 /*	Copyright (c) 1988 AT&T	*/
    27 /*	  All Rights Reserved	*/
    29 /*	  All Rights Reserved	*/
    28 
    30 
    29 
    31 
    30 /* 
    32 /*
    31  * University Copyright- Copyright (c) 1982, 1986, 1988
    33  * University Copyright- Copyright (c) 1982, 1986, 1988
    32  * The Regents of the University of California
    34  * The Regents of the University of California
    33  * All Rights Reserved
    35  * All Rights Reserved
    34  * 
    36  *
    35  * University Acknowledgment- Portions of this document are derived from
    37  * University Acknowledgment- Portions of this document are derived from
    36  * software developed by the University of California, Berkeley, and its
    38  * software developed by the University of California, Berkeley, and its
    37  * contributors.
    39  * contributors.
    38  */
    40  */
    39 
       
    40 #pragma ident	"%Z%%M%	%I%	%E% SMI"
       
    41 
    41 
    42 /*
    42 /*
    43  *  *******************************************************************
    43  *  *******************************************************************
    44  *                         COPYRIGHT NOTICE                           *
    44  *                         COPYRIGHT NOTICE                           *
    45  * ********************************************************************
    45  * ********************************************************************
   185 		old_use_count = -1;
   185 		old_use_count = -1;
   186 		DEBUG(2, "\n\nPART %d\n\n", part2);
   186 		DEBUG(2, "\n\nPART %d\n\n", part2);
   187 		while (use_list.head != NULL && old_use_count != use_count) {
   187 		while (use_list.head != NULL && old_use_count != use_count) {
   188 			old_use_count = use_count;
   188 			old_use_count = use_count;
   189 			for (ptr = use_list.tail; ptr != NULL;
   189 			for (ptr = use_list.tail; ptr != NULL;
   190 							ptr = ptr->bptr) {
   190 			    ptr = ptr->bptr) {
   191 				fseek(stdin, ptr->offset, 0);
   191 				fseek(stdin, ptr->offset, 0);
   192 				reset_input();
   192 				reset_input();
   193 				if ((token_type = get_token()) != NAMES)
   193 				if ((token_type = get_token()) != NAMES)
   194 					syserr_abort(
   194 					syserr_abort(
   195 "Token after a seek not NAMES");
   195 "Token after a seek not NAMES");
   197 				if (complete)
   197 				if (complete)
   198 					dequeue(ptr);
   198 					dequeue(ptr);
   199 			}
   199 			}
   200 
   200 
   201 			for (ptr = use_list.head; ptr != NULL;
   201 			for (ptr = use_list.head; ptr != NULL;
   202 							ptr = ptr->fptr) {
   202 			    ptr = ptr->fptr) {
   203 				fseek(stdin, ptr->offset, 0);
   203 				fseek(stdin, ptr->offset, 0);
   204 				reset_input();
   204 				reset_input();
   205 				if ((token_type = get_token()) != NAMES)
   205 				if ((token_type = get_token()) != NAMES)
   206 					syserr_abort(
   206 					syserr_abort(
   207 "Token after a seek not NAMES");
   207 "Token after a seek not NAMES");
   215 		}
   215 		}
   216 	}
   216 	}
   217 
   217 
   218 	if (use_list.head != NULL && !check_only) {
   218 	if (use_list.head != NULL && !check_only) {
   219 		fprintf(stderr,
   219 		fprintf(stderr,
   220 "\nError in following up use-links.  Either there is\n");
   220 "\nError in following use-links. Either there is a loop in the links\n"
   221 		fprintf(stderr,
   221 "or they reference non-existent terminals. The following is a list of\n"
   222 "a loop in the links or they reference non-existant\n");
   222 "the entries involved:\n\n");
   223 		fprintf(stderr,
       
   224 			"terminals.  The following is a list of the entries\n");
       
   225 		fprintf(stderr, "involved:\n\n");
       
   226 
   223 
   227 		for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
   224 		for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
   228 			fseek(stdin, ptr->offset, 0);
   225 			fseek(stdin, ptr->offset, 0);
   229 			fgets(line, 1024, stdin);
   226 			fgets(line, 1024, stdin);
   230 			fprintf(stderr, "%s", line);
   227 			fprintf(stderr, "%s", line);
   243 	fprintf(stderr, "dump_list %s\n", str);
   240 	fprintf(stderr, "dump_list %s\n", str);
   244 	for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
   241 	for (ptr = use_list.head; ptr != NULL; ptr = ptr->fptr) {
   245 		fseek(stdin, ptr->offset, 0);
   242 		fseek(stdin, ptr->offset, 0);
   246 		fgets(line, 1024, stdin);
   243 		fgets(line, 1024, stdin);
   247 		fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s",
   244 		fprintf(stderr, "ptr %x off %d bptr %x fptr %x str %s",
   248 		ptr, ptr->offset, ptr->bptr, ptr->fptr, line);
   245 		    ptr, ptr->offset, ptr->bptr, ptr->fptr, line);
   249 	}
   246 	}
   250 	fprintf(stderr, "\n");
   247 	fprintf(stderr, "\n");
   251 }
   248 }
   252 
   249 
   253 /*
   250 /*
   370 	complete = 1;
   367 	complete = 1;
   371 	return (token_type);
   368 	return (token_type);
   372 }
   369 }
   373 
   370 
   374 /*
   371 /*
   375     Change all cancellations to a non-entry.
   372  * Change all cancellations to a non-entry.
   376     For booleans, @ -> false
   373  * For booleans, @ -> false
   377     For nums, @ -> -1
   374  * For nums, @ -> -1
   378     For strings, @ -> -1
   375  * For strings, @ -> -1
   379 
   376  *
   380     This only has to be done for entries which
   377  * This only has to be done for entries which
   381     have to be compatible with the pre-Vr3 format.
   378  * have to be compatible with the pre-Vr3 format.
   382 */
   379  */
   383 #ifndef NOCANCELCOMPAT
   380 #ifndef NOCANCELCOMPAT
   384 void
   381 void
   385 elim_cancellations(short Booleans[], short Numbers[], short Strings[])
   382 elim_cancellations(short Booleans[], short Numbers[], short Strings[])
   386 {
   383 {
   387 	int i;
   384 	int i;
   400 			Strings[i] = -1;
   397 			Strings[i] = -1;
   401 	}
   398 	}
   402 }
   399 }
   403 #endif /* NOCANCELCOMPAT */
   400 #endif /* NOCANCELCOMPAT */
   404 /*
   401 /*
   405     Change the cancellation signal from the -2 used internally to
   402  * Change the cancellation signal from the -2 used internally to
   406     the 2 used within the binary.
   403  * the 2 used within the binary.
   407 */
   404  */
   408 void
   405 void
   409 change_cancellations(short Booleans[])
   406 change_cancellations(short Booleans[])
   410 {
   407 {
   411 	int i;
   408 	int i;
   412 	for (i = 0; i < BoolCount; i++) {
   409 	for (i = 0; i < BoolCount; i++) {
   496 			continue;
   493 			continue;
   497 		else if (isspace(*name) || (*name == '/'))
   494 		else if (isspace(*name) || (*name == '/'))
   498 			return (1);
   495 			return (1);
   499 	if (error) {
   496 	if (error) {
   500 		fprintf(stderr, "%s: Line %d: Illegal terminal name - '%s'\n",
   497 		fprintf(stderr, "%s: Line %d: Illegal terminal name - '%s'\n",
   501 						progname, curr_line, name);
   498 		    progname, curr_line, name);
   502 		fprintf(stderr,
   499 		fprintf(stderr,
   503 			"Terminal names must start with a letter or digit\n");
   500 		    "Terminal names must start with a letter or digit\n");
   504 		exit(1);
   501 		exit(1);
   505 	}
   502 	}
   506 	return (0);
   503 	return (0);
   507 }
   504 }
   508 
   505 
   560 
   557 
   561 	check_dir(first_name[0]);
   558 	check_dir(first_name[0]);
   562 
   559 
   563 	sprintf(filename, "%c/%s", first_name[0], first_name);
   560 	sprintf(filename, "%c/%s", first_name[0], first_name);
   564 
   561 
   565 	if (strlen(filename) > 16)
       
   566 		warning("'%s' filename too long, truncating to '%.16s'\n",
       
   567 							filename, filename);
       
   568 	if (stat64(filename, &statbuf) >= 0 && statbuf.st_mtime >= start_time) {
   562 	if (stat64(filename, &statbuf) >= 0 && statbuf.st_mtime >= start_time) {
   569 		warning("'%s' defined in more than one entry.", first_name);
   563 		warning("'%s' defined in more than one entry.", first_name);
   570 		fprintf(stderr, "Entry being used is '%s'.\n",
   564 		fprintf(stderr, "Entry being used is '%s'.\n",
   571 			    (unsigned)term_names + string_table);
   565 		    (unsigned)term_names + string_table);
   572 	}
   566 	}
   573 
   567 
   574 	if (!check_only) {
   568 	if (!check_only) {
   575 		unlink(filename);
   569 		unlink(filename);
   576 		fp = fopen(filename, "w");
   570 		fp = fopen(filename, "w");
   577 		if (fp == NULL) {
   571 		if (fp == NULL) {
   578 			perror(filename);
   572 			perror(filename);
   579 			syserr_abort("Can't open %s/%s\n",
   573 			syserr_abort("Can't open %s/%s\n", destination,
   580 							destination, filename);
   574 			    filename);
   581 		}
   575 		}
   582 		DEBUG(1, "Created %.16s\n", filename);
   576 		DEBUG(1, "Created %s\n", filename);
   583 	} else DEBUG(1, "Would have created %.16s\n", filename);
   577 	} else DEBUG(1, "Would have created %s\n", filename);
   584 
   578 
   585 #ifndef NOCANCELCOMPAT
   579 #ifndef NOCANCELCOMPAT
   586 	/* if there is no '+' in the name, eliminate */
   580 	/* eliminate cancellation markings if there is no '+' in the name */
   587 	/* cancellation markings. */
       
   588 	if (strchr(first_name, '+') == 0)
   581 	if (strchr(first_name, '+') == 0)
   589 		elim_cancellations(Booleans, Numbers, Strings);
   582 		elim_cancellations(Booleans, Numbers, Strings);
   590 	else
   583 	else
   591 #endif /* NOCANCELCOMPAT */
   584 #endif /* NOCANCELCOMPAT */
   592 		change_cancellations(Booleans);
   585 		change_cancellations(Booleans);
   593 
   586 
   594 	if (!check_only) {
   587 	if (!check_only) {
   595 		if (write_object(fp, Booleans, Numbers, Strings) < 0) {
   588 		if (write_object(fp, Booleans, Numbers, Strings) < 0) {
   596 			syserr_abort("Error in writing %s/%s",
   589 			syserr_abort("Error writing %s/%s", destination,
   597 						destination, filename);
   590 			    filename);
   598 		}
   591 		}
   599 		fclose(fp);
   592 		fclose(fp);
   600 	}
   593 	}
   601 
   594 
   602 	alphastart = isalpha(first_name[0]);
   595 	alphastart = isalpha(first_name[0]);
   618 		}
   611 		}
   619 
   612 
   620 		if (invalid_term_name(cur_name)) {
   613 		if (invalid_term_name(cur_name)) {
   621 			if (other_names)
   614 			if (other_names)
   622 				warning("'%s': bad term name found in list.",
   615 				warning("'%s': bad term name found in list.",
   623 								cur_name);
   616 				    cur_name);
   624 			continue;
   617 			continue;
   625 		}
   618 		}
   626 
   619 
   627 		check_dir(cur_name[0]);
   620 		check_dir(cur_name[0]);
   628 
   621 
   629 		sprintf(linkname, "%c/%s", cur_name[0], cur_name);
   622 		sprintf(linkname, "%c/%s", cur_name[0], cur_name);
   630 
   623 
   631 		if (strlen(linkname) > 16) {
       
   632 			if (other_names) {
       
   633 				warning(
       
   634 "'%s' linkname too long, truncating to '%.16s'\n", linkname, linkname);
       
   635 			} else {
       
   636 				continue;
       
   637 			}
       
   638 		}
       
   639 		alphastart |= isalpha(cur_name[0]);
   624 		alphastart |= isalpha(cur_name[0]);
   640 
   625 
   641 		if (strcmp(first_name, cur_name) == 0) {
   626 		if (strcmp(first_name, cur_name) == 0) {
   642 			warning("Terminal name '%s' synonym for itself",
   627 			warning("Terminal name '%s' synonym for itself",
   643 							first_name);
   628 			    first_name);
   644 		} else  {
   629 		} else  {
   645 			if (!check_only) {
   630 			if (!check_only) {
   646 				if (stat64(linkname, &statbuf) >= 0 &&
   631 				if (stat64(linkname, &statbuf) >= 0 &&
   647 					    statbuf.st_mtime >= start_time) {
   632 				    statbuf.st_mtime >= start_time) {
   648 					warning(
   633 					warning(
   649 "'%s' defined in more than one entry.", cur_name);
   634 "'%s' defined in more than one entry.", cur_name);
   650 					fprintf(stderr,
   635 					fprintf(stderr,
   651 					    "Entry being used is '%s'.\n",
   636 					    "Entry being used is '%s'.\n",
   652 					    (unsigned)term_names +
   637 					    (unsigned)term_names +
   653 								string_table);
   638 					    string_table);
   654 				}
   639 				}
   655 				unlink(linkname);
   640 				unlink(linkname);
   656 				if (link(filename, linkname) < 0)
   641 				if (link(filename, linkname) < 0)
   657 					syserr_abort("Can't link %s to %s",
   642 					syserr_abort("Can't link %s to %s",
   658 							filename, linkname);
   643 					    filename, linkname);
   659 				DEBUG(1, "Linked %.16s\n", linkname);
   644 				DEBUG(1, "Linked %s\n", linkname);
   660 			} else DEBUG(1, "Would have linked %.16s\n", linkname);
   645 			} else DEBUG(1, "Would have linked %s\n", linkname);
   661 		}
   646 		}
   662 	}
   647 	}
   663 
   648 
   664 	if (!alphastart) {
   649 	if (!alphastart) {
   665 		warning("At least one synonym should begin with a letter.");
   650 		warning("At least one synonym should begin with a letter.");