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