vif.c
1 //! @file vif.c
2 //! @author J. Marcel van der Veer
3 //
4 //! @section Copyright
5 //
6 // This file is part of VIF - vintage FORTRAN compiler.
7 // Copyright 2020-2024 J. Marcel van der Veer <algol68g@xs4all.nl>.
8 //
9 //! @section License
10 //
11 // This program is free software; you can redistribute it and/or modify it
12 // under the terms of the GNU General Public License as published by the
13 // Free Software Foundation; either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful, but
17 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 // more details. You should have received a copy of the GNU General Public
20 // License along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22 //! @section Synopsis
23 //!
24 //! VIF driver.
25
26 #include <vif.h>
27
28 int_4 nglobals = 0;
29 int_4 nlocals = 0;
30 int_4 ncommons = 2; // 0 means local, 1 external
31 int_4 implicit_r8 = FALSE;
32 int_4 f4_do_loops = FALSE;
33 int_4 gcc_ftn_lines = TRUE;
34 int_4 hollerith = FALSE;
35 int_4 syntax_only = FALSE;
36 int_4 no_warnings = FALSE;
37
38 int_4 MAX_FTN_LINES;
39 FTN_LINE *source, *files;
40
41 int_4 MAX_C_SRC;
42 C_SRC *object;
43
44 IDENT globals[MAX_IDENTS];
45 IDENT locals[MAX_IDENTS];
46 char *commons[MAX_COMMONS];
47 IMPLICIT implic[26];
48 LBL labels[MAX_LABELS];
49
50 logical_4 strlens[MAX_STRLENS];
51
52 int_4 compile_only = FALSE;
53 int_4 abend = FALSE;
54 int_4 frequency = FALSE;
55 int_4 load_go = FALSE;
56 int_4 load_go_erase = FALSE;
57 int_4 renum = FALSE;
58 int_4 func;
59 int_4 end_statements;
60 int_4 indent = 0;
61 int_4 line = 0;
62 int_4 n_c_src = 0;
63 int_4 nfiles = 0;
64 int_4 nftnlines = 1;
65 int_4 nglobtmps = 0;
66 int_4 nlabels = 0;
67 int_4 nloctmps = 0;
68 int_4 new_libnam = FALSE;
69 int_4 new_object = FALSE;
70 int_4 pnprocs = -1, nprocs = 0;
71 int_4 page = 0;
72 int_4 pcalls = 0;
73 int_4 prelin, precol;
74 int_4 quiet_mode = FALSE;
75 int_4 trace = FALSE;
76
77 int_4 curlin = 1, curcol = START_OF_LINE;
78 int_4 curret, preret;
79 RECORD prelex, curlex, retnam;
80 RECORD libnam, modnam, procnam;
81 RECORD stat_start;
82 RECORD program, block;
83 RECORD hmodule, hsection;
84 RECORD hdate;
85 RECORD oflags;
86 RECORD object_name;
87
88 int_4 reserved (char *lex)
89 {
90 static char *words[] = {
91 "accept", "assign", "automatic", "call", "character", "close", "common", "complex", "continue",
92 "dimension", "data", "do", "double", "else", "elseif",
93 "end", "enddo", "endif", "entry", "external", "format", "function", "goto",
94 "if", "implicit", "integer", "intrinsic", "logical", "long", "open", "pause", "precision", "print",
95 "procedure", "program", "punch", "read", "real", "repeat", "return", "rewind", "save", "subroutine",
96 "then", "to", "until", "while", "write",
97 NULL
98 };
99 //
100 for (char **sym = words; *sym != NULL; sym++) {
101 if (EQUAL (*sym, lex)) {
102 return TRUE;
103 }
104 }
105 return FALSE;
106 }
107
108 int_4 isint_4 (char *s, int_4 *val)
109 {
110 // Is 's' an integer denotation, and what is its value?
111 char *end;
112 int_4 k = strtol (s, &end, 10);
113 int_4 rc = (end != NULL && end[0] == '\0');
114 if (val != NULL && rc) {
115 *val = k;
116 }
117 return rc;
118 }
119
120 char *date (void)
121 {
122 time_t t;
123 struct tm *info;
124 t = time (NULL);
125 info = localtime (&t);
126 strftime (hdate, RECLN, "%a %d-%b-%Y %H:%M:%S", info);
127 return hdate;
128 }
129
130 char *tod (void)
131 {
132 static RECORD str;
133 time_t t;
134 struct tm *info;
135 t = time (NULL);
136 info = localtime (&t);
137 strftime (str, RECLN, "%H:%M:%S", info);
138 return str;
139 }
140
141 char *stralloc (char *text)
142 {
143 if (text == NULL) {
144 return NULL;
145 } else {
146 int_4 len = strlen (text) + 1;
147 char *new = (char *) f_malloc (len);
148 if (new == NULL) {
149 OVERFLOW (3101, "stralloc");
150 }
151 return strcpy (new, text);
152 }
153 }
154
155 char *strallocat (char *text, char *add)
156 {
157 if (text == NULL) {
158 return stralloc (add);
159 } else {
160 int_4 len = strlen (text) + strlen (add) + 1;
161 char *new = (char *) f_malloc (len);
162 if (new == NULL) {
163 OVERFLOW (3102, "strallocat");
164 }
165 return strcat (strcpy (new, text), add);
166 }
167 }
168
169 void prelude (int_4 argc, char **argv, char *project)
170 {
171 {
172 RECORD usr;
173 if (getlogin_r (usr, RECLN) == 0) {
174 code (0, HEADER, newpage (usr, basename (project)));
175 } else {
176 code (0, HEADER, newpage (VERSION, project));
177 }
178 code (0, HEADER, "\n");
179 if (getlogin_r (usr, RECLN) == 0) {
180 banner (0, BANNER, _strupper (usr));
181 code (0, BANNER, "\n");
182 }
183 banner (0, BANNER, _strupper (basename (project)));
184 code (0, BANNER, "\n");
185 }
186 code (0, CONSTANTS, newpage ("global-scope", "definitions"));
187 code (0, CONSTANTS, "#include <vif.h>\n");
188 code (0, CONSTANTS, "\n");
189 code (0, CONSTANTS, "static int_4 _km1 = -1, _k0 = 0, _k1 = 1;\n");
190 code (0, CONSTANTS, "\n");
191 code (0, COMMON, "\n");
192 code (0, MESSAGES, newpage ("global-scope", "diagnostics"));
193 code (0, TYPEDEF, newpage ("global-scope", "typedefs"));
194 code (0, TYPEDEF, "static FORMAT *__fmt_a = NULL;\n");
195 code (0, PROTOTYPE, newpage ("global-scope", "prototypes"));
196 code (0, FREQ, newpage ("global-scope", "frequency-table"));
197 code (0, FREQ, "#define __ncalls ");
198 pcalls = code (0, FREQ, NULL);
199 code (0, FREQ, "\n");
200 code (0, FREQ, "static CALLS __calls[__ncalls] = {\n");
201 }
202
203 void postlude (void)
204 {
205 RECORD str;
206 code (0, PROTOTYPE, "\n");
207 code (0, FREQ, " {NULL , 0}\n");
208 _srecordf (str, "%d", nprocs + 1);
209 patch (pcalls, str);
210 code (0, FREQ, "};\n");
211 // Write the common blocks.
212 if (ncommons > EXTERN) {
213 code (0, COMMON, newpage ("global-scope", "common-blocks"));
214 code_common ();
215 }
216 // Define character array types encountered.
217 for (int k = 0, len = 2; k < MAX_STRLENS; k++, len *= 2) {
218 if (strlens[k]) {
219 _srecordf (str, "typedef char char_%d[%d];\n", len - 1, len);
220 code (0, TYPEDEF, str);
221 }
222 }
223 // Add an entry procedure.
224 if (! compile_only) {
225 nprocs++;
226 code (nprocs, BODY, newpage ("global-scope", "entry-point"));
227 code (nprocs, BODY, "// Global entry point.\n");
228 code (nprocs, BODY, "int_4 main (int_4 argc, char **argv)\n");
229 code (nprocs, BODY, "{\n");
230 code (nprocs, BODY, "_vif_init ();\n");
231 code (nprocs, BODY, "_ffile[0] = NEW_FTN_FILE (NULL, form_formatted, action_readwrite, 0);\n");
232 _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdin, form_formatted, action_read, MAX_LRECL);\n", STDF_IN);
233 code (nprocs, BODY, str);
234 _srecordf (str, "_ffile[%d].buff = (char *) f_malloc (MAX_LRECL + 1);\n", STDF_IN);
235 code (nprocs, BODY, str);
236 _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdout, form_formatted, action_write, 0);\n", STDF_OUT);
237 code (nprocs, BODY, str);
238 #if STDF_OUT != STDF_PUN
239 _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdout, form_formatted, action_write, 0);\n", STDF_PUN);
240 code (nprocs, BODY, str);
241 #endif
242 _srecordf (str, "_ffile[%d] = NEW_FTN_FILE (stdout, form_formatted, action_write, 0);\n", STDF_ERR);
243 code (nprocs, BODY, str);
244 if (strlen (block) > 0) {
245 RECORD call;
246 RECCLR (call);
247 _srecordf (call, "%s (); // Block data.\n", block);
248 code (nprocs, BODY, call);
249 }
250 if (strlen (program) > 0) {
251 RECORD call;
252 RECCLR (call);
253 _srecordf (call, "%s (); // Fortran entry point.\n", program);
254 code (nprocs, BODY, call);
255 }
256 if (frequency) {
257 code (nprocs, BODY, "_vif_freq (__calls);");
258 }
259 code (nprocs, BODY, "_vif_exit ();\n");
260 code (nprocs, BODY, "return EXIT_SUCCESS;\n");
261 code (nprocs, BODY, "}\n");
262 }
263 }
264
265 static void usage (void)
266 {
267 printf ("Usage: %s [-O][-f][-g][-k][-p][-v] file [, file, ...]\n", PACKAGE);
268 printf ("\n");
269 printf (" -c : Compile as a library.\n");
270 printf (" -d : FORTRAN IV style do loops.\n");
271 printf (" -f : Generate a call frequency table.\n");
272 printf (" -g : Execute upon successful compilation.\n");
273 printf (" -k : Backend compiler reports diagnostics at object code line.\n");
274 printf (" -l : Generate a verbose listing file.\n");
275 printf (" -o name: sets name for object file to `name.c' and for executable to `name'.\n");
276 printf (" -p : Keep the generated code upon successful compilation in pdf format.\n");
277 printf (" -q : Quiet mode.\n");
278 printf (" -r : Renumber FORTRAN source code.\n");
279 printf (" -s : Check syntax only.\n");
280 printf (" -t : Trace mode.\n");
281 printf (" -v : Print the version and exit.\n");
282 printf (" -w : Suppress warning diagnostics.\n");
283 printf (" -W : Set default REAL length to 8 and default COMPLEX length to 16.\n");
284 printf (" -O0 : Do not optimize the object code.\n");
285 printf (" -O : Optimize the object code.\n");
286 printf (" -O1 : Optimize the object code.\n");
287 printf (" -O2 : Optimize the object code.\n");
288 printf (" -O3 : Optimize the object code.\n");
289 printf (" -Of : Optimize the object code.\n");
290 }
291
292 int_4 optimise = 0, keep = FALSE, pretty = FALSE;
293
294 void version (void)
295 {
296 printf ("VIF %s - an experimental VIntage Fortran compiler.\n", VERSION);
297 printf ("Copyright 2020-2024 J.M. van der Veer.\n\n");
298 printf ("Backend compiler : %s\n", BACKEND);
299 printf ("Install directory: %s\n\n", LOCDIR);
300 printf ("This is free software covered by the GNU General Public License.\n");
301 printf ("There is ABSOLUTELY NO WARRANTY for VIF;\n");
302 printf ("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
303 printf ("See the GNU General Public License for more details.\n");
304 }
305
306 #define OPTION(s) EQUAL (opt, (s))
307
308 void option (char *opt)
309 {
310 if (OPTION ("--frequency")) {
311 frequency = TRUE;
312 } else if (OPTION ("--go")) {
313 load_go = TRUE;
314 } else if (OPTION ("--keep")) {
315 keep = TRUE;
316 } else if (OPTION ("--lib")) {
317 new_libnam = TRUE;
318 } else if (OPTION ("--pdf")) {
319 keep = TRUE;
320 pretty = TRUE;
321 } else if (OPTION ("--f4-do-loops")) {
322 f4_do_loops = TRUE;
323 } else if (OPTION ("--renumber")) {
324 renum = TRUE;
325 } else if (OPTION ("--hollerith")) {
326 hollerith = TRUE;
327 } else if (OPTION ("--license")) {
328 version ();
329 exit (EXIT_SUCCESS);
330 } else if (OPTION ("--version")) {
331 version ();
332 exit (EXIT_SUCCESS);
333 } else if (opt[1] == '-' && opt[2] == '\0') {
334 return;
335 } else for (int_4 k = 1; opt[k] != '\0'; k++) {
336 if (opt[k] == 'O') {
337 optimise = 0;
338 if (opt[k + 1] == '0') {
339 _srecordf(oflags, "%s", "-O0 -ggdb");
340 k++;
341 } else if (opt[k + 1] == '1') {
342 _srecordf(oflags, "%s", "-O1");
343 optimise = 1;
344 k++;
345 } else if (opt[k + 1] == '2') {
346 _srecordf(oflags, "%s", "-O2");
347 optimise = 2;
348 k++;
349 } else if (opt[k + 1] == '3') {
350 _srecordf(oflags, "%s", "-funroll-all-loops -O3");
351 optimise = 3;
352 k++;
353 } else if (opt[k + 1] == 'f') {
354 _srecordf(oflags, "%s", "-Ofast");
355 optimise = 4;
356 k++;
357 } else {
358 _srecordf(oflags, "%s", "-O");
359 optimise = 1;
360 }
361 } else if (opt[k] == 'c') {
362 compile_only = TRUE;
363 } else if (opt[k] == 'd') {
364 f4_do_loops = TRUE;
365 } else if (opt[k] == 'f') {
366 frequency = TRUE;
367 } else if (opt[k] == 'g') {
368 load_go = TRUE;
369 } else if (opt[k] == 'k') {
370 gcc_ftn_lines = FALSE;
371 } else if (opt[k] == 'l') {
372 keep = TRUE;
373 } else if (opt[k] == 'o') {
374 new_object = TRUE;
375 } else if (opt[k] == 'p') {
376 keep = TRUE;
377 pretty = TRUE;
378 } else if (opt[k] == 'q') {
379 quiet_mode = TRUE;
380 } else if (opt[k] == 'r') {
381 renum = TRUE;
382 } else if (opt[k] == 's') {
383 syntax_only = TRUE;
384 } else if (opt[k] == 't') {
385 trace = TRUE;
386 } else if (opt[k] == 'v') {
387 version ();
388 exit (EXIT_SUCCESS);
389 } else if (opt[k] == 'w') {
390 no_warnings = TRUE;
391 } else if (opt[k] == 'W') {
392 implicit_r8 = TRUE;
393 } else if (opt[k] == 'x') {
394 load_go = TRUE;
395 load_go_erase = TRUE;
396 } else {
397 usage ();
398 exit (EXIT_FAILURE);
399 }
400 }
401 }
402
403 #undef OPTION
404
405 int_4 main (int_4 argc, char **argv)
406 {
407 int_4 rc = EXIT_SUCCESS, start = 1;
408 RECORD c_file, lst_file;
409 //
410 MAX_FTN_LINES = INCREMENT;
411 MAX_C_SRC = INCREMENT;
412 source = (FTN_LINE *) f_malloc (MAX_FTN_LINES * sizeof (FTN_LINE));
413 object = (C_SRC *) f_malloc (MAX_C_SRC * sizeof (C_SRC));
414 files = (FTN_LINE *) f_malloc (MAX_SOURCE_FILES * sizeof (FTN_LINE));
415 // Options
416 f4_do_loops = FALSE;
417 new_libnam = FALSE;
418 new_object = FALSE;
419 oflags[0] = '\0';
420 RECCLR (libnam);
421 RECCLR (object_name);
422 while (argv[start] != NULL && argv[start][0] == '-') {
423 option (argv[start]);
424 start++;
425 if (new_libnam) {
426 new_libnam = FALSE;
427 if (strlen (libnam) == 0 && argv[start] != NULL) {
428 strcpy (libnam, argv[start]);
429 start++;
430 } else {
431 usage ();
432 exit (EXIT_FAILURE);
433 }
434 } else if (new_object) {
435 new_object = FALSE;
436 if (strlen (object_name) == 0 && argv[start] != NULL) {
437 strcpy (object_name, argv[start]);
438 start++;
439 } else {
440 usage ();
441 exit (EXIT_FAILURE);
442 }
443 }
444 }
445 if (argv[start] == NULL) {
446 usage ();
447 exit (EXIT_FAILURE);
448 }
449 RECCLR (program);
450 RECCLR (block);
451 RECCLR (curlex);
452 RECCLR (prelex);
453 for (int_4 k = 0; k < MAX_STRLENS; k++) {
454 strlens[k] = FALSE;
455 }
456 date ();
457 strcpy (hmodule, "global-scope");
458 strcpy (hsection, "global-section");
459 // Import all sources.
460 RECORD argv_start;
461 _srecordf (argv_start, argv[start]);
462 for (int k = start; k < argc; k++) {
463 get_source (stralloc (argv[k]), 0);
464 }
465 // Name for project derives from first source file.
466 if (strlen (libnam) == 0) {
467 if (new_object) {
468 strcpy (libnam, object_name);
469 } else {
470 strcpy (libnam, argv_start);
471 }
472 for (int k = (int_4) strlen (libnam); k >= 0; k--) {
473 if (libnam[k] == '.') {
474 libnam[k] = '\0';
475 break;
476 }
477 }
478 }
479 // Fill in what we know at the start.
480 prelude (argc, argv, libnam);
481 // Compile all subprograms.
482 nmodules = 0;
483 curlin = 1;
484 curcol = START_OF_LINE;
485 scan_modules ();
486 curlin = 1;
487 curcol = START_OF_LINE;
488 macro_nest = 0;
489 lhs_factor = FALSE;
490 subprograms ();
491 // Fill in what we know afterwards, and write C source.
492 postlude ();
493 // Remove stale files.
494 RECCLR (c_file);
495 strcpy (c_file, libnam);
496 strcat (c_file, ".c");
497 remove (c_file);
498 strcpy (lst_file, libnam);
499 strcat (lst_file, ".l");
500 remove (lst_file);
501 //
502 strcpy (c_file, libnam);
503 if (nerrors == 0) {
504 strcat (c_file, ".c");
505 } else {
506 strcat (c_file, ".l");
507 }
508 write_object (c_file);
509 // Compile intermediate code.
510 if (syntax_only) {
511 RECORD str;
512 _srecordf (str, "** linker ** no object file generated");
513 diagnostic (0, str);
514 if (nerrors == 0) {
515 rc = EXIT_SUCCESS;
516 } else {
517 rc = EXIT_FAILURE;
518 }
519 } else if (renum) {
520 RECORD str;
521 if (nerrors == 0) {
522 _srecordf (str, "** renumber ** fortran file generated");
523 rc = EXIT_SUCCESS;
524 } else {
525 _srecordf (str, "** renumber ** no fortran file generated");
526 rc = EXIT_FAILURE;
527 }
528 diagnostic (0, str);
529 } else if (nerrors != 0) {
530 RECORD str;
531 nerrors++;
532 _srecordf (str, "** linker ** no object file generated");
533 diagnostic (0, str);
534 rc = EXIT_FAILURE;
535 } else {
536 RECORD cmd, str;
537 if (compile_only) {
538 if (optimise > 0) {
539 _srecordf (cmd, "%s %s %s -c %s.c -o %s.o", BACKEND, oflags, CFLAGS, libnam, libnam);
540 } else {
541 _srecordf (cmd, "%s -O0 -ggdb %s -c %s.c -o %s.o", BACKEND, CFLAGS, libnam, libnam);
542 }
543 } else {
544 if (optimise > 0) {
545 #if defined (BOOTSTRAP)
546 _srecordf (cmd, "%s %s %s %s.c -o %s %s", BACKEND, oflags, CFLAGS, libnam, libnam, LD_FLAGS);
547 #else
548 _srecordf (cmd, "%s %s %s %s.c -o %s -L%s %s", BACKEND, oflags, CFLAGS, libnam, libnam, LOCDIR, LD_FLAGS);
549 #endif
550 } else {
551 #if defined (BOOTSTRAP)
552 _srecordf (cmd, "%s -O0 -ggdb %s %s.c -o %s %s", BACKEND, CFLAGS, libnam, libnam, LD_FLAGS);
553 #else
554 _srecordf (cmd, "%s -O0 -ggdb %s %s.c -o %s -L%s %s", BACKEND, CFLAGS, libnam, libnam, LOCDIR, LD_FLAGS);
555 #endif
556 }
557 }
558 if (system (cmd) == EXIT_SUCCESS) {
559 struct stat s;
560 if (compile_only) {
561 RECORD obj;
562 _srecordf (obj, "%s.o", libnam);
563 stat (obj, &s);
564 } else {
565 stat (libnam, &s);
566 }
567 _srecordf (str, "** linker ** object size %ld bytes", s.st_size);
568 diagnostic (0, str);
569 } else {
570 nerrors++;
571 _srecordf (str, "** linker ** no object file generated");
572 diagnostic (0, str);
573 rc = EXIT_FAILURE;
574 }
575 RECORD mov;
576 _srecordf (mov, "mv %s %s", c_file, lst_file);
577 system (mov);
578 }
579 // Wrap it up
580 {
581 RECORD str, sub, err, war;
582 if (nprocs > 0 && ! compile_only) {
583 nprocs--; // discount 'main'
584 }
585 if (nprocs == 0) {
586 _srecordf (sub, "no subprograms");
587 } else if (nprocs == 1) {
588 _srecordf (sub, "1 subprogram");
589 } else {
590 _srecordf (sub, "%d subprograms", nprocs);
591 }
592 if (nerrors == 0) {
593 _srecordf (err, "no errors");
594 } else if (nerrors == 1) {
595 _srecordf (err, "1 error");
596 } else {
597 _srecordf (err, "%d errors", nerrors);
598 }
599 if (nwarns == 0) {
600 _srecordf (war, "no warnings");
601 } else if (nwarns == 1) {
602 _srecordf (war, "1 warning");
603 } else {
604 _srecordf (war, "%d warnings", nwarns);
605 }
606 _srecordf (str, "** statistics ** %s, %s, %s", sub, err, war);
607 diagnostic (0, str);
608 }
609 // Execution.
610 if (!renum && load_go && nerrors == 0 && ! syntax_only) {
611 RECORD cmd;
612 fprintf (stderr, "** execution **\n");
613 if (libnam[0] == '/') {
614 _srecordf (cmd, "%s | tee ft06f000", libnam);
615 } else {
616 _srecordf (cmd, "./%s | tee ft06f000", libnam);
617 }
618 rc = system (cmd);
619 if (!keep) {
620 _srecordf (cmd, "rm -f ./%s ./%s.c ./%s.s", libnam, libnam, libnam);
621 (void) system (cmd);
622 }
623 if (load_go_erase) {
624 if (libnam[0] == '/') {
625 _srecordf (cmd, "rm -f %s", libnam);
626 } else {
627 _srecordf (cmd, "rm -f ./%s", libnam);
628 }
629 (void) system (cmd);
630 }
631 }
632 // Renumber source files.
633 if (renum && nerrors == 0) {
634 for (int k = start; k < argc; k++) {
635 relabel (stralloc (argv[k]));
636 }
637 }
638 // Write C source again with post-compile information.
639 remove (c_file);
640 strcpy (c_file, libnam);
641 if (rc == EXIT_SUCCESS) {
642 strcat (c_file, ".c");
643 } else {
644 strcat (c_file, ".l");
645 }
646 write_object (c_file);
647 // Pretty listing file as PDF.
648 if (keep && pretty) {
649 RECORD cmd;
650 _srecordf (cmd, "command -v enscript > /dev/null && command -v ps2pdf > /dev/null && enscript --quiet --font=Courier-Bold@9 -l -H1 -r --margins=25:25:40:40 -p - %s | ps2pdf - %s.pdf", c_file, libnam);
651 (void) system (cmd);
652 }
653 if (!keep) {
654 RECORD cmd;
655 _srecordf (cmd, "rm -f %s.c %s.s", libnam, libnam);
656 (void) system (cmd);
657 _srecordf (cmd, "rm -f %s.c %s.s", libnam, libnam);
658 (void) system (cmd);
659 }
660 // Exeunt.
661 exit (rc);
662 }
© 2002-2024 J.M. van der Veer (jmvdveer@xs4all.nl)
|