[9] | 1 | /* Driver for Minix compilers.
|
---|
| 2 | Written june 1987 by Ceriel J.H. Jacobs, partly derived from old
|
---|
| 3 | cc-driver, written by Erik Baalbergen.
|
---|
| 4 | This driver is mostly table-driven, the table being in the form of
|
---|
| 5 | some global initialized structures.
|
---|
| 6 | */
|
---|
| 7 | /* $Header: /cvsup/minix/src/commands/i86/cc.c,v 1.1.1.1 2005/04/21 14:54:55 beng Exp $ */
|
---|
| 8 |
|
---|
| 9 | #include <sys/types.h>
|
---|
| 10 | #include <sys/wait.h>
|
---|
| 11 | #include <errno.h>
|
---|
| 12 | #include <signal.h>
|
---|
| 13 | #include <string.h>
|
---|
| 14 | #include <stdlib.h>
|
---|
| 15 | #include <fcntl.h>
|
---|
| 16 | #include <unistd.h>
|
---|
| 17 |
|
---|
| 18 | /* Paths. (Executables in /usr are first tried with /usr stripped off.) */
|
---|
| 19 | #define SHELL "/bin/sh"
|
---|
| 20 | #define PP "/usr/lib/ncpp"
|
---|
| 21 | #define IRREL "/usr/lib/irrel"
|
---|
| 22 | #define CEM "/usr/lib/ncem"
|
---|
| 23 | #define M2EM "/usr/lib/nm2em"
|
---|
| 24 | #define ENCODE "/usr/lib/em_encode"
|
---|
| 25 | #define OPT "/usr/lib/nopt"
|
---|
| 26 | #define CG "/usr/lib/ncg"
|
---|
| 27 | #define AS "/usr/lib/as"
|
---|
| 28 | #define LD "/usr/lib/ld"
|
---|
| 29 | #define CV "/usr/lib/cv"
|
---|
| 30 | #define LIBDIR "/usr/lib"
|
---|
| 31 | #define CRT "/usr/lib/ncrtso.o"
|
---|
| 32 | #define PEM "/usr/lib/npem"
|
---|
| 33 | #define PRT "/usr/lib/nprtso.o"
|
---|
| 34 | #define M2RT "/usr/lib/nm2rtso.o"
|
---|
| 35 | #define LIBC "/usr/lib/libd.a", "/usr/lib/libc.a"
|
---|
| 36 | #define LIBP "/usr/lib/libp.a", "/usr/lib/libc.a"
|
---|
| 37 | #define LIBM2 "/usr/lib/libm2.a", "/usr/lib/libc.a"
|
---|
| 38 | #define END "/usr/lib/libe.a", "/usr/lib/end.a"
|
---|
| 39 | #define M2DEF "-I/usr/lib/m2"
|
---|
| 40 |
|
---|
| 41 |
|
---|
| 42 | /* every pass that this program knows about has associated with it
|
---|
| 43 | a structure, containing such information as its name, where it
|
---|
| 44 | resides, the flags it accepts, and the like.
|
---|
| 45 | */
|
---|
| 46 | struct passinfo {
|
---|
| 47 | char *p_name; /* name of this pass */
|
---|
| 48 | char *p_path; /* where is it */
|
---|
| 49 | char *p_from; /* suffix of source (comma-separated list) */
|
---|
| 50 | char *p_to; /* suffix of destination */
|
---|
| 51 | char *p_acceptflags; /* comma separated list; format:
|
---|
| 52 | flag
|
---|
| 53 | flag*
|
---|
| 54 | flag=xxx
|
---|
| 55 | flag*=xxx[*]
|
---|
| 56 | where a star matches a, possibly empty,
|
---|
| 57 | string
|
---|
| 58 | */
|
---|
| 59 | int p_flags;
|
---|
| 60 | #define INPUT 01 /* needs input file as argument */
|
---|
| 61 | #define OUTPUT 02 /* needs output file as argument */
|
---|
| 62 | #define LOADER 04 /* this pass is the loader */
|
---|
| 63 | #define STDIN 010 /* reads from standard input */
|
---|
| 64 | #define STDOUT 020 /* writes on standard output */
|
---|
| 65 | #define NOCLEAN 040 /* do not remove target if this pass fails */
|
---|
| 66 | #define O_OUTPUT 0100 /* -o outputfile, hack for as */
|
---|
| 67 | #define PREPALWAYS 0200 /* always to be preprocessed */
|
---|
| 68 | #define PREPCOND 0400 /* preprocessed when starting with '#' */
|
---|
| 69 | #define PREPNOLN 01000 /* suppress line number info (cpp -P) */
|
---|
| 70 | };
|
---|
| 71 |
|
---|
| 72 | #define MAXHEAD 10
|
---|
| 73 | #define MAXTAIL 5
|
---|
| 74 | #define MAXPASS 7
|
---|
| 75 |
|
---|
| 76 | /* Every language handled by this program has a "compile" structure
|
---|
| 77 | associated with it, describing the start-suffix, how the driver for
|
---|
| 78 | this language is called, which passes must be called, which flags
|
---|
| 79 | and arguments must be passed to these passes, etc.
|
---|
| 80 | The language is determined by the suffix of the argument program.
|
---|
| 81 | However, if this suffix does not determine a language (DEFLANG),
|
---|
| 82 | the callname is used.
|
---|
| 83 | Notice that the 's' suffix does not determine a language, because
|
---|
| 84 | the input file could have been derived from f.i. a C-program.
|
---|
| 85 | So, if you use "cc x.s", the C-runtime system will be used, but if
|
---|
| 86 | you use "as x.s", it will not.
|
---|
| 87 | */
|
---|
| 88 | struct compile {
|
---|
| 89 | char *c_suffix; /* starting suffix of this list of passes */
|
---|
| 90 | char *c_callname; /* affects runtime system loaded with program */
|
---|
| 91 | struct pass {
|
---|
| 92 | char *pp_name; /* name of the pass */
|
---|
| 93 | char *pp_head[MAXHEAD]; /* args in front of filename */
|
---|
| 94 | char *pp_tail[MAXTAIL]; /* args after filename */
|
---|
| 95 | } c_passes[MAXPASS];
|
---|
| 96 | int c_flags;
|
---|
| 97 | #define DEFLANG 010 /* this suffix determines a language */
|
---|
| 98 | };
|
---|
| 99 |
|
---|
| 100 | struct passinfo passinfo[] = {
|
---|
| 101 | { "cpp", PP, "CPP", "i", "wo=o,I*,D*,U*,P", INPUT|STDOUT },
|
---|
| 102 | { "irrel", IRREL, "i", "i", "m", INPUT},
|
---|
| 103 | { "cem", CEM, "i,c", "k", "m=o,p,wa=a,wo=o,ws=s,w,T*", INPUT|OUTPUT|PREPALWAYS },
|
---|
| 104 | { "pc", PEM, "i,p", "k", "n=L,w,a,A,R", INPUT|OUTPUT|PREPCOND },
|
---|
| 105 | { "m2", M2EM, "i,mod", "k", "n=L,w*,A,R,W*,3,I*", INPUT|OUTPUT|PREPCOND },
|
---|
| 106 | { "encode", ENCODE, "i,e", "k", "", INPUT|STDOUT|PREPCOND|PREPNOLN },
|
---|
| 107 | { "opt", OPT, "k", "m", "", STDIN|STDOUT },
|
---|
| 108 | { "cg", CG, "m", "s", "O=p4", INPUT|OUTPUT },
|
---|
| 109 | { "as", AS, "i,s", "o", "T*", INPUT|O_OUTPUT|PREPCOND },
|
---|
| 110 | { "ld", LD, "o", "out", "i,s", INPUT|LOADER }, /* changed */
|
---|
| 111 | { "cv", CV, "out", 0, "", INPUT|OUTPUT|NOCLEAN }, /* must come after loader */
|
---|
| 112 | { 0}
|
---|
| 113 | };
|
---|
| 114 |
|
---|
| 115 | #define PREP_FLAGS "-D_EM_WSIZE=2", "-D_EM_PSIZE=2", "-D_EM_SSIZE=2", \
|
---|
| 116 | "-D_EM_LSIZE=4", "-D_EM_FSIZE=4", "-D_EM_DSIZE=8", \
|
---|
| 117 | "-D__ACK__", "-D__minix", "-D__i86"
|
---|
| 118 |
|
---|
| 119 | struct pass preprocessor = { "cpp",
|
---|
| 120 | { PREP_FLAGS }
|
---|
| 121 | , {0}
|
---|
| 122 | };
|
---|
| 123 |
|
---|
| 124 | struct pass prepnoln = { "cpp",
|
---|
| 125 | { PREP_FLAGS, "-P" }
|
---|
| 126 | , {0}
|
---|
| 127 | };
|
---|
| 128 |
|
---|
| 129 | struct pass irrel = { "irrel",
|
---|
| 130 | {0}
|
---|
| 131 | };
|
---|
| 132 |
|
---|
| 133 | /* The "*" in the arguments for the loader indicates the place where the
|
---|
| 134 | * fp-emulation library should come.
|
---|
| 135 | */
|
---|
| 136 | struct compile passes[] = {
|
---|
| 137 | { "c", "cc",
|
---|
| 138 | { { "cem", {"-L"}, {0} }, /* changed */
|
---|
| 139 | { "opt", {0}, {0} },
|
---|
| 140 | { "cg", {0}, {0} },
|
---|
| 141 | { "as", {"-"}, {0} },
|
---|
| 142 | { "ld", {CRT}, /* changed */
|
---|
| 143 | {LIBC, "*", END}},
|
---|
| 144 | { "cv", {0}, {0} }
|
---|
| 145 | },
|
---|
| 146 | DEFLANG
|
---|
| 147 | },
|
---|
| 148 | { "p", "pc",
|
---|
| 149 | { { "pc", {0}, {0} },
|
---|
| 150 | { "opt", {0}, {0} },
|
---|
| 151 | { "cg", {0}, {0} },
|
---|
| 152 | { "as", {"-"}, {0} },
|
---|
| 153 | { "ld", {PRT},
|
---|
| 154 | {LIBP,
|
---|
| 155 | "*", END}},
|
---|
| 156 | { "cv", {0}, {0} }
|
---|
| 157 | },
|
---|
| 158 | DEFLANG
|
---|
| 159 | },
|
---|
| 160 | { "mod", "m2",
|
---|
| 161 | { { "m2", {M2DEF}, {0} },
|
---|
| 162 | { "opt", {0}, {0} },
|
---|
| 163 | { "cg", {0}, {0} },
|
---|
| 164 | { "as", {"-"}, {0} },
|
---|
| 165 | { "ld", {M2RT},
|
---|
| 166 | {LIBM2,
|
---|
| 167 | "*", END}},
|
---|
| 168 | { "cv", {0}, {0} }
|
---|
| 169 | },
|
---|
| 170 | DEFLANG
|
---|
| 171 | },
|
---|
| 172 | { "e", "encode",
|
---|
| 173 | { { "encode", {0}, {0}},
|
---|
| 174 | { "opt", {0}, {0} },
|
---|
| 175 | { "cg", {0}, {0} },
|
---|
| 176 | { "as", {"-"}, {0} },
|
---|
| 177 | { "ld", {0}, {"*", END}},
|
---|
| 178 | { "cv", {0}, {0} }
|
---|
| 179 | },
|
---|
| 180 | DEFLANG
|
---|
| 181 | },
|
---|
| 182 | { "s", "as",
|
---|
| 183 | { { "as", {0}, {0}}
|
---|
| 184 | },
|
---|
| 185 | 0
|
---|
| 186 | },
|
---|
| 187 | { "CPP", "cpp",
|
---|
| 188 | { { "cpp", {PREP_FLAGS}, {0}}
|
---|
| 189 | },
|
---|
| 190 | DEFLANG
|
---|
| 191 | },
|
---|
| 192 | { 0},
|
---|
| 193 | };
|
---|
| 194 |
|
---|
| 195 | #define MAXARGC 150 /* maximum number of arguments allowed in a list */
|
---|
| 196 | #define USTR_SIZE 64 /* maximum length of string variable */
|
---|
| 197 |
|
---|
| 198 | typedef char USTRING[USTR_SIZE];
|
---|
| 199 |
|
---|
| 200 | struct arglist {
|
---|
| 201 | int al_argc;
|
---|
| 202 | char *al_argv[MAXARGC];
|
---|
| 203 | };
|
---|
| 204 |
|
---|
| 205 | struct arglist CALLVEC;
|
---|
| 206 |
|
---|
| 207 | int kids = -1;
|
---|
| 208 |
|
---|
| 209 | char *o_FILE = "a.out"; /* default name for executable file */
|
---|
| 210 |
|
---|
| 211 | #define init(a) ((a)->al_argc = 1)
|
---|
| 212 | #define cleanup(str) (str && remove(str))
|
---|
| 213 |
|
---|
| 214 | char *ProgCall = 0;
|
---|
| 215 |
|
---|
| 216 | int RET_CODE = 0;
|
---|
| 217 |
|
---|
| 218 | char *stopsuffix;
|
---|
| 219 | int v_flag = 0;
|
---|
| 220 | int t_flag = 0;
|
---|
| 221 | int noexec = 0;
|
---|
| 222 | int fp_lib = 1;
|
---|
| 223 | int E_flag = 0;
|
---|
| 224 | int i_flag = 1;
|
---|
| 225 |
|
---|
| 226 |
|
---|
| 227 | USTRING curfil;
|
---|
| 228 | USTRING newfil;
|
---|
| 229 | struct arglist SRCFILES;
|
---|
| 230 | struct arglist LDIRS;
|
---|
| 231 | struct arglist LDFILES;
|
---|
| 232 | struct arglist GEN_LDFILES;
|
---|
| 233 | struct arglist FLAGS;
|
---|
| 234 |
|
---|
| 235 | char *tmpdir = "/tmp";
|
---|
| 236 | char tmpname[64];
|
---|
| 237 |
|
---|
| 238 | struct compile *compbase;
|
---|
| 239 | struct pass *loader;
|
---|
| 240 | struct passinfo *loaderinfo;
|
---|
| 241 | char *source;
|
---|
| 242 | int maxLlen;
|
---|
| 243 |
|
---|
| 244 | _PROTOTYPE(char *library, (char *nm ));
|
---|
| 245 | _PROTOTYPE(void trapcc, (int sig ));
|
---|
| 246 | _PROTOTYPE(int main, (int argc, char *argv []));
|
---|
| 247 | _PROTOTYPE(int remove, (char *str ));
|
---|
| 248 | _PROTOTYPE(char *alloc, (unsigned u ));
|
---|
| 249 | _PROTOTYPE(int append, (struct arglist *al, char *arg ));
|
---|
| 250 | _PROTOTYPE(int concat, (struct arglist *al1, struct arglist *al2 ));
|
---|
| 251 | _PROTOTYPE(char *mkstr, (char *dst, char *arg1, char *arg2, char *arg3 ));
|
---|
| 252 | _PROTOTYPE(int basename, (char *str, char *dst ));
|
---|
| 253 | _PROTOTYPE(char *extension, (char *fln ));
|
---|
| 254 | _PROTOTYPE(int runvec, (struct arglist *vec, struct passinfo *pass, char *in, char *out ));
|
---|
| 255 | _PROTOTYPE(int prnum, (unsigned x ));
|
---|
| 256 | _PROTOTYPE(int prs, (char *str ));
|
---|
| 257 | _PROTOTYPE(int panic, (char *str ));
|
---|
| 258 | _PROTOTYPE(int pr_vec, (struct arglist *vec ));
|
---|
| 259 | _PROTOTYPE(int ex_vec, (struct arglist *vec ));
|
---|
| 260 | _PROTOTYPE(int mktempname, (char *nm ));
|
---|
| 261 | _PROTOTYPE(int mkbase, (void));
|
---|
| 262 | _PROTOTYPE(int mkloader, (void));
|
---|
| 263 | _PROTOTYPE(int needsprep, (char *name ));
|
---|
| 264 | _PROTOTYPE(int cfile, (char *name ));
|
---|
| 265 | _PROTOTYPE(char *apply, (struct passinfo *pinf, struct compile *cp, char *name, int passindex, int noremove, int first, char *resultname ));
|
---|
| 266 | _PROTOTYPE(int applicable, (struct passinfo *pinf, char *suffix ));
|
---|
| 267 | _PROTOTYPE(char *process, (char *name, int noremove ));
|
---|
| 268 | _PROTOTYPE(int mkvec, (struct arglist *call, char *in, char *out, struct pass *pass, struct passinfo *pinf ));
|
---|
| 269 | _PROTOTYPE(int callld, (struct arglist *in, char *out, struct pass *pass, struct passinfo *pinf ));
|
---|
| 270 | _PROTOTYPE(int clean, (struct arglist *c ));
|
---|
| 271 | _PROTOTYPE(int scanflags, (struct arglist *call, struct passinfo *pinf ));
|
---|
| 272 |
|
---|
| 273 |
|
---|
| 274 |
|
---|
| 275 | char *
|
---|
| 276 | library(nm)
|
---|
| 277 | char *nm;
|
---|
| 278 | {
|
---|
| 279 | static char f[512];
|
---|
| 280 | int Lcount;
|
---|
| 281 |
|
---|
| 282 | for (Lcount = 0; Lcount < LDIRS.al_argc; Lcount++) {
|
---|
| 283 | mkstr(f, LDIRS.al_argv[Lcount], "/lib", nm);
|
---|
| 284 | strcat(f, ".a");
|
---|
| 285 | if (access(f, 0) != 0) {
|
---|
| 286 | f[strlen(f)-1] = 'a';
|
---|
| 287 | if (access(f, 0) != 0) continue;
|
---|
| 288 | }
|
---|
| 289 | return f;
|
---|
| 290 | }
|
---|
| 291 | mkstr(f, LIBDIR, "/lib", nm);
|
---|
| 292 | strcat(f, ".a");
|
---|
| 293 | if (access(f, 0) != 0) {
|
---|
| 294 | int i = strlen(f) - 1;
|
---|
| 295 | f[i] = 'a';
|
---|
| 296 | if (access(f, 0) != 0) f[i] = 'A';
|
---|
| 297 | }
|
---|
| 298 | return f;
|
---|
| 299 | }
|
---|
| 300 |
|
---|
| 301 | void trapcc(sig)
|
---|
| 302 | int sig;
|
---|
| 303 | {
|
---|
| 304 | signal(sig, SIG_IGN);
|
---|
| 305 | if (kids != -1) kill(kids, sig);
|
---|
| 306 | cleanup(newfil);
|
---|
| 307 | cleanup(curfil);
|
---|
| 308 | exit(1);
|
---|
| 309 | }
|
---|
| 310 |
|
---|
| 311 | main(argc, argv)
|
---|
| 312 | char *argv[];
|
---|
| 313 | {
|
---|
| 314 | char *str;
|
---|
| 315 | char **argvec;
|
---|
| 316 | int count;
|
---|
| 317 | char *file;
|
---|
| 318 |
|
---|
| 319 | maxLlen = strlen(LIBDIR);
|
---|
| 320 | ProgCall = *argv++;
|
---|
| 321 |
|
---|
| 322 | mkbase();
|
---|
| 323 |
|
---|
| 324 | if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
---|
| 325 | signal(SIGHUP, trapcc);
|
---|
| 326 | if (signal(SIGINT, SIG_IGN) != SIG_IGN)
|
---|
| 327 | signal(SIGINT, trapcc);
|
---|
| 328 | if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
|
---|
| 329 | signal(SIGQUIT, trapcc);
|
---|
| 330 | while (--argc > 0) {
|
---|
| 331 | if (*(str = *argv++) != '-' || str[1] == 0) {
|
---|
| 332 | append(&SRCFILES, str);
|
---|
| 333 | continue;
|
---|
| 334 | }
|
---|
| 335 |
|
---|
| 336 | if (strcmp(str, "-com") == 0) {
|
---|
| 337 | i_flag = 0;
|
---|
| 338 | } else
|
---|
| 339 | if (strcmp(str, "-sep") == 0) {
|
---|
| 340 | i_flag = 1;
|
---|
| 341 | } else {
|
---|
| 342 | switch (str[1]) {
|
---|
| 343 |
|
---|
| 344 | case 'c':
|
---|
| 345 | stopsuffix = "o";
|
---|
| 346 | if (str[2] == '.') stopsuffix = str + 3;
|
---|
| 347 | break;
|
---|
| 348 | case 'f':
|
---|
| 349 | fp_lib = (strcmp(str+2, "hard") != 0);
|
---|
| 350 | break;
|
---|
| 351 | case 'F':
|
---|
| 352 | case 'W':
|
---|
| 353 | /* Ignore. */
|
---|
| 354 | break;
|
---|
| 355 | case 'L':
|
---|
| 356 | append(&LDIRS, &str[2]);
|
---|
| 357 | count = strlen(&str[2]);
|
---|
| 358 | if (count > maxLlen) maxLlen = count;
|
---|
| 359 | break;
|
---|
| 360 | case 'l':
|
---|
| 361 | append(&SRCFILES, library(&str[2]));
|
---|
| 362 | break;
|
---|
| 363 | case 'm':
|
---|
| 364 | /* Use -m, ignore -mxxx. */
|
---|
| 365 | if (str[2] == 0) append(&FLAGS, str);
|
---|
| 366 | break;
|
---|
| 367 | case 'o':
|
---|
| 368 | if (argc-- >= 0)
|
---|
| 369 | o_FILE = *argv++;
|
---|
| 370 | break;
|
---|
| 371 | case 'S':
|
---|
| 372 | stopsuffix = "s";
|
---|
| 373 | break;
|
---|
| 374 | case 'E':
|
---|
| 375 | E_flag = 1;
|
---|
| 376 | stopsuffix = "i";
|
---|
| 377 | break;
|
---|
| 378 | case 'P':
|
---|
| 379 | stopsuffix = "i";
|
---|
| 380 | append(&FLAGS, str);
|
---|
| 381 | break;
|
---|
| 382 | case 'v':
|
---|
| 383 | v_flag++;
|
---|
| 384 | if (str[2] == 'n')
|
---|
| 385 | noexec = 1;
|
---|
| 386 | break;
|
---|
| 387 | case 't':
|
---|
| 388 | /* save temporaries */
|
---|
| 389 | t_flag++;
|
---|
| 390 | break;
|
---|
| 391 | case '.':
|
---|
| 392 | if (str[2] == 'o') {
|
---|
| 393 | /* no runtime start-off */
|
---|
| 394 | loader->pp_head[0] = 0;
|
---|
| 395 | }
|
---|
| 396 | break;
|
---|
| 397 | case 'i':
|
---|
| 398 | i_flag++;
|
---|
| 399 | break;
|
---|
| 400 | case 'T':
|
---|
| 401 | tmpdir = &str[2];
|
---|
| 402 | /*FALLTHROUGH*/
|
---|
| 403 | default:
|
---|
| 404 | append(&FLAGS, str);
|
---|
| 405 |
|
---|
| 406 | }
|
---|
| 407 | }
|
---|
| 408 | }
|
---|
| 409 |
|
---|
| 410 | if (i_flag) append(&FLAGS, "-i");
|
---|
| 411 |
|
---|
| 412 | mktempname(tmpname);
|
---|
| 413 |
|
---|
| 414 | count = SRCFILES.al_argc;
|
---|
| 415 | argvec = &(SRCFILES.al_argv[0]);
|
---|
| 416 |
|
---|
| 417 | while (count-- > 0) {
|
---|
| 418 |
|
---|
| 419 | file = *argvec++;
|
---|
| 420 | source = file;
|
---|
| 421 |
|
---|
| 422 | file = process(file, 1);
|
---|
| 423 |
|
---|
| 424 | if (file && ! stopsuffix) append(&LDFILES, file);
|
---|
| 425 | }
|
---|
| 426 |
|
---|
| 427 | clean(&SRCFILES);
|
---|
| 428 |
|
---|
| 429 | /* loader ... */
|
---|
| 430 | if (RET_CODE == 0 && LDFILES.al_argc > 0) {
|
---|
| 431 | register struct passinfo *pp = passinfo;
|
---|
| 432 |
|
---|
| 433 | while (!(pp->p_flags & LOADER)) pp++;
|
---|
| 434 | mkstr(newfil, tmpname, pp->p_to, "");
|
---|
| 435 | callld(&LDFILES, !((pp+1)->p_name) ? o_FILE : newfil, loader, pp);
|
---|
| 436 | if (RET_CODE == 0) {
|
---|
| 437 | register int i = GEN_LDFILES.al_argc;
|
---|
| 438 |
|
---|
| 439 | while (i-- > 0) {
|
---|
| 440 | remove(GEN_LDFILES.al_argv[i]);
|
---|
| 441 | free(GEN_LDFILES.al_argv[i]);
|
---|
| 442 | }
|
---|
| 443 | if ((++pp)->p_name) {
|
---|
| 444 | process(newfil, 0);
|
---|
| 445 | }
|
---|
| 446 | }
|
---|
| 447 | }
|
---|
| 448 | exit(RET_CODE);
|
---|
| 449 | }
|
---|
| 450 |
|
---|
| 451 | remove(str)
|
---|
| 452 | char *str;
|
---|
| 453 | {
|
---|
| 454 | if (t_flag)
|
---|
| 455 | return;
|
---|
| 456 | if (v_flag) {
|
---|
| 457 | prs("rm ");
|
---|
| 458 | prs(str);
|
---|
| 459 | prs("\n");
|
---|
| 460 | }
|
---|
| 461 | if (noexec)
|
---|
| 462 | return;
|
---|
| 463 | unlink(str);
|
---|
| 464 | }
|
---|
| 465 |
|
---|
| 466 | char *
|
---|
| 467 | alloc(u)
|
---|
| 468 | unsigned u;
|
---|
| 469 | {
|
---|
| 470 | register char *p = malloc(u);
|
---|
| 471 |
|
---|
| 472 | if (p == 0) panic("no space\n");
|
---|
| 473 | return p;
|
---|
| 474 | }
|
---|
| 475 |
|
---|
| 476 | append(al, arg)
|
---|
| 477 | struct arglist *al;
|
---|
| 478 | char *arg;
|
---|
| 479 | {
|
---|
| 480 | char *a = alloc((unsigned) (strlen(arg) + 1));
|
---|
| 481 |
|
---|
| 482 | strcpy(a, arg);
|
---|
| 483 | if (al->al_argc >= MAXARGC)
|
---|
| 484 | panic("argument list overflow\n");
|
---|
| 485 | al->al_argv[(al->al_argc)++] = a;
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | concat(al1, al2)
|
---|
| 489 | struct arglist *al1, *al2;
|
---|
| 490 | {
|
---|
| 491 | register i = al2->al_argc;
|
---|
| 492 | register char **p = &(al1->al_argv[al1->al_argc]);
|
---|
| 493 | register char **q = &(al2->al_argv[0]);
|
---|
| 494 |
|
---|
| 495 | if ((al1->al_argc += i) >= MAXARGC)
|
---|
| 496 | panic("argument list overflow\n");
|
---|
| 497 | while (i-- > 0)
|
---|
| 498 | *p++ = *q++;
|
---|
| 499 | }
|
---|
| 500 |
|
---|
| 501 | char *
|
---|
| 502 | mkstr(dst, arg1, arg2, arg3)
|
---|
| 503 | char *dst, *arg1, *arg2, *arg3;
|
---|
| 504 | {
|
---|
| 505 | register char *p;
|
---|
| 506 | register char *q = dst;
|
---|
| 507 |
|
---|
| 508 | p = arg1;
|
---|
| 509 | while (*q++ = *p++);
|
---|
| 510 | q--;
|
---|
| 511 | p = arg2;
|
---|
| 512 | while (*q++ = *p++);
|
---|
| 513 | q--;
|
---|
| 514 | p = arg3;
|
---|
| 515 | while (*q++ = *p++);
|
---|
| 516 | q--;
|
---|
| 517 | return dst;
|
---|
| 518 | }
|
---|
| 519 |
|
---|
| 520 | basename(str, dst)
|
---|
| 521 | char *str;
|
---|
| 522 | register char *dst;
|
---|
| 523 | {
|
---|
| 524 | register char *p1 = str;
|
---|
| 525 | register char *p2 = p1;
|
---|
| 526 |
|
---|
| 527 | while (*p1)
|
---|
| 528 | if (*p1++ == '/')
|
---|
| 529 | p2 = p1;
|
---|
| 530 | p1--;
|
---|
| 531 | while (*p1 != '.' && p1 > p2) p1--;
|
---|
| 532 | if (*p1 == '.') {
|
---|
| 533 | *p1 = '\0';
|
---|
| 534 | while (*dst++ = *p2++);
|
---|
| 535 | *p1 = '.';
|
---|
| 536 | }
|
---|
| 537 | else
|
---|
| 538 | while (*dst++ = *p2++);
|
---|
| 539 | }
|
---|
| 540 |
|
---|
| 541 | char *
|
---|
| 542 | extension(fln)
|
---|
| 543 | char *fln;
|
---|
| 544 | {
|
---|
| 545 | register char *fn = fln;
|
---|
| 546 |
|
---|
| 547 | while (*fn) fn++;
|
---|
| 548 | while (fn > fln && *fn != '.') fn--;
|
---|
| 549 | if (fn != fln) return fn+1;
|
---|
| 550 | return (char *)0;
|
---|
| 551 | }
|
---|
| 552 |
|
---|
| 553 | runvec(vec, pass, in, out)
|
---|
| 554 | struct arglist *vec;
|
---|
| 555 | struct passinfo *pass;
|
---|
| 556 | char *in, *out;
|
---|
| 557 | {
|
---|
| 558 | int pid, status;
|
---|
| 559 | int shifted = 0;
|
---|
| 560 |
|
---|
| 561 | if (
|
---|
| 562 | strncmp(vec->al_argv[1], "/usr/", 5) == 0
|
---|
| 563 | &&
|
---|
| 564 | access(vec->al_argv[1] + 4, 1) == 0
|
---|
| 565 | ) {
|
---|
| 566 | vec->al_argv[1] += 4;
|
---|
| 567 | shifted = 1;
|
---|
| 568 | }
|
---|
| 569 |
|
---|
| 570 | if (v_flag) {
|
---|
| 571 | pr_vec(vec);
|
---|
| 572 | if (pass->p_flags & STDIN) {
|
---|
| 573 | prs(" <");
|
---|
| 574 | prs(in);
|
---|
| 575 | }
|
---|
| 576 | if (pass->p_flags & STDOUT && !E_flag) {
|
---|
| 577 | prs(" >");
|
---|
| 578 | prs(out);
|
---|
| 579 | }
|
---|
| 580 | prs("\n");
|
---|
| 581 | }
|
---|
| 582 | if (noexec) {
|
---|
| 583 | if (shifted) vec->al_argv[1] -= 4;
|
---|
| 584 | clean(vec);
|
---|
| 585 | return 1;
|
---|
| 586 | }
|
---|
| 587 | if ((pid = fork()) == 0) { /* start up the process */
|
---|
| 588 | if (pass->p_flags & STDIN && strcmp(in, "-") != 0) {
|
---|
| 589 | /* redirect standard input */
|
---|
| 590 | close(0);
|
---|
| 591 | if (open(in, 0) != 0)
|
---|
| 592 | panic("cannot open input file\n");
|
---|
| 593 | }
|
---|
| 594 | if (pass->p_flags & STDOUT && !E_flag) {
|
---|
| 595 | /* redirect standard output */
|
---|
| 596 | close(1);
|
---|
| 597 | if (creat(out, 0666) != 1)
|
---|
| 598 | panic("cannot create output file\n");
|
---|
| 599 | }
|
---|
| 600 | ex_vec(vec);
|
---|
| 601 | }
|
---|
| 602 | if (pid == -1)
|
---|
| 603 | panic("no more processes\n");
|
---|
| 604 | kids = pid;
|
---|
| 605 | wait(&status);
|
---|
| 606 | if (status) switch(status & 0177) {
|
---|
| 607 | case SIGHUP:
|
---|
| 608 | case SIGINT:
|
---|
| 609 | case SIGQUIT:
|
---|
| 610 | case SIGTERM:
|
---|
| 611 | case 0:
|
---|
| 612 | break;
|
---|
| 613 | default:
|
---|
| 614 | if (E_flag && (status & 0177) == SIGPIPE) break;
|
---|
| 615 | prs(vec->al_argv[1]);
|
---|
| 616 | prs(" died with signal ");
|
---|
| 617 | prnum(status & 0177);
|
---|
| 618 | prs("\n");
|
---|
| 619 | }
|
---|
| 620 | if (shifted) vec->al_argv[1] -= 4;
|
---|
| 621 | clean(vec);
|
---|
| 622 | kids = -1;
|
---|
| 623 | return status ? ((RET_CODE = 1), 0) : 1;
|
---|
| 624 | }
|
---|
| 625 |
|
---|
| 626 | prnum(x)
|
---|
| 627 | register unsigned x;
|
---|
| 628 | {
|
---|
| 629 | static char numbuf[8]; /* though it prints at most 3 characters */
|
---|
| 630 | register char *cp = numbuf + sizeof(numbuf) - 1;
|
---|
| 631 |
|
---|
| 632 | *cp = '\0';
|
---|
| 633 | while (x >= 10) {
|
---|
| 634 | *--cp = (x % 10) + '0';
|
---|
| 635 | x /= 10;
|
---|
| 636 | }
|
---|
| 637 | *--cp = x + '0';
|
---|
| 638 | prs(cp);
|
---|
| 639 |
|
---|
| 640 | }
|
---|
| 641 |
|
---|
| 642 | prs(str)
|
---|
| 643 | char *str;
|
---|
| 644 | {
|
---|
| 645 | if (str && *str)
|
---|
| 646 | write(2, str, strlen(str));
|
---|
| 647 | }
|
---|
| 648 |
|
---|
| 649 | panic(str)
|
---|
| 650 | char *str;
|
---|
| 651 | {
|
---|
| 652 | prs(str);
|
---|
| 653 | trapcc(SIGINT);
|
---|
| 654 | }
|
---|
| 655 |
|
---|
| 656 | pr_vec(vec)
|
---|
| 657 | register struct arglist *vec;
|
---|
| 658 | {
|
---|
| 659 | register char **ap = &vec->al_argv[1];
|
---|
| 660 |
|
---|
| 661 | vec->al_argv[vec->al_argc] = 0;
|
---|
| 662 | prs(*ap);
|
---|
| 663 | while (*++ap) {
|
---|
| 664 | prs(" ");
|
---|
| 665 | if (strlen(*ap))
|
---|
| 666 | prs(*ap);
|
---|
| 667 | else
|
---|
| 668 | prs("(empty)");
|
---|
| 669 | }
|
---|
| 670 | }
|
---|
| 671 |
|
---|
| 672 | ex_vec(vec)
|
---|
| 673 | register struct arglist *vec;
|
---|
| 674 | {
|
---|
| 675 | extern int errno;
|
---|
| 676 |
|
---|
| 677 | vec->al_argv[vec->al_argc] = 0;
|
---|
| 678 | execv(vec->al_argv[1], &(vec->al_argv[1]));
|
---|
| 679 | if (errno == ENOEXEC) { /* not an a.out, try it with the SHELL */
|
---|
| 680 | vec->al_argv[0] = SHELL;
|
---|
| 681 | execv(SHELL, &(vec->al_argv[0]));
|
---|
| 682 | }
|
---|
| 683 | if (access(vec->al_argv[1], 1) == 0) {
|
---|
| 684 | /* File is executable. */
|
---|
| 685 | prs("Cannot execute ");
|
---|
| 686 | prs(vec->al_argv[1]);
|
---|
| 687 | prs(". Not enough memory.\n");
|
---|
| 688 | prs("Reduce the memory use of your system and try again\n");
|
---|
| 689 | } else {
|
---|
| 690 | prs(vec->al_argv[1]);
|
---|
| 691 | prs(" is not executable\n");
|
---|
| 692 | }
|
---|
| 693 | exit(1);
|
---|
| 694 | }
|
---|
| 695 |
|
---|
| 696 | mktempname(nm)
|
---|
| 697 | register char *nm;
|
---|
| 698 | {
|
---|
| 699 | register int i;
|
---|
| 700 | register int pid = getpid();
|
---|
| 701 |
|
---|
| 702 | mkstr(nm, tmpdir, "/", compbase->c_callname);
|
---|
| 703 | while (*nm) nm++;
|
---|
| 704 |
|
---|
| 705 | for (i = 9; i > 3; i--) {
|
---|
| 706 | *nm++ = (pid % 10) + '0';
|
---|
| 707 | pid /= 10;
|
---|
| 708 | }
|
---|
| 709 | *nm++ = '.';
|
---|
| 710 | *nm++ = '\0'; /* null termination */
|
---|
| 711 | }
|
---|
| 712 |
|
---|
| 713 | mkbase()
|
---|
| 714 | {
|
---|
| 715 | register struct compile *p = passes;
|
---|
| 716 | USTRING callname;
|
---|
| 717 | register int len;
|
---|
| 718 |
|
---|
| 719 | basename(ProgCall, callname);
|
---|
| 720 | len = strlen(callname);
|
---|
| 721 | while (p->c_suffix) {
|
---|
| 722 | if (strcmp(p->c_callname, callname+len-strlen(p->c_callname)) == 0) {
|
---|
| 723 | compbase = p;
|
---|
| 724 | mkloader();
|
---|
| 725 | return;
|
---|
| 726 | }
|
---|
| 727 | p++;
|
---|
| 728 | }
|
---|
| 729 | /* we should not get here */
|
---|
| 730 | panic("internal error\n");
|
---|
| 731 | }
|
---|
| 732 |
|
---|
| 733 | mkloader()
|
---|
| 734 | {
|
---|
| 735 | register struct passinfo *p = passinfo;
|
---|
| 736 | register struct pass *pass;
|
---|
| 737 |
|
---|
| 738 | while (!(p->p_flags & LOADER)) p++;
|
---|
| 739 | loaderinfo = p;
|
---|
| 740 | pass = &(compbase->c_passes[0]);
|
---|
| 741 | while (strcmp(pass->pp_name, p->p_name)) pass++;
|
---|
| 742 | loader = pass;
|
---|
| 743 | }
|
---|
| 744 |
|
---|
| 745 | needsprep(name)
|
---|
| 746 | char *name;
|
---|
| 747 | {
|
---|
| 748 | int file;
|
---|
| 749 | char fc;
|
---|
| 750 |
|
---|
| 751 | file = open(name,0);
|
---|
| 752 | if (file <0) return 0;
|
---|
| 753 | if (read(file, &fc, 1) != 1) fc = 0;
|
---|
| 754 | close(file);
|
---|
| 755 | return fc == '#';
|
---|
| 756 | }
|
---|
| 757 |
|
---|
| 758 | cfile(name)
|
---|
| 759 | char *name;
|
---|
| 760 | {
|
---|
| 761 | while (*name != '\0' && *name != '.')
|
---|
| 762 | name++;
|
---|
| 763 |
|
---|
| 764 | if (*name == '\0') return 0;
|
---|
| 765 | return (*++name == 'c' && *++name == '\0');
|
---|
| 766 | }
|
---|
| 767 |
|
---|
| 768 | char *
|
---|
| 769 | apply(pinf, cp, name, passindex, noremove, first, resultname)
|
---|
| 770 | register struct passinfo *pinf;
|
---|
| 771 | register struct compile *cp;
|
---|
| 772 | char *name, *resultname;
|
---|
| 773 | {
|
---|
| 774 | /* Apply a pass, indicated by "pinf", with args in
|
---|
| 775 | cp->c_passes[passindex], to name "name", leaving the result
|
---|
| 776 | in a file with name "resultname", concatenated with result
|
---|
| 777 | suffix.
|
---|
| 778 | When neccessary, the preprocessor is run first.
|
---|
| 779 | If "noremove" is NOT set, the file "name" is removed.
|
---|
| 780 | */
|
---|
| 781 |
|
---|
| 782 | struct arglist *call = &CALLVEC;
|
---|
| 783 | struct pass *pass = &(cp->c_passes[passindex]);
|
---|
| 784 | char *outname;
|
---|
| 785 |
|
---|
| 786 | if ( /* this pass is the first pass */
|
---|
| 787 | first
|
---|
| 788 | &&
|
---|
| 789 | ( /* preprocessor always needed */
|
---|
| 790 | (pinf->p_flags & PREPALWAYS)
|
---|
| 791 | ||/* or only when "needsprep" says so */
|
---|
| 792 | ( (pinf->p_flags & PREPCOND) && needsprep(name))
|
---|
| 793 | )
|
---|
| 794 | ) {
|
---|
| 795 | mkstr(newfil, tmpname, passinfo[0].p_to, "");
|
---|
| 796 | mkvec(call, name, newfil,
|
---|
| 797 | (pinf->p_flags & PREPNOLN) ? &prepnoln : &preprocessor,
|
---|
| 798 | &passinfo[0]);
|
---|
| 799 | if (! runvec(call, &passinfo[0], name, newfil)) {
|
---|
| 800 | cleanup(newfil);
|
---|
| 801 | return 0;
|
---|
| 802 | }
|
---|
| 803 |
|
---|
| 804 | /* A .c file must always be mishandled by irrel. */
|
---|
| 805 | if (cfile(name)) {
|
---|
| 806 | /* newfil is OK */
|
---|
| 807 | mkvec(call, newfil, newfil, &irrel, &passinfo[1]);
|
---|
| 808 | if (! runvec(call, &passinfo[1], newfil, newfil)) {
|
---|
| 809 | cleanup(newfil);
|
---|
| 810 | return 0;
|
---|
| 811 | }
|
---|
| 812 | }
|
---|
| 813 | strcpy(curfil, newfil);
|
---|
| 814 | newfil[0] = '\0';
|
---|
| 815 | name = curfil;
|
---|
| 816 | noremove = 0;
|
---|
| 817 | }
|
---|
| 818 | if (pinf->p_to) outname = mkstr(newfil, resultname, pinf->p_to, "");
|
---|
| 819 | else outname = o_FILE;
|
---|
| 820 | mkvec(call, name, outname, pass, pinf);
|
---|
| 821 | if (! runvec(call, pinf, name, outname)) {
|
---|
| 822 | if (! (pinf->p_flags & NOCLEAN)) cleanup(outname);
|
---|
| 823 | if (! noremove) cleanup(name);
|
---|
| 824 | return 0;
|
---|
| 825 | }
|
---|
| 826 | if (! noremove) cleanup(name);
|
---|
| 827 | strcpy(curfil, newfil);
|
---|
| 828 | newfil[0] = '\0';
|
---|
| 829 | return curfil;
|
---|
| 830 | }
|
---|
| 831 |
|
---|
| 832 | int
|
---|
| 833 | applicable(pinf, suffix)
|
---|
| 834 | struct passinfo *pinf;
|
---|
| 835 | char *suffix;
|
---|
| 836 | {
|
---|
| 837 | /* Return one if the pass indicated by "pinfo" is applicable to
|
---|
| 838 | a file with suffix "suffix".
|
---|
| 839 | */
|
---|
| 840 | register char *sfx = pinf->p_from;
|
---|
| 841 | int l;
|
---|
| 842 |
|
---|
| 843 | if (! suffix) return 0;
|
---|
| 844 | l = strlen(suffix);
|
---|
| 845 | while (*sfx) {
|
---|
| 846 | register char *p = sfx;
|
---|
| 847 |
|
---|
| 848 | while (*p && *p != ',') p++;
|
---|
| 849 | if (l == p - sfx && strncmp(sfx, suffix, l) == 0) {
|
---|
| 850 | return 1;
|
---|
| 851 | }
|
---|
| 852 | if (*p == ',') sfx = p+1;
|
---|
| 853 | else sfx = p;
|
---|
| 854 | }
|
---|
| 855 | return 0;
|
---|
| 856 | }
|
---|
| 857 |
|
---|
| 858 | char *
|
---|
| 859 | process(name, noremove)
|
---|
| 860 | char *name;
|
---|
| 861 | {
|
---|
| 862 | register struct compile *cp = passes;
|
---|
| 863 | char *suffix = extension(name);
|
---|
| 864 | USTRING base;
|
---|
| 865 | register struct pass *pass;
|
---|
| 866 | register struct passinfo *pinf;
|
---|
| 867 |
|
---|
| 868 | if (E_flag) {
|
---|
| 869 | /* -E uses the cpp pass. */
|
---|
| 870 | suffix = "CPP";
|
---|
| 871 | }
|
---|
| 872 |
|
---|
| 873 | if (! suffix) return name;
|
---|
| 874 |
|
---|
| 875 | basename(name, base);
|
---|
| 876 |
|
---|
| 877 | while (cp->c_suffix) {
|
---|
| 878 | if ((cp->c_flags & DEFLANG) &&
|
---|
| 879 | strcmp(cp->c_suffix, suffix) == 0)
|
---|
| 880 | break;
|
---|
| 881 | cp++;
|
---|
| 882 | }
|
---|
| 883 | if (! cp->c_suffix) cp = compbase;
|
---|
| 884 | pass = cp->c_passes;
|
---|
| 885 | while (pass->pp_name) {
|
---|
| 886 | int first = 1;
|
---|
| 887 |
|
---|
| 888 | for (pinf=passinfo; strcmp(pass->pp_name,pinf->p_name);pinf++)
|
---|
| 889 | ;
|
---|
| 890 | if (! (pinf->p_flags & LOADER) && applicable(pinf, suffix)) {
|
---|
| 891 | int cont = ! stopsuffix || ! pinf->p_to ||
|
---|
| 892 | strcmp(stopsuffix, pinf->p_to) != 0;
|
---|
| 893 | name = apply(pinf,
|
---|
| 894 | cp,
|
---|
| 895 | name,
|
---|
| 896 | (int) (pass - cp->c_passes),
|
---|
| 897 | noremove,
|
---|
| 898 | first,
|
---|
| 899 | applicable(loaderinfo, pinf->p_to) ||
|
---|
| 900 | !cont ?
|
---|
| 901 | strcat(base, ".") :
|
---|
| 902 | tmpname);
|
---|
| 903 | first = noremove = 0;
|
---|
| 904 | suffix = pinf->p_to;
|
---|
| 905 | if (!cont || !name) break;
|
---|
| 906 | }
|
---|
| 907 | pass++;
|
---|
| 908 | }
|
---|
| 909 | if (!noremove && name)
|
---|
| 910 | append(&GEN_LDFILES, name);
|
---|
| 911 | return name;
|
---|
| 912 | }
|
---|
| 913 |
|
---|
| 914 | mkvec(call, in, out, pass, pinf)
|
---|
| 915 | struct arglist *call;
|
---|
| 916 | char *in, *out;
|
---|
| 917 | struct pass *pass;
|
---|
| 918 | register struct passinfo *pinf;
|
---|
| 919 | {
|
---|
| 920 | register int i;
|
---|
| 921 |
|
---|
| 922 | init(call);
|
---|
| 923 | append(call, pinf->p_path);
|
---|
| 924 | scanflags(call, pinf);
|
---|
| 925 | if (pass) for (i = 0; i < MAXHEAD; i++)
|
---|
| 926 | if (pass->pp_head[i])
|
---|
| 927 | append(call, pass->pp_head[i]);
|
---|
| 928 | else break;
|
---|
| 929 | if (pinf->p_flags & INPUT && strcmp(in, "-") != 0)
|
---|
| 930 | append(call, in);
|
---|
| 931 | if (pinf->p_flags & OUTPUT)
|
---|
| 932 | append(call, out);
|
---|
| 933 | if (pinf->p_flags & O_OUTPUT) {
|
---|
| 934 | append(call, "-o");
|
---|
| 935 | append(call, out);
|
---|
| 936 | }
|
---|
| 937 | if (pass) for (i = 0; i < MAXTAIL; i++)
|
---|
| 938 | if (pass->pp_tail[i])
|
---|
| 939 | append(call, pass->pp_tail[i]);
|
---|
| 940 | else break;
|
---|
| 941 | }
|
---|
| 942 |
|
---|
| 943 | callld(in, out, pass, pinf)
|
---|
| 944 | struct arglist *in;
|
---|
| 945 | char *out;
|
---|
| 946 | struct pass *pass;
|
---|
| 947 | register struct passinfo *pinf;
|
---|
| 948 | {
|
---|
| 949 | struct arglist *call = &CALLVEC;
|
---|
| 950 | register int i;
|
---|
| 951 |
|
---|
| 952 | init(call);
|
---|
| 953 | append(call, pinf->p_path);
|
---|
| 954 | scanflags(call, pinf);
|
---|
| 955 | append(call, "-o");
|
---|
| 956 | append(call, out);
|
---|
| 957 | for (i = 0; i < MAXHEAD; i++)
|
---|
| 958 | if (pass->pp_head[i])
|
---|
| 959 | append(call, pass->pp_head[i]);
|
---|
| 960 | else break;
|
---|
| 961 | if (pinf->p_flags & INPUT)
|
---|
| 962 | concat(call, in);
|
---|
| 963 | if (pinf->p_flags & OUTPUT)
|
---|
| 964 | append(call, out);
|
---|
| 965 | for (i = 0; i < MAXTAIL; i++) {
|
---|
| 966 | if (pass->pp_tail[i]) {
|
---|
| 967 | if (pass->pp_tail[i][0] == '-' &&
|
---|
| 968 | pass->pp_tail[i][1] == 'l') {
|
---|
| 969 | append(call, library(&(pass->pp_tail[i][2])));
|
---|
| 970 | }
|
---|
| 971 | else if (*(pass->pp_tail[i]) != '*')
|
---|
| 972 | append(call, pass->pp_tail[i]);
|
---|
| 973 | else if (fp_lib)
|
---|
| 974 | append(call, library("fp"));
|
---|
| 975 | } else break;
|
---|
| 976 | }
|
---|
| 977 | if (! runvec(call, pinf, (char *) 0, out)) {
|
---|
| 978 | cleanup(out);
|
---|
| 979 | RET_CODE = 1;
|
---|
| 980 | }
|
---|
| 981 | }
|
---|
| 982 |
|
---|
| 983 | clean(c)
|
---|
| 984 | register struct arglist *c;
|
---|
| 985 | {
|
---|
| 986 | register int i;
|
---|
| 987 |
|
---|
| 988 | for (i = 1; i < c->al_argc; i++) {
|
---|
| 989 | free(c->al_argv[i]);
|
---|
| 990 | c->al_argv[i] = 0;
|
---|
| 991 | }
|
---|
| 992 | c->al_argc = 0;
|
---|
| 993 | }
|
---|
| 994 |
|
---|
| 995 | scanflags(call, pinf)
|
---|
| 996 | struct arglist *call;
|
---|
| 997 | struct passinfo *pinf;
|
---|
| 998 | {
|
---|
| 999 | /* Find out which flags from FLAGS must be passed to pass "pinf",
|
---|
| 1000 | and how.
|
---|
| 1001 | Append them to "call"
|
---|
| 1002 | */
|
---|
| 1003 | register int i;
|
---|
| 1004 | USTRING flg;
|
---|
| 1005 |
|
---|
| 1006 | for (i = 0; i < FLAGS.al_argc; i++) {
|
---|
| 1007 | register char *q = pinf->p_acceptflags;
|
---|
| 1008 |
|
---|
| 1009 | while (*q) {
|
---|
| 1010 | register char *p = FLAGS.al_argv[i] + 1;
|
---|
| 1011 |
|
---|
| 1012 | while (*q && *q == *p) {
|
---|
| 1013 | q++; p++;
|
---|
| 1014 | }
|
---|
| 1015 | if (*q == ',' || !*q) {
|
---|
| 1016 | if (! *p) {
|
---|
| 1017 | /* append literally */
|
---|
| 1018 | append(call, FLAGS.al_argv[i]);
|
---|
| 1019 | }
|
---|
| 1020 | break;
|
---|
| 1021 | }
|
---|
| 1022 | if (*q == '*') {
|
---|
| 1023 | register char *s = flg;
|
---|
| 1024 |
|
---|
| 1025 | if (*++q != '=') {
|
---|
| 1026 | /* append literally */
|
---|
| 1027 | append(call, FLAGS.al_argv[i]);
|
---|
| 1028 | break;
|
---|
| 1029 | }
|
---|
| 1030 | *s++ = '-';
|
---|
| 1031 | if (*q) q++; /* skip ',' */
|
---|
| 1032 | while (*q && *q != ',' && *q != '*') {
|
---|
| 1033 | /* copy replacement flag */
|
---|
| 1034 | *s++ = *q++;
|
---|
| 1035 | }
|
---|
| 1036 | if (*q == '*') {
|
---|
| 1037 | /* copy rest */
|
---|
| 1038 | while (*p) *s++ = *p++;
|
---|
| 1039 | }
|
---|
| 1040 | *s = 0;
|
---|
| 1041 | append(call, flg);
|
---|
| 1042 | break;
|
---|
| 1043 | }
|
---|
| 1044 | if (*q == '=') {
|
---|
| 1045 | /* copy replacement */
|
---|
| 1046 | register char *s = flg;
|
---|
| 1047 |
|
---|
| 1048 | *s++ = '-';
|
---|
| 1049 | q++;
|
---|
| 1050 | while (*q && *q != ',') *s++ = *q++;
|
---|
| 1051 | *s = 0;
|
---|
| 1052 | append(call, flg);
|
---|
| 1053 | break;
|
---|
| 1054 | }
|
---|
| 1055 | while (*q && *q++ != ',')
|
---|
| 1056 | ;
|
---|
| 1057 | }
|
---|
| 1058 | }
|
---|
| 1059 | }
|
---|