00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <sys/types.h>
00010 #include <sys/wait.h>
00011 #include <errno.h>
00012 #include <signal.h>
00013 #include <string.h>
00014 #include <stdlib.h>
00015 #include <fcntl.h>
00016 #include <unistd.h>
00017
00018
00019 #define SHELL "/bin/sh"
00020 #define PP "/usr/lib/ncpp"
00021 #define IRREL "/usr/lib/irrel"
00022 #define CEM "/usr/lib/ncem"
00023 #define M2EM "/usr/lib/nm2em"
00024 #define ENCODE "/usr/lib/em_encode"
00025 #define OPT "/usr/lib/nopt"
00026 #define CG "/usr/lib/ncg"
00027 #define AS "/usr/lib/as"
00028 #define LD "/usr/lib/ld"
00029 #define CV "/usr/lib/cv"
00030 #define LIBDIR "/usr/lib"
00031 #define CRT "/usr/lib/ncrtso.o"
00032 #define PEM "/usr/lib/npem"
00033 #define PRT "/usr/lib/nprtso.o"
00034 #define M2RT "/usr/lib/nm2rtso.o"
00035 #define LIBC "/usr/lib/libd.a", "/usr/lib/libc.a"
00036 #define LIBP "/usr/lib/libp.a", "/usr/lib/libc.a"
00037 #define LIBM2 "/usr/lib/libm2.a", "/usr/lib/libc.a"
00038 #define END "/usr/lib/libe.a", "/usr/lib/end.a"
00039 #define M2DEF "-I/usr/lib/m2"
00040
00041
00042
00043
00044
00045
00046 struct passinfo {
00047 char *p_name;
00048 char *p_path;
00049 char *p_from;
00050 char *p_to;
00051 char *p_acceptflags;
00052
00053
00054
00055
00056
00057
00058
00059 int p_flags;
00060 #define INPUT 01
00061 #define OUTPUT 02
00062 #define LOADER 04
00063 #define STDIN 010
00064 #define STDOUT 020
00065 #define NOCLEAN 040
00066 #define O_OUTPUT 0100
00067 #define PREPALWAYS 0200
00068 #define PREPCOND 0400
00069 #define PREPNOLN 01000
00070 };
00071
00072 #define MAXHEAD 10
00073 #define MAXTAIL 5
00074 #define MAXPASS 7
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 struct compile {
00089 char *c_suffix;
00090 char *c_callname;
00091 struct pass {
00092 char *pp_name;
00093 char *pp_head[MAXHEAD];
00094 char *pp_tail[MAXTAIL];
00095 } c_passes[MAXPASS];
00096 int c_flags;
00097 #define DEFLANG 010
00098 };
00099
00100 struct passinfo passinfo[] = {
00101 { "cpp", PP, "CPP", "i", "wo=o,I*,D*,U*,P", INPUT|STDOUT },
00102 { "irrel", IRREL, "i", "i", "m", INPUT},
00103 { "cem", CEM, "i,c", "k", "m=o,p,wa=a,wo=o,ws=s,w,T*", INPUT|OUTPUT|PREPALWAYS },
00104 { "pc", PEM, "i,p", "k", "n=L,w,a,A,R", INPUT|OUTPUT|PREPCOND },
00105 { "m2", M2EM, "i,mod", "k", "n=L,w*,A,R,W*,3,I*", INPUT|OUTPUT|PREPCOND },
00106 { "encode", ENCODE, "i,e", "k", "", INPUT|STDOUT|PREPCOND|PREPNOLN },
00107 { "opt", OPT, "k", "m", "", STDIN|STDOUT },
00108 { "cg", CG, "m", "s", "O=p4", INPUT|OUTPUT },
00109 { "as", AS, "i,s", "o", "T*", INPUT|O_OUTPUT|PREPCOND },
00110 { "ld", LD, "o", "out", "i,s", INPUT|LOADER },
00111 { "cv", CV, "out", 0, "", INPUT|OUTPUT|NOCLEAN },
00112 { 0}
00113 };
00114
00115 #define PREP_FLAGS "-D_EM_WSIZE=2", "-D_EM_PSIZE=2", "-D_EM_SSIZE=2", \
00116 "-D_EM_LSIZE=4", "-D_EM_FSIZE=4", "-D_EM_DSIZE=8", \
00117 "-D__ACK__", "-D__minix", "-D__i86"
00118
00119 struct pass preprocessor = { "cpp",
00120 { PREP_FLAGS }
00121 , {0}
00122 };
00123
00124 struct pass prepnoln = { "cpp",
00125 { PREP_FLAGS, "-P" }
00126 , {0}
00127 };
00128
00129 struct pass irrel = { "irrel",
00130 {0}
00131 };
00132
00133
00134
00135
00136 struct compile passes[] = {
00137 { "c", "cc",
00138 { { "cem", {"-L"}, {0} },
00139 { "opt", {0}, {0} },
00140 { "cg", {0}, {0} },
00141 { "as", {"-"}, {0} },
00142 { "ld", {CRT},
00143 {LIBC, "*", END}},
00144 { "cv", {0}, {0} }
00145 },
00146 DEFLANG
00147 },
00148 { "p", "pc",
00149 { { "pc", {0}, {0} },
00150 { "opt", {0}, {0} },
00151 { "cg", {0}, {0} },
00152 { "as", {"-"}, {0} },
00153 { "ld", {PRT},
00154 {LIBP,
00155 "*", END}},
00156 { "cv", {0}, {0} }
00157 },
00158 DEFLANG
00159 },
00160 { "mod", "m2",
00161 { { "m2", {M2DEF}, {0} },
00162 { "opt", {0}, {0} },
00163 { "cg", {0}, {0} },
00164 { "as", {"-"}, {0} },
00165 { "ld", {M2RT},
00166 {LIBM2,
00167 "*", END}},
00168 { "cv", {0}, {0} }
00169 },
00170 DEFLANG
00171 },
00172 { "e", "encode",
00173 { { "encode", {0}, {0}},
00174 { "opt", {0}, {0} },
00175 { "cg", {0}, {0} },
00176 { "as", {"-"}, {0} },
00177 { "ld", {0}, {"*", END}},
00178 { "cv", {0}, {0} }
00179 },
00180 DEFLANG
00181 },
00182 { "s", "as",
00183 { { "as", {0}, {0}}
00184 },
00185 0
00186 },
00187 { "CPP", "cpp",
00188 { { "cpp", {PREP_FLAGS}, {0}}
00189 },
00190 DEFLANG
00191 },
00192 { 0},
00193 };
00194
00195 #define MAXARGC 150
00196 #define USTR_SIZE 64
00197
00198 typedef char USTRING[USTR_SIZE];
00199
00200 struct arglist {
00201 int al_argc;
00202 char *al_argv[MAXARGC];
00203 };
00204
00205 struct arglist CALLVEC;
00206
00207 int kids = -1;
00208
00209 char *o_FILE = "a.out";
00210
00211 #define init(a) ((a)->al_argc = 1)
00212 #define cleanup(str) (str && remove(str))
00213
00214 char *ProgCall = 0;
00215
00216 int RET_CODE = 0;
00217
00218 char *stopsuffix;
00219 int v_flag = 0;
00220 int t_flag = 0;
00221 int noexec = 0;
00222 int fp_lib = 1;
00223 int E_flag = 0;
00224 int i_flag = 1;
00225
00226
00227 USTRING curfil;
00228 USTRING newfil;
00229 struct arglist SRCFILES;
00230 struct arglist LDIRS;
00231 struct arglist LDFILES;
00232 struct arglist GEN_LDFILES;
00233 struct arglist FLAGS;
00234
00235 char *tmpdir = "/tmp";
00236 char tmpname[64];
00237
00238 struct compile *compbase;
00239 struct pass *loader;
00240 struct passinfo *loaderinfo;
00241 char *source;
00242 int maxLlen;
00243
00244 _PROTOTYPE(char *library, (char *nm ));
00245 _PROTOTYPE(void trapcc, (int sig ));
00246 _PROTOTYPE(int main, (int argc, char *argv []));
00247 _PROTOTYPE(int remove, (char *str ));
00248 _PROTOTYPE(char *alloc, (unsigned u ));
00249 _PROTOTYPE(int append, (struct arglist *al, char *arg ));
00250 _PROTOTYPE(int concat, (struct arglist *al1, struct arglist *al2 ));
00251 _PROTOTYPE(char *mkstr, (char *dst, char *arg1, char *arg2, char *arg3 ));
00252 _PROTOTYPE(int basename, (char *str, char *dst ));
00253 _PROTOTYPE(char *extension, (char *fln ));
00254 _PROTOTYPE(int runvec, (struct arglist *vec, struct passinfo *pass, char *in, char *out ));
00255 _PROTOTYPE(int prnum, (unsigned x ));
00256 _PROTOTYPE(int prs, (char *str ));
00257 _PROTOTYPE(int panic, (char *str ));
00258 _PROTOTYPE(int pr_vec, (struct arglist *vec ));
00259 _PROTOTYPE(int ex_vec, (struct arglist *vec ));
00260 _PROTOTYPE(int mktempname, (char *nm ));
00261 _PROTOTYPE(int mkbase, (void));
00262 _PROTOTYPE(int mkloader, (void));
00263 _PROTOTYPE(int needsprep, (char *name ));
00264 _PROTOTYPE(int cfile, (char *name ));
00265 _PROTOTYPE(char *apply, (struct passinfo *pinf, struct compile *cp, char *name, int passindex, int noremove, int first, char *resultname ));
00266 _PROTOTYPE(int applicable, (struct passinfo *pinf, char *suffix ));
00267 _PROTOTYPE(char *process, (char *name, int noremove ));
00268 _PROTOTYPE(int mkvec, (struct arglist *call, char *in, char *out, struct pass *pass, struct passinfo *pinf ));
00269 _PROTOTYPE(int callld, (struct arglist *in, char *out, struct pass *pass, struct passinfo *pinf ));
00270 _PROTOTYPE(int clean, (struct arglist *c ));
00271 _PROTOTYPE(int scanflags, (struct arglist *call, struct passinfo *pinf ));
00272
00273
00274
00275 char *
00276 library(nm)
00277 char *nm;
00278 {
00279 static char f[512];
00280 int Lcount;
00281
00282 for (Lcount = 0; Lcount < LDIRS.al_argc; Lcount++) {
00283 mkstr(f, LDIRS.al_argv[Lcount], "/lib", nm);
00284 strcat(f, ".a");
00285 if (access(f, 0) != 0) {
00286 f[strlen(f)-1] = 'a';
00287 if (access(f, 0) != 0) continue;
00288 }
00289 return f;
00290 }
00291 mkstr(f, LIBDIR, "/lib", nm);
00292 strcat(f, ".a");
00293 if (access(f, 0) != 0) {
00294 int i = strlen(f) - 1;
00295 f[i] = 'a';
00296 if (access(f, 0) != 0) f[i] = 'A';
00297 }
00298 return f;
00299 }
00300
00301 void trapcc(sig)
00302 int sig;
00303 {
00304 signal(sig, SIG_IGN);
00305 if (kids != -1) kill(kids, sig);
00306 cleanup(newfil);
00307 cleanup(curfil);
00308 exit(1);
00309 }
00310
00311 main(argc, argv)
00312 char *argv[];
00313 {
00314 char *str;
00315 char **argvec;
00316 int count;
00317 char *file;
00318
00319 maxLlen = strlen(LIBDIR);
00320 ProgCall = *argv++;
00321
00322 mkbase();
00323
00324 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
00325 signal(SIGHUP, trapcc);
00326 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
00327 signal(SIGINT, trapcc);
00328 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
00329 signal(SIGQUIT, trapcc);
00330 while (--argc > 0) {
00331 if (*(str = *argv++) != '-' || str[1] == 0) {
00332 append(&SRCFILES, str);
00333 continue;
00334 }
00335
00336 if (strcmp(str, "-com") == 0) {
00337 i_flag = 0;
00338 } else
00339 if (strcmp(str, "-sep") == 0) {
00340 i_flag = 1;
00341 } else {
00342 switch (str[1]) {
00343
00344 case 'c':
00345 stopsuffix = "o";
00346 if (str[2] == '.') stopsuffix = str + 3;
00347 break;
00348 case 'f':
00349 fp_lib = (strcmp(str+2, "hard") != 0);
00350 break;
00351 case 'F':
00352 case 'W':
00353
00354 break;
00355 case 'L':
00356 append(&LDIRS, &str[2]);
00357 count = strlen(&str[2]);
00358 if (count > maxLlen) maxLlen = count;
00359 break;
00360 case 'l':
00361 append(&SRCFILES, library(&str[2]));
00362 break;
00363 case 'm':
00364
00365 if (str[2] == 0) append(&FLAGS, str);
00366 break;
00367 case 'o':
00368 if (argc-- >= 0)
00369 o_FILE = *argv++;
00370 break;
00371 case 'S':
00372 stopsuffix = "s";
00373 break;
00374 case 'E':
00375 E_flag = 1;
00376 stopsuffix = "i";
00377 break;
00378 case 'P':
00379 stopsuffix = "i";
00380 append(&FLAGS, str);
00381 break;
00382 case 'v':
00383 v_flag++;
00384 if (str[2] == 'n')
00385 noexec = 1;
00386 break;
00387 case 't':
00388
00389 t_flag++;
00390 break;
00391 case '.':
00392 if (str[2] == 'o') {
00393
00394 loader->pp_head[0] = 0;
00395 }
00396 break;
00397 case 'i':
00398 i_flag++;
00399 break;
00400 case 'T':
00401 tmpdir = &str[2];
00402
00403 default:
00404 append(&FLAGS, str);
00405
00406 }
00407 }
00408 }
00409
00410 if (i_flag) append(&FLAGS, "-i");
00411
00412 mktempname(tmpname);
00413
00414 count = SRCFILES.al_argc;
00415 argvec = &(SRCFILES.al_argv[0]);
00416
00417 while (count-- > 0) {
00418
00419 file = *argvec++;
00420 source = file;
00421
00422 file = process(file, 1);
00423
00424 if (file && ! stopsuffix) append(&LDFILES, file);
00425 }
00426
00427 clean(&SRCFILES);
00428
00429
00430 if (RET_CODE == 0 && LDFILES.al_argc > 0) {
00431 register struct passinfo *pp = passinfo;
00432
00433 while (!(pp->p_flags & LOADER)) pp++;
00434 mkstr(newfil, tmpname, pp->p_to, "");
00435 callld(&LDFILES, !((pp+1)->p_name) ? o_FILE : newfil, loader, pp);
00436 if (RET_CODE == 0) {
00437 register int i = GEN_LDFILES.al_argc;
00438
00439 while (i-- > 0) {
00440 remove(GEN_LDFILES.al_argv[i]);
00441 free(GEN_LDFILES.al_argv[i]);
00442 }
00443 if ((++pp)->p_name) {
00444 process(newfil, 0);
00445 }
00446 }
00447 }
00448 exit(RET_CODE);
00449 }
00450
00451 remove(str)
00452 char *str;
00453 {
00454 if (t_flag)
00455 return;
00456 if (v_flag) {
00457 prs("rm ");
00458 prs(str);
00459 prs("\n");
00460 }
00461 if (noexec)
00462 return;
00463 unlink(str);
00464 }
00465
00466 char *
00467 alloc(u)
00468 unsigned u;
00469 {
00470 register char *p = malloc(u);
00471
00472 if (p == 0) panic("no space\n");
00473 return p;
00474 }
00475
00476 append(al, arg)
00477 struct arglist *al;
00478 char *arg;
00479 {
00480 char *a = alloc((unsigned) (strlen(arg) + 1));
00481
00482 strcpy(a, arg);
00483 if (al->al_argc >= MAXARGC)
00484 panic("argument list overflow\n");
00485 al->al_argv[(al->al_argc)++] = a;
00486 }
00487
00488 concat(al1, al2)
00489 struct arglist *al1, *al2;
00490 {
00491 register i = al2->al_argc;
00492 register char **p = &(al1->al_argv[al1->al_argc]);
00493 register char **q = &(al2->al_argv[0]);
00494
00495 if ((al1->al_argc += i) >= MAXARGC)
00496 panic("argument list overflow\n");
00497 while (i-- > 0)
00498 *p++ = *q++;
00499 }
00500
00501 char *
00502 mkstr(dst, arg1, arg2, arg3)
00503 char *dst, *arg1, *arg2, *arg3;
00504 {
00505 register char *p;
00506 register char *q = dst;
00507
00508 p = arg1;
00509 while (*q++ = *p++);
00510 q--;
00511 p = arg2;
00512 while (*q++ = *p++);
00513 q--;
00514 p = arg3;
00515 while (*q++ = *p++);
00516 q--;
00517 return dst;
00518 }
00519
00520 basename(str, dst)
00521 char *str;
00522 register char *dst;
00523 {
00524 register char *p1 = str;
00525 register char *p2 = p1;
00526
00527 while (*p1)
00528 if (*p1++ == '/')
00529 p2 = p1;
00530 p1--;
00531 while (*p1 != '.' && p1 > p2) p1--;
00532 if (*p1 == '.') {
00533 *p1 = '\0';
00534 while (*dst++ = *p2++);
00535 *p1 = '.';
00536 }
00537 else
00538 while (*dst++ = *p2++);
00539 }
00540
00541 char *
00542 extension(fln)
00543 char *fln;
00544 {
00545 register char *fn = fln;
00546
00547 while (*fn) fn++;
00548 while (fn > fln && *fn != '.') fn--;
00549 if (fn != fln) return fn+1;
00550 return (char *)0;
00551 }
00552
00553 runvec(vec, pass, in, out)
00554 struct arglist *vec;
00555 struct passinfo *pass;
00556 char *in, *out;
00557 {
00558 int pid, status;
00559 int shifted = 0;
00560
00561 if (
00562 strncmp(vec->al_argv[1], "/usr/", 5) == 0
00563 &&
00564 access(vec->al_argv[1] + 4, 1) == 0
00565 ) {
00566 vec->al_argv[1] += 4;
00567 shifted = 1;
00568 }
00569
00570 if (v_flag) {
00571 pr_vec(vec);
00572 if (pass->p_flags & STDIN) {
00573 prs(" <");
00574 prs(in);
00575 }
00576 if (pass->p_flags & STDOUT && !E_flag) {
00577 prs(" >");
00578 prs(out);
00579 }
00580 prs("\n");
00581 }
00582 if (noexec) {
00583 if (shifted) vec->al_argv[1] -= 4;
00584 clean(vec);
00585 return 1;
00586 }
00587 if ((pid = fork()) == 0) {
00588 if (pass->p_flags & STDIN && strcmp(in, "-") != 0) {
00589
00590 close(0);
00591 if (open(in, 0) != 0)
00592 panic("cannot open input file\n");
00593 }
00594 if (pass->p_flags & STDOUT && !E_flag) {
00595
00596 close(1);
00597 if (creat(out, 0666) != 1)
00598 panic("cannot create output file\n");
00599 }
00600 ex_vec(vec);
00601 }
00602 if (pid == -1)
00603 panic("no more processes\n");
00604 kids = pid;
00605 wait(&status);
00606 if (status) switch(status & 0177) {
00607 case SIGHUP:
00608 case SIGINT:
00609 case SIGQUIT:
00610 case SIGTERM:
00611 case 0:
00612 break;
00613 default:
00614 if (E_flag && (status & 0177) == SIGPIPE) break;
00615 prs(vec->al_argv[1]);
00616 prs(" died with signal ");
00617 prnum(status & 0177);
00618 prs("\n");
00619 }
00620 if (shifted) vec->al_argv[1] -= 4;
00621 clean(vec);
00622 kids = -1;
00623 return status ? ((RET_CODE = 1), 0) : 1;
00624 }
00625
00626 prnum(x)
00627 register unsigned x;
00628 {
00629 static char numbuf[8];
00630 register char *cp = numbuf + sizeof(numbuf) - 1;
00631
00632 *cp = '\0';
00633 while (x >= 10) {
00634 *--cp = (x % 10) + '0';
00635 x /= 10;
00636 }
00637 *--cp = x + '0';
00638 prs(cp);
00639
00640 }
00641
00642 prs(str)
00643 char *str;
00644 {
00645 if (str && *str)
00646 write(2, str, strlen(str));
00647 }
00648
00649 panic(str)
00650 char *str;
00651 {
00652 prs(str);
00653 trapcc(SIGINT);
00654 }
00655
00656 pr_vec(vec)
00657 register struct arglist *vec;
00658 {
00659 register char **ap = &vec->al_argv[1];
00660
00661 vec->al_argv[vec->al_argc] = 0;
00662 prs(*ap);
00663 while (*++ap) {
00664 prs(" ");
00665 if (strlen(*ap))
00666 prs(*ap);
00667 else
00668 prs("(empty)");
00669 }
00670 }
00671
00672 ex_vec(vec)
00673 register struct arglist *vec;
00674 {
00675 extern int errno;
00676
00677 vec->al_argv[vec->al_argc] = 0;
00678 execv(vec->al_argv[1], &(vec->al_argv[1]));
00679 if (errno == ENOEXEC) {
00680 vec->al_argv[0] = SHELL;
00681 execv(SHELL, &(vec->al_argv[0]));
00682 }
00683 if (access(vec->al_argv[1], 1) == 0) {
00684
00685 prs("Cannot execute ");
00686 prs(vec->al_argv[1]);
00687 prs(". Not enough memory.\n");
00688 prs("Reduce the memory use of your system and try again\n");
00689 } else {
00690 prs(vec->al_argv[1]);
00691 prs(" is not executable\n");
00692 }
00693 exit(1);
00694 }
00695
00696 mktempname(nm)
00697 register char *nm;
00698 {
00699 register int i;
00700 register int pid = getpid();
00701
00702 mkstr(nm, tmpdir, "/", compbase->c_callname);
00703 while (*nm) nm++;
00704
00705 for (i = 9; i > 3; i--) {
00706 *nm++ = (pid % 10) + '0';
00707 pid /= 10;
00708 }
00709 *nm++ = '.';
00710 *nm++ = '\0';
00711 }
00712
00713 mkbase()
00714 {
00715 register struct compile *p = passes;
00716 USTRING callname;
00717 register int len;
00718
00719 basename(ProgCall, callname);
00720 len = strlen(callname);
00721 while (p->c_suffix) {
00722 if (strcmp(p->c_callname, callname+len-strlen(p->c_callname)) == 0) {
00723 compbase = p;
00724 mkloader();
00725 return;
00726 }
00727 p++;
00728 }
00729
00730 panic("internal error\n");
00731 }
00732
00733 mkloader()
00734 {
00735 register struct passinfo *p = passinfo;
00736 register struct pass *pass;
00737
00738 while (!(p->p_flags & LOADER)) p++;
00739 loaderinfo = p;
00740 pass = &(compbase->c_passes[0]);
00741 while (strcmp(pass->pp_name, p->p_name)) pass++;
00742 loader = pass;
00743 }
00744
00745 needsprep(name)
00746 char *name;
00747 {
00748 int file;
00749 char fc;
00750
00751 file = open(name,0);
00752 if (file <0) return 0;
00753 if (read(file, &fc, 1) != 1) fc = 0;
00754 close(file);
00755 return fc == '#';
00756 }
00757
00758 cfile(name)
00759 char *name;
00760 {
00761 while (*name != '\0' && *name != '.')
00762 name++;
00763
00764 if (*name == '\0') return 0;
00765 return (*++name == 'c' && *++name == '\0');
00766 }
00767
00768 char *
00769 apply(pinf, cp, name, passindex, noremove, first, resultname)
00770 register struct passinfo *pinf;
00771 register struct compile *cp;
00772 char *name, *resultname;
00773 {
00774
00775
00776
00777
00778
00779
00780
00781
00782 struct arglist *call = &CALLVEC;
00783 struct pass *pass = &(cp->c_passes[passindex]);
00784 char *outname;
00785
00786 if (
00787 first
00788 &&
00789 (
00790 (pinf->p_flags & PREPALWAYS)
00791 ||
00792 ( (pinf->p_flags & PREPCOND) && needsprep(name))
00793 )
00794 ) {
00795 mkstr(newfil, tmpname, passinfo[0].p_to, "");
00796 mkvec(call, name, newfil,
00797 (pinf->p_flags & PREPNOLN) ? &prepnoln : &preprocessor,
00798 &passinfo[0]);
00799 if (! runvec(call, &passinfo[0], name, newfil)) {
00800 cleanup(newfil);
00801 return 0;
00802 }
00803
00804
00805 if (cfile(name)) {
00806
00807 mkvec(call, newfil, newfil, &irrel, &passinfo[1]);
00808 if (! runvec(call, &passinfo[1], newfil, newfil)) {
00809 cleanup(newfil);
00810 return 0;
00811 }
00812 }
00813 strcpy(curfil, newfil);
00814 newfil[0] = '\0';
00815 name = curfil;
00816 noremove = 0;
00817 }
00818 if (pinf->p_to) outname = mkstr(newfil, resultname, pinf->p_to, "");
00819 else outname = o_FILE;
00820 mkvec(call, name, outname, pass, pinf);
00821 if (! runvec(call, pinf, name, outname)) {
00822 if (! (pinf->p_flags & NOCLEAN)) cleanup(outname);
00823 if (! noremove) cleanup(name);
00824 return 0;
00825 }
00826 if (! noremove) cleanup(name);
00827 strcpy(curfil, newfil);
00828 newfil[0] = '\0';
00829 return curfil;
00830 }
00831
00832 int
00833 applicable(pinf, suffix)
00834 struct passinfo *pinf;
00835 char *suffix;
00836 {
00837
00838
00839
00840 register char *sfx = pinf->p_from;
00841 int l;
00842
00843 if (! suffix) return 0;
00844 l = strlen(suffix);
00845 while (*sfx) {
00846 register char *p = sfx;
00847
00848 while (*p && *p != ',') p++;
00849 if (l == p - sfx && strncmp(sfx, suffix, l) == 0) {
00850 return 1;
00851 }
00852 if (*p == ',') sfx = p+1;
00853 else sfx = p;
00854 }
00855 return 0;
00856 }
00857
00858 char *
00859 process(name, noremove)
00860 char *name;
00861 {
00862 register struct compile *cp = passes;
00863 char *suffix = extension(name);
00864 USTRING base;
00865 register struct pass *pass;
00866 register struct passinfo *pinf;
00867
00868 if (E_flag) {
00869
00870 suffix = "CPP";
00871 }
00872
00873 if (! suffix) return name;
00874
00875 basename(name, base);
00876
00877 while (cp->c_suffix) {
00878 if ((cp->c_flags & DEFLANG) &&
00879 strcmp(cp->c_suffix, suffix) == 0)
00880 break;
00881 cp++;
00882 }
00883 if (! cp->c_suffix) cp = compbase;
00884 pass = cp->c_passes;
00885 while (pass->pp_name) {
00886 int first = 1;
00887
00888 for (pinf=passinfo; strcmp(pass->pp_name,pinf->p_name);pinf++)
00889 ;
00890 if (! (pinf->p_flags & LOADER) && applicable(pinf, suffix)) {
00891 int cont = ! stopsuffix || ! pinf->p_to ||
00892 strcmp(stopsuffix, pinf->p_to) != 0;
00893 name = apply(pinf,
00894 cp,
00895 name,
00896 (int) (pass - cp->c_passes),
00897 noremove,
00898 first,
00899 applicable(loaderinfo, pinf->p_to) ||
00900 !cont ?
00901 strcat(base, ".") :
00902 tmpname);
00903 first = noremove = 0;
00904 suffix = pinf->p_to;
00905 if (!cont || !name) break;
00906 }
00907 pass++;
00908 }
00909 if (!noremove && name)
00910 append(&GEN_LDFILES, name);
00911 return name;
00912 }
00913
00914 mkvec(call, in, out, pass, pinf)
00915 struct arglist *call;
00916 char *in, *out;
00917 struct pass *pass;
00918 register struct passinfo *pinf;
00919 {
00920 register int i;
00921
00922 init(call);
00923 append(call, pinf->p_path);
00924 scanflags(call, pinf);
00925 if (pass) for (i = 0; i < MAXHEAD; i++)
00926 if (pass->pp_head[i])
00927 append(call, pass->pp_head[i]);
00928 else break;
00929 if (pinf->p_flags & INPUT && strcmp(in, "-") != 0)
00930 append(call, in);
00931 if (pinf->p_flags & OUTPUT)
00932 append(call, out);
00933 if (pinf->p_flags & O_OUTPUT) {
00934 append(call, "-o");
00935 append(call, out);
00936 }
00937 if (pass) for (i = 0; i < MAXTAIL; i++)
00938 if (pass->pp_tail[i])
00939 append(call, pass->pp_tail[i]);
00940 else break;
00941 }
00942
00943 callld(in, out, pass, pinf)
00944 struct arglist *in;
00945 char *out;
00946 struct pass *pass;
00947 register struct passinfo *pinf;
00948 {
00949 struct arglist *call = &CALLVEC;
00950 register int i;
00951
00952 init(call);
00953 append(call, pinf->p_path);
00954 scanflags(call, pinf);
00955 append(call, "-o");
00956 append(call, out);
00957 for (i = 0; i < MAXHEAD; i++)
00958 if (pass->pp_head[i])
00959 append(call, pass->pp_head[i]);
00960 else break;
00961 if (pinf->p_flags & INPUT)
00962 concat(call, in);
00963 if (pinf->p_flags & OUTPUT)
00964 append(call, out);
00965 for (i = 0; i < MAXTAIL; i++) {
00966 if (pass->pp_tail[i]) {
00967 if (pass->pp_tail[i][0] == '-' &&
00968 pass->pp_tail[i][1] == 'l') {
00969 append(call, library(&(pass->pp_tail[i][2])));
00970 }
00971 else if (*(pass->pp_tail[i]) != '*')
00972 append(call, pass->pp_tail[i]);
00973 else if (fp_lib)
00974 append(call, library("fp"));
00975 } else break;
00976 }
00977 if (! runvec(call, pinf, (char *) 0, out)) {
00978 cleanup(out);
00979 RET_CODE = 1;
00980 }
00981 }
00982
00983 clean(c)
00984 register struct arglist *c;
00985 {
00986 register int i;
00987
00988 for (i = 1; i < c->al_argc; i++) {
00989 free(c->al_argv[i]);
00990 c->al_argv[i] = 0;
00991 }
00992 c->al_argc = 0;
00993 }
00994
00995 scanflags(call, pinf)
00996 struct arglist *call;
00997 struct passinfo *pinf;
00998 {
00999
01000
01001
01002
01003 register int i;
01004 USTRING flg;
01005
01006 for (i = 0; i < FLAGS.al_argc; i++) {
01007 register char *q = pinf->p_acceptflags;
01008
01009 while (*q) {
01010 register char *p = FLAGS.al_argv[i] + 1;
01011
01012 while (*q && *q == *p) {
01013 q++; p++;
01014 }
01015 if (*q == ',' || !*q) {
01016 if (! *p) {
01017
01018 append(call, FLAGS.al_argv[i]);
01019 }
01020 break;
01021 }
01022 if (*q == '*') {
01023 register char *s = flg;
01024
01025 if (*++q != '=') {
01026
01027 append(call, FLAGS.al_argv[i]);
01028 break;
01029 }
01030 *s++ = '-';
01031 if (*q) q++;
01032 while (*q && *q != ',' && *q != '*') {
01033
01034 *s++ = *q++;
01035 }
01036 if (*q == '*') {
01037
01038 while (*p) *s++ = *p++;
01039 }
01040 *s = 0;
01041 append(call, flg);
01042 break;
01043 }
01044 if (*q == '=') {
01045
01046 register char *s = flg;
01047
01048 *s++ = '-';
01049 q++;
01050 while (*q && *q != ',') *s++ = *q++;
01051 *s = 0;
01052 append(call, flg);
01053 break;
01054 }
01055 while (*q && *q++ != ',')
01056 ;
01057 }
01058 }
01059 }