📄 cc.c
字号:
while (*fn) fn++; while (fn > fln && *fn != '.') fn--; if (fn != fln) return fn+1; return (char *)0;}runvec(vec, pass, in, out) struct arglist *vec; struct passinfo *pass; char *in, *out;{ int pid, status; int shifted = 0; if ( strncmp(vec->al_argv[1], "/usr/", 5) == 0 && access(vec->al_argv[1] + 4, 1) == 0 ) { vec->al_argv[1] += 4; shifted = 1; } if (v_flag) { pr_vec(vec); if (pass->p_flags & STDIN) { prs(" <"); prs(in); } if (pass->p_flags & STDOUT && !E_flag) { prs(" >"); prs(out); } prs("\n"); } if (noexec) { if (shifted) vec->al_argv[1] -= 4; clean(vec); return 1; } if ((pid = fork()) == 0) { /* start up the process */ if (pass->p_flags & STDIN && strcmp(in, "-") != 0) { /* redirect standard input */ close(0); if (open(in, 0) != 0) panic("cannot open input file\n"); } if (pass->p_flags & STDOUT && !E_flag) { /* redirect standard output */ close(1); if (creat(out, 0666) != 1) panic("cannot create output file\n"); } ex_vec(vec); } if (pid == -1) panic("no more processes\n"); kids = pid; wait(&status); if (status) switch(status & 0177) { case SIGHUP: case SIGINT: case SIGQUIT: case SIGTERM: case 0: break; default: if (E_flag && (status & 0177) == SIGPIPE) break; prs(vec->al_argv[1]); prs(" died with signal "); prnum(status & 0177); prs("\n"); } if (shifted) vec->al_argv[1] -= 4; clean(vec); kids = -1; return status ? ((RET_CODE = 1), 0) : 1;}prnum(x) register unsigned x;{ static char numbuf[8]; /* though it prints at most 3 characters */ register char *cp = numbuf + sizeof(numbuf) - 1; *cp = '\0'; while (x >= 10) { *--cp = (x % 10) + '0'; x /= 10; } *--cp = x + '0'; prs(cp);}prs(str) char *str;{ if (str && *str) write(2, str, strlen(str));}panic(str) char *str;{ prs(str); trapcc(SIGINT);}pr_vec(vec) register struct arglist *vec;{ register char **ap = &vec->al_argv[1]; vec->al_argv[vec->al_argc] = 0; prs(*ap); while (*++ap) { prs(" "); if (strlen(*ap)) prs(*ap); else prs("(empty)"); }}ex_vec(vec) register struct arglist *vec;{ extern int errno; vec->al_argv[vec->al_argc] = 0; execv(vec->al_argv[1], &(vec->al_argv[1])); if (errno == ENOEXEC) { /* not an a.out, try it with the SHELL */ vec->al_argv[0] = SHELL; execv(SHELL, &(vec->al_argv[0])); } if (access(vec->al_argv[1], 1) == 0) { /* File is executable. */ prs("Cannot execute "); prs(vec->al_argv[1]); prs(". Not enough memory.\n"); prs("Reduce the memory use of your system and try again\n"); } else { prs(vec->al_argv[1]); prs(" is not executable\n"); } exit(1);}mktempname(nm) register char *nm;{ register int i; register int pid = getpid(); mkstr(nm, tmpdir, "/", compbase->c_callname); while (*nm) nm++; for (i = 9; i > 3; i--) { *nm++ = (pid % 10) + '0'; pid /= 10; } *nm++ = '.'; *nm++ = '\0'; /* null termination */}mkbase(){ register struct compile *p = passes; USTRING callname; register int len; basename(ProgCall, callname); len = strlen(callname); while (p->c_suffix) { if (strcmp(p->c_callname, callname+len-strlen(p->c_callname)) == 0) { compbase = p; mkloader(); return; } p++; } /* we should not get here */ panic("internal error\n");}mkloader(){ register struct passinfo *p = passinfo; register struct pass *pass; while (!(p->p_flags & LOADER)) p++; loaderinfo = p; pass = &(compbase->c_passes[0]); while (strcmp(pass->pp_name, p->p_name)) pass++; loader = pass;}needsprep(name) char *name;{ int file; char fc; file = open(name,0); if (file <0) return 0; if (read(file, &fc, 1) != 1) fc = 0; close(file); return fc == '#';}cfile(name) char *name;{ while (*name != '\0' && *name != '.') name++; if (*name == '\0') return 0; return (*++name == 'c' && *++name == '\0');}char *apply(pinf, cp, name, passindex, noremove, first, resultname) register struct passinfo *pinf; register struct compile *cp; char *name, *resultname;{ /* Apply a pass, indicated by "pinf", with args in cp->c_passes[passindex], to name "name", leaving the result in a file with name "resultname", concatenated with result suffix. When neccessary, the preprocessor is run first. If "noremove" is NOT set, the file "name" is removed. */ struct arglist *call = &CALLVEC; struct pass *pass = &(cp->c_passes[passindex]); char *outname; if ( /* this pass is the first pass */ first && ( /* preprocessor always needed */ (pinf->p_flags & PREPALWAYS) ||/* or only when "needsprep" says so */ ( (pinf->p_flags & PREPCOND) && needsprep(name)) ) ) { mkstr(newfil, tmpname, passinfo[0].p_to, ""); mkvec(call, name, newfil, &preprocessor, &passinfo[0]); if (! runvec(call, &passinfo[0], name, newfil)) { cleanup(newfil); return 0; } /* * When -m is specified and we have a .c file, then we * should run irrel. */ if (m_flag && cfile(name)) { /* newfil is OK */ mkvec(call, newfil, newfil, &irrel, &passinfo[1]); if (! runvec(call, &passinfo[1], newfil, newfil)) { cleanup(newfil); return 0; } } strcpy(curfil, newfil); newfil[0] = '\0'; name = curfil; noremove = 0; } if (pinf->p_to) outname = mkstr(newfil, resultname, pinf->p_to, ""); else outname = o_FILE; mkvec(call, name, outname, pass, pinf); if (! runvec(call, pinf, name, outname)) { if (! (pinf->p_flags & NOCLEAN)) cleanup(outname); if (! noremove) cleanup(name); return 0; } if (! noremove) cleanup(name); strcpy(curfil, newfil); newfil[0] = '\0'; return curfil;}intapplicable(pinf, suffix) struct passinfo *pinf; char *suffix;{ /* Return one if the pass indicated by "pinfo" is applicable to a file with suffix "suffix". */ register char *sfx = pinf->p_from; int l; if (! suffix) return 0; l = strlen(suffix); while (*sfx) { register char *p = sfx; while (*p && *p != ',') p++; if (l == p - sfx && strncmp(sfx, suffix, l) == 0) { return 1; } if (*p == ',') sfx = p+1; else sfx = p; } return 0;} char *process(name, noremove) char *name;{ register struct compile *cp = passes; char *suffix = extension(name); USTRING base; register struct pass *pass; register struct passinfo *pinf; if (E_flag) { /* -E uses the cpp pass. */ suffix = "CPP"; } if (! suffix) return name; basename(name, base); while (cp->c_suffix) { if ((cp->c_flags & DEFLANG) && strcmp(cp->c_suffix, suffix) == 0) break; cp++; } if (! cp->c_suffix) cp = compbase; pass = cp->c_passes; while (pass->pp_name) { int first = 1; for (pinf=passinfo; strcmp(pass->pp_name,pinf->p_name);pinf++) ; if (! (pinf->p_flags & LOADER) && applicable(pinf, suffix)) { int cont = ! stopsuffix || ! pinf->p_to || strcmp(stopsuffix, pinf->p_to) != 0; name = apply(pinf, cp, name, (int) (pass - cp->c_passes), noremove, first, applicable(loaderinfo, pinf->p_to) || !cont ? strcat(base, ".") : tmpname); first = noremove = 0; suffix = pinf->p_to; if (!cont || !name) break; } pass++; } if (!noremove && name) append(&GEN_LDFILES, name); return name;}mkvec(call, in, out, pass, pinf) struct arglist *call; char *in, *out; struct pass *pass; register struct passinfo *pinf;{ register int i; init(call); append(call, pinf->p_path); scanflags(call, pinf); if (pass) for (i = 0; i < MAXHEAD; i++) if (pass->pp_head[i]) append(call, pass->pp_head[i]); else break; if (pinf->p_flags & INPUT && strcmp(in, "-") != 0) append(call, in); if (pinf->p_flags & OUTPUT) append(call, out); if (pinf->p_flags & O_OUTPUT) { append(call, "-o"); append(call, out); } if (pass) for (i = 0; i < MAXTAIL; i++) if (pass->pp_tail[i]) append(call, pass->pp_tail[i]); else break;}callld(in, out, pass, pinf) struct arglist *in; char *out; struct pass *pass; register struct passinfo *pinf;{ struct arglist *call = &CALLVEC; register int i; init(call); append(call, pinf->p_path); scanflags(call, pinf); append(call, "-o"); append(call, out); for (i = 0; i < MAXHEAD; i++) if (pass->pp_head[i]) append(call, pass->pp_head[i]); else break; if (pinf->p_flags & INPUT) concat(call, in); if (pinf->p_flags & OUTPUT) append(call, out); for (i = 0; i < MAXTAIL; i++) { if (pass->pp_tail[i]) { if (pass->pp_tail[i][0] == '-' && pass->pp_tail[i][1] == 'l') { append(call, library(&(pass->pp_tail[i][2]))); } else if (*(pass->pp_tail[i]) != '*') append(call, pass->pp_tail[i]); else if (fp_lib) append(call, library("fp")); } else break; } if (! runvec(call, pinf, (char *) 0, out)) { cleanup(out); RET_CODE = 1; }}clean(c) register struct arglist *c;{ register int i; for (i = 1; i < c->al_argc; i++) { free(c->al_argv[i]); c->al_argv[i] = 0; } c->al_argc = 0;}scanflags(call, pinf) struct arglist *call; struct passinfo *pinf;{ /* Find out which flags from FLAGS must be passed to pass "pinf", and how. Append them to "call" */ register int i; USTRING flg; for (i = 0; i < FLAGS.al_argc; i++) { register char *q = pinf->p_acceptflags; while (*q) { register char *p = FLAGS.al_argv[i] + 1; while (*q && *q == *p) { q++; p++; } if (*q == ',' || !*q) { if (! *p) { /* append literally */ append(call, FLAGS.al_argv[i]); } break; } if (*q == '*') { register char *s = flg; if (*++q != '=') { /* append literally */ append(call, FLAGS.al_argv[i]); break; } *s++ = '-'; if (*q) q++; /* skip ',' */ while (*q && *q != ',' && *q != '*') { /* copy replacement flag */ *s++ = *q++; } if (*q == '*') { /* copy rest */ while (*p) *s++ = *p++; } *s = 0; append(call, flg); break; } if (*q == '=') { /* copy replacement */ register char *s = flg; *s++ = '-'; q++; while (*q && *q != ',') *s++ = *q++; *s = 0; append(call, flg); break; } while (*q && *q++ != ',') ; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -