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