V8/usr/src/cmd/ccom/vax/gentable.c

Compare this file to the similar file:
Show the results in this format:

#include "stdio.h"

char line[10240];
struct arg {
	char *val;
	int len;
} args[1000];
int narg;
struct arg words[2000];
extern char *wordskip(), *matchskip();

main()
{	char *p, *q;
	for(;;) {
		(void) fgets(line, sizeof(line), stdin);
		if(feof(stdin))
			exit(0);
		narg = 0;
		p = wordskip(line, '\t');
		q = matchskip(p);
		if(!findargs(p))
			continue;
		if(!uniqargs())
			continue;
		if(!matchargs(q))
			continue;
		if(!checktemp(q))
			continue;
		fixtree();
		prleft(q);
	}
}

fixtree()
{	int i, j;
	for(i = 0; i < narg; i++)
	for(j = 0; j < args[i].len; j++)
		args[i].val[j] = i;
}


checktemp(q)
char *q;	/* [^\].(fp) is an unusable temporary, and ,$n */
{	char *p;
	for(p = q; *p != '\n'; p++)
		if(*p == 'f' && *(p-1) == '(' && *(p-2) > ' ')
			return(0);
	for(p = q; *p != '\n'; p++)
		if(*p == ',' && *(p+1) == '$' && *(p+2) > ' ')
			return(0);
	for(p = q; *p != '\n'; p++)
		if(*p == '$' && *(p+1) == '-')
			return(0);
	return(1);
}

prleft(q)
char *q;
{	char *p, *s;
	for(p = line; *p != '\t'; p++)
		;
	*p = ' ';
	for(p = line; *p != '\n'; ) {
		if(*p >= ' ') {
			putchar(*p++);
			continue;
		}
		for(s = p; *s == *p; s++)
			;
		if(*p < 10)
			printf("\\%d", *p);
		else
			printf("\\%c", *p - 9 + 'a');
		p = s;
	}
	putchar('\n');
}
int alens[33];	/* if an arg > 32, forget it */
matchargs(s)
char *s;
{	char *p;
	int i, j, ok;
	for(i = 0; i < 33; i++)
		alens[i] = 0;
	for(i = 0; i < narg; i++)
		if(args[i].len <= 32)
			alens[args[i].len]++;
		else
			return(0);
	for(j = 32; j >= 1; j--) {
		if(alens[j] == 0)
			continue;
		for(i = 0; i < narg; i++) {
			if(args[i].len != j)
				continue;
			ok = 0;
			for(p = s; *p != '\n'; p++)
				if(*p == args[i].val[0])
					ok += matchit(p, i);
			if(ok == 0)
				return(0);
		}
	}
	return(1);
}

matchit(p, i)
char *p;
{	int j, c;
	for(j = 0; j < args[i].len; j++)
		if(p[j] != args[i].val[j])
			return(0);
	if((c = p[j]) <= '9' && c >= '0')
		return(0);
	if(c <= 'z' && c >= 'a')
		return(0);
	if(c <= 'Z' && c >= 'A')
		return(0);
	for(j = 0; j < args[i].len; j++)
		p[j] = i;	/* assumes narg < 32!!!!*/
	return(1);
}

findargs(p)
char *p;
{	int cnt, i, j;
	struct arg *a;
	if(*p != '(') {
		fprintf(stderr, "findargs fmt %s", line);
		return(0);
	}
	cnt = setwords(p);
	for(i = 0; i <= cnt; i++)
		stripcrud(words + i);
	for(i = 0; i <= cnt; i++) {
		a = &words[i];
		if(a->len == 0)
			continue;
		switch(numargs(a->val)) {
		case 0:
			continue;
		case 2:
			args[narg++] = words[++i];
		case 1:
			args[narg++] = words[++i];
			continue;
		default:
			fprintf(stderr, "unk op %s|%s", a->val, line);
			return(0);
		}
	}
	return(1);
}

struct {
	char *val;
	int num, len;
} ops[] = {
	{"and", 0},
	{"asg", 0},	/* asg ops are binary*/
	{"assign", 0},
	{"call", 1},
	{"cm", 0},
	{"comop", 0},
	{"compl", 0},
	{"conv", 0},
	{"decr", 0},
	{"div", 0},
	{"er", 0},
	{"fld", 2},
	{"funarg", 0},
	{"genbr", 2},
	{"genlab", 1},
	{"genubr", 1},
	{"icon", 1},
	{"init", 0},
	{"incr", 0},
	{"ls", 0},
	{"minus", 0},
	{"mod", 0},
	{"mul", 0},
	{"name", 1},
	{"not", 0},
	{"or", 0},
	{"plus", 0},
	{"reg", 1},
	{"return", 0},
	{"unary", 0},	/* common prefix for unary ops */
	{"rnode", 0},
	{"qnode", 0},
	{"snode", 0},
	{"rs", 0},
	{"star", 0},
	{"starg", 2},
	{"stasg", 1},
	{"stcall", 2},
	{"vauto", 1},
	{"vparam", 1},
	{0,0}
};

numargs(s)
char *s;
{	int i;
	static int init = 0;
	if(!init++)
		for(i = 0; ops[i].val; i++)
			ops[i].len = strlen(ops[i].val);
	for(i = 0; ops[i].val; i++)
		if(strncmp(s+1, ops[i].val,ops[i].len) == 0)
			return(ops[i].num);
	return(-1);
}

stripcrud(a)
struct arg *a;
{	char *p;
	for(p = a->val + a->len - 1; *p == ' ' || *p == ')'; p--)
		;
	if(p < a->val)
		p = a->val - 1;
	a->len = p - a->val + 1;
}

setwords(p)
char *p;
{	int i;
	i = 0;
loop:
	words[i].val = p;
	p = wordskip(p, ' ');
	words[i].len = p - words[i].val;
	if(*p == '\\')
		return(i);
	i++;
	goto loop;
}

argcmp(a, b)
struct arg *a, *b;
{	int n, i;
	n = a->len;
	if(b->len < n)
		n = b->len;
	i = strncmp(a->val, b->val, n);
	if(i != 0)
		return(i);
	if(a->len < b->len)
		return(-1);
	else if(a->len > b->len)
		return(1);
	return(0);
}

uniqargs()
{	int i, j;
	for(i = 1; i < narg; i++) {
		if(args[i].len <= 0)
			continue;
		for(j = 0; j < i; j++) {
			if(args[j].len <= 0)
				continue;
			if(argcmp(args + i, args + j) == 0) {
				/*printf("%5.5s %5.5s ", args[i].val, args[j].val);
				*/return(0);
			}
		}
	}
	return(1);
}

char *
wordskip(p, c)
char *p;
{
	for(; *p != c; p++)
		;
	for(; *p == c; p++)
		;
	return(p);
}

char *
matchskip(p)
char *p;
{	int cnt;
	for(cnt = 0; ; p++)
		if(*p == '(')
			cnt++;
		else if(*p == ')')
			if(--cnt <= 0)
				return(p+1);
}