From 82b998117aac8b470e0250458b61d7e804c9ca93 Mon Sep 17 00:00:00 2001 From: uz Date: Mon, 23 Feb 2009 21:25:59 +0000 Subject: [PATCH] Added a separate output module that is used to manage the output file. Fixed the -E switch: Output was always sent to stdout and an empty assembler output file was generated. Now the output is sent to either .i or the file named in the -o option. git-svn-id: svn://svn.cc65.org/cc65/trunk@3955 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/asmcode.c | 16 ++--- src/cc65/asmcode.h | 12 ++-- src/cc65/codeent.c | 54 +++++++------- src/cc65/codeent.h | 9 ++- src/cc65/codelab.c | 17 ++--- src/cc65/codelab.h | 14 ++-- src/cc65/codeseg.c | 95 +++++++++++++------------ src/cc65/codeseg.h | 17 +++-- src/cc65/compile.c | 14 +++- src/cc65/dataseg.c | 21 +++--- src/cc65/dataseg.h | 13 ++-- src/cc65/main.c | 38 ++++------ src/cc65/make/gcc.mak | 1 + src/cc65/make/watcom.mak | 3 +- src/cc65/output.c | 149 +++++++++++++++++++++++++++++++++++++++ src/cc65/output.h | 92 ++++++++++++++++++++++++ src/cc65/segments.c | 26 +++---- src/cc65/segments.h | 12 ++-- src/cc65/textseg.c | 19 ++--- src/cc65/textseg.h | 13 ++-- 20 files changed, 437 insertions(+), 198 deletions(-) create mode 100644 src/cc65/output.c create mode 100644 src/cc65/output.h diff --git a/src/cc65/asmcode.c b/src/cc65/asmcode.c index f81d3ebb8..a09b00dfa 100644 --- a/src/cc65/asmcode.c +++ b/src/cc65/asmcode.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -96,15 +96,15 @@ int CodeRangeIsEmpty (const CodeMark* Start, const CodeMark* End) -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 (); @@ -116,7 +116,7 @@ void WriteOutput (FILE* F) /* 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; } diff --git a/src/cc65/asmcode.h b/src/cc65/asmcode.h index 745be2118..b43cfce8d 100644 --- a/src/cc65/asmcode.h +++ b/src/cc65/asmcode.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -79,8 +79,8 @@ void MoveCode (const CodeMark* Start, const CodeMark* End, const CodeMark* Targe 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 */ diff --git a/src/cc65/codeent.c b/src/cc65/codeent.c index 13b7aed14..aed401d88 100644 --- a/src/cc65/codeent.c +++ b/src/cc65/codeent.c @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -34,7 +34,6 @@ #include -#include /* common */ #include "chartype.h" @@ -44,12 +43,13 @@ #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" @@ -1362,8 +1362,8 @@ static char* RegContentDesc (const RegContents* RC, char* Buf) -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; @@ -1373,14 +1373,14 @@ void CE_Output (const CodeEntry* E, FILE* F) 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) { @@ -1391,50 +1391,50 @@ void CE_Output (const CodeEntry* E, FILE* F) 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: @@ -1446,25 +1446,23 @@ void CE_Output (const CodeEntry* E, FILE* F) 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"); } diff --git a/src/cc65/codeent.h b/src/cc65/codeent.h index 01a815728..db3d17106 100644 --- a/src/cc65/codeent.h +++ b/src/cc65/codeent.h @@ -6,8 +6,8 @@ /* */ /* */ /* */ -/* (C) 2001-2005, Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 2001-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -38,7 +38,6 @@ -#include #include /* common */ @@ -223,8 +222,8 @@ void CE_GenRegInfo (CodeEntry* E, RegContents* InputRegs); * 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 */ diff --git a/src/cc65/codelab.c b/src/cc65/codelab.c index 7fd66e7e2..9e3b93765 100644 --- a/src/cc65/codelab.c +++ b/src/cc65/codelab.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -40,6 +40,7 @@ /* cc65 */ #include "codeent.h" #include "codelab.h" +#include "output.h" @@ -122,13 +123,13 @@ void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel) -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"); } } diff --git a/src/cc65/codelab.h b/src/cc65/codelab.h index 8f298e0fb..649c0a2b7 100644 --- a/src/cc65/codelab.h +++ b/src/cc65/codelab.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -38,8 +38,6 @@ -#include - /* common */ #include "coll.h" @@ -113,8 +111,8 @@ void CL_MoveRefs (CodeLabel* OldLabel, CodeLabel* NewLabel); * 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 */ diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index ad1b3aeb7..55b7aa697 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2001-2008, Ullrich von Bassewitz */ +/* (C) 2001-2009, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -55,6 +55,7 @@ #include "error.h" #include "global.h" #include "ident.h" +#include "output.h" #include "symentry.h" @@ -65,22 +66,20 @@ -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"); } } @@ -1225,7 +1224,7 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last) -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 @@ -1241,34 +1240,34 @@ void CS_OutputPrologue (const CodeSeg* S, FILE* F) */ 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; @@ -1285,51 +1284,55 @@ void CS_Output (CodeSeg* S, FILE* F) 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 */ diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h index 100bb2604..453dd7a52 100644 --- a/src/cc65/codeseg.h +++ b/src/cc65/codeseg.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -39,7 +39,6 @@ #include -#include /* common */ #include "attrib.h" @@ -267,19 +266,19 @@ int CS_IsBasicBlock (CodeSeg* S, unsigned First, unsigned Last); * 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); @@ -291,7 +290,7 @@ void CS_GenRegInfo (CodeSeg* S); /* End of codeseg.h */ -#endif +#endif diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 8475657a4..2e6acadd1 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -2,11 +2,11 @@ /* */ /* 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 */ @@ -55,6 +55,7 @@ #include "input.h" #include "litpool.h" #include "macrotab.h" +#include "output.h" #include "pragma.h" #include "preproc.h" #include "standard.h" @@ -344,11 +345,18 @@ void Compile (const char* FileName) /* 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); } diff --git a/src/cc65/dataseg.c b/src/cc65/dataseg.c index 72b22ce76..ebb033cbc 100644 --- a/src/cc65/dataseg.c +++ b/src/cc65/dataseg.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -39,8 +39,9 @@ #include "xsprintf.h" /* cc65 */ -#include "error.h" #include "dataseg.h" +#include "error.h" +#include "output.h" @@ -105,8 +106,8 @@ void DS_AddLine (DataSeg* S, const char* Format, ...) -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; @@ -119,15 +120,15 @@ void DS_Output (const DataSeg* S, FILE* F) } /* 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"); } diff --git a/src/cc65/dataseg.h b/src/cc65/dataseg.h index af1b02448..dab06e893 100644 --- a/src/cc65/dataseg.h +++ b/src/cc65/dataseg.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -39,7 +39,6 @@ #include -#include /* common */ #include "attrib.h" @@ -83,8 +82,8 @@ void DS_AddVLine (DataSeg* S, const char* Format, va_list ap) attribute ((format 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 */ diff --git a/src/cc65/main.c b/src/cc65/main.c index c058f13de..d3ba3e4ac 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -62,6 +62,7 @@ #include "incpath.h" #include "input.h" #include "macrotab.h" +#include "output.h" #include "scanner.h" #include "standard.h" #include "segments.h" @@ -720,8 +721,7 @@ int main (int argc, char* argv[]) unsigned I; - /* Initialize the output file name */ - const char* OutputFile = 0; + /* Initialize the input file name */ const char* InputFile = 0; /* Initialize the cmdline module */ @@ -769,7 +769,7 @@ int main (int argc, char* argv[]) break; case 'o': - OutputFile = GetArg (&I, 2); + SetOutputName (GetArg (&I, 2)); break; case 'r': @@ -866,9 +866,7 @@ int main (int argc, char* argv[]) } /* 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) { @@ -893,29 +891,21 @@ int main (int argc, char* argv[]) 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"); } diff --git a/src/cc65/make/gcc.mak b/src/cc65/make/gcc.mak index 1752e1029..2bae8a73a 100644 --- a/src/cc65/make/gcc.mak +++ b/src/cc65/make/gcc.mak @@ -72,6 +72,7 @@ OBJS = anonname.o \ macrotab.o \ main.o \ opcodes.o \ + output.o \ preproc.o \ pragma.o \ reginfo.o \ diff --git a/src/cc65/make/watcom.mak b/src/cc65/make/watcom.mak index bf31faaf4..b861e169c 100644 --- a/src/cc65/make/watcom.mak +++ b/src/cc65/make/watcom.mak @@ -17,7 +17,7 @@ WINE = wine AR = $(WINE) WLIB CC = $(WINE) WCC386 LD = $(WINE) WLINK -WSTRIP = $(WINE) WSTRIP -q +WSTRIP = $(WINE) WSTRIP -q LNKCFG = ld.tmp @@ -107,6 +107,7 @@ OBJS = anonname.obj \ macrotab.obj \ main.obj \ opcodes.obj \ + output.obj \ preproc.obj \ pragma.obj \ reginfo.obj \ diff --git a/src/cc65/output.c b/src/cc65/output.c new file mode 100644 index 000000000..1c40e04a2 --- /dev/null +++ b/src/cc65/output.c @@ -0,0 +1,149 @@ +/*****************************************************************************/ +/* */ +/* 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 +#include +#include +#include + +/* 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; +} + + + diff --git a/src/cc65/output.h b/src/cc65/output.h new file mode 100644 index 000000000..cdcd42c4d --- /dev/null +++ b/src/cc65/output.h @@ -0,0 +1,92 @@ +/*****************************************************************************/ +/* */ +/* 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 + +/* 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 + + + diff --git a/src/cc65/segments.c b/src/cc65/segments.c index 57f1a8047..97fa98cea 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -272,25 +272,25 @@ void RemoveGlobalCode (void) -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); } diff --git a/src/cc65/segments.h b/src/cc65/segments.h index 6d6ad2fac..fd4d2d5f3 100644 --- a/src/cc65/segments.h +++ b/src/cc65/segments.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -147,8 +147,8 @@ int HaveGlobalCode (void); 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 */ diff --git a/src/cc65/textseg.c b/src/cc65/textseg.c index f15f13f18..172a1c450 100644 --- a/src/cc65/textseg.c +++ b/src/cc65/textseg.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -44,6 +44,7 @@ #include "xsprintf.h" /* cc65 */ +#include "output.h" #include "textseg.h" @@ -84,7 +85,7 @@ void TS_AddVLine (TextSeg* S, const char* Format, va_list ap) 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); @@ -94,8 +95,8 @@ void TS_AddLine (TextSeg* S, const char* 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; @@ -109,11 +110,11 @@ void TS_Output (const TextSeg* S, FILE* F) /* 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"); } diff --git a/src/cc65/textseg.h b/src/cc65/textseg.h index 568903e12..7aa53a3e0 100644 --- a/src/cc65/textseg.h +++ b/src/cc65/textseg.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -45,7 +45,6 @@ #include -#include /* common */ #include "attrib.h" @@ -85,8 +84,8 @@ void TS_AddVLine (TextSeg* S, const char* Format, va_list ap) attribute ((format 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 */ -- 2.39.5