10e3d5408SPeter Wemm /**************************************************************************** 20e3d5408SPeter Wemm * Copyright (c) 1998,1999 Free Software Foundation, Inc. * 30e3d5408SPeter Wemm * * 40e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 50e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 60e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 70e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 80e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 90e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 100e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 110e3d5408SPeter Wemm * * 120e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 130e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 140e3d5408SPeter Wemm * * 150e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 160e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 170e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 180e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 190e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 200e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 210e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 220e3d5408SPeter Wemm * * 230e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 240e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 250e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 260e3d5408SPeter Wemm * authorization. * 270e3d5408SPeter Wemm ****************************************************************************/ 280e3d5408SPeter Wemm 290e3d5408SPeter Wemm /**************************************************************************** 300e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 310e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> * 320e3d5408SPeter Wemm ****************************************************************************/ 330e3d5408SPeter Wemm 340e3d5408SPeter Wemm /* 350e3d5408SPeter Wemm * tic.c --- Main program for terminfo compiler 360e3d5408SPeter Wemm * by Eric S. Raymond 370e3d5408SPeter Wemm * 380e3d5408SPeter Wemm */ 390e3d5408SPeter Wemm 400e3d5408SPeter Wemm #include <progs.priv.h> 410e3d5408SPeter Wemm 420e3d5408SPeter Wemm #include <dump_entry.h> 430e3d5408SPeter Wemm #include <term_entry.h> 440e3d5408SPeter Wemm 450e3d5408SPeter Wemm MODULE_ID("$Id: tic.c,v 1.51 1999/06/19 21:35:36 Philippe.De.Muyter Exp $") 460e3d5408SPeter Wemm 470e3d5408SPeter Wemm const char *_nc_progname = "tic"; 480e3d5408SPeter Wemm 490e3d5408SPeter Wemm static FILE *log_fp; 500e3d5408SPeter Wemm static FILE *tmp_fp; 510e3d5408SPeter Wemm static bool showsummary = FALSE; 520e3d5408SPeter Wemm static const char *to_remove; 530e3d5408SPeter Wemm 540e3d5408SPeter Wemm static void (*save_check_termtype)(TERMTYPE *); 550e3d5408SPeter Wemm static void check_termtype(TERMTYPE *tt); 560e3d5408SPeter Wemm 570e3d5408SPeter Wemm static const char usage_string[] = "[-h] [-v[n]] [-e names] [-CILNRTcfrswx1] source-file\n"; 580e3d5408SPeter Wemm 590e3d5408SPeter Wemm static void cleanup(void) 600e3d5408SPeter Wemm { 610e3d5408SPeter Wemm if (tmp_fp != 0) 620e3d5408SPeter Wemm fclose(tmp_fp); 630e3d5408SPeter Wemm if (to_remove != 0) { 640e3d5408SPeter Wemm #if HAVE_REMOVE 650e3d5408SPeter Wemm remove(to_remove); 660e3d5408SPeter Wemm #else 670e3d5408SPeter Wemm unlink(to_remove); 680e3d5408SPeter Wemm #endif 690e3d5408SPeter Wemm } 700e3d5408SPeter Wemm } 710e3d5408SPeter Wemm 720e3d5408SPeter Wemm static void failed(const char *msg) 730e3d5408SPeter Wemm { 740e3d5408SPeter Wemm perror(msg); 750e3d5408SPeter Wemm cleanup(); 760e3d5408SPeter Wemm exit(EXIT_FAILURE); 770e3d5408SPeter Wemm } 780e3d5408SPeter Wemm 790e3d5408SPeter Wemm static void usage(void) 800e3d5408SPeter Wemm { 810e3d5408SPeter Wemm static const char *const tbl[] = { 820e3d5408SPeter Wemm "Options:", 830e3d5408SPeter Wemm " -1 format translation output one capability per line", 840e3d5408SPeter Wemm " -C translate entries to termcap source form", 850e3d5408SPeter Wemm " -I translate entries to terminfo source form", 860e3d5408SPeter Wemm " -L translate entries to full terminfo source form", 870e3d5408SPeter Wemm " -N disable smart defaults for source translation", 880e3d5408SPeter Wemm " -R restrict translation to given terminfo/termcap version", 890e3d5408SPeter Wemm " -T remove size-restrictions on compiled description", 900e3d5408SPeter Wemm " -c check only, validate input without compiling or translating", 910e3d5408SPeter Wemm " -f format complex strings for readability", 920e3d5408SPeter Wemm " -G format %{number} to %'char'", 930e3d5408SPeter Wemm " -g format %'char' to %{number}", 940e3d5408SPeter Wemm " -e<names> translate/compile only entries named by comma-separated list", 950e3d5408SPeter Wemm " -o<dir> set output directory for compiled entry writes", 960e3d5408SPeter Wemm " -r force resolution of all use entries in source translation", 970e3d5408SPeter Wemm " -s print summary statistics", 980e3d5408SPeter Wemm " -v[n] set verbosity level", 990e3d5408SPeter Wemm " -w[n] set format width for translation output", 1000e3d5408SPeter Wemm #if NCURSES_XNAMES 1010e3d5408SPeter Wemm " -x treat unknown capabilities as user-defined", 1020e3d5408SPeter Wemm #endif 1030e3d5408SPeter Wemm "", 1040e3d5408SPeter Wemm "Parameters:", 1050e3d5408SPeter Wemm " <file> file to translate or compile" 1060e3d5408SPeter Wemm }; 1070e3d5408SPeter Wemm size_t j; 1080e3d5408SPeter Wemm 1090e3d5408SPeter Wemm printf("Usage: %s %s\n", _nc_progname, usage_string); 1100e3d5408SPeter Wemm for (j = 0; j < sizeof(tbl)/sizeof(tbl[0]); j++) 1110e3d5408SPeter Wemm puts(tbl[j]); 1120e3d5408SPeter Wemm exit(EXIT_FAILURE); 1130e3d5408SPeter Wemm } 1140e3d5408SPeter Wemm 1150e3d5408SPeter Wemm #define L_BRACE '{' 1160e3d5408SPeter Wemm #define R_BRACE '}' 1170e3d5408SPeter Wemm #define S_QUOTE '\''; 1180e3d5408SPeter Wemm 1190e3d5408SPeter Wemm static void write_it(ENTRY *ep) 1200e3d5408SPeter Wemm { 1210e3d5408SPeter Wemm unsigned n; 1220e3d5408SPeter Wemm int ch; 1230e3d5408SPeter Wemm char *s, *d, *t; 1240e3d5408SPeter Wemm char result[MAX_ENTRY_SIZE]; 1250e3d5408SPeter Wemm 1260e3d5408SPeter Wemm /* 1270e3d5408SPeter Wemm * Look for strings that contain %{number}, convert them to %'char', 1280e3d5408SPeter Wemm * which is shorter and runs a little faster. 1290e3d5408SPeter Wemm */ 1300e3d5408SPeter Wemm for (n = 0; n < STRCOUNT; n++) { 1310e3d5408SPeter Wemm s = ep->tterm.Strings[n]; 1320e3d5408SPeter Wemm if (VALID_STRING(s) 1330e3d5408SPeter Wemm && strchr(s, L_BRACE) != 0) { 1340e3d5408SPeter Wemm d = result; 1350e3d5408SPeter Wemm t = s; 1360e3d5408SPeter Wemm while ((ch = *t++) != 0) { 1370e3d5408SPeter Wemm *d++ = ch; 1380e3d5408SPeter Wemm if (ch == '\\') { 1390e3d5408SPeter Wemm *d++ = *t++; 1400e3d5408SPeter Wemm } else if ((ch == '%') 1410e3d5408SPeter Wemm && (*t == L_BRACE)) { 1420e3d5408SPeter Wemm char *v = 0; 1430e3d5408SPeter Wemm long value = strtol(t+1, &v, 0); 1440e3d5408SPeter Wemm if (v != 0 1450e3d5408SPeter Wemm && *v == R_BRACE 1460e3d5408SPeter Wemm && value > 0 1470e3d5408SPeter Wemm && value != '\\' /* FIXME */ 1480e3d5408SPeter Wemm && value < 127 1490e3d5408SPeter Wemm && isprint((int)value)) { 1500e3d5408SPeter Wemm *d++ = S_QUOTE; 1510e3d5408SPeter Wemm *d++ = (int)value; 1520e3d5408SPeter Wemm *d++ = S_QUOTE; 1530e3d5408SPeter Wemm t = (v + 1); 1540e3d5408SPeter Wemm } 1550e3d5408SPeter Wemm } 1560e3d5408SPeter Wemm } 1570e3d5408SPeter Wemm *d = 0; 1580e3d5408SPeter Wemm if (strlen(result) < strlen(s)) 1590e3d5408SPeter Wemm strcpy(s, result); 1600e3d5408SPeter Wemm } 1610e3d5408SPeter Wemm } 1620e3d5408SPeter Wemm 1630e3d5408SPeter Wemm _nc_set_type(_nc_first_name(ep->tterm.term_names)); 1640e3d5408SPeter Wemm _nc_curr_line = ep->startline; 1650e3d5408SPeter Wemm _nc_write_entry(&ep->tterm); 1660e3d5408SPeter Wemm } 1670e3d5408SPeter Wemm 1680e3d5408SPeter Wemm static bool immedhook(ENTRY *ep GCC_UNUSED) 1690e3d5408SPeter Wemm /* write out entries with no use capabilities immediately to save storage */ 1700e3d5408SPeter Wemm { 1710e3d5408SPeter Wemm #ifndef HAVE_BIG_CORE 1720e3d5408SPeter Wemm /* 1730e3d5408SPeter Wemm * This is strictly a core-economy kluge. The really clean way to handle 1740e3d5408SPeter Wemm * compilation is to slurp the whole file into core and then do all the 1750e3d5408SPeter Wemm * name-collision checks and entry writes in one swell foop. But the 1760e3d5408SPeter Wemm * terminfo master file is large enough that some core-poor systems swap 1770e3d5408SPeter Wemm * like crazy when you compile it this way...there have been reports of 1780e3d5408SPeter Wemm * this process taking *three hours*, rather than the twenty seconds or 1790e3d5408SPeter Wemm * less typical on my development box. 1800e3d5408SPeter Wemm * 1810e3d5408SPeter Wemm * So. This hook *immediately* writes out the referenced entry if it 1820e3d5408SPeter Wemm * has no use capabilities. The compiler main loop refrains from 1830e3d5408SPeter Wemm * adding the entry to the in-core list when this hook fires. If some 1840e3d5408SPeter Wemm * other entry later needs to reference an entry that got written 1850e3d5408SPeter Wemm * immediately, that's OK; the resolution code will fetch it off disk 1860e3d5408SPeter Wemm * when it can't find it in core. 1870e3d5408SPeter Wemm * 1880e3d5408SPeter Wemm * Name collisions will still be detected, just not as cleanly. The 1890e3d5408SPeter Wemm * write_entry() code complains before overwriting an entry that 1900e3d5408SPeter Wemm * postdates the time of tic's first call to write_entry(). Thus 1910e3d5408SPeter Wemm * it will complain about overwriting entries newly made during the 1920e3d5408SPeter Wemm * tic run, but not about overwriting ones that predate it. 1930e3d5408SPeter Wemm * 1940e3d5408SPeter Wemm * The reason this is a hook, and not in line with the rest of the 1950e3d5408SPeter Wemm * compiler code, is that the support for termcap fallback cannot assume 1960e3d5408SPeter Wemm * it has anywhere to spool out these entries! 1970e3d5408SPeter Wemm * 1980e3d5408SPeter Wemm * The _nc_set_type() call here requires a compensating one in 1990e3d5408SPeter Wemm * _nc_parse_entry(). 2000e3d5408SPeter Wemm * 2010e3d5408SPeter Wemm * If you define HAVE_BIG_CORE, you'll disable this kluge. This will 2020e3d5408SPeter Wemm * make tic a bit faster (because the resolution code won't have to do 2030e3d5408SPeter Wemm * disk I/O nearly as often). 2040e3d5408SPeter Wemm */ 2050e3d5408SPeter Wemm if (ep->nuses == 0) 2060e3d5408SPeter Wemm { 2070e3d5408SPeter Wemm int oldline = _nc_curr_line; 2080e3d5408SPeter Wemm 2090e3d5408SPeter Wemm write_it(ep); 2100e3d5408SPeter Wemm _nc_curr_line = oldline; 2110e3d5408SPeter Wemm free(ep->tterm.str_table); 2120e3d5408SPeter Wemm return(TRUE); 2130e3d5408SPeter Wemm } 2140e3d5408SPeter Wemm #endif /* HAVE_BIG_CORE */ 2150e3d5408SPeter Wemm return(FALSE); 2160e3d5408SPeter Wemm } 2170e3d5408SPeter Wemm 2180e3d5408SPeter Wemm static void put_translate(int c) 2190e3d5408SPeter Wemm /* emit a comment char, translating terminfo names to termcap names */ 2200e3d5408SPeter Wemm { 2210e3d5408SPeter Wemm static bool in_name = FALSE; 2220e3d5408SPeter Wemm static char namebuf[132], suffix[132], *sp; 2230e3d5408SPeter Wemm 2240e3d5408SPeter Wemm if (!in_name) 2250e3d5408SPeter Wemm { 2260e3d5408SPeter Wemm if (c == '<') 2270e3d5408SPeter Wemm { 2280e3d5408SPeter Wemm in_name = TRUE; 2290e3d5408SPeter Wemm sp = namebuf; 2300e3d5408SPeter Wemm } 2310e3d5408SPeter Wemm else 2320e3d5408SPeter Wemm putchar(c); 2330e3d5408SPeter Wemm } 2340e3d5408SPeter Wemm else if (c == '\n' || c == '@') 2350e3d5408SPeter Wemm { 2360e3d5408SPeter Wemm *sp++ = '\0'; 2370e3d5408SPeter Wemm (void) putchar('<'); 2380e3d5408SPeter Wemm (void) fputs(namebuf, stdout); 2390e3d5408SPeter Wemm putchar(c); 2400e3d5408SPeter Wemm in_name = FALSE; 2410e3d5408SPeter Wemm } 2420e3d5408SPeter Wemm else if (c != '>') 2430e3d5408SPeter Wemm *sp++ = c; 2440e3d5408SPeter Wemm else /* ah! candidate name! */ 2450e3d5408SPeter Wemm { 2460e3d5408SPeter Wemm char *up; 2470e3d5408SPeter Wemm NCURSES_CONST char *tp; 2480e3d5408SPeter Wemm 2490e3d5408SPeter Wemm *sp++ = '\0'; 2500e3d5408SPeter Wemm in_name = FALSE; 2510e3d5408SPeter Wemm 2520e3d5408SPeter Wemm suffix[0] = '\0'; 2530e3d5408SPeter Wemm if ((up = strchr(namebuf, '#')) != 0 2540e3d5408SPeter Wemm || (up = strchr(namebuf, '=')) != 0 2550e3d5408SPeter Wemm || ((up = strchr(namebuf, '@')) != 0 && up[1] == '>')) 2560e3d5408SPeter Wemm { 2570e3d5408SPeter Wemm (void) strcpy(suffix, up); 2580e3d5408SPeter Wemm *up = '\0'; 2590e3d5408SPeter Wemm } 2600e3d5408SPeter Wemm 2610e3d5408SPeter Wemm if ((tp = nametrans(namebuf)) != 0) 2620e3d5408SPeter Wemm { 2630e3d5408SPeter Wemm (void) putchar(':'); 2640e3d5408SPeter Wemm (void) fputs(tp, stdout); 2650e3d5408SPeter Wemm (void) fputs(suffix, stdout); 2660e3d5408SPeter Wemm (void) putchar(':'); 2670e3d5408SPeter Wemm } 2680e3d5408SPeter Wemm else 2690e3d5408SPeter Wemm { 2700e3d5408SPeter Wemm /* couldn't find a translation, just dump the name */ 2710e3d5408SPeter Wemm (void) putchar('<'); 2720e3d5408SPeter Wemm (void) fputs(namebuf, stdout); 2730e3d5408SPeter Wemm (void) fputs(suffix, stdout); 2740e3d5408SPeter Wemm (void) putchar('>'); 2750e3d5408SPeter Wemm } 2760e3d5408SPeter Wemm 2770e3d5408SPeter Wemm } 2780e3d5408SPeter Wemm } 2790e3d5408SPeter Wemm 2800e3d5408SPeter Wemm /* Returns a string, stripped of leading/trailing whitespace */ 2810e3d5408SPeter Wemm static char *stripped(char *src) 2820e3d5408SPeter Wemm { 2830e3d5408SPeter Wemm while (isspace(*src)) 2840e3d5408SPeter Wemm src++; 2850e3d5408SPeter Wemm if (*src != '\0') { 2860e3d5408SPeter Wemm char *dst = strcpy(malloc(strlen(src)+1), src); 2870e3d5408SPeter Wemm size_t len = strlen(dst); 2880e3d5408SPeter Wemm while (--len != 0 && isspace(dst[len])) 2890e3d5408SPeter Wemm dst[len] = '\0'; 2900e3d5408SPeter Wemm return dst; 2910e3d5408SPeter Wemm } 2920e3d5408SPeter Wemm return 0; 2930e3d5408SPeter Wemm } 2940e3d5408SPeter Wemm 2950e3d5408SPeter Wemm /* Parse the "-e" option-value into a list of names */ 2960e3d5408SPeter Wemm static const char **make_namelist(char *src) 2970e3d5408SPeter Wemm { 2980e3d5408SPeter Wemm const char **dst = 0; 2990e3d5408SPeter Wemm 3000e3d5408SPeter Wemm char *s, *base; 3010e3d5408SPeter Wemm unsigned pass, n, nn; 3020e3d5408SPeter Wemm char buffer[BUFSIZ]; 3030e3d5408SPeter Wemm 3040e3d5408SPeter Wemm if (src == 0) { 3050e3d5408SPeter Wemm /* EMPTY */; 3060e3d5408SPeter Wemm } else if (strchr(src, '/') != 0) { /* a filename */ 3070e3d5408SPeter Wemm FILE *fp = fopen(src, "r"); 3080e3d5408SPeter Wemm if (fp == 0) 3090e3d5408SPeter Wemm failed(src); 3100e3d5408SPeter Wemm 3110e3d5408SPeter Wemm for (pass = 1; pass <= 2; pass++) { 3120e3d5408SPeter Wemm nn = 0; 3130e3d5408SPeter Wemm while (fgets(buffer, sizeof(buffer), fp) != 0) { 3140e3d5408SPeter Wemm if ((s = stripped(buffer)) != 0) { 3150e3d5408SPeter Wemm if (dst != 0) 3160e3d5408SPeter Wemm dst[nn] = s; 3170e3d5408SPeter Wemm nn++; 3180e3d5408SPeter Wemm } 3190e3d5408SPeter Wemm } 3200e3d5408SPeter Wemm if (pass == 1) { 3210e3d5408SPeter Wemm dst = (const char **)calloc(nn+1, sizeof(*dst)); 3220e3d5408SPeter Wemm rewind(fp); 3230e3d5408SPeter Wemm } 3240e3d5408SPeter Wemm } 3250e3d5408SPeter Wemm fclose(fp); 3260e3d5408SPeter Wemm } else { /* literal list of names */ 3270e3d5408SPeter Wemm for (pass = 1; pass <= 2; pass++) { 3280e3d5408SPeter Wemm for (n = nn = 0, base = src; ; n++) { 3290e3d5408SPeter Wemm int mark = src[n]; 3300e3d5408SPeter Wemm if (mark == ',' || mark == '\0') { 3310e3d5408SPeter Wemm if (pass == 1) { 3320e3d5408SPeter Wemm nn++; 3330e3d5408SPeter Wemm } else { 3340e3d5408SPeter Wemm src[n] = '\0'; 3350e3d5408SPeter Wemm if ((s = stripped(base)) != 0) 3360e3d5408SPeter Wemm dst[nn++] = s; 3370e3d5408SPeter Wemm base = &src[n+1]; 3380e3d5408SPeter Wemm } 3390e3d5408SPeter Wemm } 3400e3d5408SPeter Wemm if (mark == '\0') 3410e3d5408SPeter Wemm break; 3420e3d5408SPeter Wemm } 3430e3d5408SPeter Wemm if (pass == 1) 3440e3d5408SPeter Wemm dst = (const char **)calloc(nn+1, sizeof(*dst)); 3450e3d5408SPeter Wemm } 3460e3d5408SPeter Wemm } 3470e3d5408SPeter Wemm if (showsummary) { 3480e3d5408SPeter Wemm fprintf(log_fp, "Entries that will be compiled:\n"); 3490e3d5408SPeter Wemm for (n = 0; dst[n] != 0; n++) 3500e3d5408SPeter Wemm fprintf(log_fp, "%d:%s\n", n+1, dst[n]); 3510e3d5408SPeter Wemm } 3520e3d5408SPeter Wemm return dst; 3530e3d5408SPeter Wemm } 3540e3d5408SPeter Wemm 3550e3d5408SPeter Wemm static bool matches(const char **needle, const char *haystack) 3560e3d5408SPeter Wemm /* does entry in needle list match |-separated field in haystack? */ 3570e3d5408SPeter Wemm { 3580e3d5408SPeter Wemm bool code = FALSE; 3590e3d5408SPeter Wemm size_t n; 3600e3d5408SPeter Wemm 3610e3d5408SPeter Wemm if (needle != 0) 3620e3d5408SPeter Wemm { 3630e3d5408SPeter Wemm for (n = 0; needle[n] != 0; n++) 3640e3d5408SPeter Wemm { 3650e3d5408SPeter Wemm if (_nc_name_match(haystack, needle[n], "|")) 3660e3d5408SPeter Wemm { 3670e3d5408SPeter Wemm code = TRUE; 3680e3d5408SPeter Wemm break; 3690e3d5408SPeter Wemm } 3700e3d5408SPeter Wemm } 3710e3d5408SPeter Wemm } 3720e3d5408SPeter Wemm else 3730e3d5408SPeter Wemm code = TRUE; 3740e3d5408SPeter Wemm return(code); 3750e3d5408SPeter Wemm } 3760e3d5408SPeter Wemm 3770e3d5408SPeter Wemm int main (int argc, char *argv[]) 3780e3d5408SPeter Wemm { 3790e3d5408SPeter Wemm char my_tmpname[PATH_MAX]; 3800e3d5408SPeter Wemm int v_opt = -1, debug_level; 3810e3d5408SPeter Wemm int smart_defaults = TRUE; 3820e3d5408SPeter Wemm char *termcap; 3830e3d5408SPeter Wemm ENTRY *qp; 3840e3d5408SPeter Wemm 3850e3d5408SPeter Wemm int this_opt, last_opt = '?'; 3860e3d5408SPeter Wemm 3870e3d5408SPeter Wemm int outform = F_TERMINFO; /* output format */ 3880e3d5408SPeter Wemm int sortmode = S_TERMINFO; /* sort_mode */ 3890e3d5408SPeter Wemm 3900e3d5408SPeter Wemm int width = 60; 3910e3d5408SPeter Wemm bool formatted = FALSE; /* reformat complex strings? */ 3920e3d5408SPeter Wemm int numbers = 0; /* format "%'char'" to/from "%{number}" */ 3930e3d5408SPeter Wemm bool infodump = FALSE; /* running as captoinfo? */ 3940e3d5408SPeter Wemm bool capdump = FALSE; /* running as infotocap? */ 3950e3d5408SPeter Wemm bool forceresolve = FALSE; /* force resolution */ 3960e3d5408SPeter Wemm bool limited = TRUE; 3970e3d5408SPeter Wemm char *tversion = (char *)NULL; 3980e3d5408SPeter Wemm const char *source_file = "terminfo"; 3990e3d5408SPeter Wemm const char **namelst = 0; 4000e3d5408SPeter Wemm char *outdir = (char *)NULL; 4010e3d5408SPeter Wemm bool check_only = FALSE; 4020e3d5408SPeter Wemm 4030e3d5408SPeter Wemm log_fp = stderr; 4040e3d5408SPeter Wemm 4050e3d5408SPeter Wemm if ((_nc_progname = strrchr(argv[0], '/')) == NULL) 4060e3d5408SPeter Wemm _nc_progname = argv[0]; 4070e3d5408SPeter Wemm else 4080e3d5408SPeter Wemm _nc_progname++; 4090e3d5408SPeter Wemm 4100e3d5408SPeter Wemm infodump = (strcmp(_nc_progname, "captoinfo") == 0); 4110e3d5408SPeter Wemm capdump = (strcmp(_nc_progname, "infotocap") == 0); 4120e3d5408SPeter Wemm #if NCURSES_XNAMES 4130e3d5408SPeter Wemm use_extended_names(FALSE); 4140e3d5408SPeter Wemm #endif 4150e3d5408SPeter Wemm 4160e3d5408SPeter Wemm /* 4170e3d5408SPeter Wemm * Processing arguments is a little complicated, since someone made a 4180e3d5408SPeter Wemm * design decision to allow the numeric values for -w, -v options to 4190e3d5408SPeter Wemm * be optional. 4200e3d5408SPeter Wemm */ 4210e3d5408SPeter Wemm while ((this_opt = getopt(argc, argv, "0123456789CILNR:TVce:fGgo:rsvwx")) != EOF) { 4220e3d5408SPeter Wemm if (isdigit(this_opt)) { 4230e3d5408SPeter Wemm switch (last_opt) { 4240e3d5408SPeter Wemm case 'v': 4250e3d5408SPeter Wemm v_opt = (v_opt * 10) + (this_opt - '0'); 4260e3d5408SPeter Wemm break; 4270e3d5408SPeter Wemm case 'w': 4280e3d5408SPeter Wemm width = (width * 10) + (this_opt - '0'); 4290e3d5408SPeter Wemm break; 4300e3d5408SPeter Wemm default: 4310e3d5408SPeter Wemm if (this_opt != '1') 4320e3d5408SPeter Wemm usage(); 4330e3d5408SPeter Wemm last_opt = this_opt; 4340e3d5408SPeter Wemm width = 0; 4350e3d5408SPeter Wemm } 4360e3d5408SPeter Wemm continue; 4370e3d5408SPeter Wemm } 4380e3d5408SPeter Wemm switch (this_opt) { 4390e3d5408SPeter Wemm case 'C': 4400e3d5408SPeter Wemm capdump = TRUE; 4410e3d5408SPeter Wemm outform = F_TERMCAP; 4420e3d5408SPeter Wemm sortmode = S_TERMCAP; 4430e3d5408SPeter Wemm break; 4440e3d5408SPeter Wemm case 'I': 4450e3d5408SPeter Wemm infodump = TRUE; 4460e3d5408SPeter Wemm outform = F_TERMINFO; 4470e3d5408SPeter Wemm sortmode = S_TERMINFO; 4480e3d5408SPeter Wemm break; 4490e3d5408SPeter Wemm case 'L': 4500e3d5408SPeter Wemm infodump = TRUE; 4510e3d5408SPeter Wemm outform = F_VARIABLE; 4520e3d5408SPeter Wemm sortmode = S_VARIABLE; 4530e3d5408SPeter Wemm break; 4540e3d5408SPeter Wemm case 'N': 4550e3d5408SPeter Wemm smart_defaults = FALSE; 4560e3d5408SPeter Wemm break; 4570e3d5408SPeter Wemm case 'R': 4580e3d5408SPeter Wemm tversion = optarg; 4590e3d5408SPeter Wemm break; 4600e3d5408SPeter Wemm case 'T': 4610e3d5408SPeter Wemm limited = FALSE; 4620e3d5408SPeter Wemm break; 4630e3d5408SPeter Wemm case 'V': 4640e3d5408SPeter Wemm puts(NCURSES_VERSION); 4650e3d5408SPeter Wemm return EXIT_SUCCESS; 4660e3d5408SPeter Wemm case 'c': 4670e3d5408SPeter Wemm check_only = TRUE; 4680e3d5408SPeter Wemm break; 4690e3d5408SPeter Wemm case 'e': 4700e3d5408SPeter Wemm namelst = make_namelist(optarg); 4710e3d5408SPeter Wemm break; 4720e3d5408SPeter Wemm case 'f': 4730e3d5408SPeter Wemm formatted = TRUE; 4740e3d5408SPeter Wemm break; 4750e3d5408SPeter Wemm case 'G': 4760e3d5408SPeter Wemm numbers = 1; 4770e3d5408SPeter Wemm break; 4780e3d5408SPeter Wemm case 'g': 4790e3d5408SPeter Wemm numbers = -1; 4800e3d5408SPeter Wemm break; 4810e3d5408SPeter Wemm case 'o': 4820e3d5408SPeter Wemm outdir = optarg; 4830e3d5408SPeter Wemm break; 4840e3d5408SPeter Wemm case 'r': 4850e3d5408SPeter Wemm forceresolve = TRUE; 4860e3d5408SPeter Wemm break; 4870e3d5408SPeter Wemm case 's': 4880e3d5408SPeter Wemm showsummary = TRUE; 4890e3d5408SPeter Wemm break; 4900e3d5408SPeter Wemm case 'v': 4910e3d5408SPeter Wemm v_opt = 0; 4920e3d5408SPeter Wemm break; 4930e3d5408SPeter Wemm case 'w': 4940e3d5408SPeter Wemm width = 0; 4950e3d5408SPeter Wemm break; 4960e3d5408SPeter Wemm #if NCURSES_XNAMES 4970e3d5408SPeter Wemm case 'x': 4980e3d5408SPeter Wemm use_extended_names(TRUE); 4990e3d5408SPeter Wemm break; 5000e3d5408SPeter Wemm #endif 5010e3d5408SPeter Wemm default: 5020e3d5408SPeter Wemm usage(); 5030e3d5408SPeter Wemm } 5040e3d5408SPeter Wemm last_opt = this_opt; 5050e3d5408SPeter Wemm } 5060e3d5408SPeter Wemm 5070e3d5408SPeter Wemm debug_level = (v_opt > 0) ? v_opt : (v_opt == 0); 5080e3d5408SPeter Wemm _nc_tracing = (1 << debug_level) - 1; 5090e3d5408SPeter Wemm 5100e3d5408SPeter Wemm if (_nc_tracing) 5110e3d5408SPeter Wemm { 5120e3d5408SPeter Wemm save_check_termtype = _nc_check_termtype; 5130e3d5408SPeter Wemm _nc_check_termtype = check_termtype; 5140e3d5408SPeter Wemm } 5150e3d5408SPeter Wemm 5160e3d5408SPeter Wemm #ifndef HAVE_BIG_CORE 5170e3d5408SPeter Wemm /* 5180e3d5408SPeter Wemm * Aaargh! immedhook seriously hoses us! 5190e3d5408SPeter Wemm * 5200e3d5408SPeter Wemm * One problem with immedhook is it means we can't do -e. Problem 5210e3d5408SPeter Wemm * is that we can't guarantee that for each terminal listed, all the 5220e3d5408SPeter Wemm * terminals it depends on will have been kept in core for reference 5230e3d5408SPeter Wemm * resolution -- in fact it's certain the primitive types at the end 5240e3d5408SPeter Wemm * of reference chains *won't* be in core unless they were explicitly 5250e3d5408SPeter Wemm * in the select list themselves. 5260e3d5408SPeter Wemm */ 5270e3d5408SPeter Wemm if (namelst && (!infodump && !capdump)) 5280e3d5408SPeter Wemm { 5290e3d5408SPeter Wemm (void) fprintf(stderr, 5300e3d5408SPeter Wemm "Sorry, -e can't be used without -I or -C\n"); 5310e3d5408SPeter Wemm cleanup(); 5320e3d5408SPeter Wemm return EXIT_FAILURE; 5330e3d5408SPeter Wemm } 5340e3d5408SPeter Wemm #endif /* HAVE_BIG_CORE */ 5350e3d5408SPeter Wemm 5360e3d5408SPeter Wemm if (optind < argc) { 5370e3d5408SPeter Wemm source_file = argv[optind++]; 5380e3d5408SPeter Wemm if (optind < argc) { 5390e3d5408SPeter Wemm fprintf (stderr, 5400e3d5408SPeter Wemm "%s: Too many file names. Usage:\n\t%s %s", 5410e3d5408SPeter Wemm _nc_progname, 5420e3d5408SPeter Wemm _nc_progname, 5430e3d5408SPeter Wemm usage_string); 5440e3d5408SPeter Wemm return EXIT_FAILURE; 5450e3d5408SPeter Wemm } 5460e3d5408SPeter Wemm } else { 5470e3d5408SPeter Wemm if (infodump == TRUE) { 5480e3d5408SPeter Wemm /* captoinfo's no-argument case */ 5490e3d5408SPeter Wemm source_file = "/etc/termcap"; 5500e3d5408SPeter Wemm if ((termcap = getenv("TERMCAP")) != 0 5510e3d5408SPeter Wemm && (namelst = make_namelist(getenv("TERM"))) != 0) { 5520e3d5408SPeter Wemm if (access(termcap, F_OK) == 0) { 5530e3d5408SPeter Wemm /* file exists */ 5540e3d5408SPeter Wemm source_file = termcap; 5550e3d5408SPeter Wemm } else 5560e3d5408SPeter Wemm if ((source_file = tmpnam(my_tmpname)) != 0 5570e3d5408SPeter Wemm && (tmp_fp = fopen(source_file, "w")) != 0) { 5580e3d5408SPeter Wemm fprintf(tmp_fp, "%s\n", termcap); 5590e3d5408SPeter Wemm fclose(tmp_fp); 5600e3d5408SPeter Wemm tmp_fp = fopen(source_file, "r"); 5610e3d5408SPeter Wemm to_remove = source_file; 5620e3d5408SPeter Wemm } else { 5630e3d5408SPeter Wemm failed("tmpnam"); 5640e3d5408SPeter Wemm } 5650e3d5408SPeter Wemm } 5660e3d5408SPeter Wemm } else { 5670e3d5408SPeter Wemm /* tic */ 5680e3d5408SPeter Wemm fprintf (stderr, 5690e3d5408SPeter Wemm "%s: File name needed. Usage:\n\t%s %s", 5700e3d5408SPeter Wemm _nc_progname, 5710e3d5408SPeter Wemm _nc_progname, 5720e3d5408SPeter Wemm usage_string); 5730e3d5408SPeter Wemm cleanup(); 5740e3d5408SPeter Wemm return EXIT_FAILURE; 5750e3d5408SPeter Wemm } 5760e3d5408SPeter Wemm } 5770e3d5408SPeter Wemm 5780e3d5408SPeter Wemm if (tmp_fp == 0 5790e3d5408SPeter Wemm && (tmp_fp = fopen(source_file, "r")) == 0) { 5800e3d5408SPeter Wemm fprintf (stderr, "%s: Can't open %s\n", _nc_progname, source_file); 5810e3d5408SPeter Wemm return EXIT_FAILURE; 5820e3d5408SPeter Wemm } 5830e3d5408SPeter Wemm 5840e3d5408SPeter Wemm if (infodump) 5850e3d5408SPeter Wemm dump_init(tversion, 5860e3d5408SPeter Wemm smart_defaults 5870e3d5408SPeter Wemm ? outform 5880e3d5408SPeter Wemm : F_LITERAL, 5890e3d5408SPeter Wemm sortmode, width, debug_level, formatted); 5900e3d5408SPeter Wemm else if (capdump) 5910e3d5408SPeter Wemm dump_init(tversion, 5920e3d5408SPeter Wemm outform, 5930e3d5408SPeter Wemm sortmode, width, debug_level, FALSE); 5940e3d5408SPeter Wemm 5950e3d5408SPeter Wemm /* parse entries out of the source file */ 5960e3d5408SPeter Wemm _nc_set_source(source_file); 5970e3d5408SPeter Wemm #ifndef HAVE_BIG_CORE 5980e3d5408SPeter Wemm if (!(check_only || infodump || capdump)) 5990e3d5408SPeter Wemm _nc_set_writedir(outdir); 6000e3d5408SPeter Wemm #endif /* HAVE_BIG_CORE */ 6010e3d5408SPeter Wemm _nc_read_entry_source(tmp_fp, (char *)NULL, 6020e3d5408SPeter Wemm !smart_defaults, FALSE, 6030e3d5408SPeter Wemm (check_only || infodump || capdump) ? NULLHOOK : immedhook); 6040e3d5408SPeter Wemm 6050e3d5408SPeter Wemm /* do use resolution */ 6060e3d5408SPeter Wemm if (check_only || (!infodump && !capdump) || forceresolve) { 6070e3d5408SPeter Wemm if (!_nc_resolve_uses() && !check_only) { 6080e3d5408SPeter Wemm cleanup(); 6090e3d5408SPeter Wemm return EXIT_FAILURE; 6100e3d5408SPeter Wemm } 6110e3d5408SPeter Wemm } 6120e3d5408SPeter Wemm 6130e3d5408SPeter Wemm /* length check */ 6140e3d5408SPeter Wemm if (check_only && (capdump || infodump)) 6150e3d5408SPeter Wemm { 6160e3d5408SPeter Wemm for_entry_list(qp) 6170e3d5408SPeter Wemm { 6180e3d5408SPeter Wemm if (matches(namelst, qp->tterm.term_names)) 6190e3d5408SPeter Wemm { 6200e3d5408SPeter Wemm int len = fmt_entry(&qp->tterm, NULL, TRUE, infodump, numbers); 6210e3d5408SPeter Wemm 6220e3d5408SPeter Wemm if (len>(infodump?MAX_TERMINFO_LENGTH:MAX_TERMCAP_LENGTH)) 6230e3d5408SPeter Wemm (void) fprintf(stderr, 6240e3d5408SPeter Wemm "warning: resolved %s entry is %d bytes long\n", 6250e3d5408SPeter Wemm _nc_first_name(qp->tterm.term_names), 6260e3d5408SPeter Wemm len); 6270e3d5408SPeter Wemm } 6280e3d5408SPeter Wemm } 6290e3d5408SPeter Wemm } 6300e3d5408SPeter Wemm 6310e3d5408SPeter Wemm /* write or dump all entries */ 6320e3d5408SPeter Wemm if (!check_only) 6330e3d5408SPeter Wemm { 6340e3d5408SPeter Wemm if (!infodump && !capdump) 6350e3d5408SPeter Wemm { 6360e3d5408SPeter Wemm _nc_set_writedir(outdir); 6370e3d5408SPeter Wemm for_entry_list(qp) 6380e3d5408SPeter Wemm if (matches(namelst, qp->tterm.term_names)) 6390e3d5408SPeter Wemm write_it(qp); 6400e3d5408SPeter Wemm } 6410e3d5408SPeter Wemm else 6420e3d5408SPeter Wemm { 6430e3d5408SPeter Wemm /* this is in case infotocap() generates warnings */ 6440e3d5408SPeter Wemm _nc_curr_col = _nc_curr_line = -1; 6450e3d5408SPeter Wemm 6460e3d5408SPeter Wemm for_entry_list(qp) 6470e3d5408SPeter Wemm if (matches(namelst, qp->tterm.term_names)) 6480e3d5408SPeter Wemm { 6490e3d5408SPeter Wemm int j = qp->cend - qp->cstart; 6500e3d5408SPeter Wemm int len = 0; 6510e3d5408SPeter Wemm 6520e3d5408SPeter Wemm /* this is in case infotocap() generates warnings */ 6530e3d5408SPeter Wemm _nc_set_type(_nc_first_name(qp->tterm.term_names)); 6540e3d5408SPeter Wemm 6550e3d5408SPeter Wemm (void) fseek(tmp_fp, qp->cstart, SEEK_SET); 6560e3d5408SPeter Wemm while (j-- ) 6570e3d5408SPeter Wemm if (infodump) 6580e3d5408SPeter Wemm (void) putchar(fgetc(tmp_fp)); 6590e3d5408SPeter Wemm else 6600e3d5408SPeter Wemm put_translate(fgetc(tmp_fp)); 6610e3d5408SPeter Wemm 6620e3d5408SPeter Wemm len = dump_entry(&qp->tterm, limited, numbers, NULL); 6630e3d5408SPeter Wemm for (j = 0; j < qp->nuses; j++) 6640e3d5408SPeter Wemm len += dump_uses((char *)(qp->uses[j].parent), infodump); 6650e3d5408SPeter Wemm (void) putchar('\n'); 6660e3d5408SPeter Wemm if (debug_level != 0 && !limited) 6670e3d5408SPeter Wemm printf("# length=%d\n", len); 6680e3d5408SPeter Wemm } 6690e3d5408SPeter Wemm if (!namelst) 6700e3d5408SPeter Wemm { 6710e3d5408SPeter Wemm int c, oldc = '\0'; 6720e3d5408SPeter Wemm bool in_comment = FALSE; 6730e3d5408SPeter Wemm bool trailing_comment = FALSE; 6740e3d5408SPeter Wemm 6750e3d5408SPeter Wemm (void) fseek(tmp_fp, _nc_tail->cend, SEEK_SET); 6760e3d5408SPeter Wemm while ((c = fgetc(tmp_fp)) != EOF) 6770e3d5408SPeter Wemm { 6780e3d5408SPeter Wemm if (oldc == '\n') { 6790e3d5408SPeter Wemm if (c == '#') { 6800e3d5408SPeter Wemm trailing_comment = TRUE; 6810e3d5408SPeter Wemm in_comment = TRUE; 6820e3d5408SPeter Wemm } else { 6830e3d5408SPeter Wemm in_comment = FALSE; 6840e3d5408SPeter Wemm } 6850e3d5408SPeter Wemm } 6860e3d5408SPeter Wemm if (trailing_comment 6870e3d5408SPeter Wemm && (in_comment || (oldc == '\n' && c == '\n'))) 6880e3d5408SPeter Wemm putchar(c); 6890e3d5408SPeter Wemm oldc = c; 6900e3d5408SPeter Wemm } 6910e3d5408SPeter Wemm } 6920e3d5408SPeter Wemm } 6930e3d5408SPeter Wemm } 6940e3d5408SPeter Wemm 6950e3d5408SPeter Wemm /* Show the directory into which entries were written, and the total 6960e3d5408SPeter Wemm * number of entries 6970e3d5408SPeter Wemm */ 6980e3d5408SPeter Wemm if (showsummary 6990e3d5408SPeter Wemm && (!(check_only || infodump || capdump))) { 7000e3d5408SPeter Wemm int total = _nc_tic_written(); 7010e3d5408SPeter Wemm if (total != 0) 7020e3d5408SPeter Wemm fprintf(log_fp, "%d entries written to %s\n", 7030e3d5408SPeter Wemm total, 7040e3d5408SPeter Wemm _nc_tic_dir((char *)0)); 7050e3d5408SPeter Wemm else 7060e3d5408SPeter Wemm fprintf(log_fp, "No entries written\n"); 7070e3d5408SPeter Wemm } 7080e3d5408SPeter Wemm cleanup(); 7090e3d5408SPeter Wemm return(EXIT_SUCCESS); 7100e3d5408SPeter Wemm } 7110e3d5408SPeter Wemm 7120e3d5408SPeter Wemm /* 7130e3d5408SPeter Wemm * This bit of legerdemain turns all the terminfo variable names into 7140e3d5408SPeter Wemm * references to locations in the arrays Booleans, Numbers, and Strings --- 7150e3d5408SPeter Wemm * precisely what's needed (see comp_parse.c). 7160e3d5408SPeter Wemm */ 7170e3d5408SPeter Wemm 7180e3d5408SPeter Wemm TERMINAL *cur_term; /* tweak to avoid linking lib_cur_term.c */ 7190e3d5408SPeter Wemm 7200e3d5408SPeter Wemm #undef CUR 7210e3d5408SPeter Wemm #define CUR tp-> 7220e3d5408SPeter Wemm 7230e3d5408SPeter Wemm /* other sanity-checks (things that we don't want in the normal 7240e3d5408SPeter Wemm * logic that reads a terminfo entry) 7250e3d5408SPeter Wemm */ 7260e3d5408SPeter Wemm static void check_termtype(TERMTYPE *tp) 7270e3d5408SPeter Wemm { 7280e3d5408SPeter Wemm bool conflict = FALSE; 7290e3d5408SPeter Wemm unsigned j, k; 7300e3d5408SPeter Wemm char fkeys[STRCOUNT]; 7310e3d5408SPeter Wemm 7320e3d5408SPeter Wemm /* 7330e3d5408SPeter Wemm * A terminal entry may contain more than one keycode assigned to 7340e3d5408SPeter Wemm * a given string (e.g., KEY_END and KEY_LL). But curses will only 7350e3d5408SPeter Wemm * return one (the last one assigned). 7360e3d5408SPeter Wemm */ 7370e3d5408SPeter Wemm memset(fkeys, 0, sizeof(fkeys)); 7380e3d5408SPeter Wemm for (j = 0; _nc_tinfo_fkeys[j].code; j++) { 7390e3d5408SPeter Wemm char *a = tp->Strings[_nc_tinfo_fkeys[j].offset]; 7400e3d5408SPeter Wemm bool first = TRUE; 7410e3d5408SPeter Wemm if (!VALID_STRING(a)) 7420e3d5408SPeter Wemm continue; 7430e3d5408SPeter Wemm for (k = j+1; _nc_tinfo_fkeys[k].code; k++) { 7440e3d5408SPeter Wemm char *b = tp->Strings[_nc_tinfo_fkeys[k].offset]; 7450e3d5408SPeter Wemm if (!VALID_STRING(b) 7460e3d5408SPeter Wemm || fkeys[k]) 7470e3d5408SPeter Wemm continue; 7480e3d5408SPeter Wemm if (!strcmp(a,b)) { 7490e3d5408SPeter Wemm fkeys[j] = 1; 7500e3d5408SPeter Wemm fkeys[k] = 1; 7510e3d5408SPeter Wemm if (first) { 7520e3d5408SPeter Wemm if (!conflict) { 7530e3d5408SPeter Wemm _nc_warning("Conflicting key definitions (using the last)"); 7540e3d5408SPeter Wemm conflict = TRUE; 7550e3d5408SPeter Wemm } 7560e3d5408SPeter Wemm fprintf(stderr, "... %s is the same as %s", 7570e3d5408SPeter Wemm keyname(_nc_tinfo_fkeys[j].code), 7580e3d5408SPeter Wemm keyname(_nc_tinfo_fkeys[k].code)); 7590e3d5408SPeter Wemm first = FALSE; 7600e3d5408SPeter Wemm } else { 7610e3d5408SPeter Wemm fprintf(stderr, ", %s", 7620e3d5408SPeter Wemm keyname(_nc_tinfo_fkeys[k].code)); 7630e3d5408SPeter Wemm } 7640e3d5408SPeter Wemm } 7650e3d5408SPeter Wemm } 7660e3d5408SPeter Wemm if (!first) 7670e3d5408SPeter Wemm fprintf(stderr, "\n"); 7680e3d5408SPeter Wemm } 7690e3d5408SPeter Wemm 7700e3d5408SPeter Wemm /* 7710e3d5408SPeter Wemm * Quick check for color. We could also check if the ANSI versus 7720e3d5408SPeter Wemm * non-ANSI strings are misused. 7730e3d5408SPeter Wemm */ 7740e3d5408SPeter Wemm if ((max_colors > 0) != (max_pairs > 0) 7750e3d5408SPeter Wemm || (max_colors > max_pairs)) 7760e3d5408SPeter Wemm _nc_warning("inconsistent values for max_colors and max_pairs"); 7770e3d5408SPeter Wemm 7780e3d5408SPeter Wemm PAIRED(set_foreground, set_background) 7790e3d5408SPeter Wemm PAIRED(set_a_foreground, set_a_background) 7800e3d5408SPeter Wemm 7810e3d5408SPeter Wemm /* 7820e3d5408SPeter Wemm * These may be mismatched because the terminal description relies on 7830e3d5408SPeter Wemm * restoring the cursor visibility by resetting it. 7840e3d5408SPeter Wemm */ 7850e3d5408SPeter Wemm ANDMISSING(cursor_invisible, cursor_normal) 7860e3d5408SPeter Wemm ANDMISSING(cursor_visible, cursor_normal) 7870e3d5408SPeter Wemm 7880e3d5408SPeter Wemm /* 7890e3d5408SPeter Wemm * From XSI & O'Reilly, we gather that sc/rc are required if csr is 7900e3d5408SPeter Wemm * given, because the cursor position after the scrolling operation is 7910e3d5408SPeter Wemm * performed is undefined. 7920e3d5408SPeter Wemm */ 7930e3d5408SPeter Wemm ANDMISSING(change_scroll_region, save_cursor) 7940e3d5408SPeter Wemm ANDMISSING(change_scroll_region, restore_cursor) 7950e3d5408SPeter Wemm 7960e3d5408SPeter Wemm /* 7970e3d5408SPeter Wemm * Some standard applications (e.g., vi) and some non-curses 7980e3d5408SPeter Wemm * applications (e.g., jove) get confused if we have both ich/ich1 and 7990e3d5408SPeter Wemm * smir/rmir. Let's be nice and warn about that, too, even though 8000e3d5408SPeter Wemm * ncurses handles it. 8010e3d5408SPeter Wemm */ 8020e3d5408SPeter Wemm if ((PRESENT(enter_insert_mode) || PRESENT(exit_insert_mode)) 8030e3d5408SPeter Wemm && (PRESENT(insert_character) || PRESENT(parm_ich))) { 8040e3d5408SPeter Wemm _nc_warning("non-curses applications may be confused by ich/ich1 with smir/rmir"); 8050e3d5408SPeter Wemm } 8060e3d5408SPeter Wemm 8070e3d5408SPeter Wemm /* 8080e3d5408SPeter Wemm * Finally, do the non-verbose checks 8090e3d5408SPeter Wemm */ 8100e3d5408SPeter Wemm if (save_check_termtype != 0) 8110e3d5408SPeter Wemm save_check_termtype(tp); 8120e3d5408SPeter Wemm } 813