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:
parent
d352b85c87
commit
82b998117a
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,7 @@ OBJS = anonname.o \
|
||||
macrotab.o \
|
||||
main.o \
|
||||
opcodes.o \
|
||||
output.o \
|
||||
preproc.o \
|
||||
pragma.o \
|
||||
reginfo.o \
|
||||
|
@ -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
149
src/cc65/output.c
Normal 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
92
src/cc65/output.h
Normal 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
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user