ticparse.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1996, by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* Terminal Information Compiler
*
* Copyright 1990, 1992 by Mortice Kern Systems Inc. All rights reserved.
*
* Portions of this code Copyright 1982 by Pavel Curtis.
*/
#ifdef M_RCSID
#ifndef lint
#endif
#endif
#include "tic.h"
#include <ctype.h>
#include <errno.h>
char *string_table;
int next_free; /* next free character in string_table */
int table_size = 0; /* current string_table size */
int term_names; /* string table offset - current terminal */
int part2 = 0; /* set to allow old compiled defns to be used */
int complete = 0; /* 1 if entry done with no forward uses */
struct use_item {
long offset;
};
struct use_header {
};
int use_count = 0;
/*
* The use_list is a doubly-linked list with NULLs terminating the lists:
*
* use_item use_item use_item
* --------- --------- ---------
* | | | | | | offset
* |-------| |-------| |-------|
* | ----+-->| ----+-->| NULL | fptr
* |-------| |-------| |-------|
* | NULL |<--+---- |<--+---- | bptr
* --------- --------- ---------
* ^ ^
* | ------------------ |
* | | | | |
* +--+---- | ----+---+
* | | |
* ------------------
* head tail
* use_list
*
*/
3107, "File does not start with terminal names in column one", "E"
);
\n\
Error in following up use-links. Either there is\n\
a loop in the links or they reference non-existant\n\
terminals. The following is a list of the entries\n\
involved:\n\n\
", "E");
char nomem_use_list[] = m_textstr(
3110, "Not enough memory for use_list element", "E"
);
char more_than_one[] = m_textstr(
3112, "More than one entry defined for \"%s\".\n","W term"
);
compile: Line %d: Illegal terminal name - '%s'\n\
Terminal names must start with lowercase or digit.\n\
", "E line_num term");
/*f
* debugging routine to dump list
*/
STATIC int
char *str;
{
char line[512];
{
}
}
/*f
* Generate an error message if given name does not begin with a
* digit or lower-case letter.
*/
STATIC int
char *name;
{
exit(1);
}
}
/*f
* Test whether this machine will need byte-swapping
*/
STATIC int
{
union {
short num;
char byte[2];
} test;
}
/*f
* Put a record of the given offset onto the use-list.
*/
STATIC int
long offset;
{
{
}
else
{
}
use_count ++;
}
/*f
* remove the pointed-to item from the use_list
*/
STATIC int
{
else
else
use_count --;
}
/*f
* Write out the compiled entry to the given file.
* Return 0 if OK or -1 if not.
*/
STATIC int
{
int i, tlength;
if (TERM_NAMES_LENGTH < tlength)
if (must_swap()) {
} else {
}
return (-1);
return (-1);
if (must_swap()) {
for (i = 0; i < NUMCOUNT; ++i)
for (i = 0; i < STRCOUNT; ++i)
}
return (-1);
return (0);
}
/*f
* Save the compiled version of a description in the filesystem.
*
* make a copy of the name-list
* break it up into first-name and all-but-last-name
* creat(first-name)
* write object information to first-name
* close(first-name)
* for each name in all-but-last-name
* link to first-name
*
*/
STATIC void
{
/* Bag copy of terminal name list. Parse off the last name,
* which should be the terminal's long name. Parse off the
* first name to be used for the terminal filename.
*/
if (*p == '|') {
long_name = ++p;
break;
}
}
if (tname == p)
if (*p == '|') {
if (tname < p)
*p++ = '\0';
break;
}
}
if (check_only) {
return;
}
/* Create terminfo object file. */
}
if (write_object(fp) < 0)
/* Create links for alternate names. */
while (p < long_name) {
for (q = p; p < long_name; ++p) {
if (*p == '|') {
*p++ = '\0';
break;
}
}
check_name(q);
continue;
}
continue;
}
continue;
}
}
if (write_object(fp) < 0)
} else {
}
}
}
/*f
* copy string into next free part of string_table, doing a realloc()
* if necessary. return offset of beginning of string from start of
* string_table.
*/
STATIC int
char *string;
{
int old_next_free = next_free;
if (table_size == 0)
{
table_size = 1024;
}
{
== NULL)
table_size += 1024;
}
return (old_next_free);
}
/*f
* Merge the compiled file whose name is in cur_token.valstring
* with the current entry.
*
* if it's a forward use-link
* if item_ptr == NULL
* queue it up for later handling
* else
* ignore it (we're already going through the queue)
* else it's a backward use-link
* read in the object file for that terminal
* merge contents with current structure
*
* Returned value is 0 if it was a backward link and we
* successfully read it in, -1 if a forward link.
*/
STATIC int
long entry_offset;
{
int i, err;
);
}
} else {
}
return (-1);
}
switch (err) {
case 1:
for (i = 0; i < BOOLCOUNT; ++i) {
boolean[i] = 1;
}
for (i = 0; i < NUMCOUNT; ++i) {
}
for (i = 0; i < STRCOUNT; ++i) {
}
(void) del_curterm(cur_term);
break;
case 0:
case -1:
}
return (0);
}
/*f
* Compile one entry. During the first pass, item_ptr is NULL. In pass
* two, item_ptr points to the current entry in the use_list.
*
* found-forward-use = FALSE
* re-initialise internal arrays
* save names in string_table
* get_token()
* while (not EOF and not NAMES)
* if found-forward-use
* do nothing
* else if 'use'
* if handle_use() < 0
* found-forward-use = TRUE
* else
* check for existance and type-correctness
* enter cap into structure
* if STRING
* save string in string_table
* get_token()
* if ! found-forward-use
* clear CANCELS out of the structure
* dump compiled entry into filesystem
*/
STATIC int
{
void *array;
long entry_offset;
int i, index;
register int token_type;
int found_forward_use = 0;
reset();
next_free = 0;
complete = 0;
for (token_type = get_token();
token_type = get_token()) {
if (found_forward_use) {
;
found_forward_use = 1;
} else {
);
continue;
}
switch (token_type) {
case CANCEL:
else
continue;
case BOOLEAN:
continue;
}
break;
case NUMBER:
continue;
}
break;
case STRING:
);
continue;
}
break;
default:
panic_mode(',');
continue;
}
}
}
if (found_forward_use)
return (token_type);
/* Changed canceled values into in-active values. */
for (i = 0; i < BOOLCOUNT; ++i)
if (boolean[i] == 2)
boolean[i] = 0;
for (i = 0; i < NUMCOUNT; ++i)
if (number[i] == -2)
number[i] = -1;
for (i = 0; i < STRCOUNT; ++i)
if (string[i] == -2)
string[i] = -1;
complete = 1;
return (token_type);
}
/*f
* Main loop of the compiler.
*
* get_token()
* if curr_token != NAMES
* err_abort()
* while (not at end of file)
* do an entry
*/
void
compile()
{
char line[1024];
int token_type;
int old_use_count;
token_type = get_token();
if (token_type != NAMES)
while (token_type != EOF)
old_use_count = -1;
{
{
reset_input();
if (complete)
}
{
reset_input();
if (complete)
}
}
}
}
exit(1);
}
}