1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-25 17:29:50 +00:00

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 <inputstem>.i or
the file named in the -o option.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3955 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2009-02-23 21:25:59 +00:00
parent d352b85c87
commit 82b998117a
20 changed files with 436 additions and 197 deletions

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 <stdlib.h>
#include <string.h>
/* 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");
}

View File

@ -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 <stdio.h>
#include <string.h>
/* 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 */

View File

@ -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");
}
}

View File

@ -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 <stdio.h>
/* 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 */

View File

@ -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;
/* 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
/* 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 */

View File

@ -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 <stdarg.h>
#include <stdio.h>
/* 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);

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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 <stdarg.h>
#include <stdio.h>
/* 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 */

View File

@ -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");
}

View File

@ -72,6 +72,7 @@ OBJS = anonname.o \
macrotab.o \
main.o \
opcodes.o \
output.o \
preproc.o \
pragma.o \
reginfo.o \

View File

@ -107,6 +107,7 @@ OBJS = anonname.obj \
macrotab.obj \
main.obj \
opcodes.obj \
output.obj \
preproc.obj \
pragma.obj \
reginfo.obj \

149
src/cc65/output.c Normal file
View File

@ -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 <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;
}

92
src/cc65/output.h Normal file
View File

@ -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 <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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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"
@ -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");
}

View File

@ -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 <stdarg.h>
#include <stdio.h>
/* 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 */