diff options
-rw-r--r-- | usr.bin/tic/Makefile | 17 | ||||
-rw-r--r-- | usr.bin/tic/captoinfo.1tbl | 190 | ||||
-rw-r--r-- | usr.bin/tic/tic.1 | 261 | ||||
-rw-r--r-- | usr.bin/tic/tic.c | 596 |
4 files changed, 1064 insertions, 0 deletions
diff --git a/usr.bin/tic/Makefile b/usr.bin/tic/Makefile new file mode 100644 index 00000000000..18854b6871c --- /dev/null +++ b/usr.bin/tic/Makefile @@ -0,0 +1,17 @@ +# $OpenBSD: Makefile,v 1.1 1998/07/24 19:37:33 millert Exp $ + +PROG= tic +SRCS= dump_entry.c tic.c +MAN= tic.1 captoinfo.1tbl +LINKS= ${BINDIR}/tic ${BINDIR}/infotocap ${BINDIR}/tic ${BINDIR}/captoinfo +DPADD= ${LIBCURSES} +LDADD= -lcurses +CURSES= ${.CURDIR}/../../lib/libcurses +CFLAGS+= -I${CURSES} -I${.CURDIR} -I. + +beforedepend: termsort.c + +termsort.c: MKtermsort.sh + sh ${.CURDIR}/MKtermsort.sh awk ${CURSES}/Caps > ${.TARGET} + +.include <bsd.prog.mk> diff --git a/usr.bin/tic/captoinfo.1tbl b/usr.bin/tic/captoinfo.1tbl new file mode 100644 index 00000000000..fb8e8a124af --- /dev/null +++ b/usr.bin/tic/captoinfo.1tbl @@ -0,0 +1,190 @@ +.\" $OpenBSD: captoinfo.1tbl,v 1.1 1998/07/24 19:37:34 millert Exp $ +.\" +.\"*************************************************************************** +.\" Copyright (c) 1998 Free Software Foundation, Inc. * +.\" * +.\" Permission is hereby granted, free of charge, to any person obtaining a * +.\" copy of this software and associated documentation files (the * +.\" "Software"), to deal in the Software without restriction, including * +.\" without limitation the rights to use, copy, modify, merge, publish, * +.\" distribute, distribute with modifications, sublicense, and/or sell * +.\" copies of the Software, and to permit persons to whom the Software is * +.\" furnished to do so, subject to the following conditions: * +.\" * +.\" The above copyright notice and this permission notice shall be included * +.\" in all copies or substantial portions of the Software. * +.\" * +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * +.\" IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * +.\" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * +.\" OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * +.\" THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +.\" * +.\" Except as contained in this notice, the name(s) of the above copyright * +.\" holders shall not be used in advertising or otherwise to promote the * +.\" sale, use or other dealings in this Software without prior written * +.\" authorization. * +.\"*************************************************************************** +.\" +.\" $From: captoinfo.1m,v 1.10 1998/03/11 21:12:53 juergen Exp $ +'\" t +.TH captoinfo 1 "" +.ds n 5 +.ds d /usr/share/terminfo +.SH NAME +\fBcaptoinfo\fR - convert a \fItermcap\fR description into a \fIterminfo\fR description +.SH SYNOPSIS +\fBcaptoinfo\fR [\fB-v\fIn\fR \fIwidth\fR] [\fB-V\fR] [\fB-1\fR] [\fB-w\fR \fIwidth\fR] \fIfile\fR . . . +.SH DESCRIPTION +\fBcaptoinfo\fR looks in \fIfile\fR for \fBtermcap\fR descriptions. For each +one found, an equivalent \fBterminfo\fR description is written to standard +output. Termcap \fBtc\fR capabilities are translated directly to terminfo +\fBuse\fR capabilities. + +If no \fIfile\fR is given, then the environment variable \fBTERMCAP\fR is used +for the filename or entry. If \fBTERMCAP\fR is a full pathname to a file, only +the terminal whose name is specified in the environment variable \fBTERM\fR is +extracted from that file. If the environment variable \fBTERMCAP\fR is not +set, then the file \fB\*d\fR is read. +.TP 5 +\fB-v\fR +print out tracing information on standard error as the program runs. +.TP 5 +\fB-V\fR +print out the version of the program in use on standard error and exit. +.TP 5 +\fB-1\fR +cause the fields to print out one to a line. Otherwise, the fields +will be printed several to a line to a maximum width of 60 +characters. +.TP 5 +\fB-w\fR +change the output to \fIwidth\fR characters. +.SH FILES +.TP 20 +\*d +Compiled terminal description database. +.SH TRANSLATIONS FROM NONSTANDARD CAPABILITIES +.PP +Some obsolete nonstandard capabilities will automatically be translated +into standard (SVr4/XSI Curses) terminfo capabilities by \fBcaptoinfo\fR. +Whenever one of these automatic translations is done, the program +will issue an notification to stderr, inviting the user to check that +it has not mistakenly translated a completely unknown and random +capability and/or syntax error. +.PP +.TS H +c c c c +c c c c +l l l l. +Nonstd Std From Terminfo +name name capability +_ +BO mr AT&T enter_reverse_mode +CI vi AT&T cursor_invisible +CV ve AT&T cursor_normal +DS mh AT&T enter_dim_mode +EE me AT&T exit_attribute_mode +FE LF AT&T label_on +FL LO AT&T label_off +XS mk AT&T enter_secure_mode +EN @7 XENIX key_end +GE ae XENIX exit_alt_charset_mode +GS as XENIX enter_alt_charset_mode +HM kh XENIX key_home +LD kL XENIX key_dl +PD kN XENIX key_npage +PN po XENIX prtr_off +PS pf XENIX prtr_on +PU kP XENIX key_ppage +RT @8 XENIX kent +UP ku XENIX kcuu1 +KA k; Tek key_f10 +KB F1 Tek key_f11 +KC F2 Tek key_f12 +KD F3 Tek key_f13 +KE F4 Tek key_f14 +KF F5 Tek key_f15 +BC Sb Tek set_background +FC Sf Tek set_foreground +HS mh Iris enter_dim_mode +.TE +.PP +XENIX termcap also used to have a set of extension capabilities +for forms drawing, designed to take advantage of the IBM PC +high-half graphics. They were as follows: +.PP +.TS H +c c +l l. +Cap Graphic +_ +G2 upper left +G3 lower left +G1 upper right +G4 lower right +GR pointing right +GL pointing left +GU pointing up +GD pointing down +GH horizontal line +GV vertical line +GC intersection +G6 upper left +G7 lower left +G5 upper right +G8 lower right +Gr tee pointing right +Gr tee pointing left +Gu tee pointing up +Gd tee pointing down +Gh horizontal line +Gv vertical line +Gc intersection +GG acs magic cookie count +.TE +.PP +If the single-line capabilities occur in an entry, they will automatically +be composed into an \fBacsc\fR string. The double-line capabilities and +\fBGG\fR are discarded with a warning message. +.PP +IBM's AIX has a terminfo facility descended from SVr1 terminfo but incompatible +with the SVr4 format. The following AIX extensions are automatically +translated: +.PP +.TS +c c +l l. +IBM XSI +_ +ksel kslt +kbtab kcbt +font0 s0ds +font1 s1ds +font2 s2ds +font3 s3ds +.TE +.PP +Additionally, the AIX \fBbox1\fR capability will be automatically translated to +an \fBacsc\fR string. +.PP +Hewlett-Packard's terminfo library supports two nonstandard terminfo +capabilities \fBmeml\fR (memory lock) and \fBmemu\fR (memory unlock). +These will be discarded with a warning message. +.SH NOTES +This utility is actually a link to \fItic\fR(1), running in \fI-I\fR mode. + +The trace option isn't identical to SVr4's. Under SVr4, instead of following +the -v with a trace level n, you repeat it n times. +.SH SEE ALSO +\fBcurses\fR(3), \fBinfocmp\fR(1), \fBterminfo\fR(\*n) +.SH AUTHOR +Eric S. Raymond <esr@snark.thyrsus.com> +.\"# +.\"# The following sets edit modes for GNU EMACS +.\"# Local Variables: +.\"# mode:nroff +.\"# fill-column:79 +.\"# End: diff --git a/usr.bin/tic/tic.1 b/usr.bin/tic/tic.1 new file mode 100644 index 00000000000..5eb6f777a56 --- /dev/null +++ b/usr.bin/tic/tic.1 @@ -0,0 +1,261 @@ +.\" $OpenBSD: tic.1,v 1.1 1998/07/24 19:37:35 millert Exp $ +.\" +.\"*************************************************************************** +.\" Copyright (c) 1998 Free Software Foundation, Inc. * +.\" * +.\" Permission is hereby granted, free of charge, to any person obtaining a * +.\" copy of this software and associated documentation files (the * +.\" "Software"), to deal in the Software without restriction, including * +.\" without limitation the rights to use, copy, modify, merge, publish, * +.\" distribute, distribute with modifications, sublicense, and/or sell * +.\" copies of the Software, and to permit persons to whom the Software is * +.\" furnished to do so, subject to the following conditions: * +.\" * +.\" The above copyright notice and this permission notice shall be included * +.\" in all copies or substantial portions of the Software. * +.\" * +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * +.\" IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * +.\" DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * +.\" OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * +.\" THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +.\" * +.\" Except as contained in this notice, the name(s) of the above copyright * +.\" holders shall not be used in advertising or otherwise to promote the * +.\" sale, use or other dealings in this Software without prior written * +.\" authorization. * +.\"*************************************************************************** +.\" +.\" $From: tic.1m,v 1.21 1998/05/17 00:23:46 tom Exp $ +.TH tic 1 "" +.ds n 5 +.ds d /usr/share/terminfo +.SH NAME +\fBtic\fR - the \fIterminfo\fR entry-description compiler +.SH SYNOPSIS +\fBtic\fR +[\fB-\ +1\ +C\ +I\ +N\ +R\ +T\ +c\ +f\ +r\ +s\ +\fR] +[\fB-e\fR \fInames\fR] +[\fB-o\fR \fIdir\fR] +[\fB-v\fR[\fIn\fR]] +[\fB-w\fR[\fIn\fR]] +\fIfile\fR +.br +.SH DESCRIPTION +The command \fBtic\fR translates a \fBterminfo\fR file from source +format into compiled format. The compiled format is necessary for use with +the library routines in \fBcurses\fR(3). +.PP +The results are normally placed in the system terminfo +directory \fB\*d\fR. There are two ways to change this behavior. +.PP +First, you may override the system default by setting the variable +\fBTERMINFO\fR in your shell environment to a valid (existing) directory name. +.PP +Secondly, if \fBtic\fR cannot get access to \fI\*d\fR or your TERMINFO +directory, it looks for the directory \fI$HOME/.terminfo\fR; if that directory +exists, the entry is placed there. +.PP +Libraries that read terminfo entries are expected to check for a TERMINFO +directory first, look at \fI$HOME/.terminfo\fR if TERMINFO is not set, and +finally look in \fI\*d\fR. +.TP +\fB-c\fR +specifies to only check \fIfile\fR for errors, including syntax problems and +bad use links. If you specify \fB-C\fR (\fB-I\fR) with this option, the code +will print warnings about entries which, after use resolution, are more than +1023 (4096) bytes long. Due to a fixed buffer length in older termcap +libraries (and a documented limit in terminfo), these entries may cause core +dumps. +.TP +\fB-v\fR\fIn\fR +specifies that (verbose) output be written to standard error trace +information showing \fBtic\fR's progress. The optional integer +\fIn\fR is a number from 1 to 10, inclusive, indicating the desired +level of detail of information. If \fIn\fR is omitted, the default +level is 1. If \fIn\fR is specified and greater than 1, the level of +detail is increased. +.TP +\fB-o\fR\fIdir\fR +Write compiled entries to given directory. Overrides the TERMINFO environment +variable. +.TP +\fB-w\fR\fIn\fR +specifies the width of the output. +.TP +\fB-1\fR +restricts the output to a single column +.TP +\fB-C\fR +Force source translation to termcap format. Note: this differs from the -C +option of \fIinfocmp\fR(1) in that it does not merely translate capability +names, but also translates terminfo strings to termcap format. Capabilities +that are not translatable are left in the entry under their terminfo names +but commented out with two preceding dots. +.TP +\fB-I\fR +Force source translation to terminfo format. +.TP +\fB-L\fR +Force source translation to terminfo format +using the long C variable names listed in <\fBterm.h\fR> +.TP +\fB-N\fR +Disable smart defaults. +Normally, when translating from termcap to terminfo, the compiler makes +a number of assumptions about the defaults of string capabilities +\fBreset1_string\fR, \fBcarriage_return\fR, \fBcursor_left\fR, +\fBcursor_down\fR, \fBscroll_forward\fR, \fBtab\fR, \fBnewline\fR, +\fBkey_backspace\fR, \fBkey_left\fR, and \fBkey_down\fR, then attempts +to use obsolete termcap capabilities to deduce correct values. It also +normally suppresses output of obsolete termcap capabilities such as \fBbs\fR. +This option forces a more literal translation that also preserves the +obsolete capabilities. +.TP +\fB-R\fR\fIsubset\fR +Restrict output to a given subset. This option is for use with archaic +versions of terminfo like those on SVr1, Ultrix, or HP/UX that don't support +the full set of SVR4/XSI Curses terminfo; and outright broken ports like AIX 3.x +that have their own extensions incompatible with SVr4/XSI. Available subsets +are "SVr1", "Ultrix", "HP", "BSD" and "AIX"; see \fBterminfo\fR(\*n) for details. +.TP +\fB-T\fR +eliminates size-restrictions on the generated text. +This is mainly useful for testing and analysis, since the compiled +descriptions are limited (e.g., 1023 for termcap, 4096 for terminfo). +.TP +\fB-r\fR +Force entry resolution (so there are no remaining tc capabilities) even +when doing translation to termcap format. This may be needed if you are +preparing a termcap file for a termcap library (such as GNU termcap up +to version 1.3 or BSD termcap up to 4.3BSD) that doesn't handle multiple +tc capabilities per entry. +.TP +\fB-e\fR +Limit writes and translations to the following comma-separated list of +terminals. +If any name or alias of a terminal matches one of the names in +the list, the entry will be written or translated as normal. +Otherwise no output will be generated for it. +The option value is interpreted as a file containing the list if it +contains a '/'. +(Note: depending on how tic was compiled, this option may require -I or -C.) +.TP +\fB-f\fR +Display complex terminfo strings which contain if/then/else/endif expressions +indented for readability. +.TP +\fB-s\fR +Summarize the compile by showing the directory into which entries +are written, and the number of entries which are compiled. +.TP +\fIfile\fR +contains one or more \fBterminfo\fR terminal descriptions in source +format [see \fBterminfo\fR(\*n)]. Each description in the file +describes the capabilities of a particular terminal. +.PP +The debug flag levels are as follows: +.TP +1 +Names of files created and linked +.TP +2 +Information related to the ``use'' facility +.TP +3 +Statistics from the hashing algorithm +.TP +5 +String-table memory allocations +.TP +7 +Entries into the string-table +.TP +8 +List of tokens encountered by scanner +.TP +9 +All values computed in construction of the hash table +.LP +If n is not given, it is taken to be one. +.PP +All but one of the capabilities recognized by \fBtic\fR are documented +in \fBterminfo\fR(\*n). The exception is the \fBuse\fR capability. + +When a \fBuse\fR=\fIentry\fR-\fIname\fR field is discovered in a +terminal entry currently being compiled, \fBtic\fR reads in the binary +from \fB\*d\fR to complete the entry. (Entries created from +\fIfile\fR will be used first. If the environment variable +\fBTERMINFO\fR is set, that directory is searched instead of +\fB\*d\fR.) \fBtic\fR duplicates the capabilities in +\fIentry\fR-\fIname\fR for the current entry, with the exception of +those capabilities that explicitly are defined in the current entry. + +When an entry, e.g., \fBentry_name_1\fR, contains a +\fBuse=\fR\fIentry\fR_\fIname\fR_\fI2\fR field, any canceled +capabilities in \fIentry\fR_\fIname\fR_\fI2\fR must also appear in +\fBentry_name_1\fR before \fBuse=\fR for these capabilities to be +canceled in \fBentry_name_1\fR. + +If the environment variable \fBTERMINFO\fR is set, the compiled +results are placed there instead of \fB\*d\fR. + +Total compiled entries cannot exceed 4096 bytes. The name field cannot +exceed 512 bytes. Terminal names exceeding the maximum alias length +(32 characters on systems with long filenames, 14 characters otherwise) +will be truncated to the maximum alias length and a warning message will be printed. +.SH COMPATIBILITY +There is some evidence that historic \fBtic\fR implementations treated +description fields with no whitespace in them as additional aliases or +short names. This \fBtic\fR does not do that, but it does warn when +description fields may be treated that way and check them for dangerous +characters. +.SH EXTENSIONS +Unlike the stock SVr4 \fBtic\fR command, this implementation can actually +compile termcap sources. In fact, entries in terminfo and termcap syntax can +be mixed in a single source file. See \fBterminfo\fR(\*n) for the list of +termcap names taken to be equivalent to terminfo names. + +The SVr4 manual pages are not clear on the resolution rules for \fBuse\fR +capabilities. +This implementation of \fBtic\fR will find \fBuse\fR targets anywhere +in the source file, or anywhere in the file tree rooted at \fBTERMINFO\fR (if +\fBTERMINFO\fR is defined), or in the user's \fI$HOME/.terminfo\fR directory +(if it exists), or (finally) anywhere in the system's file tree of +compiled entries. + +The error messages from this \fBtic\fR have the same format as GNU C +error messages, and can be parsed by GNU Emacs's compile facility. + +The -o, -I, -C, -N, -R, -e, -f, -T, -r and -s options +are not supported under SVr4. +The SVr4 -c mode does not report bad use links. + +System V does not compile entries to or read entries from your +\fI$HOME/.terminfo\fR directory unless TERMINFO is explicitly set to it. +.SH FILES +.TP 5 +\fB\*d/?/*\fR +Compiled terminal description database. +.SH SEE ALSO +\fBinfocmp\fR(1), \fBcaptoinfo\fR(1), \fBtoe\fR(1), +\fBcurses\fR(3), \fBterminfo\fR(\*n). +.\"# +.\"# The following sets edit modes for GNU EMACS +.\"# Local Variables: +.\"# mode:nroff +.\"# fill-column:79 +.\"# End: diff --git a/usr.bin/tic/tic.c b/usr.bin/tic/tic.c new file mode 100644 index 00000000000..a2861ba712e --- /dev/null +++ b/usr.bin/tic/tic.c @@ -0,0 +1,596 @@ +/* $OpenBSD: tic.c,v 1.1 1998/07/24 19:37:35 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * + * and: Eric S. Raymond <esr@snark.thyrsus.com> * + ****************************************************************************/ + +/* + * tic.c --- Main program for terminfo compiler + * by Eric S. Raymond + * + */ + +#include <progs.priv.h> + +#include <dump_entry.h> +#include <term_entry.h> + +MODULE_ID("$From: tic.c,v 1.30 1998/03/28 20:04:11 tom Exp $") + +const char *_nc_progname = "tic"; + +static FILE *log_fp; +static bool showsummary = FALSE; + +static const char usage_string[] = "[-h] [-v[n]] [-e names] [-CILNRTcfrsw1] source-file\n"; + +static void usage(void) +{ + static const char *const tbl[] = { + "Options:", + " -1 format translation output one capability per line", + " -C translate entries to termcap source form", + " -I translate entries to terminfo source form", + " -L translate entries to full terminfo source form", + " -N disable smart defaults for source translation", + " -R restrict translation to given terminfo/termcap version", + " -T remove size-restrictions on compiled description", + " -c check only, validate input without compiling or translating", + " -f format complex strings for readability", + " -e<names> translate/compile only entries named by comma-separated list", + " -o<dir> set output directory for compiled entry writes", + " -r force resolution of all use entries in source translation", + " -s print summary statistics", + " -v[n] set verbosity level", + " -w[n] set format width for translation output", + "", + "Parameters:", + " <file> file to translate or compile" + }; + size_t j; + + printf("Usage: %s %s\n", _nc_progname, usage_string); + for (j = 0; j < sizeof(tbl)/sizeof(tbl[0]); j++) + puts(tbl[j]); + exit(EXIT_FAILURE); +} + +static bool immedhook(ENTRY *ep) +/* write out entries with no use capabilities immediately to save storage */ +{ +#ifndef HAVE_BIG_CORE + /* + * This is strictly a core-economy kluge. The really clean way to handle + * compilation is to slurp the whole file into core and then do all the + * name-collision checks and entry writes in one swell foop. But the + * terminfo master file is large enough that some core-poor systems swap + * like crazy when you compile it this way...there have been reports of + * this process taking *three hours*, rather than the twenty seconds or + * less typical on my development box. + * + * So. This hook *immediately* writes out the referenced entry if it + * has no use capabilities. The compiler main loop refrains from + * adding the entry to the in-core list when this hook fires. If some + * other entry later needs to reference an entry that got written + * immediately, that's OK; the resolution code will fetch it off disk + * when it can't find it in core. + * + * Name collisions will still be detected, just not as cleanly. The + * write_entry() code complains before overwriting an entry that + * postdates the time of tic's first call to write_entry(). Thus + * it will complain about overwriting entries newly made during the + * tic run, but not about overwriting ones that predate it. + * + * The reason this is a hook, and not in line with the rest of the + * compiler code, is that the support for termcap fallback cannot assume + * it has anywhere to spool out these entries! + * + * The _nc_set_type() call here requires a compensating one in + * _nc_parse_entry(). + * + * If you define HAVE_BIG_CORE, you'll disable this kluge. This will + * make tic a bit faster (because the resolution code won't have to do + * disk I/O nearly as often). + */ + if (ep->nuses == 0) + { + int oldline = _nc_curr_line; + + _nc_set_type(_nc_first_name(ep->tterm.term_names)); + _nc_curr_line = ep->startline; + _nc_write_entry(&ep->tterm); + _nc_curr_line = oldline; + free(ep->tterm.str_table); + return(TRUE); + } + else +#endif /* HAVE_BIG_CORE */ + return(FALSE); +} + +static void put_translate(int c) +/* emit a comment char, translating terminfo names to termcap names */ +{ + static bool in_name = FALSE; + static char namebuf[132], suffix[132], *sp; + + if (!in_name) + { + if (c == '<') + { + in_name = TRUE; + sp = namebuf; + } + else + putchar(c); + } + else if (c == '\n' || c == '@') + { + *sp++ = '\0'; + (void) putchar('<'); + (void) fputs(namebuf, stdout); + putchar(c); + in_name = FALSE; + } + else if (c != '>') + *sp++ = c; + else /* ah! candidate name! */ + { + char *up; + NCURSES_CONST char *tp; + + *sp++ = '\0'; + in_name = FALSE; + + suffix[0] = '\0'; + if ((up = strchr(namebuf, '#')) != 0 + || (up = strchr(namebuf, '=')) != 0 + || ((up = strchr(namebuf, '@')) != 0 && up[1] == '>')) + { + (void) strcpy(suffix, up); + *up = '\0'; + } + + if ((tp = nametrans(namebuf)) != 0) + { + (void) putchar(':'); + (void) fputs(tp, stdout); + (void) fputs(suffix, stdout); + (void) putchar(':'); + } + else + { + /* couldn't find a translation, just dump the name */ + (void) putchar('<'); + (void) fputs(namebuf, stdout); + (void) fputs(suffix, stdout); + (void) putchar('>'); + } + + } +} + +/* Returns a string, stripped of leading/trailing whitespace */ +static char *stripped(char *src) +{ + while (isspace(*src)) + src++; + if (*src != '\0') { + char *dst = strcpy(malloc(strlen(src)+1), src); + size_t len = strlen(dst); + while (--len != 0 && isspace(dst[len])) + dst[len] = '\0'; + return dst; + } + return 0; +} + +/* Parse the "-e" option-value into a list of names */ +static const char **make_namelist(char *src) +{ + const char **dst = 0; + + char *s, *base; + size_t pass, n, nn; + char buffer[BUFSIZ]; + + if (strchr(src, '/') != 0) { /* a filename */ + FILE *fp = fopen(src, "r"); + if (fp == 0) { + perror(src); + exit(EXIT_FAILURE); + } + for (pass = 1; pass <= 2; pass++) { + nn = 0; + while (fgets(buffer, sizeof(buffer), fp) != 0) { + if ((s = stripped(buffer)) != 0) { + if (dst != 0) + dst[nn] = s; + nn++; + } + } + if (pass == 1) { + dst = (const char **)calloc(nn+1, sizeof(*dst)); + rewind(fp); + } + } + fclose(fp); + } else { /* literal list of names */ + for (pass = 1; pass <= 2; pass++) { + for (n = nn = 0, base = src; ; n++) { + int mark = src[n]; + if (mark == ',' || mark == '\0') { + if (pass == 1) { + nn++; + } else { + src[n] = '\0'; + if ((s = stripped(base)) != 0) + dst[nn++] = s; + base = &src[n+1]; + } + } + if (mark == '\0') + break; + } + if (pass == 1) + dst = (const char **)calloc(nn+1, sizeof(*dst)); + } + } + if (showsummary) { + fprintf(log_fp, "Entries that will be compiled:\n"); + for (n = 0; dst[n] != 0; n++) + fprintf(log_fp, "%d:%s\n", n+1, dst[n]); + } + return dst; +} + +static bool matches(const char **needle, const char *haystack) +/* does entry in needle list match |-separated field in haystack? */ +{ + bool code = FALSE; + size_t n; + + if (needle != 0) + { + for (n = 0; needle[n] != 0; n++) + { + if (_nc_name_match(haystack, needle[n], "|")) + { + code = TRUE; + break; + } + } + } + else + code = TRUE; + return(code); +} + +int main (int argc, char *argv[]) +{ +int v_opt = -1, debug_level; +int smart_defaults = TRUE; +char *termcap; +ENTRY *qp; + +int this_opt, last_opt = '?'; + +int outform = F_TERMINFO; /* output format */ +int sortmode = S_TERMINFO; /* sort_mode */ + +int width = 60; +bool formatted = FALSE; /* reformat complex strings? */ +bool infodump = FALSE; /* running as captoinfo? */ +bool capdump = FALSE; /* running as infotocap? */ +bool forceresolve = FALSE; /* force resolution */ +bool limited = TRUE; +char *tversion = (char *)NULL; +const char *source_file = "terminfo"; +const char **namelst = 0; +char *outdir = (char *)NULL; +bool check_only = FALSE; + + log_fp = stderr; + + if ((_nc_progname = strrchr(argv[0], '/')) == NULL) + _nc_progname = argv[0]; + else + _nc_progname++; + + infodump = (strcmp(_nc_progname, "captoinfo") == 0); + capdump = (strcmp(_nc_progname, "infotocap") == 0); + + /* + * Processing arguments is a little complicated, since someone made a + * design decision to allow the numeric values for -w, -v options to + * be optional. + */ + while ((this_opt = getopt(argc, argv, "0123456789CILNR:TVce:fo:rsvw")) != EOF) { + if (isdigit(this_opt)) { + switch (last_opt) { + case 'v': + v_opt = (v_opt * 10) + (this_opt - '0'); + break; + case 'w': + width = (width * 10) + (this_opt - '0'); + break; + default: + if (this_opt != '1') + usage(); + last_opt = this_opt; + width = 0; + } + continue; + } + switch (this_opt) { + case 'C': + capdump = TRUE; + outform = F_TERMCAP; + sortmode = S_TERMCAP; + break; + case 'I': + infodump = TRUE; + outform = F_TERMINFO; + sortmode = S_TERMINFO; + break; + case 'L': + infodump = TRUE; + outform = F_VARIABLE; + sortmode = S_VARIABLE; + break; + case 'N': + smart_defaults = FALSE; + break; + case 'R': + tversion = optarg; + break; + case 'T': + limited = FALSE; + break; + case 'V': + puts(NCURSES_VERSION); + return EXIT_SUCCESS; + case 'c': + check_only = TRUE; + break; + case 'e': + namelst = make_namelist(optarg); + break; + case 'f': + formatted = TRUE; + break; + case 'o': + outdir = optarg; + break; + case 'r': + forceresolve = TRUE; + break; + case 's': + showsummary = TRUE; + break; + case 'v': + v_opt = 0; + break; + case 'w': + width = 0; + break; + default: + usage(); + } + last_opt = this_opt; + } + + debug_level = (v_opt > 0) ? v_opt : (v_opt == 0); + _nc_tracing = (1 << debug_level) - 1; + + if (optind < argc) { + source_file = argv[optind++]; + if (optind < argc) { + fprintf (stderr, + "%s: Too many file names. Usage:\n\t%s %s", + _nc_progname, + _nc_progname, + usage_string); + return EXIT_FAILURE; + } + } else { + if (infodump == TRUE) { + /* captoinfo's no-argument case */ + source_file = "/etc/termcap"; + if ((termcap = getenv("TERMCAP")) != NULL) { + if (access(termcap, F_OK) == 0) { + /* file exists */ + source_file = termcap; + } + } + } else { + /* tic */ + fprintf (stderr, + "%s: File name needed. Usage:\n\t%s %s", + _nc_progname, + _nc_progname, + usage_string); + return EXIT_FAILURE; + } + } + + if (freopen(source_file, "r", stdin) == NULL) { + fprintf (stderr, "%s: Can't open %s\n", _nc_progname, source_file); + return EXIT_FAILURE; + } + + if (infodump) + dump_init(tversion, + smart_defaults + ? outform + : F_LITERAL, + sortmode, width, debug_level, formatted); + else if (capdump) + dump_init(tversion, + outform, + sortmode, width, debug_level, FALSE); + + /* parse entries out of the source file */ + _nc_set_source(source_file); +#ifndef HAVE_BIG_CORE + if (!(check_only || infodump || capdump)) + _nc_set_writedir(outdir); +#endif /* HAVE_BIG_CORE */ + _nc_read_entry_source(stdin, (char *)NULL, + !smart_defaults, FALSE, + (check_only || infodump || capdump) ? NULLHOOK : immedhook); + + /* do use resolution */ + if (check_only || (!infodump && !capdump) || forceresolve) + if (!_nc_resolve_uses() && !check_only) + return EXIT_FAILURE; + +#ifndef HAVE_BIG_CORE + /* + * Aaargh! immedhook seriously hoses us! + * + * One problem with immedhook is it means we can't do -e. Problem + * is that we can't guarantee that for each terminal listed, all the + * terminals it depends on will have been kept in core for reference + * resolution -- in fact it's certain the primitive types at the end + * of reference chains *won't* be in core unless they were explicitly + * in the select list themselves. + */ + if (namelst && (!infodump && !capdump)) + { + (void) fprintf(stderr, + "Sorry, -e can't be used without -I or -C\n"); + return EXIT_FAILURE; + } +#endif /* HAVE_BIG_CORE */ + + /* length check */ + if (check_only && (capdump || infodump)) + { + for_entry_list(qp) + { + if (matches(namelst, qp->tterm.term_names)) + { + int len = fmt_entry(&qp->tterm, NULL, TRUE, infodump); + + if (len>(infodump?MAX_TERMINFO_LENGTH:MAX_TERMCAP_LENGTH)) + (void) fprintf(stderr, + "warning: resolved %s entry is %d bytes long\n", + _nc_first_name(qp->tterm.term_names), + len); + } + } + } + + /* write or dump all entries */ + if (!check_only) + { + if (!infodump && !capdump) + { + _nc_set_writedir(outdir); + for_entry_list(qp) + if (matches(namelst, qp->tterm.term_names)) + { + _nc_set_type(_nc_first_name(qp->tterm.term_names)); + _nc_curr_line = qp->startline; + _nc_write_entry(&qp->tterm); + } + } + else + { + /* this is in case infotocap() generates warnings */ + _nc_curr_col = _nc_curr_line = -1; + + for_entry_list(qp) + if (matches(namelst, qp->tterm.term_names)) + { + int j = qp->cend - qp->cstart; + int len = 0; + + /* this is in case infotocap() generates warnings */ + _nc_set_type(_nc_first_name(qp->tterm.term_names)); + + (void) fseek(stdin, qp->cstart, SEEK_SET); + while (j-- ) + if (infodump) + (void) putchar(getchar()); + else + put_translate(getchar()); + + len = dump_entry(&qp->tterm, limited, NULL); + for (j = 0; j < qp->nuses; j++) + len += dump_uses((char *)(qp->uses[j].parent), infodump); + (void) putchar('\n'); + if (debug_level != 0 && !limited) + printf("# length=%d\n", len); + } + if (!namelst) + { + int c, oldc = '\0'; + bool in_comment = FALSE; + bool trailing_comment = FALSE; + + (void) fseek(stdin, _nc_tail->cend, SEEK_SET); + while ((c = getchar()) != EOF) + { + if (oldc == '\n') { + if (c == '#') { + trailing_comment = TRUE; + in_comment = TRUE; + } else { + in_comment = FALSE; + } + } + if (trailing_comment + && (in_comment || (oldc == '\n' && c == '\n'))) + putchar(c); + oldc = c; + } + } + } + } + + /* Show the directory into which entries were written, and the total + * number of entries + */ + if (showsummary + && (!(check_only || infodump || capdump))) { + int total = _nc_tic_written(); + if (total != 0) + fprintf(log_fp, "%d entries written to %s\n", + total, + _nc_tic_dir((char *)0)); + else + fprintf(log_fp, "No entries written\n"); + } + return(EXIT_SUCCESS); +} |