PushSegments (0);
/* Identify the compiler version */
+ AddTextLine (";");
AddTextLine ("; File generated by cc65 v %u.%u.%u",
VER_MAJOR, VER_MINOR, VER_PATCH);
+ AddTextLine (";");
/* Insert some object file options */
- AddTextLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"",
+ AddTextLine ("\t.fopt\t\tcompiler,\"cc65 v %u.%u.%u\"",
VER_MAJOR, VER_MINOR, VER_PATCH);
/* If we're producing code for some other CPU, switch the command set */
if (CPU == CPU_65C02) {
- AddTextLine (".pc02");
+ AddTextLine ("\t.pc02");
}
/* Allow auto import for runtime library routines */
- AddTextLine (".autoimport\ton");
+ AddTextLine ("\t.autoimport\ton");
/* Switch the assembler into case sensitive mode */
- AddTextLine (".case\t\ton");
+ AddTextLine ("\t.case\t\ton");
/* Tell the assembler if we want to generate debug info */
- AddTextLine (".debuginfo\t%s", (DebugInfo != 0)? "on" : "off");
+ AddTextLine ("\t.debuginfo\t%s", (DebugInfo != 0)? "on" : "off");
/* Import the stack pointer for direct auto variable access */
- AddTextLine (".importzp\tsp, sreg, regsave, regbank, tmp1, ptr1");
+ AddTextLine ("\t.importzp\tsp, sreg, regsave, regbank, tmp1, ptr1");
/* Define long branch macros */
- AddTextLine (".macpack\tlongbranch");
+ AddTextLine ("\t.macpack\tlongbranch");
+}
+
+
+
+void g_fileinfo (const char* Name, unsigned long Size, unsigned long MTime)
+/* If debug info is enabled, place a file info into the source */
+{
+ if (DebugInfo) {
+ AddTextLine ("\t.dbg\t\tfile, \"%s\", %lu, %lu", Name, Size, MTime);
+ }
}
/*****************************************************************************/
-/* Pre- and postamble */
+/* Files, pre- and postamble */
/*****************************************************************************/
void g_preamble (void);
/* Generate the assembler code preamble */
+void g_fileinfo (const char* Name, unsigned long Size, unsigned long MTime);
+/* If debug info is enabled, place a file info into the source */
+
/*****************************************************************************/
/* 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.
+ * 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 */
if (AddSource) {
fprintf (F, ";\n; %s\n;\n", LI->Line);
}
+
+ /* Add line debug info */
+ if (DebugInfo) {
+ fprintf (F, "\t.dbg\tline, \"%s\", %u\n",
+ GetInputName (LI), GetInputLine (LI));
+ }
}
/* Output the code */
OutputCodeEntry (E, F);
#include "function.h"
#include "global.h"
#include "incpath.h"
+#include "input.h"
#include "litpool.h"
#include "macrotab.h"
#include "pragma.h"
-void Compile (void)
+void Compile (const char* FileName)
/* Top level compile routine. Will setup things and call the parser. */
{
char* Path;
/* Generate the code generator preamble */
g_preamble ();
+ /* Open the input file */
+ OpenMainFile (FileName);
+
/* Ok, start the ball rolling... */
Parse ();
-void Compile (void);
+void Compile (const char* FileName);
/* Top level compile routine. Will setup things and call the parser. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
/* common */
#include "check.h"
#include "xmalloc.h"
/* cc65 */
-#include "asmcode.h"
+#include "asmcode.h"
+#include "codegen.h"
#include "error.h"
#include "incpath.h"
#include "lineinfo.h"
/*****************************************************************************/
-/* struct IFile */
+/* Helper functions */
+/*****************************************************************************/
+
+
+
+static long GetFileSize (FILE* F)
+/* Calculate the size of the file F, return -1 on error. */
+{
+ long Size;
+ long CurPos = ftell (F);
+ if (CurPos < 0) {
+ /* Error */
+ return -1;
+ }
+ if (fseek (F, 0, SEEK_END) != 0) {
+ /* Error */
+ return -1;
+ }
+ Size = ftell (F);
+ if (Size < 0) {
+ /* Error */
+ return -1;
+ }
+ if (fseek (F, CurPos, SEEK_SET) != 0) {
+ /* Error */
+ return -1;
+ }
+ return Size;
+}
+
+
+
+static long GetFileTime (const char* Name)
+/* Get the time of last modification for the given file. Return -1 on errors. */
+{
+ struct stat Buf;
+ if (stat (Name, &Buf) != 0) {
+ /* Error */
+ return -1;
+ }
+ return (long) Buf.st_mtime;
+}
+
+
+
+/*****************************************************************************/
+/* struct IFile */
/*****************************************************************************/
/* Initialize the fields */
IF->Index = CollCount (&IFiles) + 1;
IF->Usage = 0;
+ IF->Size = 0;
+ IF->MTime = 0;
memcpy (IF->Name, Name, Len+1);
/* Insert the new structure into the IFile collection */
AF->F = F;
AF->Input = IF;
- /* Increment the usage counter of the corresponding IFile */
- ++IF->Usage;
+ /* Increment the usage counter of the corresponding IFile. If this
+ * is the first use, set the file data and output debug info if
+ * requested.
+ */
+ if (IF->Usage++ == 0) {
+
+ long Val;
+
+ /* Get the file size */
+ Val = GetFileSize (AF->F);
+ if (Val < 0) {
+ Fatal ("Cannot seek on `%s': %s", IF->Name, strerror (errno));
+ }
+ IF->Size = Val;
+
+ /* Get the file modification time */
+ Val = GetFileTime (IF->Name);
+ if (Val < 0) {
+ Fatal ("Cannot stat `%s': %s", IF->Name, strerror (errno));
+ }
+ IF->MTime = Val;
+
+ /* Set the debug data */
+ g_fileinfo (IF->Name, IF->Size, IF->MTime);
+ }
/* Insert the new structure into the AFile collection */
CollAppend (&AFiles, AF);
/* Struct that describes an input file */
typedef struct IFile IFile;
struct IFile {
- unsigned Index; /* File index */
- unsigned Usage; /* Usage counter */
- char Name[1]; /* Name of file (dynamically allocated) */
+ unsigned Index; /* File index */
+ unsigned Usage; /* Usage counter */
+ unsigned long Size; /* File size */
+ unsigned long MTime; /* Time of last modification */
+ char Name[1]; /* Name of file (dynamically allocated) */
};
void ClearLine (void);
/* Clear the current input line */
-
+
void InitLine (const char* Buf);
/* Initialize lptr from Buf and read CurC and NextC from the new input line */
#include "error.h"
#include "global.h"
#include "incpath.h"
-#include "input.h"
+#include "input.h"
#include "macrotab.h"
#include "scanner.h"
#include "segments.h"
AbEnd ("No input files");
}
- /* Open the input file */
- OpenMainFile (InputFile);
-
/* Create the output file name if it was not explicitly given */
if (OutputFile == 0) {
OutputFile = MakeFilename (InputFile, ".s");
}
/* Go! */
- Compile ();
+ Compile (InputFile);
/* Create the output file if we didn't had any errors */
if (ErrorCount == 0 || Debug) {