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