#define	LINELEN	136
#define	NUMLONG	40
#define	NAMELEN	12
struct info	{	char	func[NAMELEN];
			char	file[NAMELEN];
			char	caller[NAMELEN]; } ;
struct info last;
	char	text[LINELEN];
struct buff	{	int	fdes;
			int	nleft;
			char	*nextp;
			char	area[512]; } buf;
	char	longfs[NUMLONG][NAMELEN];
	int	numlfun;
main(argc,argv)
	char	*argv[];
{
	extern fout;
	if(argc-- < 3)
	{	printf("arg count\n");
		exit(12);
	}
	if(!fopen(&buf,*++argv))
	{	printf("cannot open: %s\n",*argv);
		exit(12);
	}
	for(numlfun = 0; numlfun < NUMLONG && getlong(); numlfun++)
		move(text,longfs[numlfun]);
	if(numlfun == NUMLONG) printf("warning: too many long functions\n");
	close(buf.fdes);
	blankit(&last,3 * NAMELEN);
	blankit(text,LINELEN);
	fout = dup(1);
	while (--argc && *++argv)
	{	if(!fopen(&buf,*argv))
		{	printf("cannot open: %s\n",*argv);
			flush();
			continue;
		}
		while (getline()) ckline();
		close(buf.fdes);
	}
	flush();
}
getline()
{	register int c, dlm;
	register char	*p;
	char *ptr;
	blankit(text,3 * NAMELEN);
	p = text;
	while ((c = get(&buf)) >= 0)
	{	if(c == '\n')
		{	*p = 0;
			return(1);
		}
		c =& 0377;
		switch(dlm)
		{	case 0:
			case 1:
			case 2:	if(c == '\t')
				{	ptr = &text[dlm * NAMELEN];
					if(p - ptr > 6)
						if(p = bsrch(longfs,ptr,numlfun,p - ptr))
							move(p,ptr);
					p = &text[++dlm * NAMELEN];
				}
				else *p++ = c;
				break;
			case 3:	if(c == '\t' )
					p = &text[dlm++ * NAMELEN];
				break;
			default: *p++ = c;
		}
	}
	return(0);
}
ckline()
{
	int nl, j;
	register int offset;
	nl = 0;
	for (j = 0; j < 3; j++)
	{	offset = j * NAMELEN;
		if(compar(&last.func[offset],&text[offset],NAMELEN) || nl)
		{	if(j == 0)
			{	putchar('\n');
				nl++;
			}
			move(&text[offset],&last.func[offset]);
		}
		else blankit(&text[offset],NAMELEN);
	}
	pukeln();
}
pukeln()
{
	register char *p;
	for(p = text; *p; p++)  putchar(*p);
	putchar('\n');
}
move(from,to)
	char *from,*to;
{
	register char *f,*t;
	register i;
	f = from;
	t = to;
	for (i = 0; i < NAMELEN; i++) *t++ = *f++;
}
fopen(b,file)
	struct buff *b;
	char *file;
{
	b->nleft = 0;
	if((b->fdes = open(file,0)) < 0) return(0);
	return(1);
}
get(p)
	struct buff *p;
{
	if(p->nleft ==  0)
	{	if((p->nleft = read(p->fdes,p->area,512)) == 0)
			return(-1);
		p->nextp = p->area;
	}
	p->nleft--;
	return(*p->nextp++ & 0377);
}
blankit(ptr,len)
	char *ptr;
{
	register l;
	register char *p;
	l = len;
	p = ptr;
	while(l--) *p++ = ' ';
}
bsrch(start,name,items,namelen)
	char *name, *start;
{	register int hi, lo, mid;
	char *p;
	int c;
	if (items < 1) return(0);
	hi = items - 1;
	lo = 0;
	mid = (hi + lo) / 2;
	while (hi - lo > 1)
	{	if ((c = compar(start + mid * NAMELEN,name,namelen)) == 0)
			return(start + mid * NAMELEN);
		else if(c > 0) hi = mid;
		     else lo = mid;
		mid = (hi + lo) / 2;
	}
	p = start + lo * NAMELEN;
	if (compar(p,name,namelen) == 0) return(p);
	p = start + hi * NAMELEN;
	return(compar(p,name,namelen) == 0 ? p : 0);
}
compar(f,s,len)
	char *f,*s;
{
	register i, j, k;
	for(k = 0; k < len; k++)
		if((i = *f++) != (j = *s++)) return(i < j ? -1 : 1);
	return(0);
}
getlong()
{
	register char *p;
	while(1)
	{	blankit(text,NAMELEN);
		for(p = text; (*p = get(&buf)) != '\n'; p++)
			if (*p < 0) return(0);
		*p = ' ';
		if(p - text > 8) return(1);
	}
}
