xref: /illumos-gate/usr/src/cmd/captoinfo/captoinfo.c (revision 8f32bfdc)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
27b5514887Smuffin /*	Copyright (c) 1988 AT&T	*/
28*8f32bfdcSToomas Soome /*	  All Rights Reserved	*/
29b5514887Smuffin 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  *  NAME
327c478bd9Sstevel@tonic-gate  *	captoinfo - convert a termcap description to a terminfo description
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  *  SYNOPSIS
357c478bd9Sstevel@tonic-gate  *	captoinfo [-1vV] [-w width] [ filename ... ]
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  *  AUTHOR
387c478bd9Sstevel@tonic-gate  *	Tony Hansen, January 22, 1984.
397c478bd9Sstevel@tonic-gate  */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include "curses.h"
427c478bd9Sstevel@tonic-gate #include <ctype.h>
437c478bd9Sstevel@tonic-gate #include <stdlib.h>
44b5514887Smuffin #include <unistd.h>
45b5514887Smuffin #include <string.h>
467c478bd9Sstevel@tonic-gate #include "otermcap.h"
477c478bd9Sstevel@tonic-gate #include "print.h"
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #define	trace stderr			/* send trace messages to stderr */
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /* extra termcap variables no longer in terminfo */
527c478bd9Sstevel@tonic-gate char *oboolcodes[] =
537c478bd9Sstevel@tonic-gate 	{
547c478bd9Sstevel@tonic-gate 	"bs",	/* Terminal can backspace with "^H" */
557c478bd9Sstevel@tonic-gate 	"nc",	/* No correctly working carriage return (DM2500,H2000) */
567c478bd9Sstevel@tonic-gate 	"ns",	/* Terminal is a CRT but does not scroll. */
577c478bd9Sstevel@tonic-gate 	"pt",	/* Has hardware tabs (may need to be set with "is") */
587c478bd9Sstevel@tonic-gate 	"MT",	/* Has meta key, alternate code. */
597c478bd9Sstevel@tonic-gate 	"xr",	/* Return acts like ce \r \n (Delta Data) */
607c478bd9Sstevel@tonic-gate 	0
617c478bd9Sstevel@tonic-gate };
627c478bd9Sstevel@tonic-gate int cap_bs = 0, cap_nc = 1, cap_ns = 2, cap_pt = 3, cap_MT = 4, cap_xr = 5;
637c478bd9Sstevel@tonic-gate char *onumcodes[] =
647c478bd9Sstevel@tonic-gate 	{
657c478bd9Sstevel@tonic-gate 	"dB",	/* Number of millisec of bs delay needed */
667c478bd9Sstevel@tonic-gate 	"dC",	/* Number of millisec of cr delay needed */
677c478bd9Sstevel@tonic-gate 	"dF",	/* Number of millisec of ff delay needed */
687c478bd9Sstevel@tonic-gate 	"dN",	/* Number of millisec of nl delay needed */
697c478bd9Sstevel@tonic-gate 	"dT",	/* Number of millisec of tab delay needed */
707c478bd9Sstevel@tonic-gate 	"ug",	/* Number of blank chars left by us or ue */
717c478bd9Sstevel@tonic-gate /* Ignore the 'kn' number. It was ill-defined and never used. */
727c478bd9Sstevel@tonic-gate 	"kn",	/* Number of "other" keys */
737c478bd9Sstevel@tonic-gate 	0
747c478bd9Sstevel@tonic-gate };
757c478bd9Sstevel@tonic-gate int cap_dB = 0, cap_dC = 1, cap_dF = 2, cap_dN = 3, cap_dT = 4, cap_ug = 5;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate char *ostrcodes[] =
787c478bd9Sstevel@tonic-gate 	{
797c478bd9Sstevel@tonic-gate 	"bc",	/* Backspace if not "^H" */
807c478bd9Sstevel@tonic-gate 	"ko",	/* Termcap entries for other non-function keys */
817c478bd9Sstevel@tonic-gate 	"ma",	/* Arrow key map, used by vi version 2 only */
827c478bd9Sstevel@tonic-gate 	"nl",	/* Newline character (default "\n") */
837c478bd9Sstevel@tonic-gate 	"rs",	/* undocumented reset string, like is (info is2) */
847c478bd9Sstevel@tonic-gate /* Ignore the 'ml' and 'mu' strings. */
857c478bd9Sstevel@tonic-gate 	"ml",	/* Memory lock on above cursor. */
867c478bd9Sstevel@tonic-gate 	"mu",	/* Memory unlock (turn off memory lock). */
877c478bd9Sstevel@tonic-gate 	0
887c478bd9Sstevel@tonic-gate };
897c478bd9Sstevel@tonic-gate int cap_bc = 0, cap_ko = 1, cap_ma = 2, cap_nl = 3, cap_rs = 4;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate #define	numelements(x)	(sizeof (x)/sizeof (x[0]))
927c478bd9Sstevel@tonic-gate char oboolval[2][numelements(oboolcodes)];
937c478bd9Sstevel@tonic-gate short onumval[2][numelements(onumcodes)];
947c478bd9Sstevel@tonic-gate char *ostrval[2][numelements(ostrcodes)];
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /* externs from libcurses.a */
977c478bd9Sstevel@tonic-gate extern char *boolnames[], *boolcodes[];
987c478bd9Sstevel@tonic-gate extern char *numnames[], *numcodes[];
997c478bd9Sstevel@tonic-gate extern char *strnames[], *strcodes[];
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /* globals for this file */
1027c478bd9Sstevel@tonic-gate char *progname;			/* argv [0], the name of the program */
1037c478bd9Sstevel@tonic-gate static char *term_name;		/* the name of the terminal being worked on */
1047c478bd9Sstevel@tonic-gate static int uselevel;		/* whether we're dealing with use= info */
1057c478bd9Sstevel@tonic-gate static int boolcount,		/* the maximum numbers of each name array */
1067c478bd9Sstevel@tonic-gate 	    numcount,
1077c478bd9Sstevel@tonic-gate 	    strcount;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /* globals dealing with the environment */
1107c478bd9Sstevel@tonic-gate extern char **environ;
1117c478bd9Sstevel@tonic-gate static char TERM[100];
1127c478bd9Sstevel@tonic-gate #if defined(SYSV) || defined(USG)  /* handle both Sys Vr2 and Vr3 curses */
1137c478bd9Sstevel@tonic-gate static char dirname[BUFSIZ];
1147c478bd9Sstevel@tonic-gate #else
1157c478bd9Sstevel@tonic-gate #include <sys/param.h>
1167c478bd9Sstevel@tonic-gate static char dirname[MAXPATHLEN];
1177c478bd9Sstevel@tonic-gate #endif /* SYSV || USG */
1187c478bd9Sstevel@tonic-gate static char TERMCAP[BUFSIZ+15];
1197c478bd9Sstevel@tonic-gate static char *newenviron[] = { &TERM[0], &TERMCAP[0], 0 };
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate /* dynamic arrays */
1227c478bd9Sstevel@tonic-gate static char *boolval[2];	/* dynamic array of boolean values */
1237c478bd9Sstevel@tonic-gate static short *numval[2];	/* dynamic array of numeric values */
1247c478bd9Sstevel@tonic-gate static char **strval[2];	/* dynamic array of string pointers */
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate /* data buffers */
1277c478bd9Sstevel@tonic-gate static char *capbuffer;		/* string table, pointed at by strval */
1287c478bd9Sstevel@tonic-gate static char *nextstring;	/* pointer into string table */
1297c478bd9Sstevel@tonic-gate static char *bp;		/* termcap raw string table */
1307c478bd9Sstevel@tonic-gate static char *buflongname;	/* place to copy the long names */
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate /* flags */
1337c478bd9Sstevel@tonic-gate static int verbose = 0;		/* debugging printing level */
1347c478bd9Sstevel@tonic-gate static int copycomments = 0;	/* copy comments from tercap source */
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate #define	ispadchar(c)	(isdigit(c) || (c) == '.' || (c) == '*')
1377c478bd9Sstevel@tonic-gate 
138b5514887Smuffin static void getlongname(void);
139b5514887Smuffin static void handleko(void);
140b5514887Smuffin static void handlema(void);
141b5514887Smuffin static void print_no_use_entry(void);
1427c478bd9Sstevel@tonic-gate static void print_use_entry(char *);
143b5514887Smuffin static void captoinfo(void);
144b5514887Smuffin static void use_etc_termcap(void);
145b5514887Smuffin static void initdirname(void);
1467c478bd9Sstevel@tonic-gate static void setfilename(char *);
147b5514887Smuffin static void setterm_name(void);
1487c478bd9Sstevel@tonic-gate static void use_file(char *);
1497c478bd9Sstevel@tonic-gate static void sorttable(char *[], char *[]);
150b5514887Smuffin static void inittables(void);
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate /*
1537c478bd9Sstevel@tonic-gate  *  Verify that the names given in the termcap entry are all valid.
1547c478bd9Sstevel@tonic-gate  */
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate int
capsearch(char * codes[],char * ocodes[],char * cap)1577c478bd9Sstevel@tonic-gate capsearch(char *codes[], char *ocodes[], char *cap)
1587c478bd9Sstevel@tonic-gate {
1597c478bd9Sstevel@tonic-gate 	for (; *codes; codes++)
1607c478bd9Sstevel@tonic-gate 		if (((*codes)[0] == cap[0]) && ((*codes)[1] == cap[1]))
1617c478bd9Sstevel@tonic-gate 			return (1);
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	for (; *ocodes; ocodes++)
1647c478bd9Sstevel@tonic-gate 		if (((*ocodes)[0] == cap[0]) && ((*ocodes)[1] == cap[1]))
1657c478bd9Sstevel@tonic-gate 			return (1);
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	return (0);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate void
checktermcap()1717c478bd9Sstevel@tonic-gate checktermcap()
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate 	char *tbuf = bp;
1747c478bd9Sstevel@tonic-gate 	enum { tbool, tnum, tstr, tcancel, tunknown } type;
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	for (;;) {
1777c478bd9Sstevel@tonic-gate 		tbuf = tskip(tbuf);
1787c478bd9Sstevel@tonic-gate 		while (*tbuf == '\t' || *tbuf == ' ' || *tbuf == ':')
1797c478bd9Sstevel@tonic-gate 			tbuf++;
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 		if (*tbuf == 0)
1827c478bd9Sstevel@tonic-gate 			return;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 		/* commented out entry? */
1857c478bd9Sstevel@tonic-gate 		if (*tbuf == '.') {
1867c478bd9Sstevel@tonic-gate 			if (verbose)
1877c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "termcap string '%c%c' "
1887c478bd9Sstevel@tonic-gate 				    "commented out.\n", tbuf[1], tbuf[2]);
1897c478bd9Sstevel@tonic-gate 			if (!capsearch(boolcodes, oboolcodes, tbuf + 1) &&
1907c478bd9Sstevel@tonic-gate 			    !capsearch(numcodes, onumcodes, tbuf + 1) &&
1917c478bd9Sstevel@tonic-gate 			    !capsearch(strcodes, ostrcodes, tbuf + 1))
1927c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
1937c478bd9Sstevel@tonic-gate 				    "%s: TERM=%s: commented out code '%.2s' "
1947c478bd9Sstevel@tonic-gate 				    "is unknown.\n", progname, term_name,
1957c478bd9Sstevel@tonic-gate 				    tbuf+1);
1967c478bd9Sstevel@tonic-gate 			continue;
1977c478bd9Sstevel@tonic-gate 		}
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 		if (verbose)
2007c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "looking at termcap string "
2017c478bd9Sstevel@tonic-gate 			    "'%.2s'.\n", tbuf);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 		switch (tbuf[2]) {
2047c478bd9Sstevel@tonic-gate 			case ':': case '\0':	type = tbool;	break;
2057c478bd9Sstevel@tonic-gate 			case '#':			type = tnum;	break;
2067c478bd9Sstevel@tonic-gate 			case '=':			type = tstr;	break;
2077c478bd9Sstevel@tonic-gate 			case '@':			type = tcancel;	break;
2087c478bd9Sstevel@tonic-gate 			default:
2097c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
2107c478bd9Sstevel@tonic-gate 				    "%s: TERM=%s: unknown type given for the "
2117c478bd9Sstevel@tonic-gate 				    "termcap code '%.2s'.\n", progname,
2127c478bd9Sstevel@tonic-gate 				    term_name, tbuf);
2137c478bd9Sstevel@tonic-gate 				type = tunknown;
2147c478bd9Sstevel@tonic-gate 		}
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 		if (verbose > 1)
2177c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "type of '%.2s' is %s.\n", tbuf,
2187c478bd9Sstevel@tonic-gate 			    (type == tbool) ? "boolean" :
2197c478bd9Sstevel@tonic-gate 			    (type == tnum) ? "numeric" :
2207c478bd9Sstevel@tonic-gate 			    (type = tstr) ? "string" :
2217c478bd9Sstevel@tonic-gate 			    (type = tcancel) ? "canceled" : "unknown");
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 		/* look for the name in bools */
2247c478bd9Sstevel@tonic-gate 		if (capsearch(boolcodes, oboolcodes, tbuf)) {
2257c478bd9Sstevel@tonic-gate 			if (type != tbool && type != tcancel)
2267c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
2277c478bd9Sstevel@tonic-gate 				    "%s: TERM=%s: wrong type given for the "
2287c478bd9Sstevel@tonic-gate 				    "boolean termcap code '%.2s'.\n", progname,
2297c478bd9Sstevel@tonic-gate 				    term_name, tbuf);
230e673284eSToomas Soome 			continue;
2317c478bd9Sstevel@tonic-gate 		}
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 		/* look for the name in nums */
2347c478bd9Sstevel@tonic-gate 		if (capsearch(numcodes, onumcodes, tbuf)) {
2357c478bd9Sstevel@tonic-gate 			if (type != tnum && type != tcancel)
2367c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
2377c478bd9Sstevel@tonic-gate 				    "%s: TERM=%s: wrong type given for the "
2387c478bd9Sstevel@tonic-gate 				    "numeric termcap code '%.2s'.\n", progname,
2397c478bd9Sstevel@tonic-gate 				    term_name, tbuf);
240e673284eSToomas Soome 			continue;
2417c478bd9Sstevel@tonic-gate 		}
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 		/* look for the name in strs */
2447c478bd9Sstevel@tonic-gate 		if (capsearch(strcodes, ostrcodes, tbuf)) {
2457c478bd9Sstevel@tonic-gate 			if (type != tstr && type != tcancel)
2467c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
2477c478bd9Sstevel@tonic-gate 				    "%s: TERM=%s: wrong type given for the "
2487c478bd9Sstevel@tonic-gate 				    "string termcap code '%.2s'.\n", progname,
2497c478bd9Sstevel@tonic-gate 				    term_name, tbuf);
250e673284eSToomas Soome 			continue;
2517c478bd9Sstevel@tonic-gate 		}
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
2547c478bd9Sstevel@tonic-gate 		    "%s: TERM=%s: the %s termcap code '%.2s' is not a valid "
2557c478bd9Sstevel@tonic-gate 		    "name.\n", progname, term_name,
2567c478bd9Sstevel@tonic-gate 		    (type == tbool) ? "boolean" :
2577c478bd9Sstevel@tonic-gate 		    (type == tnum) ? "numeric" :
2587c478bd9Sstevel@tonic-gate 		    (type = tstr) ? "string" :
2597c478bd9Sstevel@tonic-gate 		    (type = tcancel) ? "canceled" : "(unknown type)", tbuf);
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate  *  Fill up the termcap tables.
2657c478bd9Sstevel@tonic-gate  */
2667c478bd9Sstevel@tonic-gate int
filltables(void)267b5514887Smuffin filltables(void)
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate 	int i, tret;
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 	/* Retrieve the termcap entry. */
2727c478bd9Sstevel@tonic-gate 	if ((tret = otgetent(bp, term_name)) != 1) {
2737c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
2747c478bd9Sstevel@tonic-gate 		    "%s: TERM=%s: tgetent failed with return code %d (%s).\n",
2757c478bd9Sstevel@tonic-gate 		    progname, term_name, tret,
2767c478bd9Sstevel@tonic-gate 		    (tret == 0) ? "non-existent or invalid entry" :
2777c478bd9Sstevel@tonic-gate 		    (tret == -1) ? "cannot open $TERMCAP" : "unknown reason");
2787c478bd9Sstevel@tonic-gate 		return (0);
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	if (verbose) {
2827c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "bp=");
2837c478bd9Sstevel@tonic-gate 		(void) cpr(trace, bp);
2847c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, ".\n");
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if (uselevel == 0)
2887c478bd9Sstevel@tonic-gate 		checktermcap();
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate 	/* Retrieve the values that are in terminfo. */
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	/* booleans */
2937c478bd9Sstevel@tonic-gate 	for (i = 0; boolcodes[i]; i++) {
2947c478bd9Sstevel@tonic-gate 		boolval[uselevel][i] = otgetflag(boolcodes[i]);
2957c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
2967c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "boolcodes=%s, ", boolcodes[i]);
2977c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "boolnames=%s, ", boolnames[i]);
2987c478bd9Sstevel@tonic-gate 			(void) fprintf(trace,
2997c478bd9Sstevel@tonic-gate 			    "flag=%d.\n", boolval[uselevel][i]);
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	/* numbers */
3047c478bd9Sstevel@tonic-gate 	for (i = 0; numcodes[i]; i++) {
3057c478bd9Sstevel@tonic-gate 		numval[uselevel][i] = otgetnum(numcodes[i]);
3067c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
3077c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "numcodes=%s, ", numcodes[i]);
3087c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "numnames=%s, ", numnames[i]);
3097c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "num=%d.\n", numval[uselevel][i]);
3107c478bd9Sstevel@tonic-gate 		}
3117c478bd9Sstevel@tonic-gate 	}
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	if (uselevel == 0)
3147c478bd9Sstevel@tonic-gate 		nextstring = capbuffer;
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	/* strings */
3177c478bd9Sstevel@tonic-gate 	for (i = 0; strcodes[i]; i++) {
3187c478bd9Sstevel@tonic-gate 		strval[uselevel][i] = otgetstr(strcodes[i], &nextstring);
3197c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
3207c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "strcodes=%s, ", strcodes [i]);
3217c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "strnames=%s, ", strnames [i]);
3227c478bd9Sstevel@tonic-gate 			if (strval[uselevel][i]) {
3237c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "str=");
3247c478bd9Sstevel@tonic-gate 				tpr(trace, strval[uselevel][i]);
3257c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, ".\n");
3267c478bd9Sstevel@tonic-gate 			}
3277c478bd9Sstevel@tonic-gate 		else
3287c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "str=NULL.\n");
3297c478bd9Sstevel@tonic-gate 		}
3307c478bd9Sstevel@tonic-gate 		/* remove zero length strings */
3317c478bd9Sstevel@tonic-gate 		if (strval[uselevel][i] && (strval[uselevel][i][0] == '\0')) {
3327c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
3337c478bd9Sstevel@tonic-gate 			    "%s: TERM=%s: cap %s (info %s) is NULL: REMOVED\n",
3347c478bd9Sstevel@tonic-gate 			    progname, term_name, strcodes[i], strnames[i]);
3357c478bd9Sstevel@tonic-gate 			strval[uselevel][i] = NULL;
3367c478bd9Sstevel@tonic-gate 		}
3377c478bd9Sstevel@tonic-gate 	}
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	/* Retrieve the values not found in terminfo anymore. */
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	/* booleans */
3427c478bd9Sstevel@tonic-gate 	for (i = 0; oboolcodes[i]; i++) {
3437c478bd9Sstevel@tonic-gate 		oboolval[uselevel][i] = otgetflag(oboolcodes[i]);
3447c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
3457c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "oboolcodes=%s, ",
3467c478bd9Sstevel@tonic-gate 			    oboolcodes[i]);
3477c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "flag=%d.\n",
3487c478bd9Sstevel@tonic-gate 			    oboolval[uselevel][i]);
3497c478bd9Sstevel@tonic-gate 		}
3507c478bd9Sstevel@tonic-gate 	}
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	/* numbers */
3537c478bd9Sstevel@tonic-gate 	for (i = 0; onumcodes[i]; i++) {
3547c478bd9Sstevel@tonic-gate 		onumval[uselevel][i] = otgetnum(onumcodes[i]);
3557c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
3567c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "onumcodes=%s, ", onumcodes[i]);
3577c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "num=%d.\n",
3587c478bd9Sstevel@tonic-gate 			    onumval[uselevel][i]);
3597c478bd9Sstevel@tonic-gate 		}
3607c478bd9Sstevel@tonic-gate 	}
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	/* strings */
3637c478bd9Sstevel@tonic-gate 	for (i = 0; ostrcodes[i]; i++) {
3647c478bd9Sstevel@tonic-gate 		ostrval[uselevel][i] = otgetstr(ostrcodes[i], &nextstring);
3657c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
3667c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "ostrcodes=%s, ", ostrcodes[i]);
3677c478bd9Sstevel@tonic-gate 			if (ostrval[uselevel][i]) {
3687c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "ostr=");
3697c478bd9Sstevel@tonic-gate 				tpr(trace, ostrval[uselevel][i]);
3707c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, ".\n");
3717c478bd9Sstevel@tonic-gate 			}
3727c478bd9Sstevel@tonic-gate 			else
3737c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "ostr=NULL.\n");
3747c478bd9Sstevel@tonic-gate 		}
3757c478bd9Sstevel@tonic-gate 		/* remove zero length strings */
3767c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][i] && (ostrval[uselevel][i][0] == '\0')) {
3777c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
3787c478bd9Sstevel@tonic-gate 			    "%s: TERM=%s: cap %s (no terminfo name) is NULL: "
3797c478bd9Sstevel@tonic-gate 			    "REMOVED\n", progname, term_name, ostrcodes[i]);
3807c478bd9Sstevel@tonic-gate 			ostrval[uselevel][i] = NULL;
3817c478bd9Sstevel@tonic-gate 		}
3827c478bd9Sstevel@tonic-gate 	}
3837c478bd9Sstevel@tonic-gate 	return (1);
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate /*
3877c478bd9Sstevel@tonic-gate  *  This routine copies the set of names from the termcap entry into
3887c478bd9Sstevel@tonic-gate  *  a separate buffer, getting rid of the old obsolete two character
3897c478bd9Sstevel@tonic-gate  *  names.
3907c478bd9Sstevel@tonic-gate  */
3917c478bd9Sstevel@tonic-gate static void
getlongname(void)392b5514887Smuffin getlongname(void)
3937c478bd9Sstevel@tonic-gate {
3947c478bd9Sstevel@tonic-gate 	char *b = &bp[0],  *l = buflongname;
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 	/* Skip the two character name */
3977c478bd9Sstevel@tonic-gate 	if (bp[2] == '|')
3987c478bd9Sstevel@tonic-gate 		b = &bp[3];
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	/* Copy the rest of the names */
4017c478bd9Sstevel@tonic-gate 	while (*b && *b != ':')
4027c478bd9Sstevel@tonic-gate 		*l++ = *b++;
4037c478bd9Sstevel@tonic-gate 	*l = '\0';
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	if (b != &bp[0]) {
4067c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: obsolete 2 character name "
4077c478bd9Sstevel@tonic-gate 		    "'%2.2s' removed.\n", progname, bp);
4087c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "\tsynonyms are: '%s'\n", buflongname);
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate /*
4137c478bd9Sstevel@tonic-gate  *  Return the value of the termcap string 'capname' as stored in our list.
4147c478bd9Sstevel@tonic-gate  */
415b5514887Smuffin char *
getcapstr(char * capname)416b5514887Smuffin getcapstr(char *capname)
4177c478bd9Sstevel@tonic-gate {
4187c478bd9Sstevel@tonic-gate 	int i;
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	if (verbose > 1)
4217c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "looking for termcap value of %s.\n",
4227c478bd9Sstevel@tonic-gate 		    capname);
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	/* Check the old termcap list. */
4257c478bd9Sstevel@tonic-gate 	for (i = 0; ostrcodes[i]; i++)
4267c478bd9Sstevel@tonic-gate 		if (strcmp(ostrcodes[i], capname) == 0) {
4277c478bd9Sstevel@tonic-gate 			if (verbose > 1) {
4287c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "\tvalue is:");
4297c478bd9Sstevel@tonic-gate 				tpr(trace, ostrval[uselevel][i]);
4307c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, ".\n");
4317c478bd9Sstevel@tonic-gate 			}
4327c478bd9Sstevel@tonic-gate 			return (ostrval[uselevel][i]);
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	if (verbose > 1)
4367c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "termcap name '%s' not found in "
4377c478bd9Sstevel@tonic-gate 		    "ostrcodes.\n", capname);
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 	/* Check the terminfo list. */
4407c478bd9Sstevel@tonic-gate 	for (i = 0; strcodes[i]; i++)
4417c478bd9Sstevel@tonic-gate 		if (strcmp(strcodes[i], capname) == 0) {
4427c478bd9Sstevel@tonic-gate 			if (verbose > 1) {
4437c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "\tvalue is:");
4447c478bd9Sstevel@tonic-gate 				tpr(trace, strval[uselevel][i]);
4457c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, ".\n");
4467c478bd9Sstevel@tonic-gate 			}
4477c478bd9Sstevel@tonic-gate 			return (strval[uselevel][i]);
4487c478bd9Sstevel@tonic-gate 		}
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: TERM=%s: termcap name '%s' not found.\n",
4517c478bd9Sstevel@tonic-gate 	    progname, term_name, capname);
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	return ((char *)NULL);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate /*
4577c478bd9Sstevel@tonic-gate  *  Search for a name in the given table and
4587c478bd9Sstevel@tonic-gate  *  return the index.
4597c478bd9Sstevel@tonic-gate  *  Someday I'll redo this to use bsearch().
4607c478bd9Sstevel@tonic-gate  */
4617c478bd9Sstevel@tonic-gate /* ARGSUSED */
4627c478bd9Sstevel@tonic-gate int
search(char * names[],int max,char * infoname)4637c478bd9Sstevel@tonic-gate search(char *names[], int max, char *infoname)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate #ifndef BSEARCH
4667c478bd9Sstevel@tonic-gate 	int i;
4677c478bd9Sstevel@tonic-gate 	for (i = 0; names [i] != NULL; i++)
4687c478bd9Sstevel@tonic-gate 		if (strcmp(names [i], infoname) == 0)
4697c478bd9Sstevel@tonic-gate 			return (i);
470e673284eSToomas Soome 	return (-1);
4717c478bd9Sstevel@tonic-gate #else				/* this doesn't work for some reason */
4727c478bd9Sstevel@tonic-gate 	char **bret;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	bret = (char **)bsearch(infoname, (char *)names, max,
4757c478bd9Sstevel@tonic-gate 	    sizeof (char *), strcmp);
4767c478bd9Sstevel@tonic-gate 	(void) fprintf(trace, "search looking for %s.\n", infoname);
4777c478bd9Sstevel@tonic-gate 	(void) fprintf(trace, "base=%#x, bret=%#x, nel=%d.\n", names,
4787c478bd9Sstevel@tonic-gate 	    bret, max);
4797c478bd9Sstevel@tonic-gate 	(void) fprintf(trace, "returning %d.\n", bret == NULL ? -1 :
4807c478bd9Sstevel@tonic-gate 	    bret - names);
4817c478bd9Sstevel@tonic-gate 	if (bret == NULL)
4827c478bd9Sstevel@tonic-gate 		return (-1);
4837c478bd9Sstevel@tonic-gate 	else
4847c478bd9Sstevel@tonic-gate 		return (bret - names);
4857c478bd9Sstevel@tonic-gate #endif /* OLD */
4867c478bd9Sstevel@tonic-gate }
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate /*
4897c478bd9Sstevel@tonic-gate  *  return the value of the terminfo string 'infoname'
4907c478bd9Sstevel@tonic-gate  */
491b5514887Smuffin char *
getinfostr(char * infoname)492b5514887Smuffin getinfostr(char *infoname)
4937c478bd9Sstevel@tonic-gate {
4947c478bd9Sstevel@tonic-gate 	int i;
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	if (verbose > 1)
4977c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "looking for terminfo value of %s.\n",
4987c478bd9Sstevel@tonic-gate 		    infoname);
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	i = search(strnames, strcount, infoname);
5017c478bd9Sstevel@tonic-gate 	if (i != -1) {
5027c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
5037c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "\tvalue is:");
5047c478bd9Sstevel@tonic-gate 			tpr(trace, strval[uselevel][i]);
5057c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, ".\n");
5067c478bd9Sstevel@tonic-gate 		}
5077c478bd9Sstevel@tonic-gate 		return (strval[uselevel][i]);
5087c478bd9Sstevel@tonic-gate 	}
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 	if (verbose > 1)
5117c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "terminfo name '%s' not found.\n",
5127c478bd9Sstevel@tonic-gate 		    infoname);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 	return ((char *)NULL);
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate  *  Replace the value stored for the terminfo boolean
5197c478bd9Sstevel@tonic-gate  *  capability 'infoname' with the newvalue.
5207c478bd9Sstevel@tonic-gate  */
5217c478bd9Sstevel@tonic-gate void
putbool(char * infoname,int newvalue)5227c478bd9Sstevel@tonic-gate putbool(char *infoname, int newvalue)
5237c478bd9Sstevel@tonic-gate {
5247c478bd9Sstevel@tonic-gate 	int i;
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 	if (verbose > 1)
5277c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "changing value for %s to %d.\n",
5287c478bd9Sstevel@tonic-gate 		    infoname, newvalue);
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 	i = search(boolnames, boolcount, infoname);
5317c478bd9Sstevel@tonic-gate 	if (i != -1) {
5327c478bd9Sstevel@tonic-gate 		if (verbose > 1)
5337c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "value was: %d.\n",
5347c478bd9Sstevel@tonic-gate 			    boolval[uselevel][i]);
5357c478bd9Sstevel@tonic-gate 
5367c478bd9Sstevel@tonic-gate 		boolval[uselevel][i] = newvalue;
5377c478bd9Sstevel@tonic-gate 		return;
5387c478bd9Sstevel@tonic-gate 	}
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: TERM=%s: the boolean name '%s' was not "
5417c478bd9Sstevel@tonic-gate 	    "found!\n", progname, term_name, infoname);
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate /*
5457c478bd9Sstevel@tonic-gate  *  Replace the value stored for the terminfo number
5467c478bd9Sstevel@tonic-gate  *  capability 'infoname' with the newvalue.
5477c478bd9Sstevel@tonic-gate  */
5487c478bd9Sstevel@tonic-gate void
putnum(char * infoname,int newvalue)5497c478bd9Sstevel@tonic-gate putnum(char *infoname, int newvalue)
5507c478bd9Sstevel@tonic-gate {
5517c478bd9Sstevel@tonic-gate 	int i;
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 	if (verbose > 1)
5547c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "changing value for %s to %d.\n",
5557c478bd9Sstevel@tonic-gate 		    infoname, newvalue);
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	i = search(numnames, numcount, infoname);
5587c478bd9Sstevel@tonic-gate 	if (i != -1) {
5597c478bd9Sstevel@tonic-gate 		if (verbose > 1)
5607c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "value was: %d.\n",
5617c478bd9Sstevel@tonic-gate 			    numval[uselevel][i]);
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 		numval[uselevel][i] = newvalue;
5647c478bd9Sstevel@tonic-gate 		return;
5657c478bd9Sstevel@tonic-gate 	}
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: TERM=%s: the numeric name '%s' was not "
5687c478bd9Sstevel@tonic-gate 	    "found!\n",
569b5514887Smuffin 	    progname, term_name, infoname);
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate /*
5737c478bd9Sstevel@tonic-gate  *  replace the value stored for the terminfo string capability 'infoname'
5747c478bd9Sstevel@tonic-gate  *  with the newvalue.
5757c478bd9Sstevel@tonic-gate  */
5767c478bd9Sstevel@tonic-gate void
putstr(char * infoname,char * newvalue)5777c478bd9Sstevel@tonic-gate putstr(char *infoname, char *newvalue)
5787c478bd9Sstevel@tonic-gate {
5797c478bd9Sstevel@tonic-gate 	int i;
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 	if (verbose > 1) {
5827c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "changing value for %s to ", infoname);
5837c478bd9Sstevel@tonic-gate 		tpr(trace, newvalue);
5847c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, ".\n");
5857c478bd9Sstevel@tonic-gate 	}
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 	i = search(strnames, strcount, infoname);
5887c478bd9Sstevel@tonic-gate 	if (i != -1) {
5897c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
5907c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "value was:");
5917c478bd9Sstevel@tonic-gate 			tpr(trace, strval[uselevel][i]);
5927c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, ".\n");
5937c478bd9Sstevel@tonic-gate 		}
5947c478bd9Sstevel@tonic-gate 		strval[uselevel][i] = nextstring;
5957c478bd9Sstevel@tonic-gate 		while (*newvalue)
5967c478bd9Sstevel@tonic-gate 			*nextstring++ = *newvalue++;
5977c478bd9Sstevel@tonic-gate 		*nextstring++ = '\0';
5987c478bd9Sstevel@tonic-gate 		return;
5997c478bd9Sstevel@tonic-gate 	}
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: TERM=%s: the string name '%s' was not "
6027c478bd9Sstevel@tonic-gate 	    "found!\n",
603b5514887Smuffin 	    progname, term_name, infoname);
6047c478bd9Sstevel@tonic-gate }
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate /*
6077c478bd9Sstevel@tonic-gate  *  Add in extra delays if they are not recorded already.
6087c478bd9Sstevel@tonic-gate  *  This is done before the padding information has been modified by
6097c478bd9Sstevel@tonic-gate  *  changecalculations() below, so the padding information, if there
6107c478bd9Sstevel@tonic-gate  *  already, is still at the beginning of the string in termcap format.
6117c478bd9Sstevel@tonic-gate  */
6127c478bd9Sstevel@tonic-gate void
addpadding(int cappadding,char * infostr)6137c478bd9Sstevel@tonic-gate addpadding(int cappadding, char *infostr)
6147c478bd9Sstevel@tonic-gate {
6157c478bd9Sstevel@tonic-gate 	char *cap;
6167c478bd9Sstevel@tonic-gate 	char tempbuffer [100];
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 	/* Is there padding to add? */
6197c478bd9Sstevel@tonic-gate 	if (cappadding > 0)
6207c478bd9Sstevel@tonic-gate 	/* Is there a string to add it to? */
6217c478bd9Sstevel@tonic-gate 		if (cap = getinfostr(infostr))
6227c478bd9Sstevel@tonic-gate 		/* Is there any padding info already? */
6237c478bd9Sstevel@tonic-gate 			if (ispadchar(*cap)) {
6247c478bd9Sstevel@tonic-gate 				/* EMPTY */;
6257c478bd9Sstevel@tonic-gate 		/* Assume that the padding info that is there is correct. */
6267c478bd9Sstevel@tonic-gate 			} else {
6277c478bd9Sstevel@tonic-gate 		/* Add the padding at the end of the present string. */
6287c478bd9Sstevel@tonic-gate 				(void) snprintf(tempbuffer, sizeof (tempbuffer),
6297c478bd9Sstevel@tonic-gate 				    "%s$<%d>", cap, cappadding);
6307c478bd9Sstevel@tonic-gate 				putstr(infostr, tempbuffer);
6317c478bd9Sstevel@tonic-gate 		} else {
6327c478bd9Sstevel@tonic-gate 			/* Create a new string that only has the padding. */
6337c478bd9Sstevel@tonic-gate 			(void) sprintf(tempbuffer, "$<%d>", cappadding);
6347c478bd9Sstevel@tonic-gate 			putstr(infostr, tempbuffer);
6357c478bd9Sstevel@tonic-gate 		}
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate struct
6397c478bd9Sstevel@tonic-gate 	{
6407c478bd9Sstevel@tonic-gate 	char *capname;
6417c478bd9Sstevel@tonic-gate 	char *keyedinfoname;
6427c478bd9Sstevel@tonic-gate 	} ko_map[] = {
6437c478bd9Sstevel@tonic-gate 	"al",		"kil1",
6447c478bd9Sstevel@tonic-gate 	"bs",		"kbs",		/* special addition */
6457c478bd9Sstevel@tonic-gate 	"bt",		"kcbt",
6467c478bd9Sstevel@tonic-gate 	"cd",		"ked",
6477c478bd9Sstevel@tonic-gate 	"ce",		"kel",
6487c478bd9Sstevel@tonic-gate 	"cl",		"kclr",
6497c478bd9Sstevel@tonic-gate 	"ct",		"ktbc",
6507c478bd9Sstevel@tonic-gate 	"dc",		"kdch1",
6517c478bd9Sstevel@tonic-gate 	"dl",		"kdl1",
6527c478bd9Sstevel@tonic-gate 	"do",		"kcud1",
6537c478bd9Sstevel@tonic-gate 	"ei",		"krmir",
6547c478bd9Sstevel@tonic-gate 	"ho",		"khome",
6557c478bd9Sstevel@tonic-gate 	"ic",		"kich1",
6567c478bd9Sstevel@tonic-gate 	"im",		"kich1",	/* special addition */
6577c478bd9Sstevel@tonic-gate 	"le",		"kcub1",
6587c478bd9Sstevel@tonic-gate 	"ll",		"kll",
6597c478bd9Sstevel@tonic-gate 	"nd",		"kcuf1",
6607c478bd9Sstevel@tonic-gate 	"sf",		"kind",
6617c478bd9Sstevel@tonic-gate 	"sr",		"kri",
6627c478bd9Sstevel@tonic-gate 	"st",		"khts",
6637c478bd9Sstevel@tonic-gate 	"up",		"kcuu1",
6647c478bd9Sstevel@tonic-gate /*	"",		"kctab",	*/
6657c478bd9Sstevel@tonic-gate /*	"",		"knp",		*/
6667c478bd9Sstevel@tonic-gate /*	"",		"kpp",		*/
6677c478bd9Sstevel@tonic-gate 	0,		0
6687c478bd9Sstevel@tonic-gate 	};
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate /*
6717c478bd9Sstevel@tonic-gate  *  Work with the ko string. It is a comma separated list of keys for which
6727c478bd9Sstevel@tonic-gate  *  the keyboard has a key by the same name that emits the same sequence.
6737c478bd9Sstevel@tonic-gate  *  For example, ko = dc, im, ei means that there are keys called
6747c478bd9Sstevel@tonic-gate  *  delete-character, enter-insert-mode and exit-insert-mode on the keyboard,
6757c478bd9Sstevel@tonic-gate  *  and they emit the same sequences as specified in the dc, im and ei
6767c478bd9Sstevel@tonic-gate  *  capabilities.
6777c478bd9Sstevel@tonic-gate  */
6787c478bd9Sstevel@tonic-gate static void
handleko(void)679b5514887Smuffin handleko(void)
6807c478bd9Sstevel@tonic-gate {
6817c478bd9Sstevel@tonic-gate 	char capname[3];
6827c478bd9Sstevel@tonic-gate 	char *capstr;
6837c478bd9Sstevel@tonic-gate 	int i, j, found;
6847c478bd9Sstevel@tonic-gate 	char *infostr;
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	if (verbose > 1)
6877c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "working on termcap ko string.\n");
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 	if (ostrval[uselevel][cap_ko] == NULL)
6907c478bd9Sstevel@tonic-gate 		return;
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate 	capname[2] = '\0';
6937c478bd9Sstevel@tonic-gate 	for (i = 0; ostrval[uselevel][cap_ko][i] != '\0'; ) {
6947c478bd9Sstevel@tonic-gate 		/* isolate the termcap name */
6957c478bd9Sstevel@tonic-gate 		capname[0] = ostrval[uselevel][cap_ko][i++];
6967c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][cap_ko][i] == '\0')
6977c478bd9Sstevel@tonic-gate 			break;
6987c478bd9Sstevel@tonic-gate 		capname[1] = ostrval[uselevel][cap_ko][i++];
6997c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][cap_ko][i] == ',')
7007c478bd9Sstevel@tonic-gate 			i++;
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
7037c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "key termcap name is '");
7047c478bd9Sstevel@tonic-gate 			tpr(trace, capname);
7057c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "'.\n");
7067c478bd9Sstevel@tonic-gate 		}
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 		/* match it up into our list */
7097c478bd9Sstevel@tonic-gate 		found = 0;
7107c478bd9Sstevel@tonic-gate 		for (j = 0; !found && ko_map[j].keyedinfoname != NULL; j++) {
7117c478bd9Sstevel@tonic-gate 			if (verbose > 1)
7127c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "looking at termcap name %s.\n",
7137c478bd9Sstevel@tonic-gate 			    ko_map[j].capname);
7147c478bd9Sstevel@tonic-gate 			if (capname[0] == ko_map[j].capname[0] &&
7157c478bd9Sstevel@tonic-gate 			    capname[1] == ko_map[j].capname[1]) {
7167c478bd9Sstevel@tonic-gate 				/* add the value to our database */
7177c478bd9Sstevel@tonic-gate 				if ((capstr = getcapstr(capname)) != NULL) {
7187c478bd9Sstevel@tonic-gate 					infostr = getinfostr
7197c478bd9Sstevel@tonic-gate 					    (ko_map[j].keyedinfoname);
7207c478bd9Sstevel@tonic-gate 				if (infostr == NULL) {
7217c478bd9Sstevel@tonic-gate 					/* skip any possible padding */
7227c478bd9Sstevel@tonic-gate 					/* information */
7237c478bd9Sstevel@tonic-gate 					while (ispadchar(*capstr))
7247c478bd9Sstevel@tonic-gate 						capstr++;
7257c478bd9Sstevel@tonic-gate 					putstr(ko_map[j].keyedinfoname, capstr);
7267c478bd9Sstevel@tonic-gate 				} else
7277c478bd9Sstevel@tonic-gate 					if (strcmp(capstr, infostr) != 0) {
7287c478bd9Sstevel@tonic-gate 						(void) fprintf(stderr,
7297c478bd9Sstevel@tonic-gate 						    "%s: TERM=%s: a function "
7307c478bd9Sstevel@tonic-gate 						    "key for '%s' was "
7317c478bd9Sstevel@tonic-gate 						    "specified with the "
7327c478bd9Sstevel@tonic-gate 						    "value ", progname,
7337c478bd9Sstevel@tonic-gate 						    term_name, capname);
7347c478bd9Sstevel@tonic-gate 						tpr(stderr, capstr);
7357c478bd9Sstevel@tonic-gate 						(void) fprintf(stderr,
7367c478bd9Sstevel@tonic-gate 						    ", but it already has the "
7377c478bd9Sstevel@tonic-gate 						    "value '");
7387c478bd9Sstevel@tonic-gate 						tpr(stderr, infostr);
7397c478bd9Sstevel@tonic-gate 						(void) fprintf(stderr, "'.\n");
7407c478bd9Sstevel@tonic-gate 					}
7417c478bd9Sstevel@tonic-gate 				}
7427c478bd9Sstevel@tonic-gate 				found = 1;
7437c478bd9Sstevel@tonic-gate 			}
7447c478bd9Sstevel@tonic-gate 		}
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 		if (!found) {
7477c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: TERM=%s: the unknown "
7487c478bd9Sstevel@tonic-gate 			    "termcap name '%s' was\n", progname, term_name,
7497c478bd9Sstevel@tonic-gate 			    capname);
7507c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "specified in the 'ko' "
7517c478bd9Sstevel@tonic-gate 			    "termcap capability.\n");
7527c478bd9Sstevel@tonic-gate 		}
7537c478bd9Sstevel@tonic-gate 	}
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate #define	CONTROL(x)		((x) & 037)
7577c478bd9Sstevel@tonic-gate struct
7587c478bd9Sstevel@tonic-gate 	{
7597c478bd9Sstevel@tonic-gate 	char vichar;
7607c478bd9Sstevel@tonic-gate 	char *keyedinfoname;
7617c478bd9Sstevel@tonic-gate 	} ma_map[] = {
7627c478bd9Sstevel@tonic-gate 		CONTROL('J'),	"kcud1",	/* down */
7637c478bd9Sstevel@tonic-gate 		CONTROL('N'),	"kcud1",
7647c478bd9Sstevel@tonic-gate 		'j',		"kcud1",
7657c478bd9Sstevel@tonic-gate 		CONTROL('P'),	"kcuu1",	/* up */
7667c478bd9Sstevel@tonic-gate 		'k',		"kcuu1",
7677c478bd9Sstevel@tonic-gate 		'h',		"kcub1",	/* left */
7687c478bd9Sstevel@tonic-gate 		CONTROL('H'),	"kcub1",
7697c478bd9Sstevel@tonic-gate 		' ',		"kcuf1",	/* right */
7707c478bd9Sstevel@tonic-gate 		'l',		"kcuf1",
7717c478bd9Sstevel@tonic-gate 		'H',		"khome",	/* home */
7727c478bd9Sstevel@tonic-gate 		CONTROL('L'),	"kclr",		/* clear */
7737c478bd9Sstevel@tonic-gate 		0,		0
7747c478bd9Sstevel@tonic-gate 	};
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate /*
7777c478bd9Sstevel@tonic-gate  *  Work with the ma string. This is a list of pairs of characters.
7787c478bd9Sstevel@tonic-gate  *  The first character is the what a function key sends. The second
7797c478bd9Sstevel@tonic-gate  *  character is the equivalent vi function that should be done when
7807c478bd9Sstevel@tonic-gate  *  it receives that character. Note that only function keys that send
7817c478bd9Sstevel@tonic-gate  *  a single character could be defined by this list.
7827c478bd9Sstevel@tonic-gate  */
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate void
prchar(FILE * stream,int c)7857c478bd9Sstevel@tonic-gate prchar(FILE *stream, int c)
7867c478bd9Sstevel@tonic-gate {
7877c478bd9Sstevel@tonic-gate 	char xbuf[2];
7887c478bd9Sstevel@tonic-gate 	xbuf[0] = c;
7897c478bd9Sstevel@tonic-gate 	xbuf[1] = '\0';
7907c478bd9Sstevel@tonic-gate 	(void) fprintf(stream, "%s", iexpand(xbuf));
7917c478bd9Sstevel@tonic-gate }
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate static void
handlema(void)794b5514887Smuffin handlema(void)
7957c478bd9Sstevel@tonic-gate {
7967c478bd9Sstevel@tonic-gate 	char vichar;
7977c478bd9Sstevel@tonic-gate 	char cap[2];
7987c478bd9Sstevel@tonic-gate 	int i, j, found;
7997c478bd9Sstevel@tonic-gate 	char *infostr;
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 	if (verbose > 1)
8027c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "working on termcap ma string.\n");
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate 	if (ostrval[uselevel][cap_ma] == NULL)
8057c478bd9Sstevel@tonic-gate 		return;
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	cap[1] = '\0';
8087c478bd9Sstevel@tonic-gate 	for (i = 0; ostrval[uselevel][cap_ma][i] != '\0'; ) {
8097c478bd9Sstevel@tonic-gate 		/* isolate the key's value */
8107c478bd9Sstevel@tonic-gate 		cap[0] = ostrval[uselevel][cap_ma][i++];
8117c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
8127c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "key value is '");
8137c478bd9Sstevel@tonic-gate 			tpr(trace, cap);
8147c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "'.\n");
8157c478bd9Sstevel@tonic-gate 		}
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][cap_ma][i] == '\0')
8187c478bd9Sstevel@tonic-gate 			break;
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 		/* isolate the vi key name */
8217c478bd9Sstevel@tonic-gate 		vichar = ostrval[uselevel][cap_ma][i++];
8227c478bd9Sstevel@tonic-gate 		if (verbose > 1) {
8237c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "the vi key is '");
8247c478bd9Sstevel@tonic-gate 			prchar(trace, vichar);
8257c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "'.\n");
8267c478bd9Sstevel@tonic-gate 		}
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 		/* match up the vi name in our list */
8297c478bd9Sstevel@tonic-gate 		found = 0;
8307c478bd9Sstevel@tonic-gate 		for (j = 0; !found && ma_map[j].keyedinfoname != NULL; j++) {
8317c478bd9Sstevel@tonic-gate 			if (verbose > 1) {
8327c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "looking at vi "
8337c478bd9Sstevel@tonic-gate 				    "character '");
8347c478bd9Sstevel@tonic-gate 				prchar(trace, ma_map[j].vichar);
8357c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "'\n");
8367c478bd9Sstevel@tonic-gate 			}
8377c478bd9Sstevel@tonic-gate 			if (vichar == ma_map[j].vichar) {
8387c478bd9Sstevel@tonic-gate 				infostr = getinfostr(ma_map[j].keyedinfoname);
8397c478bd9Sstevel@tonic-gate 				if (infostr == NULL)
8407c478bd9Sstevel@tonic-gate 					putstr(ma_map[j].keyedinfoname, cap);
8417c478bd9Sstevel@tonic-gate 				else if (strcmp(cap, infostr) != 0) {
8427c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, "%s: TERM=%s: "
8437c478bd9Sstevel@tonic-gate 					    "the vi character '", progname,
8447c478bd9Sstevel@tonic-gate 					    term_name);
8457c478bd9Sstevel@tonic-gate 					prchar(stderr, vichar);
8467c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr,
8477c478bd9Sstevel@tonic-gate 					    "' (info '%s') has the value '",
8487c478bd9Sstevel@tonic-gate 					    ma_map[j].keyedinfoname);
8497c478bd9Sstevel@tonic-gate 					tpr(stderr, infostr);
8507c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, "', but 'ma' "
8517c478bd9Sstevel@tonic-gate 					    "gives '");
8527c478bd9Sstevel@tonic-gate 					prchar(stderr, cap[0]);
8537c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr, "'.\n");
8547c478bd9Sstevel@tonic-gate 				}
8557c478bd9Sstevel@tonic-gate 				found = 1;
8567c478bd9Sstevel@tonic-gate 			}
8577c478bd9Sstevel@tonic-gate 		}
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate 		if (!found) {
8607c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: the unknown vi key '",
8617c478bd9Sstevel@tonic-gate 			    progname);
8627c478bd9Sstevel@tonic-gate 			prchar(stderr, vichar);
8637c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "' was\n");
8647c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "specified in the 'ma' termcap "
8657c478bd9Sstevel@tonic-gate 			    "capability.\n");
8667c478bd9Sstevel@tonic-gate 		}
8677c478bd9Sstevel@tonic-gate 	}
8687c478bd9Sstevel@tonic-gate }
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate /*
8717c478bd9Sstevel@tonic-gate  *  Many capabilities were defaulted in termcap which must now be explicitly
8727c478bd9Sstevel@tonic-gate  *  given. We'll assume that the defaults are in effect for this terminal.
8737c478bd9Sstevel@tonic-gate  */
8747c478bd9Sstevel@tonic-gate void
adddefaults(void)875b5514887Smuffin adddefaults(void)
8767c478bd9Sstevel@tonic-gate {
8777c478bd9Sstevel@tonic-gate 	char *cap;
8787c478bd9Sstevel@tonic-gate 	int sg;
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 	if (verbose > 1)
8817c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "assigning defaults.\n");
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 	/* cr was assumed to be ^M, unless nc was given, */
8847c478bd9Sstevel@tonic-gate 	/* which meant it could not be done. */
8857c478bd9Sstevel@tonic-gate 	/* Also, xr meant that ^M acted strangely. */
8867c478bd9Sstevel@tonic-gate 	if ((getinfostr("cr") == NULL) && !oboolval[uselevel][cap_nc] &&
8877c478bd9Sstevel@tonic-gate 	    !oboolval[uselevel][cap_xr])
8887c478bd9Sstevel@tonic-gate 		if ((cap = getcapstr("cr")) == NULL)
8897c478bd9Sstevel@tonic-gate 			putstr("cr", "\r");
8907c478bd9Sstevel@tonic-gate 		else
8917c478bd9Sstevel@tonic-gate 			putstr("cr", cap);
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate 	/* cursor down was assumed to be ^J if not specified by nl */
8947c478bd9Sstevel@tonic-gate 	if (getinfostr("cud1") == NULL)
8957c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][cap_nl] != NULL)
8967c478bd9Sstevel@tonic-gate 			putstr("cud1", ostrval[uselevel][cap_nl]);
8977c478bd9Sstevel@tonic-gate 		else
8987c478bd9Sstevel@tonic-gate 			putstr("cud1", "\n");
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 	/* ind was assumed to be ^J, unless ns was given, */
9017c478bd9Sstevel@tonic-gate 	/* which meant it could not be done. */
9027c478bd9Sstevel@tonic-gate 	if ((getinfostr("ind") == NULL) && !oboolval[uselevel][cap_ns])
9037c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][cap_nl] == NULL)
9047c478bd9Sstevel@tonic-gate 			putstr("ind", "\n");
9057c478bd9Sstevel@tonic-gate 		else
9067c478bd9Sstevel@tonic-gate 			putstr("ind", ostrval[uselevel][cap_nl]);
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate 	/* bel was assumed to be ^G */
9097c478bd9Sstevel@tonic-gate 	if (getinfostr("bel") == NULL)
9107c478bd9Sstevel@tonic-gate 		putstr("bel", "\07");
9117c478bd9Sstevel@tonic-gate 
9127c478bd9Sstevel@tonic-gate 	/* if bs, then could do backspacing, */
9137c478bd9Sstevel@tonic-gate 	/* with value of bc, default of ^H */
9147c478bd9Sstevel@tonic-gate 	if ((getinfostr("cub1") == NULL) && oboolval[uselevel][cap_bs])
9157c478bd9Sstevel@tonic-gate 		if (ostrval[uselevel][cap_bc] != NULL)
9167c478bd9Sstevel@tonic-gate 			putstr("cub1", ostrval[uselevel][cap_bc]);
9177c478bd9Sstevel@tonic-gate 		else
9187c478bd9Sstevel@tonic-gate 			putstr("cub1", "\b");
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 	/* default xon to true */
9217c478bd9Sstevel@tonic-gate 	if (!otgetflag("xo"))
9227c478bd9Sstevel@tonic-gate 		putbool("xon", 1);
9237c478bd9Sstevel@tonic-gate 
9247c478bd9Sstevel@tonic-gate 	/* if pt, then hardware tabs are allowed, */
9257c478bd9Sstevel@tonic-gate 	/* with value of ta, default of ^I */
9267c478bd9Sstevel@tonic-gate 	if ((getinfostr("ht") == NULL) && oboolval[uselevel][cap_pt])
9277c478bd9Sstevel@tonic-gate 		if ((cap = getcapstr("ta")) == NULL)
9287c478bd9Sstevel@tonic-gate 			putstr("ht", "\t");
9297c478bd9Sstevel@tonic-gate 		else
9307c478bd9Sstevel@tonic-gate 			putstr("ht", cap);
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	/* The dX numbers are now stored as padding */
9337c478bd9Sstevel@tonic-gate 	/* in the appropriate terminfo string. */
9347c478bd9Sstevel@tonic-gate 	addpadding(onumval[uselevel][cap_dB], "cub1");
9357c478bd9Sstevel@tonic-gate 	addpadding(onumval[uselevel][cap_dC], "cr");
9367c478bd9Sstevel@tonic-gate 	addpadding(onumval[uselevel][cap_dF], "ff");
9377c478bd9Sstevel@tonic-gate 	addpadding(onumval[uselevel][cap_dN], "cud1");
9387c478bd9Sstevel@tonic-gate 	addpadding(onumval[uselevel][cap_dT], "ht");
9397c478bd9Sstevel@tonic-gate 
9407c478bd9Sstevel@tonic-gate 	/* The ug and sg caps were essentially identical, */
9417c478bd9Sstevel@tonic-gate 	/* so ug almost never got used. We set sg from ug */
9427c478bd9Sstevel@tonic-gate 	/* if it hasn't already been set. */
9437c478bd9Sstevel@tonic-gate 	if (onumval[uselevel][cap_ug] >= 0 && (sg = otgetnum("sg")) < 0)
9447c478bd9Sstevel@tonic-gate 		putnum("xmc", onumval[uselevel][cap_ug]);
9457c478bd9Sstevel@tonic-gate 	else if ((onumval[uselevel][cap_ug] >= 0) &&
9467c478bd9Sstevel@tonic-gate 	    (sg >= 0) && (onumval[uselevel][cap_ug] != sg))
9477c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
9487c478bd9Sstevel@tonic-gate 		    "%s: TERM=%s: Warning: termcap sg and ug had different "
9497c478bd9Sstevel@tonic-gate 		    "values (%d<->%d).\n", progname, term_name, sg,
9507c478bd9Sstevel@tonic-gate 		    onumval[uselevel][cap_ug]);
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 	/* The MT boolean was never really part of termcap, */
9537c478bd9Sstevel@tonic-gate 	/* but we can check for it anyways. */
9547c478bd9Sstevel@tonic-gate 	if (oboolval[uselevel][cap_MT] && !otgetflag("km"))
9557c478bd9Sstevel@tonic-gate 		putbool("km", 1);
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	/* the rs string was renamed r2 (info rs2) */
9587c478bd9Sstevel@tonic-gate 	if ((ostrval[uselevel][cap_rs] != NULL) &&
959*8f32bfdcSToomas Soome 	    (ostrval[uselevel][cap_rs][0] != '\0'))
9607c478bd9Sstevel@tonic-gate 		putstr("rs2", ostrval[uselevel][cap_rs]);
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 	handleko();
9637c478bd9Sstevel@tonic-gate 	handlema();
9647c478bd9Sstevel@tonic-gate }
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate #define	caddch(x) *to++ = (x)
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate /*
9697c478bd9Sstevel@tonic-gate  *  add the string to the string table
9707c478bd9Sstevel@tonic-gate  */
971b5514887Smuffin char *
caddstr(char * to,char * str)972b5514887Smuffin caddstr(char *to, char *str)
9737c478bd9Sstevel@tonic-gate {
9747c478bd9Sstevel@tonic-gate 	while (*str)
9757c478bd9Sstevel@tonic-gate 		*to++ = *str++;
9767c478bd9Sstevel@tonic-gate 	return (to);
9777c478bd9Sstevel@tonic-gate }
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate /* If there is no padding info or parmed strings, */
9807c478bd9Sstevel@tonic-gate /* then we do not need to copy the string. */
9817c478bd9Sstevel@tonic-gate int
needscopying(char * string)9827c478bd9Sstevel@tonic-gate needscopying(char *string)
9837c478bd9Sstevel@tonic-gate {
9847c478bd9Sstevel@tonic-gate 	/* any string at all? */
9857c478bd9Sstevel@tonic-gate 	if (string == NULL)
9867c478bd9Sstevel@tonic-gate 		return (0);
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate 	/* any padding info? */
9897c478bd9Sstevel@tonic-gate 	if (ispadchar(*string))
9907c478bd9Sstevel@tonic-gate 		return (1);
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate 	/* any parmed info? */
9937c478bd9Sstevel@tonic-gate 	while (*string)
9947c478bd9Sstevel@tonic-gate 		if (*string++ == '%')
9957c478bd9Sstevel@tonic-gate 			return (1);
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	return (0);
9987c478bd9Sstevel@tonic-gate }
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate /*
10017c478bd9Sstevel@tonic-gate  *  Certain manipulations of the stack require strange manipulations of the
10027c478bd9Sstevel@tonic-gate  *  values that are on the stack. To handle these, we save the values of the
10037c478bd9Sstevel@tonic-gate  *  parameters in registers at the very beginning and make the changes in
10047c478bd9Sstevel@tonic-gate  *  the registers. We don't want to do this in the general case because of the
10057c478bd9Sstevel@tonic-gate  *  potential performance loss.
10067c478bd9Sstevel@tonic-gate  */
10077c478bd9Sstevel@tonic-gate int
fancycap(char * string)10087c478bd9Sstevel@tonic-gate fancycap(char *string)
10097c478bd9Sstevel@tonic-gate {
10107c478bd9Sstevel@tonic-gate 	int parmset = 0;
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 	while (*string)
10137c478bd9Sstevel@tonic-gate 		if (*string++ == '%') {
10147c478bd9Sstevel@tonic-gate 			switch (*string) {
10157c478bd9Sstevel@tonic-gate 				/* These manipulate just the top value on */
10167c478bd9Sstevel@tonic-gate 				/* the stack, so we only have to do */
10177c478bd9Sstevel@tonic-gate 				/* something strange if a %r follows. */
10187c478bd9Sstevel@tonic-gate 				case '>': case 'B': case 'D':
10197c478bd9Sstevel@tonic-gate 					parmset = 1;
10207c478bd9Sstevel@tonic-gate 					break;
10217c478bd9Sstevel@tonic-gate 				/* If the parm has already been been */
10227c478bd9Sstevel@tonic-gate 				/* pushed onto the stack by %>, then we */
10237c478bd9Sstevel@tonic-gate 				/* can not reverse the parms and must get */
10247c478bd9Sstevel@tonic-gate 				/* them from the registers. */
10257c478bd9Sstevel@tonic-gate 				case 'r':
10267c478bd9Sstevel@tonic-gate 					if (parmset)
10277c478bd9Sstevel@tonic-gate 						return (1);
10287c478bd9Sstevel@tonic-gate 					break;
10297c478bd9Sstevel@tonic-gate 				/* This manipulates both parameters, so we */
10307c478bd9Sstevel@tonic-gate 				/* cannot just do one and leave the value */
10317c478bd9Sstevel@tonic-gate 				/* on the stack like we can with %>, */
10327c478bd9Sstevel@tonic-gate 				/* %B or %D. */
10337c478bd9Sstevel@tonic-gate 				case 'n':
10347c478bd9Sstevel@tonic-gate 					return (1);
10357c478bd9Sstevel@tonic-gate 			}
10367c478bd9Sstevel@tonic-gate 			string++;
10377c478bd9Sstevel@tonic-gate 		}
1038e673284eSToomas Soome 	return (0);
10397c478bd9Sstevel@tonic-gate }
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate /*
10427c478bd9Sstevel@tonic-gate  *  Change old style of doing calculations to the new stack style.
10437c478bd9Sstevel@tonic-gate  *  Note that this will not necessarily produce the most efficient string,
10447c478bd9Sstevel@tonic-gate  *  but it will work.
10457c478bd9Sstevel@tonic-gate  */
10467c478bd9Sstevel@tonic-gate void
changecalculations()10477c478bd9Sstevel@tonic-gate changecalculations()
10487c478bd9Sstevel@tonic-gate {
10497c478bd9Sstevel@tonic-gate 	int i, currentparm;
10507c478bd9Sstevel@tonic-gate 	char *from, *to = nextstring;
10517c478bd9Sstevel@tonic-gate 	int ch;
10527c478bd9Sstevel@tonic-gate 	int parmset, parmsaved;
10537c478bd9Sstevel@tonic-gate 	char padding[100], *saveto;
10547c478bd9Sstevel@tonic-gate 
10557c478bd9Sstevel@tonic-gate 	for (i = 0; strnames[i]; i++)
10567c478bd9Sstevel@tonic-gate 		if (needscopying(strval[uselevel][i])) {
10577c478bd9Sstevel@tonic-gate 			if (verbose) {
10587c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, "%s needs copying, "
10597c478bd9Sstevel@tonic-gate 				    "was:", strnames [i]);
10607c478bd9Sstevel@tonic-gate 				tpr(trace, strval[uselevel][i]);
10617c478bd9Sstevel@tonic-gate 				(void) fprintf(trace, ".\n");
10627c478bd9Sstevel@tonic-gate 			}
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate 			from = strval[uselevel][i];
10657c478bd9Sstevel@tonic-gate 			strval[uselevel][i] = to;
10667c478bd9Sstevel@tonic-gate 			currentparm = 1;
10677c478bd9Sstevel@tonic-gate 			parmset = 0;
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 	    /* Handle padding information. Save it so that it can be */
10707c478bd9Sstevel@tonic-gate 	    /* placed at the end of the string where it should */
10717c478bd9Sstevel@tonic-gate 	    /* have been in the first place. */
10727c478bd9Sstevel@tonic-gate 			if (ispadchar(*from)) {
10737c478bd9Sstevel@tonic-gate 				saveto = to;
10747c478bd9Sstevel@tonic-gate 				to = padding;
10757c478bd9Sstevel@tonic-gate 				to = caddstr(to, "$<");
10767c478bd9Sstevel@tonic-gate 				while (isdigit(*from) || *from == '.')
10777c478bd9Sstevel@tonic-gate 					caddch(*from++);
10787c478bd9Sstevel@tonic-gate 				if (*from == '*')
10797c478bd9Sstevel@tonic-gate 					caddch(*from++);
10807c478bd9Sstevel@tonic-gate 				caddch('>');
10817c478bd9Sstevel@tonic-gate 				caddch('\0');
10827c478bd9Sstevel@tonic-gate 				to = saveto;
10837c478bd9Sstevel@tonic-gate 			} else
10847c478bd9Sstevel@tonic-gate 				padding[0] = '\0';
10857c478bd9Sstevel@tonic-gate 
10867c478bd9Sstevel@tonic-gate 			if (fancycap(from)) {
10877c478bd9Sstevel@tonic-gate 				to = caddstr(to, "%p1%Pa%p2%Pb");
10887c478bd9Sstevel@tonic-gate 				parmsaved = 1;
10897c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
10907c478bd9Sstevel@tonic-gate 				    "%s: TERM=%s: Warning: the string "
10917c478bd9Sstevel@tonic-gate 				    "produced for '%s' may be inefficient.\n",
10927c478bd9Sstevel@tonic-gate 				    progname, term_name, strnames[i]);
10937c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "It should be "
10947c478bd9Sstevel@tonic-gate 				    "looked at by hand.\n");
10957c478bd9Sstevel@tonic-gate 			} else
10967c478bd9Sstevel@tonic-gate 				parmsaved = 0;
10977c478bd9Sstevel@tonic-gate 
10987c478bd9Sstevel@tonic-gate 			while ((ch = *from++) != '\0')
10997c478bd9Sstevel@tonic-gate 				if (ch != '%')
11007c478bd9Sstevel@tonic-gate 					caddch(ch);
11017c478bd9Sstevel@tonic-gate 				else
11027c478bd9Sstevel@tonic-gate 				switch (ch = *from++) {
11037c478bd9Sstevel@tonic-gate 					case '.':	/* %.  -> %p1%c */
11047c478bd9Sstevel@tonic-gate 					case 'd':	/* %d  -> %p1%d */
11057c478bd9Sstevel@tonic-gate 					case '2':	/* %2  -> %p1%2.2d */
11067c478bd9Sstevel@tonic-gate 					case '3':	/* %3  -> %p1%3.3d */
11077c478bd9Sstevel@tonic-gate 					case '+':
11087c478bd9Sstevel@tonic-gate 					/* %+x -> %p1%'x'%+%c */
11097c478bd9Sstevel@tonic-gate 
11107c478bd9Sstevel@tonic-gate 					case '>':
11117c478bd9Sstevel@tonic-gate 					/* %>xy -> %p1%Pc%?%'x'%> */
11127c478bd9Sstevel@tonic-gate 					/* %t%gc%'y'%+ */
11137c478bd9Sstevel@tonic-gate 					/* if current value > x, then add y. */
11147c478bd9Sstevel@tonic-gate 					/* No output. */
11157c478bd9Sstevel@tonic-gate 
11167c478bd9Sstevel@tonic-gate 					case 'B':
11177c478bd9Sstevel@tonic-gate 					/* %B: BCD */
11187c478bd9Sstevel@tonic-gate 					/* (16*(x/10))+(x%10) */
11197c478bd9Sstevel@tonic-gate 					/* No output. */
11207c478bd9Sstevel@tonic-gate 					/* (Adds Regent 100) */
11217c478bd9Sstevel@tonic-gate 
11227c478bd9Sstevel@tonic-gate 					case 'D':
11237c478bd9Sstevel@tonic-gate 					/* %D: Reverse coding */
11247c478bd9Sstevel@tonic-gate 					/* (x-2*(x%16)) */
11257c478bd9Sstevel@tonic-gate 					/* No output. */
11267c478bd9Sstevel@tonic-gate 					/* (Delta Data) */
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 					if (!parmset)
11297c478bd9Sstevel@tonic-gate 						if (parmsaved) {
11307c478bd9Sstevel@tonic-gate 							to = caddstr(to, "%g");
11317c478bd9Sstevel@tonic-gate 							if (currentparm == 1)
11327c478bd9Sstevel@tonic-gate 								caddch('a');
11337c478bd9Sstevel@tonic-gate 							else
11347c478bd9Sstevel@tonic-gate 								caddch('b');
11357c478bd9Sstevel@tonic-gate 						} else {
11367c478bd9Sstevel@tonic-gate 							to = caddstr(to, "%p");
11377c478bd9Sstevel@tonic-gate 							if (currentparm == 1)
11387c478bd9Sstevel@tonic-gate 								caddch('1');
11397c478bd9Sstevel@tonic-gate 							else
11407c478bd9Sstevel@tonic-gate 								caddch('2');
11417c478bd9Sstevel@tonic-gate 						}
11427c478bd9Sstevel@tonic-gate 					currentparm = 3 - currentparm;
11437c478bd9Sstevel@tonic-gate 					parmset = 0;
11447c478bd9Sstevel@tonic-gate 					switch (ch) {
11457c478bd9Sstevel@tonic-gate 						case '.':
11467c478bd9Sstevel@tonic-gate 							to = caddstr(to, "%c");
11477c478bd9Sstevel@tonic-gate 							break;
11487c478bd9Sstevel@tonic-gate 						case 'd':
11497c478bd9Sstevel@tonic-gate 							to = caddstr(to, "%d");
11507c478bd9Sstevel@tonic-gate 							break;
11517c478bd9Sstevel@tonic-gate 						case '2': case '3':
11527c478bd9Sstevel@tonic-gate #ifdef USG	/* Vr2==USG, Vr3==SYSV. Use %02d for Vr2, %2.2d for Vr3 */
11537c478bd9Sstevel@tonic-gate 							caddch('%');
11547c478bd9Sstevel@tonic-gate 							caddch('0');
11557c478bd9Sstevel@tonic-gate #else
11567c478bd9Sstevel@tonic-gate 							caddch('%');
11577c478bd9Sstevel@tonic-gate 							caddch(ch);
11587c478bd9Sstevel@tonic-gate 							caddch('.');
11597c478bd9Sstevel@tonic-gate #endif /* USG vs. SYSV */
11607c478bd9Sstevel@tonic-gate 							caddch(ch);
11617c478bd9Sstevel@tonic-gate 							caddch('d');
11627c478bd9Sstevel@tonic-gate 							break;
11637c478bd9Sstevel@tonic-gate 						case '+':
11647c478bd9Sstevel@tonic-gate 							to = caddstr(to, "%'");
11657c478bd9Sstevel@tonic-gate 							caddch(*from++);
11667c478bd9Sstevel@tonic-gate 							to = caddstr(to,
11677c478bd9Sstevel@tonic-gate 							    "'%+%c");
11687c478bd9Sstevel@tonic-gate 							break;
11697c478bd9Sstevel@tonic-gate 						case '>':
11707c478bd9Sstevel@tonic-gate 							to = caddstr(to,
11717c478bd9Sstevel@tonic-gate 							    "%Pc%?%'");
11727c478bd9Sstevel@tonic-gate 							caddch(*from++);
11737c478bd9Sstevel@tonic-gate 							to = caddstr(to,
11747c478bd9Sstevel@tonic-gate 							    "'%>%t%gc%'");
11757c478bd9Sstevel@tonic-gate 							caddch(*from++);
11767c478bd9Sstevel@tonic-gate 							to = caddstr(to,
11777c478bd9Sstevel@tonic-gate 							    "'%+");
11787c478bd9Sstevel@tonic-gate 							parmset = 1;
11797c478bd9Sstevel@tonic-gate 							break;
11807c478bd9Sstevel@tonic-gate 						case 'B':
11817c478bd9Sstevel@tonic-gate 							to = caddstr(to,
11827c478bd9Sstevel@tonic-gate "%Pc%gc%{10}%/%{16}%*%gc%{10}%m%+");
11837c478bd9Sstevel@tonic-gate 						parmset = 1;
11847c478bd9Sstevel@tonic-gate 						break;
11857c478bd9Sstevel@tonic-gate 
11867c478bd9Sstevel@tonic-gate 						case 'D':
11877c478bd9Sstevel@tonic-gate 							to = caddstr(to,
11887c478bd9Sstevel@tonic-gate "%Pc%gc%gc%{16}%m%{2}%*%-");
11897c478bd9Sstevel@tonic-gate 							parmset = 1;
11907c478bd9Sstevel@tonic-gate 							break;
11917c478bd9Sstevel@tonic-gate 					}
11927c478bd9Sstevel@tonic-gate 					break;
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate 					/* %r reverses current parameter */
11957c478bd9Sstevel@tonic-gate 					case 'r':
11967c478bd9Sstevel@tonic-gate 						currentparm = 3 - currentparm;
11977c478bd9Sstevel@tonic-gate 						break;
11987c478bd9Sstevel@tonic-gate 
11997c478bd9Sstevel@tonic-gate 					/* %n: exclusive-or row AND column */
12007c478bd9Sstevel@tonic-gate 					/* with 0140, 96 decimal, no output */
12017c478bd9Sstevel@tonic-gate 					/* (Datamedia 2500, Exidy Sorceror) */
12027c478bd9Sstevel@tonic-gate 					case 'n':
12037c478bd9Sstevel@tonic-gate 						to = caddstr(to,
12047c478bd9Sstevel@tonic-gate 						    "%ga%'`'%^%Pa");
12057c478bd9Sstevel@tonic-gate 						to = caddstr(to,
12067c478bd9Sstevel@tonic-gate 						    "%gb%'`'%^%Pb");
12077c478bd9Sstevel@tonic-gate 						break;
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 					/* assume %x means %x */
12107c478bd9Sstevel@tonic-gate 					/* this includes %i and %% */
12117c478bd9Sstevel@tonic-gate 					default:
12127c478bd9Sstevel@tonic-gate 						caddch('%');
12137c478bd9Sstevel@tonic-gate 						caddch(ch);
12147c478bd9Sstevel@tonic-gate 				}
12157c478bd9Sstevel@tonic-gate 		to = caddstr(to, padding);
12167c478bd9Sstevel@tonic-gate 		caddch('\0');
12177c478bd9Sstevel@tonic-gate 
12187c478bd9Sstevel@tonic-gate 		if (verbose) {
12197c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "and has become:");
12207c478bd9Sstevel@tonic-gate 			tpr(trace, strval[uselevel][i]);
12217c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, ".\n");
12227c478bd9Sstevel@tonic-gate 		}
12237c478bd9Sstevel@tonic-gate 	}
12247c478bd9Sstevel@tonic-gate 	nextstring = to;
12257c478bd9Sstevel@tonic-gate }
12267c478bd9Sstevel@tonic-gate 
12277c478bd9Sstevel@tonic-gate static void
print_no_use_entry(void)1228b5514887Smuffin print_no_use_entry(void)
12297c478bd9Sstevel@tonic-gate {
12307c478bd9Sstevel@tonic-gate 	int i;
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 	pr_heading("", buflongname);
12337c478bd9Sstevel@tonic-gate 	pr_bheading();
12347c478bd9Sstevel@tonic-gate 
12357c478bd9Sstevel@tonic-gate 	for (i = 0; boolcodes[i]; i++)
12367c478bd9Sstevel@tonic-gate 		if (boolval[0][i])
12377c478bd9Sstevel@tonic-gate 			pr_boolean(boolnames[i], (char *)0, (char *)0, 1);
12387c478bd9Sstevel@tonic-gate 
12397c478bd9Sstevel@tonic-gate 	pr_bfooting();
12407c478bd9Sstevel@tonic-gate 	pr_sheading();
12417c478bd9Sstevel@tonic-gate 
12427c478bd9Sstevel@tonic-gate 	for (i = 0; numcodes[i]; i++)
12437c478bd9Sstevel@tonic-gate 		if (numval[0][i] > -1)
12447c478bd9Sstevel@tonic-gate 			pr_number(numnames[i], (char *)0, (char *)0,
12457c478bd9Sstevel@tonic-gate 			    numval[0][i]);
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	pr_nfooting();
12487c478bd9Sstevel@tonic-gate 	pr_sheading();
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 	for (i = 0; strcodes[i]; i++)
12517c478bd9Sstevel@tonic-gate 		if (strval[0][i])
12527c478bd9Sstevel@tonic-gate 			pr_string(strnames[i], (char *)0, (char *)0,
12537c478bd9Sstevel@tonic-gate 			    strval[0][i]);
12547c478bd9Sstevel@tonic-gate 
12557c478bd9Sstevel@tonic-gate 	pr_sfooting();
12567c478bd9Sstevel@tonic-gate }
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate static void
print_use_entry(char * usename)12597c478bd9Sstevel@tonic-gate print_use_entry(char *usename)
12607c478bd9Sstevel@tonic-gate {
12617c478bd9Sstevel@tonic-gate 	int i;
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate 	pr_heading("", buflongname);
12647c478bd9Sstevel@tonic-gate 	pr_bheading();
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate 	for (i = 0; boolcodes[i]; i++)
12677c478bd9Sstevel@tonic-gate 		if (boolval[0][i] && !boolval[1][i])
12687c478bd9Sstevel@tonic-gate 			pr_boolean(boolnames[i], (char *)0, (char *)0, 1);
12697c478bd9Sstevel@tonic-gate 		else if (!boolval[0][i] && boolval[1][i])
12707c478bd9Sstevel@tonic-gate 			pr_boolean(boolnames[i], (char *)0, (char *)0, -1);
12717c478bd9Sstevel@tonic-gate 
12727c478bd9Sstevel@tonic-gate 	pr_bfooting();
12737c478bd9Sstevel@tonic-gate 	pr_nheading();
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate 	for (i = 0; numcodes[i]; i++)
12767c478bd9Sstevel@tonic-gate 		if ((numval[0][i] > -1) && (numval[0][i] != numval[1][i]))
12777c478bd9Sstevel@tonic-gate 			pr_number(numnames[i], (char *)0, (char *)0,
12787c478bd9Sstevel@tonic-gate 			    numval[0][i]);
12797c478bd9Sstevel@tonic-gate 		else if ((numval [0] [i] == -1) && (numval [1] [i] > -1))
12807c478bd9Sstevel@tonic-gate 			pr_number(numnames[i], (char *)0, (char *)0, -1);
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 	pr_nfooting();
12837c478bd9Sstevel@tonic-gate 	pr_sheading();
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate 	for (i = 0; strcodes[i]; i++)
12867c478bd9Sstevel@tonic-gate 		/* print out str[0] if: */
12877c478bd9Sstevel@tonic-gate 		/* str[0] != NULL and str[1] == NULL, or str[0] != str[1] */
12887c478bd9Sstevel@tonic-gate 		if (strval[0][i] && ((strval[1][i] == NULL) ||
12897c478bd9Sstevel@tonic-gate 		    (strcmp(strval[0][i], strval[1][i]) != 0)))
12907c478bd9Sstevel@tonic-gate 				pr_string(strnames[i], (char *)0, (char *)0,
12917c478bd9Sstevel@tonic-gate 				    strval[0][i]);
12927c478bd9Sstevel@tonic-gate 		/* print out @ if str[0] == NULL and str[1] != NULL */
12937c478bd9Sstevel@tonic-gate 		else if (strval[0][i] == NULL && strval[1][i] != NULL)
12947c478bd9Sstevel@tonic-gate 			pr_string(strnames[i], (char *)0, (char *)0,
12957c478bd9Sstevel@tonic-gate 			    (char *)0);
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	pr_sfooting();
12987c478bd9Sstevel@tonic-gate 
12997c478bd9Sstevel@tonic-gate 	(void) printf("\tuse=%s,\n", usename);
13007c478bd9Sstevel@tonic-gate }
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate static void
captoinfo(void)1303b5514887Smuffin captoinfo(void)
13047c478bd9Sstevel@tonic-gate {
13057c478bd9Sstevel@tonic-gate 	char usename[512];
13067c478bd9Sstevel@tonic-gate 	char *sterm_name;
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate 	if (term_name == NULL) {
13097c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: Null term_name given.\n",
13107c478bd9Sstevel@tonic-gate 		    progname);
13117c478bd9Sstevel@tonic-gate 		return;
13127c478bd9Sstevel@tonic-gate 	}
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate 	if (verbose)
13157c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "changing cap to info, TERM=%s.\n",
13167c478bd9Sstevel@tonic-gate 		    term_name);
13177c478bd9Sstevel@tonic-gate 
13187c478bd9Sstevel@tonic-gate 	uselevel = 0;
13197c478bd9Sstevel@tonic-gate 	if (filltables() == 0)
13207c478bd9Sstevel@tonic-gate 		return;
13217c478bd9Sstevel@tonic-gate 	getlongname();
13227c478bd9Sstevel@tonic-gate 	adddefaults();
13237c478bd9Sstevel@tonic-gate 	changecalculations();
13247c478bd9Sstevel@tonic-gate 	if (TLHtcfound != 0) {
13257c478bd9Sstevel@tonic-gate 		uselevel = 1;
13267c478bd9Sstevel@tonic-gate 		if (verbose)
13277c478bd9Sstevel@tonic-gate 			(void) fprintf(trace, "use= found, %s uses %s.\n",
13287c478bd9Sstevel@tonic-gate 			    term_name, TLHtcname);
13297c478bd9Sstevel@tonic-gate 		(void) strcpy(usename, TLHtcname);
13307c478bd9Sstevel@tonic-gate 		sterm_name = term_name;
13317c478bd9Sstevel@tonic-gate 		term_name = usename;
13327c478bd9Sstevel@tonic-gate 		if (filltables() == 0)
13337c478bd9Sstevel@tonic-gate 			return;
13347c478bd9Sstevel@tonic-gate 		adddefaults();
13357c478bd9Sstevel@tonic-gate 		changecalculations();
13367c478bd9Sstevel@tonic-gate 		term_name = sterm_name;
13377c478bd9Sstevel@tonic-gate 		print_use_entry(usename);
13387c478bd9Sstevel@tonic-gate 	} else
13397c478bd9Sstevel@tonic-gate 		print_no_use_entry();
13407c478bd9Sstevel@tonic-gate }
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate 
13437c478bd9Sstevel@tonic-gate #include <signal.h>   /* use this file to determine if this is SVR4.0 system */
13447c478bd9Sstevel@tonic-gate 
13457c478bd9Sstevel@tonic-gate static void
use_etc_termcap(void)1346b5514887Smuffin use_etc_termcap(void)
13477c478bd9Sstevel@tonic-gate {
13487c478bd9Sstevel@tonic-gate 	if (verbose)
13497c478bd9Sstevel@tonic-gate #ifdef  SIGSTOP
13507c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "reading from /usr/share/lib/termcap\n");
13517c478bd9Sstevel@tonic-gate #else   /* SIGSTOP */
13527c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "reading from /etc/termcap\n");
13537c478bd9Sstevel@tonic-gate #endif  /* SIGSTOP */
13547c478bd9Sstevel@tonic-gate 		term_name = getenv("TERM");
13557c478bd9Sstevel@tonic-gate 		captoinfo();
13567c478bd9Sstevel@tonic-gate }
13577c478bd9Sstevel@tonic-gate 
13587c478bd9Sstevel@tonic-gate static void
initdirname(void)1359b5514887Smuffin initdirname(void)
13607c478bd9Sstevel@tonic-gate {
13617c478bd9Sstevel@tonic-gate #if defined(SYSV) || defined(USG)  /* handle both Sys Vr2 and Vr3 curses */
13627c478bd9Sstevel@tonic-gate 	(void) getcwd(dirname, BUFSIZ-2);
13637c478bd9Sstevel@tonic-gate #else
13647c478bd9Sstevel@tonic-gate 	(void) getwd(dirname);
13657c478bd9Sstevel@tonic-gate #endif /* SYSV || USG */
13667c478bd9Sstevel@tonic-gate 	if (verbose)
13677c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "current directory name=%s.\n", dirname);
1368e673284eSToomas Soome 	environ = newenviron;
13697c478bd9Sstevel@tonic-gate }
13707c478bd9Sstevel@tonic-gate 
13717c478bd9Sstevel@tonic-gate static void
setfilename(char * capfile)13727c478bd9Sstevel@tonic-gate setfilename(char *capfile)
13737c478bd9Sstevel@tonic-gate {
13747c478bd9Sstevel@tonic-gate 	if (capfile [0] == '/')
13757c478bd9Sstevel@tonic-gate 		(void) snprintf(TERMCAP, sizeof (TERMCAP),
13767c478bd9Sstevel@tonic-gate 		    "TERMCAP=%s", capfile);
13777c478bd9Sstevel@tonic-gate 	else
13787c478bd9Sstevel@tonic-gate 		(void) snprintf(TERMCAP, sizeof (TERMCAP),
13797c478bd9Sstevel@tonic-gate 		    "TERMCAP=%s/%s", dirname, capfile);
13807c478bd9Sstevel@tonic-gate 	if (verbose)
13817c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "setting the environment for %s.\n",
13827c478bd9Sstevel@tonic-gate 		    TERMCAP);
13837c478bd9Sstevel@tonic-gate }
13847c478bd9Sstevel@tonic-gate 
13857c478bd9Sstevel@tonic-gate static void
setterm_name(void)1386b5514887Smuffin setterm_name(void)
13877c478bd9Sstevel@tonic-gate {
13887c478bd9Sstevel@tonic-gate 	if (verbose)
13897c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "setting the environment "
13907c478bd9Sstevel@tonic-gate 		    "for TERM=%s.\n", term_name);
13917c478bd9Sstevel@tonic-gate 	(void) snprintf(TERM, sizeof (TERM), "TERM=%s", term_name);
13927c478bd9Sstevel@tonic-gate }
13937c478bd9Sstevel@tonic-gate 
13947c478bd9Sstevel@tonic-gate /* Look at the current line to see if it is a list of names. */
13957c478bd9Sstevel@tonic-gate /* If it is, return the first name in the list, else NULL. */
13967c478bd9Sstevel@tonic-gate /* As a side-effect, comment lines and blank lines */
13977c478bd9Sstevel@tonic-gate /* are copied to standard output. */
13987c478bd9Sstevel@tonic-gate 
1399b5514887Smuffin char *
getterm_name(char * line)1400b5514887Smuffin getterm_name(char *line)
14017c478bd9Sstevel@tonic-gate {
14027c478bd9Sstevel@tonic-gate 	char *lineptr = line;
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 	if (verbose)
14057c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "extracting name from '%s'.\n", line);
14067c478bd9Sstevel@tonic-gate 
14077c478bd9Sstevel@tonic-gate 	/* Copy comment lines out. */
14087c478bd9Sstevel@tonic-gate 	if (*line == '#') {
14097c478bd9Sstevel@tonic-gate 		if (copycomments)
14107c478bd9Sstevel@tonic-gate 			(void) printf("%s", line);
14117c478bd9Sstevel@tonic-gate 	}
14127c478bd9Sstevel@tonic-gate 	/* Blank lines get copied too. */
14137c478bd9Sstevel@tonic-gate 	else if (isspace (*line)) {
14147c478bd9Sstevel@tonic-gate 		if (copycomments) {
14157c478bd9Sstevel@tonic-gate 			for (; *lineptr; lineptr++)
14167c478bd9Sstevel@tonic-gate 				if (!isspace(*lineptr))
14177c478bd9Sstevel@tonic-gate 					break;
14187c478bd9Sstevel@tonic-gate 			if (*lineptr == '\0')
14197c478bd9Sstevel@tonic-gate 			(void) printf("\n");
14207c478bd9Sstevel@tonic-gate 		}
14217c478bd9Sstevel@tonic-gate 	}
14227c478bd9Sstevel@tonic-gate 	else
14237c478bd9Sstevel@tonic-gate 		for (; *lineptr; lineptr++)
14247c478bd9Sstevel@tonic-gate 			if (*lineptr == '|' || *lineptr == ':') {
14257c478bd9Sstevel@tonic-gate 				*lineptr = '\0';
14267c478bd9Sstevel@tonic-gate 				if (verbose)
14277c478bd9Sstevel@tonic-gate 					(void) fprintf(trace,
14287c478bd9Sstevel@tonic-gate 					    "returning %s.\n", line);
14297c478bd9Sstevel@tonic-gate 				return (line);
14307c478bd9Sstevel@tonic-gate 			}
14317c478bd9Sstevel@tonic-gate 	if (verbose)
14327c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "returning NULL.\n");
14337c478bd9Sstevel@tonic-gate 	return (NULL);
14347c478bd9Sstevel@tonic-gate }
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate static void
use_file(char * filename)14377c478bd9Sstevel@tonic-gate use_file(char *filename)
14387c478bd9Sstevel@tonic-gate {
14397c478bd9Sstevel@tonic-gate 	FILE *termfile;
14407c478bd9Sstevel@tonic-gate 	char buffer[BUFSIZ];
14417c478bd9Sstevel@tonic-gate 
14427c478bd9Sstevel@tonic-gate 	if (verbose)
14437c478bd9Sstevel@tonic-gate 		(void) fprintf(trace, "reading from %s.\n", filename);
14447c478bd9Sstevel@tonic-gate 
14457c478bd9Sstevel@tonic-gate 	if ((termfile = fopen(filename, "r")) == NULL) {
14467c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%s: cannot open %s for reading.\n",
14477c478bd9Sstevel@tonic-gate 		    progname, filename);
14487c478bd9Sstevel@tonic-gate 		return;
14497c478bd9Sstevel@tonic-gate 	}
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate 	copycomments++;
14527c478bd9Sstevel@tonic-gate 	setfilename(filename);
14537c478bd9Sstevel@tonic-gate 
14547c478bd9Sstevel@tonic-gate 	while (fgets(buffer, BUFSIZ, termfile) != NULL) {
14557c478bd9Sstevel@tonic-gate 		if ((term_name = getterm_name(buffer)) != NULL) {
14567c478bd9Sstevel@tonic-gate 			setterm_name();
14577c478bd9Sstevel@tonic-gate 			captoinfo();
14587c478bd9Sstevel@tonic-gate 		}
14597c478bd9Sstevel@tonic-gate 	}
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate 
14627c478bd9Sstevel@tonic-gate /*
14637c478bd9Sstevel@tonic-gate  *  Sort a name and code table pair according to the name table.
14647c478bd9Sstevel@tonic-gate  *  Use a simple bubble sort for now. Too bad I can't call qsort(3).
14657c478bd9Sstevel@tonic-gate  *  At least I only have to do it once for each table.
14667c478bd9Sstevel@tonic-gate  */
14677c478bd9Sstevel@tonic-gate static void
sorttable(char * nametable[],char * codetable[])14687c478bd9Sstevel@tonic-gate sorttable(char *nametable[], char *codetable[])
14697c478bd9Sstevel@tonic-gate {
14707c478bd9Sstevel@tonic-gate 	int i, j;
14717c478bd9Sstevel@tonic-gate 	char *c;
14727c478bd9Sstevel@tonic-gate 
14737c478bd9Sstevel@tonic-gate 	for (i = 0; nametable[i]; i++)
14747c478bd9Sstevel@tonic-gate 		for (j = 0; j < i; j++)
14757c478bd9Sstevel@tonic-gate 			if (strcmp(nametable[i], nametable[j]) < 0) {
14767c478bd9Sstevel@tonic-gate 				c = nametable[i];
14777c478bd9Sstevel@tonic-gate 				nametable[i] = nametable[j];
14787c478bd9Sstevel@tonic-gate 				nametable[j] = c;
14797c478bd9Sstevel@tonic-gate 				c = codetable[i];
14807c478bd9Sstevel@tonic-gate 				codetable[i] = codetable[j];
14817c478bd9Sstevel@tonic-gate 				codetable[j] = c;
14827c478bd9Sstevel@tonic-gate 			}
14837c478bd9Sstevel@tonic-gate }
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate /*
14867c478bd9Sstevel@tonic-gate  *  Initialize and sort the name and code tables. Allocate space for the
14877c478bd9Sstevel@tonic-gate  *  value tables.
14887c478bd9Sstevel@tonic-gate  */
14897c478bd9Sstevel@tonic-gate static void
inittables(void)1490b5514887Smuffin inittables(void)
14917c478bd9Sstevel@tonic-gate {
14927c478bd9Sstevel@tonic-gate 	unsigned int i;
14937c478bd9Sstevel@tonic-gate 
14947c478bd9Sstevel@tonic-gate 	for (i = 0; boolnames [i]; i++)
14957c478bd9Sstevel@tonic-gate 		;
14967c478bd9Sstevel@tonic-gate 	boolval[0] = (char *)malloc(i * sizeof (char));
14977c478bd9Sstevel@tonic-gate 	boolval[1] = (char *)malloc(i * sizeof (char));
14987c478bd9Sstevel@tonic-gate 	boolcount = i;
14997c478bd9Sstevel@tonic-gate 	sorttable(boolnames, boolcodes);
15007c478bd9Sstevel@tonic-gate 
15017c478bd9Sstevel@tonic-gate 	for (i = 0; numcodes [i]; i++)
15027c478bd9Sstevel@tonic-gate 		;
15037c478bd9Sstevel@tonic-gate 	numval[0] = (short *)malloc(i * sizeof (short));
15047c478bd9Sstevel@tonic-gate 	numval[1] = (short *)malloc(i * sizeof (short));
15057c478bd9Sstevel@tonic-gate 	numcount = i;
15067c478bd9Sstevel@tonic-gate 	sorttable(numnames, numcodes);
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 	for (i = 0; strcodes [i]; i++)
15097c478bd9Sstevel@tonic-gate 		;
15107c478bd9Sstevel@tonic-gate 	strval[0] = (char **)malloc(i * sizeof (char *));
15117c478bd9Sstevel@tonic-gate 	strval[1] = (char **)malloc(i * sizeof (char *));
15127c478bd9Sstevel@tonic-gate 	strcount = i;
15137c478bd9Sstevel@tonic-gate 	sorttable(strnames, strcodes);
15147c478bd9Sstevel@tonic-gate }
15157c478bd9Sstevel@tonic-gate 
1516b5514887Smuffin int
main(int argc,char ** argv)15177c478bd9Sstevel@tonic-gate main(int argc, char **argv)
15187c478bd9Sstevel@tonic-gate {
15197c478bd9Sstevel@tonic-gate 	int c;
15207c478bd9Sstevel@tonic-gate 	char _capbuffer [8192];
15217c478bd9Sstevel@tonic-gate 	char _bp [TBUFSIZE];
15227c478bd9Sstevel@tonic-gate 	char _buflongname [128];
15237c478bd9Sstevel@tonic-gate 
15247c478bd9Sstevel@tonic-gate 	capbuffer = &_capbuffer[0];
15257c478bd9Sstevel@tonic-gate 	bp = &_bp[0];
15267c478bd9Sstevel@tonic-gate 	buflongname = &_buflongname[0];
15277c478bd9Sstevel@tonic-gate 	progname = argv[0];
15287c478bd9Sstevel@tonic-gate 
15297c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "1vVw:")) != EOF)
15307c478bd9Sstevel@tonic-gate 		switch (c) {
15317c478bd9Sstevel@tonic-gate 			case '1':
15327c478bd9Sstevel@tonic-gate 				pr_onecolumn(1);
15337c478bd9Sstevel@tonic-gate 				break;
15347c478bd9Sstevel@tonic-gate 			case 'w':
15357c478bd9Sstevel@tonic-gate 				pr_width(atoi(optarg));
15367c478bd9Sstevel@tonic-gate 				break;
15377c478bd9Sstevel@tonic-gate 			case 'v':
15387c478bd9Sstevel@tonic-gate 				verbose++;
15397c478bd9Sstevel@tonic-gate 				break;
15407c478bd9Sstevel@tonic-gate 			case 'V':
15417c478bd9Sstevel@tonic-gate 				(void) printf("%s: version %s\n", progname,
15427c478bd9Sstevel@tonic-gate 				    "@(#)curses:screen/captoinfo.c	1.12");
15437c478bd9Sstevel@tonic-gate 				(void) fflush(stdout);
15447c478bd9Sstevel@tonic-gate 				exit(0);
15457c478bd9Sstevel@tonic-gate 				/* FALLTHROUGH (not really) */
15467c478bd9Sstevel@tonic-gate 			case '?':
15477c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
15487c478bd9Sstevel@tonic-gate 				    "usage: %s [-1Vv] [-w width] "
15497c478bd9Sstevel@tonic-gate 				    "[filename ...]\n", progname);
15507c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, "\t-1\tsingle column "
15517c478bd9Sstevel@tonic-gate 				    "output\n");
15527c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
15537c478bd9Sstevel@tonic-gate 				    "\t-v\tverbose debugging output\n");
15547c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
15557c478bd9Sstevel@tonic-gate 				    "\t-V\tprint program version\n");
15567c478bd9Sstevel@tonic-gate 				exit(-1);
1557b5514887Smuffin 		}
15587c478bd9Sstevel@tonic-gate 
15597c478bd9Sstevel@tonic-gate 	/* initialize */
15607c478bd9Sstevel@tonic-gate 	pr_init(pr_terminfo);
15617c478bd9Sstevel@tonic-gate 	inittables();
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 	if (optind >= argc)
15647c478bd9Sstevel@tonic-gate 		use_etc_termcap();
15657c478bd9Sstevel@tonic-gate 	else {
15667c478bd9Sstevel@tonic-gate 		initdirname();
15677c478bd9Sstevel@tonic-gate 	for (; optind < argc; optind++)
1568b5514887Smuffin 		use_file(argv [optind]);
15697c478bd9Sstevel@tonic-gate 	}
15707c478bd9Sstevel@tonic-gate 
15717c478bd9Sstevel@tonic-gate 	return (0);
15727c478bd9Sstevel@tonic-gate }
15737c478bd9Sstevel@tonic-gate 
15747c478bd9Sstevel@tonic-gate /* fake out the modules in print.c so we don't have to load in */
15757c478bd9Sstevel@tonic-gate /* cexpand.c and infotocap.c */
15767c478bd9Sstevel@tonic-gate /* ARGSUSED */
1577b5514887Smuffin int
cpr(FILE * stream,char * string)1578b5514887Smuffin cpr(FILE *stream, char *string)
1579b5514887Smuffin {
1580b5514887Smuffin 	return (0);
1581b5514887Smuffin }
1582