xref: /csrg-svn/sys/vax/inline/main.c (revision 16978)
116962Smckusick /* Copyright (c) 1984 Regents of the University of California */
216962Smckusick 
316962Smckusick #ifndef lint
4*16978Smckusick static char sccsid[] = "@(#)main.c	1.4	(Berkeley)	08/20/84";
516962Smckusick #endif not lint
616962Smckusick 
716962Smckusick #include <stdio.h>
816962Smckusick #include <ctype.h>
916963Smckusick #include "inline.h"
1016962Smckusick 
1116975Smckusick /*
1216975Smckusick  * These are the pattern tables to be loaded
1316975Smckusick  */
1416975Smckusick struct pats *inittables[] = {
1516975Smckusick 	language_ptab,
1616975Smckusick 	libc_ptab,
1716975Smckusick 	machine_ptab,
1816975Smckusick 	0
1916975Smckusick };
2016975Smckusick 
2116962Smckusick main(argc, argv)
2216962Smckusick 	int argc;
2316962Smckusick 	char *argv[];
2416962Smckusick {
2516962Smckusick 	register char *cp, *lp;
2616962Smckusick 	register char *bufp;
27*16978Smckusick 	register struct pats *pp, **php;
28*16978Smckusick 	struct pats **tablep;
29*16978Smckusick 	register struct inststoptbl *itp, **ithp;
3016962Smckusick 	int size;
3116962Smckusick 	extern char *index();
3216962Smckusick 
3316962Smckusick 	if (argc > 1)
3416962Smckusick 		freopen(argv[1], "r", stdin);
3516962Smckusick 	if (argc > 2)
3616962Smckusick 		freopen(argv[2], "w", stdout);
3716962Smckusick 	/*
38*16978Smckusick 	 * Set up the hash table for the patterns.
3916962Smckusick 	 */
4016975Smckusick 	for (tablep = inittables; *tablep; tablep++) {
4116975Smckusick 		for (pp = *tablep; pp->name[0] != '\0'; pp++) {
42*16978Smckusick 			php = &patshdr[hash(pp->name, &size)];
4316975Smckusick 			pp->size = size;
44*16978Smckusick 			pp->next = *php;
45*16978Smckusick 			*php = pp;
4616975Smckusick 		}
4716962Smckusick 	}
4816962Smckusick 	/*
49*16978Smckusick 	 * Set up the hash table for the instruction stop table.
50*16978Smckusick 	 */
51*16978Smckusick 	for (itp = inststoptable; itp->name[0] != '\0'; itp++) {
52*16978Smckusick 		ithp = &inststoptblhdr[hash(itp->name, &size)];
53*16978Smckusick 		itp->size = size;
54*16978Smckusick 		itp->next = *ithp;
55*16978Smckusick 		*ithp = itp;
56*16978Smckusick 	}
57*16978Smckusick 	/*
5816962Smckusick 	 * check each line and replace as appropriate
5916962Smckusick 	 */
6016962Smckusick 	buftail = bufhead = 0;
6116962Smckusick 	bufp = line[0];
6216962Smckusick 	while (fgets(bufp, MAXLINELEN, stdin)) {
6316962Smckusick 		lp = index(bufp, LABELCHAR);
6416962Smckusick 		if (lp != NULL) {
6516962Smckusick 			bufp = newline();
6616962Smckusick 			if (*++lp == '\n') {
6716962Smckusick 				emptyqueue();
6816962Smckusick 				continue;
6916962Smckusick 			}
7016962Smckusick 			strcpy(bufp, lp);
7116962Smckusick 			*lp++ = '\n';
7216962Smckusick 			*lp = '\0';
7316962Smckusick 			emptyqueue();
7416962Smckusick 		}
7516962Smckusick 		for (cp = bufp; isspace(*cp); cp++)
7616962Smckusick 			/* void */;
7716962Smckusick 		if ((cp = doreplaceon(cp)) == 0) {
7816962Smckusick 			bufp = newline();
7916962Smckusick 			continue;
8016962Smckusick 		}
81*16978Smckusick 		for (pp = patshdr[hash(cp, &size)]; pp; pp = pp->next) {
8216962Smckusick 			if (pp->size == size && bcmp(pp->name, cp, size) == 0) {
8316962Smckusick 				expand(pp->replace);
8416962Smckusick 				bufp = line[bufhead];
8516962Smckusick 				break;
8616962Smckusick 			}
8716962Smckusick 		}
8816962Smckusick 		if (!pp) {
8916962Smckusick 			emptyqueue();
9016962Smckusick 			fputs(bufp, stdout);
9116962Smckusick 		}
9216962Smckusick 	}
9316962Smckusick 	emptyqueue();
9416962Smckusick 	exit(0);
9516962Smckusick }
9616962Smckusick 
9716962Smckusick /*
9816962Smckusick  * Integrate an expansion into the assembly stream
9916962Smckusick  */
10016962Smckusick expand(replace)
10116962Smckusick 	char *replace;
10216962Smckusick {
10316962Smckusick 	register int curptr;
10416962Smckusick 	char *nextreplace, *argv[MAXARGS];
105*16978Smckusick 	int argc, argreg, foundarg, mod = 0;
10616962Smckusick 	char parsebuf[BUFSIZ];
10716962Smckusick 
10816962Smckusick 	for (curptr = bufhead; curptr != buftail; ) {
10916962Smckusick 		nextreplace = copyline(replace, line[bufhead]);
11016962Smckusick 		argc = parseline(line[bufhead], argv, parsebuf);
11116962Smckusick 		argreg = nextarg(argc, argv);
11216962Smckusick 		if (argreg == -1)
11316962Smckusick 			break;
114*16978Smckusick 		for (foundarg = 0; curptr != buftail; ) {
115*16978Smckusick 			curptr = PRED(curptr);
11616962Smckusick 			argc = parseline(line[curptr], argv, parsebuf);
117*16978Smckusick 			if (isendofblock(argc, argv))
11816962Smckusick 				break;
119*16978Smckusick 			if (foundarg = ispusharg(argc, argv))
120*16978Smckusick 				break;
12116962Smckusick 			mod |= 1 << modifies(argc, argv);
12216962Smckusick 		}
123*16978Smckusick 		if (!foundarg)
12416962Smckusick 			break;
12516962Smckusick 		replace = nextreplace;
12616962Smckusick 		if (mod & (1 << argreg)) {
127*16978Smckusick 			if (curptr == buftail) {
128*16978Smckusick 				(void)newline();
129*16978Smckusick 				break;
130*16978Smckusick 			}
13116962Smckusick 			(void)newline();
13216962Smckusick 		} else {
13316962Smckusick 			rewrite(line[curptr], argc, argv, argreg);
13416962Smckusick 			mod |= 1 << argreg;
13516962Smckusick 		}
13616962Smckusick 	}
13716962Smckusick 	emptyqueue();
13816962Smckusick 	fputs(replace, stdout);
13916962Smckusick }
14016962Smckusick 
14116962Smckusick /*
14216962Smckusick  * Parse a line of assembly language into opcode and arguments.
14316962Smckusick  */
14416962Smckusick parseline(linep, argv, linebuf)
14516962Smckusick 	char *linep;
14616962Smckusick 	char *argv[];
14716962Smckusick 	char *linebuf;
14816962Smckusick {
14916962Smckusick 	register char *bufp = linebuf, *cp = linep;
15016962Smckusick 	register int argc = 0;
15116962Smckusick 
15216962Smckusick 	for (;;) {
15316962Smckusick 		/*
15416962Smckusick 		 * skip over white space
15516962Smckusick 		 */
15616962Smckusick 		while (isspace(*cp))
15716962Smckusick 			cp++;
15816962Smckusick 		if (*cp == '\0')
15916962Smckusick 			return (argc);
16016962Smckusick 		/*
16116962Smckusick 		 * copy argument
16216962Smckusick 		 */
16316962Smckusick 		if (argc == MAXARGS - 1) {
16416962Smckusick 			fprintf(stderr, "instruction too long->%s", linep);
16516962Smckusick 			return (argc);
16616962Smckusick 		}
16716962Smckusick 		argv[argc++] = bufp;
168*16978Smckusick 		while (!isspace(*cp) && *cp != ARGSEPCHAR && *cp != COMMENTCHAR)
16916962Smckusick 			*bufp++ = *cp++;
17016962Smckusick 		*bufp++ = '\0';
17116962Smckusick 		if (*cp == COMMENTCHAR)
17216962Smckusick 			return (argc);
173*16978Smckusick 		if (*cp == ARGSEPCHAR)
17416962Smckusick 			cp++;
17516962Smckusick 	}
17616962Smckusick }
17716962Smckusick 
17816962Smckusick /*
179*16978Smckusick  * Check for instructions that end a basic block.
180*16978Smckusick  */
181*16978Smckusick isendofblock(argc, argv)
182*16978Smckusick 	int argc;
183*16978Smckusick 	char *argv[];
184*16978Smckusick {
185*16978Smckusick 	register struct inststoptbl *itp;
186*16978Smckusick 	int size;
187*16978Smckusick 
188*16978Smckusick 	if (argc == 0)
189*16978Smckusick 		return (0);
190*16978Smckusick 	for (itp = inststoptblhdr[hash(argv[0], &size)]; itp; itp = itp->next)
191*16978Smckusick 		if (itp->size == size && bcmp(argv[0], itp->name, size) == 0)
192*16978Smckusick 			return (1);
193*16978Smckusick 	return (0);
194*16978Smckusick }
195*16978Smckusick 
196*16978Smckusick /*
19716962Smckusick  * Copy a newline terminated string.
19816962Smckusick  * Return pointer to character following last character copied.
19916962Smckusick  */
20016962Smckusick char *
20116962Smckusick copyline(from, to)
20216962Smckusick 	register char *from, *to;
20316962Smckusick {
20416962Smckusick 
20516962Smckusick 	while (*from != '\n')
20616962Smckusick 		*to++ = *from++;
20716962Smckusick 	*to++ = *from++;
20816962Smckusick 	*to = '\0';
20916962Smckusick 	return (from);
21016962Smckusick }
21116962Smckusick 
21216962Smckusick /*
21316962Smckusick  * open space for next line in the queue
21416962Smckusick  */
21516962Smckusick char *
21616962Smckusick newline()
21716962Smckusick {
21816962Smckusick 	bufhead = SUCC(bufhead);
21916962Smckusick 	if (bufhead == buftail) {
22016962Smckusick 		fputs(line[buftail], stdout);
22116962Smckusick 		buftail = SUCC(buftail);
22216962Smckusick 	}
22316962Smckusick 	return (line[bufhead]);
22416962Smckusick }
22516962Smckusick 
22616962Smckusick /*
22716962Smckusick  * empty the queue by printing out all its lines.
22816962Smckusick  */
22916962Smckusick emptyqueue()
23016962Smckusick {
23116962Smckusick 	while (buftail != bufhead) {
23216962Smckusick 		fputs(line[buftail], stdout);
23316962Smckusick 		buftail = SUCC(buftail);
23416962Smckusick 	}
23516962Smckusick }
23616962Smckusick 
23716962Smckusick /*
23816962Smckusick  * Compute the hash of a string.
23916962Smckusick  * Return the hash and the size of the item hashed
24016962Smckusick  */
24116962Smckusick hash(cp, size)
24216962Smckusick 	char *cp;
24316962Smckusick 	int *size;
24416962Smckusick {
24516962Smckusick 	register char *cp1 = cp;
246*16978Smckusick 	register int hash = 0;
24716962Smckusick 
24816962Smckusick 	while (*cp1 && *cp1 != '\n')
24916962Smckusick 		hash += (int)*cp1++;
25016962Smckusick 	*size = cp1 - cp + 1;
25116962Smckusick 	hash &= HSHSIZ - 1;
252*16978Smckusick 	return (hash);
25316962Smckusick }
254