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