📄 captoinfo.c
字号:
/* Copyright (c) 1984 AT&T *//* All Rights Reserved *//* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T *//* The copyright notice above does not evidence any *//* actual or intended publication of such source code. */#ifndef lintstatic char sccsid[] = "@(#)captoinfo.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.6.1.7 */#endif/* NAME captoinfo - convert a termcap description to a terminfo description SYNOPSIS captoinfo [-1vV] [-w width] [ filename ... ] AUTHOR Tony Hansen, January 22, 1984.*/#include "curses.h"#include <ctype.h>#include "otermcap.h"#include "print.h"#define trace stderr /* send trace messages to stderr *//* extra termcap variables no longer in terminfo */char *oboolcodes[] = { "bs", /* Terminal can backspace with "^H" */ "nc", /* No correctly working carriage return (DM2500,H2000) */ "ns", /* Terminal is a CRT but does not scroll. */ "pt", /* Has hardware tabs (may need to be set with "is") */ "MT", /* Has meta key, alternate code. */ "xr", /* Return acts like ce \r \n (Delta Data) */ 0 };int cap_bs = 0, cap_nc = 1, cap_ns = 2, cap_pt = 3, cap_MT = 4, cap_xr = 5;char *onumcodes[] = { "dB", /* Number of millisec of bs delay needed */ "dC", /* Number of millisec of cr delay needed */ "dF", /* Number of millisec of ff delay needed */ "dN", /* Number of millisec of nl delay needed */ "dT", /* Number of millisec of tab delay needed */ "ug", /* Number of blank chars left by us or ue *//* Ignore the 'kn' number. It was ill-defined and never used. */ "kn", /* Number of "other" keys */ 0 };int cap_dB = 0, cap_dC = 1, cap_dF = 2, cap_dN = 3, cap_dT = 4, cap_ug = 5;char *ostrcodes[] = { "bc", /* Backspace if not "^H" */ "ko", /* Termcap entries for other non-function keys */ "ma", /* Arrow key map, used by vi version 2 only */ "nl", /* Newline character (default "\n") */ "rs", /* undocumented reset string, like is (info is2) *//* Ignore the 'ml' and 'mu' strings. */ "ml", /* Memory lock on above cursor. */ "mu", /* Memory unlock (turn off memory lock). */ 0 };int cap_bc = 0, cap_ko = 1, cap_ma = 2, cap_nl = 3, cap_rs = 4;#define numelements(x) (sizeof(x)/sizeof(x[0]))char oboolval [2] [numelements(oboolcodes)];short onumval [2] [numelements(onumcodes)];char *ostrval [2] [numelements(ostrcodes)];/* externs from libcurses.a */extern char *boolnames [], *boolcodes [];extern char *numnames [], *numcodes [];extern char *strnames [], *strcodes [];/* externs from libc.a */extern char *getenv ();extern char *malloc ();extern void exit ();#if defined(SYSV) || defined(USG) /* handle both Sys Vr2 and Vr3 curses */extern char *getcwd ();#elseextern char *getwd ();#endif /* SYSV || USG */extern int getopt ();extern int optind;extern char *optarg;extern int strncmp(), strcmp();extern char *strcpy();/* globals for this file */char *progname; /* argv [0], the name of the program */static char *term_name; /* the name of the terminal being worked on */static int uselevel; /* whether we're dealing with use= info */static int boolcount, /* the maximum numbers of each name array */ numcount, strcount;/* globals dealing with the environment */extern char **environ;static char TERM [100];#if defined(SYSV) || defined(USG) /* handle both Sys Vr2 and Vr3 curses */static char dirname [BUFSIZ];#else# include <sys/param.h>static char dirname [MAXPATHLEN];#endif /* SYSV || USG */static char TERMCAP [BUFSIZ+15];static char *newenviron [] = { &TERM [0], &TERMCAP [0], 0 };/* dynamic arrays */static char *boolval [2]; /* dynamic array of boolean values */static short *numval [2]; /* dynamic array of numeric values */static char **strval [2]; /* dynamic array of string pointers *//* data buffers */static char *capbuffer; /* string table, pointed at by strval */static char *nextstring; /* pointer into string table */static char *bp; /* termcap raw string table */static char *buflongname; /* place to copy the long names *//* flags */static int verbose = 0; /* debugging printing level */static int copycomments = 0; /* copy comments from tercap source */#define ispadchar(c) (isdigit(c) || (c) == '.' || (c) == '*')/* Verify that the names given in the termcap entry are all valid.*/int capsearch (codes, ocodes, cap)register char *codes[], *ocodes[], *cap;{ for ( ; *codes; codes++) if (((*codes)[0] == cap[0]) && ((*codes)[1] == cap[1])) return 1; for ( ; *ocodes; ocodes++) if (((*ocodes)[0] == cap[0]) && ((*ocodes)[1] == cap[1])) return 1; return 0;}void checktermcap(){ register char *tbuf = bp; enum { tbool, tnum, tstr, tcancel, tunknown } type; for (;;) { tbuf = tskip(tbuf); while (*tbuf == '\t' || *tbuf == ' ' || *tbuf == ':') tbuf++; if (*tbuf == 0) return; /* commented out entry? */ if (*tbuf == '.') { if (verbose) (void) fprintf (trace, "termcap string '%c%c' commented out.\n", tbuf[1], tbuf[2]); if (!capsearch (boolcodes, oboolcodes, tbuf+1) && !capsearch (numcodes, onumcodes, tbuf+1) && !capsearch (strcodes, ostrcodes, tbuf+1)) (void) fprintf (stderr, "%s: TERM=%s: commented out code '%.2s' is unknown.\n", progname, term_name, tbuf+1); continue; } if (verbose) (void) fprintf (trace, "looking at termcap string '%.2s'.\n", tbuf); switch (tbuf[2]) { case ':': case '\0': type = tbool; break; case '#': type = tnum; break; case '=': type = tstr; break; case '@': type = tcancel; break; default: (void) fprintf (stderr, "%s: TERM=%s: unknown type given for the termcap code '%.2s'.\n", progname, term_name, tbuf); type = tunknown; } if (verbose > 1) (void) fprintf (trace, "type of '%.2s' is %s.\n", tbuf, (type == tbool) ? "boolean" : (type == tnum) ? "numeric" : (type = tstr) ? "string" : (type = tcancel) ? "canceled" : "unknown"); /* look for the name in bools */ if (capsearch (boolcodes, oboolcodes, tbuf)) { if (type != tbool && type != tcancel) (void) fprintf (stderr, "%s: TERM=%s: wrong type given for the boolean termcap code '%.2s'.\n", progname, term_name, tbuf); continue; } /* look for the name in nums */ if (capsearch (numcodes, onumcodes, tbuf)) { if (type != tnum && type != tcancel) (void) fprintf (stderr, "%s: TERM=%s: wrong type given for the numeric termcap code '%.2s'.\n", progname, term_name, tbuf); continue; } /* look for the name in strs */ if (capsearch (strcodes, ostrcodes, tbuf)) { if (type != tstr && type != tcancel) (void) fprintf (stderr, "%s: TERM=%s: wrong type given for the string termcap code '%.2s'.\n", progname, term_name, tbuf); continue; } (void) fprintf (stderr, "%s: TERM=%s: the %s termcap code '%.2s' is not a valid name.\n", progname, term_name, (type == tbool) ? "boolean" : (type == tnum) ? "numeric" : (type = tstr) ? "string" : (type = tcancel) ? "canceled" : "(unknown type)", tbuf); }}/* Fill up the termcap tables.*/int filltables (){ register int i, tret; /* Retrieve the termcap entry. */ if ((tret = otgetent (bp, term_name)) != 1) { (void) fprintf (stderr, "%s: TERM=%s: tgetent failed with return code %d (%s).\n", progname, term_name, tret, (tret == 0) ? "non-existent or invalid entry" : (tret == -1) ? "cannot open $TERMCAP" : "unknown reason"); return 0; } if (verbose) { (void) fprintf (trace, "bp="); (void) cpr (trace, bp); (void) fprintf (trace, ".\n"); } if (uselevel == 0) checktermcap(); /* Retrieve the values that are in terminfo. */ /* booleans */ for (i = 0; boolcodes [i]; i++) { boolval [uselevel] [i] = otgetflag (boolcodes [i]); if (verbose > 1) { (void) fprintf (trace, "boolcodes=%s, ", boolcodes [i]); (void) fprintf (trace, "boolnames=%s, ", boolnames [i]); (void) fprintf (trace, "flag=%d.\n", boolval [uselevel] [i]); } } /* numbers */ for (i = 0; numcodes [i]; i++) { numval [uselevel] [i] = otgetnum (numcodes [i]); if (verbose > 1) { (void) fprintf (trace, "numcodes=%s, ", numcodes [i]); (void) fprintf (trace, "numnames=%s, ", numnames [i]); (void) fprintf (trace, "num=%d.\n", numval [uselevel] [i]); } } if (uselevel == 0) nextstring = capbuffer; /* strings */ for (i = 0; strcodes [i]; i++) { strval [uselevel] [i] = otgetstr (strcodes [i], &nextstring); if (verbose > 1) { (void) fprintf (trace, "strcodes=%s, ", strcodes [i]); (void) fprintf (trace, "strnames=%s, ", strnames [i]); if (strval [uselevel] [i]) { (void) fprintf (trace, "str="); tpr (trace, strval [uselevel] [i]); (void) fprintf (trace, ".\n"); } else (void) fprintf (trace, "str=NULL.\n"); } /* remove zero length strings */ if (strval[uselevel][i] && (strval[uselevel][i][0] == '\0') ) { (void) fprintf (stderr, "%s: TERM=%s: cap %s (info %s) is NULL: REMOVED\n", progname, term_name, strcodes[i], strnames[i]); strval [uselevel] [i] = NULL; } } /* Retrieve the values not found in terminfo anymore. */ /* booleans */ for (i = 0; oboolcodes [i]; i++) { oboolval [uselevel] [i] = otgetflag (oboolcodes [i]); if (verbose > 1) { (void) fprintf (trace, "oboolcodes=%s, ", oboolcodes[i]); (void) fprintf (trace, "flag=%d.\n", oboolval [uselevel] [i]); } } /* numbers */ for (i = 0; onumcodes [i]; i++) { onumval [uselevel] [i] = otgetnum (onumcodes [i]); if (verbose > 1) { (void) fprintf (trace, "onumcodes=%s, ", onumcodes [i]); (void) fprintf (trace, "num=%d.\n", onumval [uselevel] [i]); } } /* strings */ for (i = 0; ostrcodes [i]; i++) { ostrval [uselevel] [i] = otgetstr (ostrcodes [i], &nextstring); if (verbose > 1) { (void) fprintf (trace, "ostrcodes=%s, ", ostrcodes [i]); if (ostrval [uselevel] [i]) { (void) fprintf (trace, "ostr="); tpr (trace, ostrval [uselevel] [i]); (void) fprintf (trace, ".\n"); } else (void) fprintf (trace, "ostr=NULL.\n"); } /* remove zero length strings */ if (ostrval[uselevel][i] && (ostrval[uselevel][i][0] == '\0') ) { (void) fprintf (stderr, "%s: TERM=%s: cap %s (no terminfo name) is NULL: REMOVED\n", progname, term_name, ostrcodes[i]); ostrval [uselevel] [i] = NULL; } } return 1;}/* This routine copies the set of names from the termcap entry into a separate buffer, getting rid of the old obsolete two character names.*/getlongname (){ register char *b = &bp [0], *l = buflongname; /* Skip the two character name */ if (bp [2] == '|') b = &bp [3]; /* Copy the rest of the names */ while (*b && *b != ':') *l++ = *b++; *l = '\0'; if (b != &bp[0]) { (void) fprintf (stderr, "%s: obsolete 2 character name '%2.2s' removed.\n", progname, bp); (void) fprintf (stderr, "\tsynonyms are: '%s'\n", buflongname); }}/* Return the value of the termcap string 'capname' as stored in our list.*/char *getcapstr (capname)register char *capname;{ register int i; if (verbose > 1) (void) fprintf (trace, "looking for termcap value of %s.\n", capname); /* Check the old termcap list. */ for (i = 0; ostrcodes [i]; i++) if (strcmp (ostrcodes [i], capname) == 0) { if (verbose > 1) { (void) fprintf (trace, "\tvalue is:"); tpr (trace, ostrval [uselevel] [i]); (void) fprintf (trace, ".\n"); } return ostrval [uselevel] [i]; } if (verbose > 1) (void) fprintf (trace, "termcap name '%s' not found in ostrcodes.\n", capname); /* Check the terminfo list. */ for (i = 0; strcodes [i]; i++) if (strcmp (strcodes [i], capname) == 0) { if (verbose > 1) { (void) fprintf (trace, "\tvalue is:"); tpr (trace, strval [uselevel] [i]); (void) fprintf (trace, ".\n"); } return strval [uselevel] [i]; } (void) fprintf (stderr, "%s: TERM=%s: termcap name '%s' not found.\n", progname, term_name, capname); return (char *) NULL;}/* Search for a name in the given table and return the index. Someday I'll redo this to use bsearch().*//* ARGSUSED */int search (names, max, infoname)char *names[], *infoname;int max;{#ifndef BSEARCH register int i; for (i = 0; names [i] != NULL; i++) if (strcmp (names [i], infoname) == 0) return i; return -1;#else /* this doesn't work for some reason */ extern char *bsearch(); register char **bret; bret = (char **) bsearch ( infoname, (char *) names, max, sizeof (char *), strcmp); (void) fprintf (trace, "search looking for %s.\n", infoname); (void) fprintf (trace, "base=%#x, bret=%#x, nel=%d.\n", names, bret, max); (void) fprintf (trace, "returning %d.\n", bret == NULL ? -1 : bret - names); if (bret == NULL) return -1; else return bret - names;#endif /* OLD */}/* return the value of the terminfo string 'infoname'*/char *getinfostr (infoname)register char *infoname;{ register int i; if (verbose > 1) (void) fprintf (trace, "looking for terminfo value of %s.\n", infoname); i = search (strnames, strcount, infoname); if (i != -1) { if (verbose > 1) { (void) fprintf (trace, "\tvalue is:"); tpr (trace, strval [uselevel] [i]); (void) fprintf (trace, ".\n"); } return strval [uselevel] [i]; } if (verbose > 1) (void) fprintf (trace, "terminfo name '%s' not found.\n", infoname); return (char *) NULL;}/* Replace the value stored for the terminfo boolean capability 'infoname' with the newvalue.*/void putbool (infoname, newvalue)register char *infoname;register int newvalue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -