Bug Summary

File:src/emit.c
Warning:line 526, column 2
Value stored to 'stype' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name emit.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c emit.c
1/*****************************************************************************
2 *
3 * emit.c: Compiler output.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "ccode.h"
10#include "ccomp.h"
11#include "compcfg.h"
12#include "comsg.h"
13#include "emit.h"
14#include "file.h"
15#include "fint.h"
16#include "format.h"
17#include "genlisp.h"
18#include "include.h"
19#include "lib.h"
20#include "opsys.h"
21#include "sexpr.h"
22#include "stab.h"
23#include "store.h"
24#include "util.h"
25#include "java/genjava.h"
26#include "java/javacode.h"
27#include "java/javaobj.h"
28
29/****************************************************************************
30 *
31 * :: Controlling options
32 *
33 **************************************************************************/
34
35static String emitCName = NULL((void*)0);
36
37static String emitEntryFile = NULL((void*)0);
38static String emitOutputDir = NULL((void*)0);
39static FileName emitOutputFileName[FTYPENO_LIMIT];
40static String emitFileIdName = NULL((void*)0);
41static String emitFileIdPrefix = NULL((void*)0);
42
43static Bool emitSolo = false((int) 0);
44static Bool emitDoLineNos = false((int) 0);
45static Bool emitDoRun = false((int) 0);
46static Bool emitDoInterp = false((int) 0);
47
48static Bool emitDo [FTYPENO_LIMIT];
49static Bool emitDone[FTYPENO_LIMIT];
50static Bool emitNeed[FTYPENO_LIMIT];
51static Bool emitKeep[FTYPENO_LIMIT];
52
53static Bool emitWantDep;
54
55#define emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)) (emitDoLineNos ? SXRW_SrcPos(1L<<2) : SXRW_NoSrcPos(1L<<3))
56
57void
58emitSetDependsWanted(Bool flag)
59{
60 emitWantDep = flag;
61}
62
63int
64emitDependsWanted()
65{
66 return emitWantDep;
67}
68
69/*
70 * Select the file types to be emitted.
71 * Return 0 on success, -1 on failure.
72 */
73int
74emitSelect(String arg)
75{
76 static Bool isInit = false((int) 0);
77 int ftn, rc;
78 String argbuf, ft, fn;
79 Bool fileNameSupplied = false((int) 0);
80
81 if (!isInit) {
82 int i;
83 for (i = 0; i < FTYPENO_LIMIT; i++) {
84 emitDo [i] = false((int) 0);
85 emitDone[i] = false((int) 0);
86 emitOutputFileName[i] = 0;
87 }
88 isInit = true1;
89 }
90
91 /* Parse <ft>=<fn> */
92 argbuf = strCopy(arg);
93 for (fn = ft = argbuf; *fn; fn++)
94 if (*fn == '=' || *fn == ':') {
95 *fn++ = 0;
96 fileNameSupplied = true1;
97 break;
98 }
99
100 if (fileNameSupplied && strLength(fn) == 0) {
101 comsgFatal(NULL((void*)0), ALDOR_F_EmitNoFileSupplied274, ft);
102 }
103
104 if (ftypeIs(ft,FTYPENO_INCLUDED)) ftn = FTYPENO_INCLUDED;
105 else if (ftypeIs(ft,FTYPENO_ABSYN)) ftn = FTYPENO_ABSYN;
106 else if (ftypeIs(ft,FTYPENO_OLDABSYN)) {
107 comsgWarning(NULL((void*)0), ALDOR_W_OldOptAbsyn39);
108 ftn = FTYPENO_OLDABSYN;
109 }
110 else if (ftypeIs(ft,FTYPENO_INTERMED)) ftn = FTYPENO_INTERMED;
111 else if (ftypeIs(ft,FTYPENO_FOAMEXPR)) ftn = FTYPENO_FOAMEXPR;
112 else if (ftypeIs(ft,FTYPENO_SYMEEXPR)) ftn = FTYPENO_SYMEEXPR;
113 else if (ftypeIs(ft,FTYPENO_ANNABS)) ftn = FTYPENO_ANNABS;
114
115 else if (ftypeEqual(ft, "lsp")) ftn = FTYPENO_LISP;
116 else if (ftypeEqual(ft, "java")) ftn = FTYPENO_JAVA;
117 else if (ftypeEqual(ft, "c")) ftn = FTYPENO_C;
118 else if (ftypeEqual(ft, "c++")) ftn = FTYPENO_CPP;
119 else if (ftypeEqual(ft, "o")) ftn = FTYPENO_OBJECT;
120 else if (ftypeEqual(ft, "x")) ftn = FTYPENO_EXEC;
121 else if (ftypeEqual(ft, "axlmain")) {
122 comsgWarning(NULL((void*)0), ALDOR_W_OldOptMain38);
123 ftn = FTYPENO_AXLMAINC;
124 }
125 else if (ftypeEqual(ft, "main")) ftn = FTYPENO_AXLMAINC;
126 else ftn = FTYPENO_LIMIT;
127
128
129 if (ftn == FTYPENO_LIMIT) {
130 rc = -1;
131 }
132 else {
133 rc = 0;
134 emitDo[ftn] = true1;
135 if (*fn) emitSetOutputFile(ftn, fn);
136 }
137
138 strFree(argbuf);
139
140 return rc;
141}
142
143void
144emitAllDone()
145{
146 int i;
147 for (i = 0; i < FTYPENO_LIMIT; i += 1)
148 emitDone[i] = true1;
149}
150
151void
152emitSetDone(int i)
153{
154 emitDone[i] = true1;
155}
156
157int
158emitSetOutputDir(String dir)
159{
160 if (!osDirIsThere(dir)) return -1;
161 emitOutputDir = dir;
162 return 0;
163}
164
165void
166emitSetCName(String str)
167{
168 emitCName = str;
169}
170
171int
172emitSetOutputFile(FTypeNo ftno, String fname)
173{
174 if (emitOutputFileName[ftno]) fnameFree(emitOutputFileName[ftno]);
175 emitOutputFileName[ftno] = fnameParse(fname);
176 return 0;
177}
178
179void
180emitSetEntryFile(String fname)
181{
182 emitEntryFile = fname;
183}
184
185String
186emitGetEntryFile(void)
187{
188 return emitEntryFile;
189}
190
191void
192emitSetDebug(Bool wantDebug)
193{
194 emitDoLineNos = wantDebug;
195 ccSetDebug(wantDebug);
196}
197
198void
199emitSetProfile(Bool wantProfile)
200{
201 ccSetProfile(wantProfile);
202}
203
204void
205emitSetRun(Bool flag)
206{
207 emitDoRun = flag;
208}
209
210void
211emitSetInterp(Bool flag)
212{
213 emitDoInterp = flag;
214}
215
216Bool
217emitIsEntry(EmitInfo finfo)
218{
219 FileName srcfn = emitSrcFile(finfo);
220
221 if (finfo->isAXLmain) return false((int) 0);
222
223 return emitEntryFile && strEqual(fnameName(srcfn)((srcfn)->partv[1]), emitEntryFile);
224}
225
226String
227emitEntryFileName(void)
228{
229 return emitEntryFile;
230}
231
232void
233emitSetFileIdName(String name)
234{
235 emitFileIdName = name;
236}
237
238void
239emitSetFileIdPrefix(String name)
240{
241 emitFileIdPrefix = name;
242}
243
244void
245emitDoneOptions(int argc, String *argv)
246{
247 int i;
248 FileName fn;
249
250 for (i = 0; i < FTYPENO_LIMIT; i++) {
251 emitKeep[i] = emitDo[i];
252 emitNeed[i] = emitDo[i];
253 }
254
255 /* If none of -[gF] are given, assume -Fao. */
256 emitNeed[FTYPENO_INTERMED] = emitKeep[FTYPENO_INTERMED] |=
257 !(emitDo[FTYPENO_INCLUDED] || emitDo[FTYPENO_CPP] ||
258 emitDo[FTYPENO_ABSYN] || emitDo[FTYPENO_OLDABSYN] ||
259 emitDo[FTYPENO_FOAMEXPR] || emitDo[FTYPENO_SYMEEXPR] ||
260 emitDo[FTYPENO_LISP] || emitDo[FTYPENO_C] ||
261 emitDo[FTYPENO_OBJECT] || emitDo[FTYPENO_EXEC] ||
262 emitDo[FTYPENO_AXLMAINC] || emitDo[FTYPENO_JAVA] ||
263 emitDoRun || emitDoInterp);
264
265 emitNeed[FTYPENO_INTERMED] |= emitDoInterp;
266
267 if (emitDoInterp) {
268 int i;
269
270 for (i = 0; i < argc; i++) {
271 fn = fnameParse(argv[i]);
272
273 if (ftypeHas(fn,FTYPENO_INTERMED)) {
274 emitKeep[FTYPENO_INTERMED] = true1;
275 emitNeed[FTYPENO_INTERMED] = false((int) 0);
276 }
277
278 fnameFree(fn);
279 }
280 }
281
282 /* Certain file types imply prerequisites. */
283 emitNeed[FTYPENO_C] |=
284 emitDo[FTYPENO_OBJECT] || emitDo[FTYPENO_EXEC] ||
285 emitDoRun;
286
287 emitNeed[FTYPENO_OBJECT] |=
288 emitDo[FTYPENO_EXEC] || emitDoRun;
289
290 emitNeed[FTYPENO_AXLMAINC] |=
291 emitDo[FTYPENO_EXEC] || emitDoRun;
292
293 emitNeed[FTYPENO_EXEC] |=
294 emitDoRun;
295
296
297 /* Set entry file and output directory. */
298 if (!emitEntryFile && argc > 0) {
299 FileName firstFn = fnameParse(argv[0]);
300 emitSetEntryFile(strCopy(fnameName(firstFn)((firstFn)->partv[1])));
301 fnameFree(firstFn);
302 }
303 if (!emitOutputDir)
304 emitOutputDir = osCurDirName();
305
306 emitSolo = argc == 1;
307}
308
309
310/******************************************************************************
311 *
312 * :: File information structure
313 *
314 *****************************************************************************/
315
316# define emitInfoFnameTempV(fi)((fi)->fnameTempV) ((fi)->fnameTempV)
317# define emitInfoFnameTemp(fi,i)((fi)->fnameTempV[i]) ((fi)->fnameTempV[i])
318# define emitInfoFname(fi, ft)((fi)->fname[ft]) ((fi)->fname[ft])
319# define emitInfoInUse(fi, ft)((fi)->inUse[ft]) ((fi)->inUse[ft])
320# define emitInfoIsAXLmain(fi)((fi)->isAXLmain) ((fi)->isAXLmain)
321# define emitInfoIsStdIn(fi)((fi)->isStdIn) ((fi)->isStdIn)
322
323EmitInfo
324emitInfoNew(FileName srcfn)
325{
326 static int ftv[] = {FTYPENO_INCLUDED, FTYPENO_ABSYN,
327 FTYPENO_OLDABSYN, FTYPENO_INTERMED,
328 FTYPENO_FOAMEXPR, FTYPENO_SYMEEXPR,
329 FTYPENO_LISP, -1};
330 EmitInfo finfo;
331 String dir, name, type;
332 int i;
333
334 finfo = (EmitInfo) stoAlloc((unsigned) OB_Other0, sizeof(*finfo));
335 finfo->flist = listNil(FileName)((FileNameList) 0);
336 emitInfoFnameTempV(finfo)((finfo)->fnameTempV) = NULL((void*)0);
337
338 for (i = 0; i < FTYPENO_LIMIT; i++) {
339 emitInfoFname(finfo, i)((finfo)->fname[i]) = NULL((void*)0);
340 emitInfoInUse(finfo, i)((finfo)->inUse[i]) = false((int) 0);
341 }
342 emitInfoIsAXLmain(finfo)((finfo)->isAXLmain) = false((int) 0);
343 emitInfoFname(finfo, FTYPENO_SRC)((finfo)->fname[FTYPENO_SRC]) = fnameCopy(srcfn);
344
345 dir = emitOutputDir;
346 name = fnameName(srcfn)((srcfn)->partv[1]);
347 for (i = 0; ftv[i] >= 0; i++) {
348 type = ftypeString(ftv[i]);
349 emitInfoFname(finfo, ftv[i])((finfo)->fname[ftv[i]]) = fnameNew(dir, name, type);
350 }
351
352 finfo->isStdIn = (fnameIsStdin(srcfn));
353
354 /*
355 * The temp file name vector and the other file names are filled in
356 * on demand by emitFileName since we want a test whether a file
357 * already exists to be as close to generating the file as possible.
358 * Also, we don't want a lock file to be generated when we don't
359 * need temp files since the lock files would be left over when
360 * running axiomxl inside a debugger and aborting the debugger.
361 */
362
363 return finfo;
364}
365
366EmitInfo
367emitInfoNewAXLmain(void)
368{
369 String axlmainName = strConcat(emitEntryFile, "-aldormain");
370 FileName srcfn = fnameNew(emitOutputDir, axlmainName, ".c");
371 EmitInfo finfo = emitInfoNew(srcfn);
372 strFree(axlmainName);
373
374 emitInfoIsAXLmain(finfo)((finfo)->isAXLmain) = true1;
375
376/*
377 emitFileName(finfo, FTYPENO_C);
378 emitFileName(finfo, FTYPENO_OBJECT);
379*/
380
381 fnameFree(srcfn);
382
383 return finfo;
384}
385
386void
387emitInfoShow(EmitInfo finfo)
388{
389 int i;
390 FILE *fout = osStdout;
391
392 fprintf(fout, "<<");
393 if (emitInfoIsAXLmain(finfo)((finfo)->isAXLmain)) fprintf(fout, "[aldormain]");
394 for (i = 0; i < FTYPENO_LIMIT; i++) {
395 if (!finfo->fname[i] && !finfo->inUse[i]) continue;
396
397 fprintf(fout, "| .%s ", ftypeString(i));
398 if (finfo->inUse[i])
399 fprintf(fout, " ** IN USE ** ");
400 if (finfo->fname[i])
401 fprintf(fout, "\"%s\"",
402 fnameUnparseStatic(finfo->fname[i]));
403 }
404 if (finfo->fnameTempV) {
405 fprintf(fout, "| TEMP => ");
406 for (i = 0; finfo->fnameTempV[i]; i++)
407 fprintf(fout, " \"%s\"",
408 fnameUnparseStatic(finfo->fnameTempV[i]));
409 }
410 fprintf(fout, ">>\n");
411}
412
413void
414emitInfoFree(EmitInfo finfo)
415{
416 int i;
417
418 if (!finfo) return;
419
420 if (emitInfoFnameTempV(finfo)((finfo)->fnameTempV)) {
421 for (i = 0; emitInfoFnameTemp(finfo, i)((finfo)->fnameTempV[i]); i++) {
422 FileName fn = emitInfoFnameTemp(finfo, i)((finfo)->fnameTempV[i]);
423 if (ftypeNo(fnameType(fn)((fn)->partv[2])) == FTYPENO_LOCK)
424 fileRemove(fn);
425 fnameFree(fn);
426 }
427 stoFree((Pointer) emitInfoFnameTempV(finfo)((finfo)->fnameTempV));
428 }
429 for (i = 0; i < FTYPENO_LIMIT; i++) {
430 FileName fn = emitInfoFname(finfo, i)((finfo)->fname[i]);
431
432 if (!fn) continue;
433
434 /* Warn if we couldn't do what was needed. */
435 if (emitIsOutputNeeded(finfo, i) && !emitDone[i])
436 comsgWarning(NULL((void*)0), ALDOR_W_NotCreatingFile266,
437 fnameUnparse(fn));
438
439 fnameFree(fn);
440 }
441 listFree(FileName)(FileName_listPointer->Free)(finfo->flist);
442 stoFree((Pointer) finfo);
443}
444
445/*****************************************************************************
446 *
447 * :: File names to use.
448 *
449 *****************************************************************************/
450
451
452FileName
453emitSrcFile(EmitInfo finfo)
454{
455 return finfo->fname[FTYPENO_SRC];
456}
457
458String
459emitGetFileIdName(EmitInfo finfo)
460{
461 String name;
462
463 if (emitFileIdName)
464 return emitFileIdName;
465
466 name = fnameName(emitSrcFile(finfo))((emitSrcFile(finfo))->partv[1]);
467 if (emitFileIdPrefix)
468 name = strConcat(emitFileIdPrefix, name);
469
470 return strCopy(name);
471}
472
473localstatic void
474emitFnameTempAndLock(EmitInfo finfo, String dir, String name)
475{
476 FileName * fntv;
477 int i;
478
479 static String * emitTFTypes = 0; /* Vector of temp file types. */
480
481 if (!emitTFTypes) {
482 emitTFTypes = (String *) stoAlloc((unsigned) OB_Other0,
483 5 * sizeof(String));
484 emitTFTypes[0] = FTYPE_LOCK"ask";
485 emitTFTypes[1] = FTYPE_C"c";
486 emitTFTypes[2] = FTYPE_OBJECTosObjectFileType;
487 emitTFTypes[3] = FTYPE_EXECosExecFileType;
488 emitTFTypes[4] = NULL((void*)0);
489 }
490
491 /*
492 * Let's hope nobody grabs the same temp file names between
493 * calling fnameTempVector and creating the lock file.
494 */
495 fntv = fnameTempVector(dir, name, emitTFTypes);
496 if (!fntv)
497 comsgFatal(NULL((void*)0), ALDOR_F_CantFindTemp360);
498 else {
499 for (i = 0; fntv[i]; i++)
500 if (ftypeNo(fnameType(fntv[i])((fntv[i])->partv[2])) == FTYPENO_LOCK) break;
501 fclose(fileWrOpen(fntv[i])fileMustOpen(fntv[i],osIoWrMode));
502 }
503
504 emitInfoFnameTempV(finfo)((finfo)->fnameTempV) = fntv;
505}
506
507FileName
508emitFileName(EmitInfo finfo, FTypeNo ft)
509{
510 FileName srcfn, fn, fnt;
511 String dir, type, name, stype;
512 Bool tempFileNeeded, chk;
513 FTypeNo fto = ft;
514 int i;
515
516 if (emitOutputFileName[ft])
517 return emitOutputFileName[ft];
518
519 if (emitInfoFname(finfo, ft)((finfo)->fname[ft]))
520 return emitInfoFname(finfo, ft)((finfo)->fname[ft]);
521
522 srcfn = emitSrcFile(finfo);
523 dir = emitOutputDir;
524 name = fnameName(srcfn)((srcfn)->partv[1]);
525 type = ftypeString(ft);
526 stype = fnameType(srcfn)((srcfn)->partv[2]);
Value stored to 'stype' is never read
527
528 fn = fnameNew(dir, name, type);
529
530 /*
531 * Since some C compilers don't honor the `-o' flag when
532 * generating an object file, we need to have the following
533 * complicated logic to find out whether we need a temp file.
534 *
535 * An object file that's created by somebody else while we
536 * work on the C file might get clobbered.
537 */
538
539 tempFileNeeded = emitIsOutputNeeded(finfo, ft) &&
540 !emitKeep[ft] && fileIsThere(fn);
541
542 chk = tempFileNeeded;
543 if (ft == FTYPENO_AXLMAINC)
544 ft = FTYPENO_C;
545 if (ft == FTYPENO_C) {
546 fnt = fnameNew(dir, name, ftypeString(FTYPENO_OBJECT));
547 tempFileNeeded |= (emitNeed[FTYPENO_OBJECT]
548 && !emitKeep[FTYPENO_OBJECT]
549 && fileIsThere(fnt));
550 fnameFree(fnt);
551 }
552 else if (ft == FTYPENO_OBJECT) {
553 /*
554 * Compute the C file name recursively if we don't have
555 * one yet so we know whether we need a temp object file.
556 */
557 fnt = emitFileName(finfo, FTYPENO_C);
558 tempFileNeeded = !strEqual(name, fnameName(fnt)((fnt)->partv[1]));
559 }
560
561 if (tempFileNeeded) {
562 if (chk && !fnameEqual(srcfn,fn) && emitIsGeneratedFile(fn)) {
563 String file = fnameUnparse(fn);
564 comsgWarning(NULL((void*)0), ALDOR_W_WillObsolete264, file);
565 strFree(file);
566 }
567 fnameFree(fn);
568 if (!emitInfoFnameTempV(finfo)((finfo)->fnameTempV))
569 emitFnameTempAndLock(finfo, dir, name);
570 /* Find the temporary file name for the given file type. */
571 for (i = 0; emitInfoFnameTemp(finfo, i)((finfo)->fnameTempV[i]); i++)
572 if (ftypeEqual(fnameType(emitInfoFnameTemp(finfo, i))((((finfo)->fnameTempV[i]))->partv[2]),
573 ftypeString(ft)))
574 break;
575 assert(emitInfoFnameTemp(finfo,i))do { if (!(((finfo)->fnameTempV[i]))) _do_assert(("emitInfoFnameTemp(finfo,i)"
),"emit.c",575); } while (0)
;
576 fn = fnameCopy(emitInfoFnameTemp(finfo, i)((finfo)->fnameTempV[i]));
577 }
578 emitInfoFname(finfo, ft)((finfo)->fname[ft]) = fn;
579 if (ft != fto) emitInfoFname(finfo, fto)((finfo)->fname[fto]) = fnameCopy(fn);
580
581 return fn;
582}
583
584
585Bool
586emitIsOutputNeeded(EmitInfo finfo, FTypeNo ft)
587{
588 Bool need = emitNeed[ft];
589
590 if (finfo && emitInfoIsStdIn(finfo)((finfo)->isStdIn))
591 need = false((int) 0);
592
593 if (finfo && emitInfoIsAXLmain(finfo)((finfo)->isAXLmain))
594 need = need && emitNeed[FTYPENO_AXLMAINC];
595
596 return need;
597}
598
599Bool
600emitIsOutputNeededOrWarn(EmitInfo finfo, FTypeNo ft)
601{
602 FileName srcfn, fn;
603 String name;
604 Bool needed, keep;
605
606 srcfn = emitSrcFile (finfo);
607 fn = emitFileName (finfo, ft);
608 needed = emitIsOutputNeeded(finfo, ft);
609 keep = emitKeep[ft];
610
611 if (!needed && fileIsThere(fn) && !fnameEqual(srcfn, fn)
612 && emitIsGeneratedFile(fn)) {
613 name = fnameUnparse(fn);
614 comsgWarning(NULL((void*)0), ALDOR_W_WillObsolete264, name);
615 strFree(name);
616 }
617 if (needed && keep && fileIsThere(fn) && !emitIsGeneratedFile(fn)) {
618 name = fnameUnparse(fn);
619 comsgFatal(NULL((void*)0), ALDOR_F_WdClobberFile263, name);
620 strFree(name);
621 }
622 if (needed && keep && fnameEqual(srcfn, fn)) {
623 if (emitSolo) {
624 name = fnameUnparse(fn);
625 comsgFatal(NULL((void*)0), ALDOR_F_WdClobberIn262, name);
626 strFree(name);
627 }
628 else
629 needed = false((int) 0);
630 }
631
632 return needed;
633}
634
635EmitInfo
636emitExecutableNameOrWarn(int numFiles, EmitInfo *finfov)
637{
638 EmitInfo finfo;
639 FileName fn;
640 int i;
641
642 /* Let's check for errors first and find the entry finfo. */
643 if (emitEntryFile) {
644 for (i = 0; i < numFiles; i++)
645 if (finfov[i] && emitIsEntry(finfov[i])) break;
646 if (i == numFiles) {
647 if (emitIsOutputNeeded(finfov[0], FTYPENO_EXEC))
648 comsgFatal(NULL((void*)0),ALDOR_F_CmdCantUseEntry6,
649 emitEntryFile);
650 else
651 comsgWarning(NULL((void*)0),ALDOR_W_CmdFunnyEntry8,
652 emitEntryFile);
653 return NULL((void*)0);
654 }
655 finfo = finfov[i];
656 }
657 else
658 finfo = finfov[0];
659
660 /* We might see a `file out of date' warning here. */
661 emitIsOutputNeededOrWarn(finfo, FTYPENO_EXEC);
662 fn = emitFileName(finfo, FTYPENO_EXEC);
663
664 if (strEqual(fnameDir(fn)((fn)->partv[0]), "")) fnameSetDir(fn, osCurDirName());
665
666 return finfo;
667}
668
669
670/*
671 * Test whether a file was generated by Aldor.
672 */
673Bool
674emitIsGeneratedFile(FileName fn)
675{
676 int tno;
677 String hd1;
678 FILE *infile;
679 Bool result;
680
681 extern String emitCHdFmt1, emitLispHdFmt1;
682
683 if (!fileIsThere(fn)) return false((int) 0);
684
685 tno = ftypeNo(fnameType(fn)((fn)->partv[2]));
686 switch (tno) {
687 case FTYPENO_C: hd1 = emitCHdFmt1; break;
688 case FTYPENO_LISP: hd1 = emitLispHdFmt1; break;
689
690 case FTYPENO_INCLUDED:
691 case FTYPENO_ABSYN:
692 case FTYPENO_OLDABSYN:
693 case FTYPENO_INTERMED:
694 case FTYPENO_FOAMEXPR:
695 case FTYPENO_SYMEEXPR:
696 case FTYPENO_OBJECT:
697 case FTYPENO_JAVA:
698 case FTYPENO_EXEC:
699 case FTYPENO_ANNABS:
700 return true1;
701 default:
702 return false((int) 0);
703 }
704
705 infile = fileRdOpen(fn)fileMustOpen(fn,osIoRdMode);
706 result = true1;
707
708 while (*hd1 && result) if (fgetc(infile)!=*hd1++) result = false((int) 0);
709
710 fclose(infile);
711 return result;
712}
713
714
715/******************************************************************************
716 *
717 * :: File utilities: Rename and Remove
718 *
719 *****************************************************************************/
720
721localstatic void
722emitFileRename(EmitInfo finfo, FTypeNo ft)
723{
724 FileName srcfn = emitSrcFile(finfo);
725 String name = fnameName(srcfn)((srcfn)->partv[1]);
726 FileName ofn = emitFileName(finfo, ft);
727 FileName nfn;
728
729 if (emitInfoIsAXLmain(finfo)((finfo)->isAXLmain)) return;
730
731 if (!ftypeIs(fnameType(srcfn)((srcfn)->partv[2]), ft) && !strEqual(name, fnameName(ofn)((ofn)->partv[1]))
732 && emitKeep[ft]) {
733 nfn = fnameNew(fnameDir(ofn)((ofn)->partv[0]), name, fnameType(ofn)((ofn)->partv[2]));
734 emitInfoFname(finfo, ft)((finfo)->fname[ft]) = nfn;
735 fileRename(ofn, nfn);
736 fnameFree(ofn);
737 }
738}
739
740localstatic void
741emitFileRemove(EmitInfo finfo, FTypeNo ft)
742{
743 FileName srcfn = emitSrcFile(finfo);
744 String name = fnameName(srcfn)((srcfn)->partv[1]);
745 FileName ofn = emitFileName(finfo, ft);
746 FileName nfn;
747
748 if (emitInfoIsAXLmain(finfo)((finfo)->isAXLmain)) return;
749
750 /* Remove an existing C/object file if it's going to be overwritten
751 later in emitFileRename. */
752 if (!ftypeIs(fnameType(srcfn)((srcfn)->partv[2]), ft) && !strEqual(name, fnameName(ofn)((ofn)->partv[1]))
753 && emitKeep[ft]) {
754 nfn = fnameNew(fnameDir(ofn)((ofn)->partv[0]), name, fnameType(ofn)((ofn)->partv[2]));
755 fileRemove(nfn);
756 fnameFree(nfn);
757 }
758}
759
760
761/*****************************************************************************
762 *
763 * :: Syme list collectors
764 *
765 ****************************************************************************/
766
767/*!!*/
768extern SymeList foamSymeList (Foam);
769
770SymeList
771emitCollectIntermedSymes(Stab stab, Foam foam)
772{
773 SymeList xsymes, fsymes, symes;
774
775 xsymes = stabGetExportedSymes(stab);
776 fsymes = foamSymeList(foam);
777
778 symes = listNil(Syme)((SymeList) 0);
779 symes = listNConcat(Syme)(Syme_listPointer->NConcat)(symes, xsymes);
780 symes = listNConcat(Syme)(Syme_listPointer->NConcat)(symes, fsymes);
781
782 return symes;
783}
784
785/*****************************************************************************
786 *
787 * :: Dumb emitters -- just do what they're told.
788 *
789 ****************************************************************************/
790
791/*
792 * Emit the .ai file of included source.
793 */
794void
795emitTheIncluded(EmitInfo finfo, SrcLineList sll)
796{
797 FILE *fout;
798 FileName fn;
799
800 fn = emitFileName(finfo, FTYPENO_INCLUDED);
801 emitInfoInUse(finfo, FTYPENO_INCLUDED)((finfo)->inUse[FTYPENO_INCLUDED]) = true1;
802 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
803 inclWrite(fout, sll);
804 fclose(fout);
805 emitInfoInUse(finfo, FTYPENO_INCLUDED)((finfo)->inUse[FTYPENO_INCLUDED]) = false((int) 0);
806 emitSetDone(FTYPENO_INCLUDED);
807}
808
809/*
810 * Emit the .ap abstract syntax file.
811 */
812void
813emitTheAbSyn(EmitInfo finfo, AbSyn absyn)
814{
815 FILE *fout;
816 FileName fn;
817
818 fn = emitFileName(finfo, FTYPENO_ABSYN);
819 emitInfoInUse(finfo, FTYPENO_ABSYN)((finfo)->inUse[FTYPENO_ABSYN]) = true1;
820 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
821 abWrSExpr(fout, absyn, emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)));
822 fclose(fout);
823 emitInfoInUse(finfo, FTYPENO_ABSYN)((finfo)->inUse[FTYPENO_ABSYN]) = false((int) 0);
824 emitSetDone(FTYPENO_ABSYN);
825}
826
827/*
828 * Emit the .ax abstract syntax file.
829 */
830void
831emitTheOldAbSyn(EmitInfo finfo, AbSyn absyn)
832{
833 FILE *fout;
834 FileName fn;
835
836 fn = emitFileName(finfo, FTYPENO_OLDABSYN);
837 emitInfoInUse(finfo, FTYPENO_OLDABSYN)((finfo)->inUse[FTYPENO_OLDABSYN]) = true1;
838 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
839 abWrSExpr(fout, absyn, emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)));
840 fclose(fout);
841 emitInfoInUse(finfo, FTYPENO_OLDABSYN)((finfo)->inUse[FTYPENO_OLDABSYN]) = false((int) 0);
842 emitSetDone(FTYPENO_OLDABSYN);
843}
844
845/*
846 * Emit the parts of a .ao file.
847 */
848void
849emitTheIntermed(EmitInfo finfo, SymeList sl, Foam foam, AbSyn macs)
850{
851 Lib lib;
852 FileName fn;
853
854 fn = emitFileName(finfo, FTYPENO_INTERMED);
855 emitInfoInUse(finfo, FTYPENO_INTERMED)((finfo)->inUse[FTYPENO_INTERMED]) = true1;
856 lib = libWrite(fn);
857 libPutSymes(lib, sl, foam);
858 libPutFoamSymes(lib, foam);
859 libPutMacros(lib, macs);
860 foam = libPutFoam(lib, foam);
861
862 libPutFileId(lib, emitGetFileIdName(finfo));
863
864 if (emitDoLineNos)
865 libPutPos(lib, foam);
866
867 libClose(lib);
868 emitInfoInUse(finfo, FTYPENO_INTERMED)((finfo)->inUse[FTYPENO_INTERMED]) = false((int) 0);
869 emitSetDone(FTYPENO_INTERMED);
870}
871
872/*
873 * Emit the files needed in order to compile against the .ao file
874 */
875extern void
876emitTheDependencies (EmitInfo finfo)
877{
878 FileName fn;
879 StringList lst;
880
881 fn = emitFileName(finfo, FTYPENO_INTERMED);
882 lst = libDependencies(fn);
883 printf("Dependencies(%s):", emitGetFileIdName(finfo));
884
885 while (lst) {
886 printf(" %s", car(lst)((lst)->first));
887 lst = cdr(lst)((lst)->rest);
888 }
889 printf("\n");
890}
891
892/*
893 * Emit lisp-readable symbol meaning information to the .asy file.
894 */
895void
896emitTheSymbolExpr(EmitInfo finfo, SymeList symes, AbSyn macs)
897{
898 FILE *fout;
899 FileName fn;
900
901
902 fn = emitFileName(finfo, FTYPENO_SYMEEXPR);
903 emitInfoInUse(finfo, FTYPENO_SYMEEXPR)((finfo)->inUse[FTYPENO_SYMEEXPR]) = true1;
904 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
905 symeListWrSExpr(fout, fnameName(emitSrcFile(finfo))((emitSrcFile(finfo))->partv[1]),
906 symes, SXRW_Default((1L<<1) | (1L<<3)));
907 abWrSExpr(fout, macs, SXRW_Default((1L<<1) | (1L<<3)));
908#if 0
909 /* This crap writes out any and all info regarding
910 * types imported/inlined. Enable if you want to know
911 * everything (axiom doesn't).
912 */
913 nuttin1 = abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
914 nuttin2 = abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
915 tu = getAllTypesUsed(car(stabFile())((stabFile())->first));
916 ab = abNewImport(sposNone, nuttin1, nuttin2)abNew(AB_Import, sposNone,2, nuttin1,nuttin2);
917 tl = tu->typesImported;
918 while (tl) {
919 ab->abImport.origin = car(tl)((tl)->first);
920 abWrSExpr(fout, ab, emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)));
921 tl = cdr(tl)((tl)->rest);
922 }
923 ab->abImport.origin = nuttin2;
924 abFree(ab);
925
926 nuttin1 = abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
927 nuttin2 = abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
928 ab = abNewInline(sposNone, nuttin1, nuttin2)abNew(AB_Inline, sposNone,2, nuttin1,nuttin2);
929 tl = tu->typesInlined;
930 while (tl) {
931 ab->abInline.origin = car(tl)((tl)->first);
932 abWrSExpr(fout, ab, emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)));
933 tl = cdr(tl)((tl)->rest);
934 }
935 ab->abInline.origin = nuttin2;
936 abFree(ab);
937
938 listFree(AbSyn)(AbSyn_listPointer->Free)(tu->typesImported);
939 listFree(AbSyn)(AbSyn_listPointer->Free)(tu->typesInlined);
940 listFree(AbSyn)(AbSyn_listPointer->Free)(tu->typesOther);
941 stoFree(tu);
942#endif
943 fclose(fout);
944 emitInfoInUse(finfo, FTYPENO_SYMEEXPR)((finfo)->inUse[FTYPENO_SYMEEXPR]) = false((int) 0);
945 emitSetDone(FTYPENO_SYMEEXPR);
946}
947
948/*
949 * Emit lisp-readable symbol meaning information to the .asy file.
950 */
951void
952emitTheAnnotatedAbSyn(EmitInfo finfo, SExpr whole)
953{
954 FILE *fout;
955 FileName fn;
956
957 fn = emitFileName(finfo, FTYPENO_ANNABS);
958 emitInfoInUse(finfo, FTYPENO_ANNABS)((finfo)->inUse[FTYPENO_ANNABS]) = true1;
959 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
960 sxiWrite(fout, whole, SXRW_Default((1L<<1) | (1L<<3)));
961
962 fclose(fout);
963 emitInfoInUse(finfo, FTYPENO_ANNABS)((finfo)->inUse[FTYPENO_ANNABS]) = false((int) 0);
964 emitSetDone(FTYPENO_ANNABS);
965}
966
967
968/*
969 * Emit lisp-readable Foam codes to the .fm file.
970 */
971void
972emitTheFoamExpr(EmitInfo finfo, Foam foam)
973{
974 FILE *fout;
975 FileName fn;
976
977 fn = emitFileName(finfo, FTYPENO_FOAMEXPR);
978 emitInfoInUse(finfo, FTYPENO_FOAMEXPR)((finfo)->inUse[FTYPENO_FOAMEXPR]) = true1;
979 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
980 foamWrSExpr(fout, foam, emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)));
981 fclose(fout);
982 emitInfoInUse(finfo, FTYPENO_FOAMEXPR)((finfo)->inUse[FTYPENO_FOAMEXPR]) = false((int) 0);
983 emitSetDone(FTYPENO_FOAMEXPR);
984}
985
986/*
987 * Emit the .l Lisp-code file.
988 */
989String emitLispHdFmt1 = ";;;\n;;; Lisp code generated by Aldor";
990String emitLispHdFmt2 = " from file \"%s\"";
991String emitLispHdFmt3 = ".\n;;;\n";
992
993void
994emitTheCpp() {
995 emitSetDone(FTYPENO_CPP);
996}
997
998void
999emitTheLisp(EmitInfo finfo, SExpr lispCode)
1000{
1001 FILE *fout;
1002 String fnstring;
1003 FileName srcfn, fn;
1004
1005 srcfn = emitSrcFile(finfo);
1006 fn = emitFileName(finfo, FTYPENO_LISP);
1007
1008 emitInfoInUse(finfo, FTYPENO_LISP)((finfo)->inUse[FTYPENO_LISP]) = true1;
1009 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
1010
1011 fnstring = fnameUnparseStaticWithout(srcfn);
1012 fprintf(fout, "%s", emitLispHdFmt1);
1013 if (!emitInfoIsAXLmain(finfo)((finfo)->isAXLmain)) fprintf(fout, emitLispHdFmt2, fnstring);
1014 fprintf(fout, "%s", emitLispHdFmt3);
1015
1016 for ( ; !sxiNull(lispCode)(((lispCode)->sxHdr.tag) == SX_Nil); lispCode = sxCdr(lispCode)((lispCode)->sxCons.sxCdrField)) {
1017 fprintf(fout, "\n");
1018 sxiWrite(fout, sxCar(lispCode)((lispCode)->sxCons.sxCarField), glWriteMode | emitSxIoMode(emitDoLineNos ? (1L<<2) : (1L<<3)));
1019 }
1020 fclose(fout);
1021 emitInfoInUse(finfo, FTYPENO_LISP)((finfo)->inUse[FTYPENO_LISP]) = false((int) 0);
1022 emitSetDone(FTYPENO_LISP);
1023}
1024
1025/*
1026 * Emit the .c C-code file.
1027 */
1028String emitCHdFmt1 = "/*\n * C code generated by Aldor";
1029String emitCHdFmt2 = " from file \"%s\"";
1030String emitCHdFmt3 = ".\n */\n";
1031
1032void
1033emitTheC(EmitInfo finfo, CCodeList cco)
1034{
1035 FILE *fout=NULL((void*)0), *hout = NULL((void*)0);
1036 String fnstring;
1037 FileName srcfn, fn, hfn=NULL((void*)0);
1038 CCodeMode ccmode;
1039 int i, l = listLength(CCode)(CCode_listPointer->_Length)(cco);
1040 Bool stdc;
1041
1042 srcfn = emitSrcFile(finfo);
1043 fn = emitFileName(finfo, FTYPENO_C);
1044 emitFileRemove(finfo, FTYPENO_C);
1045 emitInfoInUse(finfo, FTYPENO_C)((finfo)->inUse[FTYPENO_C]) = true1;
1046 emitSetDone(FTYPENO_C);
1047
1048 stdc = ccDoStandardC();
1049
1050 if (l > 1) {
1051 hfn = emitFileName(finfo, FTYPENO_H);
1052 emitFileRemove(finfo, FTYPENO_H);
1053 emitInfoInUse(finfo, FTYPENO_H)((finfo)->inUse[FTYPENO_H]) = true1;
1054 hout = fileWrOpen(hfn)fileMustOpen(hfn,osIoWrMode);
1055
1056 fnstring = fnameUnparseStaticWithout(srcfn);
1057 fprintf(hout, emitCHdFmt1, 0);
1058 fprintf(hout, emitCHdFmt2, fnstring);
1059 fprintf(hout, emitCHdFmt3, 0);
1060 fprintf(hout, "\n");
1061 }
1062
1063 ccmode = stdc ? CCOM_StandardC : CCOM_OldC;
1064 ccmode |= emitDoLineNos && ccLineNos() ? CCOM_LineNo : 0;
1065
1066 for (i = 0; cco && cco != listNil(CCode)((CCodeList) 0); cco = cdr(cco)((cco)->rest), i++) {
1067#define FN_PREF_LEN5 5
1068#define FN_SUFF_LEN3 3
1069 String fnold;
1070 char fnnew[FN_PREF_LEN5 + FN_SUFF_LEN3 + 10];
1071 FileName fname;
1072 int k, nf;
1073 if ((i || !hout) && i < l) {
1074 if (ccoArgc(ccoArgv(car(cco))[0])((((((cco)->first))->ccoNode.argv)[0])->ccoNode.argc
)
) {
1075 /* Need to check for name conflicts here. */
1076 if (i == 1 || !hout)
1077 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
1078 else {
1079 fnold = emitCName;
1080 if (!fnold) fnold = fnameName(fn)((fn)->partv[1]);
1081
1082 for (k = 0; k < FN_PREF_LEN5; k++) {
1083 if (!fnold[k]) break;
1084 fnnew[k] = fnold[k];
1085 }
1086 nf = (i > 1) ? i-1 : i;
1087
1088 sprintf(fnnew + k, "%.*d",
1089 FN_SUFF_LEN3, nf);
1090
1091 fname = fnameNew(fnameDir(fn)((fn)->partv[0]),
1092 fnnew,
1093 fnameType(fn)((fn)->partv[2]));
1094 /* Add to list of filenames */
1095 finfo->flist = listCons(FileName)(FileName_listPointer->Cons)(fname, finfo->flist);
1096 fout = fileWrOpen(fname)fileMustOpen(fname,osIoWrMode);
1097 }
1098 fnstring = fnameUnparseStaticWithout(srcfn);
1099 fprintf(fout, emitCHdFmt1, 0);
1100 if (!emitInfoIsAXLmain(finfo)((finfo)->isAXLmain))
1101 fprintf(fout, emitCHdFmt2, fnstring);
1102 fprintf(fout, emitCHdFmt3, 0);
1103 fprintf(fout, "\n");
1104 if (emitDoLineNos && ccLineNos())
1105 fprintf(fout, "#line 1 \"%s.as\"\n\n",
1106 fnameName(fn)((fn)->partv[1]));
1107 fprintf(fout, "#include \"foam_c.h\"");
1108 if (l > 1)
1109 fprintf(fout, "\n#include \"%s\"",
1110 fnameUnparseStatic(hfn));
1111 ccoPrint(fout, car(cco)((cco)->first), ccmode);
1112 fclose(fout);
1113 }
1114 }
1115 else
1116 ccoPrint(hout, car(cco)((cco)->first), ccmode);
1117 }
1118 if (finfo->flist) finfo->flist = listNReverse(FileName)(FileName_listPointer->NReverse)(finfo->flist);
1119 emitInfoInUse(finfo, FTYPENO_C)((finfo)->inUse[FTYPENO_C]) = false((int) 0);
1120 emitSetDone(FTYPENO_LISP);
1121 if (hout) {
1122 fclose(hout);
1123 emitInfoInUse(finfo, FTYPENO_H)((finfo)->inUse[FTYPENO_H]) = false((int) 0);
1124 emitSetDone(FTYPENO_H);
1125 }
1126}
1127
1128/*
1129 * Emit the .o object-code file by compiling C-code.
1130 */
1131void
1132emitTheObject(EmitInfo finfo)
1133{
1134 FileNameList fl;
1135 FileName cfile = emitFileName(finfo, FTYPENO_C);
1136 FileName ofile = emitFileName(finfo, FTYPENO_OBJECT);
1137
1138 emitFileRemove(finfo, FTYPENO_OBJECT);
1139
1140 emitInfoInUse(finfo, FTYPENO_OBJECT)((finfo)->inUse[FTYPENO_OBJECT]) = true1;
1141 ccCompileFile(emitOutputDir, ofile, cfile);
1142 /* Need to emit an object file for each C file in filename list */
1143 for (fl = finfo->flist; fl; fl = cdr(fl)((fl)->rest))
1144 ccCompileFile(emitOutputDir, NULL((void*)0), car(fl)((fl)->first));
1145 emitInfoInUse(finfo, FTYPENO_OBJECT)((finfo)->inUse[FTYPENO_OBJECT]) = false((int) 0);
1146 emitSetDone(FTYPENO_OBJECT);
1147
1148 /* Keep if (-Fc && !aldormain.c) or (-Waldormain && aldormain.c). */
1149 if (emitKeep[FTYPENO_C] && !emitInfoIsAXLmain(finfo)((finfo)->isAXLmain))
1150 ; /* Keep */
1151 else if (strEqual(fnameType(emitSrcFile(finfo))((emitSrcFile(finfo))->partv[2]), FTYPE_C"c"))
1152 ; /* Keep */
1153 else if (emitDo[FTYPENO_AXLMAINC] && emitInfoIsAXLmain(finfo)((finfo)->isAXLmain))
1154 ; /* Keep */
1155 else {
1156 fileRemove(cfile);
1157 if (listLength(FileName)(FileName_listPointer->_Length)(finfo->flist) > 0)
1158 fileRemove(emitFileName(finfo, FTYPENO_H));
1159 /* Remove each C file in filename list */
1160 for (fl = finfo->flist; fl; fl = cdr(fl)((fl)->rest))
1161 fileRemove(car(fl)((fl)->first));
1162 }
1163
1164 emitFileRename(finfo, FTYPENO_C);
1165}
1166
1167
1168
1169/*****************************************************************************
1170 *
1171 * :: Java
1172 *
1173 ****************************************************************************/
1174
1175static String emitJavaHeader = "//\n// Java generated by aldor from file %s\n//\n";
1176
1177localstatic void emitOneJavaFile (EmitInfo finfo, JavaCode javaFile);
1178localstatic FileName emitJavaFileName(EmitInfo finfo, JavaCode javaFile);
1179
1180void
1181emitTheJava(EmitInfo finfo, JavaCodeList javaFiles)
1182{
1183 emitInfoInUse(finfo, FTYPENO_JAVA)((finfo)->inUse[FTYPENO_JAVA]) = true1;
1184
1185 while (javaFiles != listNil(JavaCode)((JavaCodeList) 0)) {
1186 emitOneJavaFile(finfo, car(javaFiles)((javaFiles)->first));
1187 javaFiles = cdr(javaFiles)((javaFiles)->rest);
1188 }
1189
1190 emitInfoInUse(finfo, FTYPENO_JAVA)((finfo)->inUse[FTYPENO_JAVA]) = false((int) 0);
1191 emitSetDone(FTYPENO_JAVA);
1192}
1193
1194
1195localstatic void
1196emitOneJavaFile(EmitInfo finfo, JavaCode javaFile)
1197{
1198 JavaCodePContext ctxt;
1199 FileName fn, srcfn;
1200 OStream ostream;
1201 FILE *fout;
1202
1203 srcfn = emitSrcFile(finfo);
1204 fn = emitJavaFileName(finfo, javaFile);
1205
1206 fout = fileWrOpen(fn)fileMustOpen(fn,osIoWrMode);
1207 ostream = ostreamNewFrFile(fout);
1208 ostreamPrintf(ostream, emitJavaHeader, fnameUnparseStaticWithout(srcfn));
1209
1210 ctxt = jcoPContextNew(ostream, false((int) 0));
1211 jcoWrite(ctxt, javaFile);
1212 jcoPContextFree(ctxt);
1213 ostreamClose(ostream);
1214 fclose(fout);
1215}
1216
1217localstatic FileName
1218emitJavaFileName(EmitInfo finfo, JavaCode javaFile)
1219{
1220 FileName javaFileName = emitFileName(finfo, FTYPENO_JAVA);
1221 String fileName = jcFileClassName(javaFile);
1222 String pkgName = strReplace(jcFilePackageName(javaFile), ".", "/");
1223 String destDir = strPrintf("%s/%s", fnameDir(javaFileName)((javaFileName)->partv[0]),
1224 pkgName == NULL((void*)0) ? "" : pkgName);
1225
1226 return fnameNew(destDir, fileName, FTYPE_JAVA"java");
1227}
1228
1229/*****************************************************************************
1230 *
1231 * :: Producing and running executable file
1232 *
1233 ****************************************************************************/
1234
1235localstatic Bool
1236emitIsKindOfObjectFile(FileName fn)
1237{
1238 String type = fnameType(fn)((fn)->partv[2]);
1239 return ftypeIs(type, FTYPENO_OBJECT) ||
1240 ftypeIs(type, FTYPENO_AR_OBJ) ||
1241 ftypeIs(type, FTYPENO_AR_INT);
1242}
1243
1244static EmitInfo emitExecFinfo;
1245
1246void
1247emitLink(int numFiles, EmitInfo * finfov)
1248{
1249 FileName * files;
1250 FileName srcfn;
1251 FileName execfn;
1252 int i, ix, tmpFiles = 0;
1253
1254 /*
1255 * Compute the exec name first, so we get the `file out of date'
1256 * warning message even if we don't need an executable.
1257 */
1258 emitExecFinfo = emitExecutableNameOrWarn(numFiles, finfov);
1259
1260 if (!emitExecFinfo
1261 || !emitIsOutputNeeded(emitExecFinfo, FTYPENO_EXEC)) {
1262 for (i = 0; i < numFiles - 1; i++)
1263 emitFileRename(finfov[i], FTYPENO_OBJECT);
1264 return;
1265 }
1266
1267 for (i = 0; i < numFiles; i++)
1268 tmpFiles += listLength(FileName)(FileName_listPointer->_Length)(finfov[i]->flist);
1269
1270 files = (FileName *) stoAlloc((unsigned) OB_Other0,
1271 (tmpFiles+numFiles) * sizeof(FileName));
1272 for (i = 0, ix = 0; i < numFiles; i++, ix++) {
1273 FileNameList finfo;
1274 srcfn = emitSrcFile(finfov[i]);
1275 if (emitIsKindOfObjectFile(srcfn)
1276 && !emitInfoIsAXLmain(finfov[i])((finfov[i])->isAXLmain))
1277 files[ix] = srcfn;
1278 else
1279 files[ix] = emitFileName(finfov[i], FTYPENO_OBJECT);
1280 for (finfo = finfov[i]->flist;
1281 finfo && finfo != listNil(FileName)((FileNameList) 0);
1282 finfo = cdr(finfo)((finfo)->rest)) {
1283 FileName tmpobj;
1284 ix++;
1285 tmpobj = car(finfo)((finfo)->first);
1286 fnameType(tmpobj)((tmpobj)->partv[2]) = FTYPE_OBJECTosObjectFileType;
1287 files[ix] = tmpobj;
1288 }
1289 }
1290
1291 emitInfoInUse(emitExecFinfo, FTYPENO_EXEC)((emitExecFinfo)->inUse[FTYPENO_EXEC]) = true1;
1292 execfn = emitFileName(emitExecFinfo, FTYPENO_EXEC);
1293 ccSetOutputFile(fnameUnparse(execfn));
1294 ccLinkProgram(emitOutputDir, files, numFiles + tmpFiles);
1295 emitInfoInUse(emitExecFinfo, FTYPENO_EXEC)((emitExecFinfo)->inUse[FTYPENO_EXEC]) = false((int) 0);
1296 emitSetDone(FTYPENO_AXLMAINC);
1297 emitSetDone(FTYPENO_EXEC);
1298
1299 for (i = 0, ix = 0; i < numFiles - 1; i++, ix++) {
1300 FileNameList fl;
1301 srcfn = emitSrcFile(finfov[i]);
1302 if (!emitIsKindOfObjectFile(srcfn) &&
1303 !emitKeep[FTYPENO_OBJECT]) {
1304 fileRemove(files[ix]);
1305 for (fl = finfov[i]->flist; fl; fl = cdr(fl)((fl)->rest))
1306 fileRemove(files[++ix]);
1307 }
1308 emitFileRename(finfov[i], FTYPENO_OBJECT);
1309 }
1310 fileRemove(emitFileName(finfov[numFiles - 1], FTYPENO_OBJECT));
1311}
1312
1313void
1314emitRun(int argc1, String *argv1)
1315{
1316 FileName emitExecName;
1317
1318 if (!emitDoRun) return;
1319
1320 /* If emitDoRun, we are sure that emitExecFinfo != NULL. */
1321 emitExecName = emitFileName(emitExecFinfo, FTYPENO_EXEC);
1322
1323 ccGoProgram(emitExecName, argc1, argv1);
1324
1325 if (!emitKeep[FTYPENO_EXEC])
1326 fileRemove(emitExecName);
1327}
1328
1329void
1330emitInterp(int argc1, String *argv1)
1331{
1332 FileName emitExecName;
1333 Bool result;
1334 if (!emitDoInterp) return;
1335
1336 /* If emitDoInterp, we are sure that emitExecFinfo != NULL. */
1337 emitExecName = emitFileName(emitExecFinfo, FTYPENO_INTERMED);
1338
1339 result = fintFile(emitExecName);
1340
1341 if (!emitKeep[FTYPENO_INTERMED])
1342 fileRemove(emitExecName);
1343
1344 if (!result) {
1345 exitFailure();
1346 }
1347}
1348
1349
1350/******************************************************************************
1351 *
1352 * :: Cleanup
1353 *
1354 *****************************************************************************/
1355
1356void
1357emitCleanup(int numFiles, EmitInfo *finfov)
1358{
1359 EmitInfo finfo;
1360 FileName fn;
1361 String name;
1362 int i, j;
1363
1364 if (!finfov) return;
1365
1366 /* For each of the input files */
1367 for (i = 0; i < numFiles; i++) {
1368 finfo = finfov[i];
1369 if (!finfo) continue;
1370 /* For each file generated from the ith input file */
1371 for (j = 0; j < FTYPENO_LIMIT; j++) {
1372 /* Don't remove files we didn't generate. */
1373 if (!emitInfoFname(finfo, j)((finfo)->fname[j])
1374 || !emitIsOutputNeeded(finfo, j))
1375 continue;
1376
1377 /*
1378 * Deal with aldormain.c when j==FTYPENO_AXLMAINC
1379 * and aldormain.o when j==FTYPENO_OBJECT.
1380 */
1381 if (emitInfoIsAXLmain(finfo)((finfo)->isAXLmain) &&
1382 (j != FTYPENO_AXLMAINC) &&
1383 (j != FTYPENO_OBJECT))
1384 continue;
1385
1386 fn = emitInfoFname(finfo, j)((finfo)->fname[j]);
1387 name = fnameUnparse(fn);
1388
1389 /* Need to remove all files in filename list */
1390 for (; finfo->flist; finfo->flist = cdr(finfo->flist)((finfo->flist)->rest))
1391 fileRemove(car(finfo->flist)((finfo->flist)->first));
1392 if (emitInfoInUse(finfo, j)((finfo)->inUse[j]) && fileIsThere(fn)) {
1393 comsgWarning(NULL((void*)0), ALDOR_W_RemovingFile265, name);
1394 fileRemove(fn);
1395 }
1396 else if (fileIsThere(fn)) {
1397 if (!emitKeep[j]) {
1398 /* We might not want a warning here. */
1399 comsgWarning(NULL((void*)0),ALDOR_W_RemovingFile265,name);
1400 fileRemove(fn);
1401 }
1402 else
1403 emitFileRename(finfo, j);
1404 }
1405 strFree(name);
1406 }
1407 emitAllDone(); /* FIXME: why is this in the inner loop? */
1408 emitInfoFree(finfo);
1409 finfov[i] = 0;
1410 }
1411}