/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
-/* Römerstraße 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
-void WriteOutput (FILE* F)
-/* Write the final output to a file */
+void WriteAsmOutput (void)
+/* Write the final assembler output to the output file */
{
SymTable* SymTab;
SymEntry* Entry;
/* Output the global data segment */
CHECK (!HaveGlobalCode ());
- OutputSegments (CS, F);
+ OutputSegments (CS);
/* Output all global or referenced functions */
SymTab = GetGlobalSymTab ();
/* Function which is defined and referenced or extern */
CS_MergeLabels (Entry->V.F.Seg->Code);
RunOpt (Entry->V.F.Seg->Code);
- OutputSegments (Entry->V.F.Seg, F);
+ OutputSegments (Entry->V.F.Seg);
}
Entry = Entry->NextSym;
}
/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
-/* Römerstraße 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
int CodeRangeIsEmpty (const CodeMark* Start, const CodeMark* End);
/* Return true if the given code range is empty (no code between Start and End) */
-void WriteOutput (FILE* F);
-/* Write the final output to a file */
+void WriteAsmOutput (void);
+/* Write the final assembler output to the output file */
/* */
/* */
/* */
-/* (C) 2001-2005, Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
#include <stdlib.h>
-#include <string.h>
/* common */
#include "chartype.h"
#include "xsprintf.h"
/* cc65 */
+#include "codeent.h"
#include "codeinfo.h"
#include "error.h"
#include "global.h"
#include "codelab.h"
#include "opcodes.h"
-#include "codeent.h"
+#include "output.h"
-void CE_Output (const CodeEntry* E, FILE* F)
-/* Output the code entry to a file */
+void CE_Output (const CodeEntry* E)
+/* Output the code entry to the output file */
{
const OPCDesc* D;
unsigned Chars;
unsigned LabelCount = CollCount (&E->Labels);
unsigned I;
for (I = 0; I < LabelCount; ++I) {
- CL_Output (CollConstAt (&E->Labels, I), F);
+ CL_Output (CollConstAt (&E->Labels, I));
}
/* Get the opcode description */
D = GetOPCDesc (E->OPC);
/* Print the mnemonic */
- Chars = fprintf (F, "\t%s", D->Mnemo);
+ Chars = WriteOutput ("\t%s", D->Mnemo);
/* Print the operand */
switch (E->AM) {
case AM65_ACC:
/* accumulator */
- Chars += fprintf (F, "%*sa", 9-Chars, "");
+ Chars += WriteOutput ("%*sa", 9-Chars, "");
break;
case AM65_IMM:
/* immidiate */
- Chars += fprintf (F, "%*s#%s", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s#%s", 9-Chars, "", E->Arg);
break;
case AM65_ZP:
case AM65_ABS:
/* zeropage and absolute */
- Chars += fprintf (F, "%*s%s", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s%s", 9-Chars, "", E->Arg);
break;
case AM65_ZPX:
case AM65_ABSX:
/* zeropage,X and absolute,X */
- Chars += fprintf (F, "%*s%s,x", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s%s,x", 9-Chars, "", E->Arg);
break;
case AM65_ABSY:
/* absolute,Y */
- Chars += fprintf (F, "%*s%s,y", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s%s,y", 9-Chars, "", E->Arg);
break;
case AM65_ZPX_IND:
/* (zeropage,x) */
- Chars += fprintf (F, "%*s(%s,x)", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s(%s,x)", 9-Chars, "", E->Arg);
break;
case AM65_ZP_INDY:
/* (zeropage),y */
- Chars += fprintf (F, "%*s(%s),y", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s(%s),y", 9-Chars, "", E->Arg);
break;
case AM65_ZP_IND:
/* (zeropage) */
- Chars += fprintf (F, "%*s(%s)", 9-Chars, "", E->Arg);
+ Chars += WriteOutput ("%*s(%s)", 9-Chars, "", E->Arg);
break;
case AM65_BRA:
/* branch */
Target = E->JumpTo? E->JumpTo->Name : E->Arg;
- Chars += fprintf (F, "%*s%s", 9-Chars, "", Target);
+ Chars += WriteOutput ("%*s%s", 9-Chars, "", Target);
break;
default:
if (Debug) {
char Use [128];
char Chg [128];
- fprintf (F,
- "%*s; USE: %-12s CHG: %-12s SIZE: %u",
- 30-Chars, "",
- RegInfoDesc (E->Use, Use),
- RegInfoDesc (E->Chg, Chg),
- E->Size);
+ WriteOutput ("%*s; USE: %-12s CHG: %-12s SIZE: %u",
+ 30-Chars, "",
+ RegInfoDesc (E->Use, Use),
+ RegInfoDesc (E->Chg, Chg),
+ E->Size);
if (E->RI) {
char RegIn[32];
char RegOut[32];
- fprintf (F,
- " In %s Out %s",
- RegContentDesc (&E->RI->In, RegIn),
- RegContentDesc (&E->RI->Out, RegOut));
+ WriteOutput (" In %s Out %s",
+ RegContentDesc (&E->RI->In, RegIn),
+ RegContentDesc (&E->RI->Out, RegOut));
}
}
/* Terminate the line */
- fprintf (F, "\n");
+ WriteOutput ("\n");
}
/* */
/* */
/* */
-/* (C) 2001-2005, Ullrich von Bassewitz */
-/* Römerstrasse 52 */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
-#include <stdio.h>
#include <string.h>
/* common */
* overwritten.
*/
-void CE_Output (const CodeEntry* E, FILE* F);
-/* Output the code entry to a file */
+void CE_Output (const CodeEntry* E);
+/* Output the code entry to the output file */
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* cc65 */
#include "codeent.h"
#include "codelab.h"
+#include "output.h"
-void CL_Output (const CodeLabel* L, FILE* F)
-/* Output the code label to a file */
+void CL_Output (const CodeLabel* L)
+/* Output the code label to the output file */
{
- fprintf (F, "%s:", L->Name);
+ WriteOutput ("%s:", L->Name);
if (strlen (L->Name) > 6) {
/* Label is too long, add a linefeed */
- fputc ('\n', F);
+ WriteOutput ("\n");
}
}
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
-#include <stdio.h>
-
/* common */
#include "coll.h"
* more references on return.
*/
-void CL_Output (const CodeLabel* L, FILE* F);
-/* Output the code label to a file */
+void CL_Output (const CodeLabel* L);
+/* Output the code label to the output file */
/* */
/* */
/* */
-/* (C) 2001-2008, Ullrich von Bassewitz */
+/* (C) 2001-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "error.h"
#include "global.h"
#include "ident.h"
+#include "output.h"
#include "symentry.h"
-static void CS_PrintFunctionHeader (const CodeSeg* S, FILE* F)
-/* Print a comment with the function signature to the given file */
+static void CS_PrintFunctionHeader (const CodeSeg* S)
+/* Print a comment with the function signature to the output file */
{
/* Get the associated function */
const SymEntry* Func = S->Func;
/* If this is a global code segment, do nothing */
if (Func) {
- fprintf (F,
- "; ---------------------------------------------------------------\n"
- "; ");
- PrintFuncSig (F, Func->Name, Func->Type);
- fprintf (F,
- "\n"
- "; ---------------------------------------------------------------\n"
- "\n");
+ WriteOutput ("; ---------------------------------------------------------------\n"
+ "; ");
+ PrintFuncSig (OutputFile, Func->Name, Func->Type);
+ WriteOutput ("\n"
+ "; ---------------------------------------------------------------\n"
+ "\n");
}
}
-void CS_OutputPrologue (const CodeSeg* S, FILE* F)
+void CS_OutputPrologue (const CodeSeg* S)
/* If the given code segment is a code segment for a function, output the
* assembler prologue into the file. That is: Output a comment header, switch
* to the correct segment and enter the local function scope. If the code
*/
if (Func) {
/* Get the function descriptor */
- CS_PrintFunctionHeader (S, F);
- fprintf (F, ".segment\t\"%s\"\n\n.proc\t_%s", S->SegName, Func->Name);
+ CS_PrintFunctionHeader (S);
+ WriteOutput (".segment\t\"%s\"\n\n.proc\t_%s", S->SegName, Func->Name);
if (IsQualNear (Func->Type)) {
- fputs (": near", F);
+ WriteOutput (": near");
} else if (IsQualFar (Func->Type)) {
- fputs (": far", F);
+ WriteOutput (": far");
}
- fputs ("\n\n", F);
+ WriteOutput ("\n\n");
}
}
-void CS_OutputEpilogue (const CodeSeg* S, FILE* F)
+void CS_OutputEpilogue (const CodeSeg* S)
/* If the given code segment is a code segment for a function, output the
* assembler epilogue into the file. That is: Close the local function scope.
*/
{
if (S->Func) {
- fputs ("\n.endproc\n\n", F);
+ WriteOutput ("\n.endproc\n\n");
}
}
-void CS_Output (CodeSeg* S, FILE* F)
-/* Output the code segment data to a file */
+void CS_Output (CodeSeg* S)
+/* Output the code segment data to the output file */
{
unsigned I;
const LineInfo* LI;
CS_GenRegInfo (S);
/* Output the segment directive */
- fprintf (F, ".segment\t\"%s\"\n\n", S->SegName);
+ WriteOutput (".segment\t\"%s\"\n\n", S->SegName);
/* Output all entries, prepended by the line information if it has changed */
LI = 0;
for (I = 0; I < Count; ++I) {
- /* Get the next entry */
- const CodeEntry* E = CollConstAt (&S->Entries, I);
- /* Check if the line info has changed. If so, output the source line
- * if the option is enabled and output debug line info if the debug
- * option is enabled.
- */
- if (E->LI != LI) {
- /* Line info has changed, remember the new line info */
- LI = E->LI;
-
- /* Add the source line as a comment. Beware: When line continuation
+ /* Get the next entry */
+ const CodeEntry* E = CollConstAt (&S->Entries, I);
+ /* Check if the line info has changed. If so, output the source line
+ * if the option is enabled and output debug line info if the debug
+ * option is enabled.
+ */
+ if (E->LI != LI) {
+ /* Line info has changed, remember the new line info */
+ LI = E->LI;
+
+ /* Add the source line as a comment. Beware: When line continuation
* was used, the line may contain newlines.
*/
- if (AddSource) {
+ if (AddSource) {
const char* L = LI->Line;
- fputs (";\n; ", F);
+ WriteOutput (";\n; ");
while (*L) {
- if (*L == '\n') {
- fputs ("\n; ", F);
+ const char* N = strchr (L, '\n');
+ if (N) {
+ /* We have a newline, just write the first part */
+ WriteOutput ("%.*s\n; ", N - L, L);
+ L = N+1;
} else {
- fputc (*L, F);
+ /* No Newline, write as is */
+ WriteOutput ("%s\n", L);
+ break;
}
- ++L;
}
- fputs ("\n;\n", F);
- }
+ WriteOutput ("\n;\n");
+ }
- /* Add line debug info */
+ /* Add line debug info */
if (DebugInfo) {
- fprintf (F, "\t.dbg\tline, \"%s\", %u\n",
- GetInputName (LI), GetInputLine (LI));
+ WriteOutput ("\t.dbg\tline, \"%s\", %u\n",
+ GetInputName (LI), GetInputLine (LI));
}
}
/* Output the code */
- CE_Output (E, F);
+ CE_Output (E);
}
/* If debug info is enabled, terminate the last line number information */
if (DebugInfo) {
- fputs ("\t.dbg\tline\n", F);
+ WriteOutput ("\t.dbg\tline\n");
}
/* Free register info */
/* */
/* */
/* */
-/* (C) 2001-2004 Ullrich von Bassewitz */
-/* Römerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <stdarg.h>
-#include <stdio.h>
/* common */
#include "attrib.h"
* Last, and that no insn may jump into this block from the outside.
*/
-void CS_OutputPrologue (const CodeSeg* S, FILE* F);
+void CS_OutputPrologue (const CodeSeg* S);
/* If the given code segment is a code segment for a function, output the
* assembler prologue into the file. That is: Output a comment header, switch
* to the correct segment and enter the local function scope. If the code
* segment is global, do nothing.
*/
-void CS_OutputEpilogue (const CodeSeg* S, FILE* F);
+void CS_OutputEpilogue (const CodeSeg* S);
/* If the given code segment is a code segment for a function, output the
* assembler epilogue into the file. That is: Close the local function scope.
*/
-void CS_Output (CodeSeg* S, FILE* F);
+void CS_Output (CodeSeg* S);
/* Output the code segment data to a file */
void CS_FreeRegInfo (CodeSeg* S);
/* End of codeseg.h */
-#endif
+#endif
/* */
/* compile.c */
/* */
-/* Top level compiler subroutine */
+/* Top level compiler subroutine */
/* */
/* */
/* */
-/* (C) 2000-2008 Ullrich von Bassewitz */
+/* (C) 2000-2009 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#include "input.h"
#include "litpool.h"
#include "macrotab.h"
+#include "output.h"
#include "pragma.h"
#include "preproc.h"
#include "standard.h"
/* Are we supposed to compile or just preprocess the input? */
if (PreprocessOnly) {
+ /* Open the file */
+ OpenOutputFile ();
+
+ /* Preprocess each line and write it to the output file */
while (NextLine ()) {
Preprocess ();
- printf ("%.*s\n", SB_GetLen (Line), SB_GetConstBuf (Line));
+ WriteOutput ("%.*s\n", SB_GetLen (Line), SB_GetConstBuf (Line));
}
+ /* Close the output file */
+ CloseOutputFile ();
+
if (Debug) {
PrintMacroStats (stdout);
}
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "xsprintf.h"
/* cc65 */
-#include "error.h"
#include "dataseg.h"
+#include "error.h"
+#include "output.h"
-void DS_Output (const DataSeg* S, FILE* F)
-/* Output the data segment data to a file */
+void DS_Output (const DataSeg* S)
+/* Output the data segment data to the output file */
{
unsigned I;
}
/* Output the segment directive */
- fprintf (F, ".segment\t\"%s\"\n\n", S->SegName);
+ WriteOutput (".segment\t\"%s\"\n\n", S->SegName);
/* Output all entries */
for (I = 0; I < Count; ++I) {
- fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I));
+ WriteOutput ("%s\n", (const char*) CollConstAt (&S->Lines, I));
}
/* Add an additional newline after the segment output */
- fprintf (F, "\n");
+ WriteOutput ("\n");
}
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <stdarg.h>
-#include <stdio.h>
/* common */
#include "attrib.h"
void DS_AddLine (DataSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
/* Add a line to the given data segment */
-void DS_Output (const DataSeg* S, FILE* F);
-/* Output the data segment data to a file */
+void DS_Output (const DataSeg* S);
+/* Output the data segment data to the output file */
/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
-/* Römerstraße 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "incpath.h"
#include "input.h"
#include "macrotab.h"
+#include "output.h"
#include "scanner.h"
#include "standard.h"
#include "segments.h"
unsigned I;
- /* Initialize the output file name */
- const char* OutputFile = 0;
+ /* Initialize the input file name */
const char* InputFile = 0;
/* Initialize the cmdline module */
break;
case 'o':
- OutputFile = GetArg (&I, 2);
+ SetOutputName (GetArg (&I, 2));
break;
case 'r':
}
/* Create the output file name if it was not explicitly given */
- if (OutputFile == 0) {
- OutputFile = MakeFilename (InputFile, ".s");
- }
+ MakeDefaultOutputName (InputFile);
/* If no CPU given, use the default CPU for the target */
if (CPU == CPU_UNKNOWN) {
Compile (InputFile);
/* Create the output file if we didn't had any errors */
- if (ErrorCount == 0 || Debug) {
+ if (PreprocessOnly == 0 && (ErrorCount == 0 || Debug)) {
/* Open the file */
- FILE* F = fopen (OutputFile, "w");
- if (F == 0) {
- Fatal ("Cannot open output file `%s': %s", OutputFile, strerror (errno));
- }
- Print (stdout, 1, "Opened output file `%s'\n", OutputFile);
+ OpenOutputFile ();
/* Write the output to the file */
- WriteOutput (F);
- Print (stdout, 1, "Wrote output to `%s'\n", OutputFile);
+ WriteAsmOutput ();
+ Print (stdout, 1, "Wrote output to `%s'\n", OutputFilename);
/* Close the file, check for errors */
- if (fclose (F) != 0) {
- remove (OutputFile);
- Fatal ("Cannot write to output file (disk full?)");
- }
- Print (stdout, 1, "Closed output file `%s'\n", OutputFile);
+ CloseOutputFile ();
/* Create dependencies if requested */
if (CreateDep) {
- DoCreateDep (OutputFile);
+ DoCreateDep (OutputFilename);
Print (stdout, 1, "Creating dependeny file\n");
}
macrotab.o \
main.o \
opcodes.o \
+ output.o \
preproc.o \
pragma.o \
reginfo.o \
AR = $(WINE) WLIB
CC = $(WINE) WCC386
LD = $(WINE) WLINK
-WSTRIP = $(WINE) WSTRIP -q
+WSTRIP = $(WINE) WSTRIP -q
LNKCFG = ld.tmp
macrotab.obj \
main.obj \
opcodes.obj \
+ output.obj \
preproc.obj \
pragma.obj \
reginfo.obj \
--- /dev/null
+/*****************************************************************************/
+/* */
+/* output.c */
+/* */
+/* Output file handling */
+/* */
+/* */
+/* */
+/* (C) 2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+
+/* common */
+#include "check.h"
+#include "fname.h"
+#include "print.h"
+#include "xmalloc.h"
+
+/* cc65 */
+#include "error.h"
+#include "global.h"
+#include "output.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Name of the output file. Dynamically allocated and read only. */
+const char* OutputFilename = 0;
+
+/* Output file handle */
+FILE* OutputFile = 0;
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void SetOutputName (const char* Name)
+/* Sets the name of the output file. */
+{
+ OutputFilename = Name;
+}
+
+
+
+void MakeDefaultOutputName (const char* InputFilename)
+/* If the name of the output file is empty or NULL, the name of the output
+ * file is derived from the input file by adjusting the file name extension.
+ */
+{
+ if (OutputFilename == 0 || *OutputFilename == '\0') {
+ /* We don't have an output file for now */
+ const char* Ext = PreprocessOnly? ".i" : ".s";
+ OutputFilename = MakeFilename (InputFilename, Ext);
+ }
+}
+
+
+
+void OpenOutputFile ()
+/* Open the output file. Will call Fatal() in case of failures. */
+{
+ /* Output file must not be open and we must have a name*/
+ PRECONDITION (OutputFile == 0 && OutputFilename != 0);
+
+ /* Open the file */
+ OutputFile = fopen (OutputFilename, "w");
+ if (OutputFile == 0) {
+ Fatal ("Cannot open output file `%s': %s", OutputFilename, strerror (errno));
+ }
+ Print (stdout, 1, "Opened output file `%s'\n", OutputFilename);
+}
+
+
+
+void CloseOutputFile ()
+/* Close the output file. Will call Fatal() in case of failures. */
+{
+ /* Output file must be open */
+ PRECONDITION (OutputFile != 0);
+
+ /* Close the file, check for errors */
+ if (fclose (OutputFile) != 0) {
+ remove (OutputFilename);
+ Fatal ("Cannot write to output file (disk full?)");
+ }
+ Print (stdout, 1, "Closed output file `%s'\n", OutputFilename);
+}
+
+
+
+int WriteOutput (const char* Format, ...)
+/* Write to the output file using printf like formatting. Returns the number
+ * of chars written.
+ */
+{
+ va_list ap;
+ int CharCount;
+
+ /* Must have an output file */
+ PRECONDITION (OutputFile != 0);
+
+ /* Output formatted */
+ va_start (ap, Format);
+ CharCount = vfprintf (OutputFile, Format, ap);
+ va_end (ap);
+
+ /* Return the number of chars written */
+ return CharCount;
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* output.h */
+/* */
+/* Output file handling */
+/* */
+/* */
+/* */
+/* (C) 2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef OUTPUT_H
+#define OUTPUT_H
+
+
+
+#include <stdio.h>
+
+/* common */
+#include "attrib.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Name of the output file. Dynamically allocated and read only. */
+extern const char* OutputFilename;
+
+/* Output file handle. Use WriteOutput if possible. Read only. */
+extern FILE* OutputFile;
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void SetOutputName (const char* Name);
+/* Sets the name of the output file. */
+
+void MakeDefaultOutputName (const char* InputFilename);
+/* If the name of the output file is empty or NULL, the name of the output
+ * file is derived from the input file by adjusting the file name extension.
+ */
+
+void OpenOutputFile ();
+/* Open the output file. Will call Fatal() in case of failures. */
+
+void CloseOutputFile ();
+/* Close the output file. Will call Fatal() in case of failures. */
+
+int WriteOutput (const char* Format, ...) attribute ((format (printf, 1, 2)));
+/* Write to the output file using printf like formatting. Returns the number
+ * of chars written.
+ */
+
+
+/* End of output.h */
+#endif
+
+
+
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
-void OutputSegments (const Segments* S, FILE* F)
-/* Output the given segments to the file */
+void OutputSegments (const Segments* S)
+/* Output the given segments to the output file */
{
/* Output the function prologue if the segments came from a function */
- CS_OutputPrologue (S->Code, F);
+ CS_OutputPrologue (S->Code);
/* Output the text segment */
- TS_Output (S->Text, F);
+ TS_Output (S->Text);
/* Output the three data segments */
- DS_Output (S->Data, F);
- DS_Output (S->ROData, F);
- DS_Output (S->BSS, F);
+ DS_Output (S->Data);
+ DS_Output (S->ROData);
+ DS_Output (S->BSS);
/* Output the code segment */
- CS_Output (S->Code, F);
+ CS_Output (S->Code);
/* Output the code segment epiloque */
- CS_OutputEpilogue (S->Code, F);
+ CS_OutputEpilogue (S->Code);
}
/* */
/* */
/* */
-/* (C) 2000-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2000-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
void RemoveGlobalCode (void);
/* Remove all code from the global code segment. Used for error recovery. */
-void OutputSegments (const Segments* S, FILE* F);
-/* Output the given segments to the file */
+void OutputSegments (const Segments* S);
+/* Output the given segments to the output file */
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "xsprintf.h"
/* cc65 */
+#include "output.h"
#include "textseg.h"
void TS_AddLine (TextSeg* S, const char* Format, ...)
-/* Add a line to the given text segment */
+/* Add a line to the given text segment */
{
va_list ap;
va_start (ap, Format);
-void TS_Output (const TextSeg* S, FILE* F)
-/* Output the text segment data to a file */
+void TS_Output (const TextSeg* S)
+/* Output the text segment data to the output file */
{
unsigned I;
/* Output all entries */
for (I = 0; I < Count; ++I) {
- fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I));
+ WriteOutput ("%s\n", (const char*) CollConstAt (&S->Lines, I));
}
/* Add an additional newline after the segment output */
- fprintf (F, "\n");
+ WriteOutput ("\n");
}
/* */
/* */
/* */
-/* (C) 2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@cc65.org */
+/* (C) 2001-2009, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <stdarg.h>
-#include <stdio.h>
/* common */
#include "attrib.h"
void TS_AddLine (TextSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
/* Add a line to the given text segment */
-void TS_Output (const TextSeg* S, FILE* F);
-/* Output the text segment data to a file */
+void TS_Output (const TextSeg* S);
+/* Output the text segment data to the output file */