775 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			775 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * xref makes cross references.
 | 
						|
 *   November 1977		Johan Stevenson
 | 
						|
 */
 | 
						|
 | 
						|
#include	<stdio.h>
 | 
						|
#include	<signal.h>
 | 
						|
#include	<setjmp.h>
 | 
						|
 | 
						|
/* type of flags() calls */
 | 
						|
#define	HEAD	0
 | 
						|
#define	TAIL	1
 | 
						|
 | 
						|
FILE	*input;
 | 
						|
FILE	*output;
 | 
						|
FILE	*hashin;
 | 
						|
jmp_buf	env;		/* used by setjmp and longjmp */
 | 
						|
int	scanout[2];	/* descriptor of output of scan */
 | 
						|
int	postin[2];	/* descriptor of input of post */
 | 
						|
int	ch;		/*last char*/
 | 
						|
int	chsy;		/*type of last char*/
 | 
						|
char	id[80];		/*last identifier*/
 | 
						|
char	fl[80];		/*last filename (see post) */
 | 
						|
char	buf[80];	/*work space*/
 | 
						|
int	proc	= 0;	/*process id of sort*/
 | 
						|
int	nflag;		/*line number flag*/
 | 
						|
int	nfiles;
 | 
						|
int	argc;
 | 
						|
char	**argv;
 | 
						|
char	*procname;
 | 
						|
char	*file;		/*points to current file*/
 | 
						|
int	pass1	= 1;
 | 
						|
int	pass2	= 1;
 | 
						|
int	only	= 0;	/* 1 if only selected words needed */
 | 
						|
int	useroif	= 0;	/* 1 if user supplied ignore/only file*/
 | 
						|
char	*oifile	= "/usr/lib/xrefign.\0";
 | 
						|
int	oifsuf = 0;	/* index in oifile of last char */
 | 
						|
int	linecount;
 | 
						|
int	width	= 72;	/*line width*/
 | 
						|
int	type;		/* which scanner must be used */
 | 
						|
int	forced	= 0;	/* scanner type chosen by user */
 | 
						|
 | 
						|
stop()
 | 
						|
{	
 | 
						|
	if (proc!=0)
 | 
						|
		kill(proc,9);
 | 
						|
	exit(-1);
 | 
						|
}
 | 
						|
 | 
						|
main(narg,args) char **args; 
 | 
						|
int narg;
 | 
						|
{
 | 
						|
	argc=narg; 
 | 
						|
	argv = args;
 | 
						|
	argc--; 
 | 
						|
	argv++;
 | 
						|
	if (signal(SIGHUP,stop) != SIG_DFL)
 | 
						|
		signal(SIGHUP,SIG_IGN);
 | 
						|
	if (signal(SIGINT,stop) != SIG_DFL)
 | 
						|
		signal(SIGINT,SIG_IGN);
 | 
						|
	while (argc && argv[0][0]=='-' && argv[0][1]!='\0')
 | 
						|
	{
 | 
						|
		argc--; 
 | 
						|
		flags(*argv++,HEAD);
 | 
						|
	}
 | 
						|
	if (argc==0) {
 | 
						|
		argc++;
 | 
						|
		*--argv = "-";
 | 
						|
	}
 | 
						|
	if (pass1 && pass2) {
 | 
						|
		if (pipe(scanout)<0 || pipe(postin)<0)
 | 
						|
			fatal("pipe failed");
 | 
						|
		if ((proc=fork()) == 0) {
 | 
						|
			close(0); 
 | 
						|
			close(1);
 | 
						|
			dup(scanout[0]); 
 | 
						|
			dup(postin[1]);
 | 
						|
			close(scanout[0]); 
 | 
						|
			close(scanout[1]);
 | 
						|
			close(postin[0]); 
 | 
						|
			close(postin[1]);
 | 
						|
			execl("/bin/sort","xref","+1","-3","+0n",0); 
 | 
						|
			execl("/usr/bin/sort","xref","+1","-3","+0n",0);
 | 
						|
			fatal("sort not found");
 | 
						|
		}
 | 
						|
		if (proc == -1) fatal("fork failed");
 | 
						|
		close(scanout[0]); 
 | 
						|
		close(postin[1]);
 | 
						|
	}
 | 
						|
	else if (pass1)
 | 
						|
		scanout[1] = dup(1);
 | 
						|
	else if (pass2)
 | 
						|
		postin[0] = dup(0);
 | 
						|
	if (pass1) {
 | 
						|
		if (useroif) {
 | 
						|
			if ((hashin = fopen(oifile, "r")) == NULL)
 | 
						|
				fatal("bad ignore/only file: %s",oifile);
 | 
						|
			buildhash();
 | 
						|
			fclose(hashin);
 | 
						|
		}
 | 
						|
		input = stdin;
 | 
						|
		output = fdopen(scanout[1], "w");
 | 
						|
		nfiles = argc;
 | 
						|
		setjmp(env);
 | 
						|
		while (argc--)
 | 
						|
			if (argv[0][0] == '-' && argv[0][1] != '\0')
 | 
						|
				flags(*argv++,TAIL);
 | 
						|
			else
 | 
						|
				scan(*argv++);
 | 
						|
		fclose(input);
 | 
						|
		fclose(output);
 | 
						|
	}
 | 
						|
	if (pass2) {
 | 
						|
		input = fdopen(postin[0], "r");
 | 
						|
		output = stdout;
 | 
						|
		post();
 | 
						|
	}
 | 
						|
	exit(0);
 | 
						|
}
 | 
						|
 | 
						|
