239 lines
6.1 KiB
C
Executable File
239 lines
6.1 KiB
C
Executable File
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
|
|
/* All Rights Reserved */
|
|
|
|
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
|
|
/* The copyright notice above does not evidence any */
|
|
/* actual or intended publication of such source code. */
|
|
|
|
#ident "@(#)output.c 1.4 92/07/14 SMI" /* SVr4.0 k18.2 */
|
|
|
|
#include <stdio.h>
|
|
#include "symtab.h"
|
|
#include "kbd.h"
|
|
|
|
#ifdef NATIVE
|
|
#define gettxt(a,b) b
|
|
#else
|
|
extern char *gettxt();
|
|
#endif
|
|
|
|
extern int numnode;
|
|
extern int nerrors;
|
|
extern struct kbd_map maplist[];
|
|
extern int curmap;
|
|
extern unsigned char curswitch;
|
|
extern unsigned char oneone[];
|
|
extern int oneflag;
|
|
extern int fullflag;
|
|
extern int timeflag;
|
|
|
|
struct kbd_header hdr = { KBD_MAGIC, 0 };
|
|
struct kbd_tab *tb = 0;
|
|
struct cornode *nodes;
|
|
|
|
int tsize = 0;
|
|
unsigned char *tptr;
|
|
unsigned char text[65536]; /* 64 k max text */
|
|
|
|
extern int optt, optv, optreach;
|
|
extern struct node *root;
|
|
char *calloc();
|
|
|
|
buildtbl(val) /* build one map; don't output yet */
|
|
char *val;
|
|
{
|
|
register struct kbd_tab *t;
|
|
register int i;
|
|
register unsigned char *s;
|
|
|
|
hdr.h_magic[KBD_HOFF] = KBD_VER;
|
|
hdr.h_magic[KBD_HOFF+1] = '\007';
|
|
if (val == LINKAGE) {
|
|
++(hdr.h_ntabs);
|
|
return;
|
|
}
|
|
t = (struct kbd_tab *) calloc(1, sizeof(struct kbd_tab));
|
|
if (oneflag) {
|
|
t->t_flag |= KBD_ONE;
|
|
maplist[curmap].mapone = (unsigned char *) calloc(1, 256);
|
|
s = maplist[curmap].mapone;
|
|
for (i = 0; i < 256; i++)
|
|
*s++ = oneone[i];
|
|
}
|
|
maplist[curmap].maptab = t;
|
|
|
|
++(hdr.h_ntabs); /* add a table */
|
|
strncpy(t->t_name, maplist[curmap].mapname, 15);
|
|
t->t_nodes = numnode;
|
|
if (fullflag) {
|
|
t->t_min = maplist[curmap].map_min;
|
|
t->t_max = maplist[curmap].map_max;
|
|
t->t_flag |= KBD_FULL;
|
|
}
|
|
else
|
|
t->t_min = t->t_max = 0;
|
|
if (timeflag)
|
|
t->t_flag |= KBD_TIME;
|
|
nodes = (struct cornode *)calloc(numnode, sizeof(struct cornode));
|
|
tsize = 0;
|
|
tptr = text;
|
|
maplist[curmap].maproot = root;
|
|
tbaux(root); /* build node table */
|
|
/*
|
|
* add in "error" entry, if any.
|
|
*/
|
|
if (maplist[curmap].maperr) {
|
|
t->t_error = (unsigned short) (tptr - text);
|
|
t->t_flag |= KBD_ERR;
|
|
strcpy(tptr, maplist[curmap].maperr);
|
|
i = strlen(maplist[curmap].maperr) + 1;
|
|
tsize += i;
|
|
tptr += i;
|
|
}
|
|
root = (struct node *) 0; /* no map yet... */
|
|
maplist[curmap].maptext = (unsigned char *) calloc(1, (tptr - text));
|
|
memcpy(maplist[curmap].maptext, text, (tptr - text));
|
|
t->t_text = tsize;
|
|
maplist[curmap].mapnodes = nodes;
|
|
/*
|
|
* Report on bytes that can't be generated, if requested.
|
|
*/
|
|
if (optreach)
|
|
reachout(t->t_name, text, (int) tptr - (int) text,
|
|
maplist[curmap].mapone, nodes, numnode);
|
|
nodes = (struct cornode *) 0;
|
|
}
|
|
|
|
/*
|
|
* Builds the "cornode" part of a table as a contiguous block of
|
|
* cornodes.
|
|
*/
|
|
tbaux(p)
|
|
|
|
struct node *p;
|
|
{
|
|
register struct node *q;
|
|
register int i, n;
|
|
|
|
q = p;
|
|
while (q) {
|
|
n = q->n_num;
|
|
nodes[n].c_val = q->n_val;
|
|
switch (q->n_flag) {
|
|
case N_CHILD:
|
|
if (q->n_what.n_child->n_flag == N_RESULT) {
|
|
nodes[n].c_flag = ND_RESULT;
|
|
i = strlen(q->n_what.n_child->n_what.n_result) + 1;
|
|
/*
|
|
* This "if" is a hack to hoist many-one mapping results into the node.
|
|
* if "strlen(q->n_what.n_child->n_what.n_result) is 1, then set a
|
|
* flag and put the result into nodes[n].c_child directly.
|
|
*/
|
|
if (i == 2) { /* strlen is 1 */
|
|
nodes[n].c_child = *(q->n_what.n_child->n_what.n_result);
|
|
nodes[n].c_flag |= ND_INLINE;
|
|
break;
|
|
/* out of switch, finished node. */
|
|
}
|
|
nodes[n].c_child =
|
|
(unsigned short) (tptr - text);
|
|
strcpy(tptr, q->n_what.n_child->n_what.n_result);
|
|
tptr += i;
|
|
tsize += i;
|
|
if (i >= KBDOMAX) {
|
|
fprintf(stderr,
|
|
gettxt("kbdcomp:28", "Error: string too long: %s\n"),
|
|
q->n_what.n_child->n_what.n_result);
|
|
++nerrors;
|
|
}
|
|
if (tsize > (KBDTMAX-10))
|
|
fprintf(stderr,
|
|
gettxt("kbdcomp:29", "Warning: replacement text close to overflowing.\n"));
|
|
|
|
}
|
|
else {
|
|
if (q->n_flag == N_EMPTY) /* SHOULD NEVER HAPPEN - only ROOT has empties. */
|
|
fprintf(stderr, gettxt("kbdcomp:30", "Internal error - child node empty.\n"));
|
|
nodes[n].c_flag = 0; /* q->n_flag; */
|
|
nodes[n].c_child = q->n_node;
|
|
tbaux(q->n_what.n_child);
|
|
}
|
|
break;
|
|
case N_EMPTY:
|
|
nodes[n].c_child = q->n_val;
|
|
nodes[n].c_flag = (ND_RESULT | ND_INLINE);
|
|
break;
|
|
default:
|
|
case N_RESULT:
|
|
fprintf(stderr, gettxt("kbdcomp:31", "Internal error: un-hoisted node.\n"));
|
|
break;
|
|
}
|
|
if (! q->n_next)
|
|
nodes[q->n_num].c_flag |= ND_LAST;
|
|
q = q->n_next;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Output all the maps.
|
|
*/
|
|
|
|
output()
|
|
|
|
{
|
|
register struct kbd_tab *t;
|
|
register int i;
|
|
|
|
if (optt)
|
|
fprintf(stderr, gettxt("kbdcomp:32", "%d table%s:\n"), hdr.h_ntabs,
|
|
(hdr.h_ntabs == 1) ? "" : gettxt("kbdcomp:33", "s"));
|
|
if (! optv)
|
|
write(1, &hdr, sizeof(struct kbd_header));
|
|
|
|
for (i = 0; i < hdr.h_ntabs; i++) {
|
|
if (maplist[i].mapname == LINKAGE) {
|
|
t = (struct kbd_tab *) calloc(1, sizeof(struct kbd_tab));
|
|
t->t_flag = KBD_COT;
|
|
t->t_max = maplist[i].map_max;
|
|
if (optt)
|
|
fprintf(stderr, gettxt("kbdcomp:34", "Link \"%s\"\n"), maplist[i].maptext);
|
|
if (! optv) {
|
|
write(1, t, sizeof(struct kbd_tab));
|
|
write(1, maplist[i].maptext, t->t_max);
|
|
}
|
|
continue;
|
|
}
|
|
else if (maplist[i].mapname == EXTERNAL) {
|
|
t = (struct kbd_tab *) calloc(1, sizeof(struct kbd_tab));
|
|
t->t_flag = KBD_ALP;
|
|
t->t_max = maplist[i].map_max;
|
|
if (optt)
|
|
fprintf(stderr, gettxt("kbdcomp:35", "Extern \"%s\"\n"), maplist[i].maptext);
|
|
if (! optv) {
|
|
write(1, t, sizeof(struct kbd_tab));
|
|
write(1, maplist[i].maptext, t->t_max);
|
|
}
|
|
continue;
|
|
}
|
|
t = maplist[i].maptab;
|
|
if (optt) {
|
|
fprintf(stderr, gettxt("kbdcomp:36", "\t%s:\n"), maplist[i].mapname);
|
|
#if 0
|
|
fprintf(stderr, gettxt("kbdcomp:37", "\t%s: swtch(%02X) "),
|
|
maplist[i].mapname, t->t_swtch);
|
|
#endif
|
|
fprintf(stderr, gettxt("kbdcomp:38", "\t\t%d node%s, %d byte%s text\n"),
|
|
t->t_nodes, (t->t_nodes == 1) ? "" : gettxt("kbdcomp:39", "s"),
|
|
t->t_text, (t->t_text == 1) ? "" : gettxt("kbdcomp:40", "s"));
|
|
}
|
|
if (! optv) {
|
|
write(1, t, sizeof(struct kbd_tab));
|
|
if (t->t_flag & KBD_ONE)
|
|
write(1, maplist[i].mapone, 256);
|
|
write(1, maplist[i].mapnodes,
|
|
t->t_nodes * sizeof(struct cornode));
|
|
write(1, maplist[i].maptext, t->t_text);
|
|
}
|
|
}
|
|
}
|