📄 cc.c
字号:
#define SBSIZE 2000char sbf[SBSIZE];/* C command */char *tmp0;char *tmp1;char *tmp2;char *tmp3;char *tmp4;char *tmp5;char ts[1000];char *tsp ts;char *av[50];char *clist[50];char *llist[50];int instring;int pflag;int sflag;int cflag;int oflag;int proflag;int depth;int *ibuf;int *ibuf1;int *ibuf2;int *obuf;char *lp;char *line;int lineno;int exfail;struct symtab { char name[8]; char *value;} *symtab;int symsiz 200;struct symtab *defloc;struct symtab *incloc;struct symtab *eifloc;struct symtab *ifdloc;struct symtab *ifnloc;struct symtab *unxloc;int trulvl;int flslvl;char *stringbuf;char *pass0 "/lib/c0";char *pass1 "/lib/c1";char *pass2 "/lib/c2";char *pref "/lib/crt0.o";main(argc, argv)char *argv[]; { char *t; int nc, nl, i, j, c, f20, nxo; int dexit(); i = nc = nl = f20 = nxo = 0; while(++i < argc) { if(*argv[i] == '-') switch (argv[i][1]) { default: goto passa; case 'S': sflag++; cflag++; break; case 'O': oflag++; break; case 'p': proflag++; pref = "/lib/mcrt0.o"; break; case 'P': pflag++; case 'c': cflag++; break; case 'f': pref = "/lib/fcrt0.o"; pass0 = "/lib/fc0"; pass1 = "/lib/fc1"; break; case '2': if(argv[i][2] == '\0') pref = "/lib/crt2.o"; else { pref = "/lib/crt20.o"; f20 = 1; } break; case 't': if (argv[i][2]=='0') pass0 = "/usr/c/c0"; if (argv[i][2]=='1') pass1 = "/usr/c/c1"; if (argv[i][2]=='2') pass2 = "/usr/c/c2"; break; } else { passa: t = argv[i]; if(getsuf(t)=='c') { clist[nc++] = t; t = setsuf(t, 'o'); } if (nodup(llist, t)) { llist[nl++] = t; if (getsuf(t)=='o') nxo++; } } } if(nc==0) goto nocom; if (pflag==0) { tmp0 = copy("/tmp/ctm0a"); while((c=open(tmp0, 0))>=0) { close(c); tmp0[9]++; } while((creat(tmp0, 0400))<0) tmp0[9]++; } if ((signal(2, 1) & 01) == 0) signal(2, &dexit); (tmp1 = copy(tmp0))[8] = '1'; (tmp2 = copy(tmp0))[8] = '2'; (tmp3 = copy(tmp0))[8] = '3'; if (oflag) (tmp5 = copy(tmp0))[8] = '5'; if (pflag==0) (tmp4 = copy(tmp0))[8] = '4'; for (i=0; i<nc; i++) { if (nc>1) printf("%s:\n", clist[i]); av[0] = "c0"; if (pflag) tmp4 = setsuf(clist[i], 'i'); av[1] = expand(clist[i]); if (pflag || exfail) continue; if (av[1] == 0) { cflag++; continue; } av[2] = tmp1; av[3] = tmp2; if (proflag) { av[4] = "-P"; av[5] = 0; } else av[4] = 0; if (callsys(pass0, av)) { cflag++; continue; } av[0] = "c1"; av[1] = tmp1; av[2] = tmp2; if (sflag) tmp3 = setsuf(clist[i], 's'); av[3] = tmp3; if (oflag) av[3] = tmp5; av[4] = 0; if(callsys(pass1, av)) { cflag++; continue; } if (oflag) { av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; callsys(pass2, av); unlink(tmp5); } if (sflag) continue; av[0] = "as"; av[1] = "-"; av[2] = tmp3; av[3] = 0; cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); callsys("/bin/as", av); t = setsuf(clist[i], 'o'); cunlink(t); if(link("a.out", t) || cunlink("a.out")) { printf("move failed: %s\n", t); cflag++; } }nocom: if (cflag==0 && nl!=0) { i = 0; av[0] = "ld"; av[1] = "-X"; av[2] = pref; j = 3; while(i<nl) av[j++] = llist[i++]; if(f20) av[j++] = "-l2"; else { av[j++] = "-lc"; av[j++] = "-l"; } av[j++] = 0; callsys("/bin/ld", av); if (nc==1 && nxo==1) cunlink(setsuf(clist[0], 'o')); } dexit();}dexit(){ if (!pflag) { cunlink(tmp1); cunlink(tmp2); if (sflag==0) cunlink(tmp3); cunlink(tmp4); cunlink(tmp5); cunlink(tmp0); } exit();}expand(file)char *file;{ int ib1[259], ib2[259], ob[259]; struct symtab stab[200]; char ln[196]; register int c; register char *rlp; exfail = 0; ibuf = ibuf1 = ib1; ibuf2 = ib2; if (fopen(file, ibuf1)<0) return(file); if (getc(ibuf1) != '#') { close(ibuf1[0]); return(file); } ibuf1[1]++; ibuf1[2]--; obuf = ob; symtab = stab; for (c=0; c<200; c++) { stab[c].name[0] = '\0'; stab[c].value = 0; } insym(&defloc, "define"); insym(&incloc, "include"); insym(&eifloc, "endif"); insym(&ifdloc, "ifdef"); insym(&ifnloc, "ifndef"); insym(&unxloc, "unix"); stringbuf = sbf; trulvl = 0; flslvl = 0; line = ln; lineno = 0; if (fcreat(tmp4, obuf) < 0) { printf("Can't creat %s\n", tmp4); dexit(); } while(getline()) { if (ibuf==ibuf2 && pflag==0) putc(001, obuf); /*SOH: insert */ if (ln[0] != '#' && flslvl==0) for (rlp = line; c = *rlp++;) putc(c, obuf); putc('\n', obuf); } for(rlp=line; c = *rlp++;) putc(c,obuf); fflush(obuf); close(obuf[0]); close(ibuf1[0]); return(tmp4);}getline(){ register int c, sc, state; struct symtab *np; char *namep, *filname; if (ibuf==ibuf1) lineno++; lp = line; *lp = '\0'; state = 0; if ((c=getch()) == '#') state = 1; while (c!='\n' && c!='\0') { if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_') { namep = lp; sch(c); while ('a'<=(c=getch()) && c<='z' ||'A'<=c && c<='Z' ||'0'<=c && c<='9' ||c=='_') sch(c); sch('\0'); lp--; if (state>3) { if (flslvl==0 &&(state+!lookup(namep,-1)->name[0])==5) trulvl++; else flslvl++; out: while (c!='\n' && c!= '\0') c = getch(); return(c); } if (state!=2 || flslvl==0) { ungetc(c); np = lookup(namep, state); c = getch(); } if (state==1) { if (np==defloc) state = 2; else if (np==incloc) state = 3; else if (np==ifnloc) state = 4; else if (np==ifdloc) state = 5; else if (np==eifloc) { if (flslvl) --flslvl; else if (trulvl) --trulvl; else error("If-less endif"); goto out; } else { error("Undefined control"); while (c!='\n' && c!='\0') c = getch(); return(c); } } else if (state==2) { if (flslvl) goto out; np->value = stringbuf; savch(c); while ((c=getch())!='\n' && c!='\0') savch(c); savch('\0'); return(1); } continue; } else if ((sc=c)=='\'' || sc=='"') { sch(sc); filname = lp; instring++; while ((c=getch())!=sc && c!='\n' && c!='\0') { sch(c); if (c=='\\') sch(getch()); } instring = 0; if (flslvl) goto out; if (state==3) { if (flslvl) goto out; *lp = '\0'; while ((c=getch())!='\n' && c!='\0'); if (ibuf==ibuf2) error("Nested 'include'"); if (fopen(filname, ibuf2)<0) error("Missing file %s", filname); else ibuf = ibuf2; return(c); } } sch(c); c = getch(); } sch('\0'); if (state>1) error("Control syntax"); return(c);}insym(sp, namep)struct symtab **sp;char *namep;{ register struct symtab *np; *sp = np = lookup(namep, 1); np->value = np->name;}error(s, x){ printf("%d: ", lineno); printf(s, x); putchar('\n'); exfail++; cflag++;}sch(c){ register char *rlp; rlp = lp; if (rlp==line+194) error("Line overflow"); *rlp++ = c; if (rlp>line+195) rlp = line+195; lp = rlp;}savch(c){ *stringbuf++ = c; if (stringbuf-sbf < SBSIZE) return; error("Too much defining"); dexit();}getch(){ register int c;loop: if ((c=getc1())=='/' && !instring) { if ((c=getc1())!='*') { ungetc(c); return('/'); } for(;;) { c = getc1(); cloop: switch (c) { case '\0': return('\0'); case '*': if ((c=getc1())=='/') goto loop; goto cloop; case '\n': if (ibuf==ibuf1) { putc('\n', obuf); lineno++; } continue; } } } return(c);}char pushbuff[300];char *pushp pushbuff;ungetc(c) { *++pushp = c; }getc1(){ register c; if (*pushp !=0) return(*pushp--); depth=0; if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) { close(ibuf2[0]); ibuf = ibuf1; putc('\n', obuf); lineno++; c = getc1(); } if (c<0) return(0); return(c);}lookup(namep, enterf)char *namep;{ register char *np, *snp; register struct symtab *sp; int i, c, around; np = namep; around = i = 0; while (c = *np++) i =+ c; i =% symsiz; sp = &symtab[i]; while (sp->name[0]) { snp = sp; np = namep; while (*snp++ == *np) if (*np++ == '\0' || np==namep+8) { if (!enterf) subst(namep, sp); return(sp); } if (++sp >= &symtab[symsiz]) if (around++) { error("too many defines"); dexit(); } else sp = symtab; } if (enterf>0) { snp = namep; for (np = &sp->name[0]; np < &sp->name[8];) if (*np++ = *snp) snp++; } return(sp);}char revbuff[200];char *bp;backsch(c) { if (bp-revbuff > 200) error("Excessive define looping", bp--); *bp++ = c; }subst(np, sp)char *np;struct symtab *sp;{ register char *vp; lp = np; bp = revbuff; if (depth++>100) { error("define recursion loop\n"); return; } if ((vp = sp->value) == 0) return; /* arrange that define unix unix still has no effect, avoiding rescanning */ if (streq(sp->name,sp->value)) { while (*vp) sch(*vp++); return; } backsch(' '); if (*vp == '(') expdef(vp); else while (*vp) backsch(*vp++); backsch(' '); while (bp>revbuff) ungetc(*--bp);}getsuf(as)char as[];{ register int c; register char *s; register int t; s = as; c = 0; while(t = *s++) if (t=='/') c = 0; else c++; s =- 3; if (c<=14 && c>2 && *s++=='.') return(*s); return(0);}setsuf(as, ch)char as[];{ register char *s, *s1; s = s1 = copy(as); while(*s) if (*s++ == '/') s1 = s; s[-1] = ch; return(s1);}callsys(f, v)char f[], *v[]; { int t, status; if ((t=fork())==0) { execv(f, v); printf("Can't find %s\n", f); exit(1); } else if (t == -1) { printf("Try again\n"); return(1); } while(t!=wait(&status)); if ((t=(status&0377)) != 0 && t!=14) { if (t!=2) /* interrupt */ printf("Fatal error in %s\n", f); dexit(); } return((status>>8) & 0377);}copy(as)char as[];{ register char *otsp, *s; otsp = tsp; s = as; while(*tsp++ = *s++); return(otsp);}nodup(l, os)char **l, *os;{ register char *t, *s; register int c; s = os; if (getsuf(s) != 'o') return(1); while(t = *l++) { while(c = *s++) if (c != *t++) break; if (*t=='\0' && c=='\0') return(0); s = os; } return(1);}cunlink(f)char *f;{ if (f==0) return(0); return(unlink(f));}expdef(proto) char *proto;{char buffer[100], *parg[20], *pval[20], name[20], *cspace, *wp;char protcop[100], *pr;int narg, k, i, c;pr = protcop;while (*pr++ = *proto++);proto= protcop;for (narg=0; (parg[narg] = token(&proto)) != 0; narg++) ;/* now scan input */cspace = buffer;while ((c=getch()) == ' ');if (c != '(') { error("defined function requires arguments"); return; }ungetc(c);for(k=0; pval[k] = coptok(&cspace); k++);if (k!=narg) { error("define argument mismatch"); return; }while (c= *proto++) { if (!letter(c)) backsch(c); else { wp = name; *wp++ = c; while (letnum(*proto)) *wp++ = *proto++; *wp = 0; for (k=0; k<narg; k++) if(streq(name,parg[k])) break; wp = k <narg ? pval[k] : name; while (*wp) backsch(*wp++); } }}token(cpp) char **cpp;{char *val;int stc;stc = **cpp;*(*cpp)++ = '\0';if (stc==')') return(0);while (**cpp == ' ') (*cpp)++;for (val = *cpp; (stc= **cpp) != ',' && stc!= ')'; (*cpp)++) { if (!letnum(stc) || (val == *cpp && !letter(stc))) { error("define prototype argument error"); break; } }return(val);}coptok (cpp) char **cpp; {char *val;int stc, stop,paren;paren = 0;val = *cpp;if (getch() == ')') return(0);while (((stc = getch()) != ',' && stc != ')') || paren > 0) { if (stc == '"' || stc == '\'') { stop = stc; if (stop == '\'') *(*cpp)++ = '\''; while ( (stc = getch()) != stop) { if (stc == '\n') { error ("non-terminated string"); break; } if (stc == '\\') if ((stc= getch()) != stop && stc != '\\') *(*cpp)++ = '\\'; *(*cpp)++ = stc; } if (stop == '\'') *(*cpp)++ = '\''; } else if (stc == '\\') { stc = getch(); if (stc != '"' && stc != '\\') *(*cpp)++ = '\\'; *(*cpp)++ = stc; } else { *(*cpp)++ = stc; if (stc == '(') paren++; if (stc == ')') paren--; } }*(*cpp)++ = 0;ungetc(stc);return(val);}letter(c){if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_')) return (1);else return(0);}letnum(c){if (letter(c) || (c >= '0' && c <= '9')) return(1);else return(0);}streq(s,t) char *s, *t;{int c;while ( (c= *s++) == *t++) if (c==0) return(1);return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -