1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-08 15:29:37 +00:00

Use the xmalloc module from the common directory.

Rewrote the include file management, keeping a list of all include files
and cleaning up the code while going.


git-svn-id: svn://svn.cc65.org/cc65/trunk@82 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2000-06-14 21:01:37 +00:00
parent d10bf32c4c
commit aa8737733f
27 changed files with 467 additions and 902 deletions

View File

@ -35,10 +35,10 @@
#include <stdio.h>
#include "../common/xmalloc.h"
#include "../common/xsprintf.h"
#include "error.h"
#include "mem.h"
#include "asmline.h"

View File

@ -37,6 +37,7 @@
#include <string.h>
#include "../common/version.h"
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "asmlabel.h"
@ -46,7 +47,6 @@
#include "global.h"
#include "io.h"
#include "litpool.h"
#include "mem.h"
#include "optimize.h"
#include "util.h"
#include "codegen.h"
@ -946,13 +946,22 @@ void g_leasp (int offs)
ldaconst (offs); /* Load A with offset value */
AddCodeLine ("\tjsr\tleaasp"); /* Load effective address */
} else {
ldaconst (offs);
AddCodeLine ("\tclc");
AddCodeLine ("\tldx\tsp+1");
AddCodeLine ("\tadc\tsp");
AddCodeLine ("\tbcc\t*+3");
AddCodeLine ("\tinx");
AddCodeHint ("x:!"); /* Invalidate X */
if (CPU == CPU_65C02 && offs == 1) {
AddCodeLine ("\tlda\tsp");
AddCodeLine ("\tldx\tsp+1");
AddCodeLine ("\tina");
AddCodeLine ("\tbne\t*+3");
AddCodeLine ("\tinx");
AddCodeHint ("x:!"); /* Invalidate X */
} else {
ldaconst (offs);
AddCodeLine ("\tclc");
AddCodeLine ("\tldx\tsp+1");
AddCodeLine ("\tadc\tsp");
AddCodeLine ("\tbcc\t*+3");
AddCodeLine ("\tinx");
AddCodeHint ("x:!"); /* Invalidate X */
}
}
}
}
@ -1764,7 +1773,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val)
AddCodeLine ("\tjsr\tpushax"); /* Push the address */
push (flags); /* Correct the internal sp */
g_getind (flags, offs); /* Fetch the value */
g_inc (flags, val); /* Increment value in primary */
g_inc (flags, val); /* Increment value in primary */
g_putind (flags, offs); /* Store the value back */
break;
@ -3723,7 +3732,7 @@ void g_zerobytes (unsigned n)
AddCodeLine ("\t.res\t%u,$00", n);
}
/*****************************************************************************/
/* Inlined known functions */

View File

