⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 infocmp.c

📁 ncurses 库 可能有用酒用 没用就算了 我觉得还可以用
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc.              * *                                                                          * * Permission is hereby granted, free of charge, to any person obtaining a  * * copy of this software and associated documentation files (the            * * "Software"), to deal in the Software without restriction, including      * * without limitation the rights to use, copy, modify, merge, publish,      * * distribute, distribute with modifications, sublicense, and/or sell       * * copies of the Software, and to permit persons to whom the Software is    * * furnished to do so, subject to the following conditions:                 * *                                                                          * * The above copyright notice and this permission notice shall be included  * * in all copies or substantial portions of the Software.                   * *                                                                          * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    * * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               * *                                                                          * * Except as contained in this notice, the name(s) of the above copyright   * * holders shall not be used in advertising or otherwise to promote the     * * sale, use or other dealings in this Software without prior written       * * authorization.                                                           * ****************************************************************************//**************************************************************************** *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               * *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         * *     and: Thomas E. Dickey                        1996-on                 * ****************************************************************************//* *	infocmp.c -- decompile an entry, or compare two entries *		written by Eric S. Raymond */#include <progs.priv.h>#include <dump_entry.h>MODULE_ID("$Id: infocmp.c,v 1.79 2005/09/25 00:39:43 tom Exp $")#define L_CURL "{"#define R_CURL "}"#define MAXTERMS	32	/* max # terminal arguments we can handle */#define MAX_STRING	1024	/* maximum formatted string */const char *_nc_progname = "infocmp";typedef char path[PATH_MAX];/*************************************************************************** * * The following control variables, together with the contents of the * terminfo entries, completely determine the actions of the program. * ***************************************************************************/static char *tname[MAXTERMS];	/* terminal type names */static ENTRY entries[MAXTERMS];	/* terminfo entries */static int termcount;		/* count of terminal entries */static bool limited = TRUE;	/* "-r" option is not set */static bool quiet = FALSE;static bool literal = FALSE;static const char *bool_sep = ":";static const char *s_absent = "NULL";static const char *s_cancel = "NULL";static const char *tversion;	/* terminfo version selected */static int itrace;		/* trace flag for debugging */static int mwidth = 60;static int numbers = 0;		/* format "%'char'" to/from "%{number}" */static int outform = F_TERMINFO;	/* output format */static int sortmode;		/* sort_mode *//* main comparison mode */static int compare;#define C_DEFAULT	0	/* don't force comparison mode */#define C_DIFFERENCE	1	/* list differences between two terminals */#define C_COMMON	2	/* list common capabilities */#define C_NAND		3	/* list capabilities in neither terminal */#define C_USEALL	4	/* generate relative use-form entry */static bool ignorepads;		/* ignore pad prefixes when diffing */#if NO_LEAKS#undef ExitProgramstatic void ExitProgram(int code) GCC_NORETURN;/* prototype is to get gcc to accept the noreturn attribute */static voidExitProgram(int code){    while (termcount-- > 0)	_nc_free_termtype(&entries[termcount].tterm);    _nc_leaks_dump_entry();    _nc_free_and_exit(code);}#endifstatic char *canonical_name(char *ptr, char *buf)/* extract the terminal type's primary name */{    char *bp;    (void) strcpy(buf, ptr);    if ((bp = strchr(buf, '|')) != 0)	*bp = '\0';    return (buf);}/*************************************************************************** * * Predicates for dump function * ***************************************************************************/static intcapcmp(PredIdx idx, const char *s, const char *t)/* capability comparison function */{    if (!VALID_STRING(s) && !VALID_STRING(t))	return (s != t);    else if (!VALID_STRING(s) || !VALID_STRING(t))	return (1);    if ((idx == acs_chars_index) || !ignorepads)	return (strcmp(s, t));    else	return (_nc_capcmp(s, t));}static intuse_predicate(unsigned type, PredIdx idx)/* predicate function to use for use decompilation */{    ENTRY *ep;    switch (type) {    case BOOLEAN:	{	    int is_set = FALSE;	    /*	     * This assumes that multiple use entries are supposed	     * to contribute the logical or of their boolean capabilities.	     * This is true if we take the semantics of multiple uses to	     * be 'each capability gets the first non-default value found	     * in the sequence of use entries'.	     *	     * Note that cancelled or absent booleans are stored as FALSE,	     * unlike numbers and strings, whose cancelled/absent state is	     * recorded in the terminfo database.	     */	    for (ep = &entries[1]; ep < entries + termcount; ep++)		if (ep->tterm.Booleans[idx] == TRUE) {		    is_set = entries[0].tterm.Booleans[idx];		    break;		}	    if (is_set != entries[0].tterm.Booleans[idx])		return (!is_set);	    else		return (FAIL);	}    case NUMBER:	{	    int value = ABSENT_NUMERIC;	    /*	     * We take the semantics of multiple uses to be 'each	     * capability gets the first non-default value found	     * in the sequence of use entries'.	     */	    for (ep = &entries[1]; ep < entries + termcount; ep++)		if (VALID_NUMERIC(ep->tterm.Numbers[idx])) {		    value = ep->tterm.Numbers[idx];		    break;		}	    if (value != entries[0].tterm.Numbers[idx])		return (value != ABSENT_NUMERIC);	    else		return (FAIL);	}    case STRING:	{	    char *termstr, *usestr = ABSENT_STRING;	    termstr = entries[0].tterm.Strings[idx];	    /*	     * We take the semantics of multiple uses to be 'each	     * capability gets the first non-default value found	     * in the sequence of use entries'.	     */	    for (ep = &entries[1]; ep < entries + termcount; ep++)		if (ep->tterm.Strings[idx]) {		    usestr = ep->tterm.Strings[idx];		    break;		}	    if (usestr == ABSENT_STRING && termstr == ABSENT_STRING)		return (FAIL);	    else if (!usestr || !termstr || capcmp(idx, usestr, termstr))		return (TRUE);	    else		return (FAIL);	}    }    return (FALSE);		/* pacify compiler */}static booluseeq(ENTRY * e1, ENTRY * e2)/* are the use references in two entries equivalent? */{    int i, j;    if (e1->nuses != e2->nuses)	return (FALSE);    /* Ugh...this is quadratic again */    for (i = 0; i < e1->nuses; i++) {	bool foundmatch = FALSE;	/* search second entry for given use reference */	for (j = 0; j < e2->nuses; j++)	    if (!strcmp(e1->uses[i].name, e2->uses[j].name)) {		foundmatch = TRUE;		break;	    }	if (!foundmatch)	    return (FALSE);    }    return (TRUE);}static boolentryeq(TERMTYPE *t1, TERMTYPE *t2)/* are two entries equivalent? */{    unsigned i;    for (i = 0; i < NUM_BOOLEANS(t1); i++)	if (t1->Booleans[i] != t2->Booleans[i])	    return (FALSE);    for (i = 0; i < NUM_NUMBERS(t1); i++)	if (t1->Numbers[i] != t2->Numbers[i])	    return (FALSE);    for (i = 0; i < NUM_STRINGS(t1); i++)	if (capcmp((PredIdx) i, t1->Strings[i], t2->Strings[i]))	    return (FALSE);    return (TRUE);}#define TIC_EXPAND(result) _nc_tic_expand(result, outform==F_TERMINFO, numbers)static voidprint_uses(ENTRY * ep, FILE *fp)/* print an entry's use references */{    int i;    if (!ep->nuses)	fputs("NULL", fp);    else	for (i = 0; i < ep->nuses; i++) {	    fputs(ep->uses[i].name, fp);	    if (i < ep->nuses - 1)		fputs(" ", fp);	}}static const char *dump_boolean(int val)/* display the value of a boolean capability */{    switch (val) {    case ABSENT_BOOLEAN:	return (s_absent);    case CANCELLED_BOOLEAN:	return (s_cancel);    case FALSE:	return ("F");    case TRUE:	return ("T");    default:	return ("?");    }}static voiddump_numeric(int val, char *buf)/* display the value of a boolean capability */{    switch (val) {    case ABSENT_NUMERIC:	strcpy(buf, s_absent);	break;    case CANCELLED_NUMERIC:	strcpy(buf, s_cancel);	break;    default:	sprintf(buf, "%d", val);	break;    }}static voiddump_string(char *val, char *buf)/* display the value of a string capability */{    if (val == ABSENT_STRING)	strcpy(buf, s_absent);    else if (val == CANCELLED_STRING)	strcpy(buf, s_cancel);    else {	sprintf(buf, "'%.*s'", MAX_STRING - 3, TIC_EXPAND(val));    }}static voidcompare_predicate(PredType type, PredIdx idx, const char *name)/* predicate function to use for entry difference reports */{    register ENTRY *e1 = &entries[0];    register ENTRY *e2 = &entries[1];    char buf1[MAX_STRING], buf2[MAX_STRING];    int b1, b2;    int n1, n2;    char *s1, *s2;    switch (type) {    case CMP_BOOLEAN:	b1 = e1->tterm.Booleans[idx];	b2 = e2->tterm.Booleans[idx];	switch (compare) {	case C_DIFFERENCE:	    if (!(b1 == ABSENT_BOOLEAN && b2 == ABSENT_BOOLEAN) && b1 != b2)		(void) printf("\t%s: %s%s%s.\n",			      name,			      dump_boolean(b1),			      bool_sep,			      dump_boolean(b2));	    break;	case C_COMMON:	    if (b1 == b2 && b1 != ABSENT_BOOLEAN)		(void) printf("\t%s= %s.\n", name, dump_boolean(b1));	    break;	case C_NAND:	    if (b1 == ABSENT_BOOLEAN && b2 == ABSENT_BOOLEAN)		(void) printf("\t!%s.\n", name);	    break;	}	break;    case CMP_NUMBER:	n1 = e1->tterm.Numbers[idx];	n2 = e2->tterm.Numbers[idx];	dump_numeric(n1, buf1);	dump_numeric(n2, buf2);	switch (compare) {	case C_DIFFERENCE:	    if (!((n1 == ABSENT_NUMERIC && n2 == ABSENT_NUMERIC)) && n1 != n2)		(void) printf("\t%s: %s, %s.\n", name, buf1, buf2);	    break;	case C_COMMON:	    if (n1 != ABSENT_NUMERIC && n2 != ABSENT_NUMERIC && n1 == n2)		(void) printf("\t%s= %s.\n", name, buf1);	    break;	case C_NAND:	    if (n1 == ABSENT_NUMERIC && n2 == ABSENT_NUMERIC)		(void) printf("\t!%s.\n", name);	    break;	}	break;    case CMP_STRING:	s1 = e1->tterm.Strings[idx];	s2 = e2->tterm.Strings[idx];	switch (compare) {	case C_DIFFERENCE:	    if (capcmp(idx, s1, s2)) {		dump_string(s1, buf1);		dump_string(s2, buf2);		if (strcmp(buf1, buf2))		    (void) printf("\t%s: %s, %s.\n", name, buf1, buf2);	    }	    break;	case C_COMMON:	    if (s1 && s2 && !capcmp(idx, s1, s2))		(void) printf("\t%s= '%s'.\n", name, TIC_EXPAND(s1));	    break;	case C_NAND:	    if (!s1 && !s2)		(void) printf("\t!%s.\n", name);	    break;	}	break;    case CMP_USE:	/* unlike the other modes, this compares *all* use entries */	switch (compare) {	case C_DIFFERENCE:	    if (!useeq(e1, e2)) {		(void) fputs("\tuse: ", stdout);		print_uses(e1, stdout);		fputs(", ", stdout);		print_uses(e2, stdout);		fputs(".\n", stdout);	    }	    break;	case C_COMMON:	    if (e1->nuses && e2->nuses && useeq(e1, e2)) {		(void) fputs("\tuse: ", stdout);		print_uses(e1, stdout);		fputs(".\n", stdout);	    }	    break;	case C_NAND:	    if (!e1->nuses && !e2->nuses)		(void) printf("\t!use.\n");	    break;	}    }}/*************************************************************************** * * Init string analysis * ***************************************************************************/typedef struct {    const char *from;    const char *to;} assoc;static const assoc std_caps[] ={    /* these are specified by X.364 and iBCS2 */    {"\033c", "RIS"},		/* full reset */    {"\0337", "SC"},		/* save cursor */    {"\0338", "RC"},		/* restore cursor */    {"\033[r", "RSR"},		/* not an X.364 mnemonic */    {"\033[m", "SGR0"},		/* not an X.364 mnemonic */    {"\033[2J", "ED2"},		/* clear page */    /* this group is specified by ISO 2022 */    {"\033(0", "ISO DEC G0"},	/* enable DEC graphics for G0 */    {"\033(A", "ISO UK G0"},	/* enable UK chars for G0 */    {"\033(B", "ISO US G0"},	/* enable US chars for G0 */    {"\033)0", "ISO DEC G1"},	/* enable DEC graphics for G1 */    {"\033)A", "ISO UK G1"},	/* enable UK chars for G1 */    {"\033)B", "ISO US G1"},	/* enable US chars for G1 */    /* these are DEC private controls widely supported by emulators */    {"\033=", "DECPAM"},	/* application keypad mode */    {"\033>", "DECPNM"},	/* normal keypad mode */    {"\033<", "DECANSI"},	/* enter ANSI mode */    {"\033[!p", "DECSTR"},	/* soft reset */    {"\033 F", "S7C1T"},	/* 7-bit controls */    {(char *) 0, (char *) 0}};static const assoc std_modes[] =/* ECMA \E[ ... [hl] modes recognized by many emulators */{    {"2", "AM"},		/* keyboard action mode */    {"4", "IRM"},		/* insert/replace mode */    {"12", "SRM"},		/* send/receive mode */    {"20", "LNM"},		/* linefeed mode */    {(char *) 0, (char *) 0}};static const assoc private_modes[] =/* DEC \E[ ... [hl] modes recognized by many emulators */{    {"1", "CKM"},		/* application cursor keys */    {"2", "ANM"},		/* set VT52 mode */    {"3", "COLM"},		/* 132-column mode */    {"4", "SCLM"},		/* smooth scroll */    {"5", "SCNM"},		/* reverse video mode */    {"6", "OM"},		/* origin mode */    {"7", "AWM"},		/* wraparound mode */    {"8", "ARM"},		/* auto-repeat mode */    {(char *) 0, (char *) 0}};static const assoc ecma_highlights[] =/* recognize ECMA attribute sequences */{    {"0", "NORMAL"},		/* normal */    {"1", "+BOLD"},		/* bold on */    {"2", "+DIM"},		/* dim on */    {"3", "+ITALIC"},		/* italic on */    {"4", "+UNDERLINE"},	/* underline on */    {"5", "+BLINK"},		/* blink on */    {"6", "+FASTBLINK"},	/* fastblink on */    {"7", "+REVERSE"},		/* reverse on */    {"8", "+INVISIBLE"},	/* invisible on */    {"9", "+DELETED"},		/* deleted on */    {"10", "MAIN-FONT"},	/* select primary font */    {"11", "ALT-FONT-1"},	/* select alternate font 1 */    {"12", "ALT-FONT-2"},	/* select alternate font 2 */    {"13", "ALT-FONT-3"},	/* select alternate font 3 */    {"14", "ALT-FONT-4"},	/* select alternate font 4 */    {"15", "ALT-FONT-5"},	/* select alternate font 5 */    {"16", "ALT-FONT-6"},	/* select alternate font 6 */    {"17", "ALT-FONT-7"},	/* select alternate font 7 */    {"18", "ALT-FONT-1"},	/* select alternate font 1 */    {"19", "ALT-FONT-1"},	/* select alternate font 1 */    {"20", "FRAKTUR"},		/* Fraktur font */    {"21", "DOUBLEUNDER"},	/* double underline */    {"22", "-DIM"},		/* dim off */    {"23", "-ITALIC"},		/* italic off */    {"24", "-UNDERLINE"},	/* underline off */    {"25", "-BLINK"},		/* blink off */    {"26", "-FASTBLINK"},	/* fastblink off */    {"27", "-REVERSE"},		/* reverse off */    {"28", "-INVISIBLE"},	/* invisible off */    {"29", "-DELETED"},		/* deleted off */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -