From: cuz Date: Mon, 31 Mar 2008 20:54:45 +0000 (+0000) Subject: Make much more usage of dynamic strings (StrBufs) instead of char* and X-Git-Tag: V2.12.0~32 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=9174f65e541b4e1008d40ff2b86db849b2086065;p=cc65 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 --- diff --git a/src/ca65/anonname.c b/src/ca65/anonname.c index 787b3071a..3a24381f0 100644 --- a/src/ca65/anonname.c +++ b/src/ca65/anonname.c @@ -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 #include -/* 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); } diff --git a/src/ca65/anonname.h b/src/ca65/anonname.h index 2b71608a1..bce9126a3 100644 --- a/src/ca65/anonname.h +++ b/src/ca65/anonname.h @@ -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 diff --git a/src/ca65/asserts.c b/src/ca65/asserts.c index 24810e2c8..51083e620 100644 --- a/src/ca65/asserts.c +++ b/src/ca65/asserts.c @@ -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 */ /* */ diff --git a/src/ca65/dbginfo.c b/src/ca65/dbginfo.c index 760b73db3..c1f8a5b02 100644 --- a/src/ca65/dbginfo.c +++ b/src/ca65/dbginfo.c @@ -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 +/* 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 (); diff --git a/src/ca65/enum.c b/src/ca65/enum.c index bb88e09fd..368a7484a 100644 --- a/src/ca65/enum.c +++ b/src/ca65/enum.c @@ -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 (); diff --git a/src/ca65/error.c b/src/ca65/error.c index 06bbf2615..a0827de61 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -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 #include +/* 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); } diff --git a/src/ca65/error.h b/src/ca65/error.h index 2d7e2048b..b14b471bd 100644 --- a/src/ca65/error.h +++ b/src/ca65/error.h @@ -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. */ diff --git a/src/ca65/expr.c b/src/ca65/expr.c index 7aa936cd4..cb747c754 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -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"); diff --git a/src/ca65/feature.c b/src/ca65/feature.c index e5a0d4a28..fbd5e1561 100644 --- a/src/ca65/feature.c +++ b/src/ca65/feature.c @@ -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. diff --git a/src/ca65/feature.h b/src/ca65/feature.h index a297effff..d3bf08e06 100644 --- a/src/ca65/feature.h +++ b/src/ca65/feature.h @@ -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. diff --git a/src/ca65/filetab.c b/src/ca65/filetab.c index f7404cdc7..3f7b415e3 100644 --- a/src/ca65/filetab.c +++ b/src/ca65/filetab.c @@ -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) - + diff --git a/src/ca65/filetab.h b/src/ca65/filetab.h index 85c008072..fe34a3ee4 100644 --- a/src/ca65/filetab.h +++ b/src/ca65/filetab.h @@ -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. */ diff --git a/src/ca65/instr.c b/src/ca65/instr.c index 89cdaf5e8..88acf515e 100644 --- a/src/ca65/instr.c +++ b/src/ca65/instr.c @@ -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'; diff --git a/src/ca65/instr.h b/src/ca65/instr.h index 8e00c0f6d..7b36cfffb 100644 --- a/src/ca65/instr.h +++ b/src/ca65/instr.h @@ -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); + diff --git a/src/ca65/listing.c b/src/ca65/listing.c index ad97d4b50..911c27db2 100644 --- a/src/ca65/listing.c +++ b/src/ca65/listing.c @@ -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; diff --git a/src/ca65/macpack.c b/src/ca65/macpack.c index a6ec607c1..ee46d3e6f 100644 --- a/src/ca65/macpack.c +++ b/src/ca65/macpack.c @@ -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)) { diff --git a/src/ca65/macpack.h b/src/ca65/macpack.h index 73184c043..72b47a73c 100644 --- a/src/ca65/macpack.h +++ b/src/ca65/macpack.h @@ -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. diff --git a/src/ca65/macro.c b/src/ca65/macro.c index 8f4a95b91..704ed5d6f 100644 --- a/src/ca65/macro.c +++ b/src/ca65/macro.c @@ -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) { - - /* 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; + while (Tok == TOK_IDENT) { + + /* 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 (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) - - - diff --git a/src/ca65/macro.h b/src/ca65/macro.h index d889f1aa0..045204a6e 100644 --- a/src/ca65/macro.h +++ b/src/ca65/macro.h @@ -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); diff --git a/src/ca65/main.c b/src/ca65/main.c index b8a8935a3..462fb464a 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -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; diff --git a/src/ca65/nexttok.c b/src/ca65/nexttok.c index 44888b5ca..b5ae2ecb1 100644 --- a/src/ca65/nexttok.c +++ b/src/ca65/nexttok.c @@ -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); } diff --git a/src/ca65/objcode.c b/src/ca65/objcode.c index 9ca419c11..f9032a076 100644 --- a/src/ca65/objcode.c +++ b/src/ca65/objcode.c @@ -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 */ { diff --git a/src/ca65/objcode.h b/src/ca65/objcode.h index 980e373b1..317fe295b 100644 --- a/src/ca65/objcode.h +++ b/src/ca65/objcode.h @@ -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 */ diff --git a/src/ca65/objfile.c b/src/ca65/objfile.c index 0adaaee54..f9fba1521 100644 --- a/src/ca65/objfile.c +++ b/src/ca65/objfile.c @@ -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 */ { diff --git a/src/ca65/objfile.h b/src/ca65/objfile.h index 203d98993..3abcd7cf6 100644 --- a/src/ca65/objfile.h +++ b/src/ca65/objfile.h @@ -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 */ diff --git a/src/ca65/options.c b/src/ca65/options.c index fc41ad157..02e68f696 100644 --- a/src/ca65/options.c +++ b/src/ca65/options.c @@ -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) + diff --git a/src/ca65/options.h b/src/ca65/options.h index 1c6839b48..bbb429951 100644 --- a/src/ca65/options.h +++ b/src/ca65/options.h @@ -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 */ diff --git a/src/ca65/pseudo.c b/src/ca65/pseudo.c index e7e5d1a6e..4f6b62973 100644 --- a/src/ca65/pseudo.c +++ b/src/ca65/pseudo.c @@ -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 (); } diff --git a/src/ca65/pseudo.h b/src/ca65/pseudo.h index 40ff9df38..bc3305716 100644 --- a/src/ca65/pseudo.h +++ b/src/ca65/pseudo.h @@ -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 */ /* */ diff --git a/src/ca65/repeat.c b/src/ca65/repeat.c index cfe27279b..8e767daa6 100644 --- a/src/ca65/repeat.c +++ b/src/ca65/repeat.c @@ -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 (); } } diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 31cb7b93c..8b7ef9656 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -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 (toupper (SB_AtUnchecked (Id, 0)) != 'R') { return -1; } - if (!IsDigit (Ident[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; } diff --git a/src/ca65/scanner.h b/src/ca65/scanner.h index 04ba9a4bc..17492766e 100644 --- a/src/ca65/scanner.h +++ b/src/ca65/scanner.h @@ -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); - + diff --git a/src/ca65/sizeof.c b/src/ca65/sizeof.c index 1c63efd46..ba2b2281d 100644 --- a/src/ca65/sizeof.c +++ b/src/ca65/sizeof.c @@ -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); } diff --git a/src/ca65/sizeof.h b/src/ca65/sizeof.h index 547a36212..d77ddf210 100644 --- a/src/ca65/sizeof.h +++ b/src/ca65/sizeof.h @@ -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 */ /*****************************************************************************/ diff --git a/src/ca65/spool.c b/src/ca65/spool.c index f33e0583a..7d5bd98ea 100644 --- a/src/ca65/spool.c +++ b/src/ca65/spool.c @@ -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 */ diff --git a/src/ca65/spool.h b/src/ca65/spool.h index ceec3662d..9066bc9a1 100644 --- a/src/ca65/spool.h +++ b/src/ca65/spool.h @@ -59,24 +59,44 @@ extern StringPool StrPool; +#if defined(HAVE_INLINE) +INLINE unsigned GetStrBufId (const StrBuf* S) +/* Return the id of the given string buffer */ +{ + return SP_Add (&StrPool, S); +} +#else +# define GetStringId(S) SP_Add (&StrPool, (S)) +#endif + #if defined(HAVE_INLINE) INLINE unsigned GetStringId (const char* S) /* Return the id of the given string */ { - return SP_Add (&StrPool, S); + return SP_AddStr (&StrPool, S); } #else # define GetStringId(S) SP_Add (&StrPool, (S)) #endif #if defined(HAVE_INLINE) -INLINE const char* GetString (unsigned Index) +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); diff --git a/src/ca65/struct.c b/src/ca65/struct.c index ae1b00a38..869be9947 100644 --- a/src/ca65/struct.c +++ b/src/ca65/struct.c @@ -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; diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 7d2049820..9bc162c22 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -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 { diff --git a/src/ca65/symbol.c b/src/ca65/symbol.c index 15c081e87..c81899fa9 100644 --- a/src/ca65/symbol.c +++ b/src/ca65/symbol.c @@ -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; } diff --git a/src/ca65/symbol.h b/src/ca65/symbol.h index 6282a0f5a..4d0bcbf7d 100644 --- a/src/ca65/symbol.h +++ b/src/ca65/symbol.h @@ -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); diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index 5d77696d1..9146aea38 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -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; diff --git a/src/ca65/symentry.h b/src/ca65/symentry.h index b30d07241..5da15a59f 100644 --- a/src/ca65/symentry.h +++ b/src/ca65/symentry.h @@ -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) diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 8193fe33c..615e1086a 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -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) + + diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h index ba4ea7062..9b45cfd49 100644 --- a/src/ca65/symtab.h +++ b/src/ca65/symtab.h @@ -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. diff --git a/src/ca65/token.c b/src/ca65/token.c index 9d172ccb2..20c0fd9b1 100644 --- a/src/ca65/token.c +++ b/src/ca65/token.c @@ -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); } diff --git a/src/ca65/toklist.c b/src/ca65/toklist.c index a6830613a..1af5a06d6 100644 --- a/src/ca65/toklist.c +++ b/src/ca65/toklist.c @@ -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)) { diff --git a/src/ca65/toklist.h b/src/ca65/toklist.h index 1f9424954..bdf5a76b2 100644 --- a/src/ca65/toklist.h +++ b/src/ca65/toklist.h @@ -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 */ diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index be85db461..b54771aa9 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -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); } diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 1c7c0b5f6..0b90a73fc 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -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); } diff --git a/src/cc65/macrotab.c b/src/cc65/macrotab.c index 365e7a27a..35639f832 100644 --- a/src/cc65/macrotab.c +++ b/src/cc65/macrotab.c @@ -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); } diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 57ad94c2a..c12000c5a 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -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); } diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index f45bcdedd..dda22ffd2 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -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) diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index e8e13ee6a..573b09c1e 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -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) { diff --git a/src/common/hashstr.c b/src/common/hashstr.c index 0d2eb0572..4b50731c3 100644 --- a/src/common/hashstr.c +++ b/src/common/hashstr.c @@ -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; +} + + + diff --git a/src/common/hashstr.h b/src/common/hashstr.h index 21d1ef3b4..ba591c108 100644 --- a/src/common/hashstr.h +++ b/src/common/hashstr.h @@ -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 */ diff --git a/src/common/hashtab.h b/src/common/hashtab.h index 98b5901c4..4e772fa7f 100644 --- a/src/common/hashtab.h +++ b/src/common/hashtab.h @@ -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) diff --git a/src/common/searchpath.c b/src/common/searchpath.c index e4c4f7223..d0f194a60 100644 --- a/src/common/searchpath.c +++ b/src/common/searchpath.c @@ -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; } diff --git a/src/common/strbuf.c b/src/common/strbuf.c index dbdde1b78..4a489a708 100644 --- a/src/common/strbuf.c +++ b/src/common/strbuf.c @@ -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); } diff --git a/src/common/strbuf.h b/src/common/strbuf.h index e2bb6f15d..8709b647e 100644 --- a/src/common/strbuf.h +++ b/src/common/strbuf.h @@ -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 diff --git a/src/common/strpool.c b/src/common/strpool.c index 6416c24a7..4bb19fcdd 100644 --- a/src/common/strpool.c +++ b/src/common/strpool.c @@ -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; +} + + + diff --git a/src/common/strpool.h b/src/common/strpool.h index 8054567a9..2c7e39df1 100644 --- a/src/common/strpool.h +++ b/src/common/strpool.h @@ -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. */ diff --git a/src/common/tgttrans.c b/src/common/tgttrans.c index 8c047423d..a88e0e97e 100644 --- a/src/common/tgttrans.c +++ b/src/common/tgttrans.c @@ -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 +/* 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 */ { diff --git a/src/common/tgttrans.h b/src/common/tgttrans.h index 67d5addc9..51bf8ebbb 100644 --- a/src/common/tgttrans.h +++ b/src/common/tgttrans.h @@ -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 */ diff --git a/src/da65/asminc.c b/src/da65/asminc.c index 028aa03f9..22e1ff387 100644 --- a/src/da65/asminc.c +++ b/src/da65/asminc.c @@ -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); diff --git a/src/ld65/asserts.c b/src/ld65/asserts.c index 56b546afb..14da94c3e 100644 --- a/src/ld65/asserts.c +++ b/src/ld65/asserts.c @@ -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 */ diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 61ccb5aa2..7d3f15c37 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -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) + diff --git a/src/ld65/cfgexpr.c b/src/ld65/cfgexpr.c index c5c35bd4c..2a59bfa37 100644 --- a/src/ld65/cfgexpr.c +++ b/src/ld65/cfgexpr.c @@ -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); } } diff --git a/src/ld65/condes.c b/src/ld65/condes.c index 785ba82f9..1e0406a64 100644 --- a/src/ld65/condes.c +++ b/src/ld65/condes.c @@ -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 */ diff --git a/src/ld65/config.c b/src/ld65/config.c index 140f80839..c626f38c1 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -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) { diff --git a/src/ld65/dbginfo.c b/src/ld65/dbginfo.c index c51977fb7..e2725b4fd 100644 --- a/src/ld65/dbginfo.c +++ b/src/ld65/dbginfo.c @@ -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 */ /* */ diff --git a/src/ld65/dbgsyms.c b/src/ld65/dbgsyms.c index 0ecb52a7c..661ced084 100644 --- a/src/ld65/dbgsyms.c +++ b/src/ld65/dbgsyms.c @@ -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 */ /* */ diff --git a/src/ld65/error.c b/src/ld65/error.c index 807a48cae..3fea97fdc 100644 --- a/src/ld65/error.c +++ b/src/ld65/error.c @@ -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 #include #include - + /* 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); } - + diff --git a/src/ld65/exports.c b/src/ld65/exports.c index 0cdcb3bc0..7a3c120e9 100644 --- a/src/ld65/exports.c +++ b/src/ld65/exports.c @@ -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' : ' ', diff --git a/src/ld65/extsyms.c b/src/ld65/extsyms.c index 68c16a9b4..0ca35eb54 100644 --- a/src/ld65/extsyms.c +++ b/src/ld65/extsyms.c @@ -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 */ /* */ diff --git a/src/ld65/fileio.c b/src/ld65/fileio.c index b2e93bea6..4913e3ca6 100644 --- a/src/ld65/fileio.c +++ b/src/ld65/fileio.c @@ -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; diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index d67e6327d..f2649e405 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -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); } diff --git a/src/ld65/spool.c b/src/ld65/spool.c index c6e4b83cb..9afb00f4d 100644 --- a/src/ld65/spool.c +++ b/src/ld65/spool.c @@ -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, ""); + */ + SP_AddStr (&StrPool, ""); } - + diff --git a/src/ld65/spool.h b/src/ld65/spool.h index 44e0c620c..4cbdbcb80 100644 --- a/src/ld65/spool.h +++ b/src/ld65/spool.h @@ -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 */ /* */ @@ -63,24 +63,44 @@ extern StringPool StrPool; +#if defined(HAVE_INLINE) +INLINE unsigned GetStrBufId (const StrBuf* S) +/* Return the id of the given string buffer */ +{ + return SP_Add (&StrPool, S); +} +#else +# define GetStringId(S) SP_Add (&StrPool, (S)) +#endif + #if defined(HAVE_INLINE) INLINE unsigned GetStringId (const char* S) /* Return the id of the given string */ { - return SP_Add (&StrPool, S); + return SP_AddStr (&StrPool, S); } #else # define GetStringId(S) SP_Add (&StrPool, (S)) #endif #if defined(HAVE_INLINE) -INLINE const char* GetString (unsigned Index) +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);