2 Driver for fast ACK compilers.
4 Derived from the C compiler driver from Minix.
7 cc -O -I<ACK home directory>/config -DF?? driver.c
8 where F?? is either FCC, FPC, or FM2.
9 Install the resulting binaries in the EM bin directory.
10 Suggested names: afcc, afm2, and afpc.
14 Something wrong here! Only one of FM2, FPC, or FCC must be defined
18 #define MACHNAME "m68020"
19 #define SYSNAME "sun3"
23 #define MACHNAME "vax4"
24 #define SYSNAME "vax4"
28 #define MACHNAME "i386"
29 #define SYSNAME "i386"
43 Version producing ACK .o files in one pass.
45 #define MAXARGC 256 /* maximum number of arguments allowed in a list */
46 #define USTR_SIZE 128 /* maximum length of string variable */
48 typedef char USTRING[USTR_SIZE];
52 char *al_argv[MAXARGC];
55 #define CPP_NAME "$H/lib.bin/cpp"
56 #define LD_NAME "$H/lib.bin/em_led"
57 #define CV_NAME "$H/lib.bin/$S/cv"
58 #define SHELL "/bin/sh"
67 struct arglist CPP_FLAGS = {
92 struct arglist LD_HEAD = {
108 struct arglist LD_TAIL = {
109 #if defined(sun3) || defined(i386)
124 #if defined(sun3) || defined(i386)
128 "$H/lib/$S/tail_mon",
133 struct arglist align = {
159 struct arglist COMP_FLAGS;
161 char *o_FILE = "a.out"; /* default name for executable file */
163 #define remove(str) ((noexec || unlink(str)), (str)[0] = '\0')
164 #define cleanup(str) (str && str[0] && remove(str))
165 #define init(al) ((al)->al_argc = 1)
169 struct arglist SRCFILES;
170 struct arglist LDFILES;
174 struct arglist LD_FLAGS;
176 struct arglist CALL_VEC;
186 char *mkstr(char *, ...);
193 char *expand_string();
201 extern char *strcat(), *strcpy(), *mktemp(), *strchr();
206 signal(sig, SIG_IGN);
207 if (kids != -1) kill(kids, sig);
214 #define lang_suffix() "c"
215 #define comp_name() "$H/lib.bin/c_ce"
216 #define ansi_c_name() "$H/lib.bin/c_ce.ansi"
220 #define lang_suffix() "mod"
221 #define comp_name() "$H/lib.bin/m2_ce"
225 #define lang_suffix() "p"
226 #define comp_name() "$H/lib.bin/pc_ce"
238 append(&COMP_FLAGS, str);
242 case '-': /* debug options */
243 append(&COMP_FLAGS, str);
245 case 'a': /* -ansi flag */
246 if (! strcmp(str, "-ansi")) {
248 COMP = expand_string(ansi_c_name());
252 case 'w': /* disable warnings */
254 append(&COMP_FLAGS, str);
259 append(&COMP_FLAGS, &str[1]);
261 else append(&COMP_FLAGS, "-a");
274 case '-': /* debug options */
275 case 'w': /* disable warnings */
276 case 'R': /* no runtime checks */
277 case 'W': /* add warnings */
278 case 'L': /* no line numbers */
279 case 'A': /* extra array bound checks */
280 case '3': /* only accept 3rd edition Modula-2 */
281 append(&COMP_FLAGS, str);
284 append(&COMP_FLAGS, str);
286 case 'U': /* underscores in identifiers allowed */
287 if (str[2] == '\0') {
288 append(&COMP_FLAGS, str);
292 case 'e': /* local extension for Modula-2 compiler:
296 append(&COMP_FLAGS, str);
309 case '-': /* debug options */
310 case 'a': /* enable assertions */
311 case 'd': /* allow doubles (longs) */
312 case 'i': /* set size of integer sets */
313 case 't': /* tracing */
314 case 'w': /* disable warnings */
315 case 'A': /* extra array bound checks */
316 case 'C': /* distinguish between lower case and upper case */
317 case 'L': /* no FIL and LIN instructions */
318 case 'R': /* no runtime checks */
319 append(&COMP_FLAGS, str);
323 /* underscores in identifiers */
325 /* only compile standard pascal */
328 if (str[2] == '+' && str[3] == '\0') {
330 append(&COMP_FLAGS, str);
345 register struct arglist *call = &CALL_VEC;
351 setbuf(stdout, (char *) 0);
352 basename(*argv++,ProgCall);
354 COMP = expand_string(comp_name());
355 CPP = expand_string(CPP_NAME);
358 append(&CPP_FLAGS, "-D__vax");
361 append(&CPP_FLAGS, "-D__sun");
364 append(&CPP_FLAGS, "-D__mc68020");
365 append(&CPP_FLAGS, "-D__mc68000");
368 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
369 signal(SIGHUP, trapcc);
370 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
371 signal(SIGINT, trapcc);
372 if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
373 signal(SIGQUIT, trapcc);
375 if (*(str = *argv++) != '-') {
376 append(&SRCFILES, str);
382 else switch (str[1]) {
384 case 'c': /* stop after producing .o files */
387 case 'D': /* preprocessor #define */
388 case 'U': /* preprocessor #undef */
389 append(&CPP_FLAGS, str);
391 case 'I': /* include directory */
392 append(&CPP_FLAGS, str);
394 case 'g': /* debugger support */
395 append(&COMP_FLAGS, str);
398 case 'a': /* -ansi flag */
399 if (! strcmp(str, "-ansi")) {
404 case 'o': /* target file */
408 ext = extension(o_FILE);
409 if (ext != o_FILE && ! strcmp(ext, lang_suffix())
411 error("-o would overwrite %s", o_FILE);
415 case 'u': /* mark identifier as undefined */
416 append(&LD_FLAGS, str);
418 append(&LD_FLAGS, *argv++);
420 case 'O': /* use built in peephole optimizer */
423 case 'v': /* verbose */
428 case 'l': /* library file */
429 append(&SRCFILES, str);
431 case 'M': /* use other compiler (for testing) */
434 case 's': /* strip */
435 if (str[2] == '\0') {
436 append(&LD_FLAGS, str);
441 warning("%s flag ignored", str);
448 count = SRCFILES.al_argc;
449 argvec = &(SRCFILES.al_argv[0]);
450 while (count-- > 0) {
451 ext = extension(*argvec);
452 if (*argvec[0] != '-' &&
453 ext != *argvec++ && (! strcmp(ext, lang_suffix())
459 if (compile_cnt > 1 && c_flag && o_flag) {
460 warning("-o flag ignored");
465 INCLUDE = expand_string("-I$H/lib/m2");
468 INCLUDE = expand_string(ansi_c ? "-I$H/include/tail_ac" : "-I$H/include/_tail_cc");
469 append(&COMP_FLAGS, "-L");
471 count = SRCFILES.al_argc;
472 argvec = &(SRCFILES.al_argv[0]);
473 while (count-- > 0) {
475 basename(file = *argvec++, BASE);
477 ext = extension(file);
479 if (file[0] != '-' &&
480 ext != file && (!strcmp(ext, lang_suffix())
482 if (compile_cnt > 1) printf("%s\n", file);
484 ldfile = c_flag ? ofile : alloc((unsigned)strlen(BASE)+3);
490 strcpy(tmp_file, TMP_DIR);
491 strcat(tmp_file, "/F_XXXXXX");
495 concat(call, &CPP_FLAGS);
496 append(call, INCLUDE);
498 if (runvec(call, tmp_file)) {
508 if (o_flag && c_flag) {
511 else f = mkstr(ldfile, BASE, ".", "o", (char *)0);
514 concat(call, &CPP_FLAGS);
516 concat(call, &COMP_FLAGS);
518 append(call, INCLUDE);
522 if (runvec(call, (char *) 0)) {
533 else if (file[0] != '-' &&
534 strcmp(ext, "o") && strcmp(ext, "a")) {
535 warning("file with unknown suffix (%s) passed to the loader", ext);
541 append(&LDFILES, file);
545 if (RET_CODE == 0 && LDFILES.al_argc > 0) {
550 append(call, expand_string(LD_NAME));
551 concat(call, &align);
553 strcpy(tmp_file, TMP_DIR);
554 strcat(tmp_file, "/F_XXXXXX");
556 append(call, tmp_file);
557 concat(call, &LD_HEAD);
558 concat(call, &LD_FLAGS);
559 concat(call, &LDFILES);
560 if (g_flag) append(call, expand_string("$H/lib/$M/tail_db"));
562 if (! ansi_c) append(call, expand_string("$H/lib/$S/tail_cc.1s"));
564 concat(call, &LD_TAIL);
565 if (! runvec(call, (char *) 0)) {
570 append(call, expand_string(CV_NAME));
571 append(call, tmp_file);
572 append(call, o_FILE);
573 runvec(call, (char *) 0);
586 if (file < 0) return 0;
587 if (read(file, &fc, 1) != 1) fc = 0;
608 register char *p = s;
609 register char *q = &buf[0];
619 if (ansi_c) strcpy(q, "ac");
632 panic("internal error");
639 if (! expanded) return s;
641 p = alloc((unsigned int) (q - buf));
642 return strcpy(p, buf);
646 register struct arglist *al;
649 if (!arg || !*arg) return;
650 if (al->al_argc >= MAXARGC)
651 panic("argument list overflow");
652 al->al_argv[(al->al_argc)++] = arg;
656 register struct arglist *al;
658 register int i = al->al_argc;
659 register char **p = &(al->al_argv[0]);
662 *p = expand_string(*p);
668 struct arglist *al1, *al2;
670 register i = al2->al_argc;
671 register char **p = &(al1->al_argv[al1->al_argc]);
672 register char **q = &(al2->al_argv[0]);
674 if ((al1->al_argc += i) >= MAXARGC)
675 panic("argument list overflow");
683 mkstr(char *dst, ...)
693 p = va_arg(ap, char *);
698 p = va_arg(ap, char *);
719 dst = q = va_arg(ap, char *);
720 p = va_arg(ap, char *);
725 p = va_arg(ap, char *);
737 register char *p1 = str;
738 register char *p2 = p1;
744 while (*p1 != '.' && p1 >= p2) p1--;
747 while (*dst++ = *p2++);
751 while (*dst++ = *p2++);
758 register char *c = fn;
761 while (*--c != '.' && c >= fn) { }
762 if (c++ < fn || !*c) return fn;
776 if ((pid = fork()) == 0) { /* start up the process */
777 if (outp) { /* redirect standard output */
779 if (creat(outp, 0666) != 1)
780 panic("cannot create output file");
785 panic("no more processes");
788 if (status) switch(status & 0177) {
796 error("%s died with signal %d\n", vec->al_argv[1], status&0177);
799 return status ? ((RET_CODE = 1), 0) : 1;
806 fprintf(stderr, "%s: ", ProgCall);
807 fprintf(stderr, str, s1, s2);
816 fprintf(stderr, "%s: (warning) ", ProgCall);
817 fprintf(stderr, str, s1, s2);
829 register struct arglist *vec;
831 register char **ap = &vec->al_argv[1];
833 vec->al_argv[vec->al_argc] = 0;
834 fprintf(stderr, "%s", *ap);
836 fprintf(stderr, " %s", *ap);
843 register struct arglist *vec;
847 vec->al_argv[vec->al_argc] = 0;
848 execv(vec->al_argv[1], &(vec->al_argv[1]));
849 if (errno == ENOEXEC) { /* not an a.out, try it with the SHELL */
850 vec->al_argv[0] = SHELL;
851 execv(SHELL, &(vec->al_argv[0]));
853 if (access(vec->al_argv[1], 1) == 0) {
854 /* File is executable. */
855 error("cannot execute %s", vec->al_argv[1]);
857 error("%s is not executable", vec->al_argv[1]);