version 1.10, 2000/03/26 16:45:04 |
version 1.11, 2000/10/08 22:47:12 |
|
|
#include <term_entry.h> |
#include <term_entry.h> |
#include <dump_entry.h> |
#include <dump_entry.h> |
|
|
MODULE_ID("$From: infocmp.c,v 1.54 2000/03/19 02:56:14 tom Exp $") |
MODULE_ID("$From: infocmp.c,v 1.57 2000/10/01 01:26:25 tom Exp $") |
|
|
#define L_CURL "{" |
#define L_CURL "{" |
#define R_CURL "}" |
#define R_CURL "}" |
|
|
static int itrace; /* trace flag for debugging */ |
static int itrace; /* trace flag for debugging */ |
static int mwidth = 60; |
static int mwidth = 60; |
static int numbers = 0; /* format "%'char'" to/from "%{number}" */ |
static int numbers = 0; /* format "%'char'" to/from "%{number}" */ |
static int outform = F_TERMINFO;/* output format */ |
static int outform = F_TERMINFO; /* output format */ |
static int sortmode; /* sort_mode */ |
static int sortmode; /* sort_mode */ |
|
|
/* main comparison mode */ |
/* main comparison mode */ |
|
|
static void |
static void |
ExitProgram(int code) GCC_NORETURN; |
ExitProgram(int code) GCC_NORETURN; |
/* prototype is to get gcc to accept the noreturn attribute */ |
/* prototype is to get gcc to accept the noreturn attribute */ |
static void |
static void |
ExitProgram(int code) |
ExitProgram(int code) |
{ |
{ |
while (termcount-- > 0) |
while (termcount-- > 0) |
_nc_free_termtype(&entries[termcount].tterm); |
_nc_free_termtype(&entries[termcount].tterm); |
|
|
case C_DIFFERENCE: |
case C_DIFFERENCE: |
if (!(b1 == ABSENT_BOOLEAN && b2 == ABSENT_BOOLEAN) && b1 != b2) |
if (!(b1 == ABSENT_BOOLEAN && b2 == ABSENT_BOOLEAN) && b1 != b2) |
(void) printf("\t%s: %s%s%s.\n", |
(void) printf("\t%s: %s%s%s.\n", |
name, |
name, |
dump_boolean(b1), |
dump_boolean(b1), |
bool_sep, |
bool_sep, |
dump_boolean(b2)); |
dump_boolean(b2)); |
break; |
break; |
|
|
case C_COMMON: |
case C_COMMON: |
|
|
/* maybe do use resolution */ |
/* maybe do use resolution */ |
if (!_nc_resolve_uses(!limited)) { |
if (!_nc_resolve_uses(!limited)) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"There are unresolved use entries in %s:\n", |
"There are unresolved use entries in %s:\n", |
argv[n]); |
argv[n]); |
for_entry_list(qp) { |
for_entry_list(qp) { |
if (qp->nuses) { |
if (qp->nuses) { |
(void) fputs(qp->tterm.term_names, stderr); |
(void) fputs(qp->tterm.term_names, stderr); |
|
|
for (qp = heads[0]; qp; qp = qp->next) { |
for (qp = heads[0]; qp; qp = qp->next) { |
if (qp->ncrosslinks > 1) { |
if (qp->ncrosslinks > 1) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"%s in file 1 (%s) has %d matches in file 2 (%s):\n", |
"%s in file 1 (%s) has %d matches in file 2 (%s):\n", |
_nc_first_name(qp->tterm.term_names), |
_nc_first_name(qp->tterm.term_names), |
argv[0], |
argv[0], |
qp->ncrosslinks, |
qp->ncrosslinks, |
argv[1]); |
argv[1]); |
for (i = 0; i < qp->ncrosslinks; i++) |
for (i = 0; i < qp->ncrosslinks; i++) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"\t%s\n", |
"\t%s\n", |
_nc_first_name((qp->crosslinks[i])->tterm.term_names)); |
_nc_first_name((qp->crosslinks[i])->tterm.term_names)); |
} |
} |
} |
} |
|
|
for (rp = heads[1]; rp; rp = rp->next) { |
for (rp = heads[1]; rp; rp = rp->next) { |
if (rp->ncrosslinks > 1) { |
if (rp->ncrosslinks > 1) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"%s in file 2 (%s) has %d matches in file 1 (%s):\n", |
"%s in file 2 (%s) has %d matches in file 1 (%s):\n", |
_nc_first_name(rp->tterm.term_names), |
_nc_first_name(rp->tterm.term_names), |
argv[1], |
argv[1], |
rp->ncrosslinks, |
rp->ncrosslinks, |
argv[0]); |
argv[0]); |
for (i = 0; i < rp->ncrosslinks; i++) |
for (i = 0; i < rp->ncrosslinks; i++) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"\t%s\n", |
"\t%s\n", |
_nc_first_name((rp->crosslinks[i])->tterm.term_names)); |
_nc_first_name((rp->crosslinks[i])->tterm.term_names)); |
} |
} |
} |
} |
|
|
|
|
for (qp = heads[0]; qp; qp = qp->next) |
for (qp = heads[0]; qp; qp = qp->next) |
if (qp->ncrosslinks == 0) |
if (qp->ncrosslinks == 0) |
(void) printf("\t%s\n", |
(void) printf("\t%s\n", |
_nc_first_name(qp->tterm.term_names)); |
_nc_first_name(qp->tterm.term_names)); |
|
|
(void) printf("In file 2 (%s) only:\n", argv[1]); |
(void) printf("In file 2 (%s) only:\n", argv[1]); |
for (rp = heads[1]; rp; rp = rp->next) |
for (rp = heads[1]; rp; rp = rp->next) |
if (rp->ncrosslinks == 0) |
if (rp->ncrosslinks == 0) |
(void) printf("\t%s\n", |
(void) printf("\t%s\n", |
_nc_first_name(rp->tterm.term_names)); |
_nc_first_name(rp->tterm.term_names)); |
|
|
(void) printf("The following entries are equivalent:\n"); |
(void) printf("The following entries are equivalent:\n"); |
for (qp = heads[0]; qp; qp = qp->next) { |
for (qp = heads[0]; qp; qp = qp->next) { |
|
|
case C_DIFFERENCE: |
case C_DIFFERENCE: |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: dumping differences\n"); |
"infocmp: dumping differences\n"); |
(void) printf("comparing %s to %s.\n", name1, name2); |
(void) printf("comparing %s to %s.\n", name1, name2); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
break; |
break; |
|
|
case C_COMMON: |
case C_COMMON: |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: dumping common capabilities\n"); |
"infocmp: dumping common capabilities\n"); |
(void) printf("comparing %s to %s.\n", name1, name2); |
(void) printf("comparing %s to %s.\n", name1, name2); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
break; |
break; |
|
|
case C_NAND: |
case C_NAND: |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: dumping differences\n"); |
"infocmp: dumping differences\n"); |
(void) printf("comparing %s to %s.\n", name1, name2); |
(void) printf("comparing %s to %s.\n", name1, name2); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
break; |
break; |
|
|
," -w number (width)" |
," -w number (width)" |
}; |
}; |
const size_t first = 3; |
const size_t first = 3; |
const size_t last = sizeof(tbl) / sizeof(tbl[0]); |
const size_t last = SIZEOF(tbl); |
const size_t left = (last - first + 1) / 2 + first; |
const size_t left = (last - first + 1) / 2 + first; |
size_t n; |
size_t n; |
|
|
|
|
break; |
break; |
} |
} |
(void) printf("\t/* %3d: %-8s */\t%s,\n", |
(void) printf("\t/* %3d: %-8s */\t%s,\n", |
n, ExtBoolname(term, n, boolnames), str); |
n, ExtBoolname(term, n, boolnames), str); |
} |
} |
(void) printf("%s;\n", R_CURL); |
(void) printf("%s;\n", R_CURL); |
|
|
|
|
str = buf; |
str = buf; |
break; |
break; |
} |
} |
(void) printf("\t/* %3d: %-8s */\t%s,\n", n, ExtNumname(term, n, |
(void) printf("\t/* %3d: %-8s */\t%s,\n", n, |
numnames), str); |
ExtNumname(term, n, numnames), str); |
} |
} |
(void) printf("%s;\n", R_CURL); |
(void) printf("%s;\n", R_CURL); |
|
|
|
|
tp = buf; |
tp = buf; |
*tp++ = '"'; |
*tp++ = '"'; |
for (sp = term->Strings[n]; |
for (sp = term->Strings[n]; |
*sp != 0 && (tp - buf) < MAX_STRING - 6; |
*sp != 0 && (tp - buf) < MAX_STRING - 6; |
sp++) { |
sp++) { |
if (isascii(*sp) && isprint(*sp) && *sp != '\\' && *sp != '"') |
if (isascii(*sp) && isprint(*sp) && *sp != '\\' && *sp != '"') |
*tp++ = *sp; |
*tp++ = *sp; |
else { |
else { |
|
|
(void) printf("%s;\n", R_CURL); |
(void) printf("%s;\n", R_CURL); |
|
|
(void) printf("static char * %s[] = %s\n", |
(void) printf("static char * %s[] = %s\n", |
name_initializer("string_ext"), L_CURL); |
name_initializer("string_ext"), L_CURL); |
} |
} |
#endif |
#endif |
(void) printf("\t/* %3d: %-8s */\t%s,\n", n, ExtStrname(term, n, |
(void) printf("\t/* %3d: %-8s */\t%s,\n", n, |
strnames), str); |
ExtStrname(term, n, strnames), str); |
} |
} |
(void) printf("%s;\n", R_CURL); |
(void) printf("%s;\n", R_CURL); |
} |
} |
|
|
(void) printf("#if NCURSES_XNAMES\n"); |
(void) printf("#if NCURSES_XNAMES\n"); |
(void) printf("\t\t(char *)0,\t/* pointer to extended string table */\n"); |
(void) printf("\t\t(char *)0,\t/* pointer to extended string table */\n"); |
(void) printf("\t\t%s,\t/* ...corresponding names */\n", |
(void) printf("\t\t%s,\t/* ...corresponding names */\n", |
(NUM_STRINGS(term) != STRCOUNT) |
(NUM_STRINGS(term) != STRCOUNT) |
? name_initializer("string_ext") |
? name_initializer("string_ext") |
: "(char **)0"); |
: "(char **)0"); |
|
|
(void) printf("\t\t%d,\t\t/* count total Booleans */\n", NUM_BOOLEANS(term)); |
(void) printf("\t\t%d,\t\t/* count total Booleans */\n", NUM_BOOLEANS(term)); |
(void) printf("\t\t%d,\t\t/* count total Numbers */\n", NUM_NUMBERS(term)); |
(void) printf("\t\t%d,\t\t/* count total Numbers */\n", NUM_NUMBERS(term)); |
(void) printf("\t\t%d,\t\t/* count total Strings */\n", NUM_STRINGS(term)); |
(void) printf("\t\t%d,\t\t/* count total Strings */\n", NUM_STRINGS(term)); |
|
|
(void) printf("\t\t%d,\t\t/* count extensions to Booleans */\n", |
(void) printf("\t\t%d,\t\t/* count extensions to Booleans */\n", |
NUM_BOOLEANS(term) - BOOLCOUNT); |
NUM_BOOLEANS(term) - BOOLCOUNT); |
(void) printf("\t\t%d,\t\t/* count extensions to Numbers */\n", |
(void) printf("\t\t%d,\t\t/* count extensions to Numbers */\n", |
NUM_NUMBERS(term) - NUMCOUNT); |
NUM_NUMBERS(term) - NUMCOUNT); |
(void) printf("\t\t%d,\t\t/* count extensions to Strings */\n", |
(void) printf("\t\t%d,\t\t/* count extensions to Strings */\n", |
NUM_STRINGS(term) - STRCOUNT); |
NUM_STRINGS(term) - STRCOUNT); |
|
|
(void) printf("#endif /* NCURSES_XNAMES */\n"); |
(void) printf("#endif /* NCURSES_XNAMES */\n"); |
#endif /* NCURSES_XNAMES */ |
#endif /* NCURSES_XNAMES */ |
(void) printf("\t%s\n", R_CURL); |
(void) printf("\t%s\n", R_CURL); |
} |
} |
|
|
|
static int |
|
optarg_to_number(void) |
|
{ |
|
char *temp = 0; |
|
long value = strtol(optarg, &temp, 0); |
|
|
|
if (temp == 0 || temp == optarg || *temp != 0) { |
|
fprintf(stderr, "Expected a number, not \"%s\"\n", optarg); |
|
exit(EXIT_FAILURE); |
|
} |
|
return (int) value; |
|
} |
|
|
/*************************************************************************** |
/*************************************************************************** |
* |
* |
* Main sequence |
* Main sequence |
|
|
|
|
if ((terminal = getenv("TERM")) == 0) { |
if ((terminal = getenv("TERM")) == 0) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: environment variable TERM not set\n"); |
"infocmp: environment variable TERM not set\n"); |
return EXIT_FAILURE; |
return EXIT_FAILURE; |
} |
} |
|
|
|
|
sortmode = S_TERMCAP; |
sortmode = S_TERMCAP; |
else { |
else { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: unknown sort mode\n"); |
"infocmp: unknown sort mode\n"); |
return EXIT_FAILURE; |
return EXIT_FAILURE; |
} |
} |
break; |
break; |
|
|
break; |
break; |
|
|
case 'v': |
case 'v': |
itrace = atoi(optarg); |
itrace = optarg_to_number(); |
set_trace_level(itrace); |
set_trace_level(itrace); |
break; |
break; |
|
|
case 'V': |
case 'V': |
(void) fputs(NCURSES_VERSION, stdout); |
puts(curses_version()); |
putchar('\n'); |
|
ExitProgram(EXIT_SUCCESS); |
ExitProgram(EXIT_SUCCESS); |
|
|
case 'w': |
case 'w': |
mwidth = atoi(optarg); |
mwidth = optarg_to_number(); |
break; |
break; |
|
|
case 'A': |
case 'A': |
|
|
for (; optind < argc; optind++) { |
for (; optind < argc; optind++) { |
if (termcount >= MAXTERMS) { |
if (termcount >= MAXTERMS) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: too many terminal type arguments\n"); |
"infocmp: too many terminal type arguments\n"); |
return EXIT_FAILURE; |
return EXIT_FAILURE; |
} else { |
} else { |
const char *directory = termcount ? restdir : firstdir; |
const char *directory = termcount ? restdir : firstdir; |
|
|
|
|
if (directory) { |
if (directory) { |
(void) sprintf(tfile[termcount], "%s/%c/%s", |
(void) sprintf(tfile[termcount], "%s/%c/%s", |
directory, |
directory, |
*argv[optind], argv[optind]); |
*argv[optind], argv[optind]); |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: reading entry %s from file %s\n", |
"infocmp: reading entry %s from file %s\n", |
argv[optind], tfile[termcount]); |
argv[optind], tfile[termcount]); |
|
|
status = _nc_read_file_entry(tfile[termcount], |
status = _nc_read_file_entry(tfile[termcount], |
&entries[termcount].tterm); |
&entries[termcount].tterm); |
} else { |
} else { |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: reading entry %s from system directories %s\n", |
"infocmp: reading entry %s from system directories %s\n", |
argv[optind], tname[termcount]); |
argv[optind], tname[termcount]); |
|
|
status = _nc_read_entry(tname[termcount], |
status = _nc_read_entry(tname[termcount], |
tfile[termcount], |
tfile[termcount], |
&entries[termcount].tterm); |
&entries[termcount].tterm); |
directory = TERMINFO; /* for error message */ |
directory = TERMINFO; /* for error message */ |
} |
} |
|
|
if (status <= 0) { |
if (status <= 0) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: couldn't open terminfo file %s.\n", |
"infocmp: couldn't open terminfo file %s.\n", |
tfile[termcount]); |
tfile[termcount]); |
return EXIT_FAILURE; |
return EXIT_FAILURE; |
} |
} |
repair_acsc(&entries[termcount].tterm); |
repair_acsc(&entries[termcount].tterm); |
|
|
case C_DEFAULT: |
case C_DEFAULT: |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: about to dump %s\n", |
"infocmp: about to dump %s\n", |
tname[0]); |
tname[0]); |
(void) printf("#\tReconstructed via infocmp from file: %s\n", |
(void) printf("#\tReconstructed via infocmp from file: %s\n", |
tfile[0]); |
tfile[0]); |
len = dump_entry(&entries[0].tterm, limited, numbers, NULL); |
len = dump_entry(&entries[0].tterm, limited, numbers, NULL); |
putchar('\n'); |
putchar('\n'); |
if (itrace) |
if (itrace) |
|
|
case C_COMMON: |
case C_COMMON: |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: dumping common capabilities\n"); |
"infocmp: dumping common capabilities\n"); |
(void) printf("comparing %s to %s.\n", tname[0], tname[1]); |
(void) printf("comparing %s to %s.\n", tname[0], tname[1]); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
break; |
break; |
|
|
case C_NAND: |
case C_NAND: |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"infocmp: dumping differences\n"); |
"infocmp: dumping differences\n"); |
(void) printf("comparing %s to %s.\n", tname[0], tname[1]); |
(void) printf("comparing %s to %s.\n", tname[0], tname[1]); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
compare_entry(compare_predicate, &entries->tterm, quiet); |
break; |
break; |
|
|
len = dump_entry(&entries[0].tterm, limited, numbers, use_predicate); |
len = dump_entry(&entries[0].tterm, limited, numbers, use_predicate); |
for (i = 1; i < termcount; i++) |
for (i = 1; i < termcount; i++) |
len += dump_uses(tname[i], !(outform == F_TERMCAP || outform |
len += dump_uses(tname[i], !(outform == F_TERMCAP || outform |
== F_TCONVERR)); |
== F_TCONVERR)); |
putchar('\n'); |
putchar('\n'); |
if (itrace) |
if (itrace) |
(void) fprintf(stderr, "infocmp: length %d\n", len); |
(void) fprintf(stderr, "infocmp: length %d\n", len); |
|
|
(void) fprintf(stderr, "Use `tic -[CI] <file>' for this.\n"); |
(void) fprintf(stderr, "Use `tic -[CI] <file>' for this.\n"); |
else if (argc - optind != 2) |
else if (argc - optind != 2) |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"File comparison needs exactly two file arguments.\n"); |
"File comparison needs exactly two file arguments.\n"); |
else |
else |
file_comparison(argc - optind, argv + optind); |
file_comparison(argc - optind, argv + optind); |
|
|