1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-18 07:29:36 +00:00

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 */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -36,9 +36,6 @@
#include <stdio.h>
#include <string.h>
/* common */
#include "xsprintf.h"
/* ca65 */
#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
* the buffer passed to the function, Spec will be used as part of the
* identifier if given. A pointer to the buffer is returned.
*/
{
static unsigned ACount = 0;
xsprintf (Buf, Size, "%s-%s-%04X", AnonTag, Spec, ++ACount);
SB_Printf (Buf, "%s-%s-%04X", AnonTag, Spec, ++ACount);
return Buf;
}
int IsAnonName (const char* Name)
int IsAnonName (const StrBuf* Name)
/* 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 */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -38,22 +38,27 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/
/* 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
* the buffer passed to the function, Spec will be used as part of the
* 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 */
/* End of anonname.h */
#endif

View File

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

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2003 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 2003-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -65,7 +65,7 @@ void DoEnum (void)
int Anon = (Tok != TOK_IDENT);
if (!Anon) {
/* Enter a new scope, then skip the name */
SymEnterLevel (SVal, ST_ENUM, ADDR_SIZE_ABS);
SymEnterLevel (&SVal, ST_ENUM, ADDR_SIZE_ABS);
NextTok ();
}
@ -94,7 +94,7 @@ void DoEnum (void)
}
/* 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 */
NextTok ();

