xref: /csrg-svn/sys/vax/inline/main.c (revision 16975)
1 /* Copyright (c) 1984 Regents of the University of California */
2 
3 #ifndef lint
4 static char sccsid[] = "@(#)main.c	1.3	(Berkeley)	08/20/84";
5 #endif not lint
6 
7 #include <stdio.h>
8 #include <ctype.h>
9 #include "inline.h"
10 
11 /*
12  * These are the pattern tables to be loaded
13  */
14 struct pats *inittables[] = {
15 	language_ptab,
16 	libc_ptab,
17 	machine_ptab,
18 	0
19 };
20 
21 main(argc, argv)
22 	int argc;
23 	char *argv[];
24 {
25 	register struct pats *pp, **hp;
26 	register char *cp, *lp;
27 	register char *bufp;
28 	register struct pats **tablep;
29 	int size;
30 	extern char *index();
31 
32 	if (argc > 1)
33 		freopen(argv[1], "r", stdin);
34 	if (argc > 2)
35 		freopen(argv[2], "w", stdout);
36 	/*
37 	 * set up the hash table
38 	 */
39 	for (tablep = inittables; *tablep; tablep++) {
40 		for (pp = *tablep; pp->name[0] != '\0'; pp++) {
41 			hp = hash(pp->name, &size);
42 			pp->size = size;
43 			pp->next = *hp;
44 			*hp = pp;
45 		}
46 	}
47 	/*
48 	 * check each line and replace as appropriate
49 	 */
50 	buftail = bufhead = 0;
51 	bufp = line[0];
52 	while (fgets(bufp, MAXLINELEN, stdin)) {
53 		lp = index(bufp, LABELCHAR);
54 		if (lp != NULL) {
55 			bufp = newline();
56 			if (*++lp == '\n') {
57 				emptyqueue();
58 				continue;
59 			}
60 			strcpy(bufp, lp);
61 			*lp++ = '\n';
62 			*lp = '\0';
63 			emptyqueue();
64 		}
65 		for (cp = bufp; isspace(*cp); cp++)
66 			/* void */;
67 		if ((cp = doreplaceon(cp)) == 0) {
68 			bufp = newline();
69 			continue;
70 		}
71 		for (pp = *hash(cp, &size); pp; pp = pp->next) {
72 			if (pp->size == size && bcmp(pp->name, cp, size) == 0) {
73 				expand(pp->replace);
74 				bufp = line[bufhead];
75 				break;
76 			}
77 		}
78 		if (!pp) {
79 			emptyqueue();
80 			fputs(bufp, stdout);
81 		}
82 	}
83 	emptyqueue();
84 	exit(0);
85 }
86 
87 /*
88  * Integrate an expansion into the assembly stream
89  */
90 expand(replace)
91 	char *replace;
92 {
93 	register int curptr;
94 	char *nextreplace, *argv[MAXARGS];
95 	int argc, argreg, queueempty, mod = 0;
96 	char parsebuf[BUFSIZ];
97 
98 	for (curptr = bufhead; curptr != buftail; ) {
99 		queueempty = (curptr == buftail);
100 		curptr = PRED(curptr);
101 		nextreplace = copyline(replace, line[bufhead]);
102 		argc = parseline(line[bufhead], argv, parsebuf);
103 		argreg = nextarg(argc, argv);
104 		if (argreg == -1)
105 			break;
106 		while (!queueempty) {
107 			argc = parseline(line[curptr], argv, parsebuf);
108 			if (ispusharg(argc, argv))
109 				break;
110 			mod |= 1 << modifies(argc, argv);
111 			queueempty = (curptr == buftail);
112 			curptr = PRED(curptr);
113 		}
114 		if (queueempty)
115 			break;
116 		replace = nextreplace;
117 		if (mod & (1 << argreg)) {
118 			(void)newline();
119 		} else {
120 			rewrite(line[curptr], argc, argv, argreg);
121 			mod |= 1 << argreg;
122 		}
123 	}
124 	emptyqueue();
125 	fputs(replace, stdout);
126 }
127 
128 /*
129  * Parse a line of assembly language into opcode and arguments.
130  */
131 parseline(linep, argv, linebuf)
132 	char *linep;
133 	char *argv[];
134 	char *linebuf;
135 {
136 	register char *bufp = linebuf, *cp = linep;
137 	register int argc = 0;
138 
139 	for (;;) {
140 		/*
141 		 * skip over white space
142 		 */
143 		while (isspace(*cp))
144 			cp++;
145 		if (*cp == '\0')
146 			return (argc);
147 		/*
148 		 * copy argument
149 		 */
150 		if (argc == MAXARGS - 1) {
151 			fprintf(stderr, "instruction too long->%s", linep);
152 			return (argc);
153 		}
154 		argv[argc++] = bufp;
155 		while (!isspace(*cp) && *cp != ',' && *cp != COMMENTCHAR)
156 			*bufp++ = *cp++;
157 		*bufp++ = '\0';
158 		if (*cp == COMMENTCHAR)
159 			return (argc);
160 		if (*cp == ',')
161 			cp++;
162 	}
163 }
164 
165 /*
166  * Copy a newline terminated string.
167  * Return pointer to character following last character copied.
168  */
169 char *
170 copyline(from, to)
171 	register char *from, *to;
172 {
173 
174 	while (*from != '\n')
175 		*to++ = *from++;
176 	*to++ = *from++;
177 	*to = '\0';
178 	return (from);
179 }
180 
181 /*
182  * open space for next line in the queue
183  */
184 char *
185 newline()
186 {
187 	bufhead = SUCC(bufhead);
188 	if (bufhead == buftail) {
189 		fputs(line[buftail], stdout);
190 		buftail = SUCC(buftail);
191 	}
192 	return (line[bufhead]);
193 }
194 
195 /*
196  * empty the queue by printing out all its lines.
197  */
198 emptyqueue()
199 {
200 	while (buftail != bufhead) {
201 		fputs(line[buftail], stdout);
202 		buftail = SUCC(buftail);
203 	}
204 }
205 
206 /*
207  * Compute the hash of a string.
208  * Return the hash and the size of the item hashed
209  */
210 struct pats **
211 hash(cp, size)
212 	char *cp;
213 	int *size;
214 {
215 	register char *cp1 = cp;
216 	register int hash;
217 
218 	hash = 1;
219 	while (*cp1 && *cp1 != '\n')
220 		hash += (int)*cp1++;
221 	*size = cp1 - cp + 1;
222 	hash &= HSHSIZ - 1;
223 	return (&hashhdr[hash]);
224 }
225