Make much more usage of dynamic strings (StrBufs) instead of char* and

friends. Since names and other strings are now StrBufs in many places, code
for output had to be changed.
Added support for string literals to StrBuf.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3825 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2008-03-31 20:54:45 +00:00
parent 6a7e844500
commit 9174f65e54
78 changed files with 1228 additions and 864 deletions

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -36,9 +36,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
/* common */
#include "xsprintf.h"
/* ca65 */ /* ca65 */
#include "anonname.h" #include "anonname.h"
@@ -60,23 +57,27 @@ static const char AnonTag[] = "$anon";
char* AnonName (char* Buf, unsigned Size, const char* Spec) StrBuf* AnonName (StrBuf* Buf, const char* Spec)
/* Get a name for an anonymous scope, variable or type. Size is the size of /* Get a name for an anonymous scope, variable or type. Size is the size of
* the buffer passed to the function, Spec will be used as part of the * the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned. * identifier if given. A pointer to the buffer is returned.
*/ */
{ {
static unsigned ACount = 0; static unsigned ACount = 0;
xsprintf (Buf, Size, "%s-%s-%04X", AnonTag, Spec, ++ACount); SB_Printf (Buf, "%s-%s-%04X", AnonTag, Spec, ++ACount);
return Buf; return Buf;
} }
int IsAnonName (const char* Name) int IsAnonName (const StrBuf* Name)
/* Check if the given symbol name is that of an anonymous symbol */ /* Check if the given symbol name is that of an anonymous symbol */
{ {
return (strncmp (Name, AnonTag, sizeof (AnonTag) - 1) == 0); if (SB_GetLen (Name) < sizeof (AnonTag) - 1) {
/* Too short */
return 0;
}
return (strncmp (SB_GetConstBuf (Name), AnonTag, sizeof (AnonTag) - 1) == 0);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -38,22 +38,27 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
char* AnonName (char* Buf, unsigned Size, const char* Spec); StrBuf* AnonName (StrBuf* Buf, const char* Spec);
/* Get a name for an anonymous scope, variable or type. Size is the size of /* Get a name for an anonymous scope, variable or type. Size is the size of
* the buffer passed to the function, Spec will be used as part of the * the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned. * identifier if given. A pointer to the buffer is returned.
*/ */
int IsAnonName (const char* Name); int IsAnonName (const StrBuf* Name);
/* Check if the given symbol name is that of an anonymous symbol */ /* Check if the given symbol name is that of an anonymous symbol */
/* End of anonname.h */ /* End of anonname.h */
#endif #endif

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003-2005, Ullrich von Bassewitz */ /* (C) 2003-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */

View File

@@ -2,12 +2,12 @@
/* */ /* */
/* dbginfo.c */ /* dbginfo.c */
/* */ /* */
/* Handle the .dbg commands */ /* Handle the .dbg commands */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -35,6 +35,9 @@
#include <string.h> #include <string.h>
/* common */
#include "strbuf.h"
/* ca65 */ /* ca65 */
#include "error.h" #include "error.h"
#include "expr.h" #include "expr.h"
@@ -54,7 +57,7 @@
void DbgInfoFile (void) void DbgInfoFile (void)
/* Parse and handle FILE subcommand of the .dbg pseudo instruction */ /* Parse and handle FILE subcommand of the .dbg pseudo instruction */
{ {
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
unsigned long Size; unsigned long Size;
unsigned long MTime; unsigned long MTime;
@@ -66,7 +69,7 @@ void DbgInfoFile (void)
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
return; return;
} }
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
/* Comma expected */ /* Comma expected */
@@ -82,7 +85,10 @@ void DbgInfoFile (void)
MTime = ConstExpression (); MTime = ConstExpression ();
/* Insert the file into the table */ /* Insert the file into the table */
AddFile (Name, Size, MTime); AddFile (&Name, Size, MTime);
/* Free memory used for Name */
SB_Done (&Name);
} }
@@ -111,7 +117,7 @@ void DbgInfoLine (void)
} }
/* Get the index in the file table for the name */ /* Get the index in the file table for the name */
Index = GetFileIndex (SVal); Index = GetFileIndex (&SVal);
/* Skip the name */ /* Skip the name */
NextTok (); NextTok ();

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -65,7 +65,7 @@ void DoEnum (void)
int Anon = (Tok != TOK_IDENT); int Anon = (Tok != TOK_IDENT);
if (!Anon) { if (!Anon) {
/* Enter a new scope, then skip the name */ /* Enter a new scope, then skip the name */
SymEnterLevel (SVal, ST_ENUM, ADDR_SIZE_ABS); SymEnterLevel (&SVal, ST_ENUM, ADDR_SIZE_ABS);
NextTok (); NextTok ();
} }
@@ -94,7 +94,7 @@ void DoEnum (void)
} }
/* We have an identifier, generate a symbol */ /* We have an identifier, generate a symbol */
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW); Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
/* Skip the member name */ /* Skip the member name */
NextTok (); NextTok ();

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -37,10 +37,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
/* common */
#include "strbuf.h"
/* ca65 */ /* ca65 */
#include "error.h"
#include "filetab.h" #include "filetab.h"
#include "nexttok.h" #include "nexttok.h"
#include "error.h"
@@ -69,11 +72,18 @@ void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list
/* Print warning message. */ /* Print warning message. */
{ {
if (Level <= WarnLevel) { if (Level <= WarnLevel) {
fprintf (stderr, "%s(%lu): Warning: ",
GetFileName (Pos->Name), Pos->Line); StrBuf S = STATIC_STRBUF_INITIALIZER;
vfprintf (stderr, Format, ap); SB_VPrintf (&S, Format, ap);
fprintf (stderr, "\n"); SB_Terminate (&S);
fprintf (stderr, "%s(%lu): Warning: %s\n",
SB_GetConstBuf (GetFileName (Pos->Name)),
Pos->Line,
SB_GetConstBuf (&S));
++WarningCount; ++WarningCount;
SB_Done (&S);
} }
} }
@@ -110,11 +120,17 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap) void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap)
/* Print an error message */ /* Print an error message */
{ {
fprintf (stderr, "%s(%lu): Error: ", StrBuf S = STATIC_STRBUF_INITIALIZER;
GetFileName (Pos->Name), Pos->Line); SB_VPrintf (&S, Format, ap);
vfprintf (stderr, Format, ap); SB_Terminate (&S);
fprintf (stderr, "\n");
fprintf (stderr, "%s(%lu): Error: %s\n",
SB_GetConstBuf (GetFileName (Pos->Name)),
Pos->Line,
SB_GetConstBuf (&S));
++ErrorCount; ++ErrorCount;
SB_Done (&S);
} }
@@ -164,13 +180,17 @@ void Fatal (const char* Format, ...)
/* Print a message about a fatal error and die */ /* Print a message about a fatal error and die */
{ {
va_list ap; va_list ap;
StrBuf S = STATIC_STRBUF_INITIALIZER;
va_start (ap, Format); va_start (ap, Format);
fprintf (stderr, "Fatal error: "); SB_VPrintf (&S, Format, ap);
vfprintf (stderr, Format, ap); SB_Terminate (&S);
fprintf (stderr, "\n");
va_end (ap); va_end (ap);
fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S));
SB_Done (&S);
/* And die... */ /* And die... */
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
@@ -178,14 +198,19 @@ void Fatal (const char* Format, ...)
void Internal (const char* Format, ...) void Internal (const char* Format, ...)
/* Print a message about an internal compiler error and die. */ /* Print a message about an internal assembler error and die. */
{ {
va_list ap; va_list ap;
StrBuf S = STATIC_STRBUF_INITIALIZER;
va_start (ap, Format); va_start (ap, Format);
fprintf (stderr, "Internal assembler error:\n"); SB_VPrintf (&S, Format, ap);
vfprintf (stderr, Format, ap); SB_Terminate (&S);
va_end (ap); va_end (ap);
fprintf (stderr, "\n");
fprintf (stderr, "Internal assembler error: %s\n", SB_GetConstBuf (&S));
SB_Done (&S);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -73,7 +73,7 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...) attr
void Error (const char* Format, ...) attribute ((format (printf, 1, 2))); void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print an error message */ /* Print an error message */
void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3))); void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
/* Print an error message giving an explicit file and position. */ /* Print an error message giving an explicit file and position. */
@@ -84,7 +84,7 @@ void Fatal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
/* Print a message about a fatal error and die */ /* Print a message about a fatal error and die */
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2))); void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
/* Print a message about an internal compiler error and die. */ /* Print a message about an internal assembler error and die. */

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -550,8 +550,8 @@ static ExprNode* FuncReferenced (void)
static ExprNode* FuncSizeOf (void) static ExprNode* FuncSizeOf (void)
/* Handle the .SIZEOF function */ /* Handle the .SIZEOF function */
{ {
StrBuf ScopeName = AUTO_STRBUF_INITIALIZER; StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
char Name[sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
SymTable* Scope; SymTable* Scope;
SymEntry* Sym; SymEntry* Sym;
SymEntry* SizeSym; SymEntry* SizeSym;
@@ -566,27 +566,28 @@ static ExprNode* FuncSizeOf (void)
if (Tok == TOK_LOCAL_IDENT) { if (Tok == TOK_LOCAL_IDENT) {
/* Cheap local symbol */ /* Cheap local symbol */
Sym = SymFindLocal (SymLast, SVal, SYM_FIND_EXISTING); Sym = SymFindLocal (SymLast, &SVal, SYM_FIND_EXISTING);
if (Sym == 0) { if (Sym == 0) {
Error ("Unknown symbol or scope: `%s'", SVal); Error ("Unknown symbol or scope: `%m%p'", &SVal);
} else { } else {
SizeSym = GetSizeOfSymbol (Sym); SizeSym = GetSizeOfSymbol (Sym);
} }
/* Remember and skip SVal, terminate ScopeName so it is empty */ /* Remember and skip SVal, terminate ScopeName so it is empty */
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
SB_Terminate (&ScopeName); SB_Terminate (&ScopeName);
} else { } else {
/* Parse the scope and the name */ /* Parse the scope and the name */
SymTable* ParentScope = ParseScopedIdent (Name, &ScopeName); SymTable* ParentScope = ParseScopedIdent (&Name, &ScopeName);
/* Check if the parent scope is valid */ /* Check if the parent scope is valid */
if (ParentScope == 0) { if (ParentScope == 0) {
/* No such scope */ /* No such scope */
DoneStrBuf (&ScopeName); SB_Done (&ScopeName);
SB_Done (&Name);
return GenLiteral0 (); return GenLiteral0 ();
} }
@@ -597,9 +598,9 @@ static ExprNode* FuncSizeOf (void)
/* First search for a scope with the given name */ /* First search for a scope with the given name */
if (NoScope) { if (NoScope) {
Scope = SymFindAnyScope (ParentScope, Name); Scope = SymFindAnyScope (ParentScope, &Name);
} else { } else {
Scope = SymFindScope (ParentScope, Name, SYM_FIND_EXISTING); Scope = SymFindScope (ParentScope, &Name, SYM_FIND_EXISTING);
} }
/* If we did find a scope with the name, read the symbol defining the /* If we did find a scope with the name, read the symbol defining the
@@ -610,29 +611,30 @@ static ExprNode* FuncSizeOf (void)
SizeSym = GetSizeOfScope (Scope); SizeSym = GetSizeOfScope (Scope);
} else { } else {
if (NoScope) { if (NoScope) {
Sym = SymFindAny (ParentScope, Name); Sym = SymFindAny (ParentScope, &Name);
} else { } else {
Sym = SymFind (ParentScope, Name, SYM_FIND_EXISTING); Sym = SymFind (ParentScope, &Name, SYM_FIND_EXISTING);
} }
/* If we found the symbol retrieve the size, otherwise complain */ /* If we found the symbol retrieve the size, otherwise complain */
if (Sym) { if (Sym) {
SizeSym = GetSizeOfSymbol (Sym); SizeSym = GetSizeOfSymbol (Sym);
} else { } else {
Error ("Unknown symbol or scope: `%s%s'", Error ("Unknown symbol or scope: `%m%p%m%p'",
SB_GetConstBuf (&ScopeName), Name); &ScopeName, &Name);
} }
} }
} }
/* Check if we have a size */ /* Check if we have a size */
if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) { if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) {
Error ("Size of `%s%s' is unknown", SB_GetConstBuf (&ScopeName), Name); Error ("Size of `%m%p%m%p' is unknown", &ScopeName, &Name);
Size = 0; Size = 0;
} }
/* Free the scope name */ /* Free the string buffers */
DoneStrBuf (&ScopeName); SB_Done (&ScopeName);
SB_Done (&Name);
/* Return the size */ /* Return the size */
return GenLiteralExpr (Size); return GenLiteralExpr (Size);
@@ -643,19 +645,19 @@ static ExprNode* FuncSizeOf (void)
static ExprNode* FuncStrAt (void) static ExprNode* FuncStrAt (void)
/* Handle the .STRAT function */ /* Handle the .STRAT function */
{ {
char Str [sizeof(SVal)]; StrBuf Str = STATIC_STRBUF_INITIALIZER;
long Index; long Index;
unsigned char C; unsigned char C = 0;
/* String constant expected */ /* String constant expected */
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
Error ("String constant expected"); Error ("String constant expected");
NextTok (); NextTok ();
return GenLiteral0 (); goto ExitPoint;
} }
/* Remember the string and skip it */ /* Remember the string and skip it */
strcpy (Str, SVal); SB_Copy (&Str, &SVal);
NextTok (); NextTok ();
/* Comma must follow */ /* Comma must follow */
@@ -665,15 +667,19 @@ static ExprNode* FuncStrAt (void)
Index = ConstExpression (); Index = ConstExpression ();
/* Must be a valid index */ /* Must be a valid index */
if (Index >= (long) strlen (Str)) { if (Index >= (long) SB_GetLen (&Str)) {
Error ("Range error"); Error ("Range error");
return GenLiteral0 (); goto ExitPoint;
} }
/* Get the char, handle as unsigned. Be sure to translate it into /* Get the char, handle as unsigned. Be sure to translate it into
* the target character set. * the target character set.
*/ */
C = TgtTranslateChar (Str [(size_t)Index]); C = TgtTranslateChar (SB_At (&Str, (unsigned)Index));
ExitPoint:
/* Free string buffer memory */
SB_Done (&Str);
/* Return the char expression */ /* Return the char expression */
return GenLiteralExpr (C); return GenLiteralExpr (C);
@@ -699,7 +705,7 @@ static ExprNode* FuncStrLen (void)
} else { } else {
/* Get the length of the string */ /* Get the length of the string */
Len = strlen (SVal); Len = SB_GetLen (&SVal);
/* Skip the string */ /* Skip the string */
NextTok (); NextTok ();
@@ -807,7 +813,7 @@ static ExprNode* Factor (void)
break; break;
case TOK_LOCAL_IDENT: case TOK_LOCAL_IDENT:
N = Symbol (SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW)); N = Symbol (SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW));
NextTok (); NextTok ();
break; break;
@@ -948,9 +954,9 @@ static ExprNode* Factor (void)
break; break;
default: default:
if (LooseCharTerm && Tok == TOK_STRCON && strlen(SVal) == 1) { if (LooseCharTerm && Tok == TOK_STRCON && SB_GetLen (&SVal) == 1) {
/* A character constant */ /* A character constant */
N = GenLiteralExpr (TgtTranslateChar (SVal[0])); N = GenLiteralExpr (TgtTranslateChar (SB_At (&SVal, 0)));
} else { } else {
N = GenLiteral0 (); /* Dummy */ N = GenLiteral0 (); /* Dummy */
Error ("Syntax error"); Error ("Syntax error");

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2004 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -70,7 +70,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
feature_t FindFeature (const char* Key) feature_t FindFeature (const StrBuf* Key)
/* Find the feature in a table and return the corresponding enum value. If the /* Find the feature in a table and return the corresponding enum value. If the
* feature is invalid, return FEAT_UNKNOWN. * feature is invalid, return FEAT_UNKNOWN.
*/ */
@@ -79,7 +79,7 @@ feature_t FindFeature (const char* Key)
/* This is not time critical, so do a linear search */ /* This is not time critical, so do a linear search */
for (F = (feature_t) 0; F < FEAT_COUNT; ++F) { for (F = (feature_t) 0; F < FEAT_COUNT; ++F) {
if (strcmp (Key, FeatureKeys[F]) == 0) { if (SB_CompareStr (Key, FeatureKeys[F]) == 0) {
/* Found, index is enum value */ /* Found, index is enum value */
return F; return F;
} }
@@ -91,7 +91,7 @@ feature_t FindFeature (const char* Key)
feature_t SetFeature (const char* Key) feature_t SetFeature (const StrBuf* Key)
/* Find the feature and set the corresponding flag if the feature is known. /* Find the feature and set the corresponding flag if the feature is known.
* In any case, return the feature found. An invalid Key will return * In any case, return the feature found. An invalid Key will return
* FEAT_UNKNOWN. * FEAT_UNKNOWN.

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2007 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -38,6 +38,11 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@@ -70,12 +75,12 @@ typedef enum {
feature_t FindFeature (const char* Key); feature_t FindFeature (const StrBuf* Key);
/* Find the feature in a table and return the corresponding enum value. If the /* Find the feature in a table and return the corresponding enum value. If the
* feature is invalid, return FEAT_UNKNOWN. * feature is invalid, return FEAT_UNKNOWN.
*/ */
feature_t SetFeature (const char* Key); feature_t SetFeature (const StrBuf* Key);
/* Find the feature and set the corresponding flag if the feature is known. /* Find the feature and set the corresponding flag if the feature is known.
* In any case, return the feature found. An invalid Key will return * In any case, return the feature found. An invalid Key will return
* FEAT_UNKNOWN. * FEAT_UNKNOWN.

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -180,9 +180,11 @@ static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long
const char* GetFileName (unsigned Name) const StrBuf* GetFileName (unsigned Name)
/* Get the name of a file where the name index is known */ /* Get the name of a file where the name index is known */
{ {
static StrBuf ErrorMsg = LIT_STRBUF_INITIALIZER ("(outside file scope)");
const FileEntry* F; const FileEntry* F;
if (Name == 0) { if (Name == 0) {
@@ -192,30 +194,30 @@ const char* GetFileName (unsigned Name)
*/ */
if (CollCount (&FileTab) == 0) { if (CollCount (&FileTab) == 0) {
/* No files defined until now */ /* No files defined until now */
return "(outside file scope)"; return &ErrorMsg;
} else { } else {
F = CollConstAt (&FileTab, 0); F = CollConstAt (&FileTab, 0);
} }
} else { } else {
F = CollConstAt (&FileTab, Name-1); F = CollConstAt (&FileTab, Name-1);
} }
return GetString (F->Name); return GetStrBuf (F->Name);
} }
unsigned GetFileIndex (const char* Name) unsigned GetFileIndex (const StrBuf* Name)
/* Return the file index for the given file name. */ /* Return the file index for the given file name. */
{ {
/* Get the string pool index from the name */ /* Get the string pool index from the name */
unsigned NameIdx = GetStringId (Name); unsigned NameIdx = GetStrBufId (Name);
/* Search in the hash table for the name */ /* Search in the hash table for the name */
FileEntry* F = HT_FindEntry (&HashTab, &NameIdx); FileEntry* F = HT_FindEntry (&HashTab, &NameIdx);
/* If we don't have this index, print a diagnostic and use the main file */ /* If we don't have this index, print a diagnostic and use the main file */
if (F == 0) { if (F == 0) {
Error ("File name `%s' not found in file table", Name); Error ("File name `%m%p' not found in file table", Name);
return 0; return 0;
} else { } else {
return F->Index; return F->Index;
@@ -224,13 +226,13 @@ unsigned GetFileIndex (const char* Name)
unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime) unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime)
/* Add a new file to the list of input files. Return the index of the file in /* Add a new file to the list of input files. Return the index of the file in
* the table. * the table.
*/ */
{ {
/* Create a new file entry and insert it into the tables */ /* Create a new file entry and insert it into the tables */
FileEntry* F = NewFileEntry (GetStringId (Name), Size, MTime); FileEntry* F = NewFileEntry (GetStrBufId (Name), Size, MTime);
/* Return the index */ /* Return the index */
return F->Index; return F->Index;
@@ -265,4 +267,4 @@ void WriteFiles (void)

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -38,19 +38,24 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
const char* GetFileName (unsigned Name); const StrBuf* GetFileName (unsigned Name);
/* Get the name of a file where the name index is known */ /* Get the name of a file where the name index is known */
unsigned GetFileIndex (const char* Name); unsigned GetFileIndex (const StrBuf* Name);
/* Return the file index for the given file name. */ /* Return the file index for the given file name. */
unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime); unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime);
/* Add a new file to the list of input files. Return the index of the file in /* Add a new file to the list of input files. Return the index of the file in
* the table. * the table.
*/ */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2006, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -1453,7 +1453,7 @@ cpu_t GetCPU (void)
int FindInstruction (const char* Ident) int FindInstruction (const StrBuf* Ident)
/* Check if Ident is a valid mnemonic. If so, return the index in the /* Check if Ident is a valid mnemonic. If so, return the index in the
* instruction table. If not, return -1. * instruction table. If not, return -1.
*/ */
@@ -1472,7 +1472,7 @@ int FindInstruction (const char* Ident)
/* Make a copy, and uppercase that copy */ /* Make a copy, and uppercase that copy */
I = 0; I = 0;
while (Ident[I] != '\0') { while (I < SB_GetLen (Ident)) {
/* If the identifier is longer than the longest mnemonic, it cannot /* If the identifier is longer than the longest mnemonic, it cannot
* be one. * be one.
*/ */
@@ -1480,7 +1480,7 @@ int FindInstruction (const char* Ident)
/* Not found, no need for further action */ /* Not found, no need for further action */
return -1; return -1;
} }
Key[I] = toupper ((unsigned char)Ident[I]); Key[I] = toupper ((unsigned char)SB_AtUnchecked (Ident, I));
++I; ++I;
} }
Key[I] = '\0'; Key[I] = '\0';

View File

@@ -1,13 +1,13 @@
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* instr.h */ /* instr.h */
/* */ /* */
/* Instruction encoding for the ca65 macroassembler */ /* Instruction encoding for the ca65 macroassembler */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -40,6 +40,7 @@
/* common */ /* common */
#include "cpu.h" #include "cpu.h"
#include "strbuf.h"
@@ -152,7 +153,7 @@ void SetCPU (cpu_t NewCPU);
cpu_t GetCPU (void); cpu_t GetCPU (void);
/* Return the current CPU */ /* Return the current CPU */
int FindInstruction (const char* Ident); int FindInstruction (const StrBuf* Ident);
/* Check if Ident is a valid mnemonic. If so, return the index in the /* Check if Ident is a valid mnemonic. If so, return the index in the
* instruction table. If not, return -1. * instruction table. If not, return -1.
*/ */
@@ -169,3 +170,4 @@ void HandleInstruction (unsigned Index);

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2007 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -218,17 +218,20 @@ static void PrintPageHeader (FILE* F, const ListLine* L)
/* Print the header for a new page. It is assumed that the given line is the /* Print the header for a new page. It is assumed that the given line is the
* last line of the previous page. * last line of the previous page.
*/ */
{ {
/* Gte a pointer to the current input file */
const StrBuf* CurFile = GetFileName (L->File);
/* Print the header on the new page */ /* Print the header on the new page */
fprintf (F, fprintf (F,
"ca65 V%u.%u.%u - %s\n" "ca65 V%u.%u.%u - %s\n"
"Main file : %s\n" "Main file : %s\n"
"Current file: %s\n" "Current file: %.*s\n"
"\n", "\n",
VER_MAJOR, VER_MINOR, VER_PATCH, VER_MAJOR, VER_MINOR, VER_PATCH,
Copyright, Copyright,
InFile, InFile,
GetFileName (L->File)); SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
/* Count pages, reset lines */ /* Count pages, reset lines */
++PageNumber; ++PageNumber;

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -82,7 +82,7 @@ static StrBuf MacPackDir = STATIC_STRBUF_INITIALIZER;
int MacPackFind (const char* Name) int MacPackFind (const StrBuf* Name)
/* Find a macro package by name. The function will either return the id or /* Find a macro package by name. The function will either return the id or
* -1 if the package name was not found. * -1 if the package name was not found.
*/ */
@@ -90,7 +90,7 @@ int MacPackFind (const char* Name)
int I; int I;
for (I = 0; I < MAC_COUNT; ++I) { for (I = 0; I < MAC_COUNT; ++I) {
if (StrCaseCmp (Name, MacPackages[I].Name) == 0) { if (SB_CompareStr (Name, MacPackages[I].Name) == 0) {
/* Found */ /* Found */
return I; return I;
} }
@@ -130,21 +130,21 @@ void MacPackInsert (int Id)
NewInputFile (SB_GetConstBuf (&Filename)); NewInputFile (SB_GetConstBuf (&Filename));
/* Destroy the contents of Filename */ /* Destroy the contents of Filename */
DoneStrBuf (&Filename); SB_Done (&Filename);
} }
} }
void MacPackSetDir (const char* Dir) void MacPackSetDir (const StrBuf* Dir)
/* Set a directory where files for macro packages can be found. Standard is /* Set a directory where files for macro packages can be found. Standard is
* to use the builtin packages. For debugging macro packages, external files * to use the builtin packages. For debugging macro packages, external files
* can be used. * can be used.
*/ */
{ {
/* Copy the directory name to the buffer */ /* Copy the directory name to the buffer */
SB_CopyStr (&MacPackDir, Dir); SB_Copy (&MacPackDir, Dir);
/* Make sure that the last character is a path delimiter */ /* Make sure that the last character is a path delimiter */
if (SB_NotEmpty (&MacPackDir)) { if (SB_NotEmpty (&MacPackDir)) {

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -38,6 +38,11 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@@ -64,7 +69,7 @@ enum {
int MacPackFind (const char* Name); int MacPackFind (const StrBuf* Name);
/* Find a macro package by name. The function will either return the id or /* Find a macro package by name. The function will either return the id or
* -1 if the package name was not found. * -1 if the package name was not found.
*/ */
@@ -72,7 +77,7 @@ int MacPackFind (const char* Name);
void MacPackInsert (int Id); void MacPackInsert (int Id);
/* Insert the macro package with the given id in the input stream */ /* Insert the macro package with the given id in the input stream */
void MacPackSetDir (const char* Dir); void MacPackSetDir (const StrBuf* Dir);
/* Set a directory where files for macro packages can be found. Standard is /* Set a directory where files for macro packages can be found. Standard is
* to use the builtin packages. For debugging macro packages, external files * to use the builtin packages. For debugging macro packages, external files
* can be used. * can be used.

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -88,7 +88,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
typedef struct IdDesc IdDesc; typedef struct IdDesc IdDesc;
struct IdDesc { struct IdDesc {
IdDesc* Next; /* Linked list */ IdDesc* Next; /* Linked list */
char Id [1]; /* Identifier, dynamically allocated */ StrBuf Id; /* Identifier, dynamically allocated */
}; };
@@ -106,7 +106,7 @@ struct Macro {
TokNode* TokRoot; /* Root of token list */ TokNode* TokRoot; /* Root of token list */
TokNode* TokLast; /* Pointer to last token in list */ TokNode* TokLast; /* Pointer to last token in list */
unsigned char Style; /* Macro style */ unsigned char Style; /* Macro style */
char Name [1]; /* Macro name, dynamically allocated */ StrBuf Name; /* Macro name, dynamically allocated */
}; };
/* Hash table functions */ /* Hash table functions */
@@ -157,7 +157,7 @@ static unsigned LocalName = 0;
static unsigned HT_GenHash (const void* Key) static unsigned HT_GenHash (const void* Key)
/* Generate the hash over a key. */ /* Generate the hash over a key. */
{ {
return HashStr (Key); return HashBuf (Key);
} }
@@ -165,7 +165,7 @@ static unsigned HT_GenHash (const void* Key)
static const void* HT_GetKey (void* Entry) static const void* HT_GetKey (void* Entry)
/* Given a pointer to the user entry data, return a pointer to the index */ /* Given a pointer to the user entry data, return a pointer to the index */
{ {
return ((Macro*) Entry)->Name; return &((Macro*) Entry)->Name;
} }
@@ -184,7 +184,7 @@ static int HT_Compare (const void* Key1, const void* Key2)
* than zero if Key1 is greater then Key2. * than zero if Key1 is greater then Key2.
*/ */
{ {
return strcmp (Key1, Key2); return SB_Compare (Key1, Key2);
} }
@@ -195,17 +195,16 @@ static int HT_Compare (const void* Key1, const void* Key2)
static IdDesc* NewIdDesc (const char* Id) static IdDesc* NewIdDesc (const StrBuf* Id)
/* Create a new IdDesc, initialize and return it */ /* Create a new IdDesc, initialize and return it */
{ {
/* Allocate memory */ /* Allocate memory */
unsigned Len = strlen (Id); IdDesc* I = xmalloc (sizeof (IdDesc));
IdDesc* I = xmalloc (sizeof (IdDesc) + Len);
/* Initialize the struct */ /* Initialize the struct */
I->Next = 0; I->Next = 0;
memcpy (I->Id, Id, Len); I->Id = AUTO_STRBUF_INITIALIZER;
I->Id [Len] = '\0'; SB_Copy (&I->Id, Id);
/* Return the new struct */ /* Return the new struct */
return I; return I;
@@ -213,12 +212,11 @@ static IdDesc* NewIdDesc (const char* Id)
static Macro* NewMacro (const char* Name, unsigned char Style) static Macro* NewMacro (const StrBuf* Name, unsigned char Style)
/* Generate a new macro entry, initialize and return it */ /* Generate a new macro entry, initialize and return it */
{ {
/* Allocate memory */ /* Allocate memory */
unsigned Len = strlen (Name); Macro* M = xmalloc (sizeof (Macro));
Macro* M = xmalloc (sizeof (Macro) + Len);
/* Initialize the macro struct */ /* Initialize the macro struct */
InitHashNode (&M->Node, M); InitHashNode (&M->Node, M);
@@ -230,7 +228,8 @@ static Macro* NewMacro (const char* Name, unsigned char Style)
M->TokRoot = 0; M->TokRoot = 0;
M->TokLast = 0; M->TokLast = 0;
M->Style = Style; M->Style = Style;
memcpy (M->Name, Name, Len+1); M->Name = AUTO_STRBUF_INITIALIZER;
SB_Copy (&M->Name, Name);
/* Insert the macro into the global macro list */ /* Insert the macro into the global macro list */
M->List = MacroRoot; M->List = MacroRoot;
@@ -340,7 +339,7 @@ void MacDef (unsigned Style)
Error ("Identifier expected"); Error ("Identifier expected");
MacSkipDef (Style); MacSkipDef (Style);
return; return;
} else if (!UbiquitousIdents && FindInstruction (SVal) >= 0) { } else if (!UbiquitousIdents && FindInstruction (&SVal) >= 0) {
/* The identifier is a name of a 6502 instruction, which is not /* The identifier is a name of a 6502 instruction, which is not
* allowed if not explicitly enabled. * allowed if not explicitly enabled.
*/ */
@@ -350,16 +349,16 @@ void MacDef (unsigned Style)
} }
/* Did we already define that macro? */ /* Did we already define that macro? */
if (HT_Find (&MacroTab, SVal) != 0) { if (HT_Find (&MacroTab, &SVal) != 0) {
/* Macro is already defined */ /* Macro is already defined */
Error ("A macro named `%s' is already defined", SVal); Error ("A macro named `%m%p' is already defined", &SVal);
/* Skip tokens until we reach the final .endmacro */ /* Skip tokens until we reach the final .endmacro */
MacSkipDef (Style); MacSkipDef (Style);
return; return;
} }
/* Define the macro */ /* Define the macro */
M = NewMacro (SVal, Style); M = NewMacro (&SVal, Style);
/* Switch to raw token mode and skip the macro name */ /* Switch to raw token mode and skip the macro name */
EnterRawTokenMode (); EnterRawTokenMode ();
@@ -369,45 +368,45 @@ void MacDef (unsigned Style)
* otherwise we may have parameters without braces. * otherwise we may have parameters without braces.
*/ */
if (Style == MAC_STYLE_CLASSIC) { if (Style == MAC_STYLE_CLASSIC) {
HaveParams = 1; HaveParams = 1;
} else { } else {
if (Tok == TOK_LPAREN) { if (Tok == TOK_LPAREN) {
HaveParams = 1; HaveParams = 1;
NextTok (); NextTok ();
} else { } else {
HaveParams = 0; HaveParams = 0;
} }
} }
/* Parse the parameter list */ /* Parse the parameter list */
if (HaveParams) { if (HaveParams) {
while (Tok == TOK_IDENT) { while (Tok == TOK_IDENT) {
/* Create a struct holding the identifier */ /* Create a struct holding the identifier */
IdDesc* I = NewIdDesc (SVal); IdDesc* I = NewIdDesc (&SVal);
/* Insert the struct into the list, checking for duplicate idents */ /* Insert the struct into the list, checking for duplicate idents */
if (M->ParamCount == 0) { if (M->ParamCount == 0) {
M->Params = I; M->Params = I;
} else { } else {
IdDesc* List = M->Params; IdDesc* List = M->Params;
while (1) { while (1) {
if (strcmp (List->Id, SVal) == 0) { if (SB_Compare (&List->Id, &SVal) == 0) {
Error ("Duplicate symbol `%s'", SVal); Error ("Duplicate symbol `%m%p'", &SVal);
} }
if (List->Next == 0) { if (List->Next == 0) {
break; break;
} else { } else {
List = List->Next; List = List->Next;
} }
} }
List->Next = I; List->Next = I;
} }
++M->ParamCount; ++M->ParamCount;
/* Skip the name */ /* Skip the name */
NextTok (); NextTok ();
/* Maybe there are more params... */ /* Maybe there are more params... */
if (Tok == TOK_COMMA) { if (Tok == TOK_COMMA) {
@@ -471,7 +470,7 @@ void MacDef (unsigned Style)
} }
/* Put the identifier into the locals list and skip it */ /* Put the identifier into the locals list and skip it */
I = NewIdDesc (SVal); I = NewIdDesc (&SVal);
I->Next = M->Locals; I->Next = M->Locals;
M->Locals = I; M->Locals = I;
++M->LocalCount; ++M->LocalCount;
@@ -497,7 +496,7 @@ void MacDef (unsigned Style)
unsigned Count = 0; unsigned Count = 0;
IdDesc* I = M->Params; IdDesc* I = M->Params;
while (I) { while (I) {
if (strcmp (I->Id, SVal) == 0) { if (SB_Compare (&I->Id, &SVal) == 0) {
/* Local param name, replace it */ /* Local param name, replace it */
T->Tok = TOK_MACPARAM; T->Tok = TOK_MACPARAM;
T->IVal = Count; T->IVal = Count;
@@ -607,15 +606,21 @@ static int MacExpand (void* Data)
unsigned Index = 0; unsigned Index = 0;
IdDesc* I = Mac->M->Locals; IdDesc* I = Mac->M->Locals;
while (I) { while (I) {
if (strcmp (SVal, I->Id) == 0) { if (SB_Compare (&SVal, &I->Id) == 0) {
/* This is in fact a local symbol, change the name. Be sure /* This is in fact a local symbol, change the name. Be sure
* to generate a local label name if the original name was * to generate a local label name if the original name was
* a local label, and also generate a name that cannot be * a local label, and also generate a name that cannot be
* generated by a user. * generated by a user.
*/ */
unsigned PrefixLen = (I->Id[0] == LocalStart); if (SB_At (&I->Id, 0) == LocalStart) {
sprintf (SVal, "%.*sLOCAL-MACRO-SYMBOL-%04X", PrefixLen, /* Must generate a local symbol */
I->Id, Mac->LocalStart + Index); SB_Printf (&SVal, "%cLOCAL-MACRO_SYMBOL-%04X",
LocalStart, Mac->LocalStart + Index);
} else {
/* Global symbol */
SB_Printf (&SVal, "LOCAL-MACRO_SYMBOL-%04X",
Mac->LocalStart + Index);
}
break; break;
} }
/* Next symbol */ /* Next symbol */
@@ -836,7 +841,7 @@ void MacExpandStart (void)
/* Start expanding the macro in SVal */ /* Start expanding the macro in SVal */
{ {
/* Search for the macro */ /* Search for the macro */
Macro* M = HT_FindEntry (&MacroTab, SVal); Macro* M = HT_FindEntry (&MacroTab, &SVal);
CHECK (M != 0); CHECK (M != 0);
/* Call the apropriate subroutine */ /* Call the apropriate subroutine */
@@ -861,7 +866,7 @@ void MacAbort (void)
int IsMacro (const char* Name) int IsMacro (const StrBuf* Name)
/* Return true if the given name is the name of a macro */ /* Return true if the given name is the name of a macro */
{ {
return (HT_Find (&MacroTab, Name) != 0); return (HT_Find (&MacroTab, Name) != 0);
@@ -869,7 +874,7 @@ int IsMacro (const char* Name)
int IsDefine (const char* Name) int IsDefine (const StrBuf* Name)
/* Return true if the given name is the name of a define style macro */ /* Return true if the given name is the name of a define style macro */
{ {
Macro* M = HT_FindEntry (&MacroTab, Name); Macro* M = HT_FindEntry (&MacroTab, Name);
@@ -886,6 +891,3 @@ int InMacExpansion (void)

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -65,10 +65,10 @@ void MacExpandStart (void);
void MacAbort (void); void MacAbort (void);
/* Abort the current macro expansion */ /* Abort the current macro expansion */
int IsMacro (const char* Name); int IsMacro (const StrBuf* Name);
/* Return true if the given name is the name of a macro */ /* Return true if the given name is the name of a macro */
int IsDefine (const char* Name); int IsDefine (const StrBuf* Name);
/* Return true if the given name is the name of a define style macro */ /* Return true if the given name is the name of a define style macro */
int InMacExpansion (void); int InMacExpansion (void);

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -44,6 +44,7 @@
#include "cmdline.h" #include "cmdline.h"
#include "mmodel.h" #include "mmodel.h"
#include "print.h" #include "print.h"
#include "strbuf.h"
#include "target.h" #include "target.h"
#include "tgttrans.h" #include "tgttrans.h"
#include "version.h" #include "version.h"
@@ -127,14 +128,17 @@ static void Usage (void)
static void SetOptions (void) static void SetOptions (void)
/* Set the option for the translator */ /* Set the option for the translator */
{ {
char Buf [256]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
/* Set the translator */ /* Set the translator */
sprintf (Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH); SB_Printf (&Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
OptTranslator (Buf); OptTranslator (&Buf);
/* Set date and time */ /* Set date and time */
OptDateTime ((unsigned long) time(0)); OptDateTime ((unsigned long) time(0));
/* Release memory for the string */
SB_Done (&Buf);
} }
@@ -144,8 +148,12 @@ static void NewSymbol (const char* SymName, long Val)
{ {
ExprNode* Expr; ExprNode* Expr;
/* Convert the name to a string buffer */
StrBuf SymBuf = STATIC_STRBUF_INITIALIZER;
SB_CopyStr (&SymBuf, SymName);
/* Search for the symbol, allocate a new one if it doesn't exist */ /* Search for the symbol, allocate a new one if it doesn't exist */
SymEntry* Sym = SymFind (CurrentScope, SymName, SYM_ALLOC_NEW); SymEntry* Sym = SymFind (CurrentScope, &SymBuf, SYM_ALLOC_NEW);
/* Check if have already a symbol with this name */ /* Check if have already a symbol with this name */
if (SymIsDef (Sym)) { if (SymIsDef (Sym)) {
@@ -157,6 +165,9 @@ static void NewSymbol (const char* SymName, long Val)
/* Mark the symbol as defined */ /* Mark the symbol as defined */
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE); SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE);
/* Free string buffer memory */
SB_Done (&SymBuf);
} }
@@ -276,24 +287,21 @@ static void DefineSymbol (const char* Def)
const char* P; const char* P;
unsigned I; unsigned I;
long Val; long Val;
char SymName [MAX_STR_LEN+1]; StrBuf SymName = AUTO_STRBUF_INITIALIZER;
/* The symbol must start with a character or underline */ /* The symbol must start with a character or underline */
if (Def [0] != '_' && !IsAlpha (Def [0])) { if (!IsIdStart (Def [0])) {
InvDef (Def); InvDef (Def);
} }
P = Def; P = Def;
/* Copy the symbol, checking the rest */ /* Copy the symbol, checking the rest */
I = 0; I = 0;
while (IsAlNum (*P) || *P == '_') { while (IsIdChar (*P)) {
if (I <= MAX_STR_LEN) { SB_AppendChar (&SymName, *P++);
SymName [I++] = *P;
}
++P;
} }
SymName [I] = '\0'; SB_Terminate (&SymName);
/* Do we have a value given? */ /* Do we have a value given? */
if (*P != '=') { if (*P != '=') {
@@ -317,7 +325,10 @@ static void DefineSymbol (const char* Def)
} }
/* Define the new symbol */ /* Define the new symbol */
NewSymbol (SymName, Val); NewSymbol (SB_GetConstBuf (&SymName), Val);
/* Release string memory */
SB_Done (&SymName);
} }
@@ -356,8 +367,11 @@ static void OptDebugInfo (const char* Opt attribute ((unused)),
static void OptFeature (const char* Opt attribute ((unused)), const char* Arg) static void OptFeature (const char* Opt attribute ((unused)), const char* Arg)
/* Set an emulation feature */ /* Set an emulation feature */
{ {
/* Make a string buffer from Arg */
StrBuf Feature;
/* Set the feature, check for errors */ /* Set the feature, check for errors */
if (SetFeature (Arg) == FEAT_UNKNOWN) { if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) {
AbEnd ("Illegal emulation feature: `%s'", Arg); AbEnd ("Illegal emulation feature: `%s'", Arg);
} }
} }
@@ -425,8 +439,11 @@ static void OptListing (const char* Opt attribute ((unused)),
static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg) static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg)
/* Set a macro package directory */ /* Set a macro package directory */
{ {
/* Make a string buffer from Arg */
StrBuf Dir;
/* Use the directory */ /* Use the directory */
MacPackSetDir (Arg); MacPackSetDir (SB_InitFromString (&Dir, Arg));
} }
@@ -545,13 +562,13 @@ static void OneLine (void)
if (Tok == TOK_IDENT) { if (Tok == TOK_IDENT) {
if (!UbiquitousIdents) { if (!UbiquitousIdents) {
/* Macros and symbols cannot use instruction names */ /* Macros and symbols cannot use instruction names */
Instr = FindInstruction (SVal); Instr = FindInstruction (&SVal);
if (Instr < 0) { if (Instr < 0) {
Macro = IsMacro (SVal); Macro = IsMacro (&SVal);
} }
} else { } else {
/* Macros and symbols may use the names of instructions */ /* Macros and symbols may use the names of instructions */
Macro = IsMacro (SVal); Macro = IsMacro (&SVal);
} }
} }
@@ -563,9 +580,9 @@ static void OneLine (void)
/* Generate the symbol table entry, then skip the name */ /* Generate the symbol table entry, then skip the name */
if (Tok == TOK_IDENT) { if (Tok == TOK_IDENT) {
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW); Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
} else { } else {
Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW); Sym = SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW);
} }
NextTok (); NextTok ();
@@ -640,13 +657,13 @@ static void OneLine (void)
if (Tok == TOK_IDENT) { if (Tok == TOK_IDENT) {
if (!UbiquitousIdents) { if (!UbiquitousIdents) {
/* Macros and symbols cannot use instruction names */ /* Macros and symbols cannot use instruction names */
Instr = FindInstruction (SVal); Instr = FindInstruction (&SVal);
if (Instr < 0) { if (Instr < 0) {
Macro = IsMacro (SVal); Macro = IsMacro (&SVal);
} }
} else { } else {
/* Macros and symbols may use the names of instructions */ /* Macros and symbols may use the names of instructions */
Macro = IsMacro (SVal); Macro = IsMacro (&SVal);
} }
} }
} }
@@ -660,7 +677,7 @@ static void OneLine (void)
/* A macro expansion */ /* A macro expansion */
MacExpandStart (); MacExpandStart ();
} else if (Instr >= 0 || } else if (Instr >= 0 ||
(UbiquitousIdents && ((Instr = FindInstruction (SVal)) >= 0))) { (UbiquitousIdents && ((Instr = FindInstruction (&SVal)) >= 0))) {
/* A mnemonic - assemble one instruction */ /* A mnemonic - assemble one instruction */
HandleInstruction (Instr); HandleInstruction (Instr);
} else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) { } else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) {
@@ -774,6 +791,9 @@ int main (int argc, char* argv [])
{ "--version", 0, OptVersion }, { "--version", 0, OptVersion },
}; };
/* Name of the global name space */
static const StrBuf GlobalNameSpace = STATIC_STRBUF_INITIALIZER;
unsigned I; unsigned I;
/* Initialize the cmdline module */ /* Initialize the cmdline module */
@@ -782,7 +802,7 @@ int main (int argc, char* argv [])
/* Enter the base lexical level. We must do that here, since we may /* Enter the base lexical level. We must do that here, since we may
* define symbols using -D. * define symbols using -D.
*/ */
SymEnterLevel ("", ST_GLOBAL, ADDR_SIZE_DEFAULT); SymEnterLevel (&GlobalNameSpace, ST_GLOBAL, ADDR_SIZE_DEFAULT);
/* Check the parameters */ /* Check the parameters */
I = 1; I = 1;

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2007 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -142,10 +142,7 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
static void FuncConcat (void) static void FuncConcat (void)
/* Handle the .CONCAT function */ /* Handle the .CONCAT function */
{ {
char Buf[MAX_STR_LEN+1]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
char* B;
unsigned Length;
unsigned L;
/* Skip it */ /* Skip it */
NextTok (); NextTok ();
@@ -154,29 +151,16 @@ static void FuncConcat (void)
ConsumeLParen (); ConsumeLParen ();
/* Concatenate any number of strings */ /* Concatenate any number of strings */
B = Buf;
B[0] = '\0';
Length = 0;
while (1) { while (1) {
/* Next token must be a string */ /* Next token must be a string */
if (!LookAtStrCon ()) { if (!LookAtStrCon ()) {
SB_Done (&Buf);
return; return;
} }
/* Get the length of the string const and check total length */ /* Append the string */
L = strlen (SVal); SB_Append (&Buf, &SVal);
if (Length + L > MAX_STR_LEN) {
Error ("String is too long");
/* Try to recover */
SkipUntilSep ();
return;
}
/* Add the new string */
memcpy (B, SVal, L);
Length += L;
B += L;
/* Skip the string token */ /* Skip the string token */
NextTok (); NextTok ();
@@ -190,9 +174,6 @@ static void FuncConcat (void)
} }
} }
/* Terminate the string */
*B = '\0';
/* We expect a closing parenthesis, but will not skip it but replace it /* We expect a closing parenthesis, but will not skip it but replace it
* by the string token just created. * by the string token just created.
*/ */
@@ -200,8 +181,11 @@ static void FuncConcat (void)
Error ("`)' expected"); Error ("`)' expected");
} else { } else {
Tok = TOK_STRCON; Tok = TOK_STRCON;
strcpy (SVal, Buf); SB_Copy (&SVal, &Buf);
} }
/* Free the string buffer */
SB_Done (&Buf);
} }
@@ -218,9 +202,8 @@ static void NoIdent (void)
static void FuncIdent (void) static void FuncIdent (void)
/* Handle the .IDENT function */ /* Handle the .IDENT function */
{ {
char Buf[sizeof(SVal)]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
Token Id; Token Id;
unsigned Len;
unsigned I; unsigned I;
/* Skip it */ /* Skip it */
@@ -237,49 +220,45 @@ static void FuncIdent (void)
/* Check that the string contains a valid identifier. While doing so, /* Check that the string contains a valid identifier. While doing so,
* determine if it is a cheap local, or global one. * determine if it is a cheap local, or global one.
*/ */
Len = strlen (SVal); SB_Reset (&SVal);
if (Len == 0) {
NoIdent (); /* Check for a cheap local symbol */
return; if (SB_Peek (&SVal) == LocalStart) {
} SB_Skip (&SVal);
I = 0;
if (SVal[0] == LocalStart) {
if (Len < 2) {
NoIdent ();
return;
}
I = 1;
Id = TOK_LOCAL_IDENT; Id = TOK_LOCAL_IDENT;
} else { } else {
Id = TOK_IDENT; Id = TOK_IDENT;
} }
if (!IsIdStart (SVal[I])) {
/* Next character must be a valid identifier start */
if (!IsIdStart (SB_Get (&SVal))) {
NoIdent (); NoIdent ();
return; return;
} }
while (I < Len) { for (I = SB_GetIndex (&SVal); I < SB_GetLen (&SVal); ++I) {
if (!IsIdChar (SVal[I])) { if (!IsIdChar (SB_AtUnchecked (&SVal, I))) {
NoIdent (); NoIdent ();
return; return;
} }
++I;
} }
if (IgnoreCase) { if (IgnoreCase) {
UpcaseSVal (); UpcaseSVal ();
} }
/* If anything is ok, save and skip the string. Check that the next token /* If anything is ok, save and skip the string. Check that the next token
* is a right paren, in which case SVal is untouched. Replace the token by * is a right paren, then replace the token by an identifier token.
* a identifier token.
*/ */
memcpy (Buf, SVal, Len+1); SB_Copy (&Buf, &SVal);
NextTok (); NextTok ();
if (Tok != TOK_RPAREN) { if (Tok != TOK_RPAREN) {
Error ("`)' expected"); Error ("`)' expected");
} else { } else {
Tok = Id; Tok = Id;
memcpy (SVal, Buf, Len+1); SB_Copy (&SVal, &Buf);
} }
/* Free buffer memory */
SB_Done (&Buf);
} }
@@ -443,11 +422,11 @@ static void InvalidFormatString (void)
static void FuncSPrintF (void) static void FuncSPrintF (void)
/* Handle the .SPRINTF function */ /* Handle the .SPRINTF function */
{ {
char Format[sizeof (SVal)]; /* User given format */ StrBuf Format = STATIC_STRBUF_INITIALIZER; /* User supplied format */
const char* F = Format; /* User format pointer */ StrBuf R = STATIC_STRBUF_INITIALIZER; /* Result string */
StrBuf R = AUTO_STRBUF_INITIALIZER; /* Result string */ StrBuf F1 = STATIC_STRBUF_INITIALIZER; /* One format spec from F */
StrBuf F1 = AUTO_STRBUF_INITIALIZER; /* One format spec from F */ StrBuf R1 = STATIC_STRBUF_INITIALIZER; /* One result */
StrBuf R1 = AUTO_STRBUF_INITIALIZER; /* One result */ char C;
int Done; int Done;
long IVal; /* Integer value */ long IVal; /* Integer value */
@@ -463,30 +442,31 @@ static void FuncSPrintF (void)
if (!LookAtStrCon ()) { if (!LookAtStrCon ()) {
return; return;
} }
strcpy (Format, SVal); SB_Copy (&Format, &SVal);
NextTok (); NextTok ();
/* Walk over the format string, generating the function result in R */ /* Walk over the format string, generating the function result in R */
while (1) { while (1) {
/* Get the next char from the format string and check for EOS */ /* Get the next char from the format string and check for EOS */
if (*F == '\0') { if (SB_Peek (&Format) == '\0') {
break; break;
} }
/* Check for a format specifier */ /* Check for a format specifier */
if (*F != '%') { if (SB_Peek (&Format) != '%') {
/* No format specifier, just copy */ /* No format specifier, just copy */
SB_AppendChar (&R, *F++); SB_AppendChar (&R, SB_Get (&Format));
continue; continue;
} }
if (*++F == '%') { SB_Skip (&Format);
if (SB_Peek (&Format) == '%') {
/* %% */ /* %% */
SB_AppendChar (&R, '%'); SB_AppendChar (&R, '%');
++F; SB_Skip (&Format);
continue; continue;
} }
if (*F == '\0') { if (SB_Peek (&Format) == '\0') {
InvalidFormatString (); InvalidFormatString ();
break; break;
} }
@@ -505,32 +485,32 @@ static void FuncSPrintF (void)
/* Check for flags */ /* Check for flags */
Done = 0; Done = 0;
while (*F != '\0' && !Done) { while ((C = SB_Peek (&Format)) != '\0' && !Done) {
switch (*F) { switch (C) {
case '-': /* FALLTHROUGH */ case '-': /* FALLTHROUGH */
case '+': /* FALLTHROUGH */ case '+': /* FALLTHROUGH */
case ' ': /* FALLTHROUGH */ case ' ': /* FALLTHROUGH */
case '#': /* FALLTHROUGH */ case '#': /* FALLTHROUGH */
case '0': SB_AppendChar (&F1, *F++); break; case '0': SB_AppendChar (&F1, SB_Get (&Format)); break;
default: Done = 1; break; default: Done = 1; break;
} }
} }
/* We do only support a numerical width field */ /* We do only support a numerical width field */
while (IsDigit (*F)) { while (IsDigit (SB_Peek (&Format))) {
SB_AppendChar (&F1, *F++); SB_AppendChar (&F1, SB_Get (&Format));
} }
/* Precision - only positive numerical fields supported */ /* Precision - only positive numerical fields supported */
if (*F == '.') { if (SB_Peek (&Format) == '.') {
SB_AppendChar (&F1, *F++); SB_AppendChar (&F1, SB_Get (&Format));
while (IsDigit (*F)) { while (IsDigit (SB_Peek (&Format))) {
SB_AppendChar (&F1, *F++); SB_AppendChar (&F1, SB_Get (&Format));
} }
} }
/* Length modifiers aren't supported, so read the conversion specs */ /* Length modifiers aren't supported, so read the conversion specs */
switch (*F) { switch (SB_Peek (&Format)) {
case 'd': case 'd':
case 'i': case 'i':
@@ -542,7 +522,7 @@ static void FuncSPrintF (void)
* calling xsprintf later. Terminate the format string. * calling xsprintf later. Terminate the format string.
*/ */
SB_AppendChar (&F1, 'l'); SB_AppendChar (&F1, 'l');
SB_AppendChar (&F1, *F++); SB_AppendChar (&F1, SB_Get (&Format));
SB_Terminate (&F1); SB_Terminate (&F1);
/* The argument must be a constant expression */ /* The argument must be a constant expression */
@@ -558,13 +538,13 @@ static void FuncSPrintF (void)
case 's': case 's':
/* Add the format spec and terminate the format */ /* Add the format spec and terminate the format */
SB_AppendChar (&F1, *F++); SB_AppendChar (&F1, SB_Get (&Format));
SB_Terminate (&F1); SB_Terminate (&F1);
/* The argument must be a string constant */ /* The argument must be a string constant */
if (!LookAtStrCon ()) { if (!LookAtStrCon ()) {
/* Make it one */ /* Make it one */
strcpy (SVal, "**undefined**"); SB_CopyStr (&SVal, "**undefined**");
} }
/* Format this argument according to the spec */ /* Format this argument according to the spec */
@@ -580,7 +560,7 @@ static void FuncSPrintF (void)
case 'c': case 'c':
/* Add the format spec and terminate the format */ /* Add the format spec and terminate the format */
SB_AppendChar (&F1, *F++); SB_AppendChar (&F1, SB_Get (&Format));
SB_Terminate (&F1); SB_Terminate (&F1);
/* The argument must be a constant expression */ /* The argument must be a constant expression */
@@ -604,21 +584,12 @@ static void FuncSPrintF (void)
default: default:
Error ("Invalid format string"); Error ("Invalid format string");
if (*F) { SB_Skip (&Format);
/* Don't skip beyond end of string */
++F;
}
break; break;
} }
} }
/* The length of the final result may not exceed the size of a string */
if (SB_GetLen (&R) >= sizeof (SVal)) {
Error ("Resulting string is too long");
SB_Cut (&R, sizeof (SVal) - 1);
}
/* Terminate the result string */ /* Terminate the result string */
SB_Terminate (&R); SB_Terminate (&R);
@@ -629,14 +600,15 @@ static void FuncSPrintF (void)
Error ("`)' expected"); Error ("`)' expected");
} else { } else {
Tok = TOK_STRCON; Tok = TOK_STRCON;
memcpy (SVal, SB_GetConstBuf (&R), SB_GetLen (&R) + 1); SB_Copy (&SVal, &R);
} }
/* Delete the string buffers */ /* Delete the string buffers */
DoneStrBuf (&R); SB_Done (&Format);
DoneStrBuf (&F1); SB_Done (&R);
DoneStrBuf (&R1); SB_Done (&F1);
SB_Done (&R1);
} }
@@ -644,7 +616,7 @@ static void FuncSPrintF (void)
static void FuncString (void) static void FuncString (void)
/* Handle the .STRING function */ /* Handle the .STRING function */
{ {
char Buf[MAX_STR_LEN+1]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
/* Skip it */ /* Skip it */
NextTok (); NextTok ();
@@ -655,12 +627,12 @@ static void FuncString (void)
/* Accept identifiers or numeric expressions */ /* Accept identifiers or numeric expressions */
if (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) { if (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) {
/* Save the identifier, then skip it */ /* Save the identifier, then skip it */
strcpy (Buf, SVal); SB_Copy (&Buf, &SVal);
NextTok (); NextTok ();
} else { } else {
/* Numeric expression */ /* Numeric expression */
long Val = ConstExpression (); long Val = ConstExpression ();
sprintf (Buf, "%ld", Val); SB_Printf (&Buf, "%ld", Val);
} }
/* We expect a closing parenthesis, but will not skip it but replace it /* We expect a closing parenthesis, but will not skip it but replace it
@@ -670,8 +642,11 @@ static void FuncString (void)
Error ("`)' expected"); Error ("`)' expected");
} else { } else {
Tok = TOK_STRCON; Tok = TOK_STRCON;
strcpy (SVal, Buf); SB_Copy (&SVal, &Buf);
} }
/* Free string memory */
SB_Done (&Buf);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -104,15 +104,18 @@ void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size)
void EmitData (const unsigned char* Data, unsigned Size) void EmitData (const void* D, unsigned Size)
/* Emit data into the current segment */ /* Emit data into the current segment */
{ {
/* Make a useful pointer from Data */
const unsigned char* Data = D;
/* Create lots of fragments for the data */ /* Create lots of fragments for the data */
while (Size) { while (Size) {
Fragment* F; Fragment* F;
/* Determine the length of the next fragment */ /* Determine the length of the next fragment */
unsigned Len = Size; unsigned Len = Size;
if (Len > sizeof (F->V.Data)) { if (Len > sizeof (F->V.Data)) {
Len = sizeof (F->V.Data); Len = sizeof (F->V.Data);
} }
@@ -132,6 +135,15 @@ void EmitData (const unsigned char* Data, unsigned Size)
void EmitStrBuf (const StrBuf* Data)
/* Emit a string into the current segment */
{
/* Use EmitData to output the data */
EmitData (SB_GetConstBuf (Data), SB_GetLen (Data));
}
void EmitByte (ExprNode* Expr) void EmitByte (ExprNode* Expr)
/* Emit one byte */ /* Emit one byte */
{ {

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -40,6 +40,7 @@
/* ca65 */ /* ca65 */
#include "expr.h" #include "expr.h"
#include "strbuf.h"
@@ -67,9 +68,12 @@ void EmitSigned (ExprNode* Expr, unsigned Size);
void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size); void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size);
/* Emit an opcode with a PC relative argument of one or two bytes */ /* Emit an opcode with a PC relative argument of one or two bytes */
void EmitData (const unsigned char* Data, unsigned Size); void EmitData (const void* Data, unsigned Size);
/* Emit data into the current segment */ /* Emit data into the current segment */
void EmitStrBuf (const StrBuf* Data);
/* Emit a string into the current segment */
void EmitByte (ExprNode* Expr); void EmitByte (ExprNode* Expr);
/* Emit one byte */ /* Emit one byte */

View File

@@ -296,6 +296,19 @@ void ObjWriteStr (const char* S)
void ObjWriteBuf (const StrBuf* S)
/* Write a string to the object file */
{
/* Write the string with the length preceeded (this is easier for
* the reading routine than the C format since the length is known in
* advance).
*/
ObjWriteVar (SB_GetLen (S));
ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S));
}
void ObjWriteData (const void* Data, unsigned Size) void ObjWriteData (const void* Data, unsigned Size)
/* Write literal data to the file */ /* Write literal data to the file */
{ {

View File

@@ -40,6 +40,7 @@
/* common */ /* common */
#include "filepos.h" #include "filepos.h"
#include "strbuf.h"
@@ -79,6 +80,9 @@ void ObjWriteVar (unsigned long V);
void ObjWriteStr (const char* S); void ObjWriteStr (const char* S);
/* Write a string to the object file */ /* Write a string to the object file */
void ObjWriteBuf (const StrBuf* S);
/* Write a string to the object file */
void ObjWriteData (const void* Data, unsigned Size); void ObjWriteData (const void* Data, unsigned Size);
/* Write literal data to the file */ /* Write literal data to the file */

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -96,50 +96,50 @@ static Option* NewOption (unsigned char Type, unsigned long Val)
void OptStr (unsigned char Type, const char* Text) void OptStr (unsigned char Type, const StrBuf* Text)
/* Add a string option */ /* Add a string option */
{ {
NewOption (Type, GetStringId (Text)); NewOption (Type, GetStrBufId (Text));
} }
void OptComment (const char* Comment) void OptComment (const StrBuf* Comment)
/* Add a comment */ /* Add a comment */
{ {
NewOption (OPT_COMMENT, GetStringId (Comment)); NewOption (OPT_COMMENT, GetStrBufId (Comment));
} }
void OptAuthor (const char* Author) void OptAuthor (const StrBuf* Author)
/* Add an author statement */ /* Add an author statement */
{ {
NewOption (OPT_AUTHOR, GetStringId (Author)); NewOption (OPT_AUTHOR, GetStrBufId (Author));
} }
void OptTranslator (const char* Translator) void OptTranslator (const StrBuf* Translator)
/* Add a translator option */ /* Add a translator option */
{ {
NewOption (OPT_TRANSLATOR, GetStringId (Translator)); NewOption (OPT_TRANSLATOR, GetStrBufId (Translator));
} }
void OptCompiler (const char* Compiler) void OptCompiler (const StrBuf* Compiler)
/* Add a compiler option */ /* Add a compiler option */
{ {
NewOption (OPT_COMPILER, GetStringId (Compiler)); NewOption (OPT_COMPILER, GetStrBufId (Compiler));
} }
void OptOS (const char* OS) void OptOS (const StrBuf* OS)
/* Add an operating system option */ /* Add an operating system option */
{ {
NewOption (OPT_OS, GetStringId (OS)); NewOption (OPT_OS, GetStrBufId (OS));
} }
@@ -182,3 +182,4 @@ void WriteOptions (void)

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -44,22 +44,22 @@
void OptStr (unsigned char Type, const char* Text); void OptStr (unsigned char Type, const StrBuf* Text);
/* Add a string option */ /* Add a string option */
void OptComment (const char* Comment); void OptComment (const StrBuf* Comment);
/* Add a comment */ /* Add a comment */
void OptAuthor (const char* Author); void OptAuthor (const StrBuf* Author);
/* Add an author statement */ /* Add an author statement */
void OptTranslator (const char* Translator); void OptTranslator (const StrBuf* Translator);
/* Add a translator option */ /* Add a translator option */
void OptCompiler (const char* Compiler); void OptCompiler (const StrBuf* Compiler);
/* Add a compiler option */ /* Add a compiler option */
void OptOS (const char* OS); void OptOS (const StrBuf* OS);
/* Add an operating system option */ /* Add an operating system option */
void OptDateTime (unsigned long DateTime); void OptDateTime (unsigned long DateTime);
@@ -68,7 +68,7 @@ void OptDateTime (unsigned long DateTime);
void WriteOptions (void); void WriteOptions (void);
/* Write the options to the object file */ /* Write the options to the object file */
/* End of options.h */ /* End of options.h */

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -84,7 +84,7 @@
/* Keyword we're about to handle */ /* Keyword we're about to handle */
static char Keyword [sizeof (SVal)+1]; static StrBuf Keyword = STATIC_STRBUF_INITIALIZER;
/* Segment stack */ /* Segment stack */
#define MAX_PUSHED_SEGMENTS 16 #define MAX_PUSHED_SEGMENTS 16
@@ -208,7 +208,7 @@ static void ExportImport (void (*Func) (SymEntry*, unsigned char, unsigned),
} }
/* Find the symbol table entry, allocate a new one if necessary */ /* Find the symbol table entry, allocate a new one if necessary */
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW); Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
/* Skip the name */ /* Skip the name */
NextTok (); NextTok ();
@@ -238,7 +238,7 @@ static long IntArg (long Min, long Max)
* and return -1 in this case. * and return -1 in this case.
*/ */
{ {
if (Tok == TOK_IDENT && strcmp (SVal, "unlimited") == 0) { if (Tok == TOK_IDENT && SB_CompareStr (&SVal, "unlimited") == 0) {
NextTok (); NextTok ();
return -1; return -1;
} else { } else {
@@ -253,7 +253,7 @@ static long IntArg (long Min, long Max)
static void ConDes (const char* Name, unsigned Type) static void ConDes (const StrBuf* Name, unsigned Type)
/* Parse remaining line for constructor/destructor of the remaining type */ /* Parse remaining line for constructor/destructor of the remaining type */
{ {
long Prio; long Prio;
@@ -376,8 +376,6 @@ static void DoAlign (void)
static void DoASCIIZ (void) static void DoASCIIZ (void)
/* Define text with a zero terminator */ /* Define text with a zero terminator */
{ {
unsigned Len;
while (1) { while (1) {
/* Must have a string constant */ /* Must have a string constant */
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
@@ -385,12 +383,9 @@ static void DoASCIIZ (void)
return; return;
} }
/* Get the length of the string constant */
Len = strlen (SVal);
/* Translate into target charset and emit */ /* Translate into target charset and emit */
TgtTranslateBuf (SVal, Len); TgtTranslateStrBuf (&SVal);
EmitData ((unsigned char*) SVal, Len); EmitStrBuf (&SVal);
NextTok (); NextTok ();
if (Tok == TOK_COMMA) { if (Tok == TOK_COMMA) {
NextTok (); NextTok ();
@@ -459,7 +454,7 @@ static void DoAssert (void)
/* Translate the message into a string id. We can then skip the input /* Translate the message into a string id. We can then skip the input
* string. * string.
*/ */
Msg = GetStringId (SVal); Msg = GetStrBufId (&SVal);
NextTok (); NextTok ();
} else { } else {
@@ -497,9 +492,8 @@ static void DoByte (void)
while (1) { while (1) {
if (Tok == TOK_STRCON) { if (Tok == TOK_STRCON) {
/* A string, translate into target charset and emit */ /* A string, translate into target charset and emit */
unsigned Len = strlen (SVal); TgtTranslateStrBuf (&SVal);
TgtTranslateBuf (SVal, Len); EmitStrBuf (&SVal);
EmitData ((unsigned char*) SVal, Len);
NextTok (); NextTok ();
} else { } else {
EmitByte (Expression ()); EmitByte (Expression ());
@@ -575,7 +569,7 @@ static void DoConDes (void)
"DESTRUCTOR", "DESTRUCTOR",
"INTERRUPTOR", "INTERRUPTOR",
}; };
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
long Type; long Type;
/* Symbol name follows */ /* Symbol name follows */
@@ -583,7 +577,7 @@ static void DoConDes (void)
ErrorSkip ("Identifier expected"); ErrorSkip ("Identifier expected");
return; return;
} }
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
/* Type follows. May be encoded as identifier or numerical */ /* Type follows. May be encoded as identifier or numerical */
@@ -596,9 +590,8 @@ static void DoConDes (void)
/* Check if we got a valid keyword */ /* Check if we got a valid keyword */
if (Type < 0) { if (Type < 0) {
Error ("Syntax error"); ErrorSkip ("Syntax error");
SkipUntilSep (); goto ExitPoint;
return;
} }
} else { } else {
@@ -607,14 +600,18 @@ static void DoConDes (void)
Type = ConstExpression (); Type = ConstExpression ();
if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) { if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
/* Value out of range */ /* Value out of range */
Error ("Range error"); ErrorSkip ("Range error");
return; goto ExitPoint;
} }
} }
/* Parse the remainder of the line and export the symbol */ /* Parse the remainder of the line and export the symbol */
ConDes (Name, (unsigned) Type); ConDes (&Name, (unsigned) Type);
ExitPoint:
/* Free string memory */
SB_Done (&Name);
} }
@@ -622,18 +619,21 @@ static void DoConDes (void)
static void DoConstructor (void) static void DoConstructor (void)
/* Export a symbol as constructor */ /* Export a symbol as constructor */
{ {
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
/* Symbol name follows */ /* Symbol name follows */
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected"); ErrorSkip ("Identifier expected");
return; return;
} }
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
/* Parse the remainder of the line and export the symbol */ /* Parse the remainder of the line and export the symbol */
ConDes (Name, CD_TYPE_CON); ConDes (&Name, CD_TYPE_CON);
/* Free string memory */
SB_Done (&Name);
} }
@@ -714,18 +714,21 @@ static void DoDefine (void)
static void DoDestructor (void) static void DoDestructor (void)
/* Export a symbol as destructor */ /* Export a symbol as destructor */
{ {
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
/* Symbol name follows */ /* Symbol name follows */
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected"); ErrorSkip ("Identifier expected");
return; return;
} }
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
/* Parse the remainder of the line and export the symbol */ /* Parse the remainder of the line and export the symbol */
ConDes (Name, CD_TYPE_DES); ConDes (&Name, CD_TYPE_DES);
/* Free string memory */
SB_Done (&Name);
} }
@@ -786,7 +789,7 @@ static void DoError (void)
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
} else { } else {
Error ("User error: %s", SVal); Error ("User error: %m%p", &SVal);
SkipUntilSep (); SkipUntilSep ();
} }
} }
@@ -853,9 +856,9 @@ static void DoFeature (void)
LocaseSVal (); LocaseSVal ();
/* Set the feature and check for errors */ /* Set the feature and check for errors */
if (SetFeature (SVal) == FEAT_UNKNOWN) { if (SetFeature (&SVal) == FEAT_UNKNOWN) {
/* Not found */ /* Not found */
ErrorSkip ("Invalid feature: `%s'", SVal); ErrorSkip ("Invalid feature: `%m%p'", &SVal);
return; return;
} else { } else {
/* Skip the keyword */ /* Skip the keyword */
@@ -911,17 +914,17 @@ static void DoFileOpt (void)
case 0: case 0:
/* Author */ /* Author */
OptAuthor (SVal); OptAuthor (&SVal);
break; break;
case 1: case 1:
/* Comment */ /* Comment */
OptComment (SVal); OptComment (&SVal);
break; break;
case 2: case 2:
/* Compiler */ /* Compiler */
OptCompiler (SVal); OptCompiler (&SVal);
break; break;
default: default:
@@ -951,7 +954,7 @@ static void DoFileOpt (void)
} }
/* Insert the option */ /* Insert the option */
OptStr ((unsigned char) OptNum, SVal); OptStr ((unsigned char) OptNum, &SVal);
/* Done */ /* Done */
NextTok (); NextTok ();
@@ -1029,7 +1032,7 @@ static void DoImportZP (void)
static void DoIncBin (void) static void DoIncBin (void)
/* Include a binary file */ /* Include a binary file */
{ {
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
long Start = 0L; long Start = 0L;
long Count = -1L; long Count = -1L;
long Size; long Size;
@@ -1040,7 +1043,8 @@ static void DoIncBin (void)
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
return; return;
} }
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
SB_Terminate (&Name);
NextTok (); NextTok ();
/* A starting offset may follow */ /* A starting offset may follow */
@@ -1057,14 +1061,14 @@ static void DoIncBin (void)
} }
/* Try to open the file */ /* Try to open the file */
F = fopen (Name, "rb"); F = fopen (SB_GetConstBuf (&Name), "rb");
if (F == 0) { if (F == 0) {
/* Search for the file in the include directories. */ /* Search for the file in the include directories. */
char* PathName = FindInclude (Name); char* PathName = FindInclude (SB_GetConstBuf (&Name));
if (PathName == 0 || (F = fopen (PathName, "r")) == 0) { if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
/* Not found or cannot open, print an error and bail out */ /* Not found or cannot open, print an error and bail out */
ErrorSkip ("Cannot open include file `%s': %s", Name, strerror (errno)); ErrorSkip ("Cannot open include file `%m%p': %s", &Name, strerror (errno));
} }
/* Free the allocated memory */ /* Free the allocated memory */
@@ -1072,7 +1076,7 @@ static void DoIncBin (void)
/* If we had an error before, bail out now */ /* If we had an error before, bail out now */
if (F == 0) { if (F == 0) {
return; goto ExitPoint;
} }
} }
@@ -1111,8 +1115,8 @@ static void DoIncBin (void)
size_t BytesRead = fread (Buf, 1, BytesToRead, F); size_t BytesRead = fread (Buf, 1, BytesToRead, F);
if (BytesToRead != BytesRead) { if (BytesToRead != BytesRead) {
/* Some sort of error */ /* Some sort of error */
ErrorSkip ("Cannot read from include file `%s': %s", ErrorSkip ("Cannot read from include file `%m%p': %s",
Name, strerror (errno)); &Name, strerror (errno));
break; break;
} }
@@ -1126,6 +1130,10 @@ static void DoIncBin (void)
Done: Done:
/* Close the file, ignore errors since it's r/o */ /* Close the file, ignore errors since it's r/o */
(void) fclose (F); (void) fclose (F);
ExitPoint:
/* Free string memory */
SB_Done (&Name);
} }
@@ -1136,8 +1144,9 @@ static void DoInclude (void)
/* Name must follow */ /* Name must follow */
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
} else { } else {
NewInputFile (SVal); SB_Terminate (&SVal);
NewInputFile (SB_GetConstBuf (&SVal));
} }
} }
@@ -1146,18 +1155,21 @@ static void DoInclude (void)
static void DoInterruptor (void) static void DoInterruptor (void)
/* Export a symbol as interruptor */ /* Export a symbol as interruptor */
{ {
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
/* Symbol name follows */ /* Symbol name follows */
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
ErrorSkip ("Identifier expected"); ErrorSkip ("Identifier expected");
return; return;
} }
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
/* Parse the remainder of the line and export the symbol */ /* Parse the remainder of the line and export the symbol */
ConDes (Name, CD_TYPE_INT); ConDes (&Name, CD_TYPE_INT);
/* Free string memory */
SB_Done (&Name);
} }
@@ -1171,7 +1183,7 @@ static void DoInvalid (void)
* an error in the assembler itself, while DoInvalid is. * an error in the assembler itself, while DoInvalid is.
*/ */
{ {
Internal ("Unexpected token: %s", Keyword); Internal ("Unexpected token: %m%p", &Keyword);
} }
@@ -1238,7 +1250,8 @@ static void DoMacPack (void)
} }
/* Search for the macro package name */ /* Search for the macro package name */
Package = MacPackFind (SVal); LocaseSVal ();
Package = MacPackFind (&SVal);
if (Package < 0) { if (Package < 0) {
/* Not found */ /* Not found */
ErrorSkip ("Invalid macro package"); ErrorSkip ("Invalid macro package");
@@ -1289,7 +1302,7 @@ static void DoOut (void)
/* Output the string and be sure to flush the output to keep it in /* Output the string and be sure to flush the output to keep it in
* sync with any error messages if the output is redirected to a file. * sync with any error messages if the output is redirected to a file.
*/ */
printf ("%s\n", SVal); printf ("%m%p\n", &SVal);
fflush (stdout); fflush (stdout);
NextTok (); NextTok ();
} }
@@ -1355,7 +1368,7 @@ static void DoPopSeg (void)
static void DoProc (void) static void DoProc (void)
/* Start a new lexical scope */ /* Start a new lexical scope */
{ {
char Name[sizeof(SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
unsigned char AddrSize; unsigned char AddrSize;
if (Tok == TOK_IDENT) { if (Tok == TOK_IDENT) {
@@ -1363,10 +1376,10 @@ static void DoProc (void)
SymEntry* Sym; SymEntry* Sym;
/* The new scope has a name. Remember it. */ /* The new scope has a name. Remember it. */
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
/* Search for the symbol, generate a new one if needed */ /* Search for the symbol, generate a new one if needed */
Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW); Sym = SymFind (CurrentScope, &Name, SYM_ALLOC_NEW);
/* Skip the scope name */ /* Skip the scope name */
NextTok (); NextTok ();
@@ -1381,13 +1394,16 @@ static void DoProc (void)
/* A .PROC statement without a name */ /* A .PROC statement without a name */
Warning (1, "Unnamed .PROCs are deprecated, please use .SCOPE"); Warning (1, "Unnamed .PROCs are deprecated, please use .SCOPE");
AnonName (Name, sizeof (Name), "PROC"); AnonName (&Name, "PROC");
AddrSize = ADDR_SIZE_DEFAULT; AddrSize = ADDR_SIZE_DEFAULT;
} }
/* Enter a new scope */ /* Enter a new scope */
SymEnterLevel (Name, ST_PROC, AddrSize); SymEnterLevel (&Name, ST_PROC, AddrSize);
/* Free memory for Name */
SB_Done (&Name);
} }
@@ -1475,20 +1491,20 @@ static void DoROData (void)
static void DoScope (void) static void DoScope (void)
/* Start a local scope */ /* Start a local scope */
{ {
char Name[sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
unsigned char AddrSize; unsigned char AddrSize;
if (Tok == TOK_IDENT) { if (Tok == TOK_IDENT) {
/* The new scope has a name. Remember and skip it. */ /* The new scope has a name. Remember and skip it. */
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
} else { } else {
/* An unnamed scope */ /* An unnamed scope */
AnonName (Name, sizeof (Name), "SCOPE"); AnonName (&Name, "SCOPE");
} }
@@ -1496,8 +1512,10 @@ static void DoScope (void)
AddrSize = OptionalAddrSize (); AddrSize = OptionalAddrSize ();
/* Enter the new scope */ /* Enter the new scope */
SymEnterLevel (Name, ST_SCOPE, AddrSize); SymEnterLevel (&Name, ST_SCOPE, AddrSize);
/* Free memory for Name */
SB_Done (&Name);
} }
@@ -1505,24 +1523,30 @@ static void DoScope (void)
static void DoSegment (void) static void DoSegment (void)
/* Switch to another segment */ /* Switch to another segment */
{ {
char Name [sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
SegDef Def; SegDef Def;
Def.Name = Name;
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
} else { } else {
/* Save the name of the segment and skip it */ /* Save the name of the segment and skip it */
strcpy (Name, SVal); SB_Copy (&Name, &SVal);
NextTok (); NextTok ();
/* Use the name for the segment definition */
SB_Terminate (&Name);
Def.Name = SB_GetBuf (&Name);
/* Check for an optional address size modifier */ /* Check for an optional address size modifier */
Def.AddrSize = OptionalAddrSize (); Def.AddrSize = OptionalAddrSize ();
/* Set the segment */ /* Set the segment */
UseSeg (&Def); UseSeg (&Def);
} }
/* Free memory for Name */
SB_Done (&Name);
} }
@@ -1535,7 +1559,8 @@ static void DoSetCPU (void)
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
} else { } else {
/* Try to find the CPU */ /* Try to find the CPU */
cpu_t CPU = FindCPU (SVal); SB_Terminate (&SVal);
cpu_t CPU = FindCPU (SB_GetConstBuf (&SVal));
/* Switch to the new CPU */ /* Switch to the new CPU */
SetCPU (CPU); SetCPU (CPU);
@@ -1615,7 +1640,7 @@ static void DoTag (void)
static void DoUnexpected (void) static void DoUnexpected (void)
/* Got an unexpected keyword */ /* Got an unexpected keyword */
{ {
Error ("Unexpected `%s'", Keyword); Error ("Unexpected `%m%p'", &Keyword);
SkipUntilSep (); SkipUntilSep ();
} }
@@ -1627,7 +1652,7 @@ static void DoWarning (void)
if (Tok != TOK_STRCON) { if (Tok != TOK_STRCON) {
ErrorSkip ("String constant expected"); ErrorSkip ("String constant expected");
} else { } else {
Warning (0, "User warning: %s", SVal); Warning (0, "User warning: %m%p", &SVal);
SkipUntilSep (); SkipUntilSep ();
} }
} }
@@ -1832,7 +1857,7 @@ void HandlePseudo (void)
/* Remember the instruction, then skip it if needed */ /* Remember the instruction, then skip it if needed */
if ((D->Flags & ccKeepToken) == 0) { if ((D->Flags & ccKeepToken) == 0) {
strcpy (Keyword, SVal); SB_Copy (&Keyword, &SVal);
NextTok (); NextTok ();
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000 Ullrich von Bassewitz */ /* (C) 2000-2008, Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -109,7 +109,7 @@ static void RepeatTokenCheck (TokList* L)
* for and replace identifiers that are the repeat counter. * for and replace identifiers that are the repeat counter.
*/ */
{ {
if (Tok == TOK_IDENT && L->Data != 0 && strcmp (SVal, L->Data) == 0) { if (Tok == TOK_IDENT && L->Data != 0 && SB_CompareStr (&SVal, L->Data) == 0) {
/* Must replace by the repeat counter */ /* Must replace by the repeat counter */
Tok = TOK_INTCON; Tok = TOK_INTCON;
IVal = L->RepCount; IVal = L->RepCount;
@@ -143,7 +143,8 @@ void ParseRepeat (void)
ErrorSkip ("Identifier expected"); ErrorSkip ("Identifier expected");
} else { } else {
/* Remember the name and skip it */ /* Remember the name and skip it */
Name = xstrdup (SVal); SB_Terminate (&SVal);
Name = xstrdup (SB_GetConstBuf (&SVal));
NextTok (); NextTok ();
} }
} }

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -73,7 +73,7 @@
Token Tok = TOK_NONE; /* Current token */ Token Tok = TOK_NONE; /* Current token */
int WS; /* Flag: Whitespace before token */ int WS; /* Flag: Whitespace before token */
long IVal; /* Integer token attribute */ long IVal; /* Integer token attribute */
char SVal[MAX_STR_LEN+1]; /* String token attribute */ StrBuf SVal = STATIC_STRBUF_INITIALIZER;/* String token attribute */
FilePos CurPos = { 0, 0, 0 }; /* Name and position in current file */ FilePos CurPos = { 0, 0, 0 }; /* Name and position in current file */
@@ -459,6 +459,7 @@ void NewInputFile (const char* Name)
/* check again if we do now have an open file */ /* check again if we do now have an open file */
if (F != 0) { if (F != 0) {
StrBuf NameBuf;
unsigned FileIdx; unsigned FileIdx;
CharSource* S; CharSource* S;
@@ -476,7 +477,7 @@ void NewInputFile (const char* Name)
} }
/* Add the file to the input file table and remember the index */ /* Add the file to the input file table and remember the index */
FileIdx = AddFile (Name, Buf.st_size, Buf.st_mtime); FileIdx = AddFile (SB_InitFromString (&NameBuf, Name), Buf.st_size, Buf.st_mtime);
/* Create a new input source variable and initialize it */ /* Create a new input source variable and initialize it */
S = xmalloc (sizeof (*S)); S = xmalloc (sizeof (*S));
@@ -619,11 +620,7 @@ static void NextChar (void)
void LocaseSVal (void) void LocaseSVal (void)
/* Make SVal lower case */ /* Make SVal lower case */
{ {
unsigned I = 0; SB_ToLower (&SVal);
while (SVal [I]) {
SVal [I] = tolower (SVal [I]);
++I;
}
} }
@@ -631,11 +628,7 @@ void LocaseSVal (void)
void UpcaseSVal (void) void UpcaseSVal (void)
/* Make SVal upper case */ /* Make SVal upper case */
{ {
unsigned I = 0; SB_ToUpper (&SVal);
while (SVal [I]) {
SVal [I] = toupper (SVal [I]);
++I;
}
} }
@@ -653,7 +646,7 @@ static unsigned char FindDotKeyword (void)
* return TOK_NONE if not found. * return TOK_NONE if not found.
*/ */
{ {
static const struct DotKeyword K = { SVal, 0 }; struct DotKeyword K = { SB_GetConstBuf (&SVal), 0 };
struct DotKeyword* R; struct DotKeyword* R;
/* If we aren't in ignore case mode, we have to uppercase the keyword */ /* If we aren't in ignore case mode, we have to uppercase the keyword */
@@ -673,20 +666,19 @@ static unsigned char FindDotKeyword (void)
static void ReadIdent (unsigned Index) static void ReadIdent (void)
/* Read an identifier from the current input position into Ident. Filling SVal /* Read an identifier from the current input position into Ident. Filling SVal
* starts at Index with the current character in C. It is assumed that any * starts at the current position with the next character in C. It is assumed
* characters already filled in are ok, and the character in C is checked. * that any characters already filled in are ok, and the character in C is
* checked.
*/ */
{ {
/* Read the identifier */ /* Read the identifier */
do { do {
if (Index < MAX_STR_LEN) { SB_AppendChar (&SVal, C);
SVal [Index++] = C; NextChar ();
}
NextChar ();
} while (IsIdChar (C)); } while (IsIdChar (C));
SVal [Index] = '\0'; SB_Terminate (&SVal);
/* If we should ignore case, convert the identifier to upper case */ /* If we should ignore case, convert the identifier to upper case */
if (IgnoreCase) { if (IgnoreCase) {
@@ -696,18 +688,13 @@ static void ReadIdent (unsigned Index)
static unsigned ReadStringConst (int StringTerm) static void ReadStringConst (int StringTerm)
/* Read a string constant into SVal. Check for maximum string length and all /* Read a string constant into SVal. */
* other stuff. The length of the string is returned.
*/
{ {
unsigned I;
/* Skip the leading string terminator */ /* Skip the leading string terminator */
NextChar (); NextChar ();
/* Read the string */ /* Read the string */
I = 0;
while (1) { while (1) {
if (C == StringTerm) { if (C == StringTerm) {
break; break;
@@ -717,13 +704,8 @@ static unsigned ReadStringConst (int StringTerm)
break; break;
} }
/* Check for string length, print an error message once */ /* Append the char to the string */
if (I == MAX_STR_LEN) { SB_AppendChar (&SVal, C);
Error ("Maximum string size exceeded");
} else if (I < MAX_STR_LEN) {
SVal [I] = C;
}
++I;
/* Skip the character */ /* Skip the character */
NextChar (); NextChar ();
@@ -733,18 +715,12 @@ static unsigned ReadStringConst (int StringTerm)
NextChar (); NextChar ();
/* Terminate the string */ /* Terminate the string */
if (I >= MAX_STR_LEN) { SB_Terminate (&SVal);
I = MAX_STR_LEN;
}
SVal [I] = '\0';
/* Return the length of the string */
return I;
} }
static int Sweet16Reg (const char* Ident) static int Sweet16Reg (const StrBuf* Id)
/* Check if the given identifier is a sweet16 register. Return -1 if this is /* Check if the given identifier is a sweet16 register. Return -1 if this is
* not the case, return the register number otherwise. * not the case, return the register number otherwise.
*/ */
@@ -752,14 +728,17 @@ static int Sweet16Reg (const char* Ident)
unsigned RegNum; unsigned RegNum;
char Check; char Check;
if (Ident[0] != 'r' && Ident[0] != 'R') { if (SB_GetLen (Id) < 2) {
return -1; return -1;
} }
if (!IsDigit (Ident[1])) { if (toupper (SB_AtUnchecked (Id, 0)) != 'R') {
return -1;
}
if (!IsDigit (SB_AtUnchecked (Id, 1))) {
return -1; return -1;
} }
if (sscanf (Ident+1, "%u%c", &RegNum, &Check) != 1 || RegNum > 15) { if (sscanf (SB_GetConstBuf (Id)+1, "%u%c", &RegNum, &Check) != 1 || RegNum > 15) {
/* Invalid register */ /* Invalid register */
return -1; return -1;
} }
@@ -796,6 +775,9 @@ Again:
/* Mark the file position of the next token */ /* Mark the file position of the next token */
Source->Func->MarkStart (Source); Source->Func->MarkStart (Source);
/* Clear the string attribute */
SB_Clear (&SVal);
/* Hex number or PC symbol? */ /* Hex number or PC symbol? */
if (C == '$') { if (C == '$') {
NextChar (); NextChar ();
@@ -928,8 +910,8 @@ Again:
} else { } else {
/* Read the remainder of the identifier */ /* Read the remainder of the identifier */
SVal[0] = '.'; SB_AppendChar (&SVal, '.');
ReadIdent (1); ReadIdent ();
/* Dot keyword, search for it */ /* Dot keyword, search for it */
Tok = FindDotKeyword (); Tok = FindDotKeyword ();
@@ -938,14 +920,14 @@ Again:
/* Not found */ /* Not found */
if (!LeadingDotInIdents) { if (!LeadingDotInIdents) {
/* Invalid pseudo instruction */ /* Invalid pseudo instruction */
Error ("`%s' is not a recognized control command", SVal); Error ("`%m%p' is not a recognized control command", &SVal);
goto Again; goto Again;
} }
/* An identifier with a dot. Check if it's a define style /* An identifier with a dot. Check if it's a define style
* macro. * macro.
*/ */
if (IsDefine (SVal)) { if (IsDefine (&SVal)) {
/* This is a define style macro - expand it */ /* This is a define style macro - expand it */
MacExpandStart (); MacExpandStart ();
goto Restart; goto Restart;
@@ -971,11 +953,11 @@ Again:
/* Local symbol? */ /* Local symbol? */
if (C == LocalStart) { if (C == LocalStart) {
/* Read the identifier */ /* Read the identifier. */
ReadIdent (0); ReadIdent ();
/* Start character alone is not enough */ /* Start character alone is not enough */
if (SVal [1] == '\0') { if (SB_GetLen (&SVal) == 1) {
Error ("Invalid cheap local symbol"); Error ("Invalid cheap local symbol");
goto Again; goto Again;
} }
@@ -990,13 +972,13 @@ Again:
if (IsIdStart (C)) { if (IsIdStart (C)) {
/* Read the identifier */ /* Read the identifier */
ReadIdent (0); ReadIdent ();
/* Check for special names. Bail out if we have identified the type of /* Check for special names. Bail out if we have identified the type of
* the token. Go on if the token is an identifier. * the token. Go on if the token is an identifier.
*/ */
if (SVal[1] == '\0') { if (SB_GetLen (&SVal) == 1) {
switch (toupper (SVal [0])) { switch (toupper (SB_AtUnchecked (&SVal, 0))) {
case 'A': case 'A':
if (C == ':') { if (C == ':') {
@@ -1039,7 +1021,7 @@ Again:
break; break;
} }
} else if (CPU == CPU_SWEET16 && (IVal = Sweet16Reg (SVal)) >= 0) { } else if (CPU == CPU_SWEET16 && (IVal = Sweet16Reg (&SVal)) >= 0) {
/* A sweet16 register number in sweet16 mode */ /* A sweet16 register number in sweet16 mode */
Tok = TOK_REG; Tok = TOK_REG;
@@ -1048,7 +1030,7 @@ Again:
} }
/* Check for define style macro */ /* Check for define style macro */
if (IsDefine (SVal)) { if (IsDefine (&SVal)) {
/* Macro - expand it */ /* Macro - expand it */
MacExpandStart (); MacExpandStart ();
goto Restart; goto Restart;
@@ -1243,8 +1225,9 @@ CharAgain:
* string later. * string later.
*/ */
if (LooseStringTerm) { if (LooseStringTerm) {
if (ReadStringConst ('\'') == 1) { ReadStringConst ('\'');
IVal = SVal[0]; if (SB_GetLen (&SVal) == 1) {
IVal = SB_AtUnchecked (&SVal, 0);
Tok = TOK_CHARCON; Tok = TOK_CHARCON;
} else { } else {
Tok = TOK_STRCON; Tok = TOK_STRCON;
@@ -1277,8 +1260,8 @@ CharAgain:
case '\\': case '\\':
/* Line continuation? */ /* Line continuation? */
if (LineCont) { if (LineCont) {
NextChar (); NextChar ();
if (C == '\n') { if (C == '\n') {
/* Handle as white space */ /* Handle as white space */
NextChar (); NextChar ();
C = ' '; C = ' ';
@@ -1333,7 +1316,7 @@ int GetSubKey (const char** Keys, unsigned Count)
/* Do a linear search (a binary search is not worth the effort) */ /* Do a linear search (a binary search is not worth the effort) */
for (I = 0; I < Count; ++I) { for (I = 0; I < Count; ++I) {
if (strcmp (SVal, Keys [I]) == 0) { if (SB_CompareStr (&SVal, Keys [I]) == 0) {
/* Found it */ /* Found it */
return I; return I;
} }

View File

@@ -40,6 +40,7 @@
/* common */ /* common */
#include "filepos.h" #include "filepos.h"
#include "strbuf.h"
/* ca65 */ /* ca65 */
#include "token.h" #include "token.h"
@@ -58,7 +59,7 @@
extern Token Tok; /* Current token */ extern Token Tok; /* Current token */
extern int WS; /* Flag: Whitespace before token */ extern int WS; /* Flag: Whitespace before token */
extern long IVal; /* Integer token attribute */ extern long IVal; /* Integer token attribute */
extern char SVal[MAX_STR_LEN+1]; /* String token attribute */ extern StrBuf SVal; /* String token attribute */
extern FilePos CurPos; /* Name and position in file */ extern FilePos CurPos; /* Name and position in file */
extern int ForcedEnd; /* Force end of assembly */ extern int ForcedEnd; /* Force end of assembly */
@@ -119,4 +120,4 @@ void DoneScanner (void);

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008, Ullrich von Bassewit */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -52,13 +52,12 @@
/* The name of the symbol used to encode the size. The name of this entry is /* The name of the symbol used to encode the size. The name of this entry is
* choosen so that it cannot be accessed by the user. * choosen so that it cannot be accessed by the user.
*/ */
static const char SizeEntryName[] = ".size"; const StrBuf SizeEntryName = LIT_STRBUF_INITIALIZER (".size");
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@@ -68,7 +67,7 @@ SymEntry* GetSizeOfScope (SymTable* Scope)
* encodes the size, and will create a new entry if it does not exist. * encodes the size, and will create a new entry if it does not exist.
*/ */
{ {
return SymFind (Scope, SizeEntryName, SYM_ALLOC_NEW); return SymFind (Scope, &SizeEntryName, SYM_ALLOC_NEW);
} }
@@ -79,7 +78,7 @@ SymEntry* GetSizeOfSymbol (SymEntry* Sym)
* does not exist. * does not exist.
*/ */
{ {
return SymFindLocal (Sym, SizeEntryName, SYM_ALLOC_NEW); return SymFindLocal (Sym, &SizeEntryName, SYM_ALLOC_NEW);
} }

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -35,6 +35,11 @@
#ifndef SIZEOF_H #ifndef SIZEOF_H
#define SIZEOF_H #define SIZEOF_H
/* common */
#include "strbuf.h"
@@ -49,6 +54,16 @@ struct SymTable;
/*****************************************************************************/
/* Data */
/*****************************************************************************/
extern const StrBuf SizeEntryName; /* Contains name of symbol with size */
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -57,7 +57,7 @@ StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
void WriteStrPool (void) void WriteStrPool (void)
/* Write the string pool to the object file */ /* Write the string pool to the object file */
{ {
unsigned I; unsigned I;
/* Get the number of strings in the string pool */ /* Get the number of strings in the string pool */
@@ -71,7 +71,7 @@ void WriteStrPool (void)
/* Write the strings in id order */ /* Write the strings in id order */
for (I = 0; I < Count; ++I) { for (I = 0; I < Count; ++I) {
ObjWriteStr (SP_Get (&StrPool, I)); ObjWriteBuf (SP_Get (&StrPool, I));
} }
/* Done writing the string pool */ /* Done writing the string pool */

View File

@@ -60,8 +60,8 @@ extern StringPool StrPool;
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE unsigned GetStringId (const char* S) INLINE unsigned GetStrBufId (const StrBuf* S)
/* Return the id of the given string */ /* Return the id of the given string buffer */
{ {
return SP_Add (&StrPool, S); return SP_Add (&StrPool, S);
} }
@@ -70,13 +70,33 @@ INLINE unsigned GetStringId (const char* S)
#endif #endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE const char* GetString (unsigned Index) INLINE unsigned GetStringId (const char* S)
/* Return the id of the given string */
{
return SP_AddStr (&StrPool, S);
}
#else
# define GetStringId(S) SP_Add (&StrPool, (S))
#endif
#if defined(HAVE_INLINE)
INLINE const StrBuf* GetStrBuf (unsigned Index)
/* Convert a string index into a string */ /* Convert a string index into a string */
{ {
return SP_Get (&StrPool, Index); return SP_Get (&StrPool, Index);
} }
#else #else
# define GetString(Index) SP_Get (&StrPool, (Index)) # define GetStrBuf(Index) SP_Get (&StrPool, (Index))
#endif
#if defined(HAVE_INLINE)
INLINE const char* GetString (unsigned Index)
/* Convert a string index into a string */
{
return SB_GetConstBuf (SP_Get (&StrPool, Index));
}
#else
# define GetString(Index) SB_GetConstBuf (SP_Get (&StrPool, (Index)))
#endif #endif
void WriteStrPool (void); void WriteStrPool (void);

View File

@@ -106,7 +106,7 @@ static long DoStructInternal (long Offs, unsigned Type)
int Anon = (Tok != TOK_IDENT); int Anon = (Tok != TOK_IDENT);
if (!Anon) { if (!Anon) {
/* Enter a new scope, then skip the name */ /* Enter a new scope, then skip the name */
SymEnterLevel (SVal, ST_STRUCT, ADDR_SIZE_ABS); SymEnterLevel (&SVal, ST_STRUCT, ADDR_SIZE_ABS);
NextTok (); NextTok ();
/* Start at zero offset in the new scope */ /* Start at zero offset in the new scope */
Offs = 0; Offs = 0;
@@ -132,7 +132,7 @@ static long DoStructInternal (long Offs, unsigned Type)
Sym = 0; Sym = 0;
if (Tok == TOK_IDENT) { if (Tok == TOK_IDENT) {
/* We have an identifier, generate a symbol */ /* We have an identifier, generate a symbol */
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW); Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
/* Assign the symbol the offset of the current member */ /* Assign the symbol the offset of the current member */
SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE); SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);
@@ -261,7 +261,7 @@ static long DoStructInternal (long Offs, unsigned Type)
long GetStructSize (SymTable* Struct) long GetStructSize (SymTable* Struct)
/* Get the size of a struct or union */ /* Get the size of a struct or union */
{ {
SymEntry* Sym = SymFind (Struct, ".size", SYM_FIND_EXISTING); SymEntry* Sym = SymFind (Struct, &SizeEntryName, SYM_FIND_EXISTING);
if (Sym == 0) { if (Sym == 0) {
Error ("Size of struct/union is unknown"); Error ("Size of struct/union is unknown");
return 0; return 0;

View File

@@ -511,7 +511,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
DumpExpr (Expr, SymResolve); DumpExpr (Expr, SymResolve);
} }
PError (GetSymPos (Sym), PError (GetSymPos (Sym),
"Circular reference in definition of symbol `%s'", "Circular reference in definition of symbol `%m%p'",
GetSymName (Sym)); GetSymName (Sym));
ED_Invalidate (D); ED_Invalidate (D);
} else { } else {

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -53,17 +53,19 @@
SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName) SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
/* Parse a (possibly scoped) identifer. Name must point to a buffer big enough /* Parse a (possibly scoped) identifer. The scope of the name must exist and
* to hold such an identifier. The scope of the name must exist and is returned * is returned as function result, while the last part (the identifier) which
* as function result, while the last part (the identifier) which may be either * may be either a symbol or a scope depending on the context is returned in
* a symbol or a scope depending on the context is returned in Name. ScopeName * Name. FullName is a string buffer that is used to store the full name of
* is a string buffer that is used to store the name of the scope, the * the identifier including the scope. It is used internally and may be used
* identifier lives in. It does contain anything but the identifier itself, so * by the caller for error messages or similar.
* if ScopeName is empty on return, no explicit scope was specified. The full
* name of the identifier (including the scope) is ScopeName+Name.
*/ */
{ {
/* Clear both passed string buffers */
SB_Clear (Name);
SB_Clear (FullName);
/* Get the starting table */ /* Get the starting table */
SymTable* Scope; SymTable* Scope;
if (Tok == TOK_NAMESPACE) { if (Tok == TOK_NAMESPACE) {
@@ -74,17 +76,17 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
} else if (Tok == TOK_IDENT) { } else if (Tok == TOK_IDENT) {
/* Remember the name and skip it */ /* Remember the name and skip it */
strcpy (Name, SVal); SB_Copy (Name, &SVal);
NextTok (); NextTok ();
/* If no namespace symbol follows, we're already done */ /* If no namespace symbol follows, we're already done */
if (Tok != TOK_NAMESPACE) { if (Tok != TOK_NAMESPACE) {
SB_Terminate (ScopeName); SB_Terminate (FullName);
return CurrentScope; return CurrentScope;
} }
/* Pass the scope back to the caller */ /* Pass the scope back to the caller */
SB_AppendStr (ScopeName, Name); SB_Append (FullName, Name);
/* The scope must exist, so search for it starting with the current /* The scope must exist, so search for it starting with the current
* scope. * scope.
@@ -92,8 +94,8 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
Scope = SymFindAnyScope (CurrentScope, Name); Scope = SymFindAnyScope (CurrentScope, Name);
if (Scope == 0) { if (Scope == 0) {
/* Scope not found */ /* Scope not found */
SB_Terminate (ScopeName); SB_Terminate (FullName);
Error ("No such scope: `%s'", SB_GetConstBuf (ScopeName)); Error ("No such scope: `%m%p'", FullName);
return 0; return 0;
} }
@@ -101,14 +103,12 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
/* Invalid token */ /* Invalid token */
Error ("Identifier expected"); Error ("Identifier expected");
SB_Terminate (ScopeName);
Name[0] = '\0';
return 0; return 0;
} }
/* Skip the namespace token that follows */ /* Skip the namespace token that follows */
SB_AppendStr (ScopeName, "::"); SB_AppendStr (FullName, "::");
NextTok (); NextTok ();
/* Resolve scopes. */ /* Resolve scopes. */
@@ -117,13 +117,11 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
/* Next token must be an identifier. */ /* Next token must be an identifier. */
if (Tok != TOK_IDENT) { if (Tok != TOK_IDENT) {
Error ("Identifier expected"); Error ("Identifier expected");
SB_Terminate (ScopeName);
Name[0] = '\0';
return 0; return 0;
} }
/* Remember and skip the identifier */ /* Remember and skip the identifier */
strcpy (Name, SVal); SB_Copy (Name, &SVal);
NextTok (); NextTok ();
/* If a namespace token follows, we search for another scope, otherwise /* If a namespace token follows, we search for another scope, otherwise
@@ -131,24 +129,22 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
*/ */
if (Tok != TOK_NAMESPACE) { if (Tok != TOK_NAMESPACE) {
/* Symbol */ /* Symbol */
SB_Terminate (ScopeName);
return Scope; return Scope;
} }
/* Pass the scope back to the caller */ /* Pass the scope back to the caller */
SB_AppendStr (ScopeName, Name); SB_Append (FullName, Name);
/* Search for the child scope */ /* Search for the child scope */
Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING); Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
if (Scope == 0) { if (Scope == 0) {
/* Scope not found */ /* Scope not found */
SB_Terminate (ScopeName); Error ("No such scope: `%m%p'", FullName);
Error ("No such scope: `%s'", SB_GetConstBuf (ScopeName));
return 0; return 0;
} }
/* Skip the namespace token that follows */ /* Skip the namespace token that follows */
SB_AppendStr (ScopeName, "::"); SB_AppendStr (FullName, "::");
NextTok (); NextTok ();
} }
} }
@@ -160,19 +156,19 @@ SymEntry* ParseScopedSymName (int AllocNew)
* and return the symbol table entry. * and return the symbol table entry.
*/ */
{ {
StrBuf ScopeName = AUTO_STRBUF_INITIALIZER; StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
char Ident[sizeof (SVal)]; StrBuf Ident = STATIC_STRBUF_INITIALIZER;
int NoScope; int NoScope;
SymEntry* Sym; SymEntry* Sym;
/* Parse the scoped symbol name */ /* Parse the scoped symbol name */
SymTable* Scope = ParseScopedIdent (Ident, &ScopeName); SymTable* Scope = ParseScopedIdent (&Ident, &ScopeName);
/* If ScopeName is empty, no scope was specified */ /* If ScopeName is empty, no scope was specified */
NoScope = SB_IsEmpty (&ScopeName); NoScope = SB_IsEmpty (&ScopeName);
/* We don't need ScopeName any longer */ /* We don't need ScopeName any longer */
DoneStrBuf (&ScopeName); SB_Done (&ScopeName);
/* Check if the scope is valid. Errors have already been diagnosed by /* Check if the scope is valid. Errors have already been diagnosed by
* the routine, so just exit. * the routine, so just exit.
@@ -182,9 +178,9 @@ SymEntry* ParseScopedSymName (int AllocNew)
* search also in the upper levels. * search also in the upper levels.
*/ */
if (NoScope && !AllocNew) { if (NoScope && !AllocNew) {
Sym = SymFindAny (Scope, Ident); Sym = SymFindAny (Scope, &Ident);
} else { } else {
Sym = SymFind (Scope, Ident, AllocNew); Sym = SymFind (Scope, &Ident, AllocNew);
} }
} else { } else {
/* No scope ==> no symbol. To avoid errors in the calling routine that /* No scope ==> no symbol. To avoid errors in the calling routine that
@@ -192,12 +188,15 @@ SymEntry* ParseScopedSymName (int AllocNew)
* symbol. * symbol.
*/ */
if (AllocNew) { if (AllocNew) {
Sym = NewSymEntry (Ident, SF_NONE); Sym = NewSymEntry (&Ident, SF_NONE);
} else { } else {
Sym = 0; Sym = 0;
} }
} }
/* Deallocate memory for ident */
SB_Done (&Ident);
/* Return the symbol found */ /* Return the symbol found */
return Sym; return Sym;
} }
@@ -209,19 +208,19 @@ SymTable* ParseScopedSymTable (void)
* symbol space and return the symbol table struct. * symbol space and return the symbol table struct.
*/ */
{ {
StrBuf ScopeName = AUTO_STRBUF_INITIALIZER; StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
char Name[sizeof (SVal)]; StrBuf Name = STATIC_STRBUF_INITIALIZER;
int NoScope; int NoScope;
/* Parse the scoped symbol name */ /* Parse the scoped symbol name */
SymTable* Scope = ParseScopedIdent (Name, &ScopeName); SymTable* Scope = ParseScopedIdent (&Name, &ScopeName);
/* If ScopeName is empty, no scope was specified */ /* If ScopeName is empty, no scope was specified */
NoScope = SB_IsEmpty (&ScopeName); NoScope = SB_IsEmpty (&ScopeName);
/* We don't need FullName any longer */ /* We don't need FullName any longer */
DoneStrBuf (&ScopeName); SB_Done (&ScopeName);
/* If we got no error, search for the child scope withint the enclosing one. /* If we got no error, search for the child scope withint the enclosing one.
* Beware: If no explicit parent scope was specified, search in all upper * Beware: If no explicit parent scope was specified, search in all upper
@@ -230,11 +229,16 @@ SymTable* ParseScopedSymTable (void)
if (Scope) { if (Scope) {
/* Search for the last scope */ /* Search for the last scope */
if (NoScope) { if (NoScope) {
Scope = SymFindAnyScope (Scope, Name); Scope = SymFindAnyScope (Scope, &Name);
} else { } else {
Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING); Scope = SymFindScope (Scope, &Name, SYM_FIND_EXISTING);
} }
} }
/* Free memory for name */
SB_Done (&Name);
/* Return the scope found */
return Scope; return Scope;
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -55,14 +55,13 @@ struct SymTable;
struct SymTable* ParseScopedIdent (char* Name, struct StrBuf* FullName); struct SymTable* ParseScopedIdent (struct StrBuf* Name, struct StrBuf* FullName);
/* Parse a (possibly scoped) identifer. Name must point to a buffer big enough /* Parse a (possibly scoped) identifer. The scope of the name must exist and
* to hold such an identifier. The scope of the name must exist and is returned * is returned as function result, while the last part (the identifier) which
* as function result, while the last part (the identifier) which may be either * may be either a symbol or a scope depending on the context is returned in
* a symbol or a scope depending on the context is returned in Name. FullName * Name. FullName is a string buffer that is used to store the full name of
* is a string buffer that is used to store the full name of the identifier * the identifier including the scope. It is used internally and may be used
* including the scope. It is used internally and may be used by the caller * by the caller for error messages or similar.
* for error messages or similar.
*/ */
struct SymEntry* ParseScopedSymName (int AllowNew); struct SymEntry* ParseScopedSymName (int AllowNew);

View File

@@ -2,11 +2,11 @@
/* */ /* */
/* symentry.c */ /* symentry.c */
/* */ /* */
/* Symbol table entry forward for the ca65 macroassembler */ /* Symbol table entry for the ca65 macroassembler */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -72,7 +72,7 @@ SymEntry* SymLast = 0;
SymEntry* NewSymEntry (const char* Name, unsigned Flags) SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
/* Allocate a symbol table entry, initialize and return it */ /* Allocate a symbol table entry, initialize and return it */
{ {
unsigned I; unsigned I;
@@ -95,7 +95,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
S->ExportSize = ADDR_SIZE_DEFAULT; S->ExportSize = ADDR_SIZE_DEFAULT;
S->AddrSize = ADDR_SIZE_DEFAULT; S->AddrSize = ADDR_SIZE_DEFAULT;
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio)); memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
S->Name = GetStringId (Name); S->Name = GetStrBufId (Name);
/* Insert it into the list of all entries */ /* Insert it into the list of all entries */
S->List = SymList; S->List = SymList;
@@ -107,7 +107,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E) int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
/* Search in the given tree for a name. If we find the symbol, the function /* Search in the given tree for a name. If we find the symbol, the function
* will return 0 and put the entry pointer into E. If we did not find the * will return 0 and put the entry pointer into E. If we did not find the
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty, * symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
@@ -126,10 +126,10 @@ int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E)
while (1) { while (1) {
/* Get the symbol name */ /* Get the symbol name */
const char* SymName = GetString (T->Name); const StrBuf* SymName = GetStrBuf (T->Name);
/* Choose next entry */ /* Choose next entry */
int Cmp = strcmp (Name, SymName); int Cmp = SB_Compare (Name, SymName);
if (Cmp < 0 && T->Left) { if (Cmp < 0 && T->Left) {
T = T->Left; T = T->Left;
} else if (Cmp > 0&& T->Right) { } else if (Cmp > 0&& T->Right) {
@@ -216,24 +216,24 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
{ {
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* Defined symbol is marked as imported external symbol */ /* Defined symbol is marked as imported external symbol */
Error ("Symbol `%s' is already an import", GetSymName (S)); Error ("Symbol `%m%p' is already an import", GetSymName (S));
return; return;
} }
if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) { if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
/* Variable symbols cannot be exports or globals */ /* Variable symbols cannot be exports or globals */
Error ("Var symbol `%s' cannot be an export or global symbol", GetSymName (S)); Error ("Var symbol `%m%p' cannot be an export or global symbol", GetSymName (S));
return; return;
} }
if (S->Flags & SF_DEFINED) { if (S->Flags & SF_DEFINED) {
/* Multiple definition. In case of a variable, this is legal. */ /* Multiple definition. In case of a variable, this is legal. */
if ((S->Flags & SF_VAR) == 0) { if ((S->Flags & SF_VAR) == 0) {
Error ("Symbol `%s' is already defined", GetSymName (S)); Error ("Symbol `%m%p' is already defined", GetSymName (S));
S->Flags |= SF_MULTDEF; S->Flags |= SF_MULTDEF;
return; return;
} else { } else {
/* Redefinition must also be a variable symbol */ /* Redefinition must also be a variable symbol */
if ((Flags & SF_VAR) == 0) { if ((Flags & SF_VAR) == 0) {
Error ("Symbol `%s' is already different kind", GetSymName (S)); Error ("Symbol `%m%p' is already different kind", GetSymName (S));
return; return;
} }
/* Delete the current symbol expression, since it will get /* Delete the current symbol expression, since it will get
@@ -284,7 +284,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
PWarning (GetSymPos (S), 1, "Symbol `%s' is %s but exported %s", PWarning (GetSymPos (S), 1, "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
@@ -302,13 +302,13 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Mark the given symbol as an imported symbol */ /* Mark the given symbol as an imported symbol */
{ {
if (S->Flags & SF_DEFINED) { if (S->Flags & SF_DEFINED) {
Error ("Symbol `%s' is already defined", GetSymName (S)); Error ("Symbol `%m%p' is already defined", GetSymName (S));
S->Flags |= SF_MULTDEF; S->Flags |= SF_MULTDEF;
return; return;
} }
if (S->Flags & SF_EXPORT) { if (S->Flags & SF_EXPORT) {
/* The symbol is already marked as exported symbol */ /* The symbol is already marked as exported symbol */
Error ("Cannot import exported symbol `%s'", GetSymName (S)); Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
return; return;
} }
@@ -324,16 +324,16 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) { if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S)); Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
} }
if (AddrSize != S->AddrSize) { if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
if (S->Flags & SF_GLOBAL) { if (S->Flags & SF_GLOBAL) {
S->Flags &= ~SF_GLOBAL; S->Flags &= ~SF_GLOBAL;
if (AddrSize != S->AddrSize) { if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
@@ -350,12 +350,12 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Check if it's ok to export the symbol */ /* Check if it's ok to export the symbol */
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
Error ("Symbol `%s' is already an import", GetSymName (S)); Error ("Symbol `%m%p' is already an import", GetSymName (S));
return; return;
} }
if (S->Flags & SF_VAR) { if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported */ /* Variable symbols cannot be exported */
Error ("Var symbol `%s' cannot be exported", GetSymName (S)); Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
return; return;
} }
@@ -364,7 +364,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if (S->Flags & SF_GLOBAL) { if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
S->Flags &= ~SF_GLOBAL; S->Flags &= ~SF_GLOBAL;
} }
@@ -374,7 +374,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) { if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
if (S->ExportSize != AddrSize) { if (S->ExportSize != AddrSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
S->ExportSize = AddrSize; S->ExportSize = AddrSize;
@@ -388,7 +388,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
Warning (1, "Symbol `%s' is %s but exported %s", Warning (1, "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
@@ -407,7 +407,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
{ {
if (S->Flags & SF_VAR) { if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported or imported */ /* Variable symbols cannot be exported or imported */
Error ("Var symbol `%s' cannot be made global", GetSymName (S)); Error ("Var symbol `%m%p' cannot be made global", GetSymName (S));
return; return;
} }
@@ -420,7 +420,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
AddrSize = GetCurrentSegAddrSize (); AddrSize = GetCurrentSegAddrSize ();
} }
if (AddrSize != S->AddrSize) { if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
return; return;
} }
@@ -432,12 +432,12 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
if ((S->Flags & SF_DEFINED) == 0) { if ((S->Flags & SF_DEFINED) == 0) {
/* Symbol is undefined */ /* Symbol is undefined */
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} else if (AddrSize != ADDR_SIZE_DEFAULT) { } else if (AddrSize != ADDR_SIZE_DEFAULT) {
/* Symbol is defined and address size given */ /* Symbol is defined and address size given */
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
return; return;
@@ -449,7 +449,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if (S->Flags & SF_GLOBAL) { if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
return; return;
} }
@@ -467,7 +467,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
Warning (1, "Symbol `%s' is %s but exported %s", Warning (1, "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
@@ -505,12 +505,12 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
/* Check for errors */ /* Check for errors */
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
Error ("Symbol `%s' is already an import", GetSymName (S)); Error ("Symbol `%m%p' is already an import", GetSymName (S));
return; return;
} }
if (S->Flags & SF_VAR) { if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported or imported */ /* Variable symbols cannot be exported or imported */
Error ("Var symbol `%s' cannot be exported", GetSymName (S)); Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
return; return;
} }
@@ -520,7 +520,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
*/ */
if (S->Flags & (SF_EXPORT | SF_GLOBAL)) { if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
if (S->ExportSize != AddrSize) { if (S->ExportSize != AddrSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
S->Flags &= ~SF_GLOBAL; S->Flags &= ~SF_GLOBAL;
} }
@@ -534,7 +534,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
/* Use the real size of the symbol */ /* Use the real size of the symbol */
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize != S->ExportSize) { } else if (S->AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
@@ -543,7 +543,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
*/ */
if (S->ConDesPrio[Type] != CD_PRIO_NONE) { if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
if (S->ConDesPrio[Type] != Prio) { if (S->ConDesPrio[Type] != Prio) {
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S)); Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
S->ConDesPrio[Type] = Prio; S->ConDesPrio[Type] = Prio;

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2006 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -43,6 +43,7 @@
#include "coll.h" #include "coll.h"
#include "filepos.h" #include "filepos.h"
#include "inline.h" #include "inline.h"
#include "strbuf.h"
/* ca65 */ /* ca65 */
#include "spool.h" #include "spool.h"
@@ -97,7 +98,7 @@ struct SymEntry {
unsigned char ExportSize; /* Export address size */ unsigned char ExportSize; /* Export address size */
unsigned char AddrSize; /* Address size of label */ unsigned char AddrSize; /* Address size of label */
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */ unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
/* ...actually value+1 (used as flag) */ /* ...actually value+1 (used as flag) */
unsigned Name; /* Name index in global string pool */ unsigned Name; /* Name index in global string pool */
}; };
@@ -115,10 +116,10 @@ extern SymEntry* SymLast;
SymEntry* NewSymEntry (const char* Name, unsigned Flags); SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags);
/* Allocate a symbol table entry, initialize and return it */ /* Allocate a symbol table entry, initialize and return it */
int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E); int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E);
/* Search in the given tree for a name. If we find the symbol, the function /* Search in the given tree for a name. If we find the symbol, the function
* will return 0 and put the entry pointer into E. If we did not find the * will return 0 and put the entry pointer into E. If we did not find the
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty, * symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
@@ -305,10 +306,10 @@ const struct ExprNode* SymResolve (const SymEntry* Sym);
*/ */
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE const char* GetSymName (const SymEntry* S) INLINE const StrBuf* GetSymName (const SymEntry* S)
/* Return the name of the symbol */ /* Return the name of the symbol */
{ {
return GetString (S->Name); return GetStrBuf (S->Name);
} }
#else #else
# define GetSymName(S) GetString ((S)->Name) # define GetSymName(S) GetString ((S)->Name)

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2006 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -97,7 +97,7 @@ static unsigned ScopeTableSize (unsigned Level)
static SymTable* NewSymTable (SymTable* Parent, const char* Name) static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
/* Allocate a symbol table on the heap and return it */ /* Allocate a symbol table on the heap and return it */
{ {
/* Determine the lexical level and the number of table slots */ /* Determine the lexical level and the number of table slots */
@@ -119,7 +119,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
S->TableSlots = Slots; S->TableSlots = Slots;
S->TableEntries = 0; S->TableEntries = 0;
S->Parent = Parent; S->Parent = Parent;
S->Name = GetStringId (Name); S->Name = GetStrBufId (Name);
while (Slots--) { while (Slots--) {
S->Table[Slots] = 0; S->Table[Slots] = 0;
} }
@@ -133,7 +133,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
} else { } else {
while (1) { while (1) {
/* Choose next entry */ /* Choose next entry */
int Cmp = strcmp (Name, GetString (T->Name)); int Cmp = SB_Compare (Name, GetStrBuf (T->Name));
if (Cmp < 0) { if (Cmp < 0) {
if (T->Left) { if (T->Left) {
T = T->Left; T = T->Left;
@@ -150,7 +150,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
} }
} else { } else {
/* Duplicate scope name */ /* Duplicate scope name */
Internal ("Duplicate scope name: `%s'", Name); Internal ("Duplicate scope name: `%m%p'", Name);
} }
} }
} }
@@ -163,12 +163,12 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char AddrSize) void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, unsigned char AddrSize)
/* Enter a new lexical level */ /* Enter a new lexical level */
{ {
/* Map a default address size to something real */ /* Map a default address size to something real */
@@ -187,7 +187,7 @@ void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char Add
/* Check if the scope has been defined before */ /* Check if the scope has been defined before */
if (CurrentScope->Flags & ST_DEFINED) { if (CurrentScope->Flags & ST_DEFINED) {
Error ("Duplicate scope `%s'", ScopeName); Error ("Duplicate scope `%m%p'", ScopeName);
} }
} else { } else {
@@ -235,12 +235,12 @@ void SymLeaveLevel (void)
SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew) SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, int AllocNew)
/* Find a scope in the given enclosing scope */ /* Find a scope in the given enclosing scope */
{ {
SymTable** T = &Parent->Childs; SymTable** T = &Parent->Childs;
while (*T) { while (*T) {
int Cmp = strcmp (Name, GetString ((*T)->Name)); int Cmp = SB_Compare (Name, GetStrBuf ((*T)->Name));
if (Cmp < 0) { if (Cmp < 0) {
T = &(*T)->Left; T = &(*T)->Left;
} else if (Cmp > 0) { } else if (Cmp > 0) {
@@ -262,7 +262,7 @@ SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew)
SymTable* SymFindAnyScope (SymTable* Parent, const char* Name) SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name)
/* Find a scope in the given or any of its parent scopes. The function will /* Find a scope in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific * never create a new symbol, since this can only be done in one specific
* scope. * scope.
@@ -283,7 +283,7 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name)
SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew) SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, int AllocNew)
/* Find a cheap local symbol. If AllocNew is given and the entry is not /* Find a cheap local symbol. If AllocNew is given and the entry is not
* found, create a new one. Return the entry found, or the new entry created, * found, create a new one. Return the entry found, or the new entry created,
* or - in case AllocNew is zero - return 0. * or - in case AllocNew is zero - return 0.
@@ -331,7 +331,7 @@ SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew)
SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew) SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew)
/* Find a new symbol table entry in the given table. If AllocNew is given and /* Find a new symbol table entry in the given table. If AllocNew is given and
* the entry is not found, create a new one. Return the entry found, or the * the entry is not found, create a new one. Return the entry found, or the
* new entry created, or - in case AllocNew is zero - return 0. * new entry created, or - in case AllocNew is zero - return 0.
@@ -340,7 +340,7 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
SymEntry* S; SymEntry* S;
/* Global symbol: Get the hash value for the name */ /* Global symbol: Get the hash value for the name */
unsigned Hash = HashStr (Name) % Scope->TableSlots; unsigned Hash = HashBuf (Name) % Scope->TableSlots;
/* Search for the entry */ /* Search for the entry */
int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S); int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
@@ -373,7 +373,7 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
SymEntry* SymFindAny (SymTable* Scope, const char* Name) SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name)
/* Find a symbol in the given or any of its parent scopes. The function will /* Find a symbol in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific * never create a new symbol, since this can only be done in one specific
* scope. * scope.
@@ -424,7 +424,7 @@ static void SymCheckUndefined (SymEntry* S)
SymEntry* Sym = 0; SymEntry* Sym = 0;
SymTable* Tab = GetSymParentScope (S); SymTable* Tab = GetSymParentScope (S);
while (Tab) { while (Tab) {
Sym = SymFind (Tab, GetString (S->Name), SYM_FIND_EXISTING); Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING);
if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) { if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) {
/* We've found a symbol in a higher level that is /* We've found a symbol in a higher level that is
* either defined in the source, or an import. * either defined in the source, or an import.
@@ -451,8 +451,9 @@ static void SymCheckUndefined (SymEntry* S)
/* The symbol is already marked as an export. */ /* The symbol is already marked as an export. */
if (Sym->AddrSize > S->ExportSize) { if (Sym->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s", PWarning (&S->Pos, 1, "Symbol `%m%p' is %s but exported %s",
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize), GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
} else { } else {
@@ -465,8 +466,9 @@ static void SymCheckUndefined (SymEntry* S)
} }
if (Sym->AddrSize > Sym->ExportSize) { if (Sym->AddrSize > Sym->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s", PWarning (&S->Pos, 1, "Symbol `%m%p' is %s but exported %s",
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize), GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (Sym->ExportSize)); AddrSizeToStr (Sym->ExportSize));
} }
} }
@@ -483,8 +485,8 @@ static void SymCheckUndefined (SymEntry* S)
/* The symbol is definitely undefined */ /* The symbol is definitely undefined */
if (S->Flags & SF_EXPORT) { if (S->Flags & SF_EXPORT) {
/* We will not auto-import an export */ /* We will not auto-import an export */
PError (&S->Pos, "Exported symbol `%s' was never defined", PError (&S->Pos, "Exported symbol `%m%p' was never defined",
GetString (S->Name)); GetSymName (S));
} else { } else {
if (AutoImport) { if (AutoImport) {
/* Mark as import, will be indexed later */ /* Mark as import, will be indexed later */
@@ -493,7 +495,7 @@ static void SymCheckUndefined (SymEntry* S)
S->AddrSize = CodeAddrSize; S->AddrSize = CodeAddrSize;
} else { } else {
/* Error */ /* Error */
PError (&S->Pos, "Symbol `%s' is undefined", GetString (S->Name)); PError (&S->Pos, "Symbol `%m%p' is undefined", GetSymName (S));
} }
} }
} }
@@ -549,11 +551,11 @@ void SymCheck (void)
/* Check for defined symbols that were never referenced */ /* Check for defined symbols that were never referenced */
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) { if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
const char* Name = GetString (S->Name); const StrBuf* Name = GetStrBuf (S->Name);
if (Name[0] != '.') { /* Ignore internals */ if (SB_At (Name, 0) != '.') { /* Ignore internals */
PWarning (&S->Pos, 2, PWarning (&S->Pos, 2,
"Symbol `%s' is defined but never used", "Symbol `%m%p' is defined but never used",
GetString (S->Name)); GetSymName (S));
} }
} }
@@ -562,8 +564,8 @@ void SymCheck (void)
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) { if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */ /* Imported symbol is not referenced */
PWarning (&S->Pos, 2, PWarning (&S->Pos, 2,
"Symbol `%s' is imported but never used", "Symbol `%m%p' is imported but never used",
GetString (S->Name)); GetSymName (S));
} else { } else {
/* Give the import an index, count imports */ /* Give the import an index, count imports */
S->Index = ImportCount++; S->Index = ImportCount++;
@@ -593,8 +595,9 @@ void SymCheck (void)
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, PWarning (&S->Pos, 1,
"Symbol `%s' is %s but exported %s", "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S),
AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
} }
@@ -612,7 +615,7 @@ void SymCheck (void)
const FilePos* P = S->GuessedUse[S->AddrSize - 1]; const FilePos* P = S->GuessedUse[S->AddrSize - 1];
if (P) { if (P) {
PWarning (P, 0, PWarning (P, 0,
"Didn't use %s addressing for `%s'", "Didn't use %s addressing for `%m%p'",
AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->AddrSize),
GetSymName (S)); GetSymName (S));
} }
@@ -637,8 +640,8 @@ void SymDump (FILE* F)
/* Ignore unused symbols */ /* Ignore unused symbols */
if ((S->Flags & SF_UNUSED) != 0) { if ((S->Flags & SF_UNUSED) != 0) {
fprintf (F, fprintf (F,
"%-24s %s %s %s %s %s\n", "%m%-24p %s %s %s %s %s\n",
GetString (S->Name), GetSymName (S),
(S->Flags & SF_DEFINED)? "DEF" : "---", (S->Flags & SF_DEFINED)? "DEF" : "---",
(S->Flags & SF_REFERENCED)? "REF" : "---", (S->Flags & SF_REFERENCED)? "REF" : "---",
(S->Flags & SF_IMPORT)? "IMP" : "---", (S->Flags & SF_IMPORT)? "IMP" : "---",
@@ -842,3 +845,5 @@ void WriteScopes (void)

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -101,34 +101,34 @@ extern SymTable* RootScope; /* Root symbol table */
void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char AddrSize); void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, unsigned char AddrSize);
/* Enter a new lexical level */ /* Enter a new lexical level */
void SymLeaveLevel (void); void SymLeaveLevel (void);
/* Leave the current lexical level */ /* Leave the current lexical level */
SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew); SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, int AllocNew);
/* Find a scope in the given enclosing scope */ /* Find a scope in the given enclosing scope */
SymTable* SymFindAnyScope (SymTable* Parent, const char* Name); SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name);
/* Find a scope in the given or any of its parent scopes. The function will /* Find a scope in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific * never create a new symbol, since this can only be done in one specific
* scope. * scope.
*/ */
SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew); SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* StrBuf, int AllocNew);
/* Find a cheap local symbol. If AllocNew is given and the entry is not /* Find a cheap local symbol. If AllocNew is given and the entry is not
* found, create a new one. Return the entry found, or the new entry created, * found, create a new one. Return the entry found, or the new entry created,
* or - in case AllocNew is zero - return 0. * or - in case AllocNew is zero - return 0.
*/ */
SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew); SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew);
/* Find a new symbol table entry in the given table. If AllocNew is given and /* Find a new symbol table entry in the given table. If AllocNew is given and
* the entry is not found, create a new one. Return the entry found, or the * the entry is not found, create a new one. Return the entry found, or the
* new entry created, or - in case AllocNew is zero - return 0. * new entry created, or - in case AllocNew is zero - return 0.
*/ */
SymEntry* SymFindAny (SymTable* Scope, const char* Name); SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name);
/* Find a symbol in the given or any of its parent scopes. The function will /* Find a symbol in the given or any of its parent scopes. The function will
* never create a new symbol, since this can only be done in one specific * never create a new symbol, since this can only be done in one specific
* scope. * scope.

View File

@@ -47,7 +47,7 @@
int TokHasSVal (Token Tok) int TokHasSVal (Token Tok)
/* Return true if the given token has an attached SVal */ /* Return true if the given token has an attached SVal */
{ {
return (Tok == TOK_IDENT || TOK_LOCAL_IDENT || Tok == TOK_STRCON); return (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT || Tok == TOK_STRCON);
} }

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -60,16 +60,15 @@ TokNode* NewTokNode (void)
TokNode* T; TokNode* T;
/* Allocate memory */ /* Allocate memory */
unsigned Len = TokHasSVal (Tok)? strlen (SVal) : 0; T = xmalloc (sizeof (TokNode));
T = xmalloc (sizeof (TokNode) + Len);
/* Initialize the token contents */ /* Initialize the token contents */
T->Next = 0; T->Next = 0;
T->Tok = Tok; T->Tok = Tok;
T->WS = WS; T->WS = WS;
T->IVal = IVal; T->IVal = IVal;
memcpy (T->SVal, SVal, Len); T->SVal = AUTO_STRBUF_INITIALIZER;
T->SVal [Len] = '\0'; SB_Copy (&T->SVal, &SVal);
/* Return the node */ /* Return the node */
return T; return T;
@@ -80,6 +79,7 @@ TokNode* NewTokNode (void)
void FreeTokNode (TokNode* T) void FreeTokNode (TokNode* T)
/* Free the given token node */ /* Free the given token node */
{ {
SB_Done (&T->SVal);
xfree (T); xfree (T);
} }
@@ -92,7 +92,7 @@ void TokSet (TokNode* T)
Tok = T->Tok; Tok = T->Tok;
WS = T->WS; WS = T->WS;
IVal = T->IVal; IVal = T->IVal;
strcpy (SVal, T->SVal); SB_Copy (&SVal, &T->SVal);
} }
@@ -107,7 +107,7 @@ enum TC TokCmp (const TokNode* T)
/* If the token has string attribute, check it */ /* If the token has string attribute, check it */
if (TokHasSVal (T->Tok)) { if (TokHasSVal (T->Tok)) {
if (strcmp (T->SVal, SVal) != 0) { if (SB_Compare (&SVal, &T->SVal) != 0) {
return tcSameToken; return tcSameToken;
} }
} else if (TokHasIVal (T->Tok)) { } else if (TokHasIVal (T->Tok)) {

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2007 Ullrich von Bassewitz */ /* (C) 2000-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -38,6 +38,10 @@
/* common */
#include "strbuf.h"
/* ca65 */
#include "scanner.h" #include "scanner.h"
@@ -55,7 +59,7 @@ struct TokNode {
Token Tok; /* Token value */ Token Tok; /* Token value */
int WS; /* Whitespace before token? */ int WS; /* Whitespace before token? */
long IVal; /* Integer token attribute */ long IVal; /* Integer token attribute */
char SVal [1]; /* String attribute, dyn. allocated */ StrBuf SVal; /* String attribute, dyn. allocated */
}; };
/* Struct holding a token list */ /* Struct holding a token list */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2001-2004 Ullrich von Bassewitz */ /* (C) 2001-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@musoftware.de */
/* */ /* */
@@ -415,8 +415,8 @@ static void ParseAsm (void)
Done: Done:
/* Call the string buf destructors */ /* Call the string buf destructors */
DoneStrBuf (&S); SB_Done (&S);
DoneStrBuf (&T); SB_Done (&T);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2001-2006, Ullrich von Bassewitz */ /* (C) 2001-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -541,7 +541,7 @@ void CS_AddVLine (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap)
} }
/* Cleanup the string buffer */ /* Cleanup the string buffer */
DoneStrBuf (&Buf); SB_Done (&Buf);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2005, Ullrich von Bassewitz */ /* (C) 2000-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -81,7 +81,7 @@ Macro* NewMacro (const char* Name)
M->ArgCount = -1; /* Flag: Not a function like macro */ M->ArgCount = -1; /* Flag: Not a function like macro */
M->MaxArgs = 0; M->MaxArgs = 0;
InitCollection (&M->FormalArgs); InitCollection (&M->FormalArgs);
InitStrBuf (&M->Replacement); SB_Init (&M->Replacement);
M->Variadic = 0; M->Variadic = 0;
memcpy (M->Name, Name, Len+1); memcpy (M->Name, Name, Len+1);
@@ -102,7 +102,7 @@ void FreeMacro (Macro* M)
xfree (CollAtUnchecked (&M->FormalArgs, I)); xfree (CollAtUnchecked (&M->FormalArgs, I));
} }
DoneCollection (&M->FormalArgs); DoneCollection (&M->FormalArgs);
DoneStrBuf (&M->Replacement); SB_Done (&M->Replacement);
xfree (M); xfree (M);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2004 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -153,7 +153,7 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
} }
/* Call the string buf destructor */ /* Call the string buf destructor */
DoneStrBuf (&S); SB_Done (&S);
} }
@@ -223,7 +223,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
g_segname (Seg); g_segname (Seg);
/* Call the string buf destructor */ /* Call the string buf destructor */
DoneStrBuf (&S); SB_Done (&S);
} }
@@ -494,7 +494,7 @@ static void ParsePragma (void)
FlagPragma (&B, &WarnDisable); FlagPragma (&B, &WarnDisable);
break; break;
case PR_ZPSYM: case PR_ZPSYM:
StringPragma (&B, MakeZPSym); StringPragma (&B, MakeZPSym);
break; break;
@@ -522,7 +522,7 @@ static void ParsePragma (void)
} }
/* Release the StrBuf */ /* Release the StrBuf */
DoneStrBuf (&B); SB_Done (&B);
} }

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2007, Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@@ -189,7 +189,7 @@ static MacroExp* InitMacroExp (MacroExp* E, Macro* M)
/* Initialize a MacroExp structure */ /* Initialize a MacroExp structure */
{ {
InitCollection (&E->ActualArgs); InitCollection (&E->ActualArgs);
InitStrBuf (&E->Replacement); SB_Init (&E->Replacement);
E->M = M; E->M = M;
return E; return E;
} }
@@ -206,7 +206,7 @@ static void DoneMacroExp (MacroExp* E)
FreeStrBuf (CollAtUnchecked (&E->ActualArgs, I)); FreeStrBuf (CollAtUnchecked (&E->ActualArgs, I));
} }
DoneCollection (&E->ActualArgs); DoneCollection (&E->ActualArgs);
DoneStrBuf (&E->Replacement); SB_Done (&E->Replacement);
} }
@@ -488,7 +488,7 @@ static void ReadMacroArgs (MacroExp* E)
} }
/* Deallocate string buf resources */ /* Deallocate string buf resources */
DoneStrBuf (&Arg); SB_Done (&Arg);
} }
@@ -1145,7 +1145,7 @@ static void DoInclude (void)
Done: Done:
/* Free the allocated filename data */ /* Free the allocated filename data */
DoneStrBuf (&Filename); SB_Done (&Filename);
/* Clear the remaining line so the next input will come from the new /* Clear the remaining line so the next input will come from the new
* file (if open) * file (if open)

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2004 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -442,7 +442,7 @@ static void NumericConst (void)
{ {
unsigned Base; /* Temporary number base */ unsigned Base; /* Temporary number base */
unsigned Prefix; /* Base according to prefix */ unsigned Prefix; /* Base according to prefix */
StrBuf S; StrBuf S = STATIC_STRBUF_INITIALIZER;
int IsFloat; int IsFloat;
char C; char C;
unsigned DigitVal; unsigned DigitVal;
@@ -470,7 +470,6 @@ static void NumericConst (void)
* before converting it, so we can determine if it's a float or an * before converting it, so we can determine if it's a float or an
* integer. * integer.
*/ */
InitStrBuf (&S);
while (IsXDigit (CurC) && HexVal (CurC) < Base) { while (IsXDigit (CurC) && HexVal (CurC) < Base) {
SB_AppendChar (&S, CurC); SB_AppendChar (&S, CurC);
NextChar (); NextChar ();
@@ -506,7 +505,7 @@ static void NumericConst (void)
} }
/* We don't need the string buffer any longer */ /* We don't need the string buffer any longer */
DoneStrBuf (&S); SB_Done (&S);
/* Distinguish between integer and floating point constants */ /* Distinguish between integer and floating point constants */
if (!IsFloat) { if (!IsFloat) {

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -33,6 +33,11 @@
/* common */
#include "hashstr.h"
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@@ -54,3 +59,18 @@ unsigned HashStr (const char* S)
unsigned HashBuf (const StrBuf* S)
/* Return a hash value for the given string buffer */
{
unsigned I, L, H;
/* Do the hash */
H = L = 0;
for (I = 0; I < SB_GetLen (S); ++I) {
H = ((H << 3) ^ ((unsigned char) SB_AtUnchecked (S, I))) + L++;
}
return H;
}

View File

@@ -1,15 +1,15 @@
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* hashstr.h */ /* hashstr.h */
/* */ /* */
/* Hash function for strings */ /* Hash function for strings */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -38,7 +38,9 @@
/* common */
#include "attrib.h" #include "attrib.h"
#include "strbuf.h"
@@ -51,6 +53,9 @@
unsigned HashStr (const char* S) attribute ((const)); unsigned HashStr (const char* S) attribute ((const));
/* Return a hash value for the given string */ /* Return a hash value for the given string */
unsigned HashBuf (const StrBuf* S) attribute ((const));
/* Return a hash value for the given string buffer */
/* End of hashstr.h */ /* End of hashstr.h */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -112,7 +112,7 @@ INLINE void InitHashNode (HashNode* N, void* Entry)
#define InitHashNode(N, E) \ #define InitHashNode(N, E) \
(N)->Next = 0, \ (N)->Next = 0, \
(N)->Owner = 0, \ (N)->Owner = 0, \
(N)->Entry = (E) (N)->Entry = (E)
#endif #endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -138,7 +138,7 @@ static char* Find (const char* Path, const char* File)
if (access (SB_GetBuf (&PathName), 0) == 0) { if (access (SB_GetBuf (&PathName), 0) == 0) {
/* The file exists, return its name */ /* The file exists, return its name */
char* Name = xstrdup (SB_GetBuf (&PathName)); char* Name = xstrdup (SB_GetBuf (&PathName));
DoneStrBuf (&PathName); SB_Done (&PathName);
return Name; return Name;
} }
@@ -149,7 +149,7 @@ static char* Find (const char* Path, const char* File)
} }
/* Not found */ /* Not found */
DoneStrBuf (&PathName); SB_Done (&PathName);
return 0; return 0;
} }

View File

@@ -62,22 +62,37 @@ const StrBuf EmptyStrBuf = STATIC_STRBUF_INITIALIZER;
StrBuf* InitStrBuf (StrBuf* B) #if !defined(HAVE_INLINE)
StrBuf* SB_Init (StrBuf* B)
/* Initialize a string buffer */ /* Initialize a string buffer */
{
*B = EmptyStrBuf;
return B;
}
#endif
StrBuf* SB_InitFromString (StrBuf* B, const char* S)
/* Initialize a string buffer from a literal string. Beware: The buffer won't
* store a copy but a pointer to the actual string.
*/
{ {
B->Allocated = 0; B->Allocated = 0;
B->Len = 0; B->Len = strlen (S);
B->Index = 0; B->Index = 0;
B->Buf = 0; B->Buf = (char*) S;
return B; return B;
} }
void DoneStrBuf (StrBuf* B) void SB_Done (StrBuf* B)
/* Free the data of a string buffer (but not the struct itself) */ /* Free the data of a string buffer (but not the struct itself) */
{ {
xfree (B->Buf); if (B->Allocated) {
xfree (B->Buf);
}
} }
@@ -89,7 +104,7 @@ StrBuf* NewStrBuf (void)
StrBuf* B = xmalloc (sizeof (StrBuf)); StrBuf* B = xmalloc (sizeof (StrBuf));
/* Initialize the struct... */ /* Initialize the struct... */
InitStrBuf (B); SB_Init (B);
/* ...and return it */ /* ...and return it */
return B; return B;
@@ -100,7 +115,7 @@ StrBuf* NewStrBuf (void)
void FreeStrBuf (StrBuf* B) void FreeStrBuf (StrBuf* B)
/* Free a string buffer */ /* Free a string buffer */
{ {
DoneStrBuf (B); SB_Done (B);
xfree (B); xfree (B);
} }
@@ -122,8 +137,50 @@ void SB_Realloc (StrBuf* B, unsigned NewSize)
NewAllocated *= 2; NewAllocated *= 2;
} }
/* Reallocate the buffer */ /* Reallocate the buffer. Beware: The allocated size may be zero while the
B->Buf = xrealloc (B->Buf, NewAllocated); * length is not. This means that we have a buffer that wasn't allocated
* on the heap.
*/
if (B->Allocated) {
/* Just reallocate the block */
B->Buf = xrealloc (B->Buf, NewAllocated);
} else {
/* Allocate a new block and copy */
B->Buf = memcpy (xmalloc (NewAllocated), B->Buf, B->Len);
}
/* Remember the new block size */
B->Allocated = NewAllocated;
}
static void SB_CheapRealloc (StrBuf* B, unsigned NewSize)
/* Reallocate the string buffer space, make sure at least NewSize bytes are
* available. This function won't copy the old buffer contents over to the new
* buffer and may be used if the old contents are overwritten later.
*/
{
/* Get the current size, use a minimum of 8 bytes */
unsigned NewAllocated = B->Allocated;
if (NewAllocated == 0) {
NewAllocated = 8;
}
/* Round up to the next power of two */
while (NewAllocated < NewSize) {
NewAllocated *= 2;
}
/* Free the old buffer if there is one */
if (B->Allocated) {
xfree (B->Buf);
}
/* Allocate a fresh block */
B->Buf = xmalloc (NewAllocated);
/* Remember the new block size */
B->Allocated = NewAllocated; B->Allocated = NewAllocated;
} }
@@ -170,7 +227,7 @@ void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size)
/* Copy Buf to Target, discarding the old contents of Target */ /* Copy Buf to Target, discarding the old contents of Target */
{ {
if (Target->Allocated < Size) { if (Target->Allocated < Size) {
SB_Realloc (Target, Size); SB_CheapRealloc (Target, Size);
} }
memcpy (Target->Buf, Buf, Size); memcpy (Target->Buf, Buf, Size);
Target->Len = Size; Target->Len = Size;
@@ -294,7 +351,7 @@ void SB_Move (StrBuf* Target, StrBuf* Source)
*/ */
{ {
/* Free the target string */ /* Free the target string */
if (Target->Buf) { if (Target->Allocated) {
xfree (Target->Buf); xfree (Target->Buf);
} }
@@ -302,7 +359,7 @@ void SB_Move (StrBuf* Target, StrBuf* Source)
*Target = *Source; *Target = *Source;
/* Clear Source */ /* Clear Source */
InitStrBuf (Source); SB_Init (Source);
} }
@@ -359,6 +416,31 @@ int SB_Compare (const StrBuf* S1, const StrBuf* S2)
int SB_CompareStr (const StrBuf* S1, const char* S2)
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */
{
int Result;
unsigned S2Len = strlen (S2);
if (S1->Len < S2Len) {
Result = memcmp (S1->Buf, S2, S1->Len);
if (Result == 0) {
/* S1 considered lesser because it's shorter */
Result = -1;
}
} else if (S1->Len > S2Len) {
Result = memcmp (S1->Buf, S2, S2Len);
if (Result == 0) {
/* S2 considered lesser because it's shorter */
Result = 1;
}
} else {
Result = memcmp (S1->Buf, S2, S1->Len);
}
return Result;
}
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap) void SB_VPrintf (StrBuf* S, const char* Format, va_list ap)
/* printf function with S as target. The function is safe, which means that /* printf function with S as target. The function is safe, which means that
* the current contents of S are discarded, and are allocated again with * the current contents of S are discarded, and are allocated again with
@@ -382,10 +464,8 @@ void SB_VPrintf (StrBuf* S, const char* Format, va_list ap)
/* Check if we must reallocate */ /* Check if we must reallocate */
if ((unsigned) SizeNeeded >= S->Allocated) { if ((unsigned) SizeNeeded >= S->Allocated) {
/* Must retry. Don't use Realloc to avoid copying */ /* Must retry. Use CheapRealloc to avoid copying */
xfree (S->Buf); SB_CheapRealloc (S, SizeNeeded + 1); /* Account for '\0' */
S->Allocated = SizeNeeded + 1; /* Account for '\0' */
S->Buf = xmalloc (S->Allocated);
(void) xvsnprintf (S->Buf, S->Allocated, Format, ap); (void) xvsnprintf (S->Buf, S->Allocated, Format, ap);
} }

View File

@@ -49,18 +49,18 @@
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
typedef struct StrBuf StrBuf; typedef struct StrBuf StrBuf;
struct StrBuf { struct StrBuf {
unsigned Allocated; /* Size of allocated memory */ char* Buf; /* Pointer to buffer */
unsigned Len; /* Length of the string */ unsigned Len; /* Length of the string */
unsigned Index; /* Used for reading (Get and friends) */ unsigned Index; /* Used for reading (Get and friends) */
char* Buf; /* Pointer to buffer */ unsigned Allocated; /* Size of allocated memory */
}; };
/* An empty string buf */ /* An empty string buf */
extern const StrBuf EmptyStrBuf; extern const StrBuf EmptyStrBuf;
@@ -71,18 +71,36 @@ extern const StrBuf EmptyStrBuf;
/* Initializer for auto string bufs */ /* Initializer for auto string bufs */
#define AUTO_STRBUF_INITIALIZER EmptyStrBuf #define AUTO_STRBUF_INITIALIZER EmptyStrBuf
/* Initialize with a string literal (beware: evaluates str twice!) */
#define LIT_STRBUF_INITIALIZER(str) { (char*)str, sizeof(str)-1, 0, 0 }
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
StrBuf* InitStrBuf (StrBuf* B); #if defined(HAVE_INLINE)
INLINE StrBuf* SB_Init (StrBuf* B)
/* Initialize a string buffer */ /* Initialize a string buffer */
{
*B = EmptyStrBuf;
return B;
}
#else
StrBuf* SB_Init (StrBuf* B);
#endif
void DoneStrBuf (StrBuf* B); StrBuf* SB_InitFromString (StrBuf* B, const char* S);
/* Initialize a string buffer from a literal string. Beware: The buffer won't
* store a copy but a pointer to the actual string. A buffer initialized with
* this routine may be "forgotten" without calling SB_Done, since no memory
* has been allocated.
*/
void SB_Done (StrBuf* B);
/* Free the data of a string buffer (but not the struct itself) */ /* Free the data of a string buffer (but not the struct itself) */
StrBuf* NewStrBuf (void); StrBuf* NewStrBuf (void);
@@ -358,14 +376,17 @@ void SB_ToUpper (StrBuf* S);
int SB_Compare (const StrBuf* S1, const StrBuf* S2); int SB_Compare (const StrBuf* S1, const StrBuf* S2);
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */ /* Do a lexical compare of S1 and S2. See strcmp for result codes. */
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap); int SB_CompareStr (const StrBuf* S1, const char* S2);
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap) attribute ((format (printf, 2, 0)));
/* printf function with S as target. The function is safe, which means that /* printf function with S as target. The function is safe, which means that
* the current contents of S are discarded, and are allocated again with * the current contents of S are discarded, and are allocated again with
* a matching size for the output. The function will call FAIL when problems * a matching size for the output. The function will call FAIL when problems
* are detected (anything that let xsnprintf return -1). * are detected (anything that let xsnprintf return -1).
*/ */
void SB_Printf (StrBuf* S, const char* Format, ...); void SB_Printf (StrBuf* S, const char* Format, ...) attribute ((format (printf, 2, 3)));
/* vprintf function with S as target. The function is safe, which means that /* vprintf function with S as target. The function is safe, which means that
* the current contents of S are discarded, and are allocated again with * the current contents of S are discarded, and are allocated again with
* a matching size for the output. The function will call FAIL when problems * a matching size for the output. The function will call FAIL when problems

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -35,7 +35,7 @@
/* A string pool is used to store identifiers and other strings. Each string /* A string pool is used to store identifiers and other strings. Each string
* stored in the pool has a unique id, which may be used to access the string * stored in the pool has a unique id, which may be used to access the string
* in the pool. Identical strings are only stored once in the pool and have * in the pool. Identical strings are stored only once in the pool and have
* identical ids. This means that instead of comparing strings, just the * identical ids. This means that instead of comparing strings, just the
* string pool ids must be compared. * string pool ids must be compared.
*/ */
@@ -64,8 +64,7 @@ struct StringPoolEntry {
StringPoolEntry* Next; /* Pointer to next entry in hash chain */ StringPoolEntry* Next; /* Pointer to next entry in hash chain */
unsigned Hash; /* Full hash value */ unsigned Hash; /* Full hash value */
unsigned Id; /* The numeric string id */ unsigned Id; /* The numeric string id */
unsigned Len; /* Length of the string (excluding terminator) */ StrBuf Buf; /* The string itself */
char S[1]; /* The string itself */
}; };
@@ -76,21 +75,21 @@ struct StringPoolEntry {
static StringPoolEntry* NewStringPoolEntry (const char* S, unsigned Hash, unsigned Id) static StringPoolEntry* NewStringPoolEntry (const StrBuf* S, unsigned Hash, unsigned Id)
/* Create a new string pool entry and return it. */ /* Create a new string pool entry and return it. */
{ {
/* Get the length of the string */
unsigned Len = strlen (S);
/* Allocate memory */ /* Allocate memory */
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry) + Len); StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry));
/* Initialize the fields */ /* Initialize the fields */
E->Next = 0; E->Next = 0;
E->Hash = Hash; E->Hash = Hash;
E->Id = Id; E->Id = Id;
E->Len = Len; E->Buf = AUTO_STRBUF_INITIALIZER;
memcpy (E->S, S, Len+1); SB_Copy (&E->Buf, S);
/* Always zero terminate the string */
SB_Terminate (&E->Buf);
/* Return the new entry */ /* Return the new entry */
return E; return E;
@@ -129,7 +128,15 @@ void DoneStringPool (StringPool* P)
/* Free all entries and clear the entry collection */ /* Free all entries and clear the entry collection */
for (I = 0; I < CollCount (&P->Entries); ++I) { for (I = 0; I < CollCount (&P->Entries); ++I) {
xfree (CollAtUnchecked (&P->Entries, I));
/* Get a pointer to the entry */
StringPoolEntry* E = CollAtUnchecked (&P->Entries, I);
/* Free string buffer memory */
SB_Done (&E->Buf);
/* Free the memory for the entry itself */
xfree (E);
} }
CollDeleteAll (&P->Entries); CollDeleteAll (&P->Entries);
@@ -165,25 +172,26 @@ void FreeStringPool (StringPool* P)
const char* SP_Get (const StringPool* P, unsigned Index) const StrBuf* SP_Get (const StringPool* P, unsigned Index)
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */ /* Return a string from the pool. Index must exist, otherwise FAIL is called. */
{ {
/* Get the collection entry */ /* Get the collection entry */
const StringPoolEntry* E = CollConstAt (&P->Entries, Index); const StringPoolEntry* E = CollConstAt (&P->Entries, Index);
/* Return the string from the entry */ /* Return the string from the entry */
return E->S; return &E->Buf;
} }
unsigned SP_Add (StringPool* P, const char* S) unsigned SP_Add (StringPool* P, const StrBuf* S)
/* Add a string to the buffer and return the index. If the string does already /* Add a string buffer to the buffer and return the index. If the string does
* exist in the pool, SP_Add will just return the index of the existing string. * already exist in the pool, SP_AddBuf will just return the index of the
* existing string.
*/ */
{ {
/* Calculate the string hash */ /* Calculate the string hash */
unsigned Hash = HashStr (S); unsigned Hash = HashBuf (S);
/* Calculate the reduced string hash */ /* Calculate the reduced string hash */
unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0])); unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0]));
@@ -191,7 +199,7 @@ unsigned SP_Add (StringPool* P, const char* S)
/* Search for an existing entry */ /* Search for an existing entry */
StringPoolEntry* E = P->Tab[RHash]; StringPoolEntry* E = P->Tab[RHash];
while (E) { while (E) {
if (E->Hash == Hash && strcmp (E->S, S) == 0) { if (E->Hash == Hash && SB_Compare (&E->Buf, S) == 0) {
/* Found, return the id of the existing string */ /* Found, return the id of the existing string */
return E->Id; return E->Id;
} }
@@ -208,8 +216,8 @@ unsigned SP_Add (StringPool* P, const char* S)
E->Next = P->Tab[RHash]; E->Next = P->Tab[RHash];
P->Tab[RHash] = E; P->Tab[RHash] = E;
/* Add up the string size (plus terminator) */ /* Add up the string size */
P->TotalSize += E->Len + 1; P->TotalSize += SB_GetLen (&E->Buf);
/* Return the id of the entry */ /* Return the id of the entry */
return E->Id; return E->Id;
@@ -217,3 +225,22 @@ unsigned SP_Add (StringPool* P, const char* S)
unsigned SP_AddStr (StringPool* P, const char* S)
/* Add a string to the buffer and return the index. If the string does already
* exist in the pool, SP_Add will just return the index of the existing string.
*/
{
unsigned Id;
/* First make a string buffer, then add it. This is some overhead, but the
* routine will probably go.
*/
StrBuf Buf;
Id = SP_Add (P, SB_InitFromString (&Buf, S));
/* Return the id of the new entry */
return Id;
}

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -48,6 +48,7 @@
/* common */ /* common */
#include "attrib.h"
#include "coll.h" #include "coll.h"
#include "inline.h" #include "inline.h"
#include "strbuf.h" #include "strbuf.h"
@@ -100,10 +101,16 @@ StringPool* NewStringPool (void);
void FreeStringPool (StringPool* P); void FreeStringPool (StringPool* P);
/* Free a string pool */ /* Free a string pool */
const char* SP_Get (const StringPool* P, unsigned Index); const StrBuf* SP_Get (const StringPool* P, unsigned Index);
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */ /* Return a string from the pool. Index must exist, otherwise FAIL is called. */
unsigned SP_Add (StringPool* P, const char* S); unsigned SP_Add (StringPool* P, const StrBuf* S);
/* Add a string buffer to the buffer and return the index. If the string does
* already exist in the pool, SP_AddBuf will just return the index of the
* existing string.
*/
unsigned SP_AddStr (StringPool* P, const char* S);
/* Add a string to the buffer and return the index. If the string does already /* Add a string to the buffer and return the index. If the string does already
* exist in the pool, SP_Add will just return the index of the existing string. * exist in the pool, SP_Add will just return the index of the existing string.
*/ */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2004 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -35,6 +35,7 @@
#include <string.h> #include <string.h>
/* common */
#include "abend.h" #include "abend.h"
#include "check.h" #include "check.h"
#include "target.h" #include "target.h"
@@ -212,6 +213,16 @@ void TgtTranslateBuf (void* Buf, unsigned Len)
void TgtTranslateStrBuf (StrBuf* Buf)
/* Translate a string buffer from the source character set into the target
* system character set.
*/
{
TgtTranslateBuf (SB_GetBuf (Buf), SB_GetLen (Buf));
}
void TgtTranslateSet (unsigned Index, unsigned char C) void TgtTranslateSet (unsigned Index, unsigned char C)
/* Set the translation code for the given character */ /* Set the translation code for the given character */
{ {

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -34,7 +34,12 @@
#ifndef TGTTRANS_H #ifndef TGTTRANS_H
#define TGTTRANS_H #define TGTTRANS_H
/* common */
#include "strbuf.h"
@@ -62,6 +67,11 @@ void TgtTranslateBuf (void* Buf, unsigned Len);
* the target system character set. * the target system character set.
*/ */
void TgtTranslateStrBuf (StrBuf* Buf);
/* Translate a string buffer from the source character set into the target
* system character set.
*/
void TgtTranslateSet (unsigned Index, unsigned char C); void TgtTranslateSet (unsigned Index, unsigned char C);
/* Set the translation code for the given character */ /* Set the translation code for the given character */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2005 Ullrich von Bassewitz */ /* (C) 2005-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -228,7 +228,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
} }
/* Delete the string buffer contents */ /* Delete the string buffer contents */
DoneStrBuf (&Ident); SB_Done (&Ident);
/* Close the include file ignoring errors (we were just reading). */ /* Close the include file ignoring errors (we were just reading). */
(void) fclose (F); (void) fclose (F);

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999-2005 Ullrich von Bassewitz */ /* (C) 1999-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -62,9 +62,9 @@
struct BinDesc { struct BinDesc {
unsigned Undef; /* Count of undefined externals */ unsigned Undef; /* Count of undefined externals */
FILE* F; /* Output file */ FILE* F; /* Output file */
const char* Filename; /* Name of output file */ const char* Filename; /* Name of output file */
}; };
@@ -148,9 +148,9 @@ static void BinWriteMem (BinDesc* D, Memory* M)
Print (stdout, 1, " Writing `%s'\n", GetString (S->Name)); Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
/* Writes do only occur in the load area and not for BSS segments */ /* Writes do only occur in the load area and not for BSS segments */
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */ DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
S->Load == M && /* LOAD segment */ S->Load == M && /* LOAD segment */
S->Seg->Dumped == 0; /* Not already written */ S->Seg->Dumped == 0; /* Not already written */
/* Output debugging stuff */ /* Output debugging stuff */
PrintBoolVal ("bss", S->Flags & SF_BSS); PrintBoolVal ("bss", S->Flags & SF_BSS);
@@ -315,3 +315,4 @@ void BinWriteTarget (BinDesc* D, struct File* F)

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2005, Ullrich von Bassewitz */ /* (C) 2005-2008, Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -91,7 +91,7 @@ static void CE_Done (CfgExpr* E)
{ {
/* If the type is a string, we must delete the string buffer */ /* If the type is a string, we must delete the string buffer */
if (E->Type == ceString) { if (E->Type == ceString) {
DoneStrBuf (&E->SVal); SB_Done (&E->SVal);
} }
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2003 Ullrich von Bassewitz */ /* (C) 2000-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -112,7 +112,7 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
Cmp = 1; Cmp = 1;
} else { } else {
/* Use the name in this case */ /* Use the name in this case */
Cmp = strcmp (GetString (Exp1->Name), GetString (Exp2->Name)); Cmp = SB_Compare (GetStrBuf (Exp1->Name), GetStrBuf (Exp2->Name));
} }
/* Reverse the result for decreasing order */ /* Reverse the result for decreasing order */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -203,7 +203,7 @@ static Memory* CfgFindMemory (unsigned Name)
static Memory* CfgGetMemory (unsigned Name) static Memory* CfgGetMemory (unsigned Name)
/* Find the memory are with the given name. Print an error on an invalid name */ /* Find the memory are with the given name. Print an error on an invalid name */
{ {
Memory* M = CfgFindMemory (Name); Memory* M = CfgFindMemory (Name);
if (M == 0) { if (M == 0) {
CfgError ("Invalid memory area `%s'", GetString (Name)); CfgError ("Invalid memory area `%s'", GetString (Name));
} }
@@ -1557,13 +1557,14 @@ void CfgRead (void)
static void CreateRunDefines (SegDesc* S, unsigned long SegAddr) static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
/* Create the defines for a RUN segment */ /* Create the defines for a RUN segment */
{ {
char Buf [256]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
xsprintf (Buf, sizeof (Buf), "__%s_RUN__", GetString (S->Name)); SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name));
CreateMemoryExport (GetStringId (Buf), S->Run, SegAddr - S->Run->Start); CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
xsprintf (Buf, sizeof (Buf), "__%s_SIZE__", GetString (S->Name)); SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name));
CreateConstExport (GetStringId (Buf), S->Seg->Size); CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
S->Flags |= SF_RUN_DEF; S->Flags |= SF_RUN_DEF;
SB_Done (&Buf);
} }
@@ -1571,11 +1572,12 @@ static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr) static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
/* Create the defines for a LOAD segment */ /* Create the defines for a LOAD segment */
{ {
char Buf [256]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
xsprintf (Buf, sizeof (Buf), "__%s_LOAD__", GetString (S->Name)); SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name));
CreateMemoryExport (GetStringId (Buf), S->Load, SegAddr - S->Load->Start); CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
S->Flags |= SF_LOAD_DEF; S->Flags |= SF_LOAD_DEF;
SB_Done (&Buf);
} }
@@ -1697,13 +1699,14 @@ unsigned CfgAssignSegments (void)
/* If requested, define symbols for start and size of the memory area */ /* If requested, define symbols for start and size of the memory area */
if (M->Flags & MF_DEFINE) { if (M->Flags & MF_DEFINE) {
char Buf [256]; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
sprintf (Buf, "__%s_START__", GetString (M->Name)); SB_Printf (&Buf, "__%s_START__", GetString (M->Name));
CreateMemoryExport (GetStringId (Buf), M, 0); CreateMemoryExport (GetStrBufId (&Buf), M, 0);
sprintf (Buf, "__%s_SIZE__", GetString (M->Name)); SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name));
CreateConstExport (GetStringId (Buf), M->Size); CreateConstExport (GetStrBufId (&Buf), M->Size);
sprintf (Buf, "__%s_LAST__", GetString (M->Name)); SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
CreateMemoryExport (GetStringId (Buf), M, M->FillLevel); CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
SB_Done (&Buf);
} }
/* Next memory area */ /* Next memory area */
@@ -1728,7 +1731,7 @@ void CfgWriteTarget (void)
if (F->MemList) { if (F->MemList) {
/* Is there an output file? */ /* Is there an output file? */
if (strlen (GetString (F->Name)) > 0) { if (SB_GetLen (GetStrBuf (F->Name)) > 0) {
/* Assign a proper binary format */ /* Assign a proper binary format */
if (F->Format == BINFMT_DEFAULT) { if (F->Format == BINFMT_DEFAULT) {

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2001-2003 Ullrich von Bassewitz */ /* (C) 2001-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -36,9 +36,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
/* common */ /* common */
#include "cmdline.h" #include "cmdline.h"
#include "strbuf.h"
/* ld65 */ /* ld65 */
#include "error.h" #include "error.h"
@@ -54,12 +55,17 @@
void Warning (const char* Format, ...) void Warning (const char* Format, ...)
/* Print a warning message */ /* Print a warning message */
{ {
StrBuf S = STATIC_STRBUF_INITIALIZER;
va_list ap; va_list ap;
va_start (ap, Format); va_start (ap, Format);
fprintf (stderr, "%s: Warning: ", ProgName); SB_VPrintf (&S, Format, ap);
vfprintf (stderr, Format, ap);
putc ('\n', stderr);
va_end (ap); va_end (ap);
SB_Terminate (&S);
fprintf (stderr, "%s: Warning: %s\n", ProgName, SB_GetConstBuf (&S));
SB_Done (&S);
} }
@@ -67,12 +73,18 @@ void Warning (const char* Format, ...)
void Error (const char* Format, ...) void Error (const char* Format, ...)
/* Print an error message and die */ /* Print an error message and die */
{ {
StrBuf S = STATIC_STRBUF_INITIALIZER;
va_list ap; va_list ap;
va_start (ap, Format); va_start (ap, Format);
fprintf (stderr, "%s: Error: ", ProgName); SB_VPrintf (&S, Format, ap);
vfprintf (stderr, Format, ap);
putc ('\n', stderr);
va_end (ap); va_end (ap);
SB_Terminate (&S);
fprintf (stderr, "%s: Error: %s\n", ProgName, SB_GetConstBuf (&S));
SB_Done (&S);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
@@ -81,14 +93,20 @@ void Error (const char* Format, ...)
void Internal (const char* Format, ...) void Internal (const char* Format, ...)
/* Print an internal error message and die */ /* Print an internal error message and die */
{ {
StrBuf S = STATIC_STRBUF_INITIALIZER;
va_list ap; va_list ap;
va_start (ap, Format); va_start (ap, Format);
fprintf (stderr, "%s: Internal error: ", ProgName); SB_VPrintf (&S, Format, ap);
vfprintf (stderr, Format, ap);
putc ('\n', stderr);
va_end (ap); va_end (ap);
SB_Terminate (&S);
fprintf (stderr, "%s: Internal Error: %s\n", ProgName, SB_GetConstBuf (&S));
SB_Done (&S);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2005 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstra<EFBFBD>e 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -620,7 +620,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
/* Unresolved external */ /* Unresolved external */
Import* Imp = E->ImpList; Import* Imp = E->ImpList;
fprintf (stderr, fprintf (stderr,
"Unresolved external `%s' referenced in:\n", "Unresolved external `%s' referenced in:\n",
GetString (E->Name)); GetString (E->Name));
while (Imp) { while (Imp) {
const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name); const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
@@ -636,8 +636,8 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
static int CmpExpName (const void* K1, const void* K2) static int CmpExpName (const void* K1, const void* K2)
/* Compare function for qsort */ /* Compare function for qsort */
{ {
return strcmp (GetString ((*(Export**)K1)->Name), return SB_Compare (GetStrBuf ((*(Export**)K1)->Name),
GetString ((*(Export**)K2)->Name)); GetStrBuf ((*(Export**)K2)->Name));
} }
@@ -728,7 +728,7 @@ void PrintExportMap (FILE* F)
/* Print unreferenced symbols only if explictly requested */ /* Print unreferenced symbols only if explictly requested */
if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) { if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) {
fprintf (F, fprintf (F,
"%-25s %06lX %c%c%c%c ", "%-25s %06lX %c%c%c%c ",
GetString (E->Name), GetString (E->Name),
GetExportVal (E), GetExportVal (E),
E->ImpCount? 'R' : ' ', E->ImpCount? 'R' : ' ',

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999-2003 Ullrich von Bassewitz */ /* (C) 1999-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -283,34 +283,23 @@ unsigned ReadStr (FILE* F)
*/ */
{ {
unsigned Id; unsigned Id;
char* B; StrBuf Buf = STATIC_STRBUF_INITIALIZER;
char Buf[256];
/* Read the length */ /* Read the length */
unsigned Len = ReadVar (F); unsigned Len = ReadVar (F);
/* If the string is short enough, use our buffer on the stack, otherwise /* Expand the string buffer memory */
* allocate space on the heap. SB_Realloc (&Buf, Len);
*/
if (Len < sizeof (Buf)) {
B = Buf;
} else {
B = xmalloc (Len + 1);
}
/* Read the string */ /* Read the string */
ReadData (F, B, Len); ReadData (F, SB_GetBuf (&Buf), Len);
Buf.Len = Len;
/* Terminate the string */
B[Len] = '\0';
/* Insert it into the string pool and remember the id */ /* Insert it into the string pool and remember the id */
Id = GetStringId (B); Id = GetStrBufId (&Buf);
/* If we had allocated memory before, free it now */ /* Free the memory buffer */
if (B != Buf) { SB_Done (&Buf);
xfree (B);
}
/* Return the string id */ /* Return the string id */
return Id; return Id;

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2008, Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -95,7 +95,7 @@ void CfgWarning (const char* Format, ...)
va_end (ap); va_end (ap);
Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf)); Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf));
DoneStrBuf (&Buf); SB_Done (&Buf);
} }
@@ -111,7 +111,7 @@ void CfgError (const char* Format, ...)
va_end (ap); va_end (ap);
Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf)); Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf));
DoneStrBuf (&Buf); SB_Done (&Buf);
} }

View File

@@ -57,12 +57,12 @@ StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
void InitStrPool (void) void InitStrPool (void)
/* Initialize the string pool */ /* Initialize the string pool */
{ {
/* We insert a first string here, which will have id zero. This means /* We insert a first string here, which will have id zero. This means
* that we can treat index zero later as invalid. * that we can treat index zero later as invalid.
*/ */
SP_Add (&StrPool, "<invalid message #0>"); SP_AddStr (&StrPool, "<invalid message #0>");
} }

View File

@@ -6,8 +6,8 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2003 Ullrich von Bassewitz */ /* (C) 2003-2008 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */ /* Roemerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
@@ -64,8 +64,8 @@ extern StringPool StrPool;
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE unsigned GetStringId (const char* S) INLINE unsigned GetStrBufId (const StrBuf* S)
/* Return the id of the given string */ /* Return the id of the given string buffer */
{ {
return SP_Add (&StrPool, S); return SP_Add (&StrPool, S);
} }
@@ -74,13 +74,33 @@ INLINE unsigned GetStringId (const char* S)
#endif #endif
#if defined(HAVE_INLINE) #if defined(HAVE_INLINE)
INLINE const char* GetString (unsigned Index) INLINE unsigned GetStringId (const char* S)
/* Return the id of the given string */
{
return SP_AddStr (&StrPool, S);
}
#else
# define GetStringId(S) SP_Add (&StrPool, (S))
#endif
#if defined(HAVE_INLINE)
INLINE const StrBuf* GetStrBuf (unsigned Index)
/* Convert a string index into a string */ /* Convert a string index into a string */
{ {
return SP_Get (&StrPool, Index); return SP_Get (&StrPool, Index);
} }
#else #else
# define GetString(Index) SP_Get (&StrPool, (Index)) # define GetStrBuf(Index) SP_Get (&StrPool, (Index))
#endif
#if defined(HAVE_INLINE)
INLINE const char* GetString (unsigned Index)
/* Convert a string index into a string */
{
return SB_GetConstBuf (SP_Get (&StrPool, Index));
}
#else
# define GetString(Index) SB_GetConstBuf (SP_Get (&StrPool, (Index)))
#endif #endif
void InitStrPool (void); void InitStrPool (void);