1567 lines
39 KiB
C
Executable File
1567 lines
39 KiB
C
Executable File
/* Copyright (c) 1988 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 "@(#)captoinfo.c 1.5 92/07/14 SMI" /* SVr4.0 1.12 */
|
|
|
|
/*
|
|
NAME
|
|
captoinfo - convert a termcap description to a terminfo description
|
|
|
|
SYNOPSIS
|
|
captoinfo [-1vV] [-w width] [ filename ... ]
|
|
|
|
AUTHOR
|
|
Tony Hansen, January 22, 1984.
|
|
*/
|
|
|
|
#include "curses.h"
|
|
#include <ctype.h>
|
|
#include "otermcap.h"
|
|
#include "print.h"
|
|
|
|
#define trace stderr /* send trace messages to stderr */
|
|
|
|
/* extra termcap variables no longer in terminfo */
|
|
char *oboolcodes[] =
|
|
{
|
|
"bs", /* Terminal can backspace with "^H" */
|
|
"nc", /* No correctly working carriage return (DM2500,H2000) */
|
|
"ns", /* Terminal is a CRT but does not scroll. */
|
|
"pt", /* Has hardware tabs (may need to be set with "is") */
|
|
"MT", /* Has meta key, alternate code. */
|
|
"xr", /* Return acts like ce \r \n (Delta Data) */
|
|
0
|
|
};
|
|
int cap_bs = 0, cap_nc = 1, cap_ns = 2, cap_pt = 3, cap_MT = 4, cap_xr = 5;
|
|
char *onumcodes[] =
|
|
{
|
|
"dB", /* Number of millisec of bs delay needed */
|
|
"dC", /* Number of millisec of cr delay needed */
|
|
"dF", /* Number of millisec of ff delay needed */
|
|
"dN", /* Number of millisec of nl delay needed */
|
|
"dT", /* Number of millisec of tab delay needed */
|
|
"ug", /* Number of blank chars left by us or ue */
|
|
/* Ignore the 'kn' number. It was ill-defined and never used. */
|
|
"kn", /* Number of "other" keys */
|
|
0
|
|
};
|
|
int cap_dB = 0, cap_dC = 1, cap_dF = 2, cap_dN = 3, cap_dT = 4, cap_ug = 5;
|
|
|
|
char *ostrcodes[] =
|
|
{
|
|
"bc", /* Backspace if not "^H" */
|
|
"ko", /* Termcap entries for other non-function keys */
|
|
"ma", /* Arrow key map, used by vi version 2 only */
|
|
"nl", /* Newline character (default "\n") */
|
|
"rs", /* undocumented reset string, like is (info is2) */
|
|
/* Ignore the 'ml' and 'mu' strings. */
|
|
"ml", /* Memory lock on above cursor. */
|
|
"mu", /* Memory unlock (turn off memory lock). */
|
|
0
|
|
};
|
|
int cap_bc = 0, cap_ko = 1, cap_ma = 2, cap_nl = 3, cap_rs = 4;
|
|
|
|
#define numelements(x) (sizeof(x)/sizeof(x[0]))
|
|
char oboolval [2] [numelements(oboolcodes)];
|
|
short onumval [2] [numelements(onumcodes)];
|
|
char *ostrval [2] [numelements(ostrcodes)];
|
|
|
|
/* externs from libcurses.a */
|
|
extern char *boolnames [], *boolcodes [];
|
|
extern char *numnames [], *numcodes [];
|
|
extern char *strnames [], *strcodes [];
|
|
|
|
/* externs from libc.a */
|
|
extern char *getenv ();
|
|
extern char *malloc ();
|
|
extern void exit ();
|
|
#if defined(SYSV) || defined(USG) /* handle both Sys Vr2 and Vr3 curses */
|
|
extern char *getcwd ();
|
|
#else
|
|
extern char *getwd ();
|
|
#endif /* SYSV || USG */
|
|
extern int getopt ();
|
|
extern int optind;
|
|
extern char *optarg;
|
|
extern int strncmp(), strcmp();
|
|
extern char *strcpy();
|
|
|
|
/* globals for this file */
|
|
char *progname; /* argv [0], the name of the program */
|
|
static char *term_name; /* the name of the terminal being worked on */
|
|
static int uselevel; /* whether we're dealing with use= info */
|
|
static int boolcount, /* the maximum numbers of each name array */
|
|
numcount,
|
|
strcount;
|
|
|
|
/* globals dealing with the environment */
|
|
extern char **environ;
|
|
static char TERM [100];
|
|
#if defined(SYSV) || defined(USG) /* handle both Sys Vr2 and Vr3 curses */
|
|
static char dirname [BUFSIZ];
|
|
#else
|
|
# include <sys/param.h>
|
|
static char dirname [MAXPATHLEN];
|
|
#endif /* SYSV || USG */
|
|
static char TERMCAP [BUFSIZ+15];
|
|
static char *newenviron [] = { &TERM [0], &TERMCAP [0], 0 };
|
|
|
|
/* dynamic arrays */
|
|
static char *boolval [2]; /* dynamic array of boolean values */
|
|
static short *numval [2]; /* dynamic array of numeric values */
|
|
static char **strval [2]; /* dynamic array of string pointers */
|
|
|
|
/* data buffers */
|
|
static char *capbuffer; /* string table, pointed at by strval */
|
|
static char *nextstring; /* pointer into string table */
|
|
static char *bp; /* termcap raw string table */
|
|
static char *buflongname; /* place to copy the long names */
|
|
|
|
/* flags */
|
|
static int verbose = 0; /* debugging printing level */
|
|
static int copycomments = 0; /* copy comments from tercap source */
|
|
|
|
#define ispadchar(c) (isdigit(c) || (c) == '.' || (c) == '*')
|
|
|
|
/*
|
|
Verify that the names given in the termcap entry are all valid.
|
|
*/
|
|
|
|
int capsearch (codes, ocodes, cap)
|
|
register char *codes[], *ocodes[], *cap;
|
|
{
|
|
for ( ; *codes; codes++)
|
|
if (((*codes)[0] == cap[0]) && ((*codes)[1] == cap[1]))
|
|
return 1;
|
|
|
|
for ( ; *ocodes; ocodes++)
|
|
if (((*ocodes)[0] == cap[0]) && ((*ocodes)[1] == cap[1]))
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void checktermcap()
|
|
{
|
|
register char *tbuf = bp;
|
|
enum { tbool, tnum, tstr, tcancel, tunknown } type;
|
|
|
|
for (;;)
|
|
{
|
|
tbuf = tskip(tbuf);
|
|
while (*tbuf == '\t' || *tbuf == ' ' || *tbuf == ':')
|
|
tbuf++;
|
|
|
|
if (*tbuf == 0)
|
|
return;
|
|
|
|
/* commented out entry? */
|
|
if (*tbuf == '.')
|
|
{
|
|
if (verbose)
|
|
(void) fprintf (trace, "termcap string '%c%c' commented out.\n",
|
|
tbuf[1], tbuf[2]);
|
|
if (!capsearch (boolcodes, oboolcodes, tbuf+1) &&
|
|
!capsearch (numcodes, onumcodes, tbuf+1) &&
|
|
!capsearch (strcodes, ostrcodes, tbuf+1))
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: commented out code '%.2s' is unknown.\n",
|
|
progname, term_name, tbuf+1);
|
|
continue;
|
|
}
|
|
|
|
if (verbose)
|
|
(void) fprintf (trace, "looking at termcap string '%.2s'.\n",
|
|
tbuf);
|
|
|
|
switch (tbuf[2])
|
|
{
|
|
case ':': case '\0': type = tbool; break;
|
|
case '#': type = tnum; break;
|
|
case '=': type = tstr; break;
|
|
case '@': type = tcancel; break;
|
|
default:
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: unknown type given for the termcap code '%.2s'.\n",
|
|
progname, term_name, tbuf);
|
|
type = tunknown;
|
|
}
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "type of '%.2s' is %s.\n", tbuf,
|
|
(type == tbool) ? "boolean" :
|
|
(type == tnum) ? "numeric" :
|
|
(type = tstr) ? "string" :
|
|
(type = tcancel) ? "canceled" : "unknown");
|
|
|
|
/* look for the name in bools */
|
|
if (capsearch (boolcodes, oboolcodes, tbuf))
|
|
{
|
|
if (type != tbool && type != tcancel)
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: wrong type given for the boolean termcap code '%.2s'.\n",
|
|
progname, term_name, tbuf);
|
|
continue;
|
|
}
|
|
|
|
/* look for the name in nums */
|
|
if (capsearch (numcodes, onumcodes, tbuf))
|
|
{
|
|
if (type != tnum && type != tcancel)
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: wrong type given for the numeric termcap code '%.2s'.\n",
|
|
progname, term_name, tbuf);
|
|
continue;
|
|
}
|
|
|
|
/* look for the name in strs */
|
|
if (capsearch (strcodes, ostrcodes, tbuf))
|
|
{
|
|
if (type != tstr && type != tcancel)
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: wrong type given for the string termcap code '%.2s'.\n",
|
|
progname, term_name, tbuf);
|
|
continue;
|
|
}
|
|
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: the %s termcap code '%.2s' is not a valid name.\n",
|
|
progname, term_name,
|
|
(type == tbool) ? "boolean" :
|
|
(type == tnum) ? "numeric" :
|
|
(type = tstr) ? "string" :
|
|
(type = tcancel) ? "canceled" : "(unknown type)",
|
|
tbuf);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Fill up the termcap tables.
|
|
*/
|
|
int filltables ()
|
|
{
|
|
register int i, tret;
|
|
|
|
/* Retrieve the termcap entry. */
|
|
if ((tret = otgetent (bp, term_name)) != 1)
|
|
{
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: tgetent failed with return code %d (%s).\n",
|
|
progname, term_name, tret,
|
|
(tret == 0) ? "non-existent or invalid entry" :
|
|
(tret == -1) ? "cannot open $TERMCAP" :
|
|
"unknown reason");
|
|
return 0;
|
|
}
|
|
|
|
if (verbose)
|
|
{
|
|
(void) fprintf (trace, "bp=");
|
|
(void) cpr (trace, bp);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
|
|
if (uselevel == 0)
|
|
checktermcap();
|
|
|
|
/* Retrieve the values that are in terminfo. */
|
|
|
|
/* booleans */
|
|
for (i = 0; boolcodes [i]; i++)
|
|
{
|
|
boolval [uselevel] [i] = otgetflag (boolcodes [i]);
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "boolcodes=%s, ", boolcodes [i]);
|
|
(void) fprintf (trace, "boolnames=%s, ", boolnames [i]);
|
|
(void) fprintf (trace, "flag=%d.\n", boolval [uselevel] [i]);
|
|
}
|
|
}
|
|
|
|
/* numbers */
|
|
for (i = 0; numcodes [i]; i++)
|
|
{
|
|
numval [uselevel] [i] = otgetnum (numcodes [i]);
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "numcodes=%s, ", numcodes [i]);
|
|
(void) fprintf (trace, "numnames=%s, ", numnames [i]);
|
|
(void) fprintf (trace, "num=%d.\n", numval [uselevel] [i]);
|
|
}
|
|
}
|
|
|
|
if (uselevel == 0)
|
|
nextstring = capbuffer;
|
|
|
|
/* strings */
|
|
for (i = 0; strcodes [i]; i++)
|
|
{
|
|
strval [uselevel] [i] = otgetstr (strcodes [i], &nextstring);
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "strcodes=%s, ", strcodes [i]);
|
|
(void) fprintf (trace, "strnames=%s, ", strnames [i]);
|
|
if (strval [uselevel] [i])
|
|
{
|
|
(void) fprintf (trace, "str=");
|
|
tpr (trace, strval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
else
|
|
(void) fprintf (trace, "str=NULL.\n");
|
|
}
|
|
/* remove zero length strings */
|
|
if (strval[uselevel][i] && (strval[uselevel][i][0] == '\0') )
|
|
{
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: cap %s (info %s) is NULL: REMOVED\n",
|
|
progname, term_name, strcodes[i], strnames[i]);
|
|
strval [uselevel] [i] = NULL;
|
|
}
|
|
}
|
|
|
|
/* Retrieve the values not found in terminfo anymore. */
|
|
|
|
/* booleans */
|
|
for (i = 0; oboolcodes [i]; i++)
|
|
{
|
|
oboolval [uselevel] [i] = otgetflag (oboolcodes [i]);
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "oboolcodes=%s, ", oboolcodes[i]);
|
|
(void) fprintf (trace, "flag=%d.\n", oboolval [uselevel] [i]);
|
|
}
|
|
}
|
|
|
|
/* numbers */
|
|
for (i = 0; onumcodes [i]; i++)
|
|
{
|
|
onumval [uselevel] [i] = otgetnum (onumcodes [i]);
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "onumcodes=%s, ", onumcodes [i]);
|
|
(void) fprintf (trace, "num=%d.\n", onumval [uselevel] [i]);
|
|
}
|
|
}
|
|
|
|
/* strings */
|
|
for (i = 0; ostrcodes [i]; i++)
|
|
{
|
|
ostrval [uselevel] [i] = otgetstr (ostrcodes [i], &nextstring);
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "ostrcodes=%s, ", ostrcodes [i]);
|
|
if (ostrval [uselevel] [i])
|
|
{
|
|
(void) fprintf (trace, "ostr=");
|
|
tpr (trace, ostrval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
else
|
|
(void) fprintf (trace, "ostr=NULL.\n");
|
|
}
|
|
/* remove zero length strings */
|
|
if (ostrval[uselevel][i] && (ostrval[uselevel][i][0] == '\0') )
|
|
{
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: cap %s (no terminfo name) is NULL: REMOVED\n",
|
|
progname, term_name, ostrcodes[i]);
|
|
ostrval [uselevel] [i] = NULL;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
This routine copies the set of names from the termcap entry into
|
|
a separate buffer, getting rid of the old obsolete two character
|
|
names.
|
|
*/
|
|
getlongname ()
|
|
{
|
|
register char *b = &bp [0], *l = buflongname;
|
|
|
|
/* Skip the two character name */
|
|
if (bp [2] == '|')
|
|
b = &bp [3];
|
|
|
|
/* Copy the rest of the names */
|
|
while (*b && *b != ':')
|
|
*l++ = *b++;
|
|
*l = '\0';
|
|
|
|
if (b != &bp[0])
|
|
{
|
|
(void) fprintf (stderr, "%s: obsolete 2 character name '%2.2s' removed.\n",
|
|
progname, bp);
|
|
(void) fprintf (stderr, "\tsynonyms are: '%s'\n", buflongname);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Return the value of the termcap string 'capname' as stored in our list.
|
|
*/
|
|
char *getcapstr (capname)
|
|
register char *capname;
|
|
{
|
|
register int i;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "looking for termcap value of %s.\n",
|
|
capname);
|
|
|
|
/* Check the old termcap list. */
|
|
for (i = 0; ostrcodes [i]; i++)
|
|
if (strcmp (ostrcodes [i], capname) == 0)
|
|
{
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "\tvalue is:");
|
|
tpr (trace, ostrval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
return ostrval [uselevel] [i];
|
|
}
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "termcap name '%s' not found in ostrcodes.\n",
|
|
capname);
|
|
|
|
/* Check the terminfo list. */
|
|
for (i = 0; strcodes [i]; i++)
|
|
if (strcmp (strcodes [i], capname) == 0)
|
|
{
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "\tvalue is:");
|
|
tpr (trace, strval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
return strval [uselevel] [i];
|
|
}
|
|
|
|
(void) fprintf (stderr, "%s: TERM=%s: termcap name '%s' not found.\n",
|
|
progname, term_name, capname);
|
|
|
|
return (char *) NULL;
|
|
}
|
|
|
|
/*
|
|
Search for a name in the given table and return the index.
|
|
Someday I'll redo this to use bsearch().
|
|
*/
|
|
/* ARGSUSED */
|
|
int search (names, max, infoname)
|
|
char *names[], *infoname;
|
|
int max;
|
|
{
|
|
#ifndef BSEARCH
|
|
register int i;
|
|
for (i = 0; names [i] != NULL; i++)
|
|
if (strcmp (names [i], infoname) == 0)
|
|
return i;
|
|
return -1;
|
|
#else /* this doesn't work for some reason */
|
|
extern char *bsearch();
|
|
register char **bret;
|
|
|
|
bret = (char **) bsearch ( infoname, (char *) names, max, sizeof (char *), strcmp);
|
|
(void) fprintf (trace, "search looking for %s.\n", infoname);
|
|
(void) fprintf (trace, "base=%#x, bret=%#x, nel=%d.\n", names, bret, max);
|
|
(void) fprintf (trace, "returning %d.\n", bret == NULL ? -1 : bret - names);
|
|
if (bret == NULL)
|
|
return -1;
|
|
else
|
|
return bret - names;
|
|
#endif /* OLD */
|
|
}
|
|
|
|
/*
|
|
return the value of the terminfo string 'infoname'
|
|
*/
|
|
char *getinfostr (infoname)
|
|
register char *infoname;
|
|
{
|
|
register int i;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "looking for terminfo value of %s.\n",
|
|
infoname);
|
|
|
|
i = search (strnames, strcount, infoname);
|
|
if (i != -1)
|
|
{
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "\tvalue is:");
|
|
tpr (trace, strval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
return strval [uselevel] [i];
|
|
}
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "terminfo name '%s' not found.\n", infoname);
|
|
|
|
return (char *) NULL;
|
|
}
|
|
|
|
/*
|
|
Replace the value stored for the terminfo boolean
|
|
capability 'infoname' with the newvalue.
|
|
*/
|
|
void putbool (infoname, newvalue)
|
|
register char *infoname;
|
|
register int newvalue;
|
|
{
|
|
register int i;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "changing value for %s to %d.\n",
|
|
infoname, newvalue);
|
|
|
|
i = search (boolnames, boolcount, infoname);
|
|
if (i != -1)
|
|
{
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "value was: %d.\n", boolval[uselevel][i]);
|
|
|
|
boolval [uselevel] [i] = newvalue;
|
|
return;
|
|
}
|
|
|
|
(void) fprintf (stderr, "%s: TERM=%s: the boolean name '%s' was not found!\n",
|
|
progname, term_name, infoname);
|
|
}
|
|
|
|
/*
|
|
Replace the value stored for the terminfo number
|
|
capability 'infoname' with the newvalue.
|
|
*/
|
|
void putnum (infoname, newvalue)
|
|
register char *infoname;
|
|
register int newvalue;
|
|
{
|
|
register int i;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "changing value for %s to %d.\n",
|
|
infoname, newvalue);
|
|
|
|
i = search (numnames, numcount, infoname);
|
|
if (i != -1)
|
|
{
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "value was: %d.\n",
|
|
numval [uselevel] [i]);
|
|
|
|
numval [uselevel] [i] = newvalue;
|
|
return;
|
|
}
|
|
|
|
(void) fprintf (stderr, "%s: TERM=%s: the numeric name '%s' was not found!\n",
|
|
progname, term_name, infoname);
|
|
}
|
|
|
|
/*
|
|
replace the value stored for the terminfo string capability 'infoname'
|
|
with the newvalue.
|
|
*/
|
|
void putstr (infoname, newvalue)
|
|
register char *infoname, *newvalue;
|
|
{
|
|
register int i;
|
|
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "changing value for %s to ", infoname);
|
|
tpr (trace, newvalue);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
|
|
i = search (strnames, strcount, infoname);
|
|
if (i != -1)
|
|
{
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "value was:");
|
|
tpr (trace, strval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
strval [uselevel] [i] = nextstring;
|
|
while (*newvalue)
|
|
*nextstring++ = *newvalue++;
|
|
*nextstring++ = '\0';
|
|
return;
|
|
}
|
|
|
|
(void) fprintf (stderr, "%s: TERM=%s: the string name '%s' was not found!\n",
|
|
progname, term_name, infoname);
|
|
}
|
|
|
|
/*
|
|
Add in extra delays if they are not recorded already.
|
|
This is done before the padding information has been modified by
|
|
changecalculations() below, so the padding information, if there
|
|
already, is still at the beginning of the string in termcap format.
|
|
*/
|
|
void addpadding (cappadding, infostr)
|
|
register int cappadding;
|
|
register char *infostr;
|
|
{
|
|
register char *cap;
|
|
char tempbuffer [100];
|
|
|
|
/* Is there padding to add? */
|
|
if (cappadding > 0)
|
|
/* Is there a string to add it to? */
|
|
if (cap = getinfostr (infostr))
|
|
/* Is there any padding info already? */
|
|
if (ispadchar(*cap))
|
|
{
|
|
/* Assume that the padding info that is there is correct. */
|
|
}
|
|
else
|
|
{
|
|
/* Add the padding at the end of the present string. */
|
|
(void) sprintf(tempbuffer, "%s$<%d>", cap, cappadding);
|
|
putstr (infostr, tempbuffer);
|
|
}
|
|
else
|
|
{
|
|
/* Create a new string that only has the padding. */
|
|
(void) sprintf(tempbuffer, "$<%d>", cappadding);
|
|
putstr (infostr, tempbuffer);
|
|
}
|
|
}
|
|
|
|
struct
|
|
{
|
|
char *capname;
|
|
char *keyedinfoname;
|
|
} ko_map[] =
|
|
{
|
|
"al", "kil1",
|
|
"bs", "kbs", /* special addition */
|
|
"bt", "kcbt",
|
|
"cd", "ked",
|
|
"ce", "kel",
|
|
"cl", "kclr",
|
|
"ct", "ktbc",
|
|
"dc", "kdch1",
|
|
"dl", "kdl1",
|
|
"do", "kcud1",
|
|
"ei", "krmir",
|
|
"ho", "khome",
|
|
"ic", "kich1",
|
|
"im", "kich1", /* special addition */
|
|
"le", "kcub1",
|
|
"ll", "kll",
|
|
"nd", "kcuf1",
|
|
"sf", "kind",
|
|
"sr", "kri",
|
|
"st", "khts",
|
|
"up", "kcuu1",
|
|
/* "", "kctab", */
|
|
/* "", "knp", */
|
|
/* "", "kpp", */
|
|
0, 0
|
|
};
|
|
|
|
/*
|
|
Work with the ko string. It is a comma separated list of keys for which
|
|
the keyboard has a key by the same name that emits the same sequence.
|
|
For example, ko=dc,im,ei means that there are keys called
|
|
delete-character, enter-insert-mode and exit-insert-mode on the keyboard,
|
|
and they emit the same sequences as specified in the dc, im and ei
|
|
capabilities.
|
|
*/
|
|
handleko()
|
|
{
|
|
char capname[3];
|
|
register char *capstr;
|
|
register int i, j, found;
|
|
register char *infostr;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "working on termcap ko string.\n");
|
|
|
|
if (ostrval[uselevel][cap_ko] == NULL)
|
|
return;
|
|
|
|
capname[2] = '\0';
|
|
for (i = 0; ostrval[uselevel][cap_ko][i] != '\0'; )
|
|
{
|
|
/* isolate the termcap name */
|
|
capname[0] = ostrval[uselevel][cap_ko][i++];
|
|
if (ostrval[uselevel][cap_ko][i] == '\0')
|
|
break;
|
|
capname[1] = ostrval[uselevel][cap_ko][i++];
|
|
if (ostrval[uselevel][cap_ko][i] == ',')
|
|
i++;
|
|
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "key termcap name is '");
|
|
tpr (trace, capname);
|
|
(void) fprintf (trace, "'.\n");
|
|
}
|
|
|
|
/* match it up into our list */
|
|
found = 0;
|
|
for (j = 0; !found && ko_map[j].keyedinfoname != NULL; j++)
|
|
{
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "looking at termcap name %s.\n",
|
|
ko_map[j].capname);
|
|
if (capname[0] == ko_map[j].capname[0] &&
|
|
capname[1] == ko_map[j].capname[1])
|
|
{
|
|
/* add the value to our database */
|
|
if ((capstr = getcapstr (capname)) != NULL)
|
|
{
|
|
infostr = getinfostr (ko_map[j].keyedinfoname);
|
|
if (infostr == NULL)
|
|
{
|
|
/* skip any possible padding information */
|
|
while (ispadchar(*capstr))
|
|
capstr++;
|
|
putstr (ko_map[j].keyedinfoname, capstr);
|
|
}
|
|
else
|
|
if (strcmp(capstr, infostr) != 0)
|
|
{
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: a function key for '%s' was specified with the value ",
|
|
progname, term_name, capname);
|
|
tpr (stderr, capstr);
|
|
(void) fprintf (stderr, ", but it already has the value '");
|
|
tpr (stderr, infostr);
|
|
(void) fprintf (stderr, "'.\n");
|
|
}
|
|
}
|
|
found = 1;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
(void) fprintf (stderr, "%s: TERM=%s: the unknown termcap name '%s' was\n",
|
|
progname, term_name, capname);
|
|
(void) fprintf (stderr, "specified in the 'ko' termcap capability.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
#define CONTROL(x) ((x) & 037)
|
|
struct
|
|
{
|
|
char vichar;
|
|
char *keyedinfoname;
|
|
} ma_map[] =
|
|
{
|
|
CONTROL('J'), "kcud1", /* down */
|
|
CONTROL('N'), "kcud1",
|
|
'j', "kcud1",
|
|
CONTROL('P'), "kcuu1", /* up */
|
|
'k', "kcuu1",
|
|
'h', "kcub1", /* left */
|
|
CONTROL('H'), "kcub1",
|
|
' ', "kcuf1", /* right */
|
|
'l', "kcuf1",
|
|
'H', "khome", /* home */
|
|
CONTROL('L'), "kclr", /* clear */
|
|
0, 0
|
|
};
|
|
|
|
/*
|
|
Work with the ma string. This is a list of pairs of characters.
|
|
The first character is the what a function key sends. The second
|
|
character is the equivalent vi function that should be done when
|
|
it receives that character. Note that only function keys that send
|
|
a single character could be defined by this list.
|
|
*/
|
|
|
|
void prchar (stream, c)
|
|
register FILE *stream;
|
|
register int c;
|
|
{
|
|
char xbuf[2];
|
|
xbuf[0] = c;
|
|
xbuf[1] = '\0';
|
|
(void) fprintf (stream, "%s", iexpand (xbuf));
|
|
}
|
|
|
|
handlema()
|
|
{
|
|
register char vichar;
|
|
char cap[2];
|
|
register int i, j, found;
|
|
register char *infostr;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "working on termcap ma string.\n");
|
|
|
|
if (ostrval[uselevel][cap_ma] == NULL)
|
|
return;
|
|
|
|
cap[1] = '\0';
|
|
for (i = 0; ostrval[uselevel][cap_ma][i] != '\0'; )
|
|
{
|
|
/* isolate the key's value */
|
|
cap[0] = ostrval[uselevel][cap_ma][i++];
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "key value is '");
|
|
tpr (trace, cap);
|
|
(void) fprintf (trace, "'.\n");
|
|
}
|
|
|
|
if (ostrval[uselevel][cap_ma][i] == '\0')
|
|
break;
|
|
|
|
/* isolate the vi key name */
|
|
vichar = ostrval[uselevel][cap_ma][i++];
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "the vi key is '");
|
|
prchar (trace, vichar);
|
|
(void) fprintf (trace, "'.\n");
|
|
}
|
|
|
|
/* match up the vi name in our list */
|
|
found = 0;
|
|
for (j = 0; !found && ma_map[j].keyedinfoname != NULL; j++)
|
|
{
|
|
if (verbose > 1)
|
|
{
|
|
(void) fprintf (trace, "looking at vi character '");
|
|
prchar (trace, ma_map[j].vichar);
|
|
(void) fprintf (trace, "'\n");
|
|
}
|
|
if (vichar == ma_map[j].vichar)
|
|
{
|
|
infostr = getinfostr (ma_map[j].keyedinfoname);
|
|
if ( infostr == NULL )
|
|
putstr (ma_map[j].keyedinfoname, cap);
|
|
else if (strcmp (cap, infostr) != 0)
|
|
{
|
|
(void) fprintf (stderr, "%s: TERM=%s: the vi character '",
|
|
progname, term_name);
|
|
prchar (stderr, vichar);
|
|
(void) fprintf (stderr,
|
|
"' (info '%s') has the value '",
|
|
ma_map[j].keyedinfoname);
|
|
tpr (stderr, infostr);
|
|
(void) fprintf (stderr, "', but 'ma' gives '");
|
|
prchar (stderr, cap[0]);
|
|
(void) fprintf (stderr, "'.\n");
|
|
}
|
|
found = 1;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
(void) fprintf (stderr, "%s: the unknown vi key '", progname);
|
|
prchar (stderr, vichar);
|
|
(void) fprintf (stderr, "' was\n");
|
|
(void) fprintf (stderr, "specified in the 'ma' termcap capability.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Many capabilities were defaulted in termcap which must now be explicitly
|
|
given. We'll assume that the defaults are in effect for this terminal.
|
|
*/
|
|
void adddefaults ()
|
|
{
|
|
register char *cap;
|
|
register int sg;
|
|
|
|
if (verbose > 1)
|
|
(void) fprintf (trace, "assigning defaults.\n");
|
|
|
|
/* cr was assumed to be ^M, unless nc was given, */
|
|
/* which meant it could not be done. */
|
|
/* Also, xr meant that ^M acted strangely. */
|
|
if ( (getinfostr ("cr") == NULL) && !oboolval[uselevel][cap_nc] &&
|
|
!oboolval[uselevel][cap_xr])
|
|
if ( (cap = getcapstr ("cr")) == NULL)
|
|
putstr ("cr", "\r");
|
|
else
|
|
putstr ("cr", cap);
|
|
|
|
/* cursor down was assumed to be ^J if not specified by nl */
|
|
if (getinfostr ("cud1") == NULL)
|
|
if (ostrval[uselevel][cap_nl] != NULL)
|
|
putstr ("cud1", ostrval[uselevel][cap_nl]);
|
|
else
|
|
putstr ("cud1", "\n");
|
|
|
|
/* ind was assumed to be ^J, unless ns was given, */
|
|
/* which meant it could not be done. */
|
|
if ( (getinfostr ("ind") == NULL) && !oboolval[uselevel][cap_ns] )
|
|
if ( ostrval[uselevel][cap_nl] == NULL)
|
|
putstr ("ind", "\n");
|
|
else
|
|
putstr ("ind", ostrval[uselevel][cap_nl]);
|
|
|
|
/* bel was assumed to be ^G */
|
|
if (getinfostr ("bel") == NULL)
|
|
putstr ("bel", "\07");
|
|
|
|
/* if bs, then could do backspacing, */
|
|
/* with value of bc, default of ^H */
|
|
if ( (getinfostr ("cub1") == NULL) && oboolval[uselevel][cap_bs] )
|
|
if (ostrval[uselevel][cap_bc] != NULL)
|
|
putstr ("cub1", ostrval[uselevel][cap_bc]);
|
|
else
|
|
putstr ("cub1", "\b");
|
|
|
|
/* default xon to true */
|
|
if ( !otgetflag ("xo") )
|
|
putbool ("xon", 1);
|
|
|
|
/* if pt, then hardware tabs are allowed, */
|
|
/* with value of ta, default of ^I */
|
|
if ( (getinfostr ("ht") == NULL) && oboolval[uselevel][cap_pt] )
|
|
if ( (cap = getcapstr ("ta")) == NULL)
|
|
putstr ("ht", "\t");
|
|
else
|
|
putstr ("ht", cap);
|
|
|
|
/* The dX numbers are now stored as padding */
|
|
/* in the appropriate terminfo string. */
|
|
addpadding (onumval[uselevel][cap_dB], "cub1");
|
|
addpadding (onumval[uselevel][cap_dC], "cr");
|
|
addpadding (onumval[uselevel][cap_dF], "ff");
|
|
addpadding (onumval[uselevel][cap_dN], "cud1");
|
|
addpadding (onumval[uselevel][cap_dT], "ht");
|
|
|
|
/* The ug and sg caps were essentially identical, */
|
|
/* so ug almost never got used. We set sg from ug */
|
|
/* if it hasn't already been set. */
|
|
if (onumval[uselevel][cap_ug] >= 0 && (sg = otgetnum ("sg")) < 0)
|
|
putnum ("xmc", onumval[uselevel][cap_ug]);
|
|
else if ((onumval[uselevel][cap_ug] >= 0) &&
|
|
(sg >= 0) &&
|
|
(onumval[uselevel][cap_ug] != sg))
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: Warning: termcap sg and ug had different values (%d<->%d).\n",
|
|
progname, term_name, sg, onumval[uselevel][cap_ug]);
|
|
|
|
/* The MT boolean was never really part of termcap, */
|
|
/* but we can check for it anyways. */
|
|
if (oboolval[uselevel][cap_MT] && !otgetflag ("km"))
|
|
putbool ("km", 1);
|
|
|
|
/* the rs string was renamed r2 (info rs2) */
|
|
if ( (ostrval[uselevel][cap_rs] != NULL) &&
|
|
(ostrval[uselevel][cap_rs][0] != NULL) )
|
|
putstr ("rs2", ostrval[uselevel][cap_rs]);
|
|
|
|
handleko();
|
|
handlema();
|
|
}
|
|
|
|
#define caddch(x) *to++ = (x)
|
|
|
|
/*
|
|
add the string to the string table
|
|
*/
|
|
char *caddstr (to, str)
|
|
register char *to, *str;
|
|
{
|
|
while (*str)
|
|
*to++ = *str++;
|
|
return to;
|
|
}
|
|
|
|
/* If there is no padding info or parmed strings, */
|
|
/* then we do not need to copy the string. */
|
|
int needscopying (string)
|
|
register char *string;
|
|
{
|
|
/* any string at all? */
|
|
if (string == NULL)
|
|
return 0;
|
|
|
|
/* any padding info? */
|
|
if (ispadchar (*string))
|
|
return 1;
|
|
|
|
/* any parmed info? */
|
|
while (*string)
|
|
if (*string++ == '%')
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Certain manipulations of the stack require strange manipulations of the
|
|
values that are on the stack. To handle these, we save the values of the
|
|
parameters in registers at the very beginning and make the changes in
|
|
the registers. We don't want to do this in the general case because of the
|
|
potential performance loss.
|
|
*/
|
|
int fancycap (string)
|
|
register char *string;
|
|
{
|
|
register int parmset = 0;
|
|
|
|
while (*string)
|
|
if (*string++ == '%')
|
|
{
|
|
switch (*string)
|
|
{
|
|
/* These manipulate just the top value on the stack, so we */
|
|
/* only have to do something strange if a %r follows. */
|
|
case '>': case 'B': case 'D':
|
|
parmset = 1;
|
|
break;
|
|
/* If the parm has already been been pushed onto the stack */
|
|
/* by %>, then we can not reverse the parms and must get */
|
|
/* them from the registers. */
|
|
case 'r':
|
|
if (parmset)
|
|
return 1;
|
|
break;
|
|
/* This manipulates both parameters, so we cannot */
|
|
/* just do one and leave the value on the stack */
|
|
/* like we can with %>, %B or %D. */
|
|
case 'n':
|
|
return 1;
|
|
}
|
|
string++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Change old style of doing calculations to the new stack style.
|
|
Note that this will not necessarily produce the most efficient string,
|
|
but it will work.
|
|
*/
|
|
void changecalculations ()
|
|
{
|
|
register int i, currentparm;
|
|
register char *from, *to = nextstring;
|
|
int ch;
|
|
int parmset, parmsaved;
|
|
char padding [100], *saveto;
|
|
|
|
for (i = 0; strnames [i]; i++)
|
|
if (needscopying (strval [uselevel] [i]))
|
|
{
|
|
if (verbose)
|
|
{
|
|
(void) fprintf (trace, "%s needs copying, was:", strnames [i]);
|
|
tpr (trace, strval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
|
|
from = strval [uselevel] [i];
|
|
strval [uselevel] [i] = to;
|
|
currentparm = 1;
|
|
parmset = 0;
|
|
|
|
/* Handle padding information. Save it so that it can be */
|
|
/* placed at the end of the string where it should */
|
|
/* have been in the first place. */
|
|
if (ispadchar (*from))
|
|
{
|
|
saveto = to;
|
|
to = padding;
|
|
to = caddstr (to, "$<");
|
|
while (isdigit (*from) || *from == '.')
|
|
caddch (*from++);
|
|
if (*from == '*')
|
|
caddch (*from++);
|
|
caddch ('>');
|
|
caddch ('\0');
|
|
to = saveto;
|
|
}
|
|
else
|
|
padding [0] = '\0';
|
|
|
|
if (fancycap (from))
|
|
{
|
|
to = caddstr (to, "%p1%Pa%p2%Pb");
|
|
parmsaved = 1;
|
|
(void) fprintf (stderr,
|
|
"%s: TERM=%s: Warning: the string produced for '%s' may be inefficient.\n",
|
|
progname, term_name, strnames[i]);
|
|
(void) fprintf (stderr, "It should be looked at by hand.\n");
|
|
}
|
|
else
|
|
parmsaved = 0;
|
|
|
|
while (ch = *from++)
|
|
if (ch != '%')
|
|
caddch (ch);
|
|
else
|
|
switch (ch = *from++)
|
|
{
|
|
case '.': /* %. -> %p1%c */
|
|
case 'd': /* %d -> %p1%d */
|
|
case '2': /* %2 -> %p1%2.2d */
|
|
case '3': /* %3 -> %p1%3.3d */
|
|
case '+': /* %+x -> %p1%'x'%+%c */
|
|
|
|
case '>': /* %>xy -> %p1%Pc%?%'x'%>%t%gc%'y'%+ */
|
|
/* if current value > x, then add y. */
|
|
/* No output. */
|
|
|
|
case 'B': /* %B: BCD (16*(x/10))+(x%10) */
|
|
/* No output. */
|
|
/* (Adds Regent 100) */
|
|
|
|
case 'D': /* %D: Reverse coding (x-2*(x%16)) */
|
|
/* No output. */
|
|
/* (Delta Data) */
|
|
|
|
if (!parmset)
|
|
if (parmsaved)
|
|
{
|
|
to = caddstr (to, "%g");
|
|
if (currentparm == 1)
|
|
caddch ('a');
|
|
else
|
|
caddch ('b');
|
|
}
|
|
else
|
|
{
|
|
to = caddstr (to, "%p");
|
|
if (currentparm == 1)
|
|
caddch ('1');
|
|
else
|
|
caddch ('2');
|
|
}
|
|
currentparm = 3 - currentparm;
|
|
parmset = 0;
|
|
switch (ch)
|
|
{
|
|
case '.':
|
|
to = caddstr (to, "%c");
|
|
break;
|
|
case 'd':
|
|
to = caddstr (to, "%d");
|
|
break;
|
|
case '2': case '3':
|
|
#ifdef USG /* Vr2==USG, Vr3==SYSV. Use %02d for Vr2, %2.2d for Vr3 */
|
|
caddch('%'); caddch ('0');
|
|
#else
|
|
caddch('%'); caddch (ch); caddch ('.');
|
|
#endif /* USG vs. SYSV */
|
|
caddch (ch); caddch ('d');
|
|
break;
|
|
case '+':
|
|
to = caddstr (to, "%'");
|
|
caddch (*from++);
|
|
to = caddstr (to, "'%+%c");
|
|
break;
|
|
case '>':
|
|
to = caddstr (to, "%Pc%?%'");
|
|
caddch (*from++);
|
|
to = caddstr (to, "'%>%t%gc%'");
|
|
caddch (*from++);
|
|
to = caddstr (to, "'%+");
|
|
parmset = 1;
|
|
break;
|
|
case 'B':
|
|
to = caddstr (to, "%Pc%gc%{10}%/%{16}%*%gc%{10}%m%+");
|
|
parmset = 1;
|
|
break;
|
|
|
|
case 'D':
|
|
to = caddstr (to, "%Pc%gc%gc%{16}%m%{2}%*%-");
|
|
parmset = 1;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
/* %r reverses current parameter */
|
|
case 'r':
|
|
currentparm = 3 - currentparm;
|
|
break;
|
|
|
|
/* %n: exclusive-or row AND column */
|
|
/* with 0140, 96 decimal, no output */
|
|
/* (Datamedia 2500, Exidy Sorceror) */
|
|
case 'n':
|
|
to = caddstr (to, "%ga%'`'%^%Pa");
|
|
to = caddstr (to, "%gb%'`'%^%Pb");
|
|
break;
|
|
|
|
/* assume %x means %x */
|
|
/* this includes %i and %% */
|
|
default:
|
|
caddch ('%');
|
|
caddch (ch);
|
|
}
|
|
to = caddstr (to, padding);
|
|
caddch ('\0');
|
|
|
|
if (verbose)
|
|
{
|
|
(void) fprintf (trace, "and has become:");
|
|
tpr (trace, strval [uselevel] [i]);
|
|
(void) fprintf (trace, ".\n");
|
|
}
|
|
}
|
|
nextstring = to;
|
|
}
|
|
|
|
print_no_use_entry()
|
|
{
|
|
register int i;
|
|
|
|
pr_heading ("", buflongname);
|
|
pr_bheading();
|
|
|
|
for (i = 0; boolcodes [i]; i++)
|
|
if (boolval [0] [i])
|
|
pr_boolean (boolnames[i], (char *)0, (char *)0, 1);
|
|
|
|
pr_bfooting();
|
|
pr_sheading();
|
|
|
|
for (i = 0; numcodes [i]; i++)
|
|
if (numval [0] [i] > -1)
|
|
pr_number(numnames[i], (char *)0, (char *)0, numval[0][i]);
|
|
|
|
pr_nfooting();
|
|
pr_sheading();
|
|
|
|
for (i = 0; strcodes [i]; i++)
|
|
if (strval [0] [i])
|
|
pr_string (strnames[i], (char *)0, (char *)0, strval[0][i]);
|
|
|
|
pr_sfooting();
|
|
}
|
|
|
|
print_use_entry (usename)
|
|
char *usename;
|
|
{
|
|
register int i;
|
|
|
|
pr_heading ("", buflongname);
|
|
pr_bheading();
|
|
|
|
for (i = 0; boolcodes [i]; i++)
|
|
if (boolval [0] [i] && !boolval [1] [i])
|
|
pr_boolean (boolnames[i], (char *)0, (char *)0, 1);
|
|
else if (!boolval [0] [i] && boolval [1] [i])
|
|
pr_boolean (boolnames[i], (char *)0, (char *)0, -1);
|
|
|
|
pr_bfooting();
|
|
pr_nheading();
|
|
|
|
for (i = 0; numcodes [i]; i++)
|
|
if ((numval [0] [i] > -1) && (numval [0] [i] != numval [1] [i]))
|
|
pr_number (numnames[i], (char *)0, (char *)0, numval[0][i]);
|
|
else if ((numval [0] [i] == -1) && (numval [1] [i] > -1))
|
|
pr_number (numnames[i], (char *)0, (char *)0, -1);
|
|
|
|
pr_nfooting();
|
|
pr_sheading();
|
|
|
|
for (i = 0; strcodes [i]; i++)
|
|
/* print out str[0] if: */
|
|
/* str[0] != NULL and str[1] == NULL, or str[0] != str[1] */
|
|
if (strval [0] [i] &&
|
|
((strval[1][i] == NULL) ||
|
|
(strcmp(strval [0] [i],strval [1] [i]) != 0)) )
|
|
pr_string (strnames[i], (char *)0, (char *)0, strval[0][i]);
|
|
/* print out @ if str[0] == NULL and str[1] != NULL */
|
|
else if (strval [0] [i] == NULL && strval [1] [i] != NULL)
|
|
pr_string (strnames[i], (char *)0, (char *)0, (char *)0);
|
|
|
|
pr_sfooting();
|
|
|
|
(void) printf ("\tuse=%s,\n", usename);
|
|
}
|
|
|
|
captoinfo ()
|
|
{
|
|
char usename[512];
|
|
char *sterm_name;
|
|
|
|
if (term_name == NULL)
|
|
{
|
|
(void) fprintf (stderr, "%s: Null term_name given.\n", progname);
|
|
return;
|
|
}
|
|
|
|
if (verbose)
|
|
(void) fprintf (trace, "changing cap to info, TERM=%s.\n", term_name);
|
|
|
|
uselevel = 0;
|
|
if (filltables () == 0)
|
|
return;
|
|
getlongname ();
|
|
adddefaults ();
|
|
changecalculations ();
|
|
if (TLHtcfound != 0)
|
|
{
|
|
uselevel = 1;
|
|
if (verbose)
|
|
(void) fprintf (trace, "use= found, %s uses %s.\n",
|
|
term_name, TLHtcname);
|
|
(void) strcpy (usename, TLHtcname);
|
|
sterm_name = term_name;
|
|
term_name = usename;
|
|
if (filltables () == 0)
|
|
return;
|
|
adddefaults ();
|
|
changecalculations ();
|
|
term_name = sterm_name;
|
|
print_use_entry (usename);
|
|
}
|
|
else
|
|
print_no_use_entry ();
|
|
}
|
|
|
|
|
|
#include <signal.h> /* use this file to determine if this is SVR4.0 system */
|
|
|
|
use_etc_termcap ()
|
|
{
|
|
if (verbose)
|
|
#ifdef SIGSTOP
|
|
(void) fprintf (trace, "reading from /usr/share/lib/termcap\n");
|
|
#else /* SIGSTOP */
|
|
(void) fprintf (trace, "reading from /etc/termcap\n");
|
|
#endif /* SIGSTOP */
|
|
term_name = getenv ("TERM");
|
|
captoinfo ();
|
|
}
|
|
|
|
initdirname ()
|
|
{
|
|
#if defined(SYSV) || defined(USG) /* handle both Sys Vr2 and Vr3 curses */
|
|
(void) getcwd (dirname, BUFSIZ-2);
|
|
#else
|
|
(void) getwd (dirname);
|
|
#endif /* SYSV || USG */
|
|
if (verbose)
|
|
(void) fprintf (trace, "current directory name=%s.\n", dirname);
|
|
environ = newenviron;
|
|
}
|
|
|
|
setfilename (capfile)
|
|
register char *capfile;
|
|
{
|
|
if (capfile [0] == '/')
|
|
(void) sprintf (TERMCAP, "TERMCAP=%s", capfile);
|
|
else
|
|
(void) sprintf (TERMCAP, "TERMCAP=%s/%s", dirname, capfile);
|
|
if (verbose)
|
|
(void) fprintf (trace, "setting the environment for %s.\n", TERMCAP);
|
|
}
|
|
|
|
setterm_name ()
|
|
{
|
|
if (verbose)
|
|
(void) fprintf (trace, "setting the environment for TERM=%s.\n", term_name);
|
|
(void) sprintf (TERM, "TERM=%s", term_name);
|
|
}
|
|
|
|
/* Look at the current line to see if it is a list of names. */
|
|
/* If it is, return the first name in the list, else NULL. */
|
|
/* As a side-effect, comment lines and blank lines */
|
|
/* are copied to standard output. */
|
|
char *getterm_name (line)
|
|
register char *line;
|
|
{
|
|
register char *lineptr = line;
|
|
|
|
if (verbose)
|
|
(void) fprintf (trace, "extracting name from '%s'.\n", line);
|
|
|
|
/* Copy comment lines out. */
|
|
if (*line == '#')
|
|
{
|
|
if (copycomments)
|
|
(void) printf ("%s", line);
|
|
}
|
|
/* Blank lines get copied too. */
|
|
else if (isspace (*line))
|
|
{
|
|
if (copycomments)
|
|
{
|
|
for ( ; *lineptr ; lineptr++)
|
|
if (!isspace(*lineptr))
|
|
break;
|
|
if (*lineptr == '\0')
|
|
(void) printf ("\n");
|
|
}
|
|
}
|
|
else
|
|
for ( ; *lineptr ; lineptr++)
|
|
if (*lineptr == '|' || *lineptr == ':')
|
|
{
|
|
*lineptr = '\0';
|
|
if (verbose)
|
|
(void) fprintf (trace, "returning %s.\n", line);
|
|
return line;
|
|
}
|
|
if (verbose)
|
|
(void) fprintf (trace, "returning NULL.\n");
|
|
return NULL;
|
|
}
|
|
|
|
use_file (filename)
|
|
register char *filename;
|
|
{
|
|
register FILE *termfile;
|
|
char buffer [BUFSIZ];
|
|
|
|
if (verbose)
|
|
(void) fprintf (trace, "reading from %s.\n", filename);
|
|
|
|
if ( (termfile = fopen (filename, "r")) == NULL)
|
|
{
|
|
(void) fprintf (stderr, "%s: cannot open %s for reading.\n",
|
|
progname, filename);
|
|
return;
|
|
}
|
|
|
|
copycomments++;
|
|
setfilename (filename);
|
|
|
|
while (fgets (buffer, BUFSIZ, termfile) != NULL)
|
|
{
|
|
if ((term_name = getterm_name (buffer)) != NULL)
|
|
{
|
|
setterm_name ();
|
|
captoinfo ();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Sort a name and code table pair according to the name table.
|
|
Use a simple bubble sort for now. Too bad I can't call qsort(3).
|
|
At least I only have to do it once for each table.
|
|
*/
|
|
sorttable (nametable, codetable)
|
|
char *nametable [], *codetable [];
|
|
{
|
|
register int i, j;
|
|
register char *c;
|
|
|
|
for (i = 0; nametable [i]; i++)
|
|
for (j = 0; j < i; j++)
|
|
if (strcmp (nametable [i], nametable [j]) < 0)
|
|
{
|
|
c = nametable [i];
|
|
nametable [i] = nametable [j];
|
|
nametable [j] = c;
|
|
c = codetable [i];
|
|
codetable [i] = codetable [j];
|
|
codetable [j] = c;
|
|
}
|
|
}
|
|
|
|
/*
|
|
Initialize and sort the name and code tables. Allocate space for the
|
|
value tables.
|
|
*/
|
|
inittables ()
|
|
{
|
|
register unsigned int i;
|
|
|
|
for (i = 0; boolnames [i]; i++)
|
|
;
|
|
boolval[0] = (char *) malloc (i * sizeof (char));
|
|
boolval[1] = (char *) malloc (i * sizeof (char));
|
|
boolcount = i;
|
|
sorttable (boolnames, boolcodes);
|
|
|
|
for (i = 0; numcodes [i]; i++)
|
|
;
|
|
numval [0] = (short *) malloc (i * sizeof (short));
|
|
numval [1] = (short *) malloc (i * sizeof (short));
|
|
numcount = i;
|
|
sorttable (numnames, numcodes);
|
|
|
|
for (i = 0; strcodes [i]; i++)
|
|
;
|
|
strval [0] = (char **) malloc (i * sizeof (char *));
|
|
strval [1] = (char **) malloc (i * sizeof (char *));
|
|
strcount = i;
|
|
sorttable (strnames, strcodes);
|
|
}
|
|
|
|
main (argc, argv)
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
int c;
|
|
char _capbuffer [8192];
|
|
char _bp [TBUFSIZE];
|
|
char _buflongname [128];
|
|
|
|
capbuffer = &_capbuffer[0];
|
|
bp = &_bp[0];
|
|
buflongname = &_buflongname[0];
|
|
progname = argv [0];
|
|
|
|
while ( (c = getopt (argc, argv, "1vVw:")) != EOF)
|
|
switch (c)
|
|
{
|
|
case '1':
|
|
pr_onecolumn (1);
|
|
break;
|
|
case 'w':
|
|
pr_width (atoi(optarg));
|
|
break;
|
|
case 'v':
|
|
verbose++;
|
|
break;
|
|
case 'V':
|
|
printf("%s: version %s\n", progname, "@(#)curses:screen/captoinfo.c 1.12");
|
|
fflush(stdout);
|
|
exit (0);
|
|
case '?':
|
|
(void) fprintf (stderr,
|
|
"usage: %s [-1Vv] [-w width] [filename ...]\n", progname);
|
|
(void) fprintf (stderr, "\t-1\tsingle column output\n");
|
|
(void) fprintf (stderr, "\t-v\tverbose debugging output\n");
|
|
(void) fprintf (stderr, "\t-V\tprint program version\n");
|
|
exit (-1);
|
|
}
|
|
|
|
/* initialize */
|
|
pr_init (pr_terminfo);
|
|
inittables ();
|
|
|
|
if (optind >= argc)
|
|
use_etc_termcap ();
|
|
else
|
|
{
|
|
initdirname ();
|
|
for ( ; optind < argc ; optind++)
|
|
use_file (argv [optind]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* fake out the modules in print.c so we don't have to load in */
|
|
/* cexpand.c and infotocap.c */
|
|
/* ARGSUSED */
|
|
int cpr(stream, string) FILE *stream; char *string; { return 0; }
|
|
/* ARGSUSED */
|
|
char *cexpand(string) char *string; { return string; }
|
|
/* ARGSUSED */
|
|
char *infotocap(value, err) char *value; int *err; { return value; }
|