add sostat
[unix-history] / usr / src / sys / vax / inline / main.c
CommitLineData
2472a393
KM
1/* Copyright (c) 1984 Regents of the University of California */
2
3#ifndef lint
ea1f375a 4static char sccsid[] = "@(#)main.c 1.2 (Berkeley) %G%";
2472a393
KM
5#endif not lint
6
7#include <stdio.h>
8#include <ctype.h>
ea1f375a 9#include "inline.h"
2472a393
KM
10
11main(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 */
89expand(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 */
130parseline(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 */
168char *
169copyline(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 */
183char *
184newline()
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 */
197emptyqueue()
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 */
209struct pats **
210hash(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}