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