📄 setupterm.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[] = "@(#)setupterm.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.44 */#endif#ifndef NOBLIT#include <sys/jioctl.h>#endif /* NOBLIT */#include "curses_inc.h"#include "uparm.h"#ifndef _TERMPATH#define _TERMPATH(file) "/usr/lib/terminfo/file"#endif /* _TERMPATH */#include <errno.h>chtype bit_attributes[NUM_ATTRIBUTES] = { A_STANDOUT, A_UNDERLINE, A_ALTCHARSET, A_REVERSE, A_BLINK, A_DIM, A_BOLD, A_INVIS, A_PROTECT };extern char *strncpy();char *Def_term = "unknown", /* default terminal type */ term_parm_err[32], ttytype[128], _frst_tblstr[1400];static int stringsneq();TERMINAL _first_term, *cur_term = &_first_term;struct _bool_struct _frst_bools, *cur_bools = &_frst_bools;struct _num_struct _frst_nums, *cur_nums = &_frst_nums;struct _str_struct _frst_strs, *cur_strs = &_frst_strs;/* _called_before is used/cleared by delterm.c and restart.c */char _called_before = 0;short term_errno = -1;#ifdef DUMPTIextern char *boolfnames[], *boolnames[], *boolcodes[], *numfnames[], *numnames[], *numcodes[], *strfnames[], *strnames[], *strcodes[];main(argc, argv) /* FOR DEBUG ONLY */int argc;char **argv;{ if (argc > 1) setupterm(argv[1], 1, (int *)0); else setupterm((char *)0, 1, (int *)0); return (0);}_Pr(ch) /* FOR DEBUG ONLY */register int ch;{ if (ch >= 0200) { printf("M-"); ch -= 0200; } if ( (ch < ' ') || (ch == 0177) ) printf("^%c", ch ^ 0100); else printf("%c", ch);}_Sprint(n, string) /* FOR DEBUG ONLY */int n;register char *string;{ register int ch; if (n == -1) { printf(".\n"); return; } printf(", string = '"); while (ch = *string++) _Pr(ch&0377); printf("'.\n");}_Mprint(n, memory) /* FOR DEBUG ONLY */register int n;register char *memory;{ register unsigned char ch; while (ch = *memory++, n-- > 0) _Pr(ch&0377);}#define _Vr2getshi() _Vr2getsh(ip-2)#if vax || pdp11 || i386#define _Vr2getsh(ip) (* (short *) (ip))#endif /* vax || pdp11 || i386 */#ifndef _Vr2getsh/* * Here is a more portable version, which does not assume byte ordering * in shorts, sign extension, etc. */_Vr2getsh(p)register char *p;{ register int rv; if (*p == '\377') return (-1); rv = (unsigned char) *p++; rv += (unsigned char) *p * 256; return (rv);}#endif /* _Vr2getsh */#endif /* DUMPTI */#define _Getshi() _Getsh(ip) ; ip += 2/* * "function" to get a short from a pointer. The short is in a standard * format: two bytes, the first is the low order byte, the second is * the high order byte (base 256). The only negative number allowed is * -1, which is represented as 255, 255. This format happens to be the * same as the hardware on the pdp-11 and vax, making it fast and * convenient and small to do this on a pdp-11. */#if vax || pdp11 || i386#define _Getsh(ip) (* (short *) ip)#endif /* vax || pdp11 || i386 *//* * The following macro is partly due to Mike Laman, laman@sdcsvax * NCR @ Torrey Pines. - Tony Hansen */#if u3b || u3b15 || u3b2 || mc68000 || sparc#define _Getsh(ip) ((short) (*((unsigned char *) ip) | (*(ip+1) << 8)))#endif /* u3b || u3b15 || u3b2 || mc68000 || sparc */#ifndef _Getsh/* * Here is a more portable version, which does not assume byte ordering * in shorts, sign extension, etc. It does assume that the C preprocessor * does sign-extension the same as on the machine being compiled for. * When ANSI C comes along, this should be changed to check <limits.h> * to see if the low character value is negative. */static_Getsh(p)register char *p;{ register int rv, rv2;#if -1 == '\377' /* sign extension occurs */ rv = (*p++) & 0377; rv2 = (*p) & 0377;#else /* -1 == '\377' /* no sign extension */ rv = *p++; rv2 = *p;#endif /* -1 == '\377' */ if ((rv2 == 0377) && ((rv == 0377) || (rv == 0376))) return (-1); return (rv + (rv2 * 256));}#endif /* _Getsh *//* * setupterm: low level routine to dig up terminfo from database * and read it in. Parms are terminal type (0 means use getenv("TERM"), * file descriptor all output will go to (for ioctls), and a pointer * to an int into which the error return code goes (0 means to bomb * out with an error message if there's an error). Thus, * setupterm((char *)0, 1, (int *)0) is a reasonable way for a simple * program to set up. */setupterm(term, filenum, errret)char *term;int filenum; /* This is a UNIX file descriptor, not a stdio ptr. */int *errret;{ short tiebuf[2048]; char fname[1025]; /* MAXPATHLEN + 1, sigh */ register char *ip; register char *cp; int n, tfd; char *lcp, *ccp, **on_sequences, **str_array; int snames, nbools, nints, nstrs, sstrtab; char *strtab;#ifdef DUMPTI int Vr2val;#endif /* DUMPTI */ if (term == NULL) term = getenv("TERM"); if (term == NULL || *term == '\0') term = Def_term; tfd = -1; if (errret != 0) *errret = -1; if ((cp = getenv("TERMINFO")) && *cp) { if (strlen(cp) + 3 + strlen(term) > 1024) { term_errno = TERMINFO_TOO_LONG; goto out_err; } (void) strcpy(fname, cp); cp = fname + strlen(fname); *cp++ = '/'; *cp++ = *term; *cp++ = '/'; (void) strcpy(cp, term); tfd = open(fname, 0);#ifdef DUMPTI printf("looking in file %s\n", fname);#endif /* DUMPTI */ if ((tfd < 0) && (errno == EACCES)) goto cant_read; } if (tfd < 0) { (void) strcpy(fname, _TERMPATH(a/)); cp = fname + strlen(fname); cp[-2] = *term; (void) strcpy(cp, term); tfd = open(fname, 0);#ifdef DUMPTI printf("looking in file %s\n", fname);#endif /* DUMPTI */ } if (tfd < 0) { if (errno == EACCES) {cant_read: term_errno = NOT_READABLE; } else { if (access(_TERMPATH(.), 0)) term_errno = UNACCESSIBLE; else { term_errno = NO_TERMINAL; if (errret != 0) *errret = 0; } } (void) strcpy(term_parm_err, term); goto out_err; } n = read(tfd, (char *)tiebuf, sizeof tiebuf); (void) close(tfd); if (n <= 0) {corrupt: term_errno = CORRUPTED; goto out_err; } else if (n == sizeof (tiebuf)) { term_errno = ENTRY_TOO_LONG; goto out_err; } cp = ttytype; ip = (char *)tiebuf; /* Pick up header */ snames = _Getshi();#ifdef DUMPTI Vr2val = _Vr2getshi(); printf("Magic number = %d, %#o [%d, %#o].\n", snames, snames, Vr2val, Vr2val);#endif /* DUMPTI */ if (snames != MAGNUM) goto corrupt; snames = _Getshi();#ifdef DUMPTI Vr2val = _Vr2getshi(); printf("Size of names = %d, %#o [%d, %#o].\n", snames, snames, Vr2val, Vr2val);#endif /* DUMPTI */ nbools = _Getshi();#ifdef DUMPTI Vr2val = _Vr2getshi(); printf("Number of bools = %d, %#o [%d, %#o].\n", nbools, nbools, Vr2val, Vr2val);#endif /* DUMPTI */ nints = _Getshi();#ifdef DUMPTI Vr2val = _Vr2getshi(); printf("Number of ints = %d, %#o [%d, %#o].\n", nints, nints, Vr2val, Vr2val);#endif /* DUMPTI */ nstrs = _Getshi();#ifdef DUMPTI Vr2val = _Vr2getshi(); printf("Number of strings = %d, %#o [%d, %#o].\n", nstrs, nstrs, Vr2val, Vr2val);#endif /* DUMPTI */ sstrtab = _Getshi();#ifdef DUMPTI Vr2val = _Vr2getshi(); printf("Size of string table = %d, %#o [%d, %#o].\n", sstrtab, sstrtab, Vr2val, Vr2val); printf("Names are: %.*s.\n", snames, ip);#endif /* DUMPTI */ /* allocate all of the space */ strtab = NULL; if (_called_before) { /* 2nd or more times through */ if ((cur_term = (TERMINAL *) malloc(sizeof (TERMINAL))) == NULL) goto badmalloc; if ((cur_bools = (struct _bool_struct *) malloc(sizeof (struct _bool_struct))) == NULL) goto freeterminal; if ((cur_nums = (struct _num_struct *) malloc(sizeof (struct _num_struct))) == NULL) goto freebools; if ((cur_strs = (struct _str_struct *) malloc(sizeof (struct _str_struct))) == NULL) {freenums: free((char *) cur_nums);freebools: free((char *) cur_bools);freeterminal: free((char *) cur_term);badmalloc: term_errno = TERM_BAD_MALLOC;#ifdef DEBUG strcpy(term_parm_err, "setupterm");#endif /* DEBUG */out_err: if (errret == 0) { termerr(); exit(-term_errno); } else return (ERR); } } else { /* First time through */ _called_before = TRUE; cur_term = &_first_term; cur_bools = &_frst_bools; cur_nums = &_frst_nums; cur_strs = &_frst_strs; if (sstrtab < sizeof(_frst_tblstr)) strtab = _frst_tblstr; } if (strtab == NULL) { if ((strtab = (char *) malloc((unsigned) sstrtab)) == NULL) { if (cur_strs != &_frst_strs) free((char *)cur_strs); goto freenums; } } /* no more catchable errors */ if (errret) *errret = 1; (void) strncpy(cur_term->_termname, term, 50); /* In case the name is exactly 51 characters */ cur_term->_termname[50] = '\0'; cur_term->_bools = cur_bools; cur_term->_nums = cur_nums;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -