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

📄 otic.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	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[] = "@(#)otic.c 1.1 92/07/30 SMI"; /* from S5R3 1.6 */#endif#ifdef pdp11	/* Has to be this small to fit, even split I/D, with several use='s */# define CAPSIZ	2048#else# define CAPSIZ	8192		/* 4096 */#endif#define MAXHOP	32	/* max number of use= indirections */#define COMMENT		'#'#define CAPCOMMENT	'.'#define SEPARATE	','	/* Separates the capabilities. */#define	NAMESEPARATOR	'|'	/* Separates the names in the list. */#define NUMBER		'#'#define STRING		'='#define CANCEL		'@'#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include <unctrl.h>#include "uparm.h"#ifndef E_TERMINFO#define E_TERMINFO "terminfo.src"#endif#ifndef termpath#ifdef S5EMUL#define termpath(name) "/usr/5lib/terminfo/name"#else#define termpath(name) "/usr/lib/terminfo/name"#endif#endif/* * L_ctermid is only defined on USG. * We use it here since we don't include curses.h. */#if defined(L_ctermid) && !defined(sun)#define index strchr#endif/* * compile: program to compile a source terminfo file into object files */static char *tbuf;static int hopcount;	/* detect infinite loops in terminfo, init 0 */static long starttime;static int verbose;static char *progname;static char *filename;static int linenumber;static char *terminfo;char	*tskip();char	*tgetstr();char	*tdecode();extern char *boolnames[], *numnames[], *strnames[];extern char *boolcodes[], *numcodes[], *strcodes[];extern char *malloc();extern char *getenv();extern char *index();main(argc, argv)char **argv;{	int i;	progname = argv[0];	initcheck();	time(&starttime);	while (argc > 1 && argv[1][0] == '-') {		switch(argv[1][1]) {		case 'v':			if (argv[1][2])				verbose = argv[1][2] - '0';			else				verbose++;			break;		default:			(void) fprintf(stderr, "Usage: %s [-v] [files...]\n",				progname);			exit(1);		}		argc--; argv++;	}	terminfo = getenv("TERMINFO");	if (argc == 1)		compfile(stdin, "stdin");	else for (i=1; i<argc; i++)		compfile(fopen(argv[i], "r"), argv[i]);	return 0;}/* * Compile a file.  This is very similar to the * code in tgetstr but it passes through the whole file. */compfile(tf, fname)	FILE *tf;	char *fname;{	register char *cp;	char bp[CAPSIZ];	char ibuf[CAPSIZ];	if (tf == NULL) {		perror(fname);		return;	}	ibuf[0] = 0;	linenumber = 0;	filename = fname;	for (;;) {		tbuf = bp;		strcpy(bp, ibuf);		hopcount = 0;		for (;;) {			if (fgets(ibuf, sizeof ibuf, tf) == NULL) {				if (ferror(tf)) {					perror(fname);					fclose(tf);					return;				}				fclose(tf);				checknames(tbuf);				if (*bp && tnchkuse(fname))					store(bp);				return;			}			linenumber++;			/* comment or blank line */			if (ibuf[0] == COMMENT || ibuf[0] == '\n')				continue;			cp = &ibuf[strlen(ibuf)-3];			/* Allow and ignore old style backslashes */			if (*cp == SEPARATE && cp[1] == '\\')				cp[1] = 0;			cp[2] = 0;	/* get rid of newline */			/* lines with leading white space are continuation */			if (!isspace(ibuf[0]) && *bp)				break;			if (strlen(bp) + strlen(ibuf) >= CAPSIZ)				(void) fprintf(stderr,					"%s: Terminfo entry too long:\n%s",					progname, bp);			else {				cp = ibuf;				while (isspace(*cp))					cp++;				strcat(bp, cp);			}		}		/*		 * We have it, now do something with it.		 */		checknames(tbuf);		if (tnchkuse(fname))			store(bp);	}}/* * Code to check names in the buffer against list of valid names. * This is done against the unexpanded form (use= entries are still there) * to avoid redundant messages. */static short *sortedbools, *sortednums, *sortedstrs;static int numbools, numnums, numstrs;static intcmpbools(left, right)short *left, *right;{    return strcmp(boolnames[*left], boolnames[*right]);}static intcmpnums(left, right)short *left, *right;{    return strcmp(numnames[*left], numnames[*right]);}static intcmpstrs(left, right)short *left, *right;{    return strcmp(strnames[*left], strnames[*right]);}initcheck(){	register int i, j;	register char **pp;	for (i = 0, pp = boolnames; *pp; pp++, i++)		;	numbools = i;	sortedbools = (short *) malloc(i * sizeof(short));	if (!sortedbools) {		(void) fprintf (stderr, "%s: malloc failed!\n", progname);		exit(1);	}	for (j = 0; j < i; j++)	    sortedbools[j] = j;	qsort(sortedbools, numbools, sizeof(short), cmpbools);	for (i = 0, pp = numnames; *pp; pp++, i++)		;	numnums = i;	sortednums = (short *) malloc(i * sizeof(short));	if (!sortednums) {		(void) fprintf (stderr, "%s: malloc failed!\n", progname);		exit(1);	}	for (j = 0; j < i; j++)	    sortednums[j] = j;	qsort(sortednums, numnums, sizeof(short), cmpnums);	for (i = 0, pp = strnames; *pp; pp++, i++)		;	numstrs = i;	sortedstrs = (short *) malloc(i * sizeof(short));	if (!sortedstrs) {		(void) fprintf (stderr, "%s: malloc failed!\n", progname);		exit(1);	}	for (j = 0; j < i; j++)	    sortedstrs[j] = j;	qsort(sortedstrs, numstrs, sizeof(short), cmpstrs);}binsearch(name, sortedtable, size, table)char *name;short sortedtable[];int size;int table;{	int low, mid, high, cmp;	char *cmpname;	low = 0;	high = size - 1;	while (low <= high) {		mid = (low + high) / 2;		switch (table) {			case 1: cmpname = boolnames[sortedtable[mid]]; break;			case 2: cmpname = numnames[sortedtable[mid]]; break;			case 3: cmpname = strnames[sortedtable[mid]]; break;		}		cmp = strcmp(cmpname, name);		if (cmp == 0)			return 1;		else if (cmp < 0)			low = mid + 1;		else			high = mid - 1;	}	return 0;}static intlookfor(name, table)char *name;int table;{	switch(table) {		case 1: return binsearch(name, sortedbools, numbools, table);		case 2: return binsearch(name, sortednums, numnums, table);		case 3: return binsearch(name, sortedstrs, numstrs, table);	}	return -1;}staticlookup(buf, termname)register char *buf;char *termname;{#define NAMESIZE 10	char name[NAMESIZE];	char *nptr = name;	if (*buf == CAPCOMMENT)		return 1;	/* a name is followed by a SEPARATE, @, # or =. */	while (*buf && *buf != SEPARATE && *buf != CANCEL &&	       *buf != STRING && *buf != NUMBER && !isspace(*buf) &&	       nptr < &name[NAMESIZE-1])		*nptr++ = *buf++;	*nptr = '\0';	switch(*buf) {		case STRING:		/* string capability */			if (!lookfor(name, 3) && strcmp(name, "use") != 0)				(void) fprintf (stderr,					"%s: file %s, line %d, terminal '%s' has unknown string capability '%s'.\n",					progname, filename, linenumber, termname, name);			break;		case NUMBER:		/* numeric capability */			if (!lookfor(name, 2))				(void) fprintf (stderr,					"%s: file %s, line %d, terminal '%s' has unknown numeric capability '%s'.\n",					progname, filename, linenumber, termname, name);			break;		case SEPARATE:		/* boolean capability */		case ' ':		case '\t':			if (!lookfor(name, 1))				(void) fprintf (stderr,					"%s: file %s, line %d, terminal '%s' has unknown boolean capability '%s'.\n",					progname, filename, linenumber, termname, name);			break;		case CANCEL:		/* may be boolean, number or string */			if (!lookfor(name, 1) && !lookfor(name, 2) &&			    !lookfor(name, 3))				(void) fprintf (stderr,					"%s: file %s, line %d, terminal '%s' has unknown capability '%s'.\n",					progname, filename, linenumber, termname, name);			break;		default:			(void) fprintf (stderr,				"%s: file %s, line %d, terminal '%s' has capability name which is too long: '%s...'.\n",				progname, filename, linenumber, termname, name);		}}staticchecknames(buf)register char *buf;{	char *bufptr = buf;	char termname[20];	char *termptr = termname;	while (*bufptr && *bufptr != SEPARATE && *bufptr != NAMESEPARATOR &&	       termptr < &termname[20])		*termptr++ = *bufptr++;	if (termptr < &termname[20])		*termptr = '\0';	else		termname[19] = '\0';	for (buf = tskip(buf); *buf; buf = tskip(buf))		lookup(buf, termname);}/* * Get an entry for terminal name in buffer bp, * from the terminfo file.  Parse is very rudimentary; * we just notice escaped newlines. */tgetent(bp, name, fname)	char *bp, *name, *fname;{	register char *cp;	char ibuf[CAPSIZ];	FILE *tf;	ibuf[0] = 0;	tf = fopen(fname, "r");	if (tf == NULL)		return (-1);	tbuf = bp;	for (;;) {		strcpy(bp, ibuf);		for (;;) {			if (fgets(ibuf, sizeof ibuf, tf) == NULL) {				if (ferror(tf)) {					perror(fname);					fclose(tf);					return (-1);				}				fclose(tf);				if (tnamatch(name))					return(tnchkuse(fname));				return 0;			}			if (ibuf[0] == COMMENT || ibuf[0] == '\n') /* comment */				continue;			cp = &ibuf[strlen(ibuf)-3];			/* Allow and ignore old style backslashes */			if (*cp == SEPARATE && cp[1] == '\\')				cp[1] = 0;			cp[2] = 0;	/* get rid of newline */			/* lines with leading white space are continuation */			if (!isspace(ibuf[0]) && *bp)				break;			if (strlen(bp) + strlen(ibuf) >= CAPSIZ)				(void) fprintf(stderr,					"%s: file %s, line %d: Terminfo entry too long:\n%s",					progname, filename, linenumber, bp);			else {				cp = ibuf;				while (isspace(*cp))					cp++;				strcat(bp, cp);			}		}		/*		 * The real work for the match.		 */		if (tnamatch(name)) {			fclose(tf);			return(tnchkuse(fname));		}	}}/* * tnchkuse: look for use=xxx. When found, recursively * find xxx and append that entry (minus the names) * to take the place of the use=xxx entry. This allows terminfo * entries to say "like an HP2621 but doesn't turn on the labels". * Note that this works because of the left to right scan. * Multiple use= entries are allowed. */tnchkuse(fname)char *fname;{	register char *p, *q;	char tcname[128 /* 16 */];	/* name of similar terminal */	char tcbuf[CAPSIZ];	char restbuf[CAPSIZ];	char *holdtbuf = tbuf;	char *beg_use, *beg_next;	p = tbuf;	if (++hopcount > MAXHOP) {		(void) fprintf(stderr, "%s: file %s, line %d: Infinite use= loop '%s'\n",			progname, filename, linenumber, tbuf);		return (0);	}	for (;;) {		p = index(p, 'u');		if (p == NULL) {			tbuf = holdtbuf;			return 1;		}		beg_use = p;		if (*++p != 's' || *++p != 'e' || *++p != '=')			continue;		strncpy(tcname, ++p, sizeof tcname);		q = index(tcname, SEPARATE);		if (q)			*q = 0;		/* try local file ... */		if (tgetent(tcbuf, tcname, fname) != 1)	{			/* ... and master */			if (tgetent(tcbuf, tcname, E_TERMINFO) != 1) {				printf("Cannot find term %s\n", tcname);				return(0);			}		}		/* Find the end of the use= spec */		for(beg_next=beg_use;		    *beg_next && *beg_next!=SEPARATE;		    beg_next++)			;		beg_next++;		while (isspace(*beg_next++))

⌨️ 快捷键说明

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