flags(s,ftype) register char *s;
 | 
						|
{
 | 
						|
	register c;
 | 
						|
 | 
						|
	s++;	/* skip - */
 | 
						|
	switch (c = *s++) {
 | 
						|
	case 'p':
 | 
						|
	case '8':
 | 
						|
	case 'c':
 | 
						|
	case 's':
 | 
						|
	case 'x':
 | 
						|
		forced++; 
 | 
						|
		type = c; 
 | 
						|
		break;
 | 
						|
	case '1':
 | 
						|
		if (ftype == TAIL)
 | 
						|
			fatal("-1 must precede file arguments");
 | 
						|
		pass2=0; 
 | 
						|
		pass1++; 
 | 
						|
		break;
 | 
						|
	case '2':
 | 
						|
		if (ftype == TAIL)
 | 
						|
			fatal("-2 must precede file arguments");
 | 
						|
		pass1=0; 
 | 
						|
		pass2++; 
 | 
						|
		break;
 | 
						|
	case 'i':
 | 
						|
	case 'o':
 | 
						|
		only = (c == 'o'); 
 | 
						|
		useroif++;
 | 
						|
		if (*s == '\0')
 | 
						|
			fatal("more args expected");
 | 
						|
		oifile = s;
 | 
						|
		return;
 | 
						|
	case 'w':
 | 
						|
		if (*s == '\0')
 | 
						|
			fatal("more args expected");
 | 
						|
		width=atoi(s);
 | 
						|
		return;
 | 
						|
	default:
 | 
						|
		fatal("possible flags: cpsxio12w");
 | 
						|
	}
 | 
						|
	if (*s != '\0')
 | 
						|
		fatal("flags should be given as separate arguments");
 | 
						|
}
 | 
						|
 | 
						|
char *tail(s)
 | 
						|
register char *s;
 | 
						|
{
 | 
						|
	register char *t;
 | 
						|
 | 
						|
	t = s;
 | 
						|
	while (*s)
 | 
						|
		if (*s++ == '/')
 | 
						|
			t = s;
 | 
						|
	return(t);
 | 
						|
}
 | 
						|
 | 
						|
