2 Driver for fast cc-compatible ACK C compiler.
4 Derived from the C compiler driver from Minix.
7 cc -O -I<EM home dir>/config driver.c
8 Install the resulting binaries in the EM bin directory.
13 #define MACHNAME "m68020"
14 #define SYSNAME "sun3"
18 #define MACHNAME "vax4"
19 #define SYSNAME "vax4"
34 Version producing cc-compatible .o files in one pass.
36 #define MAXARGC 256 /* maximum number of arguments allowed in a list */
37 #define USTR_SIZE 128 /* maximum length of string variable */
39 typedef char USTRING[USTR_SIZE];
43 char *al_argv[MAXARGC];
46 #define CPP_NAME "$H/lib.bin/cpp"
47 #define LD_NAME "/bin/ld"
48 #define AS_NAME "/bin/as"
49 #define SHELL "/bin/sh"
57 struct arglist CPP_FLAGS = {
70 struct arglist LD_HEAD = {
93 struct arglist LD_TAIL = {
101 struct arglist LD_FLAGS;
103 struct arglist COMP_FLAGS;
105 char *o_FILE = "a.out"; /* default name for executable file */
107 #define remove(str) ((noexec || unlink(str)), (str)[0] = '\0')
108 #define cleanup(str) (str && str[0] && remove(str))
109 #define init(al) ((al)->al_argc = 1)
113 struct arglist SRCFILES;
114 struct arglist LDFILES;
118 struct arglist CALL_VEC;
126 char *mkstr(char *, ...);
133 char *expand_string();
141 extern char *strcat(), *strcpy(), *mktemp(), *strchr();
146 signal(sig, SIG_IGN);
147 if (kids != -1) kill(kids, sig);
153 #define lang_suffix() "c"
154 #define comp_name() "$H/lib.bin/c_cccompat"
161 case '-': /* debug options */
162 case 'R': /* strict K&R */
163 case 'w': /* disable warnings */
164 append(&COMP_FLAGS, str);
177 register struct arglist *call = &CALL_VEC;
182 setbuf(stdout, (char *) 0);
183 basename(*argv++,ProgCall);
185 COMP = expand_string(comp_name());
186 CPP = expand_string(CPP_NAME);
189 append(&CPP_FLAGS, "-Dvax");
192 append(&CPP_FLAGS, "-Dsun");
193 append(&CPP_FLAGS, "-Dmc68020");
194 append(&CPP_FLAGS, "-Dmc68000");
197 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
198 signal(SIGHUP, trapcc);
199 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
200 signal(SIGINT, trapcc);
201 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
202 signal(SIGQUIT, trapcc);
204 if (*(str = *argv++) != '-') {
205 append(&SRCFILES, str);
211 else switch (str[1]) {
213 case 'c': /* stop after producing .o files */
216 case 'D': /* preprocessor #define */
217 case 'U': /* preprocessor #undef */
218 append(&CPP_FLAGS, str);
220 case 'I': /* include directory */
221 append(&CPP_FLAGS, str);
223 case 'g': /* debugger support */
224 append(&COMP_FLAGS, str);
226 case 'o': /* target file */
230 ext = extension(o_FILE);
231 if (ext != o_FILE && ! strcmp(ext, lang_suffix())
233 error("-o would overwrite %s", o_FILE);
237 case 'u': /* mark identifier as undefined */
238 append(&LD_FLAGS, str);
240 append(&LD_FLAGS, *argv++);
242 case 'O': /* use built in peephole optimizer */
245 case 'v': /* verbose */
250 case 'l': /* library file */
251 append(&SRCFILES, str);
253 case 't': /* -target? */
254 if (! strcmp(str, "-target")) {
255 if (argc-- >= 0) argv++;
258 warning("%s flag ignored", str);
260 case 'M': /* use other compiler (for testing) */
263 case 's': /* strip, -sun3? */
264 if (! strcmp(str, "-sun3")) {
268 case 'n': /* text not read-only */
269 case 'N': /* text read-only */
270 case 'r': /* relocation produced */
271 case 'S': /* strip, but leave locals and globals */
272 if (str[2] == '\0') {
273 append(&LD_FLAGS, str);
278 warning("%s flag ignored", str);
285 count = SRCFILES.al_argc;
286 argvec = &(SRCFILES.al_argv[0]);
287 while (count-- > 0) {
288 ext = extension(*argvec);
289 if (*argvec[0] != '-' &&
290 ext != *argvec++ && (! strcmp(ext, lang_suffix())
296 if (compile_cnt > 1 && c_flag && o_flag) {
297 warning("-o flag ignored");
301 append(&COMP_FLAGS, "-L");
302 count = SRCFILES.al_argc;
303 argvec = &(SRCFILES.al_argv[0]);
304 while (count-- > 0) {
306 basename(file = *argvec++, BASE);
308 ext = extension(file);
310 if (file[0] != '-' &&
311 ext != file && (!strcmp(ext, lang_suffix())
313 if (compile_cnt > 1) printf("%s\n", file);
315 ldfile = c_flag ? ofile : alloc((unsigned)strlen(BASE)+3);
319 strcpy(tmp_file, TMP_DIR);
320 strcat(tmp_file, "/F_XXXXXX");
324 concat(call, &CPP_FLAGS);
326 if (runvec(call, tmp_file)) {
336 if (o_flag && c_flag) {
339 else f = mkstr(ldfile, BASE, ".", "o", (char *)0);
340 if (strcmp(ext, "s")) {
342 concat(call, &CPP_FLAGS);
343 concat(call, &COMP_FLAGS);
348 append(call, AS_NAME);
352 append(call, "-mc68020");
356 if (runvec(call, (char *) 0)) {
367 else if (file[0] != '-' &&
368 strcmp(ext, "o") && strcmp(ext, "a")) {
369 warning("file with unknown suffix (%s) passed to the loader", ext);
375 append(&LDFILES, file);
379 if (RET_CODE == 0 && LDFILES.al_argc > 0) {
383 append(call, expand_string(LD_NAME));
384 concat(call, &LD_FLAGS);
386 append(call, o_FILE);
387 concat(call, &LD_HEAD);
388 concat(call, &LDFILES);
389 concat(call, &LD_TAIL);
390 if (! runvec(call, (char *) 0)) {
404 if (file < 0) return 0;
405 if (read(file, &fc, 1) != 1) fc = 0;
426 register char *p = s;
427 register char *q = &buf[0];
446 panic("internal error");
453 if (! expanded) return s;
455 p = alloc((unsigned int) (q - buf));
456 return strcpy(p, buf);
460 register struct arglist *al;
463 if (!arg || !*arg) return;
464 if (al->al_argc >= MAXARGC)
465 panic("argument list overflow");
466 al->al_argv[(al->al_argc)++] = arg;
470 register struct arglist *al;
472 register int i = al->al_argc;
473 register char **p = &(al->al_argv[0]);
476 *p = expand_string(*p);
482 struct arglist *al1, *al2;
484 register i = al2->al_argc;
485 register char **p = &(al1->al_argv[al1->al_argc]);
486 register char **q = &(al2->al_argv[0]);
488 if ((al1->al_argc += i) >= MAXARGC)
489 panic("argument list overflow");
498 mkstr(char *dst, ...)
508 p = va_arg(ap, char *);
513 p = va_arg(ap, char *);
534 dst = q = va_arg(ap, char *);
535 p = va_arg(ap, char *);
540 p = va_arg(ap, char *);
553 register char *p1 = str;
554 register char *p2 = p1;
560 while (*p1 != '.' && p1 >= p2) p1--;
563 while (*dst++ = *p2++);
567 while (*dst++ = *p2++);
574 register char *c = fn;
577 while (*--c != '.' && c >= fn) { }
578 if (c++ < fn || !*c) return fn;
592 if ((pid = fork()) == 0) { /* start up the process */
593 if (outp) { /* redirect standard output */
595 if (creat(outp, 0666) != 1)
596 panic("cannot create output file");
601 panic("no more processes");
604 if (status) switch(status & 0177) {
612 error("%s died with signal %d\n", vec->al_argv[1], status&0177);
615 return status ? ((RET_CODE = 1), 0) : 1;
622 fprintf(stderr, "%s: ", ProgCall);
623 fprintf(stderr, str, s1, s2);
632 fprintf(stderr, "%s: (warning) ", ProgCall);
633 fprintf(stderr, str, s1, s2);
645 register struct arglist *vec;
647 register char **ap = &vec->al_argv[1];
649 vec->al_argv[vec->al_argc] = 0;
650 fprintf(stderr, "%s", *ap);
652 fprintf(stderr, " %s", *ap);
659 register struct arglist *vec;
663 vec->al_argv[vec->al_argc] = 0;
664 execv(vec->al_argv[1], &(vec->al_argv[1]));
665 if (errno == ENOEXEC) { /* not an a.out, try it with the SHELL */
666 vec->al_argv[0] = SHELL;
667 execv(SHELL, &(vec->al_argv[0]));
669 if (access(vec->al_argv[1], 1) == 0) {
670 /* File is executable. */
671 error("cannot execute %s", vec->al_argv[1]);
673 error("%s is not executable", vec->al_argv[1]);