116962Smckusick /* Copyright (c) 1984 Regents of the University of California */ 216962Smckusick 316962Smckusick #ifndef lint 4*16963Smckusick static char sccsid[] = "@(#)main.c 1.2 (Berkeley) 08/18/84"; 516962Smckusick #endif not lint 616962Smckusick 716962Smckusick #include <stdio.h> 816962Smckusick #include <ctype.h> 9*16963Smckusick #include "inline.h" 1016962Smckusick 1116962Smckusick main(argc, argv) 1216962Smckusick int argc; 1316962Smckusick char *argv[]; 1416962Smckusick { 1516962Smckusick register struct pats *pp, **hp; 1616962Smckusick register char *cp, *lp; 1716962Smckusick register char *bufp; 1816962Smckusick int size; 1916962Smckusick extern char *index(); 2016962Smckusick 2116962Smckusick if (argc > 1) 2216962Smckusick freopen(argv[1], "r", stdin); 2316962Smckusick if (argc > 2) 2416962Smckusick freopen(argv[2], "w", stdout); 2516962Smckusick /* 2616962Smckusick * set up the hash table 2716962Smckusick */ 2816962Smckusick for (pp = language_ptab; pp->name[0] != '\0'; pp++) { 2916962Smckusick hp = hash(pp->name, &size); 3016962Smckusick pp->size = size; 3116962Smckusick pp->next = *hp; 3216962Smckusick *hp = pp; 3316962Smckusick } 3416962Smckusick for (pp = libc_ptab; pp->name[0] != '\0'; pp++) { 3516962Smckusick hp = hash(pp->name, &size); 3616962Smckusick pp->size = size; 3716962Smckusick pp->next = *hp; 3816962Smckusick *hp = pp; 3916962Smckusick } 4016962Smckusick for (pp = machine_ptab; pp->name[0] != '\0'; pp++) { 4116962Smckusick hp = hash(pp->name, &size); 4216962Smckusick pp->size = size; 4316962Smckusick pp->next = *hp; 4416962Smckusick *hp = pp; 4516962Smckusick } 4616962Smckusick /* 4716962Smckusick * check each line and replace as appropriate 4816962Smckusick */ 4916962Smckusick buftail = bufhead = 0; 5016962Smckusick bufp = line[0]; 5116962Smckusick while (fgets(bufp, MAXLINELEN, stdin)) { 5216962Smckusick lp = index(bufp, LABELCHAR); 5316962Smckusick if (lp != NULL) { 5416962Smckusick bufp = newline(); 5516962Smckusick if (*++lp == '\n') { 5616962Smckusick emptyqueue(); 5716962Smckusick continue; 5816962Smckusick } 5916962Smckusick strcpy(bufp, lp); 6016962Smckusick *lp++ = '\n'; 6116962Smckusick *lp = '\0'; 6216962Smckusick emptyqueue(); 6316962Smckusick } 6416962Smckusick for (cp = bufp; isspace(*cp); cp++) 6516962Smckusick /* void */; 6616962Smckusick if ((cp = doreplaceon(cp)) == 0) { 6716962Smckusick bufp = newline(); 6816962Smckusick continue; 6916962Smckusick } 7016962Smckusick for (pp = *hash(cp, &size); pp; pp = pp->next) { 7116962Smckusick if (pp->size == size && bcmp(pp->name, cp, size) == 0) { 7216962Smckusick expand(pp->replace); 7316962Smckusick bufp = line[bufhead]; 7416962Smckusick break; 7516962Smckusick } 7616962Smckusick } 7716962Smckusick if (!pp) { 7816962Smckusick emptyqueue(); 7916962Smckusick fputs(bufp, stdout); 8016962Smckusick } 8116962Smckusick } 8216962Smckusick emptyqueue(); 8316962Smckusick exit(0); 8416962Smckusick } 8516962Smckusick 8616962Smckusick /* 8716962Smckusick * Integrate an expansion into the assembly stream 8816962Smckusick */ 8916962Smckusick expand(replace) 9016962Smckusick char *replace; 9116962Smckusick { 9216962Smckusick register int curptr; 9316962Smckusick char *nextreplace, *argv[MAXARGS]; 9416962Smckusick int argc, argreg, queueempty, mod = 0; 9516962Smckusick char parsebuf[BUFSIZ]; 9616962Smckusick 9716962Smckusick for (curptr = bufhead; curptr != buftail; ) { 9816962Smckusick queueempty = (curptr == buftail); 9916962Smckusick curptr = PRED(curptr); 10016962Smckusick nextreplace = copyline(replace, line[bufhead]); 10116962Smckusick argc = parseline(line[bufhead], argv, parsebuf); 10216962Smckusick argreg = nextarg(argc, argv); 10316962Smckusick if (argreg == -1) 10416962Smckusick break; 10516962Smckusick while (!queueempty) { 10616962Smckusick argc = parseline(line[curptr], argv, parsebuf); 10716962Smckusick if (ispusharg(argc, argv)) 10816962Smckusick break; 10916962Smckusick mod |= 1 << modifies(argc, argv); 11016962Smckusick queueempty = (curptr == buftail); 11116962Smckusick curptr = PRED(curptr); 11216962Smckusick } 11316962Smckusick if (queueempty) 11416962Smckusick break; 11516962Smckusick replace = nextreplace; 11616962Smckusick if (mod & (1 << argreg)) { 11716962Smckusick (void)newline(); 11816962Smckusick } else { 11916962Smckusick rewrite(line[curptr], argc, argv, argreg); 12016962Smckusick mod |= 1 << argreg; 12116962Smckusick } 12216962Smckusick } 12316962Smckusick emptyqueue(); 12416962Smckusick fputs(replace, stdout); 12516962Smckusick } 12616962Smckusick 12716962Smckusick /* 12816962Smckusick * Parse a line of assembly language into opcode and arguments. 12916962Smckusick */ 13016962Smckusick parseline(linep, argv, linebuf) 13116962Smckusick char *linep; 13216962Smckusick char *argv[]; 13316962Smckusick char *linebuf; 13416962Smckusick { 13516962Smckusick register char *bufp = linebuf, *cp = linep; 13616962Smckusick register int argc = 0; 13716962Smckusick 13816962Smckusick for (;;) { 13916962Smckusick /* 14016962Smckusick * skip over white space 14116962Smckusick */ 14216962Smckusick while (isspace(*cp)) 14316962Smckusick cp++; 14416962Smckusick if (*cp == '\0') 14516962Smckusick return (argc); 14616962Smckusick /* 14716962Smckusick * copy argument 14816962Smckusick */ 14916962Smckusick if (argc == MAXARGS - 1) { 15016962Smckusick fprintf(stderr, "instruction too long->%s", linep); 15116962Smckusick return (argc); 15216962Smckusick } 15316962Smckusick argv[argc++] = bufp; 15416962Smckusick while (!isspace(*cp) && *cp != ',' && *cp != COMMENTCHAR) 15516962Smckusick *bufp++ = *cp++; 15616962Smckusick *bufp++ = '\0'; 15716962Smckusick if (*cp == COMMENTCHAR) 15816962Smckusick return (argc); 15916962Smckusick if (*cp == ',') 16016962Smckusick cp++; 16116962Smckusick } 16216962Smckusick } 16316962Smckusick 16416962Smckusick /* 16516962Smckusick * Copy a newline terminated string. 16616962Smckusick * Return pointer to character following last character copied. 16716962Smckusick */ 16816962Smckusick char * 16916962Smckusick copyline(from, to) 17016962Smckusick register char *from, *to; 17116962Smckusick { 17216962Smckusick 17316962Smckusick while (*from != '\n') 17416962Smckusick *to++ = *from++; 17516962Smckusick *to++ = *from++; 17616962Smckusick *to = '\0'; 17716962Smckusick return (from); 17816962Smckusick } 17916962Smckusick 18016962Smckusick /* 18116962Smckusick * open space for next line in the queue 18216962Smckusick */ 18316962Smckusick char * 18416962Smckusick newline() 18516962Smckusick { 18616962Smckusick bufhead = SUCC(bufhead); 18716962Smckusick if (bufhead == buftail) { 18816962Smckusick fputs(line[buftail], stdout); 18916962Smckusick buftail = SUCC(buftail); 19016962Smckusick } 19116962Smckusick return (line[bufhead]); 19216962Smckusick } 19316962Smckusick 19416962Smckusick /* 19516962Smckusick * empty the queue by printing out all its lines. 19616962Smckusick */ 19716962Smckusick emptyqueue() 19816962Smckusick { 19916962Smckusick while (buftail != bufhead) { 20016962Smckusick fputs(line[buftail], stdout); 20116962Smckusick buftail = SUCC(buftail); 20216962Smckusick } 20316962Smckusick } 20416962Smckusick 20516962Smckusick /* 20616962Smckusick * Compute the hash of a string. 20716962Smckusick * Return the hash and the size of the item hashed 20816962Smckusick */ 20916962Smckusick struct pats ** 21016962Smckusick hash(cp, size) 21116962Smckusick char *cp; 21216962Smckusick int *size; 21316962Smckusick { 21416962Smckusick register char *cp1 = cp; 21516962Smckusick register int hash; 21616962Smckusick 21716962Smckusick hash = 1; 21816962Smckusick while (*cp1 && *cp1 != '\n') 21916962Smckusick hash += (int)*cp1++; 22016962Smckusick *size = cp1 - cp + 1; 22116962Smckusick hash &= HSHSIZ - 1; 22216962Smckusick return (&hashhdr[hash]); 22316962Smckusick } 224