scan(s) char *s;
 | 
						|
{
 | 
						|
	register lastc;
 | 
						|
 | 
						|
	linecount = 0; 
 | 
						|
	nflag = 0;
 | 
						|
	chsy = 0;
 | 
						|
	if (nfiles==1)
 | 
						|
		file = "";
 | 
						|
	else
 | 
						|
		file = tail(s);
 | 
						|
	if (forced==0) {
 | 
						|
		lastc = suffix(s);
 | 
						|
		if (lastc=='h')
 | 
						|
			lastc = 'c';
 | 
						|
		if (lastc=='c' || lastc=='p' || lastc=='s' || lastc=='8')
 | 
						|
			type=lastc;
 | 
						|
		else
 | 
						|
			type='x';
 | 
						|
	} else
 | 
						|
		lastc = type;
 | 
						|
	if (useroif==0) {
 | 
						|
		if (oifsuf == 0)
 | 
						|
			while (oifile[oifsuf] != '\0')
 | 
						|
				oifsuf++;
 | 
						|
		if (lastc != oifile[oifsuf] ) {
 | 
						|
			oifile[oifsuf] = lastc;
 | 
						|
			if ((hashin = fopen(oifile, "r")) == NULL) {
 | 
						|
				oifile[oifsuf] = 'x';
 | 
						|
				if ((hashin = fopen(oifile, "r")) == NULL)
 | 
						|
					fatal("cannot open %s",oifile);
 | 
						|
			}
 | 
						|
			buildhash();
 | 
						|
			fclose(hashin);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if (s[0]=='-' && s[1]=='\0')
 | 
						|
		input = stdin;
 | 
						|
	else
 | 
						|
		if ((input = fopen(s, "r")) == NULL)
 | 
						|
			fatal("cannot open %s",s);
 | 
						|
	switch (type) {
 | 
						|
	case 'x': 
 | 
						|
		x_scan(); 
 | 
						|
		break;
 | 
						|
	case 'p': 
 | 
						|
		p_scan(); 
 | 
						|
		break;
 | 
						|
	case '8':
 | 
						|
		a_scan();
 | 
						|
		break;
 | 
						|
	case 'c': 
 | 
						|
		c_scan(); 
 | 
						|
		break;
 | 
						|
	case 's': 
 | 
						|
		s_scan(); 
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	/*this place is never reached*/
 | 
						|
}
 | 
						|
 | 
						|
suffix(s)
 | 
						|
register char *s;
 | 
						|
{
 | 
						|
	while (*s) s++;
 | 
						|
	if (*(s-2) == '.')
 | 
						|
		return(*--s);
 | 
						|
	return('x');
 | 
						|
}
 | 
						|
 | 
						|
fatal(s) char *s;
 | 
						|
{
 | 
						|
	fprintf(stderr, "xref: %s",s);
 | 
						|
	fprintf(stderr, "\n");
 | 
						|
	stop();
 | 
						|
}
 | 
						|
 | 
						|
/*============================================*/
 | 
						|
 | 
						|
#define HSIZE	79
 | 
						|
 | 
						|
struct { 
 | 
						|
	int integ; 
 | 
						|
};
 | 
						|
 | 
						|
struct link {
 | 
						|
	struct link *next;
 | 
						|
	char word[];
 | 
						|
} 
 | 
						|
*hashtab[HSIZE];
 | 
						|
 | 
						|
buildhash()
 | 
						|
{
 | 
						|
	register struct link *p,*q; 
 | 
						|
	register char *s;
 | 
						|
	int i;
 | 
						|
 | 
						|
	for (i=0; i<HSIZE; i++)
 | 
						|
	{
 | 
						|
		p = hashtab[i];
 | 
						|
		hashtab[i] = 0;
 | 
						|
		while (q = p)
 | 
						|
		{
 | 
						|
			p = q->next;
 | 
						|
			free(q);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	ch = getc(hashin);
 | 
						|
	while (ch != EOF) {
 | 
						|
		s = id;
 | 
						|
		do {
 | 
						|
			*s++ = ch; 
 | 
						|
			ch = getc(hashin);
 | 
						|
		} while (ch>' ');
 | 
						|
		*s++ = '\0';
 | 
						|
		h_add(id,s-id);
 | 
						|
		while (ch!='\n' && ch!=EOF)
 | 
						|
			ch = getc(hashin);
 | 
						|
		ch = getc(hashin);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
h_add(s,l) char *s; 
 | 
						|
int l;
 | 
						|
{
 | 
						|
	register struct link *q,**p; 
 | 
						|
	char temp[80];
 | 
						|
	char *s2;
 | 
						|
 | 
						|
	if (h_in(s)) return;
 | 
						|
	s2 = temp;
 | 
						|
	strcpy(s2,s);
 | 
						|
	if (strlen(s2)<=2)
 | 
						|
		strcat(s2,"zz\0");
 | 
						|
	p = &hashtab[ s2->integ % HSIZE ];
 | 
						|
	l += 4+((4-(l & 3) & 3));
 | 
						|
	if ((q = malloc(l)) == 0)
 | 
						|
		fatal("out of space");
 | 
						|
	q->next = *p;
 | 
						|
	*p = q;
 | 
						|
	strcpy(q->word, s);
 | 
						|
}
 | 
						|
 | 
						|
h_in(s) char *s;
 | 
						|
{
 | 
						|
	register struct link *p;
 | 
						|
	char temp[80];
 | 
						|
	char *s2;
 | 
						|
 | 
						|
	s2 = temp;
 | 
						|
	strcpy(s2,s);
 | 
						|
	if (strlen(s)<= 2)
 | 
						|
		strcat(s2,"zz\0");
 | 
						|
	p = hashtab[ s2->integ % HSIZE ];
 | 
						|
	while (p) {
 | 
						|
		if (strcmp(s, p->word) == 0)
 | 
						|
			return(1);
 | 
						|
		p = p->next;
 | 
						|
	}
 | 
						|
	return(0);
 | 
						|
}
 | 
						|
 | 
						|
/*=====================================*/
 | 
						|
 | 
						|
#define NL	-1
 | 
						|
#define	ERROR	0
 | 
						|
#define	LETTER	1
 | 
						|
#define	DIGIT	2
 | 
						|
#define	QUOTE	3
 | 
						|
#define	LPAR	4
 | 
						|
#define	LBRACE	5
 | 
						|
#define DQUOTE	6
 | 
						|
#define SLASH	7
 | 
						|
#define POINT	9
 | 
						|
#define LESS	10
 | 
						|
#define USCORE	11
 | 
						|
#define	OTHER	12
 | 
						|
#define HASH 	13
 | 
						|
 | 
						|
 | 
						|
char	cs[128] = {
 | 
						|
	/*NUL*/	ERROR,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,
 | 
						|
	/*010*/	OTHER,	OTHER,	NL,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,
 | 
						|
	/*020*/	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,
 | 
						|
	/*030*/	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,
 | 
						|
	/*' '*/	OTHER,	OTHER,	DQUOTE,	HASH,	OTHER,	OTHER,	OTHER,	QUOTE,
 | 
						|
	/*'('*/	LPAR,	OTHER,	OTHER,	OTHER,	OTHER,	OTHER,	POINT,	SLASH,
 | 
						|
	/*'0'*/	DIGIT,	DIGIT,	DIGIT,	DIGIT,	DIGIT,	DIGIT,	DIGIT,	DIGIT,
 | 
						|
	/*'8'*/	DIGIT,	DIGIT,	OTHER,	OTHER,	LESS,	OTHER,	OTHER,	OTHER,
 | 
						|
	/*'@'*/	OTHER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,
 | 
						|
	/*'H'*/	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,
 | 
						|
	/*'P'*/	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,
 | 
						|
	/*'X'*/	LETTER,	LETTER,	LETTER,	OTHER,	OTHER,	OTHER,	OTHER,	USCORE,
 | 
						|
	/*'`'*/	OTHER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,
 | 
						|
	/*'h'*/	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,
 | 
						|
	/*'p'*/	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,	LETTER,
 | 
						|
	/*'x'*/	LETTER,	LETTER,	LETTER,	LBRACE,	OTHER,	OTHER,	OTHER,	OTHER
 | 
						|
};
 | 
						|
 | 
						|
nextch()
 | 
						|
{	
 | 
						|
	if (linecount == 0) {
 | 
						|
		if ((ch=getc(input))==EOF) {
 | 
						|
			fclose(input);
 | 
						|
			longjmp(env,0);
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			chsy = cs[ch];
 | 
						|
			if (chsy != DIGIT) 
 | 
						|
				linecount++;
 | 
						|
			else {
 | 
						|
				nflag = 1;
 | 
						|
				linecount = ch-'0';
 | 
						|
				chsy = cs[(ch=getc(input))];
 | 
						|
				while (chsy == DIGIT) {
 | 
						|
					linecount = linecount*10+ch-'0';
 | 
						|
					chsy = cs[(ch=getc(input))];
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else {
 | 
						|
		if ((ch=getc(input))==EOF) {
 | 
						|
			fclose(input);
 | 
						|
			longjmp(env,0);
 | 
						|
		}
 | 
						|
		if (chsy < 0) {
 | 
						|
			if (nflag == 0)
 | 
						|
				linecount++;
 | 
						|
			else {
 | 
						|
				linecount = ch-'0';
 | 
						|
				chsy = cs[(ch=getc(input))];
 | 
						|
				while (chsy == DIGIT) {
 | 
						|
					linecount = linecount*10+ch-'0';
 | 
						|
					chsy = cs[(ch=getc(input))];
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if (ch >= 128)
 | 
						|
			fatal("bad chars on file %s",*--argv);
 | 
						|
		chsy = cs[ch];
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
out(p)
 | 
						|
char *p;
 | 
						|
{	
 | 
						|
	fprintf(output, "%d	%s	%s\n",linecount,p,file);
 | 
						|
}
 | 
						|
 | 
						|
scannumber()
 | 
						|
{
 | 
						|
	do nextch(); while (chsy == DIGIT);
 | 
						|
	if (ch == '.') {
 | 
						|
		nextch();
 | 
						|
		if (chsy!=DIGIT) return;
 | 
						|
		do nextch(); while (chsy == DIGIT);
 | 
						|
	}
 | 
						|
	if (ch == 'e') {
 | 
						|
		nextch();
 | 
						|
		if (ch == '+' || ch == '-')
 | 
						|
			nextch();
 | 
						|
		while (chsy == DIGIT)
 | 
						|
			nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
scansymbol(ok1,ok2) {
 | 
						|
	register char *p;
 | 
						|
 | 
						|
	p = id;
 | 
						|
	do {	
 | 
						|
		*p++ = ch; 
 | 
						|
		nextch();
 | 
						|
	} while (chsy==LETTER || chsy==DIGIT || ch==ok1 || ch==ok2);
 | 
						|
	*p = '\0';
 | 
						|
	if (h_in(id) == only)
 | 
						|
		out(id);
 | 
						|
}
 | 
						|
 | 
						|
scanusymbol(ok1,ok2) {
 | 
						|
	register char *p;
 | 
						|
 | 
						|
	p = id;
 | 
						|
	do {	
 | 
						|
		if (ch >= 'a' && ch <= 'z')
 | 
						|
			ch += 'A'-'a';
 | 
						|
		*p++ = ch; 
 | 
						|
		nextch();
 | 
						|
	} while (chsy==LETTER || chsy==DIGIT || ch==ok1 || ch==ok2);
 | 
						|
	*p = '\0';
 | 
						|
	if (h_in(id) == only)
 | 
						|
		out(id);
 | 
						|
}
 | 
						|
 | 
						|
escaped() {	
 | 
						|
	if (ch=='\\') nextch(); 
 | 
						|
	nextch();
 | 
						|
}
 | 
						|
 | 
						|
comment(lastch) {	
 | 
						|
	nextch();
 | 
						|
	if (ch=='*') {
 | 
						|
		nextch();
 | 
						|
		do {
 | 
						|
			while(ch!='*') nextch();
 | 
						|
			nextch();
 | 
						|
		} while (ch!=lastch);
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
acmnt1() {
 | 
						|
 | 
						|
	/* handle a .COMMENT ..... .COMMENT */
 | 
						|
 | 
						|
	register char *p;
 | 
						|
	register int cont;
 | 
						|
 | 
						|
	p = id;
 | 
						|
	nextch();
 | 
						|
	if (chsy==DIGIT) scannumber();
 | 
						|
	else {
 | 
						|
		do {
 | 
						|
			*p++ = ch;
 | 
						|
			nextch();
 | 
						|
		} while (chsy==LETTER);
 | 
						|
		/* see if the word is COMMENT */
 | 
						|
		*p = '\0';
 | 
						|
		p = id;
 | 
						|
		if (strcmp("COMMENT",p)) { /* skip to next .COMMENT */
 | 
						|
			cont = 1;
 | 
						|
			while (cont) {
 | 
						|
				while (chsy != POINT) nextch();
 | 
						|
				nextch();
 | 
						|
				p = id;
 | 
						|
				do {
 | 
						|
					*p++ = ch;
 | 
						|
					nextch();
 | 
						|
				} while (chsy==LETTER);
 | 
						|
				*p = '\0';
 | 
						|
				p = id;
 | 
						|
				cont = strcmp("COMMENT",p);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		else { /* do hash lookup - could be pragmat (ignore) or record field */
 | 
						|
			if (h_in(id)==only)
 | 
						|
				out(id);
 | 
						|
		}
 | 
						|
	}			
 | 
						|
}
 | 
						|
 | 
						|
acmnt2() {
 | 
						|
	register char *p;
 | 
						|
	int cont;
 | 
						|
 | 
						|
	/* handle a CO ..... CO comment */
 | 
						|
 | 
						|
	p = id;
 | 
						|
	*p++ = 'C';
 | 
						|
	nextch();
 | 
						|
	if (ch!='O')  { /* do a scansymbol */
 | 
						|
		do {
 | 
						|
			*p++ =ch;
 | 
						|
			nextch();
 | 
						|
		} while (chsy==LETTER || chsy==DIGIT || chsy==USCORE);
 | 
						|
		if (h_in(id)==only) 
 | 
						|
			out(id);
 | 
						|
	}
 | 
						|
	else { /* found a CO .... CO */
 | 
						|
		cont = 1;
 | 
						|
		while (cont) {
 | 
						|
			while (ch!='C') nextch();
 | 
						|
			nextch();
 | 
						|
			cont = (ch!='O');
 | 
						|
		}
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
p_scan() {	
 | 
						|
	nextch();
 | 
						|
	for(;;) switch (chsy) {
 | 
						|
	case LETTER: 
 | 
						|
	case USCORE:
 | 
						|
		scanusymbol('_','\0'); 
 | 
						|
		break;
 | 
						|
	case DIGIT:
 | 
						|
		scannumber(); 
 | 
						|
		break;
 | 
						|
	case QUOTE:
 | 
						|
		do nextch(); while (ch!='\''); 
 | 
						|
		nextch(); 
 | 
						|
		break;
 | 
						|
	case DQUOTE:
 | 
						|
		do nextch(); while (ch!='"'); 
 | 
						|
		nextch(); 
 | 
						|
		break;
 | 
						|
	case LPAR:
 | 
						|
		comment(')'); 
 | 
						|
		break;
 | 
						|
	case LBRACE:
 | 
						|
		do nextch(); while (ch!='}');
 | 
						|
	default:
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
a_scan() {	
 | 
						|
	nextch();
 | 
						|
	for(;;) switch (chsy) {
 | 
						|
	case LETTER: 
 | 
						|
		if (ch=='C') acmnt2();
 | 
						|
		else
 | 
						|
		scanusymbol('_','\0'); 
 | 
						|
		break;
 | 
						|
	case DIGIT:
 | 
						|
		scannumber(); 
 | 
						|
		break;
 | 
						|
	case QUOTE:
 | 
						|
		do nextch(); while (ch!='\''); 
 | 
						|
		nextch(); 
 | 
						|
		break;
 | 
						|
	case DQUOTE:
 | 
						|
		do nextch(); while (ch!='"'); 
 | 
						|
		nextch(); 
 | 
						|
		break;
 | 
						|
	case HASH:
 | 
						|
		nextch();
 | 
						|
		while (ch!='#') nextch();
 | 
						|
		nextch();
 | 
						|
		break;
 | 
						|
	case POINT:
 | 
						|
		acmnt1();
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
c_scan()
 | 
						|
{	
 | 
						|
	nextch();
 | 
						|
	for (;;) switch (chsy) {
 | 
						|
	case LETTER: 
 | 
						|
	case USCORE:
 | 
						|
		scansymbol('_','\0'); 
 | 
						|
		break;
 | 
						|
	case DIGIT:
 | 
						|
		scannumber(); 
 | 
						|
		break;
 | 
						|
	case SLASH:
 | 
						|
		comment('/'); 
 | 
						|
		break;
 | 
						|
	case QUOTE:
 | 
						|
		do escaped(); while (ch!='\''); 
 | 
						|
		nextch(); 
 | 
						|
		break;
 | 
						|
	case DQUOTE:
 | 
						|
		do escaped(); while (ch!='"');
 | 
						|
	default:
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
s_scan()
 | 
						|
{	
 | 
						|
	nextch();
 | 
						|
	for(;;) switch(chsy) {
 | 
						|
	case LETTER: 
 | 
						|
	case POINT:
 | 
						|
		scansymbol('_','.'); 
 | 
						|
		break;
 | 
						|
	case DIGIT:
 | 
						|
		do nextch(); while (chsy==DIGIT);
 | 
						|
		if (ch=='.' || ch=='f' || ch=='b') nextch();
 | 
						|
		break;
 | 
						|
	case DQUOTE:
 | 
						|
		nextch();
 | 
						|
	case QUOTE:
 | 
						|
		escaped(); 
 | 
						|
		escaped(); 
 | 
						|
		break;
 | 
						|
	case SLASH:
 | 
						|
		do nextch(); while (ch!='\n'); 
 | 
						|
		break;
 | 
						|
	case LESS:
 | 
						|
		nextch();
 | 
						|
		do escaped(); while (ch!='>');
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
x_scan()
 | 
						|
{
 | 
						|
	register char *p;
 | 
						|
	nextch();
 | 
						|
	for (;;) switch (chsy) {
 | 
						|
	case LETTER:
 | 
						|
		p=id;
 | 
						|
		do {	
 | 
						|
			if (ch<'A' || ch>'Z') *p++ = ch;
 | 
						|
			else *p++ = ch - 'A' + 'a';
 | 
						|
			nextch();
 | 
						|
			if (ch=='-') {
 | 
						|
				nextch();
 | 
						|
				if (ch=='\n')
 | 
						|
					do nextch(); while (chsy!=LETTER);
 | 
						|
				else *p++ = '-';
 | 
						|
			}
 | 
						|
		} while (chsy==LETTER || chsy==DIGIT);
 | 
						|
		*p = '\0';
 | 
						|
		if (h_in(id) == only) out(id);
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		nextch();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*=========================================*/
 | 
						|
 | 
						|
int N;
 | 
						|
 | 
						|
post()
 | 
						|
{
 | 
						|
	register n,l,i; 
 | 
						|
	int first,newid,newfl,withfile;
 | 
						|
 | 
						|
	first = 1; 
 | 
						|
	id[0] = '\0';
 | 
						|
	ch = getc(input);
 | 
						|
	while (ch != EOF) {
 | 
						|
		l = getfld('\t');
 | 
						|
		if ((i=atoi(buf)) == 0)
 | 
						|
			fatal("line number expected");
 | 
						|
		l = getfld('\t');
 | 
						|
		newid = strcmp(id,buf);
 | 
						|
		if (newid) {
 | 
						|
			strcpy(id,buf);
 | 
						|
			if (first == 0)
 | 
						|
				putc('\n',output);
 | 
						|
			fprintf(output,"%s",id);
 | 
						|
			if (l > 7)
 | 
						|
				putc('\n',output);
 | 
						|
			putc('\t',output);
 | 
						|
			fl[0] = '\0';
 | 
						|
		}
 | 
						|
		l = getfld('\n');
 | 
						|
		newfl = strcmp(fl,buf);
 | 
						|
		if (newfl) {
 | 
						|
			strcpy(fl,buf);
 | 
						|
			if (newid == 0)
 | 
						|
				fprintf(output,"\n\t");
 | 
						|
			fprintf(output,"%s",fl);
 | 
						|
			if (l > 7)
 | 
						|
				fprintf(output,"\n\t");
 | 
						|
			putc('\t',output);
 | 
						|
		}
 | 
						|
		if (first) {
 | 
						|
			first = 0;
 | 
						|
			withfile = newfl;
 | 
						|
			N = width - 12;
 | 
						|
			if (withfile) N -= 8;
 | 
						|
			if (N<0) fatal("line width too small");
 | 
						|
			N = (N/5) + 1;
 | 
						|
		}
 | 
						|
		if (newid || newfl)
 | 
						|
			n = N;
 | 
						|
		else if (n==0) {
 | 
						|
			fprintf(output,"\n\t");
 | 
						|
			if (withfile)
 | 
						|
				putc('\t',output);
 | 
						|
			n = N;
 | 
						|
		}
 | 
						|
		else
 | 
						|
			putc(' ',output);
 | 
						|
		n--;
 | 
						|
		fprintf(output,"%4d",i);
 | 
						|
	}
 | 
						|
	putc('\n',output);
 | 
						|
}
 | 
						|
 | 
						|
getfld(stopch) {
 | 
						|
	register char *p;
 | 
						|
 | 
						|
	p = buf;
 | 
						|
	while (ch!=EOF && ch!=stopch) {
 | 
						|
		*p++ = ch;
 | 
						|
		ch = getc(input);
 | 
						|
	}
 | 
						|
	*p = '\0';
 | 
						|
	ch = getc(input);
 | 
						|
	return(p-buf);
 | 
						|
}
 |