@ -61,10 +61,7 @@
static void Parse (void)
/* Process all input text.
* At this level, only static declarations, defines, includes, and function
* definitions are legal....
*/
/* Top level parser routine. */
{
int comma;
SymEntry* Entry;
@ -253,7 +250,6 @@ void Compile (void)
/* Setup variables */
filetab[0].f_iocb = inp;
LiteralLabel = GetLabel ();
/* Add some standard paths to the include search path */

View File

@ -35,13 +35,14 @@
#include <string.h>
#include "../common/xmalloc.h"
#include "check.h"
#include "codegen.h"
#include "datatype.h"
#include "error.h"
#include "funcdesc.h"
#include "global.h"
#include "mem.h"
#include "util.h"
#include "symtab.h"

View File

@ -11,6 +11,8 @@
#include <errno.h>
#include <ctype.h>
#include "../common/xmalloc.h"
#include "anonname.h"
#include "codegen.h"
#include "datatype.h"
@ -20,7 +22,6 @@
#include "function.h"
#include "global.h"
#include "litpool.h"
#include "mem.h"
#include "pragma.h"
#include "scanner.h"
#include "symtab.h"

View File

@ -38,6 +38,7 @@
#include <stdarg.h>
#include "global.h"
#include "input.h"
#include "io.h"
#include "scanner.h"
#include "stmt.h"
@ -185,7 +186,8 @@ void Warning (unsigned WarnNum, ...)
va_list ap;
if (!NoWarn) {
fprintf (stderr, "%s(%u): Warning #%u: ", fin, curpos, WarnNum);
fprintf (stderr, "%s(%u): Warning #%u: ",
GetCurrentFile(), curpos, WarnNum);
va_start (ap, WarnNum);
vfprintf (stderr, WarnMsg [WarnNum-1], ap);
@ -207,7 +209,8 @@ void PPWarning (unsigned WarnNum, ...)
va_list ap;
if (!NoWarn) {
fprintf (stderr, "%s(%u): Warning #%u: ", fin, ln, WarnNum);
fprintf (stderr, "%s(%u): Warning #%u: ",
GetCurrentFile(), GetCurrentLine(), WarnNum);
va_start (ap, WarnNum);
vfprintf (stderr, WarnMsg [WarnNum-1], ap);
@ -224,7 +227,8 @@ void Error (unsigned ErrNum, ...)
{
va_list ap;
fprintf (stderr, "%s(%u): Error #%u: ", fin, curpos, ErrNum);
fprintf (stderr, "%s(%u): Error #%u: ",
GetCurrentFile(), curpos, ErrNum);
va_start (ap, ErrNum);
vfprintf (stderr, ErrMsg [ErrNum-1], ap);
@ -247,7 +251,8 @@ void PPError (unsigned ErrNum, ...)
{
va_list ap;
fprintf (stderr, "%s(%u): Error #%u: ", fin, ln, ErrNum);
fprintf (stderr, "%s(%u): Error #%u: ",
GetCurrentFile(), GetCurrentLine(), ErrNum);
va_start (ap, ErrNum);
vfprintf (stderr, ErrMsg [ErrNum-1], ap);
@ -267,7 +272,8 @@ void Fatal (unsigned FatNum, ...)
{
va_list ap;
fprintf (stderr, "%s(%u): Fatal #%u: ", fin, curpos, FatNum);
fprintf (stderr, "%s(%u): Fatal #%u: ",
GetCurrentFile(), curpos, FatNum);
va_start (ap, FatNum);
vfprintf (stderr, FatMsg [FatNum-1], ap);
@ -287,7 +293,8 @@ void Internal (char* Format, ...)
{
va_list ap;
fprintf (stderr, "%s(%u): Internal compiler error:\n", fin, curpos);
fprintf (stderr, "%s(%u): Internal compiler error:\n",
GetCurrentFile(), curpos);
va_start (ap, Format);
vfprintf (stderr, Format, ap);
@ -310,3 +317,4 @@ void ErrorReport (void)

View File

@ -10,6 +10,8 @@
#include <stdlib.h>
#include <string.h>
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "asmlabel.h"
#include "check.h"
@ -23,7 +25,6 @@
#include "io.h"
#include "litpool.h"
#include "macrotab.h"
#include "mem.h"
#include "preproc.h"
#include "scanner.h"
#include "stdfunc.h"

View File

@ -33,7 +33,8 @@
#include "mem.h"
#include "../common/xmalloc.h"
#include "funcdesc.h"

View File

@ -33,6 +33,8 @@
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "asmlabel.h"
#include "codegen.h"
@ -40,7 +42,6 @@
#include "funcdesc.h"
#include "litpool.h"
#include "locals.h"
#include "mem.h"
#include "scanner.h"
#include "stmt.h"
#include "symtab.h"

View File

@ -44,7 +44,8 @@
# include <unistd.h>
#endif
#include "mem.h"
#include "../common/xmalloc.h"
#include "incpath.h"

279
src/cc65/input.c Normal file
View File

@ -0,0 +1,279 @@
/*****************************************************************************/
/* */
/* input.c */
/* */
/* Input file handling */
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* 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 <string.h>
#include <errno.h>
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "check.h"
#include "error.h"
#include "global.h"
#include "incpath.h"
#include "io.h"
#include "input.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Maximum count of nested includes */
#define MAX_INC_NESTING 16
/* Struct that describes an input file */
typedef struct IFile IFile;
struct IFile {
IFile* Next; /* Next file in single linked list */
IFile* Active; /* Next file in list of active includes */
unsigned Index; /* File index */
unsigned Line; /* Line number for this file */
FILE* F; /* Input file stream */
char Name[1]; /* Name of file (dynamically allocated) */
};
/* List of input files */
static unsigned IFileTotal = 0; /* Total number of files */
static IFile* IFileList = 0; /* Single linked list of all files */
static unsigned IFileCount = 0; /* Number of active input files */
static IFile* Input = 0; /* Single linked list of active files */
/*****************************************************************************/
/* struct IFile */
/*****************************************************************************/
static IFile* NewIFile (const char* Name, FILE* F)
/* Create and return a new IFile */
{
/* Get the length of the name */
unsigned Len = strlen (Name);
/* Allocate a IFile structure */
IFile* IF = xmalloc (sizeof (IFile) + Len);
/* Initialize the fields */
IF->Index = ++IFileTotal;
IF->Line = 0;
IF->F = F;
memcpy (IF->Name, Name, Len+1);
/* Insert the structure into both lists */
IF->Next = IFileList;
IFileList = IF;
IF->Active = Input;
Input = IF;
++IFileCount;
/* Return the new struct */
return IF;
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void OpenMainFile (const char* Name)
/* Open the main file. Will call Fatal() in case of failures. */
{
/* Open the file for reading */
FILE* F = fopen (Name, "r");
if (F == 0) {
/* Cannot open */
Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno));
}
/* Setup a new IFile structure */
NewIFile (Name, F);
}
void OpenIncludeFile (const char* Name, unsigned DirSpec)
/* Open an include file and insert it into the tables. */
{
char* N;
FILE* F;
/* Check for the maximum include nesting */
if (IFileCount > MAX_INC_NESTING) {
PPError (ERR_INCLUDE_NESTING);
return;
}
/* Search for the file */
N = FindInclude (Name, DirSpec);
if (N == 0) {
PPError (ERR_INCLUDE_NOT_FOUND, Name);
return;
}
/* Open the file */
F = fopen (N, "r");
if (F == 0) {
/* Error opening the file */
PPError (ERR_INCLUDE_OPEN_FAILURE, N);
xfree (N);
return;
}
/* Allocate a new IFile structure */
NewIFile (N, F);
/* We don't need the full name any longer */
xfree (N);
}
static void CloseIncludeFile (void)
/* Close an include file and switch to the higher level file. Set Input to
* NULL if this was the main file.
*/
{
/* Must have an input file when called */
PRECONDITION (Input != 0);
/* Close the current input file (we're just reading so no error check) */
fclose (Input->F);
/* Make this file inactive and the last one active again */
Input = Input->Active;
}
int NextLine (void)
/* Get a line from the current input. Returns 0 on end of file. */
{
unsigned Len;
unsigned Part;
unsigned Start;
int Done;
/* Setup the line */
kill ();
/* If there is no file open, bail out */
if (Input == 0) {
return 0;
}
/* Read lines until we get one with real contents */
Len = 0;
Done = 0;
while (!Done && Len < LINESIZE) {
while (fgets (line + Len, LINESIZE - Len, Input->F) == 0) {
/* eof */
kill ();
/* Leave the current file */
CloseIncludeFile ();
/* If this was the last file, bail out */
if (Input == 0) {
return 0;
}
}
/* We got a new line */
++Input->Line;
/* Remove the trailing newline if we have one */
Part = strlen (line + Len);
Start = Len;
Len += Part;
while (Len > 0 && line [Len-1] == '\n') {
--Len;
}
line [Len] = '\0';
/* Output the source line in the generated assembler file
* if requested.
*/
if (AddSource && line[Start] != '\0') {
AddCodeLine ("; %s", line+Start);
}
/* Check if we have a line continuation character at the end. If not,
* we're done.
*/
if (Len > 0 && line[Len-1] == '\\') {
line[Len-1] = '\n'; /* Replace by newline */
} else {
Done = 1;
}
}
/* Got a line */
return 1;
}
const char* GetCurrentFile (void)
/* Return the name of the current input file */
{
if (Input == 0) {
return "(outside file scope)";
} else {
return Input->Name;
}
}
unsigned GetCurrentLine (void)
/* Return the line number in the current input file */
{
return Input? Input->Line : 0;
}

View File

@ -1,15 +1,15 @@
/*****************************************************************************/
/* */
/* mem.h */
/* input.h */
/* */
/* Safe memory allocation for the cc65 C compiler */
/* Input file handling */
/* */
/* */
/* */
/* (C) 1998 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -33,43 +33,35 @@
#ifndef MEM_H
#define MEM_H
#include <stddef.h>
#ifndef INPUT_H
#define INPUT_H
/*****************************************************************************/
/* data */
/* Code */
/*****************************************************************************/
extern size_t memmax;
void OpenMainFile (const char* Name);
/* Open the main file. Will call Fatal() in case of failures. */
void OpenIncludeFile (const char* Name, unsigned DirSpec);
/* Open an include file and insert it into the tables. */
int NextLine (void);
/* Get a line from the current input. Returns 0 on end of file. */
const char* GetCurrentFile (void);
/* Return the name of the current input file */
unsigned GetCurrentLine (void);
/* Return the line number in the current input file */
/*****************************************************************************/
/* code */
/*****************************************************************************/
void* xmalloc (size_t size);
/* Allocate memory, check for out of memory condition. Do some debugging */
void xfree (const void* block);
/* Free the block, do some debugging */
char* xstrdup (const char* s);
/* Duplicate a string on the heap. The function checks for out of memory */
/* End of mem.h */
/* End of input.h */
#endif

View File

@ -1,17 +1,7 @@
/* C I/O functions */
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include "asmcode.h"
#include "global.h"
#include "error.h"
#include "mem.h"
#include "codegen.h"
#include "optimize.h"
#include "io.h"
@ -27,15 +17,6 @@ char linebuf [LINESIZE];
char* line = linebuf;
char* lptr = 0;
/* Input file table and number of open input files */
struct filent filetab[MAXFILES];
int ifile = 0;
/* Current input file stream data */
FILE* inp = 0;
char* fin = 0;
unsigned ln = 0;
/*****************************************************************************/
@ -89,96 +70,3 @@ void kill (void)
static void CloseInclude (void)
/* Close an include file and switch to the higher level file. Set inp to NULL
* if this was the main file.
*/
{
struct filent* pftab;
/* Close the file */
fclose(inp);
/* Leave the include file */
if (ifile > 0) {
xfree (fin);
inp = (pftab = &filetab[--ifile])->f_iocb;
ln = pftab->f_ln;
fin = pftab->f_name;
} else {
inp = 0;
}
}
int NextLine (void)
/* Get a line from the current input. Returns -1 on end of file. */
{
unsigned Len;
unsigned Part;
unsigned Start;
int Done;
/* Setup the line */
kill ();
/* If there is no file open, bail out */
if (inp == 0) {
return 0;
}
/* Read lines until we get one with real contents */
Len = 0;
Done = 0;
while (!Done && Len < LINESIZE) {
while (fgets (line + Len, LINESIZE - Len, inp) == 0) {
/* eof */
kill ();
/* Leave the current file */
CloseInclude ();
/* If this was the last file, bail out */
if (inp == 0) {
return 0;
}
}
/* We got a new line */
++ln;
/* Remove the trailing newline if we have one */
Part = strlen (line + Len);
Start = Len;
Len += Part;
while (Len > 0 && line [Len-1] == '\n') {
--Len;
}
line [Len] = '\0';
/* Output the source line in the generated assembler file
* if requested.
*/
if (AddSource && line[Start] != '\0') {
AddCodeLine ("; %s", line+Start);
}
/* Check if we have a line continuation character at the end. If not,
* we're done.
*/
if (Len > 0 && line[Len-1] == '\\') {
line[Len-1] = '\n'; /* Replace by newline */
} else {
Done = 1;
}
}
/* Got a line */
return 1;
}

View File

@ -40,15 +40,6 @@ struct filent {
int f_ln;
};
/* Input file table and number of open input files */
extern struct filent filetab[MAXFILES];
extern int ifile;
/* Current input file stream data */
extern FILE* inp; /* Input file stream */
extern char* fin; /* Input file name */
extern unsigned ln; /* Line number */
/*****************************************************************************/
@ -73,9 +64,6 @@ int gch (void);
* pointer (no end of line check is performed).
*/
int NextLine (void);
/* Get a line from the current input. Returns -1 on end of file. */
/* End of io.h */

View File

@ -33,6 +33,8 @@
#include "../common/xmalloc.h"
#include "anonname.h"
#include "asmlabel.h"
#include "codegen.h"
@ -40,7 +42,6 @@
#include "expr.h"
#include "function.h"
#include "global.h"
#include "mem.h"
#include "symtab.h"
#include "locals.h"

View File

@ -6,8 +6,9 @@
#include "../common/xmalloc.h"
#include "error.h"
#include "mem.h"
#include "loop.h"

View File

@ -37,9 +37,9 @@
#include <string.h>
#include "../common/hashstr.h"
#include "../common/xmalloc.h"
#include "error.h"
#include "mem.h"
#include "macrotab.h"

View File

@ -42,6 +42,7 @@
#include "../common/cmdline.h"
#include "../common/fname.h"
#include "../common/version.h"
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "compile.h"
@ -49,9 +50,8 @@
#include "error.h"
#include "global.h"
#include "incpath.h"
#include "io.h"
#include "input.h"
#include "macrotab.h"
#include "mem.h"
#include "optimize.h"
#include "scanner.h"
@ -379,8 +379,7 @@ int main (int argc, char* argv[])
/* Initialize the output file name */
const char* OutputFile = 0;
fin = NULL;
const char* InputFile = 0;
/* Initialize the cmdline module */
InitCmdLine (argc, argv, "cc65");
@ -409,7 +408,7 @@ int main (int argc, char* argv[])
case 'h':
case '?':
OptHelp (Arg, 0);
OptHelp (Arg, 0);
break;
case 'g':
@ -418,7 +417,7 @@ int main (int argc, char* argv[])
case 'j':
OptSignedChars (Arg, 0);
break;
break;
case 'o':
OutputFile = GetArg (&I, 2);
@ -463,44 +462,40 @@ int main (int argc, char* argv[])
case 'f':
sscanf (P, "%lx", (long*) &OptDisable);
break;
case 'i':
FavourSize = 0;
break;
case 'r':
EnableRegVars = 1;
break;
case 's':
InlineStdFuncs = 1;
break;
}
}
break;
case 'i':
FavourSize = 0;
break;
case 'r':
EnableRegVars = 1;
break;
case 's':
InlineStdFuncs = 1;
break;
}
}
break;
case 'T':
OptAddSource (Arg, 0);
break;
case 'T':
OptAddSource (Arg, 0);
break;
case 'V':
OptVersion (Arg, 0);
break;
case 'V':
OptVersion (Arg, 0);
break;
case 'W':
NoWarn = 1;
break;
case 'W':
NoWarn = 1;
break;
default:
default:
UnknownOption (Arg);
break;
break;
}
} else {
if (fin) {
fprintf (stderr, "additional file specs ignored\n");
if (InputFile) {
fprintf (stderr, "additional file specs ignored\n");
} else {
fin = xstrdup (Arg);
inp = fopen (fin, "r");
if (inp == 0) {
Fatal (FAT_CANNOT_OPEN_INPUT, strerror (errno));
}
InputFile = Arg;
}
}
@ -509,14 +504,17 @@ int main (int argc, char* argv[])
}
/* Did we have a file spec on the command line? */
if (!fin) {
if (InputFile == 0) {
fprintf (stderr, "%s: No input files\n", argv [0]);
exit (EXIT_FAILURE);
}
/* Open the input file */
OpenMainFile (InputFile);
/* Create the output file name if it was not explicitly given */
if (OutputFile == 0) {
OutputFile = MakeFilename (fin, ".s");
OutputFile = MakeFilename (InputFile, ".s");
}
/* Go! */

View File

@ -28,13 +28,13 @@ OBJS = anonname.o \
goto.o \
ident.o \
incpath.o \
input.o \
io.o \
litpool.o \
locals.o \
loop.o \
macrotab.o \
main.o \
mem.o \
optimize.o \
preproc.o \
pragma.o \

View File

@ -82,13 +82,13 @@ OBJS = anonname.obj \
goto.obj \
ident.obj \
incpath.obj \
input.obj \
io.obj \
litpool.obj \
locals.obj \
loop.obj \
macrotab.obj \
main.obj \
mem.obj \
optimize.obj \
pragma.obj \
preproc.obj \
@ -139,13 +139,13 @@ FILE global.obj
FILE goto.obj
FILE ident.obj
FILE incpath.obj
FILE input.obj
FILE io.obj
FILE litpool.obj
FILE locals.obj
FILE loop.obj
FILE macrotab.obj
FILE main.obj
FILE mem.obj
FILE optimize.obj
FILE pragma.obj
FILE preproc.obj

View File

@ -1,605 +0,0 @@
/*****************************************************************************/
/* */
/* MEMCHECK.CC */
/* */
/* (C) 1995 Ullrich von Bassewitz */
/* Zwehrenbuehlstrasse 33 */
/* D-72070 Tuebingen */
/* EMail: uz@ibb.schwaben.com */
/* */
/*****************************************************************************/
// Poor man's memory checker. Overloads the global operators new and delete
// and does some additional checks if the variable MemCheck is set to true:
//
// * Check if an allocated block is already allocated (heap corrupt)
// * Check if a block that should be freed is allocated
// * Check if there have been writes outside the blocks bounds (by
// adding a signature to the end)
// * Check if new does not provide a NULL pointer.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#if defined(__WATCOMC__) || defined(_MSC_VER)
# include <malloc.h>
#endif
#include "check.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
typedef unsigned long u32;
// Signature of a memory block
static u32 MemSig = 0x12785634;
// Switch memory checking on or off
int MemCheck = 0;
// Switch memory filling on or off
int MemFill = 0;
// Validation on each call?
int MemValidate = 0;
// Don't really free blocks
int MemDontFree = 0;
// Logfile for allocations/deallocations
static const char* MemLogFile = 0;
static FILE* LogFile = 0;
// Statistics
u32 MemNewCount = 0;
u32 MemDelCount = 0;
u32 MemDelNULLCount = 0;
u32 MemNewCheckCount = 0;
u32 MemDelCheckCount = 0;
u32 MemLargestBlock = 0;
u32 MemUsage = 0;
u32 MemMaxUsage = 0;
// This is the fill value for memory blocks if MemFill is true. On intel
// architectures, this is the code for "INT 3", an instruction that is
// often used by debuggers as a breakpoint.
unsigned char FillVal = 0xCC;
/*****************************************************************************/
/* struct BlockInfo */
/*****************************************************************************/
typedef struct {
unsigned char* Ptr;
u32 Size;
} BlockInfo;
//
const int FirstChunk = 2000;
const int Delta = 1000;
// Variables needed
static int IsInitialized = 0;
static int BlockCount = 0;
static int BlockLimit = 0;
static BlockInfo* Blocks = 0;
/*****************************************************************************/
/* class BlockInfoColl */
/*****************************************************************************/
static void MemSetCount (int NewCount)
// Make shure, there is space for NewSize blocks in Blocks
{
if (NewCount > BlockLimit) {
// OOPS, need realloc
if (BlockLimit == 0 && NewCount <= FirstChunk) {
BlockLimit = FirstChunk;
} else {
BlockLimit = ((NewCount / Delta) + 1) * Delta;
}
Blocks = (BlockInfo*) realloc (Blocks, BlockLimit * sizeof (BlockInfo));
}
BlockCount = NewCount;
}
static int MemSearch (const unsigned char* Ptr, int* Index)
// Search for the block. Return 1 if the block is found (Index holds the
// block index in this case). Return 0 if the block is not found and return
// in Index the index where the block should be inserted.
{
// do a binary search
int First = 0;
int Last = BlockCount - 1;
int Current;
int S = 0;
while (First <= Last) {
// Set current to mid of range
Current = (Last + First) / 2;
// Do a compare
if (Blocks [Current].Ptr < Ptr) {
First = Current + 1;
} else {
Last = Current - 1;
if (Blocks [Current].Ptr == Ptr) {
// Found.
S = 1; // function result
// Set condition to terminate loop
First = Current;
}
}
}
*Index = First;
return S;
}
static void MemDelBlock (int Index)
// Delete the block with the given index
{
BlockCount--;
memmove (Blocks+Index, Blocks+Index+1, (BlockCount-Index) * sizeof (BlockInfo));
}
static void MemInsBlock (int Index, unsigned char* Ptr, u32 Size)
{
// Set the new size
MemSetCount (BlockCount + 1);
// We can insert the element. If the item is not inserted at the end
// of the collection, we must create a "hole"
if (Index != BlockCount - 1) {
memmove (Blocks + Index + 1,
Blocks + Index,
(BlockCount - 1 - Index) * sizeof (BlockInfo));
}
// store the new data
Blocks [Index].Ptr = Ptr;
Blocks [Index].Size = Size;
}
u32 MemBlocksInUse ()
{
return (u32) BlockCount;
}
static void PrintContents (const void* B, unsigned Size, FILE* F)
// Print the contents of the block
{
unsigned I;
static const unsigned MaxPrint = 14;
const unsigned char* P = (const unsigned char*) B;
if (Size > MaxPrint) {
Size = MaxPrint;
}
// Two characters space
fprintf (F, " ");
// Print the first few bytes in hex
for (I = 0; I < Size; I++) {
fprintf (F, "%02X ", P [I]);
}
fprintf (F, "%*s ", (MaxPrint-Size)*3, "");
// Print the bytes again in ASCII
for (I = 0; I < Size; I++) {
unsigned char C = P [I];
if (C < ' ' || C > 0x7E) {
C = '.';
}
putc (C, F);
}
}
void MemLogBlocksInUse (const char* Name)
{
BlockInfo* Block;
int I;
FILE* F = fopen (Name, "w+t");
if (F == 0) {
// This is a debug function, so ignore the error
return;
}
// Get the block count and log some statistics
fprintf (F, "Blocks currently in use: %8lu\n\n"
"Calls to operator new: %8lu\n"
"Calls to operator delete: %8lu\n"
"Checked calls to new: %8lu\n"
"Checked calls to delete: %8lu\n"
"Calls to delete with a NULL arg: %8lu\n\n"
"Largest block allocated: %8lu\n"
"Maximum memory usage: %8lu\n\n",
(unsigned long) BlockCount,
(unsigned long) MemNewCount,
(unsigned long) MemDelCount,
(unsigned long) MemNewCheckCount,
(unsigned long) MemDelCheckCount,
(unsigned long) MemDelNULLCount,
(unsigned long) MemLargestBlock,
(unsigned long) MemMaxUsage);
// Print a header
fprintf (F, "Num Address Size Contents\n");
fprintf (F, "----------------------------------------"
"---------------------------------------\n");
// Log the blocks
Block = Blocks;
for (I = 0; I < BlockCount; I++, Block++) {
// Print a line describing the block (convert pointers to hex values)
fprintf (F, "%-5u %08lX %5lu",
I, (unsigned long) Block->Ptr, (unsigned long) Block->Size);
// Print the first few bytes of the block
PrintContents (Block->Ptr, Block->Size, F);
// Check the block signature
if (memcmp (Block->Ptr + Block->Size, &MemSig, sizeof (MemSig)) != 0) {
// Signature overwritten
fprintf (F, " *** Signature overwritten ***\n");
} else {
fprintf (F, "\n");
}
}
// Close the file
fclose (F);
}
static long MemValidateBlocks ()
// Validate all memory blocks. Return the index of a block where the
// validation failed, otherwise return -1.
{
// Validate the blocks
long I;
BlockInfo* Block = Blocks;
for (I = 0; I < BlockCount; I++, Block++) {
// Check the block signature
if (memcmp (Block->Ptr + Block->Size, &MemSig, sizeof (MemSig)) != 0) {
// Signature overwritten
return I;
}
}
// All is well...
return -1;
}
static void MemDone ()
// Log the memory blocks if requested. Does *not* delete the block array
// since the startup code may release memory after calling the exit functions
// and in this case we will work with a freed block, if we free the block
// array here
{
// If the environment variable MEMLOGBLOCKS is set to something, use
// this "something" as a filename to log a list of still allocated blocks
const char* Name = getenv ("MEMLOGBLOCKS");
if (Name) {
MemLogBlocksInUse (Name);
}
}
static void MemInit ()
// Initialize the memory checker.
{
// Get the defaults for the memory checker
const char* Fill;
MemCheck = getenv ("MEMCHECK") != 0;
MemValidate = getenv ("MEMVALIDATE") != 0;
MemDontFree = getenv ("MEMDONTFREE") != 0;
MemLogFile = getenv ("MEMLOGFILE");
Fill = getenv ("MEMFILL");
if (Fill) {
MemFill = 1;
if (isdigit (*Fill)) {
FillVal = atoi (Fill);
}
}
// Open the logfile if set
if (MemLogFile) {
LogFile = fopen (MemLogFile, "w+t");
}
// Register the exit function
atexit (MemDone);
// Initialized now (maybe set already)
IsInitialized = 1;
}
/*****************************************************************************/
/* Allocate/free blocks */
/*****************************************************************************/
static void* MemAlloc (size_t Size)
{
unsigned char* Ptr;
// Last allocated block is remembered here
static void* LastBlock = 0;
// Initialize the memory checker on the first call
if (IsInitialized == 0) {
MemInit ();
}
// Count the calls to new
MemNewCount++;
// Update largest block info
if (Size > MemLargestBlock) {
MemLargestBlock = Size;
}
if (MemCheck) {
int Index;
// Count the checked calls
MemNewCheckCount++;
// If we need to validate all blocks, do that
if (MemValidate) {
long I = MemValidateBlocks ();
if (I != -1) {
// We have a problem. Be shure to switch of MemValidate before
// calling FAIL, otherwise we will get an endless loop...
MemValidate = 0;
FAIL ("MemCheck: Block signature overwritten!");
}
}
// Update memory usage
MemUsage += Size;
if (MemUsage > MemMaxUsage) {
MemMaxUsage = MemUsage;
}
// Get a memory block
Ptr = (unsigned char*) malloc (Size + sizeof (MemSig));
// Make a signature at the end of the block
memcpy (Ptr + Size, &MemSig, sizeof (MemSig));
// Search for the block
if (MemSearch (Ptr, &Index) != 0) {
// An item with this key exists. This means that the heap is
// corrupted
FAIL ("MemCheck: Duplicate block!");
} else {
// The returned pointer is not in the collection of already
// allocated blocks, but it may point inside of an already
// allocated block. Check this.
// Note: Index is the index of the item _before the given
// pointer, so simply check the range of the entry with index
// Index.
if (Index > 0) {
// There is a block that's memory address is less than the
// one returned by malloc
const BlockInfo* BB = Blocks + Index - 1;
if (Ptr < BB->Ptr + BB->Size) {
// Pointer points inside the block below - heap corrupted
FAIL ("MemCheck: Heap corrupt!");
}
}
// Heap ok, insert the new block
MemInsBlock (Index, Ptr, Size);
}
} else {
// No memory checking. Allocate a memory block, but beware: New is
// defined so that "new char [0]" points to a distinct object every
// time it is called, so one cannot return NULL for a size of 0!
Ptr = (unsigned char*) malloc (Size ? Size : 1);
}
// Remember the last block
LastBlock = Ptr;
// Check if we got memory, fail otherwise
if (Ptr == 0) {
FAIL ("MemCheck: Out of memory");
}
// Fill the memory block if requested
if (MemFill) {
memset (Ptr, FillVal, Size);
}
// Log the allocation if requested
if (LogFile) {
// Print a line describing the block (convert pointers to hex values)
fprintf (LogFile, "A %08lX %5lu",
(unsigned long) Ptr, (unsigned long) Size);
// Print the first few bytes of the block
PrintContents (Ptr, Size, LogFile);
fprintf (LogFile, "\n");
}
// Return a pointer to the memory block
return Ptr;
}
static void MemFree (void* P)
{
// We cannot call delete if the memory system is not initialized
if (IsInitialized == 0) {
FAIL ("MemCheck: Trying to delete a block before the first call to new!");
}
// Count the calls to delete
MemDelCount++;
// Deleting NULL pointers is always ok, nothing has to be done
if (P == 0) {
MemDelNULLCount++;
return;
}
if (MemCheck) {
int Index;
unsigned char* Ptr;
// Count the calls
MemDelCheckCount++;
// If we need to validate all blocks, do that
if (MemValidate) {
long I = MemValidateBlocks ();
if (I != -1) {
// We have a problem. Be shure to switch of MemValidate before
// calling FAIL, otherwise we will get an endless loop...
MemValidate = 0;
FAIL ("MemCheck: Block signature overwritten!");
}
}
// Cast the pointer
Ptr = (unsigned char*) P;
// Search for the block
if (MemSearch (Ptr, &Index) != 0) {
// The block exists.
BlockInfo* BI = Blocks + Index;
// Log the deallocation if requested
if (LogFile) {
// Print a line describing the block (convert pointers to hex values)
fprintf (LogFile, "D %08lX %5lu",
(unsigned long) BI->Ptr, (unsigned long) BI->Size);
// Print the first few bytes of the block
PrintContents (BI->Ptr, BI->Size, LogFile);
fprintf (LogFile, "\n");
}
// Check the signature
if (memcmp (Ptr + BI->Size, &MemSig, sizeof (MemSig)) != 0) {
// Signature overwritten
FAIL ("MemCheck: Block signature overwritten");
}
// Fill the memory block if requested
if (MemFill) {
memset (Ptr, FillVal, BI->Size);
}
// Should the block really be freed?
if (MemDontFree == 0) {
// Update memory usage
MemUsage -= BI->Size;
// Delete the entry
MemDelBlock (Index);
// Delete the memory block
free (P);
}
} else {
// Trying to free a block that is not allocated
FAIL ("MemCheck: Trying to free a block that is not allocated");
}
} else {
// Free the block without checks
free (P);
}
}
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void* xmalloc (size_t Size)
{
return MemAlloc (Size);
}
void xfree (const void* P)
{
MemFree ((void*)P);
}
char* xstrdup (const char* S)
{
unsigned Len = strlen (S) + 1;
return memcpy (xmalloc (Len), S, Len);
}

View File

@ -37,6 +37,8 @@
#include <string.h>
#include <ctype.h>
#include "../common/xmalloc.h"
#include "asmlabel.h"
#include "asmline.h"
#include "check.h"
@ -44,7 +46,6 @@
#include "error.h"
#include "global.h"
#include "io.h"
#include "mem.h"
#include "optimize.h"
@ -1218,7 +1219,7 @@ static unsigned RegValUsed (Line* Start)
* If the end of the lookahead is reached, all registers that are uncertain
* are marked as used.
* The result of the search is returned.
*/
*/
{
unsigned R;
@ -3635,6 +3636,9 @@ static Line* OptOneBlock (Line* L)
}
}
} else if (LineMatch (L, "\tadc\t")) {
if (CPU == CPU_65C02 && Y == 0 && L->Line[5] == '(' && IsYAddrMode(L)) {
L->Line[strlen(L->Line)-2] = '\0';
}
A = -1;
} else if (LineMatch (L, "\tand\t")) {
A = -1;
@ -3642,7 +3646,10 @@ static Line* OptOneBlock (Line* L)
if (A != -1) {
A = (A << 1) & 0xFF;
}
} else if (CPU == CPU_65C02 && LineFullMatch (L, "\tdea")) {
} else if (CPU == CPU_65C02 && Y == 0 && L->Line[5] == '(' && IsYAddrMode(L)) {
L->Line[strlen(L->Line)-2] = '\0';
} else if (CPU == CPU_65C02 && (LineFullMatch (L, "\tdea") ||
LineFullMatch (L, "\tdec\ta"))) {
DEC (A, 1);
} else if (LineFullMatch (L, "\tdex")) {
DEC (X, 1);
@ -3650,7 +3657,8 @@ static Line* OptOneBlock (Line* L)
DEC (Y, 1);
} else if (LineMatch (L, "\teor")) {
A = -1;
} else if (CPU == CPU_65C02 && LineFullMatch (L, "\tina")) {
} else if (CPU == CPU_65C02 && (LineFullMatch (L, "\tina") ||
LineFullMatch (L, "\tinc\ta"))) {
INC (A, 1);
} else if (LineFullMatch (L, "\tinx")) {
INC (X, 1);
@ -4092,6 +4100,9 @@ static Line* OptOneBlock (Line* L)
} else if (LineFullMatch (L, "\trti")) {
A = X = Y = -1;
} else if (LineMatch (L, "\tsbc\t")) {
if (CPU == CPU_65C02 && Y == 0 && L->Line[5] == '(' && IsYAddrMode(L)) {
L->Line[strlen(L->Line)-2] = '\0';
}
A = -1;
} else if (CPU == CPU_65C02 && LineMatch (L, "\tst")) {
/* Try to replace by stz if possible */
@ -4099,7 +4110,7 @@ static Line* OptOneBlock (Line* L)
/* Not indirect and not Y allowed */
if (L->Line[5] != '(' && !IsYAddrMode (L)) {
L->Line[3] = 'z';
}
}
} else if (X == 0 && LineMatch (L, "\tstx\t")) {
/* absolute,y not allowed */
if (!IsYAddrMode (L)) {

View File

@ -7,15 +7,17 @@
#include <errno.h>
#include <ctype.h>
#include "../common/xmalloc.h"
#include "codegen.h"
#include "error.h"
#include "expr.h"
#include "global.h"
#include "ident.h"
#include "incpath.h"
#include "input.h"
#include "io.h"
#include "macrotab.h"
#include "mem.h"
#include "scanner.h"
#include "util.h"
#include "preproc.h"
@ -33,7 +35,7 @@ static int Pass1 (char* from, char* to);
/*****************************************************************************/
/* data */
/* data */
/*****************************************************************************/
@ -83,7 +85,7 @@ static void keepstr (const char* S)
static void comment (void)
/* Remove comment from line. */
{
unsigned StartingLine = ln;
unsigned StartingLine = GetCurrentLine();
gch ();
gch ();
@ -438,7 +440,7 @@ static int Pass1 (char* from, char* to)
++lptr;
}
}
}
}
} else {
if (MaybeMacro(c)) {
done = 0;
@ -576,7 +578,7 @@ static int doiff (int skip)
skipblank ();
S = line;
while ((*S++ = *lptr++) != '\0') ;
strcat (line, ";;");
strcpy (S-1, ";;");
lptr = line;
/* Switch into special preprocessing mode */
@ -623,70 +625,58 @@ static int doifdef (int skip, int flag)
static void doinclude (void)
/* Open an include file. */
{
char name [80];
unsigned count;
char term;
char c;
char *p;
unsigned Length;
char* End;
char* Name;
char RTerm;
unsigned DirSpec;
if (ifile >= MAXFILES) {
PPError (ERR_INCLUDE_NESTING);
goto done;
}
/* Skip blanks */
mptr = mline;
skipblank ();
if (!strchr ("\"<", (term = cgch ()))) {
PPError (ERR_INCLUDE_LTERM_EXPECTED);
goto done;
}
if (term == '<') {
term = '>'; /* get right terminator */
/* Get the next char and check for a valid file name terminator. Setup
* the include directory spec (SYS/USR) by looking at the terminator.
*/
switch (cgch()) {
case '\"':
RTerm = '\"';
DirSpec = INC_USER;
break;
case '<':
RTerm = '>';
DirSpec = INC_SYS;
break;
default:
PPError (ERR_INCLUDE_LTERM_EXPECTED);
goto Done;
}
/* Get the name of the include file */
count = 0;
while ((c = *lptr) && (c != term) && count < sizeof (name)-1) {
name [count++] = c;
++lptr;
}
if (c != term) {
/* Search for the right terminator */
End = strchr (lptr, RTerm);
if (End == 0) {
/* No terminator found */
PPError (ERR_INCLUDE_RTERM_EXPECTED);
goto done;
}
name [count] = '\0';
/* Now search for the name */
p = FindInclude (name, (term == '\"')? INC_USER : INC_SYS);
if (p == 0) {
PPError (ERR_INCLUDE_NOT_FOUND, name);
goto done;
goto Done;
}
/* Save the existing file info */
filetab[ifile].f_ln = ln;
filetab[ifile].f_name = fin;
filetab[ifile].f_iocb = inp;
++ifile;
/* Create a temp copy of the filename */
Length = End - lptr;
Name = xmalloc (Length + 1);
memcpy (Name, lptr, Length);
Name[Length] = '\0';
/* Assign the name and output it */
fin = p;
if (Verbose) {
printf ("including '%s'\n", fin);
}
/* Open the include file */
OpenIncludeFile (Name, DirSpec);
/* Try to open the include file */
if ((inp = fopen (fin, "r")) == 0) {
/* oops! restore old file */
PPError (ERR_INCLUDE_OPEN_FAILURE, fin);
xfree (fin);
--ifile;
inp = filetab[ifile].f_iocb;
fin = filetab[ifile].f_name;
} else {
ln = 0;
}
/* Delete the temp filename copy */
xfree (Name);
done:
Done:
/* clear rest of line so next read will come from new file (if open) */
kill ();
}

View File

@ -18,6 +18,7 @@
#include "function.h"
#include "global.h"
#include "ident.h"
#include "input.h"
#include "io.h"
#include "litpool.h"
#include "preproc.h"
@ -355,7 +356,7 @@ void NextToken (void)
CurTok = NextTok;
/* Remember the starting position of the next token */
NextTok.Pos = ln;
NextTok.Pos = GetCurrentLine();
/* Skip spaces and read the next line if needed */
if (skipwhite () == 0) {
@ -476,12 +477,12 @@ void NextToken (void)
if (token [0] == '_') {
/* Special symbols */
if (strcmp (token, "__FILE__") == 0) {
nxtval = AddLiteral (fin);
nxtval = AddLiteral (GetCurrentFile());
nxttok = TOK_SCONST;
return;
} else if (strcmp (token, "__LINE__") == 0) {
nxttok = TOK_ICONST;
nxtval = ln;
nxtval = GetCurrentLine();
nxttype = type_int;
return;
} else if (strcmp (token, "__fixargs__") == 0) {

View File

@ -11,6 +11,8 @@
#include <stdio.h>
#include <string.h>
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "asmlabel.h"
#include "codegen.h"
@ -23,7 +25,6 @@
#include "litpool.h"
#include "locals.h"
#include "loop.h"
#include "mem.h"
#include "pragma.h"
#include "scanner.h"
#include "symtab.h"

View File

@ -33,7 +33,8 @@
#include "mem.h"
#include "../common/xmalloc.h"
#include "symentry.h"

View File

@ -39,6 +39,7 @@
#include <string.h>
#include "../common/hashstr.h"
#include "../common/xmalloc.h"
#include "asmcode.h"
#include "asmlabel.h"
@ -50,7 +51,6 @@
#include "funcdesc.h"
#include "global.h"
#include "io.h"
#include "mem.h"
#include "symentry.h"
#include "symtab.h"