wait.h needs param.h (from jim mckie)
[unix-history] / usr / src / usr.bin / pascal / pc / pc.c
CommitLineData
252367af
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
1552ec8c 13#ifndef lint
89687b99 14static char sccsid[] = "@(#)pc.c 5.3 (Berkeley) %G%";
252367af 15#endif not lint
5838b3c2 16
aa358624
BJ
17#include <stdio.h>
18#include <signal.h>
56c85eb9 19#include <sys/param.h>
89687b99 20#include <sys/wait.h>
aa358624
BJ
21
22/*
4c675422 23 * Pc - front end for Pascal compiler.
aa358624 24 */
5d9fd577
BJ
25char *pc0 = "/usr/lib/pc0";
26char *pc1 = "/lib/f1";
27char *pc2 = "/usr/lib/pc2";
28char *c2 = "/lib/c2";
29char *pc3 = "/usr/lib/pc3";
30char *ld = "/bin/ld";
31char *as = "/bin/as";
aa358624 32char *lpc = "-lpc";
5d9fd577
BJ
33char *crt0 = "/lib/crt0.o";
34char *mcrt0 = "/lib/mcrt0.o";
5838b3c2 35char *gcrt0 = "/usr/lib/gcrt0.o";
aa358624
BJ
36
37char *mktemp();
56c85eb9
PK
38char *tmpdir = "/tmp";
39char tmp0[MAXPATHLEN], tmp1[MAXPATHLEN];
aa358624
BJ
40char *tname[2];
41char *tfile[2];
42
43char *setsuf(), *savestr();
44
56c85eb9 45int Jflag, Sflag, Oflag, Tlflag, cflag, gflag, pflag, wflag, tflag;
aa358624
BJ
46int debug;
47
48#define NARGS 512
49int ldargx = 3;
50int pc0argx = 3;
51char *pc0args[NARGS] = { "pc0", "-o", "XXX" };
52char *pc1args[3] = { "pc1", 0, };
53char *pc2args[2] = { "pc2", 0 };
54char *c2args[4] = { "c2", 0, 0, 0 };
f933d5b5 55int pc3argx = 1;
aa358624
BJ
56#define pc3args pc0args
57#define ldargs pc0args
f933d5b5 58/* char *pc3args[NARGS] = { "pc3", 0 }; */
5d9fd577 59/* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */
56c85eb9
PK
60
61 /* as -J -t tmpdir -o objfile srcfile \0 */
5d9fd577 62int asargx;
56c85eb9 63char *asargs[8] = { "as", 0, };
aa358624 64
7906f7e9
KM
65char *mesg[] = {
66 0,
67 "Hangup",
68 "Interrupt",
69 "Quit",
70 "Illegal instruction",
71 "Trace/BPT trap",
72 "IOT trap",
73 "EMT trap",
74 "Floating exception",
75 "Killed",
76 "Bus error",
77 "Segmentation fault",
78 "Bad system call",
79 "Broken pipe",
80 "Alarm clock",
81 "Terminated",
82 "Signal 16",
83 "Stopped (signal)",
84 "Stopped",
85 "Continued",
86 "Child exited",
87 "Stopped (tty input)",
88 "Stopped (tty output)",
89 "Tty input interrupt",
90 "Cputime limit exceeded",
91 "Filesize limit exceeded",
92 "Signal 26",
93 "Signal 27",
94 "Signal 28",
95 "Signal 29",
96 "Signal 30",
97 "Signal 31",
98 "Signal 32"
99};
100
aa358624
BJ
101/*
102 * If the number of .p arguments (np) is 1, and the number of .o arguments
103 * (nxo) is 0, and we successfully create an ``a.out'', then we remove
104 * the one .ps .o file (onepso).
105 */
106int np, nxo;
107char *onepso;
108int errs;
109
110int onintr();
111
112main(argc, argv)
113 int argc;
114 char **argv;
115{
116 register char *argp;
117 register int i;
118 int savargx;
119 char *t, c;
120 int j;
121
122 argc--, argv++;
123 if (argc == 0) {
124 execl("/bin/cat", "cat", "/usr/lib/how_pc");
125 exit(1);
126 }
127 if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
128 signal(SIGINT, onintr);
129 signal(SIGTERM, onintr);
130 }
131 for (i = 0; i < argc; i++) {
132 argp = argv[i];
133 if (argp[0] != '-')
134 continue;
135 switch (argp[1]) {
136
137 case 'd':
138 if (argp[2] == 0)
139 debug++;
140 continue;
141 case 'i':
142 pc0args[pc0argx++] = "-i";
143 while (i+1 < argc && argv[i+1][0] != '-' &&
144 getsuf(argv[i+1]) != 'p') {
145 pc0args[pc0argx++] = argv[i+1];
146 i++;
147 }
148 if (i+1 == argc) {
149 fprintf(stderr, "pc: bad -i construction\n");
150 exit(1);
151 }
152 continue;
153 case 'o':
154 i++;
155 if (i == argc) {
156 fprintf(stderr, "pc: -o must specify file\n");
157 exit(1);
158 }
159 c = getsuf(argv[i]);
160 if (c == 'o' || c == 'p' || c == 'c') {
161 fprintf(stderr, "pc: -o would overwrite %s\n",
162 argv[i]);
163 exit(1);
164 }
165 continue;
56c85eb9
PK
166 case 't':
167 i++;
168 if (i == argc) {
aa670f3f
PK
169 fprintf(stderr, "pc: -t but no directory\n");
170 exit(1);
171 }
172 if (argp[2] != '\0') {
173 fprintf(stderr, "pc: bad -t option\n");
56c85eb9
PK
174 exit(1);
175 }
176 tmpdir = argv[i];
aa670f3f
PK
177 if (tmpdir[0] == '-') {
178 fprintf(stderr, "pc: bad -t option\n");
179 exit(1);
180 }
56c85eb9
PK
181 tflag = 1;
182 continue;
aa358624
BJ
183 case 'O':
184 Oflag = 1;
185 continue;
186 case 'S':
187 Sflag = 1;
188 continue;
5d9fd577
BJ
189 case 'J':
190 Jflag = 1;
191 continue;
aa358624
BJ
192 case 'T':
193 switch (argp[2]) {
194
195 case '0':
2ee09361 196 pc0 = "/usr/src/ucb/pascal/pc0/a.out";
24730a40
KM
197 if (argp[3] != '\0') {
198 pc0 = &argp[3];
199 }
aa358624
BJ
200 continue;
201 case '1':
0b7c08e3 202 pc1 = "/usr/src/lib/pcc/fort";
24730a40
KM
203 if (argp[3] != '\0') {
204 pc1 = &argp[3];
205 }
aa358624
BJ
206 continue;
207 case '2':
2ee09361 208 pc2 = "/usr/src/ucb/pascal/utilities/pc2";
24730a40
KM
209 if (argp[3] != '\0') {
210 pc2 = &argp[3];
211 }
aa358624
BJ
212 continue;
213 case '3':
2ee09361 214 pc3 = "/usr/src/ucb/pascal/utilities/pc3";
24730a40
KM
215 if (argp[3] != '\0') {
216 pc3 = &argp[3];
217 }
aa358624
BJ
218 continue;
219 case 'l':
5838b3c2 220 Tlflag = 1;
0b7c08e3 221 lpc = "/usr/src/usr.lib/libpc/libpc";
24730a40
KM
222 if (argp[3] != '\0') {
223 lpc = &argp[3];
224 }
aa358624
BJ
225 continue;
226 }
227 continue;
228 case 'c':
229 cflag = 1;
230 continue;
231 case 'l':
232 if (argp[2])
233 continue;
234 /* fall into ... */
235 case 'b':
aa358624 236 case 's':
aa358624
BJ
237 case 'z':
238 case 'C':
239 pc0args[pc0argx++] = argp;
f933d5b5
KM
240 continue;
241 case 'w':
242 wflag = 1;
243 pc0args[pc0argx++] = argp;
244 continue;
245 case 'g':
246 gflag = 1;
247 pc0args[pc0argx++] = argp;
aa358624 248 continue;
aa358624 249 case 'p':
5838b3c2
KM
250 if (argp[2] == 'g')
251 crt0 = gcrt0;
252 else
253 crt0 = mcrt0;
254 if (!Tlflag)
255 lpc = "-lpc_p";
256 pflag = 1;
4c675422 257 continue;
aa358624
BJ
258 }
259 }
260 if (gflag && Oflag) {
261 fprintf(stderr, "pc: warning: -g overrides -O\n");
262 Oflag = 0;
263 }
56c85eb9
PK
264 sprintf(tmp0, "%s/%s", tmpdir, "p0XXXXXX");
265 tname[0] = mktemp(tmp0);
266 sprintf(tmp1, "%s/%s", tmpdir, "p1XXXXXX");
267 tname[1] = mktemp(tmp1);
aa358624
BJ
268 savargx = pc0argx;
269 for (i = 0; i < argc; i++) {
270 argp = argv[i];
271 if (argp[0] == '-')
272 continue;
7c57a955
PK
273 if (suffix(argp) == 's') {
274 asargx = 1;
275 if (Jflag)
276 asargs[asargx++] = "-J";
9bf93e51 277# if defined(vax) || defined(tahoe)
56c85eb9
PK
278 if (tflag) {
279 asargs[asargx++] = "-t";
280 asargs[asargx++] = tmpdir;
281 }
9bf93e51 282# endif vax || tahoe
7c57a955
PK
283 asargs[asargx++] = argp;
284 asargs[asargx++] = "-o";
285 tfile[1] = setsuf(argp, 'o');
286 asargs[asargx++] = tfile[1];
287 asargs[asargx] = 0;
288 if (dosys(as, asargs, 0, 0))
289 continue;
290 tfile[1] = 0;
291 continue;
292 }
aa358624
BJ
293 if (suffix(argp) != 'p')
294 continue;
295 tfile[0] = tname[0];
296 pc0args[2] = tfile[0];
297 pc0argx = savargx;
4c675422
BJ
298 if (pflag)
299 pc0args[pc0argx++] = "-p";
84345867
KM
300 if (Jflag)
301 pc0args[pc0argx++] = "-J";
aa358624
BJ
302 pc0args[pc0argx++] = argp;
303 pc0args[pc0argx] = 0;
304 if (dosys(pc0, pc0args, 0, 0))
305 continue;
306 pc1args[1] = tfile[0];
4c675422 307 tfile[1] = tname[1];
aa358624
BJ
308 if (dosys(pc1, pc1args, 0, tfile[1]))
309 continue;
310 unlink(tfile[0]);
6e4fa11e
KM
311 tfile[0] = tname[0];
312 if (Oflag) {
313 if (dosys(c2, c2args, tfile[1], tfile[0]))
314 continue;
315 unlink(tfile[1]);
316 tfile[1] = tfile[0];
317 tfile[0] = tname[1];
318 }
319 if (Sflag)
4c675422 320 tfile[0] = setsuf(argp, 's');
aa358624
BJ
321 if (dosys(pc2, pc2args, tfile[1], tfile[0]))
322 continue;
323 unlink(tfile[1]);
324 tfile[1] = 0;
4c675422
BJ
325 if (Sflag) {
326 tfile[0] = 0;
aa358624 327 continue;
4c675422 328 }
5d9fd577
BJ
329 asargx = 1;
330 if (Jflag)
331 asargs[asargx++] = "-J";
9bf93e51 332# if defined(vax) || defined(tahoe)
56c85eb9
PK
333 if (tflag) {
334 asargs[asargx++] = "-t";
335 asargs[asargx++] = tmpdir;
336 }
9bf93e51 337# endif vax || tahoe
5d9fd577
BJ
338 asargs[asargx++] = tfile[0];
339 asargs[asargx++] = "-o";
aa358624 340 tfile[1] = setsuf(argp, 'o');
5d9fd577
BJ
341 asargs[asargx++] = tfile[1];
342 asargs[asargx] = 0;
aa358624
BJ
343 if (dosys(as, asargs, 0, 0))
344 continue;
345 tfile[1] = 0;
346 remove();
347 }
348 if (errs || cflag || Sflag)
349 done();
f933d5b5 350/* char *pc3args[NARGS] = { "pc3", 0 }; */
aa358624 351 pc3args[0] = "pc3";
f933d5b5
KM
352 if (wflag)
353 pc3args[pc3argx++] = "-w";
354 pc3args[pc3argx++] = "/usr/lib/pcexterns.o";
aa358624
BJ
355 for (i = 0; i < argc; i++) {
356 argp = argv[i];
357 if (!strcmp(argp, "-o"))
358 i++;
359 if (argp[0] == '-')
360 continue;
361 switch (getsuf(argp)) {
362
aa358624
BJ
363 case 'o':
364 pc3args[pc3argx++] = argp;
365 nxo++;
366 continue;
7c57a955 367 case 's':
aa358624
BJ
368 case 'p':
369 onepso = pc3args[pc3argx++] =
370 savestr(setsuf(argp, 'o'));
371 np++;
372 continue;
373 }
374 }
375 pc3args[pc3argx] = 0;
f933d5b5 376 if (dosys(pc3, pc3args, 0, 0) > 1)
aa358624 377 done();
c56822d4 378 errs = 0;
5d9fd577 379/* char *ldargs[NARGS] = { "ld", "-X", "/lib/crt0.o", 0, }; */
aa358624
BJ
380 ldargs[0] = "ld";
381 ldargs[1] = "-X";
4c675422 382 ldargs[2] = crt0;
aa358624
BJ
383 for (i = 0; i < argc; i++) {
384 argp = argv[i];
385 if (argp[0] != '-') {
386 switch (getsuf(argp)) {
387
388 case 'p':
7c57a955 389 case 's':
aa358624
BJ
390 ldargs[ldargx] = savestr(setsuf(argp, 'o'));
391 break;
392 default:
393 ldargs[ldargx] = argp;
394 break;
395 }
396 if (getsuf(ldargs[ldargx]) == 'o')
397 for (j = 0; j < ldargx; j++)
398 if (!strcmp(ldargs[j], ldargs[ldargx]))
399 goto duplicate;
400 ldargx++;
401duplicate:
402 continue;
403 }
404 switch (argp[1]) {
405
406 case 'i':
407 while (i+1 < argc && argv[i+1][0] != '-' &&
408 getsuf(argv[i+1]) != 'p')
409 i++;
410 continue;
411 case 'd':
412 if (argp[2] == 0)
413 continue;
414 ldargs[ldargx++] = argp;
415 continue;
416 case 'o':
417 ldargs[ldargx++] = argp;
418 i++;
419 ldargs[ldargx++] = argv[i];
420 continue;
421 case 'l':
422 if (argp[2])
423 ldargs[ldargx++] = argp;
424 continue;
56c85eb9
PK
425 case 't':
426 i++;
427 continue;
aa358624
BJ
428 case 'c':
429 case 'g':
430 case 'w':
431 case 'p':
432 case 'S':
5d9fd577 433 case 'J':
aa358624
BJ
434 case 'T':
435 case 'O':
436 case 'C':
437 case 'b':
438 case 's':
439 case 'z':
440 continue;
441 default:
442 ldargs[ldargx++] = argp;
443 continue;
444 }
445 }
446 ldargs[ldargx++] = lpc;
447 if (gflag)
448 ldargs[ldargx++] = "-lg";
5838b3c2
KM
449 if (pflag) {
450 ldargs[ldargx++] = "-lm_p";
451 ldargs[ldargx++] = "-lc_p";
452 } else {
453 ldargs[ldargx++] = "-lm";
454 ldargs[ldargx++] = "-lc";
455 }
aa358624
BJ
456 ldargs[ldargx] = 0;
457 if (dosys(ld, ldargs, 0, 0)==0 && np == 1 && nxo == 0)
458 unlink(onepso);
459 done();
460}
461
462dosys(cmd, argv, in, out)
463 char *cmd, **argv, *in, *out;
464{
465 union wait status;
466 int pid;
467
468 if (debug) {
469 int i;
470 printf("%s:", cmd);
471 for (i = 0; argv[i]; i++)
472 printf(" %s", argv[i]);
473 if (in)
474 printf(" <%s", in);
475 if (out)
476 printf(" >%s", out);
477 printf("\n");
478 }
924c1760
PA
479 /*
480 * warning: vfork doesn't work here, because the call to signal()
481 * done by the child process destroys the parent's SIGINT handler.
482 */
483 pid = fork();
aa358624
BJ
484 if (pid < 0) {
485 fprintf(stderr, "pc: No more processes\n");
486 done();
487 }
488 if (pid == 0) {
489 if (in) {
490 close(0);
491 if (open(in, 0) != 0) {
492 perror(in);
493 exit(1);
494 }
495 }
496 if (out) {
497 close(1);
498 unlink(out);
499 if (creat(out, 0666) != 1) {
500 perror(out);
501 exit(1);
502 }
503 }
504 signal(SIGINT, SIG_DFL);
505 execv(cmd, argv);
506 perror(cmd);
507 exit(1);
508 }
509 while (wait(&status) != pid)
510 ;
511 if (WIFSIGNALED(status)) {
7906f7e9
KM
512 if (status.w_termsig != SIGINT) {
513 fprintf(stderr, "%s: %s", cmd, mesg[status.w_termsig]);
514 if (status.w_coredump)
515 fprintf(stderr, " (core dumped)");
516 fprintf(stderr, "\n");
517 }
aa358624
BJ
518 errs = 100;
519 done();
520 /*NOTREACHED*/
521 }
522 if (status.w_retcode) {
523 errs = 1;
524 remove();
525 }
526 return (status.w_retcode);
527}
528
529done()
530{
531
532 remove();
533 exit(errs);
534}
535
536remove()
537{
538
539 if (tfile[0])
540 unlink(tfile[0]);
541 if (tfile[1])
542 unlink(tfile[1]);
543}
544
545onintr()
546{
547
548 errs = 1;
549 done();
550}
551
552getsuf(cp)
553 char *cp;
554{
555
556 if (*cp == 0)
557 return;
558 while (cp[1])
559 cp++;
560 if (cp[-1] != '.')
561 return (0);
562 return (*cp);
563}
564
aa358624 565char *
4c675422
BJ
566setsuf(as, ch)
567 char *as;
aa358624 568{
4c675422
BJ
569 register char *s, *s1;
570
571 s = s1 = savestr(as);
572 while (*s)
573 if (*s++ == '/')
574 s1 = s;
575 s[-1] = ch;
576 return (s1);
aa358624
BJ
577}
578
579#define NSAVETAB 512
580char *savetab;
581int saveleft;
582
583char *
584savestr(cp)
585 register char *cp;
586{
587 register int len;
588
589 len = strlen(cp) + 1;
590 if (len > saveleft) {
591 saveleft = NSAVETAB;
592 if (len > saveleft)
593 saveleft = len;
594 savetab = (char *)malloc(saveleft);
595 if (savetab == 0) {
596 fprintf(stderr, "ran out of memory (savestr)\n");
597 exit(1);
598 }
599 }
600 strncpy(savetab, cp, len);
601 cp = savetab;
602 savetab += len;
603 return (cp);
604}
605
606suffix(cp)
607 char *cp;
608{
609
610 if (cp[0] == 0 || cp[1] == 0)
611 return (0);
612 while (cp[1])
613 cp++;
614 if (cp[-1] == '.')
615 return (*cp);
616 return (0);
617}