View File

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

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2000-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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
* 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 */
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 */
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.
* In any case, return the feature found. An invalid Key will return
* FEAT_UNKNOWN.

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 2000-2007 Ullrich von Bassewitz */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -38,6 +38,11 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/
/* 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
* 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.
* In any case, return the feature found. An invalid Key will return
* FEAT_UNKNOWN.

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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 */
{
static StrBuf ErrorMsg = LIT_STRBUF_INITIALIZER ("(outside file scope)");
const FileEntry* F;
if (Name == 0) {
@ -192,30 +194,30 @@ const char* GetFileName (unsigned Name)
*/
if (CollCount (&FileTab) == 0) {
/* No files defined until now */
return "(outside file scope)";
return &ErrorMsg;
} else {
F = CollConstAt (&FileTab, 0);
}
} else {
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. */
{
/* Get the string pool index from the name */
unsigned NameIdx = GetStringId (Name);
unsigned NameIdx = GetStrBufId (Name);
/* Search in the hash table for the name */
FileEntry* F = HT_FindEntry (&HashTab, &NameIdx);
/* If we don't have this index, print a diagnostic and use the main file */
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;
} else {
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
* the table.
*/
{
/* 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 F->Index;
@ -265,4 +267,4 @@ void WriteFiles (void)

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -38,19 +38,24 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
const char* GetFileName (unsigned Name);
const StrBuf* GetFileName (unsigned Name);
/* 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. */
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
* the table.
*/

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2006, Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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
* instruction table. If not, return -1.
*/
@ -1472,7 +1472,7 @@ int FindInstruction (const char* Ident)
/* Make a copy, and uppercase that copy */
I = 0;
while (Ident[I] != '\0') {
while (I < SB_GetLen (Ident)) {
/* If the identifier is longer than the longest mnemonic, it cannot
* be one.
*/
@ -1480,7 +1480,7 @@ int FindInstruction (const char* Ident)
/* Not found, no need for further action */
return -1;
}
Key[I] = toupper ((unsigned char)Ident[I]);
Key[I] = toupper ((unsigned char)SB_AtUnchecked (Ident, I));
++I;
}
Key[I] = '\0';

View File

@ -1,13 +1,13 @@
/*****************************************************************************/
/* */
/* instr.h */
/* instr.h */
/* */
/* Instruction encoding for the ca65 macroassembler */
/* */
/* */
/* */
/* (C) 1998-2005, Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -40,6 +40,7 @@
/* common */
#include "cpu.h"
#include "strbuf.h"
@ -152,7 +153,7 @@ void SetCPU (cpu_t NewCPU);
cpu_t GetCPU (void);
/* 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
* 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 */
/* D-70794 Filderstadt */
/* 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
* 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 */
fprintf (F,
"ca65 V%u.%u.%u - %s\n"
"Main file : %s\n"
"Current file: %s\n"
"Current file: %.*s\n"
"\n",
VER_MAJOR, VER_MINOR, VER_PATCH,
Copyright,
InFile,
GetFileName (L->File));
SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
/* Count pages, reset lines */
++PageNumber;

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2005, Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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
* -1 if the package name was not found.
*/
@ -90,7 +90,7 @@ int MacPackFind (const char* Name)
int I;
for (I = 0; I < MAC_COUNT; ++I) {
if (StrCaseCmp (Name, MacPackages[I].Name) == 0) {
if (SB_CompareStr (Name, MacPackages[I].Name) == 0) {
/* Found */
return I;
}
@ -130,21 +130,21 @@ void MacPackInsert (int Id)
NewInputFile (SB_GetConstBuf (&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
* to use the builtin packages. For debugging macro packages, external files
* can be used.
*/
{
/* 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 */
if (SB_NotEmpty (&MacPackDir)) {

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2005, Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -38,6 +38,11 @@
/* common */
#include "strbuf.h"
/*****************************************************************************/
/* 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
* -1 if the package name was not found.
*/
@ -72,7 +77,7 @@ int MacPackFind (const char* Name);
void MacPackInsert (int Id);
/* 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
* to use the builtin packages. For debugging macro packages, external files
* can be used.

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2007 Ullrich von Bassewitz */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -88,7 +88,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
typedef struct IdDesc IdDesc;
struct IdDesc {
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* TokLast; /* Pointer to last token in list */
unsigned char Style; /* Macro style */
char Name [1]; /* Macro name, dynamically allocated */
StrBuf Name; /* Macro name, dynamically allocated */
};
/* Hash table functions */
@ -157,7 +157,7 @@ static unsigned LocalName = 0;
static unsigned HT_GenHash (const void* 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)
/* 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.
*/
{
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 */
{
/* Allocate memory */
unsigned Len = strlen (Id);
IdDesc* I = xmalloc (sizeof (IdDesc) + Len);
IdDesc* I = xmalloc (sizeof (IdDesc));
/* Initialize the struct */
I->Next = 0;
memcpy (I->Id, Id, Len);
I->Id [Len] = '\0';
I->Id = AUTO_STRBUF_INITIALIZER;
SB_Copy (&I->Id, Id);
/* Return the new struct */
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 */
{
/* Allocate memory */
unsigned Len = strlen (Name);
Macro* M = xmalloc (sizeof (Macro) + Len);
Macro* M = xmalloc (sizeof (Macro));
/* Initialize the macro struct */
InitHashNode (&M->Node, M);
@ -230,7 +228,8 @@ static Macro* NewMacro (const char* Name, unsigned char Style)
M->TokRoot = 0;
M->TokLast = 0;
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 */
M->List = MacroRoot;
@ -340,7 +339,7 @@ void MacDef (unsigned Style)
Error ("Identifier expected");
MacSkipDef (Style);
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
* allowed if not explicitly enabled.
*/
@ -350,16 +349,16 @@ void MacDef (unsigned Style)
}
/* Did we already define that macro? */
if (HT_Find (&MacroTab, SVal) != 0) {
if (HT_Find (&MacroTab, &SVal) != 0) {
/* 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 */
MacSkipDef (Style);
return;
}
/* Define the macro */
M = NewMacro (SVal, Style);
M = NewMacro (&SVal, Style);
/* Switch to raw token mode and skip the macro name */
EnterRawTokenMode ();
@ -369,45 +368,45 @@ void MacDef (unsigned Style)
* otherwise we may have parameters without braces.
*/
if (Style == MAC_STYLE_CLASSIC) {
HaveParams = 1;
HaveParams = 1;
} else {
if (Tok == TOK_LPAREN) {
HaveParams = 1;
NextTok ();
} else {
HaveParams = 0;
}
if (Tok == TOK_LPAREN) {
HaveParams = 1;
NextTok ();
} else {
HaveParams = 0;
}
}
/* Parse the parameter list */
if (HaveParams) {
while (Tok == TOK_IDENT) {
while (Tok == TOK_IDENT) {
/* Create a struct holding the identifier */
IdDesc* I = NewIdDesc (SVal);
/* Create a struct holding the identifier */
IdDesc* I = NewIdDesc (&SVal);
/* Insert the struct into the list, checking for duplicate idents */
if (M->ParamCount == 0) {
M->Params = I;
} else {
IdDesc* List = M->Params;
while (1) {
if (strcmp (List->Id, SVal) == 0) {
Error ("Duplicate symbol `%s'", SVal);
}
if (List->Next == 0) {
break;
} else {
List = List->Next;
}
}
List->Next = I;
}
++M->ParamCount;
/* Insert the struct into the list, checking for duplicate idents */
if (M->ParamCount == 0) {
M->Params = I;
} else {
IdDesc* List = M->Params;
while (1) {
if (SB_Compare (&List->Id, &SVal) == 0) {
Error ("Duplicate symbol `%m%p'", &SVal);
}
if (List->Next == 0) {
break;
} else {
List = List->Next;
}
}
List->Next = I;
}
++M->ParamCount;
/* Skip the name */
NextTok ();
NextTok ();
/* Maybe there are more params... */
if (Tok == TOK_COMMA) {
@ -471,7 +470,7 @@ void MacDef (unsigned Style)
}
/* Put the identifier into the locals list and skip it */
I = NewIdDesc (SVal);
I = NewIdDesc (&SVal);
I->Next = M->Locals;
M->Locals = I;
++M->LocalCount;
@ -497,7 +496,7 @@ void MacDef (unsigned Style)
unsigned Count = 0;
IdDesc* I = M->Params;
while (I) {
if (strcmp (I->Id, SVal) == 0) {
if (SB_Compare (&I->Id, &SVal) == 0) {
/* Local param name, replace it */
T->Tok = TOK_MACPARAM;
T->IVal = Count;
@ -607,15 +606,21 @@ static int MacExpand (void* Data)
unsigned Index = 0;
IdDesc* I = Mac->M->Locals;
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
* to generate a local label name if the original name was
* a local label, and also generate a name that cannot be
* generated by a user.
*/
unsigned PrefixLen = (I->Id[0] == LocalStart);
sprintf (SVal, "%.*sLOCAL-MACRO-SYMBOL-%04X", PrefixLen,
I->Id, Mac->LocalStart + Index);
if (SB_At (&I->Id, 0) == LocalStart) {
/* Must generate a local symbol */
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;
}
/* Next symbol */
@ -836,7 +841,7 @@ void MacExpandStart (void)
/* Start expanding the macro in SVal */
{
/* Search for the macro */
Macro* M = HT_FindEntry (&MacroTab, SVal);
Macro* M = HT_FindEntry (&MacroTab, &SVal);
CHECK (M != 0);
/* 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 (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 */
{
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 */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -65,10 +65,10 @@ void MacExpandStart (void);
void MacAbort (void);
/* 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 */
int IsDefine (const char* Name);
int IsDefine (const StrBuf* Name);
/* Return true if the given name is the name of a define style macro */
int InMacExpansion (void);

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2007, Ullrich von Bassewitz */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -44,6 +44,7 @@
#include "cmdline.h"
#include "mmodel.h"
#include "print.h"
#include "strbuf.h"
#include "target.h"
#include "tgttrans.h"
#include "version.h"
@ -127,14 +128,17 @@ static void Usage (void)
static void SetOptions (void)
/* Set the option for the translator */
{
char Buf [256];
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
/* Set the translator */
sprintf (Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
OptTranslator (Buf);
SB_Printf (&Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
OptTranslator (&Buf);
/* Set date and time */
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;
/* 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 */
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 */
if (SymIsDef (Sym)) {
@ -157,6 +165,9 @@ static void NewSymbol (const char* SymName, long Val)
/* Mark the symbol as defined */
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;
unsigned I;
long Val;
char SymName [MAX_STR_LEN+1];
StrBuf SymName = AUTO_STRBUF_INITIALIZER;
/* The symbol must start with a character or underline */
if (Def [0] != '_' && !IsAlpha (Def [0])) {
if (!IsIdStart (Def [0])) {
InvDef (Def);
}
P = Def;
/* Copy the symbol, checking the rest */
I = 0;
while (IsAlNum (*P) || *P == '_') {
if (I <= MAX_STR_LEN) {
SymName [I++] = *P;
}
++P;
while (IsIdChar (*P)) {
SB_AppendChar (&SymName, *P++);
}
SymName [I] = '\0';
SB_Terminate (&SymName);
/* Do we have a value given? */
if (*P != '=') {
@ -317,7 +325,10 @@ static void DefineSymbol (const char* Def)
}
/* 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)
/* Set an emulation feature */
{
/* Make a string buffer from Arg */
StrBuf Feature;
/* 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);
}
}
@ -425,8 +439,11 @@ static void OptListing (const char* Opt attribute ((unused)),
static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg)
/* Set a macro package directory */
{
/* Make a string buffer from Arg */
StrBuf Dir;
/* Use the directory */
MacPackSetDir (Arg);
MacPackSetDir (SB_InitFromString (&Dir, Arg));
}
@ -545,13 +562,13 @@ static void OneLine (void)
if (Tok == TOK_IDENT) {
if (!UbiquitousIdents) {
/* Macros and symbols cannot use instruction names */
Instr = FindInstruction (SVal);
Instr = FindInstruction (&SVal);
if (Instr < 0) {
Macro = IsMacro (SVal);
Macro = IsMacro (&SVal);
}
} else {
/* 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 */
if (Tok == TOK_IDENT) {
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
} else {
Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW);
Sym = SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW);
}
NextTok ();
@ -640,13 +657,13 @@ static void OneLine (void)
if (Tok == TOK_IDENT) {
if (!UbiquitousIdents) {
/* Macros and symbols cannot use instruction names */
Instr = FindInstruction (SVal);
Instr = FindInstruction (&SVal);
if (Instr < 0) {
Macro = IsMacro (SVal);
Macro = IsMacro (&SVal);
}
} else {
/* 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 */
MacExpandStart ();
} else if (Instr >= 0 ||
(UbiquitousIdents && ((Instr = FindInstruction (SVal)) >= 0))) {
(UbiquitousIdents && ((Instr = FindInstruction (&SVal)) >= 0))) {
/* A mnemonic - assemble one instruction */
HandleInstruction (Instr);
} else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) {
@ -774,6 +791,9 @@ int main (int argc, char* argv [])
{ "--version", 0, OptVersion },
};
/* Name of the global name space */
static const StrBuf GlobalNameSpace = STATIC_STRBUF_INITIALIZER;
unsigned I;
/* 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
* define symbols using -D.
*/
SymEnterLevel ("", ST_GLOBAL, ADDR_SIZE_DEFAULT);
SymEnterLevel (&GlobalNameSpace, ST_GLOBAL, ADDR_SIZE_DEFAULT);
/* Check the parameters */
I = 1;

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -40,6 +40,7 @@
/* ca65 */
#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);
/* 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 */
void EmitStrBuf (const StrBuf* Data);
/* Emit a string into the current segment */
void EmitByte (ExprNode* Expr);
/* 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)
/* Write literal data to the file */
{

View File

@ -40,6 +40,7 @@
/* common */
#include "filepos.h"
#include "strbuf.h"
@ -79,6 +80,9 @@ void ObjWriteVar (unsigned long V);
void ObjWriteStr (const char* S);
/* 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);
/* Write literal data to the file */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 */
{
NewOption (Type, GetStringId (Text));
NewOption (Type, GetStrBufId (Text));
}
void OptComment (const char* Comment)
void OptComment (const StrBuf* 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 */
{
NewOption (OPT_AUTHOR, GetStringId (Author));
NewOption (OPT_AUTHOR, GetStrBufId (Author));
}
void OptTranslator (const char* Translator)
void OptTranslator (const StrBuf* Translator)
/* 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 */
{
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 */
{
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 */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 */
void OptComment (const char* Comment);
void OptComment (const StrBuf* Comment);
/* Add a comment */
void OptAuthor (const char* Author);
void OptAuthor (const StrBuf* Author);
/* Add an author statement */
void OptTranslator (const char* Translator);
void OptTranslator (const StrBuf* Translator);
/* Add a translator option */
void OptCompiler (const char* Compiler);
void OptCompiler (const StrBuf* Compiler);
/* Add a compiler option */
void OptOS (const char* OS);
void OptOS (const StrBuf* OS);
/* Add an operating system option */
void OptDateTime (unsigned long DateTime);
@ -68,7 +68,7 @@ void OptDateTime (unsigned long DateTime);
void WriteOptions (void);
/* Write the options to the object file */
/* End of options.h */

View File

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

View File

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

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 2000-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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.
*/
{
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 */
Tok = TOK_INTCON;
IVal = L->RepCount;
@ -143,7 +143,8 @@ void ParseRepeat (void)
ErrorSkip ("Identifier expected");
} else {
/* Remember the name and skip it */
Name = xstrdup (SVal);
SB_Terminate (&SVal);
Name = xstrdup (SB_GetConstBuf (&SVal));
NextTok ();
}
}

View File

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

View File

@ -40,6 +40,7 @@
/* common */
#include "filepos.h"
#include "strbuf.h"
/* ca65 */
#include "token.h"
@ -58,7 +59,7 @@
extern Token Tok; /* Current token */
extern int WS; /* Flag: Whitespace before token */
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 int ForcedEnd; /* Force end of assembly */
@ -119,4 +120,4 @@ void DoneScanner (void);

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2003 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 2003-2008, Ullrich von Bassewit */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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
* 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.
*/
{
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.
*/
{
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 */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 2003-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -35,6 +35,11 @@
#ifndef 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 */
/*****************************************************************************/

View File

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

View File

@ -60,8 +60,8 @@ extern StringPool StrPool;
#if defined(HAVE_INLINE)
INLINE unsigned GetStringId (const char* S)
/* Return the id of the given string */
INLINE unsigned GetStrBufId (const StrBuf* S)
/* Return the id of the given string buffer */
{
return SP_Add (&StrPool, S);
}
@ -70,13 +70,33 @@ INLINE unsigned GetStringId (const char* S)
#endif
#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 */
{
return SP_Get (&StrPool, Index);
}
#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
void WriteStrPool (void);

View File

@ -106,7 +106,7 @@ static long DoStructInternal (long Offs, unsigned Type)
int Anon = (Tok != TOK_IDENT);
if (!Anon) {
/* Enter a new scope, then skip the name */
SymEnterLevel (SVal, ST_STRUCT, ADDR_SIZE_ABS);
SymEnterLevel (&SVal, ST_STRUCT, ADDR_SIZE_ABS);
NextTok ();
/* Start at zero offset in the new scope */
Offs = 0;
@ -132,7 +132,7 @@ static long DoStructInternal (long Offs, unsigned Type)
Sym = 0;
if (Tok == TOK_IDENT) {
/* 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 */
SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);
@ -261,7 +261,7 @@ static long DoStructInternal (long Offs, unsigned Type)
long GetStructSize (SymTable* Struct)
/* 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) {
Error ("Size of struct/union is unknown");
return 0;

View File

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

View File

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

View File

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

View File

@ -2,11 +2,11 @@
/* */
/* 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 */
/* D-70794 Filderstadt */
/* 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 */
{
unsigned I;
@ -95,7 +95,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
S->ExportSize = ADDR_SIZE_DEFAULT;
S->AddrSize = ADDR_SIZE_DEFAULT;
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
S->Name = GetStringId (Name);
S->Name = GetStrBufId (Name);
/* Insert it into the list of all entries */
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
* 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,
@ -126,10 +126,10 @@ int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E)
while (1) {
/* Get the symbol name */
const char* SymName = GetString (T->Name);
const StrBuf* SymName = GetStrBuf (T->Name);
/* Choose next entry */
int Cmp = strcmp (Name, SymName);
int Cmp = SB_Compare (Name, SymName);
if (Cmp < 0 && T->Left) {
T = T->Left;
} 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) {
/* 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;
}
if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
/* 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;
}
if (S->Flags & SF_DEFINED) {
/* Multiple definition. In case of a variable, this is legal. */
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;
return;
} else {
/* Redefinition must also be a variable symbol */
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;
}
/* 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;
} else if (S->AddrSize > S->ExportSize) {
/* 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),
AddrSizeToStr (S->ExportSize));
}
@ -302,13 +302,13 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Mark the given symbol as an imported symbol */
{
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;
return;
}
if (S->Flags & SF_EXPORT) {
/* 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;
}
@ -324,16 +324,16 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/
if (S->Flags & SF_IMPORT) {
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) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
}
}
if (S->Flags & SF_GLOBAL) {
S->Flags &= ~SF_GLOBAL;
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 */
if (S->Flags & SF_IMPORT) {
/* 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;
}
if (S->Flags & SF_VAR) {
/* 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;
}
@ -364,7 +364,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/
if (S->Flags & SF_GLOBAL) {
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;
}
@ -374,7 +374,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
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;
@ -388,7 +388,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) {
/* 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),
AddrSizeToStr (S->ExportSize));
}
@ -407,7 +407,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
{
if (S->Flags & SF_VAR) {
/* 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;
}
@ -420,7 +420,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
AddrSize = GetCurrentSegAddrSize ();
}
if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
}
return;
}
@ -432,12 +432,12 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
if ((S->Flags & SF_DEFINED) == 0) {
/* Symbol is undefined */
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) {
/* Symbol is defined and address size given */
if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
}
}
return;
@ -449,7 +449,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/
if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
}
return;
}
@ -467,7 +467,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) {
/* 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),
AddrSizeToStr (S->ExportSize));
}
@ -505,12 +505,12 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
/* Check for errors */
if (S->Flags & SF_IMPORT) {
/* 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;
}
if (S->Flags & SF_VAR) {
/* 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;
}
@ -520,7 +520,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
*/
if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
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;
}
@ -534,7 +534,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
/* Use the real size of the symbol */
S->ExportSize = S->AddrSize;
} 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] != Prio) {
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
}
}
S->ConDesPrio[Type] = Prio;

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -43,6 +43,7 @@
#include "coll.h"
#include "filepos.h"
#include "inline.h"
#include "strbuf.h"
/* ca65 */
#include "spool.h"
@ -97,7 +98,7 @@ struct SymEntry {
unsigned char ExportSize; /* Export address size */
unsigned char AddrSize; /* Address size of label */
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 */
};
@ -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 */
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
* 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,
@ -305,10 +306,10 @@ const struct ExprNode* SymResolve (const SymEntry* Sym);
*/
#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 GetString (S->Name);
return GetStrBuf (S->Name);
}
#else
# define GetSymName(S) GetString ((S)->Name)

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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 */
{
/* 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->TableEntries = 0;
S->Parent = Parent;
S->Name = GetStringId (Name);
S->Name = GetStrBufId (Name);
while (Slots--) {
S->Table[Slots] = 0;
}
@ -133,7 +133,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
} else {
while (1) {
/* Choose next entry */
int Cmp = strcmp (Name, GetString (T->Name));
int Cmp = SB_Compare (Name, GetStrBuf (T->Name));
if (Cmp < 0) {
if (T->Left) {
T = T->Left;
@ -150,7 +150,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
}
} else {
/* 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 */
{
/* 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 */
if (CurrentScope->Flags & ST_DEFINED) {
Error ("Duplicate scope `%s'", ScopeName);
Error ("Duplicate scope `%m%p'", ScopeName);
}
} 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 */
{
SymTable** T = &Parent->Childs;
while (*T) {
int Cmp = strcmp (Name, GetString ((*T)->Name));
int Cmp = SB_Compare (Name, GetStrBuf ((*T)->Name));
if (Cmp < 0) {
T = &(*T)->Left;
} 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
* never create a new symbol, since this can only be done in one specific
* 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
* found, create a new one. Return the entry found, or the new entry created,
* 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
* 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.
@ -340,7 +340,7 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
SymEntry* S;
/* 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 */
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
* never create a new symbol, since this can only be done in one specific
* scope.
@ -424,7 +424,7 @@ static void SymCheckUndefined (SymEntry* S)
SymEntry* Sym = 0;
SymTable* Tab = GetSymParentScope (S);
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) {
/* We've found a symbol in a higher level that is
* 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. */
if (Sym->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
PWarning (&S->Pos, 1, "Symbol `%m%p' is %s but exported %s",
GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (S->ExportSize));
}
} else {
@ -465,8 +466,9 @@ static void SymCheckUndefined (SymEntry* S)
}
if (Sym->AddrSize > Sym->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
PWarning (&S->Pos, 1, "Symbol `%m%p' is %s but exported %s",
GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (Sym->ExportSize));
}
}
@ -483,8 +485,8 @@ static void SymCheckUndefined (SymEntry* S)
/* The symbol is definitely undefined */
if (S->Flags & SF_EXPORT) {
/* We will not auto-import an export */
PError (&S->Pos, "Exported symbol `%s' was never defined",
GetString (S->Name));
PError (&S->Pos, "Exported symbol `%m%p' was never defined",
GetSymName (S));
} else {
if (AutoImport) {
/* Mark as import, will be indexed later */
@ -493,7 +495,7 @@ static void SymCheckUndefined (SymEntry* S)
S->AddrSize = CodeAddrSize;
} else {
/* 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 */
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
const char* Name = GetString (S->Name);
if (Name[0] != '.') { /* Ignore internals */
const StrBuf* Name = GetStrBuf (S->Name);
if (SB_At (Name, 0) != '.') { /* Ignore internals */
PWarning (&S->Pos, 2,
"Symbol `%s' is defined but never used",
GetString (S->Name));
"Symbol `%m%p' is defined but never used",
GetSymName (S));
}
}
@ -562,8 +564,8 @@ void SymCheck (void)
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */
PWarning (&S->Pos, 2,
"Symbol `%s' is imported but never used",
GetString (S->Name));
"Symbol `%m%p' is imported but never used",
GetSymName (S));
} else {
/* Give the import an index, count imports */
S->Index = ImportCount++;
@ -593,8 +595,9 @@ void SymCheck (void)
} else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1,
"Symbol `%s' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize),
"Symbol `%m%p' is %s but exported %s",
GetSymName (S),
AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize));
}
}
@ -612,7 +615,7 @@ void SymCheck (void)
const FilePos* P = S->GuessedUse[S->AddrSize - 1];
if (P) {
PWarning (P, 0,
"Didn't use %s addressing for `%s'",
"Didn't use %s addressing for `%m%p'",
AddrSizeToStr (S->AddrSize),
GetSymName (S));
}
@ -637,8 +640,8 @@ void SymDump (FILE* F)
/* Ignore unused symbols */
if ((S->Flags & SF_UNUSED) != 0) {
fprintf (F,
"%-24s %s %s %s %s %s\n",
GetString (S->Name),
"%m%-24p %s %s %s %s %s\n",
GetSymName (S),
(S->Flags & SF_DEFINED)? "DEF" : "---",
(S->Flags & SF_REFERENCED)? "REF" : "---",
(S->Flags & SF_IMPORT)? "IMP" : "---",
@ -842,3 +845,5 @@ void WriteScopes (void)

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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 */
void SymLeaveLevel (void);
/* 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 */
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
* never create a new symbol, since this can only be done in one specific
* 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
* found, create a new one. Return the entry found, or the new entry created,
* 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
* 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.
*/
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
* never create a new symbol, since this can only be done in one specific
* scope.

View File

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

View File

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

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2001-2006, Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 2001-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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 */
DoneStrBuf (&Buf);
SB_Done (&Buf);
}

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -153,7 +153,7 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
}
/* 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);
/* Call the string buf destructor */
DoneStrBuf (&S);
SB_Done (&S);
}
@ -494,7 +494,7 @@ static void ParsePragma (void)
FlagPragma (&B, &WarnDisable);
break;
case PR_ZPSYM:
case PR_ZPSYM:
StringPragma (&B, MakeZPSym);
break;
@ -522,7 +522,7 @@ static void ParsePragma (void)
}
/* 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 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -189,7 +189,7 @@ static MacroExp* InitMacroExp (MacroExp* E, Macro* M)
/* Initialize a MacroExp structure */
{
InitCollection (&E->ActualArgs);
InitStrBuf (&E->Replacement);
SB_Init (&E->Replacement);
E->M = M;
return E;
}
@ -206,7 +206,7 @@ static void DoneMacroExp (MacroExp* E)
FreeStrBuf (CollAtUnchecked (&E->ActualArgs, I));
}
DoneCollection (&E->ActualArgs);
DoneStrBuf (&E->Replacement);
SB_Done (&E->Replacement);
}
@ -488,7 +488,7 @@ static void ReadMacroArgs (MacroExp* E)
}
/* Deallocate string buf resources */
DoneStrBuf (&Arg);
SB_Done (&Arg);
}
@ -1145,7 +1145,7 @@ static void DoInclude (void)
Done:
/* Free the allocated filename data */
DoneStrBuf (&Filename);
SB_Done (&Filename);
/* Clear the remaining line so the next input will come from the new
* file (if open)

View File

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

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -33,6 +33,11 @@
/* common */
#include "hashstr.h"
/*****************************************************************************/
/* 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 */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -38,7 +38,9 @@
/* common */
#include "attrib.h"
#include "strbuf.h"
@ -51,6 +53,9 @@
unsigned HashStr (const char* S) attribute ((const));
/* 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 */

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -138,7 +138,7 @@ static char* Find (const char* Path, const char* File)
if (access (SB_GetBuf (&PathName), 0) == 0) {
/* The file exists, return its name */
char* Name = xstrdup (SB_GetBuf (&PathName));
DoneStrBuf (&PathName);
SB_Done (&PathName);
return Name;
}
@ -149,7 +149,7 @@ static char* Find (const char* Path, const char* File)
}
/* Not found */
DoneStrBuf (&PathName);
SB_Done (&PathName);
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 */
{
*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->Len = 0;
B->Len = strlen (S);
B->Index = 0;
B->Buf = 0;
B->Buf = (char*) S;
return B;
}
void DoneStrBuf (StrBuf* B)
void SB_Done (StrBuf* B)
/* 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));
/* Initialize the struct... */
InitStrBuf (B);
SB_Init (B);
/* ...and return it */
return B;
@ -100,7 +115,7 @@ StrBuf* NewStrBuf (void)
void FreeStrBuf (StrBuf* B)
/* Free a string buffer */
{
DoneStrBuf (B);
SB_Done (B);
xfree (B);
}
@ -122,8 +137,50 @@ void SB_Realloc (StrBuf* B, unsigned NewSize)
NewAllocated *= 2;
}
/* Reallocate the buffer */
B->Buf = xrealloc (B->Buf, NewAllocated);
/* Reallocate the buffer. Beware: The allocated size may be zero while the
* 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;
}
@ -170,7 +227,7 @@ void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size)
/* Copy Buf to Target, discarding the old contents of Target */
{
if (Target->Allocated < Size) {
SB_Realloc (Target, Size);
SB_CheapRealloc (Target, Size);
}
memcpy (Target->Buf, Buf, Size);
Target->Len = Size;
@ -294,7 +351,7 @@ void SB_Move (StrBuf* Target, StrBuf* Source)
*/
{
/* Free the target string */
if (Target->Buf) {
if (Target->Allocated) {
xfree (Target->Buf);
}
@ -302,7 +359,7 @@ void SB_Move (StrBuf* Target, StrBuf* Source)
*Target = *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)
/* 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
@ -382,10 +464,8 @@ void SB_VPrintf (StrBuf* S, const char* Format, va_list ap)
/* Check if we must reallocate */
if ((unsigned) SizeNeeded >= S->Allocated) {
/* Must retry. Don't use Realloc to avoid copying */
xfree (S->Buf);
S->Allocated = SizeNeeded + 1; /* Account for '\0' */
S->Buf = xmalloc (S->Allocated);
/* Must retry. Use CheapRealloc to avoid copying */
SB_CheapRealloc (S, SizeNeeded + 1); /* Account for '\0' */
(void) xvsnprintf (S->Buf, S->Allocated, Format, ap);
}

View File

@ -49,18 +49,18 @@
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
typedef struct StrBuf StrBuf;
struct StrBuf {
unsigned Allocated; /* Size of allocated memory */
char* Buf; /* Pointer to buffer */
unsigned Len; /* Length of the string */
unsigned Index; /* Used for reading (Get and friends) */
char* Buf; /* Pointer to buffer */
};
unsigned Allocated; /* Size of allocated memory */
};
/* An empty string buf */
extern const StrBuf EmptyStrBuf;
@ -71,18 +71,36 @@ extern const StrBuf EmptyStrBuf;
/* Initializer for auto string bufs */
#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 */
{
*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) */
StrBuf* NewStrBuf (void);
@ -358,14 +376,17 @@ void SB_ToUpper (StrBuf* S);
int SB_Compare (const StrBuf* S1, const StrBuf* 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);
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
* 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
* 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
* 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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 2003-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -35,7 +35,7 @@
/* 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
* 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
* string pool ids must be compared.
*/
@ -64,8 +64,7 @@ struct StringPoolEntry {
StringPoolEntry* Next; /* Pointer to next entry in hash chain */
unsigned Hash; /* Full hash value */
unsigned Id; /* The numeric string id */
unsigned Len; /* Length of the string (excluding terminator) */
char S[1]; /* The string itself */
StrBuf Buf; /* 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. */
{
/* Get the length of the string */
unsigned Len = strlen (S);
/* Allocate memory */
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry) + Len);
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry));
/* Initialize the fields */
E->Next = 0;
E->Hash = Hash;
E->Id = Id;
E->Len = Len;
memcpy (E->S, S, Len+1);
E->Buf = AUTO_STRBUF_INITIALIZER;
SB_Copy (&E->Buf, S);
/* Always zero terminate the string */
SB_Terminate (&E->Buf);
/* Return the new entry */
return E;
@ -129,7 +128,15 @@ void DoneStringPool (StringPool* P)
/* Free all entries and clear the entry collection */
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);
@ -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. */
{
/* Get the collection entry */
const StringPoolEntry* E = CollConstAt (&P->Entries, Index);
/* Return the string from the entry */
return E->S;
return &E->Buf;
}
unsigned SP_Add (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 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.
*/
{
/* Calculate the string hash */
unsigned Hash = HashStr (S);
unsigned Hash = HashBuf (S);
/* Calculate the reduced string hash */
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 */
StringPoolEntry* E = P->Tab[RHash];
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 */
return E->Id;
}
@ -208,8 +216,8 @@ unsigned SP_Add (StringPool* P, const char* S)
E->Next = P->Tab[RHash];
P->Tab[RHash] = E;
/* Add up the string size (plus terminator) */
P->TotalSize += E->Len + 1;
/* Add up the string size */
P->TotalSize += SB_GetLen (&E->Buf);
/* Return the id of the entry */
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 */
/* Römerstrasse 52 */
/* (C) 2003-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -48,6 +48,7 @@
/* common */
#include "attrib.h"
#include "coll.h"
#include "inline.h"
#include "strbuf.h"
@ -100,10 +101,16 @@ StringPool* NewStringPool (void);
void FreeStringPool (StringPool* P);
/* 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. */
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
* 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 */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -35,6 +35,7 @@
#include <string.h>
/* common */
#include "abend.h"
#include "check.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)
/* Set the translation code for the given character */
{

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -34,7 +34,12 @@
#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.
*/
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);
/* Set the translation code for the given character */

View File

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

View File

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

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 1999-2005 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 1999-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -62,9 +62,9 @@
struct BinDesc {
unsigned Undef; /* Count of undefined externals */
FILE* F; /* Output file */
const char* Filename; /* Name of output file */
unsigned Undef; /* Count of undefined externals */
FILE* F; /* 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));
/* Writes do only occur in the load area and not for BSS segments */
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
S->Load == M && /* LOAD segment */
S->Seg->Dumped == 0; /* Not already written */
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
S->Load == M && /* LOAD segment */
S->Seg->Dumped == 0; /* Not already written */
/* Output debugging stuff */
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 */
/* Römerstrasse 52 */
/* (C) 2005-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* 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 (E->Type == ceString) {
DoneStrBuf (&E->SVal);
SB_Done (&E->SVal);
}
}

View File

@ -6,8 +6,8 @@
/* */
/* */
/* */
/* (C) 2000-2003 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* (C) 2000-2008 Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
@ -112,7 +112,7 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
Cmp = 1;
} else {
/* 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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2008, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -95,7 +95,7 @@ void CfgWarning (const char* Format, ...)
va_end (ap);
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);
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)
/* 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.
*/
SP_Add (&StrPool, "<invalid message #0>");
*/
SP_AddStr (&StrPool, "<invalid message #0>");
}

View File

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