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