Make much more usage of dynamic strings (StrBufs) instead of char* and
friends. Since names and other strings are now StrBufs in many places, code for output had to be changed. Added support for string literals to StrBuf. git-svn-id: svn://svn.cc65.org/cc65/trunk@3825 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -36,9 +36,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* common */
|
|
||||||
#include "xsprintf.h"
|
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "anonname.h"
|
#include "anonname.h"
|
||||||
|
|
||||||
@@ -60,23 +57,27 @@ static const char AnonTag[] = "$anon";
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* AnonName (char* Buf, unsigned Size, const char* Spec)
|
StrBuf* AnonName (StrBuf* Buf, const char* Spec)
|
||||||
/* Get a name for an anonymous scope, variable or type. Size is the size of
|
/* Get a name for an anonymous scope, variable or type. Size is the size of
|
||||||
* the buffer passed to the function, Spec will be used as part of the
|
* the buffer passed to the function, Spec will be used as part of the
|
||||||
* identifier if given. A pointer to the buffer is returned.
|
* identifier if given. A pointer to the buffer is returned.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static unsigned ACount = 0;
|
static unsigned ACount = 0;
|
||||||
xsprintf (Buf, Size, "%s-%s-%04X", AnonTag, Spec, ++ACount);
|
SB_Printf (Buf, "%s-%s-%04X", AnonTag, Spec, ++ACount);
|
||||||
return Buf;
|
return Buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsAnonName (const char* Name)
|
int IsAnonName (const StrBuf* Name)
|
||||||
/* Check if the given symbol name is that of an anonymous symbol */
|
/* Check if the given symbol name is that of an anonymous symbol */
|
||||||
{
|
{
|
||||||
return (strncmp (Name, AnonTag, sizeof (AnonTag) - 1) == 0);
|
if (SB_GetLen (Name) < sizeof (AnonTag) - 1) {
|
||||||
|
/* Too short */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (strncmp (SB_GetConstBuf (Name), AnonTag, sizeof (AnonTag) - 1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -38,22 +38,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char* AnonName (char* Buf, unsigned Size, const char* Spec);
|
StrBuf* AnonName (StrBuf* Buf, const char* Spec);
|
||||||
/* Get a name for an anonymous scope, variable or type. Size is the size of
|
/* Get a name for an anonymous scope, variable or type. Size is the size of
|
||||||
* the buffer passed to the function, Spec will be used as part of the
|
* the buffer passed to the function, Spec will be used as part of the
|
||||||
* identifier if given. A pointer to the buffer is returned.
|
* identifier if given. A pointer to the buffer is returned.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int IsAnonName (const char* Name);
|
int IsAnonName (const StrBuf* Name);
|
||||||
/* Check if the given symbol name is that of an anonymous symbol */
|
/* Check if the given symbol name is that of an anonymous symbol */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of anonname.h */
|
/* End of anonname.h */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003-2005, Ullrich von Bassewitz */
|
/* (C) 2003-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
/* */
|
/* */
|
||||||
/* dbginfo.c */
|
/* dbginfo.c */
|
||||||
/* */
|
/* */
|
||||||
/* Handle the .dbg commands */
|
/* Handle the .dbg commands */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
@@ -54,7 +57,7 @@
|
|||||||
void DbgInfoFile (void)
|
void DbgInfoFile (void)
|
||||||
/* Parse and handle FILE subcommand of the .dbg pseudo instruction */
|
/* Parse and handle FILE subcommand of the .dbg pseudo instruction */
|
||||||
{
|
{
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
unsigned long Size;
|
unsigned long Size;
|
||||||
unsigned long MTime;
|
unsigned long MTime;
|
||||||
|
|
||||||
@@ -66,7 +69,7 @@ void DbgInfoFile (void)
|
|||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Comma expected */
|
/* Comma expected */
|
||||||
@@ -82,7 +85,10 @@ void DbgInfoFile (void)
|
|||||||
MTime = ConstExpression ();
|
MTime = ConstExpression ();
|
||||||
|
|
||||||
/* Insert the file into the table */
|
/* Insert the file into the table */
|
||||||
AddFile (Name, Size, MTime);
|
AddFile (&Name, Size, MTime);
|
||||||
|
|
||||||
|
/* Free memory used for Name */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +117,7 @@ void DbgInfoLine (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the index in the file table for the name */
|
/* Get the index in the file table for the name */
|
||||||
Index = GetFileIndex (SVal);
|
Index = GetFileIndex (&SVal);
|
||||||
|
|
||||||
/* Skip the name */
|
/* Skip the name */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -65,7 +65,7 @@ void DoEnum (void)
|
|||||||
int Anon = (Tok != TOK_IDENT);
|
int Anon = (Tok != TOK_IDENT);
|
||||||
if (!Anon) {
|
if (!Anon) {
|
||||||
/* Enter a new scope, then skip the name */
|
/* Enter a new scope, then skip the name */
|
||||||
SymEnterLevel (SVal, ST_ENUM, ADDR_SIZE_ABS);
|
SymEnterLevel (&SVal, ST_ENUM, ADDR_SIZE_ABS);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ void DoEnum (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We have an identifier, generate a symbol */
|
/* We have an identifier, generate a symbol */
|
||||||
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
|
Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
|
||||||
|
|
||||||
/* Skip the member name */
|
/* Skip the member name */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -37,10 +37,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
|
#include "error.h"
|
||||||
#include "filetab.h"
|
#include "filetab.h"
|
||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
#include "error.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -69,11 +72,18 @@ void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list
|
|||||||
/* Print warning message. */
|
/* Print warning message. */
|
||||||
{
|
{
|
||||||
if (Level <= WarnLevel) {
|
if (Level <= WarnLevel) {
|
||||||
fprintf (stderr, "%s(%lu): Warning: ",
|
|
||||||
GetFileName (Pos->Name), Pos->Line);
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
vfprintf (stderr, Format, ap);
|
SB_VPrintf (&S, Format, ap);
|
||||||
fprintf (stderr, "\n");
|
SB_Terminate (&S);
|
||||||
|
|
||||||
|
fprintf (stderr, "%s(%lu): Warning: %s\n",
|
||||||
|
SB_GetConstBuf (GetFileName (Pos->Name)),
|
||||||
|
Pos->Line,
|
||||||
|
SB_GetConstBuf (&S));
|
||||||
++WarningCount;
|
++WarningCount;
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,11 +120,17 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
|
|||||||
void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap)
|
void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap)
|
||||||
/* Print an error message */
|
/* Print an error message */
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s(%lu): Error: ",
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
GetFileName (Pos->Name), Pos->Line);
|
SB_VPrintf (&S, Format, ap);
|
||||||
vfprintf (stderr, Format, ap);
|
SB_Terminate (&S);
|
||||||
fprintf (stderr, "\n");
|
|
||||||
|
fprintf (stderr, "%s(%lu): Error: %s\n",
|
||||||
|
SB_GetConstBuf (GetFileName (Pos->Name)),
|
||||||
|
Pos->Line,
|
||||||
|
SB_GetConstBuf (&S));
|
||||||
++ErrorCount;
|
++ErrorCount;
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -164,13 +180,17 @@ void Fatal (const char* Format, ...)
|
|||||||
/* Print a message about a fatal error and die */
|
/* Print a message about a fatal error and die */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "Fatal error: ");
|
SB_VPrintf (&S, Format, ap);
|
||||||
vfprintf (stderr, Format, ap);
|
SB_Terminate (&S);
|
||||||
fprintf (stderr, "\n");
|
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
|
fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S));
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
|
|
||||||
/* And die... */
|
/* And die... */
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
@@ -178,14 +198,19 @@ void Fatal (const char* Format, ...)
|
|||||||
|
|
||||||
|
|
||||||
void Internal (const char* Format, ...)
|
void Internal (const char* Format, ...)
|
||||||
/* Print a message about an internal compiler error and die. */
|
/* Print a message about an internal assembler error and die. */
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "Internal assembler error:\n");
|
SB_VPrintf (&S, Format, ap);
|
||||||
vfprintf (stderr, Format, ap);
|
SB_Terminate (&S);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
fprintf (stderr, "\n");
|
|
||||||
|
fprintf (stderr, "Internal assembler error: %s\n", SB_GetConstBuf (&S));
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
|
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -73,7 +73,7 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...) attr
|
|||||||
|
|
||||||
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Print an error message */
|
/* Print an error message */
|
||||||
|
|
||||||
void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
||||||
/* Print an error message giving an explicit file and position. */
|
/* Print an error message giving an explicit file and position. */
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ void Fatal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
|||||||
/* Print a message about a fatal error and die */
|
/* Print a message about a fatal error and die */
|
||||||
|
|
||||||
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
||||||
/* Print a message about an internal compiler error and die. */
|
/* Print a message about an internal assembler error and die. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -550,8 +550,8 @@ static ExprNode* FuncReferenced (void)
|
|||||||
static ExprNode* FuncSizeOf (void)
|
static ExprNode* FuncSizeOf (void)
|
||||||
/* Handle the .SIZEOF function */
|
/* Handle the .SIZEOF function */
|
||||||
{
|
{
|
||||||
StrBuf ScopeName = AUTO_STRBUF_INITIALIZER;
|
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
|
||||||
char Name[sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
SymTable* Scope;
|
SymTable* Scope;
|
||||||
SymEntry* Sym;
|
SymEntry* Sym;
|
||||||
SymEntry* SizeSym;
|
SymEntry* SizeSym;
|
||||||
@@ -566,27 +566,28 @@ static ExprNode* FuncSizeOf (void)
|
|||||||
if (Tok == TOK_LOCAL_IDENT) {
|
if (Tok == TOK_LOCAL_IDENT) {
|
||||||
|
|
||||||
/* Cheap local symbol */
|
/* Cheap local symbol */
|
||||||
Sym = SymFindLocal (SymLast, SVal, SYM_FIND_EXISTING);
|
Sym = SymFindLocal (SymLast, &SVal, SYM_FIND_EXISTING);
|
||||||
if (Sym == 0) {
|
if (Sym == 0) {
|
||||||
Error ("Unknown symbol or scope: `%s'", SVal);
|
Error ("Unknown symbol or scope: `%m%p'", &SVal);
|
||||||
} else {
|
} else {
|
||||||
SizeSym = GetSizeOfSymbol (Sym);
|
SizeSym = GetSizeOfSymbol (Sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember and skip SVal, terminate ScopeName so it is empty */
|
/* Remember and skip SVal, terminate ScopeName so it is empty */
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
SB_Terminate (&ScopeName);
|
SB_Terminate (&ScopeName);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Parse the scope and the name */
|
/* Parse the scope and the name */
|
||||||
SymTable* ParentScope = ParseScopedIdent (Name, &ScopeName);
|
SymTable* ParentScope = ParseScopedIdent (&Name, &ScopeName);
|
||||||
|
|
||||||
/* Check if the parent scope is valid */
|
/* Check if the parent scope is valid */
|
||||||
if (ParentScope == 0) {
|
if (ParentScope == 0) {
|
||||||
/* No such scope */
|
/* No such scope */
|
||||||
DoneStrBuf (&ScopeName);
|
SB_Done (&ScopeName);
|
||||||
|
SB_Done (&Name);
|
||||||
return GenLiteral0 ();
|
return GenLiteral0 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,9 +598,9 @@ static ExprNode* FuncSizeOf (void)
|
|||||||
|
|
||||||
/* First search for a scope with the given name */
|
/* First search for a scope with the given name */
|
||||||
if (NoScope) {
|
if (NoScope) {
|
||||||
Scope = SymFindAnyScope (ParentScope, Name);
|
Scope = SymFindAnyScope (ParentScope, &Name);
|
||||||
} else {
|
} else {
|
||||||
Scope = SymFindScope (ParentScope, Name, SYM_FIND_EXISTING);
|
Scope = SymFindScope (ParentScope, &Name, SYM_FIND_EXISTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we did find a scope with the name, read the symbol defining the
|
/* If we did find a scope with the name, read the symbol defining the
|
||||||
@@ -610,29 +611,30 @@ static ExprNode* FuncSizeOf (void)
|
|||||||
SizeSym = GetSizeOfScope (Scope);
|
SizeSym = GetSizeOfScope (Scope);
|
||||||
} else {
|
} else {
|
||||||
if (NoScope) {
|
if (NoScope) {
|
||||||
Sym = SymFindAny (ParentScope, Name);
|
Sym = SymFindAny (ParentScope, &Name);
|
||||||
} else {
|
} else {
|
||||||
Sym = SymFind (ParentScope, Name, SYM_FIND_EXISTING);
|
Sym = SymFind (ParentScope, &Name, SYM_FIND_EXISTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we found the symbol retrieve the size, otherwise complain */
|
/* If we found the symbol retrieve the size, otherwise complain */
|
||||||
if (Sym) {
|
if (Sym) {
|
||||||
SizeSym = GetSizeOfSymbol (Sym);
|
SizeSym = GetSizeOfSymbol (Sym);
|
||||||
} else {
|
} else {
|
||||||
Error ("Unknown symbol or scope: `%s%s'",
|
Error ("Unknown symbol or scope: `%m%p%m%p'",
|
||||||
SB_GetConstBuf (&ScopeName), Name);
|
&ScopeName, &Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have a size */
|
/* Check if we have a size */
|
||||||
if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) {
|
if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) {
|
||||||
Error ("Size of `%s%s' is unknown", SB_GetConstBuf (&ScopeName), Name);
|
Error ("Size of `%m%p%m%p' is unknown", &ScopeName, &Name);
|
||||||
Size = 0;
|
Size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the scope name */
|
/* Free the string buffers */
|
||||||
DoneStrBuf (&ScopeName);
|
SB_Done (&ScopeName);
|
||||||
|
SB_Done (&Name);
|
||||||
|
|
||||||
/* Return the size */
|
/* Return the size */
|
||||||
return GenLiteralExpr (Size);
|
return GenLiteralExpr (Size);
|
||||||
@@ -643,19 +645,19 @@ static ExprNode* FuncSizeOf (void)
|
|||||||
static ExprNode* FuncStrAt (void)
|
static ExprNode* FuncStrAt (void)
|
||||||
/* Handle the .STRAT function */
|
/* Handle the .STRAT function */
|
||||||
{
|
{
|
||||||
char Str [sizeof(SVal)];
|
StrBuf Str = STATIC_STRBUF_INITIALIZER;
|
||||||
long Index;
|
long Index;
|
||||||
unsigned char C;
|
unsigned char C = 0;
|
||||||
|
|
||||||
/* String constant expected */
|
/* String constant expected */
|
||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
Error ("String constant expected");
|
Error ("String constant expected");
|
||||||
NextTok ();
|
NextTok ();
|
||||||
return GenLiteral0 ();
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the string and skip it */
|
/* Remember the string and skip it */
|
||||||
strcpy (Str, SVal);
|
SB_Copy (&Str, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Comma must follow */
|
/* Comma must follow */
|
||||||
@@ -665,15 +667,19 @@ static ExprNode* FuncStrAt (void)
|
|||||||
Index = ConstExpression ();
|
Index = ConstExpression ();
|
||||||
|
|
||||||
/* Must be a valid index */
|
/* Must be a valid index */
|
||||||
if (Index >= (long) strlen (Str)) {
|
if (Index >= (long) SB_GetLen (&Str)) {
|
||||||
Error ("Range error");
|
Error ("Range error");
|
||||||
return GenLiteral0 ();
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the char, handle as unsigned. Be sure to translate it into
|
/* Get the char, handle as unsigned. Be sure to translate it into
|
||||||
* the target character set.
|
* the target character set.
|
||||||
*/
|
*/
|
||||||
C = TgtTranslateChar (Str [(size_t)Index]);
|
C = TgtTranslateChar (SB_At (&Str, (unsigned)Index));
|
||||||
|
|
||||||
|
ExitPoint:
|
||||||
|
/* Free string buffer memory */
|
||||||
|
SB_Done (&Str);
|
||||||
|
|
||||||
/* Return the char expression */
|
/* Return the char expression */
|
||||||
return GenLiteralExpr (C);
|
return GenLiteralExpr (C);
|
||||||
@@ -699,7 +705,7 @@ static ExprNode* FuncStrLen (void)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Get the length of the string */
|
/* Get the length of the string */
|
||||||
Len = strlen (SVal);
|
Len = SB_GetLen (&SVal);
|
||||||
|
|
||||||
/* Skip the string */
|
/* Skip the string */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -807,7 +813,7 @@ static ExprNode* Factor (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LOCAL_IDENT:
|
case TOK_LOCAL_IDENT:
|
||||||
N = Symbol (SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW));
|
N = Symbol (SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW));
|
||||||
NextTok ();
|
NextTok ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -948,9 +954,9 @@ static ExprNode* Factor (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (LooseCharTerm && Tok == TOK_STRCON && strlen(SVal) == 1) {
|
if (LooseCharTerm && Tok == TOK_STRCON && SB_GetLen (&SVal) == 1) {
|
||||||
/* A character constant */
|
/* A character constant */
|
||||||
N = GenLiteralExpr (TgtTranslateChar (SVal[0]));
|
N = GenLiteralExpr (TgtTranslateChar (SB_At (&SVal, 0)));
|
||||||
} else {
|
} else {
|
||||||
N = GenLiteral0 (); /* Dummy */
|
N = GenLiteral0 (); /* Dummy */
|
||||||
Error ("Syntax error");
|
Error ("Syntax error");
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2004 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -70,7 +70,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
feature_t FindFeature (const char* Key)
|
feature_t FindFeature (const StrBuf* Key)
|
||||||
/* Find the feature in a table and return the corresponding enum value. If the
|
/* Find the feature in a table and return the corresponding enum value. If the
|
||||||
* feature is invalid, return FEAT_UNKNOWN.
|
* feature is invalid, return FEAT_UNKNOWN.
|
||||||
*/
|
*/
|
||||||
@@ -79,7 +79,7 @@ feature_t FindFeature (const char* Key)
|
|||||||
|
|
||||||
/* This is not time critical, so do a linear search */
|
/* This is not time critical, so do a linear search */
|
||||||
for (F = (feature_t) 0; F < FEAT_COUNT; ++F) {
|
for (F = (feature_t) 0; F < FEAT_COUNT; ++F) {
|
||||||
if (strcmp (Key, FeatureKeys[F]) == 0) {
|
if (SB_CompareStr (Key, FeatureKeys[F]) == 0) {
|
||||||
/* Found, index is enum value */
|
/* Found, index is enum value */
|
||||||
return F;
|
return F;
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ feature_t FindFeature (const char* Key)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
feature_t SetFeature (const char* Key)
|
feature_t SetFeature (const StrBuf* Key)
|
||||||
/* Find the feature and set the corresponding flag if the feature is known.
|
/* Find the feature and set the corresponding flag if the feature is known.
|
||||||
* In any case, return the feature found. An invalid Key will return
|
* In any case, return the feature found. An invalid Key will return
|
||||||
* FEAT_UNKNOWN.
|
* FEAT_UNKNOWN.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -38,6 +38,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -70,12 +75,12 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
feature_t FindFeature (const char* Key);
|
feature_t FindFeature (const StrBuf* Key);
|
||||||
/* Find the feature in a table and return the corresponding enum value. If the
|
/* Find the feature in a table and return the corresponding enum value. If the
|
||||||
* feature is invalid, return FEAT_UNKNOWN.
|
* feature is invalid, return FEAT_UNKNOWN.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
feature_t SetFeature (const char* Key);
|
feature_t SetFeature (const StrBuf* Key);
|
||||||
/* Find the feature and set the corresponding flag if the feature is known.
|
/* Find the feature and set the corresponding flag if the feature is known.
|
||||||
* In any case, return the feature found. An invalid Key will return
|
* In any case, return the feature found. An invalid Key will return
|
||||||
* FEAT_UNKNOWN.
|
* FEAT_UNKNOWN.
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -180,9 +180,11 @@ static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetFileName (unsigned Name)
|
const StrBuf* GetFileName (unsigned Name)
|
||||||
/* Get the name of a file where the name index is known */
|
/* Get the name of a file where the name index is known */
|
||||||
{
|
{
|
||||||
|
static StrBuf ErrorMsg = LIT_STRBUF_INITIALIZER ("(outside file scope)");
|
||||||
|
|
||||||
const FileEntry* F;
|
const FileEntry* F;
|
||||||
|
|
||||||
if (Name == 0) {
|
if (Name == 0) {
|
||||||
@@ -192,30 +194,30 @@ const char* GetFileName (unsigned Name)
|
|||||||
*/
|
*/
|
||||||
if (CollCount (&FileTab) == 0) {
|
if (CollCount (&FileTab) == 0) {
|
||||||
/* No files defined until now */
|
/* No files defined until now */
|
||||||
return "(outside file scope)";
|
return &ErrorMsg;
|
||||||
} else {
|
} else {
|
||||||
F = CollConstAt (&FileTab, 0);
|
F = CollConstAt (&FileTab, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
F = CollConstAt (&FileTab, Name-1);
|
F = CollConstAt (&FileTab, Name-1);
|
||||||
}
|
}
|
||||||
return GetString (F->Name);
|
return GetStrBuf (F->Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetFileIndex (const char* Name)
|
unsigned GetFileIndex (const StrBuf* Name)
|
||||||
/* Return the file index for the given file name. */
|
/* Return the file index for the given file name. */
|
||||||
{
|
{
|
||||||
/* Get the string pool index from the name */
|
/* Get the string pool index from the name */
|
||||||
unsigned NameIdx = GetStringId (Name);
|
unsigned NameIdx = GetStrBufId (Name);
|
||||||
|
|
||||||
/* Search in the hash table for the name */
|
/* Search in the hash table for the name */
|
||||||
FileEntry* F = HT_FindEntry (&HashTab, &NameIdx);
|
FileEntry* F = HT_FindEntry (&HashTab, &NameIdx);
|
||||||
|
|
||||||
/* If we don't have this index, print a diagnostic and use the main file */
|
/* If we don't have this index, print a diagnostic and use the main file */
|
||||||
if (F == 0) {
|
if (F == 0) {
|
||||||
Error ("File name `%s' not found in file table", Name);
|
Error ("File name `%m%p' not found in file table", Name);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return F->Index;
|
return F->Index;
|
||||||
@@ -224,13 +226,13 @@ unsigned GetFileIndex (const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime)
|
unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime)
|
||||||
/* Add a new file to the list of input files. Return the index of the file in
|
/* Add a new file to the list of input files. Return the index of the file in
|
||||||
* the table.
|
* the table.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Create a new file entry and insert it into the tables */
|
/* Create a new file entry and insert it into the tables */
|
||||||
FileEntry* F = NewFileEntry (GetStringId (Name), Size, MTime);
|
FileEntry* F = NewFileEntry (GetStrBufId (Name), Size, MTime);
|
||||||
|
|
||||||
/* Return the index */
|
/* Return the index */
|
||||||
return F->Index;
|
return F->Index;
|
||||||
@@ -265,4 +267,4 @@ void WriteFiles (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -38,19 +38,24 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetFileName (unsigned Name);
|
const StrBuf* GetFileName (unsigned Name);
|
||||||
/* Get the name of a file where the name index is known */
|
/* Get the name of a file where the name index is known */
|
||||||
|
|
||||||
unsigned GetFileIndex (const char* Name);
|
unsigned GetFileIndex (const StrBuf* Name);
|
||||||
/* Return the file index for the given file name. */
|
/* Return the file index for the given file name. */
|
||||||
|
|
||||||
unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime);
|
unsigned AddFile (const StrBuf* Name, unsigned long Size, unsigned long MTime);
|
||||||
/* Add a new file to the list of input files. Return the index of the file in
|
/* Add a new file to the list of input files. Return the index of the file in
|
||||||
* the table.
|
* the table.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2006, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -1453,7 +1453,7 @@ cpu_t GetCPU (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int FindInstruction (const char* Ident)
|
int FindInstruction (const StrBuf* Ident)
|
||||||
/* Check if Ident is a valid mnemonic. If so, return the index in the
|
/* Check if Ident is a valid mnemonic. If so, return the index in the
|
||||||
* instruction table. If not, return -1.
|
* instruction table. If not, return -1.
|
||||||
*/
|
*/
|
||||||
@@ -1472,7 +1472,7 @@ int FindInstruction (const char* Ident)
|
|||||||
|
|
||||||
/* Make a copy, and uppercase that copy */
|
/* Make a copy, and uppercase that copy */
|
||||||
I = 0;
|
I = 0;
|
||||||
while (Ident[I] != '\0') {
|
while (I < SB_GetLen (Ident)) {
|
||||||
/* If the identifier is longer than the longest mnemonic, it cannot
|
/* If the identifier is longer than the longest mnemonic, it cannot
|
||||||
* be one.
|
* be one.
|
||||||
*/
|
*/
|
||||||
@@ -1480,7 +1480,7 @@ int FindInstruction (const char* Ident)
|
|||||||
/* Not found, no need for further action */
|
/* Not found, no need for further action */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Key[I] = toupper ((unsigned char)Ident[I]);
|
Key[I] = toupper ((unsigned char)SB_AtUnchecked (Ident, I));
|
||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
Key[I] = '\0';
|
Key[I] = '\0';
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* instr.h */
|
/* instr.h */
|
||||||
/* */
|
/* */
|
||||||
/* Instruction encoding for the ca65 macroassembler */
|
/* Instruction encoding for the ca65 macroassembler */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2005, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +153,7 @@ void SetCPU (cpu_t NewCPU);
|
|||||||
cpu_t GetCPU (void);
|
cpu_t GetCPU (void);
|
||||||
/* Return the current CPU */
|
/* Return the current CPU */
|
||||||
|
|
||||||
int FindInstruction (const char* Ident);
|
int FindInstruction (const StrBuf* Ident);
|
||||||
/* Check if Ident is a valid mnemonic. If so, return the index in the
|
/* Check if Ident is a valid mnemonic. If so, return the index in the
|
||||||
* instruction table. If not, return -1.
|
* instruction table. If not, return -1.
|
||||||
*/
|
*/
|
||||||
@@ -169,3 +170,4 @@ void HandleInstruction (unsigned Index);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -218,17 +218,20 @@ static void PrintPageHeader (FILE* F, const ListLine* L)
|
|||||||
/* Print the header for a new page. It is assumed that the given line is the
|
/* Print the header for a new page. It is assumed that the given line is the
|
||||||
* last line of the previous page.
|
* last line of the previous page.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
/* Gte a pointer to the current input file */
|
||||||
|
const StrBuf* CurFile = GetFileName (L->File);
|
||||||
|
|
||||||
/* Print the header on the new page */
|
/* Print the header on the new page */
|
||||||
fprintf (F,
|
fprintf (F,
|
||||||
"ca65 V%u.%u.%u - %s\n"
|
"ca65 V%u.%u.%u - %s\n"
|
||||||
"Main file : %s\n"
|
"Main file : %s\n"
|
||||||
"Current file: %s\n"
|
"Current file: %.*s\n"
|
||||||
"\n",
|
"\n",
|
||||||
VER_MAJOR, VER_MINOR, VER_PATCH,
|
VER_MAJOR, VER_MINOR, VER_PATCH,
|
||||||
Copyright,
|
Copyright,
|
||||||
InFile,
|
InFile,
|
||||||
GetFileName (L->File));
|
SB_GetLen (CurFile), SB_GetConstBuf (CurFile));
|
||||||
|
|
||||||
/* Count pages, reset lines */
|
/* Count pages, reset lines */
|
||||||
++PageNumber;
|
++PageNumber;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2005, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -82,7 +82,7 @@ static StrBuf MacPackDir = STATIC_STRBUF_INITIALIZER;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int MacPackFind (const char* Name)
|
int MacPackFind (const StrBuf* Name)
|
||||||
/* Find a macro package by name. The function will either return the id or
|
/* Find a macro package by name. The function will either return the id or
|
||||||
* -1 if the package name was not found.
|
* -1 if the package name was not found.
|
||||||
*/
|
*/
|
||||||
@@ -90,7 +90,7 @@ int MacPackFind (const char* Name)
|
|||||||
int I;
|
int I;
|
||||||
|
|
||||||
for (I = 0; I < MAC_COUNT; ++I) {
|
for (I = 0; I < MAC_COUNT; ++I) {
|
||||||
if (StrCaseCmp (Name, MacPackages[I].Name) == 0) {
|
if (SB_CompareStr (Name, MacPackages[I].Name) == 0) {
|
||||||
/* Found */
|
/* Found */
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
@@ -130,21 +130,21 @@ void MacPackInsert (int Id)
|
|||||||
NewInputFile (SB_GetConstBuf (&Filename));
|
NewInputFile (SB_GetConstBuf (&Filename));
|
||||||
|
|
||||||
/* Destroy the contents of Filename */
|
/* Destroy the contents of Filename */
|
||||||
DoneStrBuf (&Filename);
|
SB_Done (&Filename);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void MacPackSetDir (const char* Dir)
|
void MacPackSetDir (const StrBuf* Dir)
|
||||||
/* Set a directory where files for macro packages can be found. Standard is
|
/* Set a directory where files for macro packages can be found. Standard is
|
||||||
* to use the builtin packages. For debugging macro packages, external files
|
* to use the builtin packages. For debugging macro packages, external files
|
||||||
* can be used.
|
* can be used.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Copy the directory name to the buffer */
|
/* Copy the directory name to the buffer */
|
||||||
SB_CopyStr (&MacPackDir, Dir);
|
SB_Copy (&MacPackDir, Dir);
|
||||||
|
|
||||||
/* Make sure that the last character is a path delimiter */
|
/* Make sure that the last character is a path delimiter */
|
||||||
if (SB_NotEmpty (&MacPackDir)) {
|
if (SB_NotEmpty (&MacPackDir)) {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2005, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -38,6 +38,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -64,7 +69,7 @@ enum {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int MacPackFind (const char* Name);
|
int MacPackFind (const StrBuf* Name);
|
||||||
/* Find a macro package by name. The function will either return the id or
|
/* Find a macro package by name. The function will either return the id or
|
||||||
* -1 if the package name was not found.
|
* -1 if the package name was not found.
|
||||||
*/
|
*/
|
||||||
@@ -72,7 +77,7 @@ int MacPackFind (const char* Name);
|
|||||||
void MacPackInsert (int Id);
|
void MacPackInsert (int Id);
|
||||||
/* Insert the macro package with the given id in the input stream */
|
/* Insert the macro package with the given id in the input stream */
|
||||||
|
|
||||||
void MacPackSetDir (const char* Dir);
|
void MacPackSetDir (const StrBuf* Dir);
|
||||||
/* Set a directory where files for macro packages can be found. Standard is
|
/* Set a directory where files for macro packages can be found. Standard is
|
||||||
* to use the builtin packages. For debugging macro packages, external files
|
* to use the builtin packages. For debugging macro packages, external files
|
||||||
* can be used.
|
* can be used.
|
||||||
|
|||||||
122
src/ca65/macro.c
122
src/ca65/macro.c
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -88,7 +88,7 @@ static int HT_Compare (const void* Key1, const void* Key2);
|
|||||||
typedef struct IdDesc IdDesc;
|
typedef struct IdDesc IdDesc;
|
||||||
struct IdDesc {
|
struct IdDesc {
|
||||||
IdDesc* Next; /* Linked list */
|
IdDesc* Next; /* Linked list */
|
||||||
char Id [1]; /* Identifier, dynamically allocated */
|
StrBuf Id; /* Identifier, dynamically allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ struct Macro {
|
|||||||
TokNode* TokRoot; /* Root of token list */
|
TokNode* TokRoot; /* Root of token list */
|
||||||
TokNode* TokLast; /* Pointer to last token in list */
|
TokNode* TokLast; /* Pointer to last token in list */
|
||||||
unsigned char Style; /* Macro style */
|
unsigned char Style; /* Macro style */
|
||||||
char Name [1]; /* Macro name, dynamically allocated */
|
StrBuf Name; /* Macro name, dynamically allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Hash table functions */
|
/* Hash table functions */
|
||||||
@@ -157,7 +157,7 @@ static unsigned LocalName = 0;
|
|||||||
static unsigned HT_GenHash (const void* Key)
|
static unsigned HT_GenHash (const void* Key)
|
||||||
/* Generate the hash over a key. */
|
/* Generate the hash over a key. */
|
||||||
{
|
{
|
||||||
return HashStr (Key);
|
return HashBuf (Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ static unsigned HT_GenHash (const void* Key)
|
|||||||
static const void* HT_GetKey (void* Entry)
|
static const void* HT_GetKey (void* Entry)
|
||||||
/* Given a pointer to the user entry data, return a pointer to the index */
|
/* Given a pointer to the user entry data, return a pointer to the index */
|
||||||
{
|
{
|
||||||
return ((Macro*) Entry)->Name;
|
return &((Macro*) Entry)->Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ static int HT_Compare (const void* Key1, const void* Key2)
|
|||||||
* than zero if Key1 is greater then Key2.
|
* than zero if Key1 is greater then Key2.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return strcmp (Key1, Key2);
|
return SB_Compare (Key1, Key2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -195,17 +195,16 @@ static int HT_Compare (const void* Key1, const void* Key2)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static IdDesc* NewIdDesc (const char* Id)
|
static IdDesc* NewIdDesc (const StrBuf* Id)
|
||||||
/* Create a new IdDesc, initialize and return it */
|
/* Create a new IdDesc, initialize and return it */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
unsigned Len = strlen (Id);
|
IdDesc* I = xmalloc (sizeof (IdDesc));
|
||||||
IdDesc* I = xmalloc (sizeof (IdDesc) + Len);
|
|
||||||
|
|
||||||
/* Initialize the struct */
|
/* Initialize the struct */
|
||||||
I->Next = 0;
|
I->Next = 0;
|
||||||
memcpy (I->Id, Id, Len);
|
I->Id = AUTO_STRBUF_INITIALIZER;
|
||||||
I->Id [Len] = '\0';
|
SB_Copy (&I->Id, Id);
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return I;
|
return I;
|
||||||
@@ -213,12 +212,11 @@ static IdDesc* NewIdDesc (const char* Id)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Macro* NewMacro (const char* Name, unsigned char Style)
|
static Macro* NewMacro (const StrBuf* Name, unsigned char Style)
|
||||||
/* Generate a new macro entry, initialize and return it */
|
/* Generate a new macro entry, initialize and return it */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
unsigned Len = strlen (Name);
|
Macro* M = xmalloc (sizeof (Macro));
|
||||||
Macro* M = xmalloc (sizeof (Macro) + Len);
|
|
||||||
|
|
||||||
/* Initialize the macro struct */
|
/* Initialize the macro struct */
|
||||||
InitHashNode (&M->Node, M);
|
InitHashNode (&M->Node, M);
|
||||||
@@ -230,7 +228,8 @@ static Macro* NewMacro (const char* Name, unsigned char Style)
|
|||||||
M->TokRoot = 0;
|
M->TokRoot = 0;
|
||||||
M->TokLast = 0;
|
M->TokLast = 0;
|
||||||
M->Style = Style;
|
M->Style = Style;
|
||||||
memcpy (M->Name, Name, Len+1);
|
M->Name = AUTO_STRBUF_INITIALIZER;
|
||||||
|
SB_Copy (&M->Name, Name);
|
||||||
|
|
||||||
/* Insert the macro into the global macro list */
|
/* Insert the macro into the global macro list */
|
||||||
M->List = MacroRoot;
|
M->List = MacroRoot;
|
||||||
@@ -340,7 +339,7 @@ void MacDef (unsigned Style)
|
|||||||
Error ("Identifier expected");
|
Error ("Identifier expected");
|
||||||
MacSkipDef (Style);
|
MacSkipDef (Style);
|
||||||
return;
|
return;
|
||||||
} else if (!UbiquitousIdents && FindInstruction (SVal) >= 0) {
|
} else if (!UbiquitousIdents && FindInstruction (&SVal) >= 0) {
|
||||||
/* The identifier is a name of a 6502 instruction, which is not
|
/* The identifier is a name of a 6502 instruction, which is not
|
||||||
* allowed if not explicitly enabled.
|
* allowed if not explicitly enabled.
|
||||||
*/
|
*/
|
||||||
@@ -350,16 +349,16 @@ void MacDef (unsigned Style)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Did we already define that macro? */
|
/* Did we already define that macro? */
|
||||||
if (HT_Find (&MacroTab, SVal) != 0) {
|
if (HT_Find (&MacroTab, &SVal) != 0) {
|
||||||
/* Macro is already defined */
|
/* Macro is already defined */
|
||||||
Error ("A macro named `%s' is already defined", SVal);
|
Error ("A macro named `%m%p' is already defined", &SVal);
|
||||||
/* Skip tokens until we reach the final .endmacro */
|
/* Skip tokens until we reach the final .endmacro */
|
||||||
MacSkipDef (Style);
|
MacSkipDef (Style);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define the macro */
|
/* Define the macro */
|
||||||
M = NewMacro (SVal, Style);
|
M = NewMacro (&SVal, Style);
|
||||||
|
|
||||||
/* Switch to raw token mode and skip the macro name */
|
/* Switch to raw token mode and skip the macro name */
|
||||||
EnterRawTokenMode ();
|
EnterRawTokenMode ();
|
||||||
@@ -369,45 +368,45 @@ void MacDef (unsigned Style)
|
|||||||
* otherwise we may have parameters without braces.
|
* otherwise we may have parameters without braces.
|
||||||
*/
|
*/
|
||||||
if (Style == MAC_STYLE_CLASSIC) {
|
if (Style == MAC_STYLE_CLASSIC) {
|
||||||
HaveParams = 1;
|
HaveParams = 1;
|
||||||
} else {
|
} else {
|
||||||
if (Tok == TOK_LPAREN) {
|
if (Tok == TOK_LPAREN) {
|
||||||
HaveParams = 1;
|
HaveParams = 1;
|
||||||
NextTok ();
|
NextTok ();
|
||||||
} else {
|
} else {
|
||||||
HaveParams = 0;
|
HaveParams = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the parameter list */
|
/* Parse the parameter list */
|
||||||
if (HaveParams) {
|
if (HaveParams) {
|
||||||
|
|
||||||
while (Tok == TOK_IDENT) {
|
while (Tok == TOK_IDENT) {
|
||||||
|
|
||||||
/* Create a struct holding the identifier */
|
/* Create a struct holding the identifier */
|
||||||
IdDesc* I = NewIdDesc (SVal);
|
IdDesc* I = NewIdDesc (&SVal);
|
||||||
|
|
||||||
/* Insert the struct into the list, checking for duplicate idents */
|
/* Insert the struct into the list, checking for duplicate idents */
|
||||||
if (M->ParamCount == 0) {
|
if (M->ParamCount == 0) {
|
||||||
M->Params = I;
|
M->Params = I;
|
||||||
} else {
|
} else {
|
||||||
IdDesc* List = M->Params;
|
IdDesc* List = M->Params;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (strcmp (List->Id, SVal) == 0) {
|
if (SB_Compare (&List->Id, &SVal) == 0) {
|
||||||
Error ("Duplicate symbol `%s'", SVal);
|
Error ("Duplicate symbol `%m%p'", &SVal);
|
||||||
}
|
}
|
||||||
if (List->Next == 0) {
|
if (List->Next == 0) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
List = List->Next;
|
List = List->Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List->Next = I;
|
List->Next = I;
|
||||||
}
|
}
|
||||||
++M->ParamCount;
|
++M->ParamCount;
|
||||||
|
|
||||||
/* Skip the name */
|
/* Skip the name */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Maybe there are more params... */
|
/* Maybe there are more params... */
|
||||||
if (Tok == TOK_COMMA) {
|
if (Tok == TOK_COMMA) {
|
||||||
@@ -471,7 +470,7 @@ void MacDef (unsigned Style)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Put the identifier into the locals list and skip it */
|
/* Put the identifier into the locals list and skip it */
|
||||||
I = NewIdDesc (SVal);
|
I = NewIdDesc (&SVal);
|
||||||
I->Next = M->Locals;
|
I->Next = M->Locals;
|
||||||
M->Locals = I;
|
M->Locals = I;
|
||||||
++M->LocalCount;
|
++M->LocalCount;
|
||||||
@@ -497,7 +496,7 @@ void MacDef (unsigned Style)
|
|||||||
unsigned Count = 0;
|
unsigned Count = 0;
|
||||||
IdDesc* I = M->Params;
|
IdDesc* I = M->Params;
|
||||||
while (I) {
|
while (I) {
|
||||||
if (strcmp (I->Id, SVal) == 0) {
|
if (SB_Compare (&I->Id, &SVal) == 0) {
|
||||||
/* Local param name, replace it */
|
/* Local param name, replace it */
|
||||||
T->Tok = TOK_MACPARAM;
|
T->Tok = TOK_MACPARAM;
|
||||||
T->IVal = Count;
|
T->IVal = Count;
|
||||||
@@ -607,15 +606,21 @@ static int MacExpand (void* Data)
|
|||||||
unsigned Index = 0;
|
unsigned Index = 0;
|
||||||
IdDesc* I = Mac->M->Locals;
|
IdDesc* I = Mac->M->Locals;
|
||||||
while (I) {
|
while (I) {
|
||||||
if (strcmp (SVal, I->Id) == 0) {
|
if (SB_Compare (&SVal, &I->Id) == 0) {
|
||||||
/* This is in fact a local symbol, change the name. Be sure
|
/* This is in fact a local symbol, change the name. Be sure
|
||||||
* to generate a local label name if the original name was
|
* to generate a local label name if the original name was
|
||||||
* a local label, and also generate a name that cannot be
|
* a local label, and also generate a name that cannot be
|
||||||
* generated by a user.
|
* generated by a user.
|
||||||
*/
|
*/
|
||||||
unsigned PrefixLen = (I->Id[0] == LocalStart);
|
if (SB_At (&I->Id, 0) == LocalStart) {
|
||||||
sprintf (SVal, "%.*sLOCAL-MACRO-SYMBOL-%04X", PrefixLen,
|
/* Must generate a local symbol */
|
||||||
I->Id, Mac->LocalStart + Index);
|
SB_Printf (&SVal, "%cLOCAL-MACRO_SYMBOL-%04X",
|
||||||
|
LocalStart, Mac->LocalStart + Index);
|
||||||
|
} else {
|
||||||
|
/* Global symbol */
|
||||||
|
SB_Printf (&SVal, "LOCAL-MACRO_SYMBOL-%04X",
|
||||||
|
Mac->LocalStart + Index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Next symbol */
|
/* Next symbol */
|
||||||
@@ -836,7 +841,7 @@ void MacExpandStart (void)
|
|||||||
/* Start expanding the macro in SVal */
|
/* Start expanding the macro in SVal */
|
||||||
{
|
{
|
||||||
/* Search for the macro */
|
/* Search for the macro */
|
||||||
Macro* M = HT_FindEntry (&MacroTab, SVal);
|
Macro* M = HT_FindEntry (&MacroTab, &SVal);
|
||||||
CHECK (M != 0);
|
CHECK (M != 0);
|
||||||
|
|
||||||
/* Call the apropriate subroutine */
|
/* Call the apropriate subroutine */
|
||||||
@@ -861,7 +866,7 @@ void MacAbort (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsMacro (const char* Name)
|
int IsMacro (const StrBuf* Name)
|
||||||
/* Return true if the given name is the name of a macro */
|
/* Return true if the given name is the name of a macro */
|
||||||
{
|
{
|
||||||
return (HT_Find (&MacroTab, Name) != 0);
|
return (HT_Find (&MacroTab, Name) != 0);
|
||||||
@@ -869,7 +874,7 @@ int IsMacro (const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsDefine (const char* Name)
|
int IsDefine (const StrBuf* Name)
|
||||||
/* Return true if the given name is the name of a define style macro */
|
/* Return true if the given name is the name of a define style macro */
|
||||||
{
|
{
|
||||||
Macro* M = HT_FindEntry (&MacroTab, Name);
|
Macro* M = HT_FindEntry (&MacroTab, Name);
|
||||||
@@ -886,6 +891,3 @@ int InMacExpansion (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -65,10 +65,10 @@ void MacExpandStart (void);
|
|||||||
void MacAbort (void);
|
void MacAbort (void);
|
||||||
/* Abort the current macro expansion */
|
/* Abort the current macro expansion */
|
||||||
|
|
||||||
int IsMacro (const char* Name);
|
int IsMacro (const StrBuf* Name);
|
||||||
/* Return true if the given name is the name of a macro */
|
/* Return true if the given name is the name of a macro */
|
||||||
|
|
||||||
int IsDefine (const char* Name);
|
int IsDefine (const StrBuf* Name);
|
||||||
/* Return true if the given name is the name of a define style macro */
|
/* Return true if the given name is the name of a define style macro */
|
||||||
|
|
||||||
int InMacExpansion (void);
|
int InMacExpansion (void);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
#include "mmodel.h"
|
#include "mmodel.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
#include "strbuf.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "tgttrans.h"
|
#include "tgttrans.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@@ -127,14 +128,17 @@ static void Usage (void)
|
|||||||
static void SetOptions (void)
|
static void SetOptions (void)
|
||||||
/* Set the option for the translator */
|
/* Set the option for the translator */
|
||||||
{
|
{
|
||||||
char Buf [256];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Set the translator */
|
/* Set the translator */
|
||||||
sprintf (Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
|
SB_Printf (&Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||||
OptTranslator (Buf);
|
OptTranslator (&Buf);
|
||||||
|
|
||||||
/* Set date and time */
|
/* Set date and time */
|
||||||
OptDateTime ((unsigned long) time(0));
|
OptDateTime ((unsigned long) time(0));
|
||||||
|
|
||||||
|
/* Release memory for the string */
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -144,8 +148,12 @@ static void NewSymbol (const char* SymName, long Val)
|
|||||||
{
|
{
|
||||||
ExprNode* Expr;
|
ExprNode* Expr;
|
||||||
|
|
||||||
|
/* Convert the name to a string buffer */
|
||||||
|
StrBuf SymBuf = STATIC_STRBUF_INITIALIZER;
|
||||||
|
SB_CopyStr (&SymBuf, SymName);
|
||||||
|
|
||||||
/* Search for the symbol, allocate a new one if it doesn't exist */
|
/* Search for the symbol, allocate a new one if it doesn't exist */
|
||||||
SymEntry* Sym = SymFind (CurrentScope, SymName, SYM_ALLOC_NEW);
|
SymEntry* Sym = SymFind (CurrentScope, &SymBuf, SYM_ALLOC_NEW);
|
||||||
|
|
||||||
/* Check if have already a symbol with this name */
|
/* Check if have already a symbol with this name */
|
||||||
if (SymIsDef (Sym)) {
|
if (SymIsDef (Sym)) {
|
||||||
@@ -157,6 +165,9 @@ static void NewSymbol (const char* SymName, long Val)
|
|||||||
|
|
||||||
/* Mark the symbol as defined */
|
/* Mark the symbol as defined */
|
||||||
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE);
|
SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE);
|
||||||
|
|
||||||
|
/* Free string buffer memory */
|
||||||
|
SB_Done (&SymBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -276,24 +287,21 @@ static void DefineSymbol (const char* Def)
|
|||||||
const char* P;
|
const char* P;
|
||||||
unsigned I;
|
unsigned I;
|
||||||
long Val;
|
long Val;
|
||||||
char SymName [MAX_STR_LEN+1];
|
StrBuf SymName = AUTO_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
/* The symbol must start with a character or underline */
|
/* The symbol must start with a character or underline */
|
||||||
if (Def [0] != '_' && !IsAlpha (Def [0])) {
|
if (!IsIdStart (Def [0])) {
|
||||||
InvDef (Def);
|
InvDef (Def);
|
||||||
}
|
}
|
||||||
P = Def;
|
P = Def;
|
||||||
|
|
||||||
/* Copy the symbol, checking the rest */
|
/* Copy the symbol, checking the rest */
|
||||||
I = 0;
|
I = 0;
|
||||||
while (IsAlNum (*P) || *P == '_') {
|
while (IsIdChar (*P)) {
|
||||||
if (I <= MAX_STR_LEN) {
|
SB_AppendChar (&SymName, *P++);
|
||||||
SymName [I++] = *P;
|
|
||||||
}
|
|
||||||
++P;
|
|
||||||
}
|
}
|
||||||
SymName [I] = '\0';
|
SB_Terminate (&SymName);
|
||||||
|
|
||||||
/* Do we have a value given? */
|
/* Do we have a value given? */
|
||||||
if (*P != '=') {
|
if (*P != '=') {
|
||||||
@@ -317,7 +325,10 @@ static void DefineSymbol (const char* Def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Define the new symbol */
|
/* Define the new symbol */
|
||||||
NewSymbol (SymName, Val);
|
NewSymbol (SB_GetConstBuf (&SymName), Val);
|
||||||
|
|
||||||
|
/* Release string memory */
|
||||||
|
SB_Done (&SymName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -356,8 +367,11 @@ static void OptDebugInfo (const char* Opt attribute ((unused)),
|
|||||||
static void OptFeature (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptFeature (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Set an emulation feature */
|
/* Set an emulation feature */
|
||||||
{
|
{
|
||||||
|
/* Make a string buffer from Arg */
|
||||||
|
StrBuf Feature;
|
||||||
|
|
||||||
/* Set the feature, check for errors */
|
/* Set the feature, check for errors */
|
||||||
if (SetFeature (Arg) == FEAT_UNKNOWN) {
|
if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) {
|
||||||
AbEnd ("Illegal emulation feature: `%s'", Arg);
|
AbEnd ("Illegal emulation feature: `%s'", Arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -425,8 +439,11 @@ static void OptListing (const char* Opt attribute ((unused)),
|
|||||||
static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Set a macro package directory */
|
/* Set a macro package directory */
|
||||||
{
|
{
|
||||||
|
/* Make a string buffer from Arg */
|
||||||
|
StrBuf Dir;
|
||||||
|
|
||||||
/* Use the directory */
|
/* Use the directory */
|
||||||
MacPackSetDir (Arg);
|
MacPackSetDir (SB_InitFromString (&Dir, Arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -545,13 +562,13 @@ static void OneLine (void)
|
|||||||
if (Tok == TOK_IDENT) {
|
if (Tok == TOK_IDENT) {
|
||||||
if (!UbiquitousIdents) {
|
if (!UbiquitousIdents) {
|
||||||
/* Macros and symbols cannot use instruction names */
|
/* Macros and symbols cannot use instruction names */
|
||||||
Instr = FindInstruction (SVal);
|
Instr = FindInstruction (&SVal);
|
||||||
if (Instr < 0) {
|
if (Instr < 0) {
|
||||||
Macro = IsMacro (SVal);
|
Macro = IsMacro (&SVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Macros and symbols may use the names of instructions */
|
/* Macros and symbols may use the names of instructions */
|
||||||
Macro = IsMacro (SVal);
|
Macro = IsMacro (&SVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,9 +580,9 @@ static void OneLine (void)
|
|||||||
|
|
||||||
/* Generate the symbol table entry, then skip the name */
|
/* Generate the symbol table entry, then skip the name */
|
||||||
if (Tok == TOK_IDENT) {
|
if (Tok == TOK_IDENT) {
|
||||||
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
|
Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
|
||||||
} else {
|
} else {
|
||||||
Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW);
|
Sym = SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW);
|
||||||
}
|
}
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
@@ -640,13 +657,13 @@ static void OneLine (void)
|
|||||||
if (Tok == TOK_IDENT) {
|
if (Tok == TOK_IDENT) {
|
||||||
if (!UbiquitousIdents) {
|
if (!UbiquitousIdents) {
|
||||||
/* Macros and symbols cannot use instruction names */
|
/* Macros and symbols cannot use instruction names */
|
||||||
Instr = FindInstruction (SVal);
|
Instr = FindInstruction (&SVal);
|
||||||
if (Instr < 0) {
|
if (Instr < 0) {
|
||||||
Macro = IsMacro (SVal);
|
Macro = IsMacro (&SVal);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Macros and symbols may use the names of instructions */
|
/* Macros and symbols may use the names of instructions */
|
||||||
Macro = IsMacro (SVal);
|
Macro = IsMacro (&SVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -660,7 +677,7 @@ static void OneLine (void)
|
|||||||
/* A macro expansion */
|
/* A macro expansion */
|
||||||
MacExpandStart ();
|
MacExpandStart ();
|
||||||
} else if (Instr >= 0 ||
|
} else if (Instr >= 0 ||
|
||||||
(UbiquitousIdents && ((Instr = FindInstruction (SVal)) >= 0))) {
|
(UbiquitousIdents && ((Instr = FindInstruction (&SVal)) >= 0))) {
|
||||||
/* A mnemonic - assemble one instruction */
|
/* A mnemonic - assemble one instruction */
|
||||||
HandleInstruction (Instr);
|
HandleInstruction (Instr);
|
||||||
} else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) {
|
} else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) {
|
||||||
@@ -774,6 +791,9 @@ int main (int argc, char* argv [])
|
|||||||
{ "--version", 0, OptVersion },
|
{ "--version", 0, OptVersion },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Name of the global name space */
|
||||||
|
static const StrBuf GlobalNameSpace = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Initialize the cmdline module */
|
/* Initialize the cmdline module */
|
||||||
@@ -782,7 +802,7 @@ int main (int argc, char* argv [])
|
|||||||
/* Enter the base lexical level. We must do that here, since we may
|
/* Enter the base lexical level. We must do that here, since we may
|
||||||
* define symbols using -D.
|
* define symbols using -D.
|
||||||
*/
|
*/
|
||||||
SymEnterLevel ("", ST_GLOBAL, ADDR_SIZE_DEFAULT);
|
SymEnterLevel (&GlobalNameSpace, ST_GLOBAL, ADDR_SIZE_DEFAULT);
|
||||||
|
|
||||||
/* Check the parameters */
|
/* Check the parameters */
|
||||||
I = 1;
|
I = 1;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -142,10 +142,7 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
|
|||||||
static void FuncConcat (void)
|
static void FuncConcat (void)
|
||||||
/* Handle the .CONCAT function */
|
/* Handle the .CONCAT function */
|
||||||
{
|
{
|
||||||
char Buf[MAX_STR_LEN+1];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
char* B;
|
|
||||||
unsigned Length;
|
|
||||||
unsigned L;
|
|
||||||
|
|
||||||
/* Skip it */
|
/* Skip it */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -154,29 +151,16 @@ static void FuncConcat (void)
|
|||||||
ConsumeLParen ();
|
ConsumeLParen ();
|
||||||
|
|
||||||
/* Concatenate any number of strings */
|
/* Concatenate any number of strings */
|
||||||
B = Buf;
|
|
||||||
B[0] = '\0';
|
|
||||||
Length = 0;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Next token must be a string */
|
/* Next token must be a string */
|
||||||
if (!LookAtStrCon ()) {
|
if (!LookAtStrCon ()) {
|
||||||
|
SB_Done (&Buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the length of the string const and check total length */
|
/* Append the string */
|
||||||
L = strlen (SVal);
|
SB_Append (&Buf, &SVal);
|
||||||
if (Length + L > MAX_STR_LEN) {
|
|
||||||
Error ("String is too long");
|
|
||||||
/* Try to recover */
|
|
||||||
SkipUntilSep ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the new string */
|
|
||||||
memcpy (B, SVal, L);
|
|
||||||
Length += L;
|
|
||||||
B += L;
|
|
||||||
|
|
||||||
/* Skip the string token */
|
/* Skip the string token */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -190,9 +174,6 @@ static void FuncConcat (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the string */
|
|
||||||
*B = '\0';
|
|
||||||
|
|
||||||
/* We expect a closing parenthesis, but will not skip it but replace it
|
/* We expect a closing parenthesis, but will not skip it but replace it
|
||||||
* by the string token just created.
|
* by the string token just created.
|
||||||
*/
|
*/
|
||||||
@@ -200,8 +181,11 @@ static void FuncConcat (void)
|
|||||||
Error ("`)' expected");
|
Error ("`)' expected");
|
||||||
} else {
|
} else {
|
||||||
Tok = TOK_STRCON;
|
Tok = TOK_STRCON;
|
||||||
strcpy (SVal, Buf);
|
SB_Copy (&SVal, &Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free the string buffer */
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -218,9 +202,8 @@ static void NoIdent (void)
|
|||||||
static void FuncIdent (void)
|
static void FuncIdent (void)
|
||||||
/* Handle the .IDENT function */
|
/* Handle the .IDENT function */
|
||||||
{
|
{
|
||||||
char Buf[sizeof(SVal)];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
Token Id;
|
Token Id;
|
||||||
unsigned Len;
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Skip it */
|
/* Skip it */
|
||||||
@@ -237,49 +220,45 @@ static void FuncIdent (void)
|
|||||||
/* Check that the string contains a valid identifier. While doing so,
|
/* Check that the string contains a valid identifier. While doing so,
|
||||||
* determine if it is a cheap local, or global one.
|
* determine if it is a cheap local, or global one.
|
||||||
*/
|
*/
|
||||||
Len = strlen (SVal);
|
SB_Reset (&SVal);
|
||||||
if (Len == 0) {
|
|
||||||
NoIdent ();
|
/* Check for a cheap local symbol */
|
||||||
return;
|
if (SB_Peek (&SVal) == LocalStart) {
|
||||||
}
|
SB_Skip (&SVal);
|
||||||
I = 0;
|
|
||||||
if (SVal[0] == LocalStart) {
|
|
||||||
if (Len < 2) {
|
|
||||||
NoIdent ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
I = 1;
|
|
||||||
Id = TOK_LOCAL_IDENT;
|
Id = TOK_LOCAL_IDENT;
|
||||||
} else {
|
} else {
|
||||||
Id = TOK_IDENT;
|
Id = TOK_IDENT;
|
||||||
}
|
}
|
||||||
if (!IsIdStart (SVal[I])) {
|
|
||||||
|
/* Next character must be a valid identifier start */
|
||||||
|
if (!IsIdStart (SB_Get (&SVal))) {
|
||||||
NoIdent ();
|
NoIdent ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (I < Len) {
|
for (I = SB_GetIndex (&SVal); I < SB_GetLen (&SVal); ++I) {
|
||||||
if (!IsIdChar (SVal[I])) {
|
if (!IsIdChar (SB_AtUnchecked (&SVal, I))) {
|
||||||
NoIdent ();
|
NoIdent ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
++I;
|
|
||||||
}
|
}
|
||||||
if (IgnoreCase) {
|
if (IgnoreCase) {
|
||||||
UpcaseSVal ();
|
UpcaseSVal ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If anything is ok, save and skip the string. Check that the next token
|
/* If anything is ok, save and skip the string. Check that the next token
|
||||||
* is a right paren, in which case SVal is untouched. Replace the token by
|
* is a right paren, then replace the token by an identifier token.
|
||||||
* a identifier token.
|
|
||||||
*/
|
*/
|
||||||
memcpy (Buf, SVal, Len+1);
|
SB_Copy (&Buf, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (Tok != TOK_RPAREN) {
|
if (Tok != TOK_RPAREN) {
|
||||||
Error ("`)' expected");
|
Error ("`)' expected");
|
||||||
} else {
|
} else {
|
||||||
Tok = Id;
|
Tok = Id;
|
||||||
memcpy (SVal, Buf, Len+1);
|
SB_Copy (&SVal, &Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free buffer memory */
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -443,11 +422,11 @@ static void InvalidFormatString (void)
|
|||||||
static void FuncSPrintF (void)
|
static void FuncSPrintF (void)
|
||||||
/* Handle the .SPRINTF function */
|
/* Handle the .SPRINTF function */
|
||||||
{
|
{
|
||||||
char Format[sizeof (SVal)]; /* User given format */
|
StrBuf Format = STATIC_STRBUF_INITIALIZER; /* User supplied format */
|
||||||
const char* F = Format; /* User format pointer */
|
StrBuf R = STATIC_STRBUF_INITIALIZER; /* Result string */
|
||||||
StrBuf R = AUTO_STRBUF_INITIALIZER; /* Result string */
|
StrBuf F1 = STATIC_STRBUF_INITIALIZER; /* One format spec from F */
|
||||||
StrBuf F1 = AUTO_STRBUF_INITIALIZER; /* One format spec from F */
|
StrBuf R1 = STATIC_STRBUF_INITIALIZER; /* One result */
|
||||||
StrBuf R1 = AUTO_STRBUF_INITIALIZER; /* One result */
|
char C;
|
||||||
int Done;
|
int Done;
|
||||||
long IVal; /* Integer value */
|
long IVal; /* Integer value */
|
||||||
|
|
||||||
@@ -463,30 +442,31 @@ static void FuncSPrintF (void)
|
|||||||
if (!LookAtStrCon ()) {
|
if (!LookAtStrCon ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Format, SVal);
|
SB_Copy (&Format, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Walk over the format string, generating the function result in R */
|
/* Walk over the format string, generating the function result in R */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Get the next char from the format string and check for EOS */
|
/* Get the next char from the format string and check for EOS */
|
||||||
if (*F == '\0') {
|
if (SB_Peek (&Format) == '\0') {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a format specifier */
|
/* Check for a format specifier */
|
||||||
if (*F != '%') {
|
if (SB_Peek (&Format) != '%') {
|
||||||
/* No format specifier, just copy */
|
/* No format specifier, just copy */
|
||||||
SB_AppendChar (&R, *F++);
|
SB_AppendChar (&R, SB_Get (&Format));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*++F == '%') {
|
SB_Skip (&Format);
|
||||||
|
if (SB_Peek (&Format) == '%') {
|
||||||
/* %% */
|
/* %% */
|
||||||
SB_AppendChar (&R, '%');
|
SB_AppendChar (&R, '%');
|
||||||
++F;
|
SB_Skip (&Format);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*F == '\0') {
|
if (SB_Peek (&Format) == '\0') {
|
||||||
InvalidFormatString ();
|
InvalidFormatString ();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -505,32 +485,32 @@ static void FuncSPrintF (void)
|
|||||||
|
|
||||||
/* Check for flags */
|
/* Check for flags */
|
||||||
Done = 0;
|
Done = 0;
|
||||||
while (*F != '\0' && !Done) {
|
while ((C = SB_Peek (&Format)) != '\0' && !Done) {
|
||||||
switch (*F) {
|
switch (C) {
|
||||||
case '-': /* FALLTHROUGH */
|
case '-': /* FALLTHROUGH */
|
||||||
case '+': /* FALLTHROUGH */
|
case '+': /* FALLTHROUGH */
|
||||||
case ' ': /* FALLTHROUGH */
|
case ' ': /* FALLTHROUGH */
|
||||||
case '#': /* FALLTHROUGH */
|
case '#': /* FALLTHROUGH */
|
||||||
case '0': SB_AppendChar (&F1, *F++); break;
|
case '0': SB_AppendChar (&F1, SB_Get (&Format)); break;
|
||||||
default: Done = 1; break;
|
default: Done = 1; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We do only support a numerical width field */
|
/* We do only support a numerical width field */
|
||||||
while (IsDigit (*F)) {
|
while (IsDigit (SB_Peek (&Format))) {
|
||||||
SB_AppendChar (&F1, *F++);
|
SB_AppendChar (&F1, SB_Get (&Format));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Precision - only positive numerical fields supported */
|
/* Precision - only positive numerical fields supported */
|
||||||
if (*F == '.') {
|
if (SB_Peek (&Format) == '.') {
|
||||||
SB_AppendChar (&F1, *F++);
|
SB_AppendChar (&F1, SB_Get (&Format));
|
||||||
while (IsDigit (*F)) {
|
while (IsDigit (SB_Peek (&Format))) {
|
||||||
SB_AppendChar (&F1, *F++);
|
SB_AppendChar (&F1, SB_Get (&Format));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Length modifiers aren't supported, so read the conversion specs */
|
/* Length modifiers aren't supported, so read the conversion specs */
|
||||||
switch (*F) {
|
switch (SB_Peek (&Format)) {
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
@@ -542,7 +522,7 @@ static void FuncSPrintF (void)
|
|||||||
* calling xsprintf later. Terminate the format string.
|
* calling xsprintf later. Terminate the format string.
|
||||||
*/
|
*/
|
||||||
SB_AppendChar (&F1, 'l');
|
SB_AppendChar (&F1, 'l');
|
||||||
SB_AppendChar (&F1, *F++);
|
SB_AppendChar (&F1, SB_Get (&Format));
|
||||||
SB_Terminate (&F1);
|
SB_Terminate (&F1);
|
||||||
|
|
||||||
/* The argument must be a constant expression */
|
/* The argument must be a constant expression */
|
||||||
@@ -558,13 +538,13 @@ static void FuncSPrintF (void)
|
|||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
/* Add the format spec and terminate the format */
|
/* Add the format spec and terminate the format */
|
||||||
SB_AppendChar (&F1, *F++);
|
SB_AppendChar (&F1, SB_Get (&Format));
|
||||||
SB_Terminate (&F1);
|
SB_Terminate (&F1);
|
||||||
|
|
||||||
/* The argument must be a string constant */
|
/* The argument must be a string constant */
|
||||||
if (!LookAtStrCon ()) {
|
if (!LookAtStrCon ()) {
|
||||||
/* Make it one */
|
/* Make it one */
|
||||||
strcpy (SVal, "**undefined**");
|
SB_CopyStr (&SVal, "**undefined**");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format this argument according to the spec */
|
/* Format this argument according to the spec */
|
||||||
@@ -580,7 +560,7 @@ static void FuncSPrintF (void)
|
|||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
/* Add the format spec and terminate the format */
|
/* Add the format spec and terminate the format */
|
||||||
SB_AppendChar (&F1, *F++);
|
SB_AppendChar (&F1, SB_Get (&Format));
|
||||||
SB_Terminate (&F1);
|
SB_Terminate (&F1);
|
||||||
|
|
||||||
/* The argument must be a constant expression */
|
/* The argument must be a constant expression */
|
||||||
@@ -604,21 +584,12 @@ static void FuncSPrintF (void)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
Error ("Invalid format string");
|
Error ("Invalid format string");
|
||||||
if (*F) {
|
SB_Skip (&Format);
|
||||||
/* Don't skip beyond end of string */
|
|
||||||
++F;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The length of the final result may not exceed the size of a string */
|
|
||||||
if (SB_GetLen (&R) >= sizeof (SVal)) {
|
|
||||||
Error ("Resulting string is too long");
|
|
||||||
SB_Cut (&R, sizeof (SVal) - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Terminate the result string */
|
/* Terminate the result string */
|
||||||
SB_Terminate (&R);
|
SB_Terminate (&R);
|
||||||
|
|
||||||
@@ -629,14 +600,15 @@ static void FuncSPrintF (void)
|
|||||||
Error ("`)' expected");
|
Error ("`)' expected");
|
||||||
} else {
|
} else {
|
||||||
Tok = TOK_STRCON;
|
Tok = TOK_STRCON;
|
||||||
memcpy (SVal, SB_GetConstBuf (&R), SB_GetLen (&R) + 1);
|
SB_Copy (&SVal, &R);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Delete the string buffers */
|
/* Delete the string buffers */
|
||||||
DoneStrBuf (&R);
|
SB_Done (&Format);
|
||||||
DoneStrBuf (&F1);
|
SB_Done (&R);
|
||||||
DoneStrBuf (&R1);
|
SB_Done (&F1);
|
||||||
|
SB_Done (&R1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -644,7 +616,7 @@ static void FuncSPrintF (void)
|
|||||||
static void FuncString (void)
|
static void FuncString (void)
|
||||||
/* Handle the .STRING function */
|
/* Handle the .STRING function */
|
||||||
{
|
{
|
||||||
char Buf[MAX_STR_LEN+1];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Skip it */
|
/* Skip it */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -655,12 +627,12 @@ static void FuncString (void)
|
|||||||
/* Accept identifiers or numeric expressions */
|
/* Accept identifiers or numeric expressions */
|
||||||
if (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) {
|
if (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) {
|
||||||
/* Save the identifier, then skip it */
|
/* Save the identifier, then skip it */
|
||||||
strcpy (Buf, SVal);
|
SB_Copy (&Buf, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
} else {
|
} else {
|
||||||
/* Numeric expression */
|
/* Numeric expression */
|
||||||
long Val = ConstExpression ();
|
long Val = ConstExpression ();
|
||||||
sprintf (Buf, "%ld", Val);
|
SB_Printf (&Buf, "%ld", Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We expect a closing parenthesis, but will not skip it but replace it
|
/* We expect a closing parenthesis, but will not skip it but replace it
|
||||||
@@ -670,8 +642,11 @@ static void FuncString (void)
|
|||||||
Error ("`)' expected");
|
Error ("`)' expected");
|
||||||
} else {
|
} else {
|
||||||
Tok = TOK_STRCON;
|
Tok = TOK_STRCON;
|
||||||
strcpy (SVal, Buf);
|
SB_Copy (&SVal, &Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free string memory */
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -104,15 +104,18 @@ void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void EmitData (const unsigned char* Data, unsigned Size)
|
void EmitData (const void* D, unsigned Size)
|
||||||
/* Emit data into the current segment */
|
/* Emit data into the current segment */
|
||||||
{
|
{
|
||||||
|
/* Make a useful pointer from Data */
|
||||||
|
const unsigned char* Data = D;
|
||||||
|
|
||||||
/* Create lots of fragments for the data */
|
/* Create lots of fragments for the data */
|
||||||
while (Size) {
|
while (Size) {
|
||||||
Fragment* F;
|
Fragment* F;
|
||||||
|
|
||||||
/* Determine the length of the next fragment */
|
/* Determine the length of the next fragment */
|
||||||
unsigned Len = Size;
|
unsigned Len = Size;
|
||||||
if (Len > sizeof (F->V.Data)) {
|
if (Len > sizeof (F->V.Data)) {
|
||||||
Len = sizeof (F->V.Data);
|
Len = sizeof (F->V.Data);
|
||||||
}
|
}
|
||||||
@@ -132,6 +135,15 @@ void EmitData (const unsigned char* Data, unsigned Size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void EmitStrBuf (const StrBuf* Data)
|
||||||
|
/* Emit a string into the current segment */
|
||||||
|
{
|
||||||
|
/* Use EmitData to output the data */
|
||||||
|
EmitData (SB_GetConstBuf (Data), SB_GetLen (Data));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void EmitByte (ExprNode* Expr)
|
void EmitByte (ExprNode* Expr)
|
||||||
/* Emit one byte */
|
/* Emit one byte */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -67,9 +68,12 @@ void EmitSigned (ExprNode* Expr, unsigned Size);
|
|||||||
void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size);
|
void EmitPCRel (unsigned char OPC, ExprNode* Expr, unsigned Size);
|
||||||
/* Emit an opcode with a PC relative argument of one or two bytes */
|
/* Emit an opcode with a PC relative argument of one or two bytes */
|
||||||
|
|
||||||
void EmitData (const unsigned char* Data, unsigned Size);
|
void EmitData (const void* Data, unsigned Size);
|
||||||
/* Emit data into the current segment */
|
/* Emit data into the current segment */
|
||||||
|
|
||||||
|
void EmitStrBuf (const StrBuf* Data);
|
||||||
|
/* Emit a string into the current segment */
|
||||||
|
|
||||||
void EmitByte (ExprNode* Expr);
|
void EmitByte (ExprNode* Expr);
|
||||||
/* Emit one byte */
|
/* Emit one byte */
|
||||||
|
|
||||||
|
|||||||
@@ -296,6 +296,19 @@ void ObjWriteStr (const char* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ObjWriteBuf (const StrBuf* S)
|
||||||
|
/* Write a string to the object file */
|
||||||
|
{
|
||||||
|
/* Write the string with the length preceeded (this is easier for
|
||||||
|
* the reading routine than the C format since the length is known in
|
||||||
|
* advance).
|
||||||
|
*/
|
||||||
|
ObjWriteVar (SB_GetLen (S));
|
||||||
|
ObjWriteData (SB_GetConstBuf (S), SB_GetLen (S));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ObjWriteData (const void* Data, unsigned Size)
|
void ObjWriteData (const void* Data, unsigned Size)
|
||||||
/* Write literal data to the file */
|
/* Write literal data to the file */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "filepos.h"
|
#include "filepos.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -79,6 +80,9 @@ void ObjWriteVar (unsigned long V);
|
|||||||
void ObjWriteStr (const char* S);
|
void ObjWriteStr (const char* S);
|
||||||
/* Write a string to the object file */
|
/* Write a string to the object file */
|
||||||
|
|
||||||
|
void ObjWriteBuf (const StrBuf* S);
|
||||||
|
/* Write a string to the object file */
|
||||||
|
|
||||||
void ObjWriteData (const void* Data, unsigned Size);
|
void ObjWriteData (const void* Data, unsigned Size);
|
||||||
/* Write literal data to the file */
|
/* Write literal data to the file */
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -96,50 +96,50 @@ static Option* NewOption (unsigned char Type, unsigned long Val)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptStr (unsigned char Type, const char* Text)
|
void OptStr (unsigned char Type, const StrBuf* Text)
|
||||||
/* Add a string option */
|
/* Add a string option */
|
||||||
{
|
{
|
||||||
NewOption (Type, GetStringId (Text));
|
NewOption (Type, GetStrBufId (Text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptComment (const char* Comment)
|
void OptComment (const StrBuf* Comment)
|
||||||
/* Add a comment */
|
/* Add a comment */
|
||||||
{
|
{
|
||||||
NewOption (OPT_COMMENT, GetStringId (Comment));
|
NewOption (OPT_COMMENT, GetStrBufId (Comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptAuthor (const char* Author)
|
void OptAuthor (const StrBuf* Author)
|
||||||
/* Add an author statement */
|
/* Add an author statement */
|
||||||
{
|
{
|
||||||
NewOption (OPT_AUTHOR, GetStringId (Author));
|
NewOption (OPT_AUTHOR, GetStrBufId (Author));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptTranslator (const char* Translator)
|
void OptTranslator (const StrBuf* Translator)
|
||||||
/* Add a translator option */
|
/* Add a translator option */
|
||||||
{
|
{
|
||||||
NewOption (OPT_TRANSLATOR, GetStringId (Translator));
|
NewOption (OPT_TRANSLATOR, GetStrBufId (Translator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptCompiler (const char* Compiler)
|
void OptCompiler (const StrBuf* Compiler)
|
||||||
/* Add a compiler option */
|
/* Add a compiler option */
|
||||||
{
|
{
|
||||||
NewOption (OPT_COMPILER, GetStringId (Compiler));
|
NewOption (OPT_COMPILER, GetStrBufId (Compiler));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptOS (const char* OS)
|
void OptOS (const StrBuf* OS)
|
||||||
/* Add an operating system option */
|
/* Add an operating system option */
|
||||||
{
|
{
|
||||||
NewOption (OPT_OS, GetStringId (OS));
|
NewOption (OPT_OS, GetStrBufId (OS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -182,3 +182,4 @@ void WriteOptions (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -44,22 +44,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OptStr (unsigned char Type, const char* Text);
|
void OptStr (unsigned char Type, const StrBuf* Text);
|
||||||
/* Add a string option */
|
/* Add a string option */
|
||||||
|
|
||||||
void OptComment (const char* Comment);
|
void OptComment (const StrBuf* Comment);
|
||||||
/* Add a comment */
|
/* Add a comment */
|
||||||
|
|
||||||
void OptAuthor (const char* Author);
|
void OptAuthor (const StrBuf* Author);
|
||||||
/* Add an author statement */
|
/* Add an author statement */
|
||||||
|
|
||||||
void OptTranslator (const char* Translator);
|
void OptTranslator (const StrBuf* Translator);
|
||||||
/* Add a translator option */
|
/* Add a translator option */
|
||||||
|
|
||||||
void OptCompiler (const char* Compiler);
|
void OptCompiler (const StrBuf* Compiler);
|
||||||
/* Add a compiler option */
|
/* Add a compiler option */
|
||||||
|
|
||||||
void OptOS (const char* OS);
|
void OptOS (const StrBuf* OS);
|
||||||
/* Add an operating system option */
|
/* Add an operating system option */
|
||||||
|
|
||||||
void OptDateTime (unsigned long DateTime);
|
void OptDateTime (unsigned long DateTime);
|
||||||
@@ -68,7 +68,7 @@ void OptDateTime (unsigned long DateTime);
|
|||||||
void WriteOptions (void);
|
void WriteOptions (void);
|
||||||
/* Write the options to the object file */
|
/* Write the options to the object file */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of options.h */
|
/* End of options.h */
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Keyword we're about to handle */
|
/* Keyword we're about to handle */
|
||||||
static char Keyword [sizeof (SVal)+1];
|
static StrBuf Keyword = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Segment stack */
|
/* Segment stack */
|
||||||
#define MAX_PUSHED_SEGMENTS 16
|
#define MAX_PUSHED_SEGMENTS 16
|
||||||
@@ -208,7 +208,7 @@ static void ExportImport (void (*Func) (SymEntry*, unsigned char, unsigned),
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find the symbol table entry, allocate a new one if necessary */
|
/* Find the symbol table entry, allocate a new one if necessary */
|
||||||
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
|
Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
|
||||||
|
|
||||||
/* Skip the name */
|
/* Skip the name */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -238,7 +238,7 @@ static long IntArg (long Min, long Max)
|
|||||||
* and return -1 in this case.
|
* and return -1 in this case.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (Tok == TOK_IDENT && strcmp (SVal, "unlimited") == 0) {
|
if (Tok == TOK_IDENT && SB_CompareStr (&SVal, "unlimited") == 0) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@@ -253,7 +253,7 @@ static long IntArg (long Min, long Max)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ConDes (const char* Name, unsigned Type)
|
static void ConDes (const StrBuf* Name, unsigned Type)
|
||||||
/* Parse remaining line for constructor/destructor of the remaining type */
|
/* Parse remaining line for constructor/destructor of the remaining type */
|
||||||
{
|
{
|
||||||
long Prio;
|
long Prio;
|
||||||
@@ -376,8 +376,6 @@ static void DoAlign (void)
|
|||||||
static void DoASCIIZ (void)
|
static void DoASCIIZ (void)
|
||||||
/* Define text with a zero terminator */
|
/* Define text with a zero terminator */
|
||||||
{
|
{
|
||||||
unsigned Len;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Must have a string constant */
|
/* Must have a string constant */
|
||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
@@ -385,12 +383,9 @@ static void DoASCIIZ (void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the length of the string constant */
|
|
||||||
Len = strlen (SVal);
|
|
||||||
|
|
||||||
/* Translate into target charset and emit */
|
/* Translate into target charset and emit */
|
||||||
TgtTranslateBuf (SVal, Len);
|
TgtTranslateStrBuf (&SVal);
|
||||||
EmitData ((unsigned char*) SVal, Len);
|
EmitStrBuf (&SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
if (Tok == TOK_COMMA) {
|
if (Tok == TOK_COMMA) {
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -459,7 +454,7 @@ static void DoAssert (void)
|
|||||||
/* Translate the message into a string id. We can then skip the input
|
/* Translate the message into a string id. We can then skip the input
|
||||||
* string.
|
* string.
|
||||||
*/
|
*/
|
||||||
Msg = GetStringId (SVal);
|
Msg = GetStrBufId (&SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -497,9 +492,8 @@ static void DoByte (void)
|
|||||||
while (1) {
|
while (1) {
|
||||||
if (Tok == TOK_STRCON) {
|
if (Tok == TOK_STRCON) {
|
||||||
/* A string, translate into target charset and emit */
|
/* A string, translate into target charset and emit */
|
||||||
unsigned Len = strlen (SVal);
|
TgtTranslateStrBuf (&SVal);
|
||||||
TgtTranslateBuf (SVal, Len);
|
EmitStrBuf (&SVal);
|
||||||
EmitData ((unsigned char*) SVal, Len);
|
|
||||||
NextTok ();
|
NextTok ();
|
||||||
} else {
|
} else {
|
||||||
EmitByte (Expression ());
|
EmitByte (Expression ());
|
||||||
@@ -575,7 +569,7 @@ static void DoConDes (void)
|
|||||||
"DESTRUCTOR",
|
"DESTRUCTOR",
|
||||||
"INTERRUPTOR",
|
"INTERRUPTOR",
|
||||||
};
|
};
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
long Type;
|
long Type;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
@@ -583,7 +577,7 @@ static void DoConDes (void)
|
|||||||
ErrorSkip ("Identifier expected");
|
ErrorSkip ("Identifier expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Type follows. May be encoded as identifier or numerical */
|
/* Type follows. May be encoded as identifier or numerical */
|
||||||
@@ -596,9 +590,8 @@ static void DoConDes (void)
|
|||||||
|
|
||||||
/* Check if we got a valid keyword */
|
/* Check if we got a valid keyword */
|
||||||
if (Type < 0) {
|
if (Type < 0) {
|
||||||
Error ("Syntax error");
|
ErrorSkip ("Syntax error");
|
||||||
SkipUntilSep ();
|
goto ExitPoint;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -607,14 +600,18 @@ static void DoConDes (void)
|
|||||||
Type = ConstExpression ();
|
Type = ConstExpression ();
|
||||||
if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
|
if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
|
||||||
/* Value out of range */
|
/* Value out of range */
|
||||||
Error ("Range error");
|
ErrorSkip ("Range error");
|
||||||
return;
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse the remainder of the line and export the symbol */
|
/* Parse the remainder of the line and export the symbol */
|
||||||
ConDes (Name, (unsigned) Type);
|
ConDes (&Name, (unsigned) Type);
|
||||||
|
|
||||||
|
ExitPoint:
|
||||||
|
/* Free string memory */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -622,18 +619,21 @@ static void DoConDes (void)
|
|||||||
static void DoConstructor (void)
|
static void DoConstructor (void)
|
||||||
/* Export a symbol as constructor */
|
/* Export a symbol as constructor */
|
||||||
{
|
{
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (Tok != TOK_IDENT) {
|
if (Tok != TOK_IDENT) {
|
||||||
ErrorSkip ("Identifier expected");
|
ErrorSkip ("Identifier expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Parse the remainder of the line and export the symbol */
|
/* Parse the remainder of the line and export the symbol */
|
||||||
ConDes (Name, CD_TYPE_CON);
|
ConDes (&Name, CD_TYPE_CON);
|
||||||
|
|
||||||
|
/* Free string memory */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -714,18 +714,21 @@ static void DoDefine (void)
|
|||||||
static void DoDestructor (void)
|
static void DoDestructor (void)
|
||||||
/* Export a symbol as destructor */
|
/* Export a symbol as destructor */
|
||||||
{
|
{
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (Tok != TOK_IDENT) {
|
if (Tok != TOK_IDENT) {
|
||||||
ErrorSkip ("Identifier expected");
|
ErrorSkip ("Identifier expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Parse the remainder of the line and export the symbol */
|
/* Parse the remainder of the line and export the symbol */
|
||||||
ConDes (Name, CD_TYPE_DES);
|
ConDes (&Name, CD_TYPE_DES);
|
||||||
|
|
||||||
|
/* Free string memory */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -786,7 +789,7 @@ static void DoError (void)
|
|||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
} else {
|
} else {
|
||||||
Error ("User error: %s", SVal);
|
Error ("User error: %m%p", &SVal);
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -853,9 +856,9 @@ static void DoFeature (void)
|
|||||||
LocaseSVal ();
|
LocaseSVal ();
|
||||||
|
|
||||||
/* Set the feature and check for errors */
|
/* Set the feature and check for errors */
|
||||||
if (SetFeature (SVal) == FEAT_UNKNOWN) {
|
if (SetFeature (&SVal) == FEAT_UNKNOWN) {
|
||||||
/* Not found */
|
/* Not found */
|
||||||
ErrorSkip ("Invalid feature: `%s'", SVal);
|
ErrorSkip ("Invalid feature: `%m%p'", &SVal);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/* Skip the keyword */
|
/* Skip the keyword */
|
||||||
@@ -911,17 +914,17 @@ static void DoFileOpt (void)
|
|||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
/* Author */
|
/* Author */
|
||||||
OptAuthor (SVal);
|
OptAuthor (&SVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* Comment */
|
/* Comment */
|
||||||
OptComment (SVal);
|
OptComment (&SVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
/* Compiler */
|
/* Compiler */
|
||||||
OptCompiler (SVal);
|
OptCompiler (&SVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -951,7 +954,7 @@ static void DoFileOpt (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the option */
|
/* Insert the option */
|
||||||
OptStr ((unsigned char) OptNum, SVal);
|
OptStr ((unsigned char) OptNum, &SVal);
|
||||||
|
|
||||||
/* Done */
|
/* Done */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -1029,7 +1032,7 @@ static void DoImportZP (void)
|
|||||||
static void DoIncBin (void)
|
static void DoIncBin (void)
|
||||||
/* Include a binary file */
|
/* Include a binary file */
|
||||||
{
|
{
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
long Start = 0L;
|
long Start = 0L;
|
||||||
long Count = -1L;
|
long Count = -1L;
|
||||||
long Size;
|
long Size;
|
||||||
@@ -1040,7 +1043,8 @@ static void DoIncBin (void)
|
|||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
|
SB_Terminate (&Name);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* A starting offset may follow */
|
/* A starting offset may follow */
|
||||||
@@ -1057,14 +1061,14 @@ static void DoIncBin (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try to open the file */
|
/* Try to open the file */
|
||||||
F = fopen (Name, "rb");
|
F = fopen (SB_GetConstBuf (&Name), "rb");
|
||||||
if (F == 0) {
|
if (F == 0) {
|
||||||
|
|
||||||
/* Search for the file in the include directories. */
|
/* Search for the file in the include directories. */
|
||||||
char* PathName = FindInclude (Name);
|
char* PathName = FindInclude (SB_GetConstBuf (&Name));
|
||||||
if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
|
if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
|
||||||
/* Not found or cannot open, print an error and bail out */
|
/* Not found or cannot open, print an error and bail out */
|
||||||
ErrorSkip ("Cannot open include file `%s': %s", Name, strerror (errno));
|
ErrorSkip ("Cannot open include file `%m%p': %s", &Name, strerror (errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free the allocated memory */
|
/* Free the allocated memory */
|
||||||
@@ -1072,7 +1076,7 @@ static void DoIncBin (void)
|
|||||||
|
|
||||||
/* If we had an error before, bail out now */
|
/* If we had an error before, bail out now */
|
||||||
if (F == 0) {
|
if (F == 0) {
|
||||||
return;
|
goto ExitPoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1111,8 +1115,8 @@ static void DoIncBin (void)
|
|||||||
size_t BytesRead = fread (Buf, 1, BytesToRead, F);
|
size_t BytesRead = fread (Buf, 1, BytesToRead, F);
|
||||||
if (BytesToRead != BytesRead) {
|
if (BytesToRead != BytesRead) {
|
||||||
/* Some sort of error */
|
/* Some sort of error */
|
||||||
ErrorSkip ("Cannot read from include file `%s': %s",
|
ErrorSkip ("Cannot read from include file `%m%p': %s",
|
||||||
Name, strerror (errno));
|
&Name, strerror (errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1126,6 +1130,10 @@ static void DoIncBin (void)
|
|||||||
Done:
|
Done:
|
||||||
/* Close the file, ignore errors since it's r/o */
|
/* Close the file, ignore errors since it's r/o */
|
||||||
(void) fclose (F);
|
(void) fclose (F);
|
||||||
|
|
||||||
|
ExitPoint:
|
||||||
|
/* Free string memory */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1136,8 +1144,9 @@ static void DoInclude (void)
|
|||||||
/* Name must follow */
|
/* Name must follow */
|
||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
} else {
|
} else {
|
||||||
NewInputFile (SVal);
|
SB_Terminate (&SVal);
|
||||||
|
NewInputFile (SB_GetConstBuf (&SVal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,18 +1155,21 @@ static void DoInclude (void)
|
|||||||
static void DoInterruptor (void)
|
static void DoInterruptor (void)
|
||||||
/* Export a symbol as interruptor */
|
/* Export a symbol as interruptor */
|
||||||
{
|
{
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
/* Symbol name follows */
|
/* Symbol name follows */
|
||||||
if (Tok != TOK_IDENT) {
|
if (Tok != TOK_IDENT) {
|
||||||
ErrorSkip ("Identifier expected");
|
ErrorSkip ("Identifier expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Parse the remainder of the line and export the symbol */
|
/* Parse the remainder of the line and export the symbol */
|
||||||
ConDes (Name, CD_TYPE_INT);
|
ConDes (&Name, CD_TYPE_INT);
|
||||||
|
|
||||||
|
/* Free string memory */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1171,7 +1183,7 @@ static void DoInvalid (void)
|
|||||||
* an error in the assembler itself, while DoInvalid is.
|
* an error in the assembler itself, while DoInvalid is.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Internal ("Unexpected token: %s", Keyword);
|
Internal ("Unexpected token: %m%p", &Keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1238,7 +1250,8 @@ static void DoMacPack (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Search for the macro package name */
|
/* Search for the macro package name */
|
||||||
Package = MacPackFind (SVal);
|
LocaseSVal ();
|
||||||
|
Package = MacPackFind (&SVal);
|
||||||
if (Package < 0) {
|
if (Package < 0) {
|
||||||
/* Not found */
|
/* Not found */
|
||||||
ErrorSkip ("Invalid macro package");
|
ErrorSkip ("Invalid macro package");
|
||||||
@@ -1289,7 +1302,7 @@ static void DoOut (void)
|
|||||||
/* Output the string and be sure to flush the output to keep it in
|
/* Output the string and be sure to flush the output to keep it in
|
||||||
* sync with any error messages if the output is redirected to a file.
|
* sync with any error messages if the output is redirected to a file.
|
||||||
*/
|
*/
|
||||||
printf ("%s\n", SVal);
|
printf ("%m%p\n", &SVal);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
@@ -1355,7 +1368,7 @@ static void DoPopSeg (void)
|
|||||||
static void DoProc (void)
|
static void DoProc (void)
|
||||||
/* Start a new lexical scope */
|
/* Start a new lexical scope */
|
||||||
{
|
{
|
||||||
char Name[sizeof(SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
unsigned char AddrSize;
|
unsigned char AddrSize;
|
||||||
|
|
||||||
if (Tok == TOK_IDENT) {
|
if (Tok == TOK_IDENT) {
|
||||||
@@ -1363,10 +1376,10 @@ static void DoProc (void)
|
|||||||
SymEntry* Sym;
|
SymEntry* Sym;
|
||||||
|
|
||||||
/* The new scope has a name. Remember it. */
|
/* The new scope has a name. Remember it. */
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
|
|
||||||
/* Search for the symbol, generate a new one if needed */
|
/* Search for the symbol, generate a new one if needed */
|
||||||
Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
|
Sym = SymFind (CurrentScope, &Name, SYM_ALLOC_NEW);
|
||||||
|
|
||||||
/* Skip the scope name */
|
/* Skip the scope name */
|
||||||
NextTok ();
|
NextTok ();
|
||||||
@@ -1381,13 +1394,16 @@ static void DoProc (void)
|
|||||||
|
|
||||||
/* A .PROC statement without a name */
|
/* A .PROC statement without a name */
|
||||||
Warning (1, "Unnamed .PROCs are deprecated, please use .SCOPE");
|
Warning (1, "Unnamed .PROCs are deprecated, please use .SCOPE");
|
||||||
AnonName (Name, sizeof (Name), "PROC");
|
AnonName (&Name, "PROC");
|
||||||
AddrSize = ADDR_SIZE_DEFAULT;
|
AddrSize = ADDR_SIZE_DEFAULT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter a new scope */
|
/* Enter a new scope */
|
||||||
SymEnterLevel (Name, ST_PROC, AddrSize);
|
SymEnterLevel (&Name, ST_PROC, AddrSize);
|
||||||
|
|
||||||
|
/* Free memory for Name */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1475,20 +1491,20 @@ static void DoROData (void)
|
|||||||
static void DoScope (void)
|
static void DoScope (void)
|
||||||
/* Start a local scope */
|
/* Start a local scope */
|
||||||
{
|
{
|
||||||
char Name[sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
unsigned char AddrSize;
|
unsigned char AddrSize;
|
||||||
|
|
||||||
|
|
||||||
if (Tok == TOK_IDENT) {
|
if (Tok == TOK_IDENT) {
|
||||||
|
|
||||||
/* The new scope has a name. Remember and skip it. */
|
/* The new scope has a name. Remember and skip it. */
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* An unnamed scope */
|
/* An unnamed scope */
|
||||||
AnonName (Name, sizeof (Name), "SCOPE");
|
AnonName (&Name, "SCOPE");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1496,8 +1512,10 @@ static void DoScope (void)
|
|||||||
AddrSize = OptionalAddrSize ();
|
AddrSize = OptionalAddrSize ();
|
||||||
|
|
||||||
/* Enter the new scope */
|
/* Enter the new scope */
|
||||||
SymEnterLevel (Name, ST_SCOPE, AddrSize);
|
SymEnterLevel (&Name, ST_SCOPE, AddrSize);
|
||||||
|
|
||||||
|
/* Free memory for Name */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1505,24 +1523,30 @@ static void DoScope (void)
|
|||||||
static void DoSegment (void)
|
static void DoSegment (void)
|
||||||
/* Switch to another segment */
|
/* Switch to another segment */
|
||||||
{
|
{
|
||||||
char Name [sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
SegDef Def;
|
SegDef Def;
|
||||||
Def.Name = Name;
|
|
||||||
|
|
||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Save the name of the segment and skip it */
|
/* Save the name of the segment and skip it */
|
||||||
strcpy (Name, SVal);
|
SB_Copy (&Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
|
/* Use the name for the segment definition */
|
||||||
|
SB_Terminate (&Name);
|
||||||
|
Def.Name = SB_GetBuf (&Name);
|
||||||
|
|
||||||
/* Check for an optional address size modifier */
|
/* Check for an optional address size modifier */
|
||||||
Def.AddrSize = OptionalAddrSize ();
|
Def.AddrSize = OptionalAddrSize ();
|
||||||
|
|
||||||
/* Set the segment */
|
/* Set the segment */
|
||||||
UseSeg (&Def);
|
UseSeg (&Def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free memory for Name */
|
||||||
|
SB_Done (&Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1535,7 +1559,8 @@ static void DoSetCPU (void)
|
|||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
} else {
|
} else {
|
||||||
/* Try to find the CPU */
|
/* Try to find the CPU */
|
||||||
cpu_t CPU = FindCPU (SVal);
|
SB_Terminate (&SVal);
|
||||||
|
cpu_t CPU = FindCPU (SB_GetConstBuf (&SVal));
|
||||||
|
|
||||||
/* Switch to the new CPU */
|
/* Switch to the new CPU */
|
||||||
SetCPU (CPU);
|
SetCPU (CPU);
|
||||||
@@ -1615,7 +1640,7 @@ static void DoTag (void)
|
|||||||
static void DoUnexpected (void)
|
static void DoUnexpected (void)
|
||||||
/* Got an unexpected keyword */
|
/* Got an unexpected keyword */
|
||||||
{
|
{
|
||||||
Error ("Unexpected `%s'", Keyword);
|
Error ("Unexpected `%m%p'", &Keyword);
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1627,7 +1652,7 @@ static void DoWarning (void)
|
|||||||
if (Tok != TOK_STRCON) {
|
if (Tok != TOK_STRCON) {
|
||||||
ErrorSkip ("String constant expected");
|
ErrorSkip ("String constant expected");
|
||||||
} else {
|
} else {
|
||||||
Warning (0, "User warning: %s", SVal);
|
Warning (0, "User warning: %m%p", &SVal);
|
||||||
SkipUntilSep ();
|
SkipUntilSep ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1832,7 +1857,7 @@ void HandlePseudo (void)
|
|||||||
|
|
||||||
/* Remember the instruction, then skip it if needed */
|
/* Remember the instruction, then skip it if needed */
|
||||||
if ((D->Flags & ccKeepToken) == 0) {
|
if ((D->Flags & ccKeepToken) == 0) {
|
||||||
strcpy (Keyword, SVal);
|
SB_Copy (&Keyword, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2000-2008, Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -109,7 +109,7 @@ static void RepeatTokenCheck (TokList* L)
|
|||||||
* for and replace identifiers that are the repeat counter.
|
* for and replace identifiers that are the repeat counter.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (Tok == TOK_IDENT && L->Data != 0 && strcmp (SVal, L->Data) == 0) {
|
if (Tok == TOK_IDENT && L->Data != 0 && SB_CompareStr (&SVal, L->Data) == 0) {
|
||||||
/* Must replace by the repeat counter */
|
/* Must replace by the repeat counter */
|
||||||
Tok = TOK_INTCON;
|
Tok = TOK_INTCON;
|
||||||
IVal = L->RepCount;
|
IVal = L->RepCount;
|
||||||
@@ -143,7 +143,8 @@ void ParseRepeat (void)
|
|||||||
ErrorSkip ("Identifier expected");
|
ErrorSkip ("Identifier expected");
|
||||||
} else {
|
} else {
|
||||||
/* Remember the name and skip it */
|
/* Remember the name and skip it */
|
||||||
Name = xstrdup (SVal);
|
SB_Terminate (&SVal);
|
||||||
|
Name = xstrdup (SB_GetConstBuf (&SVal));
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
Token Tok = TOK_NONE; /* Current token */
|
Token Tok = TOK_NONE; /* Current token */
|
||||||
int WS; /* Flag: Whitespace before token */
|
int WS; /* Flag: Whitespace before token */
|
||||||
long IVal; /* Integer token attribute */
|
long IVal; /* Integer token attribute */
|
||||||
char SVal[MAX_STR_LEN+1]; /* String token attribute */
|
StrBuf SVal = STATIC_STRBUF_INITIALIZER;/* String token attribute */
|
||||||
|
|
||||||
FilePos CurPos = { 0, 0, 0 }; /* Name and position in current file */
|
FilePos CurPos = { 0, 0, 0 }; /* Name and position in current file */
|
||||||
|
|
||||||
@@ -459,6 +459,7 @@ void NewInputFile (const char* Name)
|
|||||||
/* check again if we do now have an open file */
|
/* check again if we do now have an open file */
|
||||||
if (F != 0) {
|
if (F != 0) {
|
||||||
|
|
||||||
|
StrBuf NameBuf;
|
||||||
unsigned FileIdx;
|
unsigned FileIdx;
|
||||||
CharSource* S;
|
CharSource* S;
|
||||||
|
|
||||||
@@ -476,7 +477,7 @@ void NewInputFile (const char* Name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add the file to the input file table and remember the index */
|
/* Add the file to the input file table and remember the index */
|
||||||
FileIdx = AddFile (Name, Buf.st_size, Buf.st_mtime);
|
FileIdx = AddFile (SB_InitFromString (&NameBuf, Name), Buf.st_size, Buf.st_mtime);
|
||||||
|
|
||||||
/* Create a new input source variable and initialize it */
|
/* Create a new input source variable and initialize it */
|
||||||
S = xmalloc (sizeof (*S));
|
S = xmalloc (sizeof (*S));
|
||||||
@@ -619,11 +620,7 @@ static void NextChar (void)
|
|||||||
void LocaseSVal (void)
|
void LocaseSVal (void)
|
||||||
/* Make SVal lower case */
|
/* Make SVal lower case */
|
||||||
{
|
{
|
||||||
unsigned I = 0;
|
SB_ToLower (&SVal);
|
||||||
while (SVal [I]) {
|
|
||||||
SVal [I] = tolower (SVal [I]);
|
|
||||||
++I;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -631,11 +628,7 @@ void LocaseSVal (void)
|
|||||||
void UpcaseSVal (void)
|
void UpcaseSVal (void)
|
||||||
/* Make SVal upper case */
|
/* Make SVal upper case */
|
||||||
{
|
{
|
||||||
unsigned I = 0;
|
SB_ToUpper (&SVal);
|
||||||
while (SVal [I]) {
|
|
||||||
SVal [I] = toupper (SVal [I]);
|
|
||||||
++I;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -653,7 +646,7 @@ static unsigned char FindDotKeyword (void)
|
|||||||
* return TOK_NONE if not found.
|
* return TOK_NONE if not found.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
static const struct DotKeyword K = { SVal, 0 };
|
struct DotKeyword K = { SB_GetConstBuf (&SVal), 0 };
|
||||||
struct DotKeyword* R;
|
struct DotKeyword* R;
|
||||||
|
|
||||||
/* If we aren't in ignore case mode, we have to uppercase the keyword */
|
/* If we aren't in ignore case mode, we have to uppercase the keyword */
|
||||||
@@ -673,20 +666,19 @@ static unsigned char FindDotKeyword (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ReadIdent (unsigned Index)
|
static void ReadIdent (void)
|
||||||
/* Read an identifier from the current input position into Ident. Filling SVal
|
/* Read an identifier from the current input position into Ident. Filling SVal
|
||||||
* starts at Index with the current character in C. It is assumed that any
|
* starts at the current position with the next character in C. It is assumed
|
||||||
* characters already filled in are ok, and the character in C is checked.
|
* that any characters already filled in are ok, and the character in C is
|
||||||
|
* checked.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Read the identifier */
|
/* Read the identifier */
|
||||||
do {
|
do {
|
||||||
if (Index < MAX_STR_LEN) {
|
SB_AppendChar (&SVal, C);
|
||||||
SVal [Index++] = C;
|
NextChar ();
|
||||||
}
|
|
||||||
NextChar ();
|
|
||||||
} while (IsIdChar (C));
|
} while (IsIdChar (C));
|
||||||
SVal [Index] = '\0';
|
SB_Terminate (&SVal);
|
||||||
|
|
||||||
/* If we should ignore case, convert the identifier to upper case */
|
/* If we should ignore case, convert the identifier to upper case */
|
||||||
if (IgnoreCase) {
|
if (IgnoreCase) {
|
||||||
@@ -696,18 +688,13 @@ static void ReadIdent (unsigned Index)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ReadStringConst (int StringTerm)
|
static void ReadStringConst (int StringTerm)
|
||||||
/* Read a string constant into SVal. Check for maximum string length and all
|
/* Read a string constant into SVal. */
|
||||||
* other stuff. The length of the string is returned.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
unsigned I;
|
|
||||||
|
|
||||||
/* Skip the leading string terminator */
|
/* Skip the leading string terminator */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
|
|
||||||
/* Read the string */
|
/* Read the string */
|
||||||
I = 0;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (C == StringTerm) {
|
if (C == StringTerm) {
|
||||||
break;
|
break;
|
||||||
@@ -717,13 +704,8 @@ static unsigned ReadStringConst (int StringTerm)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for string length, print an error message once */
|
/* Append the char to the string */
|
||||||
if (I == MAX_STR_LEN) {
|
SB_AppendChar (&SVal, C);
|
||||||
Error ("Maximum string size exceeded");
|
|
||||||
} else if (I < MAX_STR_LEN) {
|
|
||||||
SVal [I] = C;
|
|
||||||
}
|
|
||||||
++I;
|
|
||||||
|
|
||||||
/* Skip the character */
|
/* Skip the character */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
@@ -733,18 +715,12 @@ static unsigned ReadStringConst (int StringTerm)
|
|||||||
NextChar ();
|
NextChar ();
|
||||||
|
|
||||||
/* Terminate the string */
|
/* Terminate the string */
|
||||||
if (I >= MAX_STR_LEN) {
|
SB_Terminate (&SVal);
|
||||||
I = MAX_STR_LEN;
|
|
||||||
}
|
|
||||||
SVal [I] = '\0';
|
|
||||||
|
|
||||||
/* Return the length of the string */
|
|
||||||
return I;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int Sweet16Reg (const char* Ident)
|
static int Sweet16Reg (const StrBuf* Id)
|
||||||
/* Check if the given identifier is a sweet16 register. Return -1 if this is
|
/* Check if the given identifier is a sweet16 register. Return -1 if this is
|
||||||
* not the case, return the register number otherwise.
|
* not the case, return the register number otherwise.
|
||||||
*/
|
*/
|
||||||
@@ -752,14 +728,17 @@ static int Sweet16Reg (const char* Ident)
|
|||||||
unsigned RegNum;
|
unsigned RegNum;
|
||||||
char Check;
|
char Check;
|
||||||
|
|
||||||
if (Ident[0] != 'r' && Ident[0] != 'R') {
|
if (SB_GetLen (Id) < 2) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!IsDigit (Ident[1])) {
|
if (toupper (SB_AtUnchecked (Id, 0)) != 'R') {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!IsDigit (SB_AtUnchecked (Id, 1))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf (Ident+1, "%u%c", &RegNum, &Check) != 1 || RegNum > 15) {
|
if (sscanf (SB_GetConstBuf (Id)+1, "%u%c", &RegNum, &Check) != 1 || RegNum > 15) {
|
||||||
/* Invalid register */
|
/* Invalid register */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -796,6 +775,9 @@ Again:
|
|||||||
/* Mark the file position of the next token */
|
/* Mark the file position of the next token */
|
||||||
Source->Func->MarkStart (Source);
|
Source->Func->MarkStart (Source);
|
||||||
|
|
||||||
|
/* Clear the string attribute */
|
||||||
|
SB_Clear (&SVal);
|
||||||
|
|
||||||
/* Hex number or PC symbol? */
|
/* Hex number or PC symbol? */
|
||||||
if (C == '$') {
|
if (C == '$') {
|
||||||
NextChar ();
|
NextChar ();
|
||||||
@@ -928,8 +910,8 @@ Again:
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Read the remainder of the identifier */
|
/* Read the remainder of the identifier */
|
||||||
SVal[0] = '.';
|
SB_AppendChar (&SVal, '.');
|
||||||
ReadIdent (1);
|
ReadIdent ();
|
||||||
|
|
||||||
/* Dot keyword, search for it */
|
/* Dot keyword, search for it */
|
||||||
Tok = FindDotKeyword ();
|
Tok = FindDotKeyword ();
|
||||||
@@ -938,14 +920,14 @@ Again:
|
|||||||
/* Not found */
|
/* Not found */
|
||||||
if (!LeadingDotInIdents) {
|
if (!LeadingDotInIdents) {
|
||||||
/* Invalid pseudo instruction */
|
/* Invalid pseudo instruction */
|
||||||
Error ("`%s' is not a recognized control command", SVal);
|
Error ("`%m%p' is not a recognized control command", &SVal);
|
||||||
goto Again;
|
goto Again;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* An identifier with a dot. Check if it's a define style
|
/* An identifier with a dot. Check if it's a define style
|
||||||
* macro.
|
* macro.
|
||||||
*/
|
*/
|
||||||
if (IsDefine (SVal)) {
|
if (IsDefine (&SVal)) {
|
||||||
/* This is a define style macro - expand it */
|
/* This is a define style macro - expand it */
|
||||||
MacExpandStart ();
|
MacExpandStart ();
|
||||||
goto Restart;
|
goto Restart;
|
||||||
@@ -971,11 +953,11 @@ Again:
|
|||||||
/* Local symbol? */
|
/* Local symbol? */
|
||||||
if (C == LocalStart) {
|
if (C == LocalStart) {
|
||||||
|
|
||||||
/* Read the identifier */
|
/* Read the identifier. */
|
||||||
ReadIdent (0);
|
ReadIdent ();
|
||||||
|
|
||||||
/* Start character alone is not enough */
|
/* Start character alone is not enough */
|
||||||
if (SVal [1] == '\0') {
|
if (SB_GetLen (&SVal) == 1) {
|
||||||
Error ("Invalid cheap local symbol");
|
Error ("Invalid cheap local symbol");
|
||||||
goto Again;
|
goto Again;
|
||||||
}
|
}
|
||||||
@@ -990,13 +972,13 @@ Again:
|
|||||||
if (IsIdStart (C)) {
|
if (IsIdStart (C)) {
|
||||||
|
|
||||||
/* Read the identifier */
|
/* Read the identifier */
|
||||||
ReadIdent (0);
|
ReadIdent ();
|
||||||
|
|
||||||
/* Check for special names. Bail out if we have identified the type of
|
/* Check for special names. Bail out if we have identified the type of
|
||||||
* the token. Go on if the token is an identifier.
|
* the token. Go on if the token is an identifier.
|
||||||
*/
|
*/
|
||||||
if (SVal[1] == '\0') {
|
if (SB_GetLen (&SVal) == 1) {
|
||||||
switch (toupper (SVal [0])) {
|
switch (toupper (SB_AtUnchecked (&SVal, 0))) {
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
if (C == ':') {
|
if (C == ':') {
|
||||||
@@ -1039,7 +1021,7 @@ Again:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (CPU == CPU_SWEET16 && (IVal = Sweet16Reg (SVal)) >= 0) {
|
} else if (CPU == CPU_SWEET16 && (IVal = Sweet16Reg (&SVal)) >= 0) {
|
||||||
|
|
||||||
/* A sweet16 register number in sweet16 mode */
|
/* A sweet16 register number in sweet16 mode */
|
||||||
Tok = TOK_REG;
|
Tok = TOK_REG;
|
||||||
@@ -1048,7 +1030,7 @@ Again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for define style macro */
|
/* Check for define style macro */
|
||||||
if (IsDefine (SVal)) {
|
if (IsDefine (&SVal)) {
|
||||||
/* Macro - expand it */
|
/* Macro - expand it */
|
||||||
MacExpandStart ();
|
MacExpandStart ();
|
||||||
goto Restart;
|
goto Restart;
|
||||||
@@ -1243,8 +1225,9 @@ CharAgain:
|
|||||||
* string later.
|
* string later.
|
||||||
*/
|
*/
|
||||||
if (LooseStringTerm) {
|
if (LooseStringTerm) {
|
||||||
if (ReadStringConst ('\'') == 1) {
|
ReadStringConst ('\'');
|
||||||
IVal = SVal[0];
|
if (SB_GetLen (&SVal) == 1) {
|
||||||
|
IVal = SB_AtUnchecked (&SVal, 0);
|
||||||
Tok = TOK_CHARCON;
|
Tok = TOK_CHARCON;
|
||||||
} else {
|
} else {
|
||||||
Tok = TOK_STRCON;
|
Tok = TOK_STRCON;
|
||||||
@@ -1277,8 +1260,8 @@ CharAgain:
|
|||||||
case '\\':
|
case '\\':
|
||||||
/* Line continuation? */
|
/* Line continuation? */
|
||||||
if (LineCont) {
|
if (LineCont) {
|
||||||
NextChar ();
|
NextChar ();
|
||||||
if (C == '\n') {
|
if (C == '\n') {
|
||||||
/* Handle as white space */
|
/* Handle as white space */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
C = ' ';
|
C = ' ';
|
||||||
@@ -1333,7 +1316,7 @@ int GetSubKey (const char** Keys, unsigned Count)
|
|||||||
|
|
||||||
/* Do a linear search (a binary search is not worth the effort) */
|
/* Do a linear search (a binary search is not worth the effort) */
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
if (strcmp (SVal, Keys [I]) == 0) {
|
if (SB_CompareStr (&SVal, Keys [I]) == 0) {
|
||||||
/* Found it */
|
/* Found it */
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "filepos.h"
|
#include "filepos.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
extern Token Tok; /* Current token */
|
extern Token Tok; /* Current token */
|
||||||
extern int WS; /* Flag: Whitespace before token */
|
extern int WS; /* Flag: Whitespace before token */
|
||||||
extern long IVal; /* Integer token attribute */
|
extern long IVal; /* Integer token attribute */
|
||||||
extern char SVal[MAX_STR_LEN+1]; /* String token attribute */
|
extern StrBuf SVal; /* String token attribute */
|
||||||
|
|
||||||
extern FilePos CurPos; /* Name and position in file */
|
extern FilePos CurPos; /* Name and position in file */
|
||||||
extern int ForcedEnd; /* Force end of assembly */
|
extern int ForcedEnd; /* Force end of assembly */
|
||||||
@@ -119,4 +120,4 @@ void DoneScanner (void);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008, Ullrich von Bassewit */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -52,13 +52,12 @@
|
|||||||
/* The name of the symbol used to encode the size. The name of this entry is
|
/* The name of the symbol used to encode the size. The name of this entry is
|
||||||
* choosen so that it cannot be accessed by the user.
|
* choosen so that it cannot be accessed by the user.
|
||||||
*/
|
*/
|
||||||
static const char SizeEntryName[] = ".size";
|
const StrBuf SizeEntryName = LIT_STRBUF_INITIALIZER (".size");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@@ -68,7 +67,7 @@ SymEntry* GetSizeOfScope (SymTable* Scope)
|
|||||||
* encodes the size, and will create a new entry if it does not exist.
|
* encodes the size, and will create a new entry if it does not exist.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return SymFind (Scope, SizeEntryName, SYM_ALLOC_NEW);
|
return SymFind (Scope, &SizeEntryName, SYM_ALLOC_NEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -79,7 +78,7 @@ SymEntry* GetSizeOfSymbol (SymEntry* Sym)
|
|||||||
* does not exist.
|
* does not exist.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return SymFindLocal (Sym, SizeEntryName, SYM_ALLOC_NEW);
|
return SymFindLocal (Sym, &SizeEntryName, SYM_ALLOC_NEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -35,6 +35,11 @@
|
|||||||
|
|
||||||
#ifndef SIZEOF_H
|
#ifndef SIZEOF_H
|
||||||
#define SIZEOF_H
|
#define SIZEOF_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -49,6 +54,16 @@ struct SymTable;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern const StrBuf SizeEntryName; /* Contains name of symbol with size */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
|
|||||||
|
|
||||||
void WriteStrPool (void)
|
void WriteStrPool (void)
|
||||||
/* Write the string pool to the object file */
|
/* Write the string pool to the object file */
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
/* Get the number of strings in the string pool */
|
/* Get the number of strings in the string pool */
|
||||||
@@ -71,7 +71,7 @@ void WriteStrPool (void)
|
|||||||
|
|
||||||
/* Write the strings in id order */
|
/* Write the strings in id order */
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
ObjWriteStr (SP_Get (&StrPool, I));
|
ObjWriteBuf (SP_Get (&StrPool, I));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Done writing the string pool */
|
/* Done writing the string pool */
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ extern StringPool StrPool;
|
|||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE unsigned GetStringId (const char* S)
|
INLINE unsigned GetStrBufId (const StrBuf* S)
|
||||||
/* Return the id of the given string */
|
/* Return the id of the given string buffer */
|
||||||
{
|
{
|
||||||
return SP_Add (&StrPool, S);
|
return SP_Add (&StrPool, S);
|
||||||
}
|
}
|
||||||
@@ -70,13 +70,33 @@ INLINE unsigned GetStringId (const char* S)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE const char* GetString (unsigned Index)
|
INLINE unsigned GetStringId (const char* S)
|
||||||
|
/* Return the id of the given string */
|
||||||
|
{
|
||||||
|
return SP_AddStr (&StrPool, S);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define GetStringId(S) SP_Add (&StrPool, (S))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE const StrBuf* GetStrBuf (unsigned Index)
|
||||||
/* Convert a string index into a string */
|
/* Convert a string index into a string */
|
||||||
{
|
{
|
||||||
return SP_Get (&StrPool, Index);
|
return SP_Get (&StrPool, Index);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetString(Index) SP_Get (&StrPool, (Index))
|
# define GetStrBuf(Index) SP_Get (&StrPool, (Index))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE const char* GetString (unsigned Index)
|
||||||
|
/* Convert a string index into a string */
|
||||||
|
{
|
||||||
|
return SB_GetConstBuf (SP_Get (&StrPool, Index));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define GetString(Index) SB_GetConstBuf (SP_Get (&StrPool, (Index)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void WriteStrPool (void);
|
void WriteStrPool (void);
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
int Anon = (Tok != TOK_IDENT);
|
int Anon = (Tok != TOK_IDENT);
|
||||||
if (!Anon) {
|
if (!Anon) {
|
||||||
/* Enter a new scope, then skip the name */
|
/* Enter a new scope, then skip the name */
|
||||||
SymEnterLevel (SVal, ST_STRUCT, ADDR_SIZE_ABS);
|
SymEnterLevel (&SVal, ST_STRUCT, ADDR_SIZE_ABS);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
/* Start at zero offset in the new scope */
|
/* Start at zero offset in the new scope */
|
||||||
Offs = 0;
|
Offs = 0;
|
||||||
@@ -132,7 +132,7 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
Sym = 0;
|
Sym = 0;
|
||||||
if (Tok == TOK_IDENT) {
|
if (Tok == TOK_IDENT) {
|
||||||
/* We have an identifier, generate a symbol */
|
/* We have an identifier, generate a symbol */
|
||||||
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
|
Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW);
|
||||||
|
|
||||||
/* Assign the symbol the offset of the current member */
|
/* Assign the symbol the offset of the current member */
|
||||||
SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);
|
SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);
|
||||||
@@ -261,7 +261,7 @@ static long DoStructInternal (long Offs, unsigned Type)
|
|||||||
long GetStructSize (SymTable* Struct)
|
long GetStructSize (SymTable* Struct)
|
||||||
/* Get the size of a struct or union */
|
/* Get the size of a struct or union */
|
||||||
{
|
{
|
||||||
SymEntry* Sym = SymFind (Struct, ".size", SYM_FIND_EXISTING);
|
SymEntry* Sym = SymFind (Struct, &SizeEntryName, SYM_FIND_EXISTING);
|
||||||
if (Sym == 0) {
|
if (Sym == 0) {
|
||||||
Error ("Size of struct/union is unknown");
|
Error ("Size of struct/union is unknown");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -511,7 +511,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
|
|||||||
DumpExpr (Expr, SymResolve);
|
DumpExpr (Expr, SymResolve);
|
||||||
}
|
}
|
||||||
PError (GetSymPos (Sym),
|
PError (GetSymPos (Sym),
|
||||||
"Circular reference in definition of symbol `%s'",
|
"Circular reference in definition of symbol `%m%p'",
|
||||||
GetSymName (Sym));
|
GetSymName (Sym));
|
||||||
ED_Invalidate (D);
|
ED_Invalidate (D);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -53,17 +53,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
|
SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
|
||||||
/* Parse a (possibly scoped) identifer. Name must point to a buffer big enough
|
/* Parse a (possibly scoped) identifer. The scope of the name must exist and
|
||||||
* to hold such an identifier. The scope of the name must exist and is returned
|
* is returned as function result, while the last part (the identifier) which
|
||||||
* as function result, while the last part (the identifier) which may be either
|
* may be either a symbol or a scope depending on the context is returned in
|
||||||
* a symbol or a scope depending on the context is returned in Name. ScopeName
|
* Name. FullName is a string buffer that is used to store the full name of
|
||||||
* is a string buffer that is used to store the name of the scope, the
|
* the identifier including the scope. It is used internally and may be used
|
||||||
* identifier lives in. It does contain anything but the identifier itself, so
|
* by the caller for error messages or similar.
|
||||||
* if ScopeName is empty on return, no explicit scope was specified. The full
|
|
||||||
* name of the identifier (including the scope) is ScopeName+Name.
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
/* Clear both passed string buffers */
|
||||||
|
SB_Clear (Name);
|
||||||
|
SB_Clear (FullName);
|
||||||
|
|
||||||
/* Get the starting table */
|
/* Get the starting table */
|
||||||
SymTable* Scope;
|
SymTable* Scope;
|
||||||
if (Tok == TOK_NAMESPACE) {
|
if (Tok == TOK_NAMESPACE) {
|
||||||
@@ -74,17 +76,17 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
|
|||||||
} else if (Tok == TOK_IDENT) {
|
} else if (Tok == TOK_IDENT) {
|
||||||
|
|
||||||
/* Remember the name and skip it */
|
/* Remember the name and skip it */
|
||||||
strcpy (Name, SVal);
|
SB_Copy (Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* If no namespace symbol follows, we're already done */
|
/* If no namespace symbol follows, we're already done */
|
||||||
if (Tok != TOK_NAMESPACE) {
|
if (Tok != TOK_NAMESPACE) {
|
||||||
SB_Terminate (ScopeName);
|
SB_Terminate (FullName);
|
||||||
return CurrentScope;
|
return CurrentScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass the scope back to the caller */
|
/* Pass the scope back to the caller */
|
||||||
SB_AppendStr (ScopeName, Name);
|
SB_Append (FullName, Name);
|
||||||
|
|
||||||
/* The scope must exist, so search for it starting with the current
|
/* The scope must exist, so search for it starting with the current
|
||||||
* scope.
|
* scope.
|
||||||
@@ -92,8 +94,8 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
|
|||||||
Scope = SymFindAnyScope (CurrentScope, Name);
|
Scope = SymFindAnyScope (CurrentScope, Name);
|
||||||
if (Scope == 0) {
|
if (Scope == 0) {
|
||||||
/* Scope not found */
|
/* Scope not found */
|
||||||
SB_Terminate (ScopeName);
|
SB_Terminate (FullName);
|
||||||
Error ("No such scope: `%s'", SB_GetConstBuf (ScopeName));
|
Error ("No such scope: `%m%p'", FullName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,14 +103,12 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
|
|||||||
|
|
||||||
/* Invalid token */
|
/* Invalid token */
|
||||||
Error ("Identifier expected");
|
Error ("Identifier expected");
|
||||||
SB_Terminate (ScopeName);
|
|
||||||
Name[0] = '\0';
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip the namespace token that follows */
|
/* Skip the namespace token that follows */
|
||||||
SB_AppendStr (ScopeName, "::");
|
SB_AppendStr (FullName, "::");
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* Resolve scopes. */
|
/* Resolve scopes. */
|
||||||
@@ -117,13 +117,11 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
|
|||||||
/* Next token must be an identifier. */
|
/* Next token must be an identifier. */
|
||||||
if (Tok != TOK_IDENT) {
|
if (Tok != TOK_IDENT) {
|
||||||
Error ("Identifier expected");
|
Error ("Identifier expected");
|
||||||
SB_Terminate (ScopeName);
|
|
||||||
Name[0] = '\0';
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember and skip the identifier */
|
/* Remember and skip the identifier */
|
||||||
strcpy (Name, SVal);
|
SB_Copy (Name, &SVal);
|
||||||
NextTok ();
|
NextTok ();
|
||||||
|
|
||||||
/* If a namespace token follows, we search for another scope, otherwise
|
/* If a namespace token follows, we search for another scope, otherwise
|
||||||
@@ -131,24 +129,22 @@ SymTable* ParseScopedIdent (char* Name, StrBuf* ScopeName)
|
|||||||
*/
|
*/
|
||||||
if (Tok != TOK_NAMESPACE) {
|
if (Tok != TOK_NAMESPACE) {
|
||||||
/* Symbol */
|
/* Symbol */
|
||||||
SB_Terminate (ScopeName);
|
|
||||||
return Scope;
|
return Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pass the scope back to the caller */
|
/* Pass the scope back to the caller */
|
||||||
SB_AppendStr (ScopeName, Name);
|
SB_Append (FullName, Name);
|
||||||
|
|
||||||
/* Search for the child scope */
|
/* Search for the child scope */
|
||||||
Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
|
Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
|
||||||
if (Scope == 0) {
|
if (Scope == 0) {
|
||||||
/* Scope not found */
|
/* Scope not found */
|
||||||
SB_Terminate (ScopeName);
|
Error ("No such scope: `%m%p'", FullName);
|
||||||
Error ("No such scope: `%s'", SB_GetConstBuf (ScopeName));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip the namespace token that follows */
|
/* Skip the namespace token that follows */
|
||||||
SB_AppendStr (ScopeName, "::");
|
SB_AppendStr (FullName, "::");
|
||||||
NextTok ();
|
NextTok ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,19 +156,19 @@ SymEntry* ParseScopedSymName (int AllocNew)
|
|||||||
* and return the symbol table entry.
|
* and return the symbol table entry.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
StrBuf ScopeName = AUTO_STRBUF_INITIALIZER;
|
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
|
||||||
char Ident[sizeof (SVal)];
|
StrBuf Ident = STATIC_STRBUF_INITIALIZER;
|
||||||
int NoScope;
|
int NoScope;
|
||||||
SymEntry* Sym;
|
SymEntry* Sym;
|
||||||
|
|
||||||
/* Parse the scoped symbol name */
|
/* Parse the scoped symbol name */
|
||||||
SymTable* Scope = ParseScopedIdent (Ident, &ScopeName);
|
SymTable* Scope = ParseScopedIdent (&Ident, &ScopeName);
|
||||||
|
|
||||||
/* If ScopeName is empty, no scope was specified */
|
/* If ScopeName is empty, no scope was specified */
|
||||||
NoScope = SB_IsEmpty (&ScopeName);
|
NoScope = SB_IsEmpty (&ScopeName);
|
||||||
|
|
||||||
/* We don't need ScopeName any longer */
|
/* We don't need ScopeName any longer */
|
||||||
DoneStrBuf (&ScopeName);
|
SB_Done (&ScopeName);
|
||||||
|
|
||||||
/* Check if the scope is valid. Errors have already been diagnosed by
|
/* Check if the scope is valid. Errors have already been diagnosed by
|
||||||
* the routine, so just exit.
|
* the routine, so just exit.
|
||||||
@@ -182,9 +178,9 @@ SymEntry* ParseScopedSymName (int AllocNew)
|
|||||||
* search also in the upper levels.
|
* search also in the upper levels.
|
||||||
*/
|
*/
|
||||||
if (NoScope && !AllocNew) {
|
if (NoScope && !AllocNew) {
|
||||||
Sym = SymFindAny (Scope, Ident);
|
Sym = SymFindAny (Scope, &Ident);
|
||||||
} else {
|
} else {
|
||||||
Sym = SymFind (Scope, Ident, AllocNew);
|
Sym = SymFind (Scope, &Ident, AllocNew);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* No scope ==> no symbol. To avoid errors in the calling routine that
|
/* No scope ==> no symbol. To avoid errors in the calling routine that
|
||||||
@@ -192,12 +188,15 @@ SymEntry* ParseScopedSymName (int AllocNew)
|
|||||||
* symbol.
|
* symbol.
|
||||||
*/
|
*/
|
||||||
if (AllocNew) {
|
if (AllocNew) {
|
||||||
Sym = NewSymEntry (Ident, SF_NONE);
|
Sym = NewSymEntry (&Ident, SF_NONE);
|
||||||
} else {
|
} else {
|
||||||
Sym = 0;
|
Sym = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Deallocate memory for ident */
|
||||||
|
SB_Done (&Ident);
|
||||||
|
|
||||||
/* Return the symbol found */
|
/* Return the symbol found */
|
||||||
return Sym;
|
return Sym;
|
||||||
}
|
}
|
||||||
@@ -209,19 +208,19 @@ SymTable* ParseScopedSymTable (void)
|
|||||||
* symbol space and return the symbol table struct.
|
* symbol space and return the symbol table struct.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
StrBuf ScopeName = AUTO_STRBUF_INITIALIZER;
|
StrBuf ScopeName = STATIC_STRBUF_INITIALIZER;
|
||||||
char Name[sizeof (SVal)];
|
StrBuf Name = STATIC_STRBUF_INITIALIZER;
|
||||||
int NoScope;
|
int NoScope;
|
||||||
|
|
||||||
|
|
||||||
/* Parse the scoped symbol name */
|
/* Parse the scoped symbol name */
|
||||||
SymTable* Scope = ParseScopedIdent (Name, &ScopeName);
|
SymTable* Scope = ParseScopedIdent (&Name, &ScopeName);
|
||||||
|
|
||||||
/* If ScopeName is empty, no scope was specified */
|
/* If ScopeName is empty, no scope was specified */
|
||||||
NoScope = SB_IsEmpty (&ScopeName);
|
NoScope = SB_IsEmpty (&ScopeName);
|
||||||
|
|
||||||
/* We don't need FullName any longer */
|
/* We don't need FullName any longer */
|
||||||
DoneStrBuf (&ScopeName);
|
SB_Done (&ScopeName);
|
||||||
|
|
||||||
/* If we got no error, search for the child scope withint the enclosing one.
|
/* If we got no error, search for the child scope withint the enclosing one.
|
||||||
* Beware: If no explicit parent scope was specified, search in all upper
|
* Beware: If no explicit parent scope was specified, search in all upper
|
||||||
@@ -230,11 +229,16 @@ SymTable* ParseScopedSymTable (void)
|
|||||||
if (Scope) {
|
if (Scope) {
|
||||||
/* Search for the last scope */
|
/* Search for the last scope */
|
||||||
if (NoScope) {
|
if (NoScope) {
|
||||||
Scope = SymFindAnyScope (Scope, Name);
|
Scope = SymFindAnyScope (Scope, &Name);
|
||||||
} else {
|
} else {
|
||||||
Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
|
Scope = SymFindScope (Scope, &Name, SYM_FIND_EXISTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Free memory for name */
|
||||||
|
SB_Done (&Name);
|
||||||
|
|
||||||
|
/* Return the scope found */
|
||||||
return Scope;
|
return Scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -55,14 +55,13 @@ struct SymTable;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct SymTable* ParseScopedIdent (char* Name, struct StrBuf* FullName);
|
struct SymTable* ParseScopedIdent (struct StrBuf* Name, struct StrBuf* FullName);
|
||||||
/* Parse a (possibly scoped) identifer. Name must point to a buffer big enough
|
/* Parse a (possibly scoped) identifer. The scope of the name must exist and
|
||||||
* to hold such an identifier. The scope of the name must exist and is returned
|
* is returned as function result, while the last part (the identifier) which
|
||||||
* as function result, while the last part (the identifier) which may be either
|
* may be either a symbol or a scope depending on the context is returned in
|
||||||
* a symbol or a scope depending on the context is returned in Name. FullName
|
* Name. FullName is a string buffer that is used to store the full name of
|
||||||
* is a string buffer that is used to store the full name of the identifier
|
* the identifier including the scope. It is used internally and may be used
|
||||||
* including the scope. It is used internally and may be used by the caller
|
* by the caller for error messages or similar.
|
||||||
* for error messages or similar.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct SymEntry* ParseScopedSymName (int AllowNew);
|
struct SymEntry* ParseScopedSymName (int AllowNew);
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
/* */
|
/* */
|
||||||
/* symentry.c */
|
/* symentry.c */
|
||||||
/* */
|
/* */
|
||||||
/* Symbol table entry forward for the ca65 macroassembler */
|
/* Symbol table entry for the ca65 macroassembler */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -72,7 +72,7 @@ SymEntry* SymLast = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymEntry* NewSymEntry (const char* Name, unsigned Flags)
|
SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
|
||||||
/* Allocate a symbol table entry, initialize and return it */
|
/* Allocate a symbol table entry, initialize and return it */
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
@@ -95,7 +95,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
|
|||||||
S->ExportSize = ADDR_SIZE_DEFAULT;
|
S->ExportSize = ADDR_SIZE_DEFAULT;
|
||||||
S->AddrSize = ADDR_SIZE_DEFAULT;
|
S->AddrSize = ADDR_SIZE_DEFAULT;
|
||||||
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
|
memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
|
||||||
S->Name = GetStringId (Name);
|
S->Name = GetStrBufId (Name);
|
||||||
|
|
||||||
/* Insert it into the list of all entries */
|
/* Insert it into the list of all entries */
|
||||||
S->List = SymList;
|
S->List = SymList;
|
||||||
@@ -107,7 +107,7 @@ SymEntry* NewSymEntry (const char* Name, unsigned Flags)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E)
|
int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
|
||||||
/* Search in the given tree for a name. If we find the symbol, the function
|
/* Search in the given tree for a name. If we find the symbol, the function
|
||||||
* will return 0 and put the entry pointer into E. If we did not find the
|
* will return 0 and put the entry pointer into E. If we did not find the
|
||||||
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
|
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
|
||||||
@@ -126,10 +126,10 @@ int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E)
|
|||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Get the symbol name */
|
/* Get the symbol name */
|
||||||
const char* SymName = GetString (T->Name);
|
const StrBuf* SymName = GetStrBuf (T->Name);
|
||||||
|
|
||||||
/* Choose next entry */
|
/* Choose next entry */
|
||||||
int Cmp = strcmp (Name, SymName);
|
int Cmp = SB_Compare (Name, SymName);
|
||||||
if (Cmp < 0 && T->Left) {
|
if (Cmp < 0 && T->Left) {
|
||||||
T = T->Left;
|
T = T->Left;
|
||||||
} else if (Cmp > 0&& T->Right) {
|
} else if (Cmp > 0&& T->Right) {
|
||||||
@@ -216,24 +216,24 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
|||||||
{
|
{
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
/* Defined symbol is marked as imported external symbol */
|
/* Defined symbol is marked as imported external symbol */
|
||||||
Error ("Symbol `%s' is already an import", GetSymName (S));
|
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
|
if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
|
||||||
/* Variable symbols cannot be exports or globals */
|
/* Variable symbols cannot be exports or globals */
|
||||||
Error ("Var symbol `%s' cannot be an export or global symbol", GetSymName (S));
|
Error ("Var symbol `%m%p' cannot be an export or global symbol", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (S->Flags & SF_DEFINED) {
|
if (S->Flags & SF_DEFINED) {
|
||||||
/* Multiple definition. In case of a variable, this is legal. */
|
/* Multiple definition. In case of a variable, this is legal. */
|
||||||
if ((S->Flags & SF_VAR) == 0) {
|
if ((S->Flags & SF_VAR) == 0) {
|
||||||
Error ("Symbol `%s' is already defined", GetSymName (S));
|
Error ("Symbol `%m%p' is already defined", GetSymName (S));
|
||||||
S->Flags |= SF_MULTDEF;
|
S->Flags |= SF_MULTDEF;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/* Redefinition must also be a variable symbol */
|
/* Redefinition must also be a variable symbol */
|
||||||
if ((Flags & SF_VAR) == 0) {
|
if ((Flags & SF_VAR) == 0) {
|
||||||
Error ("Symbol `%s' is already different kind", GetSymName (S));
|
Error ("Symbol `%m%p' is already different kind", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Delete the current symbol expression, since it will get
|
/* Delete the current symbol expression, since it will get
|
||||||
@@ -284,7 +284,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
|
|||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} else if (S->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
PWarning (GetSymPos (S), 1, "Symbol `%s' is %s but exported %s",
|
PWarning (GetSymPos (S), 1, "Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
@@ -302,13 +302,13 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
/* Mark the given symbol as an imported symbol */
|
/* Mark the given symbol as an imported symbol */
|
||||||
{
|
{
|
||||||
if (S->Flags & SF_DEFINED) {
|
if (S->Flags & SF_DEFINED) {
|
||||||
Error ("Symbol `%s' is already defined", GetSymName (S));
|
Error ("Symbol `%m%p' is already defined", GetSymName (S));
|
||||||
S->Flags |= SF_MULTDEF;
|
S->Flags |= SF_MULTDEF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (S->Flags & SF_EXPORT) {
|
if (S->Flags & SF_EXPORT) {
|
||||||
/* The symbol is already marked as exported symbol */
|
/* The symbol is already marked as exported symbol */
|
||||||
Error ("Cannot import exported symbol `%s'", GetSymName (S));
|
Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,16 +324,16 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
*/
|
*/
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
|
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
|
||||||
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
|
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
if (AddrSize != S->AddrSize) {
|
if (AddrSize != S->AddrSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (S->Flags & SF_GLOBAL) {
|
if (S->Flags & SF_GLOBAL) {
|
||||||
S->Flags &= ~SF_GLOBAL;
|
S->Flags &= ~SF_GLOBAL;
|
||||||
if (AddrSize != S->AddrSize) {
|
if (AddrSize != S->AddrSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,12 +350,12 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
/* Check if it's ok to export the symbol */
|
/* Check if it's ok to export the symbol */
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
/* The symbol is already marked as imported external symbol */
|
/* The symbol is already marked as imported external symbol */
|
||||||
Error ("Symbol `%s' is already an import", GetSymName (S));
|
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (S->Flags & SF_VAR) {
|
if (S->Flags & SF_VAR) {
|
||||||
/* Variable symbols cannot be exported */
|
/* Variable symbols cannot be exported */
|
||||||
Error ("Var symbol `%s' cannot be exported", GetSymName (S));
|
Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
*/
|
*/
|
||||||
if (S->Flags & SF_GLOBAL) {
|
if (S->Flags & SF_GLOBAL) {
|
||||||
if (AddrSize != S->ExportSize) {
|
if (AddrSize != S->ExportSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
S->Flags &= ~SF_GLOBAL;
|
S->Flags &= ~SF_GLOBAL;
|
||||||
}
|
}
|
||||||
@@ -374,7 +374,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
*/
|
*/
|
||||||
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
|
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
|
||||||
if (S->ExportSize != AddrSize) {
|
if (S->ExportSize != AddrSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
S->ExportSize = AddrSize;
|
S->ExportSize = AddrSize;
|
||||||
@@ -388,7 +388,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} else if (S->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
Warning (1, "Symbol `%s' is %s but exported %s",
|
Warning (1, "Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
@@ -407,7 +407,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
{
|
{
|
||||||
if (S->Flags & SF_VAR) {
|
if (S->Flags & SF_VAR) {
|
||||||
/* Variable symbols cannot be exported or imported */
|
/* Variable symbols cannot be exported or imported */
|
||||||
Error ("Var symbol `%s' cannot be made global", GetSymName (S));
|
Error ("Var symbol `%m%p' cannot be made global", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,7 +420,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
AddrSize = GetCurrentSegAddrSize ();
|
AddrSize = GetCurrentSegAddrSize ();
|
||||||
}
|
}
|
||||||
if (AddrSize != S->AddrSize) {
|
if (AddrSize != S->AddrSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -432,12 +432,12 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
if ((S->Flags & SF_DEFINED) == 0) {
|
if ((S->Flags & SF_DEFINED) == 0) {
|
||||||
/* Symbol is undefined */
|
/* Symbol is undefined */
|
||||||
if (AddrSize != S->ExportSize) {
|
if (AddrSize != S->ExportSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
} else if (AddrSize != ADDR_SIZE_DEFAULT) {
|
} else if (AddrSize != ADDR_SIZE_DEFAULT) {
|
||||||
/* Symbol is defined and address size given */
|
/* Symbol is defined and address size given */
|
||||||
if (AddrSize != S->ExportSize) {
|
if (AddrSize != S->ExportSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -449,7 +449,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
*/
|
*/
|
||||||
if (S->Flags & SF_GLOBAL) {
|
if (S->Flags & SF_GLOBAL) {
|
||||||
if (AddrSize != S->ExportSize) {
|
if (AddrSize != S->ExportSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -467,7 +467,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
|
|||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize > S->ExportSize) {
|
} else if (S->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
Warning (1, "Symbol `%s' is %s but exported %s",
|
Warning (1, "Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
@@ -505,12 +505,12 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
|||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
if (S->Flags & SF_IMPORT) {
|
if (S->Flags & SF_IMPORT) {
|
||||||
/* The symbol is already marked as imported external symbol */
|
/* The symbol is already marked as imported external symbol */
|
||||||
Error ("Symbol `%s' is already an import", GetSymName (S));
|
Error ("Symbol `%m%p' is already an import", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (S->Flags & SF_VAR) {
|
if (S->Flags & SF_VAR) {
|
||||||
/* Variable symbols cannot be exported or imported */
|
/* Variable symbols cannot be exported or imported */
|
||||||
Error ("Var symbol `%s' cannot be exported", GetSymName (S));
|
Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +520,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
|||||||
*/
|
*/
|
||||||
if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
|
if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
|
||||||
if (S->ExportSize != AddrSize) {
|
if (S->ExportSize != AddrSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
S->Flags &= ~SF_GLOBAL;
|
S->Flags &= ~SF_GLOBAL;
|
||||||
}
|
}
|
||||||
@@ -534,7 +534,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
|||||||
/* Use the real size of the symbol */
|
/* Use the real size of the symbol */
|
||||||
S->ExportSize = S->AddrSize;
|
S->ExportSize = S->AddrSize;
|
||||||
} else if (S->AddrSize != S->ExportSize) {
|
} else if (S->AddrSize != S->ExportSize) {
|
||||||
Error ("Address size mismatch for symbol `%s'", GetSymName (S));
|
Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +543,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
|
|||||||
*/
|
*/
|
||||||
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
|
||||||
if (S->ConDesPrio[Type] != Prio) {
|
if (S->ConDesPrio[Type] != Prio) {
|
||||||
Error ("Redeclaration mismatch for symbol `%s'", GetSymName (S));
|
Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
S->ConDesPrio[Type] = Prio;
|
S->ConDesPrio[Type] = Prio;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2006 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
#include "filepos.h"
|
#include "filepos.h"
|
||||||
#include "inline.h"
|
#include "inline.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
#include "spool.h"
|
#include "spool.h"
|
||||||
@@ -97,7 +98,7 @@ struct SymEntry {
|
|||||||
unsigned char ExportSize; /* Export address size */
|
unsigned char ExportSize; /* Export address size */
|
||||||
unsigned char AddrSize; /* Address size of label */
|
unsigned char AddrSize; /* Address size of label */
|
||||||
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
|
unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
|
||||||
/* ...actually value+1 (used as flag) */
|
/* ...actually value+1 (used as flag) */
|
||||||
unsigned Name; /* Name index in global string pool */
|
unsigned Name; /* Name index in global string pool */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -115,10 +116,10 @@ extern SymEntry* SymLast;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymEntry* NewSymEntry (const char* Name, unsigned Flags);
|
SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags);
|
||||||
/* Allocate a symbol table entry, initialize and return it */
|
/* Allocate a symbol table entry, initialize and return it */
|
||||||
|
|
||||||
int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E);
|
int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E);
|
||||||
/* Search in the given tree for a name. If we find the symbol, the function
|
/* Search in the given tree for a name. If we find the symbol, the function
|
||||||
* will return 0 and put the entry pointer into E. If we did not find the
|
* will return 0 and put the entry pointer into E. If we did not find the
|
||||||
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
|
* symbol, and the tree is empty, E is set to NULL. If the tree is not empty,
|
||||||
@@ -305,10 +306,10 @@ const struct ExprNode* SymResolve (const SymEntry* Sym);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE const char* GetSymName (const SymEntry* S)
|
INLINE const StrBuf* GetSymName (const SymEntry* S)
|
||||||
/* Return the name of the symbol */
|
/* Return the name of the symbol */
|
||||||
{
|
{
|
||||||
return GetString (S->Name);
|
return GetStrBuf (S->Name);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetSymName(S) GetString ((S)->Name)
|
# define GetSymName(S) GetString ((S)->Name)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2006 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -97,7 +97,7 @@ static unsigned ScopeTableSize (unsigned Level)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static SymTable* NewSymTable (SymTable* Parent, const char* Name)
|
static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
|
||||||
/* Allocate a symbol table on the heap and return it */
|
/* Allocate a symbol table on the heap and return it */
|
||||||
{
|
{
|
||||||
/* Determine the lexical level and the number of table slots */
|
/* Determine the lexical level and the number of table slots */
|
||||||
@@ -119,7 +119,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
|
|||||||
S->TableSlots = Slots;
|
S->TableSlots = Slots;
|
||||||
S->TableEntries = 0;
|
S->TableEntries = 0;
|
||||||
S->Parent = Parent;
|
S->Parent = Parent;
|
||||||
S->Name = GetStringId (Name);
|
S->Name = GetStrBufId (Name);
|
||||||
while (Slots--) {
|
while (Slots--) {
|
||||||
S->Table[Slots] = 0;
|
S->Table[Slots] = 0;
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
|
|||||||
} else {
|
} else {
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Choose next entry */
|
/* Choose next entry */
|
||||||
int Cmp = strcmp (Name, GetString (T->Name));
|
int Cmp = SB_Compare (Name, GetStrBuf (T->Name));
|
||||||
if (Cmp < 0) {
|
if (Cmp < 0) {
|
||||||
if (T->Left) {
|
if (T->Left) {
|
||||||
T = T->Left;
|
T = T->Left;
|
||||||
@@ -150,7 +150,7 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Duplicate scope name */
|
/* Duplicate scope name */
|
||||||
Internal ("Duplicate scope name: `%s'", Name);
|
Internal ("Duplicate scope name: `%m%p'", Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,12 +163,12 @@ static SymTable* NewSymTable (SymTable* Parent, const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char AddrSize)
|
void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, unsigned char AddrSize)
|
||||||
/* Enter a new lexical level */
|
/* Enter a new lexical level */
|
||||||
{
|
{
|
||||||
/* Map a default address size to something real */
|
/* Map a default address size to something real */
|
||||||
@@ -187,7 +187,7 @@ void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char Add
|
|||||||
|
|
||||||
/* Check if the scope has been defined before */
|
/* Check if the scope has been defined before */
|
||||||
if (CurrentScope->Flags & ST_DEFINED) {
|
if (CurrentScope->Flags & ST_DEFINED) {
|
||||||
Error ("Duplicate scope `%s'", ScopeName);
|
Error ("Duplicate scope `%m%p'", ScopeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -235,12 +235,12 @@ void SymLeaveLevel (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew)
|
SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, int AllocNew)
|
||||||
/* Find a scope in the given enclosing scope */
|
/* Find a scope in the given enclosing scope */
|
||||||
{
|
{
|
||||||
SymTable** T = &Parent->Childs;
|
SymTable** T = &Parent->Childs;
|
||||||
while (*T) {
|
while (*T) {
|
||||||
int Cmp = strcmp (Name, GetString ((*T)->Name));
|
int Cmp = SB_Compare (Name, GetStrBuf ((*T)->Name));
|
||||||
if (Cmp < 0) {
|
if (Cmp < 0) {
|
||||||
T = &(*T)->Left;
|
T = &(*T)->Left;
|
||||||
} else if (Cmp > 0) {
|
} else if (Cmp > 0) {
|
||||||
@@ -262,7 +262,7 @@ SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymTable* SymFindAnyScope (SymTable* Parent, const char* Name)
|
SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name)
|
||||||
/* Find a scope in the given or any of its parent scopes. The function will
|
/* Find a scope in the given or any of its parent scopes. The function will
|
||||||
* never create a new symbol, since this can only be done in one specific
|
* never create a new symbol, since this can only be done in one specific
|
||||||
* scope.
|
* scope.
|
||||||
@@ -283,7 +283,7 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew)
|
SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* Name, int AllocNew)
|
||||||
/* Find a cheap local symbol. If AllocNew is given and the entry is not
|
/* Find a cheap local symbol. If AllocNew is given and the entry is not
|
||||||
* found, create a new one. Return the entry found, or the new entry created,
|
* found, create a new one. Return the entry found, or the new entry created,
|
||||||
* or - in case AllocNew is zero - return 0.
|
* or - in case AllocNew is zero - return 0.
|
||||||
@@ -331,7 +331,7 @@ SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
|
SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew)
|
||||||
/* Find a new symbol table entry in the given table. If AllocNew is given and
|
/* Find a new symbol table entry in the given table. If AllocNew is given and
|
||||||
* the entry is not found, create a new one. Return the entry found, or the
|
* the entry is not found, create a new one. Return the entry found, or the
|
||||||
* new entry created, or - in case AllocNew is zero - return 0.
|
* new entry created, or - in case AllocNew is zero - return 0.
|
||||||
@@ -340,7 +340,7 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
|
|||||||
SymEntry* S;
|
SymEntry* S;
|
||||||
|
|
||||||
/* Global symbol: Get the hash value for the name */
|
/* Global symbol: Get the hash value for the name */
|
||||||
unsigned Hash = HashStr (Name) % Scope->TableSlots;
|
unsigned Hash = HashBuf (Name) % Scope->TableSlots;
|
||||||
|
|
||||||
/* Search for the entry */
|
/* Search for the entry */
|
||||||
int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
|
int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
|
||||||
@@ -373,7 +373,7 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymEntry* SymFindAny (SymTable* Scope, const char* Name)
|
SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name)
|
||||||
/* Find a symbol in the given or any of its parent scopes. The function will
|
/* Find a symbol in the given or any of its parent scopes. The function will
|
||||||
* never create a new symbol, since this can only be done in one specific
|
* never create a new symbol, since this can only be done in one specific
|
||||||
* scope.
|
* scope.
|
||||||
@@ -424,7 +424,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
SymEntry* Sym = 0;
|
SymEntry* Sym = 0;
|
||||||
SymTable* Tab = GetSymParentScope (S);
|
SymTable* Tab = GetSymParentScope (S);
|
||||||
while (Tab) {
|
while (Tab) {
|
||||||
Sym = SymFind (Tab, GetString (S->Name), SYM_FIND_EXISTING);
|
Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING);
|
||||||
if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) {
|
if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) {
|
||||||
/* We've found a symbol in a higher level that is
|
/* We've found a symbol in a higher level that is
|
||||||
* either defined in the source, or an import.
|
* either defined in the source, or an import.
|
||||||
@@ -451,8 +451,9 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
/* The symbol is already marked as an export. */
|
/* The symbol is already marked as an export. */
|
||||||
if (Sym->AddrSize > S->ExportSize) {
|
if (Sym->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
|
PWarning (&S->Pos, 1, "Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
|
GetSymName (Sym),
|
||||||
|
AddrSizeToStr (Sym->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -465,8 +466,9 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
}
|
}
|
||||||
if (Sym->AddrSize > Sym->ExportSize) {
|
if (Sym->AddrSize > Sym->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
|
PWarning (&S->Pos, 1, "Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
|
GetSymName (Sym),
|
||||||
|
AddrSizeToStr (Sym->AddrSize),
|
||||||
AddrSizeToStr (Sym->ExportSize));
|
AddrSizeToStr (Sym->ExportSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,8 +485,8 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
/* The symbol is definitely undefined */
|
/* The symbol is definitely undefined */
|
||||||
if (S->Flags & SF_EXPORT) {
|
if (S->Flags & SF_EXPORT) {
|
||||||
/* We will not auto-import an export */
|
/* We will not auto-import an export */
|
||||||
PError (&S->Pos, "Exported symbol `%s' was never defined",
|
PError (&S->Pos, "Exported symbol `%m%p' was never defined",
|
||||||
GetString (S->Name));
|
GetSymName (S));
|
||||||
} else {
|
} else {
|
||||||
if (AutoImport) {
|
if (AutoImport) {
|
||||||
/* Mark as import, will be indexed later */
|
/* Mark as import, will be indexed later */
|
||||||
@@ -493,7 +495,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
S->AddrSize = CodeAddrSize;
|
S->AddrSize = CodeAddrSize;
|
||||||
} else {
|
} else {
|
||||||
/* Error */
|
/* Error */
|
||||||
PError (&S->Pos, "Symbol `%s' is undefined", GetString (S->Name));
|
PError (&S->Pos, "Symbol `%m%p' is undefined", GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,11 +551,11 @@ void SymCheck (void)
|
|||||||
|
|
||||||
/* Check for defined symbols that were never referenced */
|
/* Check for defined symbols that were never referenced */
|
||||||
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
|
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
|
||||||
const char* Name = GetString (S->Name);
|
const StrBuf* Name = GetStrBuf (S->Name);
|
||||||
if (Name[0] != '.') { /* Ignore internals */
|
if (SB_At (Name, 0) != '.') { /* Ignore internals */
|
||||||
PWarning (&S->Pos, 2,
|
PWarning (&S->Pos, 2,
|
||||||
"Symbol `%s' is defined but never used",
|
"Symbol `%m%p' is defined but never used",
|
||||||
GetString (S->Name));
|
GetSymName (S));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,8 +564,8 @@ void SymCheck (void)
|
|||||||
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
|
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
|
||||||
/* Imported symbol is not referenced */
|
/* Imported symbol is not referenced */
|
||||||
PWarning (&S->Pos, 2,
|
PWarning (&S->Pos, 2,
|
||||||
"Symbol `%s' is imported but never used",
|
"Symbol `%m%p' is imported but never used",
|
||||||
GetString (S->Name));
|
GetSymName (S));
|
||||||
} else {
|
} else {
|
||||||
/* Give the import an index, count imports */
|
/* Give the import an index, count imports */
|
||||||
S->Index = ImportCount++;
|
S->Index = ImportCount++;
|
||||||
@@ -593,8 +595,9 @@ void SymCheck (void)
|
|||||||
} else if (S->AddrSize > S->ExportSize) {
|
} else if (S->AddrSize > S->ExportSize) {
|
||||||
/* We're exporting a symbol smaller than it actually is */
|
/* We're exporting a symbol smaller than it actually is */
|
||||||
PWarning (&S->Pos, 1,
|
PWarning (&S->Pos, 1,
|
||||||
"Symbol `%s' is %s but exported %s",
|
"Symbol `%m%p' is %s but exported %s",
|
||||||
GetSymName (S), AddrSizeToStr (S->AddrSize),
|
GetSymName (S),
|
||||||
|
AddrSizeToStr (S->AddrSize),
|
||||||
AddrSizeToStr (S->ExportSize));
|
AddrSizeToStr (S->ExportSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,7 +615,7 @@ void SymCheck (void)
|
|||||||
const FilePos* P = S->GuessedUse[S->AddrSize - 1];
|
const FilePos* P = S->GuessedUse[S->AddrSize - 1];
|
||||||
if (P) {
|
if (P) {
|
||||||
PWarning (P, 0,
|
PWarning (P, 0,
|
||||||
"Didn't use %s addressing for `%s'",
|
"Didn't use %s addressing for `%m%p'",
|
||||||
AddrSizeToStr (S->AddrSize),
|
AddrSizeToStr (S->AddrSize),
|
||||||
GetSymName (S));
|
GetSymName (S));
|
||||||
}
|
}
|
||||||
@@ -637,8 +640,8 @@ void SymDump (FILE* F)
|
|||||||
/* Ignore unused symbols */
|
/* Ignore unused symbols */
|
||||||
if ((S->Flags & SF_UNUSED) != 0) {
|
if ((S->Flags & SF_UNUSED) != 0) {
|
||||||
fprintf (F,
|
fprintf (F,
|
||||||
"%-24s %s %s %s %s %s\n",
|
"%m%-24p %s %s %s %s %s\n",
|
||||||
GetString (S->Name),
|
GetSymName (S),
|
||||||
(S->Flags & SF_DEFINED)? "DEF" : "---",
|
(S->Flags & SF_DEFINED)? "DEF" : "---",
|
||||||
(S->Flags & SF_REFERENCED)? "REF" : "---",
|
(S->Flags & SF_REFERENCED)? "REF" : "---",
|
||||||
(S->Flags & SF_IMPORT)? "IMP" : "---",
|
(S->Flags & SF_IMPORT)? "IMP" : "---",
|
||||||
@@ -842,3 +845,5 @@ void WriteScopes (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -101,34 +101,34 @@ extern SymTable* RootScope; /* Root symbol table */
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SymEnterLevel (const char* ScopeName, unsigned char Type, unsigned char AddrSize);
|
void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type, unsigned char AddrSize);
|
||||||
/* Enter a new lexical level */
|
/* Enter a new lexical level */
|
||||||
|
|
||||||
void SymLeaveLevel (void);
|
void SymLeaveLevel (void);
|
||||||
/* Leave the current lexical level */
|
/* Leave the current lexical level */
|
||||||
|
|
||||||
SymTable* SymFindScope (SymTable* Parent, const char* Name, int AllocNew);
|
SymTable* SymFindScope (SymTable* Parent, const StrBuf* Name, int AllocNew);
|
||||||
/* Find a scope in the given enclosing scope */
|
/* Find a scope in the given enclosing scope */
|
||||||
|
|
||||||
SymTable* SymFindAnyScope (SymTable* Parent, const char* Name);
|
SymTable* SymFindAnyScope (SymTable* Parent, const StrBuf* Name);
|
||||||
/* Find a scope in the given or any of its parent scopes. The function will
|
/* Find a scope in the given or any of its parent scopes. The function will
|
||||||
* never create a new symbol, since this can only be done in one specific
|
* never create a new symbol, since this can only be done in one specific
|
||||||
* scope.
|
* scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew);
|
SymEntry* SymFindLocal (SymEntry* Parent, const StrBuf* StrBuf, int AllocNew);
|
||||||
/* Find a cheap local symbol. If AllocNew is given and the entry is not
|
/* Find a cheap local symbol. If AllocNew is given and the entry is not
|
||||||
* found, create a new one. Return the entry found, or the new entry created,
|
* found, create a new one. Return the entry found, or the new entry created,
|
||||||
* or - in case AllocNew is zero - return 0.
|
* or - in case AllocNew is zero - return 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew);
|
SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew);
|
||||||
/* Find a new symbol table entry in the given table. If AllocNew is given and
|
/* Find a new symbol table entry in the given table. If AllocNew is given and
|
||||||
* the entry is not found, create a new one. Return the entry found, or the
|
* the entry is not found, create a new one. Return the entry found, or the
|
||||||
* new entry created, or - in case AllocNew is zero - return 0.
|
* new entry created, or - in case AllocNew is zero - return 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SymEntry* SymFindAny (SymTable* Scope, const char* Name);
|
SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name);
|
||||||
/* Find a symbol in the given or any of its parent scopes. The function will
|
/* Find a symbol in the given or any of its parent scopes. The function will
|
||||||
* never create a new symbol, since this can only be done in one specific
|
* never create a new symbol, since this can only be done in one specific
|
||||||
* scope.
|
* scope.
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
int TokHasSVal (Token Tok)
|
int TokHasSVal (Token Tok)
|
||||||
/* Return true if the given token has an attached SVal */
|
/* Return true if the given token has an attached SVal */
|
||||||
{
|
{
|
||||||
return (Tok == TOK_IDENT || TOK_LOCAL_IDENT || Tok == TOK_STRCON);
|
return (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT || Tok == TOK_STRCON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -60,16 +60,15 @@ TokNode* NewTokNode (void)
|
|||||||
TokNode* T;
|
TokNode* T;
|
||||||
|
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
unsigned Len = TokHasSVal (Tok)? strlen (SVal) : 0;
|
T = xmalloc (sizeof (TokNode));
|
||||||
T = xmalloc (sizeof (TokNode) + Len);
|
|
||||||
|
|
||||||
/* Initialize the token contents */
|
/* Initialize the token contents */
|
||||||
T->Next = 0;
|
T->Next = 0;
|
||||||
T->Tok = Tok;
|
T->Tok = Tok;
|
||||||
T->WS = WS;
|
T->WS = WS;
|
||||||
T->IVal = IVal;
|
T->IVal = IVal;
|
||||||
memcpy (T->SVal, SVal, Len);
|
T->SVal = AUTO_STRBUF_INITIALIZER;
|
||||||
T->SVal [Len] = '\0';
|
SB_Copy (&T->SVal, &SVal);
|
||||||
|
|
||||||
/* Return the node */
|
/* Return the node */
|
||||||
return T;
|
return T;
|
||||||
@@ -80,6 +79,7 @@ TokNode* NewTokNode (void)
|
|||||||
void FreeTokNode (TokNode* T)
|
void FreeTokNode (TokNode* T)
|
||||||
/* Free the given token node */
|
/* Free the given token node */
|
||||||
{
|
{
|
||||||
|
SB_Done (&T->SVal);
|
||||||
xfree (T);
|
xfree (T);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ void TokSet (TokNode* T)
|
|||||||
Tok = T->Tok;
|
Tok = T->Tok;
|
||||||
WS = T->WS;
|
WS = T->WS;
|
||||||
IVal = T->IVal;
|
IVal = T->IVal;
|
||||||
strcpy (SVal, T->SVal);
|
SB_Copy (&SVal, &T->SVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ enum TC TokCmp (const TokNode* T)
|
|||||||
|
|
||||||
/* If the token has string attribute, check it */
|
/* If the token has string attribute, check it */
|
||||||
if (TokHasSVal (T->Tok)) {
|
if (TokHasSVal (T->Tok)) {
|
||||||
if (strcmp (T->SVal, SVal) != 0) {
|
if (SB_Compare (&SVal, &T->SVal) != 0) {
|
||||||
return tcSameToken;
|
return tcSameToken;
|
||||||
}
|
}
|
||||||
} else if (TokHasIVal (T->Tok)) {
|
} else if (TokHasIVal (T->Tok)) {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2007 Ullrich von Bassewitz */
|
/* (C) 2000-2008, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -38,6 +38,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
/* ca65 */
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +59,7 @@ struct TokNode {
|
|||||||
Token Tok; /* Token value */
|
Token Tok; /* Token value */
|
||||||
int WS; /* Whitespace before token? */
|
int WS; /* Whitespace before token? */
|
||||||
long IVal; /* Integer token attribute */
|
long IVal; /* Integer token attribute */
|
||||||
char SVal [1]; /* String attribute, dyn. allocated */
|
StrBuf SVal; /* String attribute, dyn. allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Struct holding a token list */
|
/* Struct holding a token list */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2001-2004 Ullrich von Bassewitz */
|
/* (C) 2001-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
/* */
|
/* */
|
||||||
@@ -415,8 +415,8 @@ static void ParseAsm (void)
|
|||||||
|
|
||||||
Done:
|
Done:
|
||||||
/* Call the string buf destructors */
|
/* Call the string buf destructors */
|
||||||
DoneStrBuf (&S);
|
SB_Done (&S);
|
||||||
DoneStrBuf (&T);
|
SB_Done (&T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2001-2006, Ullrich von Bassewitz */
|
/* (C) 2001-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -541,7 +541,7 @@ void CS_AddVLine (CodeSeg* S, LineInfo* LI, const char* Format, va_list ap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup the string buffer */
|
/* Cleanup the string buffer */
|
||||||
DoneStrBuf (&Buf);
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2005, Ullrich von Bassewitz */
|
/* (C) 2000-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -81,7 +81,7 @@ Macro* NewMacro (const char* Name)
|
|||||||
M->ArgCount = -1; /* Flag: Not a function like macro */
|
M->ArgCount = -1; /* Flag: Not a function like macro */
|
||||||
M->MaxArgs = 0;
|
M->MaxArgs = 0;
|
||||||
InitCollection (&M->FormalArgs);
|
InitCollection (&M->FormalArgs);
|
||||||
InitStrBuf (&M->Replacement);
|
SB_Init (&M->Replacement);
|
||||||
M->Variadic = 0;
|
M->Variadic = 0;
|
||||||
memcpy (M->Name, Name, Len+1);
|
memcpy (M->Name, Name, Len+1);
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ void FreeMacro (Macro* M)
|
|||||||
xfree (CollAtUnchecked (&M->FormalArgs, I));
|
xfree (CollAtUnchecked (&M->FormalArgs, I));
|
||||||
}
|
}
|
||||||
DoneCollection (&M->FormalArgs);
|
DoneCollection (&M->FormalArgs);
|
||||||
DoneStrBuf (&M->Replacement);
|
SB_Done (&M->Replacement);
|
||||||
xfree (M);
|
xfree (M);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -153,7 +153,7 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Call the string buf destructor */
|
/* Call the string buf destructor */
|
||||||
DoneStrBuf (&S);
|
SB_Done (&S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
|||||||
g_segname (Seg);
|
g_segname (Seg);
|
||||||
|
|
||||||
/* Call the string buf destructor */
|
/* Call the string buf destructor */
|
||||||
DoneStrBuf (&S);
|
SB_Done (&S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -494,7 +494,7 @@ static void ParsePragma (void)
|
|||||||
FlagPragma (&B, &WarnDisable);
|
FlagPragma (&B, &WarnDisable);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PR_ZPSYM:
|
case PR_ZPSYM:
|
||||||
StringPragma (&B, MakeZPSym);
|
StringPragma (&B, MakeZPSym);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -522,7 +522,7 @@ static void ParsePragma (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Release the StrBuf */
|
/* Release the StrBuf */
|
||||||
DoneStrBuf (&B);
|
SB_Done (&B);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2007, Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -189,7 +189,7 @@ static MacroExp* InitMacroExp (MacroExp* E, Macro* M)
|
|||||||
/* Initialize a MacroExp structure */
|
/* Initialize a MacroExp structure */
|
||||||
{
|
{
|
||||||
InitCollection (&E->ActualArgs);
|
InitCollection (&E->ActualArgs);
|
||||||
InitStrBuf (&E->Replacement);
|
SB_Init (&E->Replacement);
|
||||||
E->M = M;
|
E->M = M;
|
||||||
return E;
|
return E;
|
||||||
}
|
}
|
||||||
@@ -206,7 +206,7 @@ static void DoneMacroExp (MacroExp* E)
|
|||||||
FreeStrBuf (CollAtUnchecked (&E->ActualArgs, I));
|
FreeStrBuf (CollAtUnchecked (&E->ActualArgs, I));
|
||||||
}
|
}
|
||||||
DoneCollection (&E->ActualArgs);
|
DoneCollection (&E->ActualArgs);
|
||||||
DoneStrBuf (&E->Replacement);
|
SB_Done (&E->Replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -488,7 +488,7 @@ static void ReadMacroArgs (MacroExp* E)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Deallocate string buf resources */
|
/* Deallocate string buf resources */
|
||||||
DoneStrBuf (&Arg);
|
SB_Done (&Arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1145,7 +1145,7 @@ static void DoInclude (void)
|
|||||||
|
|
||||||
Done:
|
Done:
|
||||||
/* Free the allocated filename data */
|
/* Free the allocated filename data */
|
||||||
DoneStrBuf (&Filename);
|
SB_Done (&Filename);
|
||||||
|
|
||||||
/* Clear the remaining line so the next input will come from the new
|
/* Clear the remaining line so the next input will come from the new
|
||||||
* file (if open)
|
* file (if open)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -442,7 +442,7 @@ static void NumericConst (void)
|
|||||||
{
|
{
|
||||||
unsigned Base; /* Temporary number base */
|
unsigned Base; /* Temporary number base */
|
||||||
unsigned Prefix; /* Base according to prefix */
|
unsigned Prefix; /* Base according to prefix */
|
||||||
StrBuf S;
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
int IsFloat;
|
int IsFloat;
|
||||||
char C;
|
char C;
|
||||||
unsigned DigitVal;
|
unsigned DigitVal;
|
||||||
@@ -470,7 +470,6 @@ static void NumericConst (void)
|
|||||||
* before converting it, so we can determine if it's a float or an
|
* before converting it, so we can determine if it's a float or an
|
||||||
* integer.
|
* integer.
|
||||||
*/
|
*/
|
||||||
InitStrBuf (&S);
|
|
||||||
while (IsXDigit (CurC) && HexVal (CurC) < Base) {
|
while (IsXDigit (CurC) && HexVal (CurC) < Base) {
|
||||||
SB_AppendChar (&S, CurC);
|
SB_AppendChar (&S, CurC);
|
||||||
NextChar ();
|
NextChar ();
|
||||||
@@ -506,7 +505,7 @@ static void NumericConst (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We don't need the string buffer any longer */
|
/* We don't need the string buffer any longer */
|
||||||
DoneStrBuf (&S);
|
SB_Done (&S);
|
||||||
|
|
||||||
/* Distinguish between integer and floating point constants */
|
/* Distinguish between integer and floating point constants */
|
||||||
if (!IsFloat) {
|
if (!IsFloat) {
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -33,6 +33,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "hashstr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -54,3 +59,18 @@ unsigned HashStr (const char* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned HashBuf (const StrBuf* S)
|
||||||
|
/* Return a hash value for the given string buffer */
|
||||||
|
{
|
||||||
|
unsigned I, L, H;
|
||||||
|
|
||||||
|
/* Do the hash */
|
||||||
|
H = L = 0;
|
||||||
|
for (I = 0; I < SB_GetLen (S); ++I) {
|
||||||
|
H = ((H << 3) ^ ((unsigned char) SB_AtUnchecked (S, I))) + L++;
|
||||||
|
}
|
||||||
|
return H;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* hashstr.h */
|
/* hashstr.h */
|
||||||
/* */
|
/* */
|
||||||
/* Hash function for strings */
|
/* Hash function for strings */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -38,7 +38,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
#include "attrib.h"
|
#include "attrib.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -51,6 +53,9 @@
|
|||||||
unsigned HashStr (const char* S) attribute ((const));
|
unsigned HashStr (const char* S) attribute ((const));
|
||||||
/* Return a hash value for the given string */
|
/* Return a hash value for the given string */
|
||||||
|
|
||||||
|
unsigned HashBuf (const StrBuf* S) attribute ((const));
|
||||||
|
/* Return a hash value for the given string buffer */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of hashstr.h */
|
/* End of hashstr.h */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -112,7 +112,7 @@ INLINE void InitHashNode (HashNode* N, void* Entry)
|
|||||||
#define InitHashNode(N, E) \
|
#define InitHashNode(N, E) \
|
||||||
(N)->Next = 0, \
|
(N)->Next = 0, \
|
||||||
(N)->Owner = 0, \
|
(N)->Owner = 0, \
|
||||||
(N)->Entry = (E)
|
(N)->Entry = (E)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -138,7 +138,7 @@ static char* Find (const char* Path, const char* File)
|
|||||||
if (access (SB_GetBuf (&PathName), 0) == 0) {
|
if (access (SB_GetBuf (&PathName), 0) == 0) {
|
||||||
/* The file exists, return its name */
|
/* The file exists, return its name */
|
||||||
char* Name = xstrdup (SB_GetBuf (&PathName));
|
char* Name = xstrdup (SB_GetBuf (&PathName));
|
||||||
DoneStrBuf (&PathName);
|
SB_Done (&PathName);
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ static char* Find (const char* Path, const char* File)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Not found */
|
/* Not found */
|
||||||
DoneStrBuf (&PathName);
|
SB_Done (&PathName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,22 +62,37 @@ const StrBuf EmptyStrBuf = STATIC_STRBUF_INITIALIZER;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
StrBuf* InitStrBuf (StrBuf* B)
|
#if !defined(HAVE_INLINE)
|
||||||
|
StrBuf* SB_Init (StrBuf* B)
|
||||||
/* Initialize a string buffer */
|
/* Initialize a string buffer */
|
||||||
|
{
|
||||||
|
*B = EmptyStrBuf;
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
StrBuf* SB_InitFromString (StrBuf* B, const char* S)
|
||||||
|
/* Initialize a string buffer from a literal string. Beware: The buffer won't
|
||||||
|
* store a copy but a pointer to the actual string.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
B->Allocated = 0;
|
B->Allocated = 0;
|
||||||
B->Len = 0;
|
B->Len = strlen (S);
|
||||||
B->Index = 0;
|
B->Index = 0;
|
||||||
B->Buf = 0;
|
B->Buf = (char*) S;
|
||||||
return B;
|
return B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DoneStrBuf (StrBuf* B)
|
void SB_Done (StrBuf* B)
|
||||||
/* Free the data of a string buffer (but not the struct itself) */
|
/* Free the data of a string buffer (but not the struct itself) */
|
||||||
{
|
{
|
||||||
xfree (B->Buf);
|
if (B->Allocated) {
|
||||||
|
xfree (B->Buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +104,7 @@ StrBuf* NewStrBuf (void)
|
|||||||
StrBuf* B = xmalloc (sizeof (StrBuf));
|
StrBuf* B = xmalloc (sizeof (StrBuf));
|
||||||
|
|
||||||
/* Initialize the struct... */
|
/* Initialize the struct... */
|
||||||
InitStrBuf (B);
|
SB_Init (B);
|
||||||
|
|
||||||
/* ...and return it */
|
/* ...and return it */
|
||||||
return B;
|
return B;
|
||||||
@@ -100,7 +115,7 @@ StrBuf* NewStrBuf (void)
|
|||||||
void FreeStrBuf (StrBuf* B)
|
void FreeStrBuf (StrBuf* B)
|
||||||
/* Free a string buffer */
|
/* Free a string buffer */
|
||||||
{
|
{
|
||||||
DoneStrBuf (B);
|
SB_Done (B);
|
||||||
xfree (B);
|
xfree (B);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +137,50 @@ void SB_Realloc (StrBuf* B, unsigned NewSize)
|
|||||||
NewAllocated *= 2;
|
NewAllocated *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reallocate the buffer */
|
/* Reallocate the buffer. Beware: The allocated size may be zero while the
|
||||||
B->Buf = xrealloc (B->Buf, NewAllocated);
|
* length is not. This means that we have a buffer that wasn't allocated
|
||||||
|
* on the heap.
|
||||||
|
*/
|
||||||
|
if (B->Allocated) {
|
||||||
|
/* Just reallocate the block */
|
||||||
|
B->Buf = xrealloc (B->Buf, NewAllocated);
|
||||||
|
} else {
|
||||||
|
/* Allocate a new block and copy */
|
||||||
|
B->Buf = memcpy (xmalloc (NewAllocated), B->Buf, B->Len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember the new block size */
|
||||||
|
B->Allocated = NewAllocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void SB_CheapRealloc (StrBuf* B, unsigned NewSize)
|
||||||
|
/* Reallocate the string buffer space, make sure at least NewSize bytes are
|
||||||
|
* available. This function won't copy the old buffer contents over to the new
|
||||||
|
* buffer and may be used if the old contents are overwritten later.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Get the current size, use a minimum of 8 bytes */
|
||||||
|
unsigned NewAllocated = B->Allocated;
|
||||||
|
if (NewAllocated == 0) {
|
||||||
|
NewAllocated = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round up to the next power of two */
|
||||||
|
while (NewAllocated < NewSize) {
|
||||||
|
NewAllocated *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the old buffer if there is one */
|
||||||
|
if (B->Allocated) {
|
||||||
|
xfree (B->Buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a fresh block */
|
||||||
|
B->Buf = xmalloc (NewAllocated);
|
||||||
|
|
||||||
|
/* Remember the new block size */
|
||||||
B->Allocated = NewAllocated;
|
B->Allocated = NewAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +227,7 @@ void SB_CopyBuf (StrBuf* Target, const char* Buf, unsigned Size)
|
|||||||
/* Copy Buf to Target, discarding the old contents of Target */
|
/* Copy Buf to Target, discarding the old contents of Target */
|
||||||
{
|
{
|
||||||
if (Target->Allocated < Size) {
|
if (Target->Allocated < Size) {
|
||||||
SB_Realloc (Target, Size);
|
SB_CheapRealloc (Target, Size);
|
||||||
}
|
}
|
||||||
memcpy (Target->Buf, Buf, Size);
|
memcpy (Target->Buf, Buf, Size);
|
||||||
Target->Len = Size;
|
Target->Len = Size;
|
||||||
@@ -294,7 +351,7 @@ void SB_Move (StrBuf* Target, StrBuf* Source)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Free the target string */
|
/* Free the target string */
|
||||||
if (Target->Buf) {
|
if (Target->Allocated) {
|
||||||
xfree (Target->Buf);
|
xfree (Target->Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +359,7 @@ void SB_Move (StrBuf* Target, StrBuf* Source)
|
|||||||
*Target = *Source;
|
*Target = *Source;
|
||||||
|
|
||||||
/* Clear Source */
|
/* Clear Source */
|
||||||
InitStrBuf (Source);
|
SB_Init (Source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -359,6 +416,31 @@ int SB_Compare (const StrBuf* S1, const StrBuf* S2)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int SB_CompareStr (const StrBuf* S1, const char* S2)
|
||||||
|
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */
|
||||||
|
{
|
||||||
|
int Result;
|
||||||
|
unsigned S2Len = strlen (S2);
|
||||||
|
if (S1->Len < S2Len) {
|
||||||
|
Result = memcmp (S1->Buf, S2, S1->Len);
|
||||||
|
if (Result == 0) {
|
||||||
|
/* S1 considered lesser because it's shorter */
|
||||||
|
Result = -1;
|
||||||
|
}
|
||||||
|
} else if (S1->Len > S2Len) {
|
||||||
|
Result = memcmp (S1->Buf, S2, S2Len);
|
||||||
|
if (Result == 0) {
|
||||||
|
/* S2 considered lesser because it's shorter */
|
||||||
|
Result = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Result = memcmp (S1->Buf, S2, S1->Len);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap)
|
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap)
|
||||||
/* printf function with S as target. The function is safe, which means that
|
/* printf function with S as target. The function is safe, which means that
|
||||||
* the current contents of S are discarded, and are allocated again with
|
* the current contents of S are discarded, and are allocated again with
|
||||||
@@ -382,10 +464,8 @@ void SB_VPrintf (StrBuf* S, const char* Format, va_list ap)
|
|||||||
|
|
||||||
/* Check if we must reallocate */
|
/* Check if we must reallocate */
|
||||||
if ((unsigned) SizeNeeded >= S->Allocated) {
|
if ((unsigned) SizeNeeded >= S->Allocated) {
|
||||||
/* Must retry. Don't use Realloc to avoid copying */
|
/* Must retry. Use CheapRealloc to avoid copying */
|
||||||
xfree (S->Buf);
|
SB_CheapRealloc (S, SizeNeeded + 1); /* Account for '\0' */
|
||||||
S->Allocated = SizeNeeded + 1; /* Account for '\0' */
|
|
||||||
S->Buf = xmalloc (S->Allocated);
|
|
||||||
(void) xvsnprintf (S->Buf, S->Allocated, Format, ap);
|
(void) xvsnprintf (S->Buf, S->Allocated, Format, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,18 +49,18 @@
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct StrBuf StrBuf;
|
typedef struct StrBuf StrBuf;
|
||||||
struct StrBuf {
|
struct StrBuf {
|
||||||
unsigned Allocated; /* Size of allocated memory */
|
char* Buf; /* Pointer to buffer */
|
||||||
unsigned Len; /* Length of the string */
|
unsigned Len; /* Length of the string */
|
||||||
unsigned Index; /* Used for reading (Get and friends) */
|
unsigned Index; /* Used for reading (Get and friends) */
|
||||||
char* Buf; /* Pointer to buffer */
|
unsigned Allocated; /* Size of allocated memory */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* An empty string buf */
|
/* An empty string buf */
|
||||||
extern const StrBuf EmptyStrBuf;
|
extern const StrBuf EmptyStrBuf;
|
||||||
@@ -71,18 +71,36 @@ extern const StrBuf EmptyStrBuf;
|
|||||||
/* Initializer for auto string bufs */
|
/* Initializer for auto string bufs */
|
||||||
#define AUTO_STRBUF_INITIALIZER EmptyStrBuf
|
#define AUTO_STRBUF_INITIALIZER EmptyStrBuf
|
||||||
|
|
||||||
|
/* Initialize with a string literal (beware: evaluates str twice!) */
|
||||||
|
#define LIT_STRBUF_INITIALIZER(str) { (char*)str, sizeof(str)-1, 0, 0 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StrBuf* InitStrBuf (StrBuf* B);
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE StrBuf* SB_Init (StrBuf* B)
|
||||||
/* Initialize a string buffer */
|
/* Initialize a string buffer */
|
||||||
|
{
|
||||||
|
*B = EmptyStrBuf;
|
||||||
|
return B;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
StrBuf* SB_Init (StrBuf* B);
|
||||||
|
#endif
|
||||||
|
|
||||||
void DoneStrBuf (StrBuf* B);
|
StrBuf* SB_InitFromString (StrBuf* B, const char* S);
|
||||||
|
/* Initialize a string buffer from a literal string. Beware: The buffer won't
|
||||||
|
* store a copy but a pointer to the actual string. A buffer initialized with
|
||||||
|
* this routine may be "forgotten" without calling SB_Done, since no memory
|
||||||
|
* has been allocated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void SB_Done (StrBuf* B);
|
||||||
/* Free the data of a string buffer (but not the struct itself) */
|
/* Free the data of a string buffer (but not the struct itself) */
|
||||||
|
|
||||||
StrBuf* NewStrBuf (void);
|
StrBuf* NewStrBuf (void);
|
||||||
@@ -358,14 +376,17 @@ void SB_ToUpper (StrBuf* S);
|
|||||||
int SB_Compare (const StrBuf* S1, const StrBuf* S2);
|
int SB_Compare (const StrBuf* S1, const StrBuf* S2);
|
||||||
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */
|
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */
|
||||||
|
|
||||||
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap);
|
int SB_CompareStr (const StrBuf* S1, const char* S2);
|
||||||
|
/* Do a lexical compare of S1 and S2. See strcmp for result codes. */
|
||||||
|
|
||||||
|
void SB_VPrintf (StrBuf* S, const char* Format, va_list ap) attribute ((format (printf, 2, 0)));
|
||||||
/* printf function with S as target. The function is safe, which means that
|
/* printf function with S as target. The function is safe, which means that
|
||||||
* the current contents of S are discarded, and are allocated again with
|
* the current contents of S are discarded, and are allocated again with
|
||||||
* a matching size for the output. The function will call FAIL when problems
|
* a matching size for the output. The function will call FAIL when problems
|
||||||
* are detected (anything that let xsnprintf return -1).
|
* are detected (anything that let xsnprintf return -1).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void SB_Printf (StrBuf* S, const char* Format, ...);
|
void SB_Printf (StrBuf* S, const char* Format, ...) attribute ((format (printf, 2, 3)));
|
||||||
/* vprintf function with S as target. The function is safe, which means that
|
/* vprintf function with S as target. The function is safe, which means that
|
||||||
* the current contents of S are discarded, and are allocated again with
|
* the current contents of S are discarded, and are allocated again with
|
||||||
* a matching size for the output. The function will call FAIL when problems
|
* a matching size for the output. The function will call FAIL when problems
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
/* A string pool is used to store identifiers and other strings. Each string
|
/* A string pool is used to store identifiers and other strings. Each string
|
||||||
* stored in the pool has a unique id, which may be used to access the string
|
* stored in the pool has a unique id, which may be used to access the string
|
||||||
* in the pool. Identical strings are only stored once in the pool and have
|
* in the pool. Identical strings are stored only once in the pool and have
|
||||||
* identical ids. This means that instead of comparing strings, just the
|
* identical ids. This means that instead of comparing strings, just the
|
||||||
* string pool ids must be compared.
|
* string pool ids must be compared.
|
||||||
*/
|
*/
|
||||||
@@ -64,8 +64,7 @@ struct StringPoolEntry {
|
|||||||
StringPoolEntry* Next; /* Pointer to next entry in hash chain */
|
StringPoolEntry* Next; /* Pointer to next entry in hash chain */
|
||||||
unsigned Hash; /* Full hash value */
|
unsigned Hash; /* Full hash value */
|
||||||
unsigned Id; /* The numeric string id */
|
unsigned Id; /* The numeric string id */
|
||||||
unsigned Len; /* Length of the string (excluding terminator) */
|
StrBuf Buf; /* The string itself */
|
||||||
char S[1]; /* The string itself */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -76,21 +75,21 @@ struct StringPoolEntry {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static StringPoolEntry* NewStringPoolEntry (const char* S, unsigned Hash, unsigned Id)
|
static StringPoolEntry* NewStringPoolEntry (const StrBuf* S, unsigned Hash, unsigned Id)
|
||||||
/* Create a new string pool entry and return it. */
|
/* Create a new string pool entry and return it. */
|
||||||
{
|
{
|
||||||
/* Get the length of the string */
|
|
||||||
unsigned Len = strlen (S);
|
|
||||||
|
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry) + Len);
|
StringPoolEntry* E = xmalloc (sizeof (StringPoolEntry));
|
||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
E->Next = 0;
|
E->Next = 0;
|
||||||
E->Hash = Hash;
|
E->Hash = Hash;
|
||||||
E->Id = Id;
|
E->Id = Id;
|
||||||
E->Len = Len;
|
E->Buf = AUTO_STRBUF_INITIALIZER;
|
||||||
memcpy (E->S, S, Len+1);
|
SB_Copy (&E->Buf, S);
|
||||||
|
|
||||||
|
/* Always zero terminate the string */
|
||||||
|
SB_Terminate (&E->Buf);
|
||||||
|
|
||||||
/* Return the new entry */
|
/* Return the new entry */
|
||||||
return E;
|
return E;
|
||||||
@@ -129,7 +128,15 @@ void DoneStringPool (StringPool* P)
|
|||||||
|
|
||||||
/* Free all entries and clear the entry collection */
|
/* Free all entries and clear the entry collection */
|
||||||
for (I = 0; I < CollCount (&P->Entries); ++I) {
|
for (I = 0; I < CollCount (&P->Entries); ++I) {
|
||||||
xfree (CollAtUnchecked (&P->Entries, I));
|
|
||||||
|
/* Get a pointer to the entry */
|
||||||
|
StringPoolEntry* E = CollAtUnchecked (&P->Entries, I);
|
||||||
|
|
||||||
|
/* Free string buffer memory */
|
||||||
|
SB_Done (&E->Buf);
|
||||||
|
|
||||||
|
/* Free the memory for the entry itself */
|
||||||
|
xfree (E);
|
||||||
}
|
}
|
||||||
CollDeleteAll (&P->Entries);
|
CollDeleteAll (&P->Entries);
|
||||||
|
|
||||||
@@ -165,25 +172,26 @@ void FreeStringPool (StringPool* P)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* SP_Get (const StringPool* P, unsigned Index)
|
const StrBuf* SP_Get (const StringPool* P, unsigned Index)
|
||||||
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */
|
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */
|
||||||
{
|
{
|
||||||
/* Get the collection entry */
|
/* Get the collection entry */
|
||||||
const StringPoolEntry* E = CollConstAt (&P->Entries, Index);
|
const StringPoolEntry* E = CollConstAt (&P->Entries, Index);
|
||||||
|
|
||||||
/* Return the string from the entry */
|
/* Return the string from the entry */
|
||||||
return E->S;
|
return &E->Buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned SP_Add (StringPool* P, const char* S)
|
unsigned SP_Add (StringPool* P, const StrBuf* S)
|
||||||
/* Add a string to the buffer and return the index. If the string does already
|
/* Add a string buffer to the buffer and return the index. If the string does
|
||||||
* exist in the pool, SP_Add will just return the index of the existing string.
|
* already exist in the pool, SP_AddBuf will just return the index of the
|
||||||
|
* existing string.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Calculate the string hash */
|
/* Calculate the string hash */
|
||||||
unsigned Hash = HashStr (S);
|
unsigned Hash = HashBuf (S);
|
||||||
|
|
||||||
/* Calculate the reduced string hash */
|
/* Calculate the reduced string hash */
|
||||||
unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0]));
|
unsigned RHash = Hash % (sizeof (P->Tab)/sizeof (P->Tab[0]));
|
||||||
@@ -191,7 +199,7 @@ unsigned SP_Add (StringPool* P, const char* S)
|
|||||||
/* Search for an existing entry */
|
/* Search for an existing entry */
|
||||||
StringPoolEntry* E = P->Tab[RHash];
|
StringPoolEntry* E = P->Tab[RHash];
|
||||||
while (E) {
|
while (E) {
|
||||||
if (E->Hash == Hash && strcmp (E->S, S) == 0) {
|
if (E->Hash == Hash && SB_Compare (&E->Buf, S) == 0) {
|
||||||
/* Found, return the id of the existing string */
|
/* Found, return the id of the existing string */
|
||||||
return E->Id;
|
return E->Id;
|
||||||
}
|
}
|
||||||
@@ -208,8 +216,8 @@ unsigned SP_Add (StringPool* P, const char* S)
|
|||||||
E->Next = P->Tab[RHash];
|
E->Next = P->Tab[RHash];
|
||||||
P->Tab[RHash] = E;
|
P->Tab[RHash] = E;
|
||||||
|
|
||||||
/* Add up the string size (plus terminator) */
|
/* Add up the string size */
|
||||||
P->TotalSize += E->Len + 1;
|
P->TotalSize += SB_GetLen (&E->Buf);
|
||||||
|
|
||||||
/* Return the id of the entry */
|
/* Return the id of the entry */
|
||||||
return E->Id;
|
return E->Id;
|
||||||
@@ -217,3 +225,22 @@ unsigned SP_Add (StringPool* P, const char* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned SP_AddStr (StringPool* P, const char* S)
|
||||||
|
/* Add a string to the buffer and return the index. If the string does already
|
||||||
|
* exist in the pool, SP_Add will just return the index of the existing string.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned Id;
|
||||||
|
|
||||||
|
/* First make a string buffer, then add it. This is some overhead, but the
|
||||||
|
* routine will probably go.
|
||||||
|
*/
|
||||||
|
StrBuf Buf;
|
||||||
|
Id = SP_Add (P, SB_InitFromString (&Buf, S));
|
||||||
|
|
||||||
|
/* Return the id of the new entry */
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "attrib.h"
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
#include "inline.h"
|
#include "inline.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
@@ -100,10 +101,16 @@ StringPool* NewStringPool (void);
|
|||||||
void FreeStringPool (StringPool* P);
|
void FreeStringPool (StringPool* P);
|
||||||
/* Free a string pool */
|
/* Free a string pool */
|
||||||
|
|
||||||
const char* SP_Get (const StringPool* P, unsigned Index);
|
const StrBuf* SP_Get (const StringPool* P, unsigned Index);
|
||||||
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */
|
/* Return a string from the pool. Index must exist, otherwise FAIL is called. */
|
||||||
|
|
||||||
unsigned SP_Add (StringPool* P, const char* S);
|
unsigned SP_Add (StringPool* P, const StrBuf* S);
|
||||||
|
/* Add a string buffer to the buffer and return the index. If the string does
|
||||||
|
* already exist in the pool, SP_AddBuf will just return the index of the
|
||||||
|
* existing string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned SP_AddStr (StringPool* P, const char* S);
|
||||||
/* Add a string to the buffer and return the index. If the string does already
|
/* Add a string to the buffer and return the index. If the string does already
|
||||||
* exist in the pool, SP_Add will just return the index of the existing string.
|
* exist in the pool, SP_Add will just return the index of the existing string.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2004 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
#include "abend.h"
|
#include "abend.h"
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
@@ -212,6 +213,16 @@ void TgtTranslateBuf (void* Buf, unsigned Len)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void TgtTranslateStrBuf (StrBuf* Buf)
|
||||||
|
/* Translate a string buffer from the source character set into the target
|
||||||
|
* system character set.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
TgtTranslateBuf (SB_GetBuf (Buf), SB_GetLen (Buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void TgtTranslateSet (unsigned Index, unsigned char C)
|
void TgtTranslateSet (unsigned Index, unsigned char C)
|
||||||
/* Set the translation code for the given character */
|
/* Set the translation code for the given character */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -34,7 +34,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#ifndef TGTTRANS_H
|
#ifndef TGTTRANS_H
|
||||||
#define TGTTRANS_H
|
#define TGTTRANS_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +67,11 @@ void TgtTranslateBuf (void* Buf, unsigned Len);
|
|||||||
* the target system character set.
|
* the target system character set.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void TgtTranslateStrBuf (StrBuf* Buf);
|
||||||
|
/* Translate a string buffer from the source character set into the target
|
||||||
|
* system character set.
|
||||||
|
*/
|
||||||
|
|
||||||
void TgtTranslateSet (unsigned Index, unsigned char C);
|
void TgtTranslateSet (unsigned Index, unsigned char C);
|
||||||
/* Set the translation code for the given character */
|
/* Set the translation code for the given character */
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2005 Ullrich von Bassewitz */
|
/* (C) 2005-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -228,7 +228,7 @@ void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the string buffer contents */
|
/* Delete the string buffer contents */
|
||||||
DoneStrBuf (&Ident);
|
SB_Done (&Ident);
|
||||||
|
|
||||||
/* Close the include file ignoring errors (we were just reading). */
|
/* Close the include file ignoring errors (we were just reading). */
|
||||||
(void) fclose (F);
|
(void) fclose (F);
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1999-2005 Ullrich von Bassewitz */
|
/* (C) 1999-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -62,9 +62,9 @@
|
|||||||
|
|
||||||
|
|
||||||
struct BinDesc {
|
struct BinDesc {
|
||||||
unsigned Undef; /* Count of undefined externals */
|
unsigned Undef; /* Count of undefined externals */
|
||||||
FILE* F; /* Output file */
|
FILE* F; /* Output file */
|
||||||
const char* Filename; /* Name of output file */
|
const char* Filename; /* Name of output file */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -148,9 +148,9 @@ static void BinWriteMem (BinDesc* D, Memory* M)
|
|||||||
Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
|
Print (stdout, 1, " Writing `%s'\n", GetString (S->Name));
|
||||||
|
|
||||||
/* Writes do only occur in the load area and not for BSS segments */
|
/* Writes do only occur in the load area and not for BSS segments */
|
||||||
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
|
DoWrite = (S->Flags & SF_BSS) == 0 && /* No BSS segment */
|
||||||
S->Load == M && /* LOAD segment */
|
S->Load == M && /* LOAD segment */
|
||||||
S->Seg->Dumped == 0; /* Not already written */
|
S->Seg->Dumped == 0; /* Not already written */
|
||||||
|
|
||||||
/* Output debugging stuff */
|
/* Output debugging stuff */
|
||||||
PrintBoolVal ("bss", S->Flags & SF_BSS);
|
PrintBoolVal ("bss", S->Flags & SF_BSS);
|
||||||
@@ -315,3 +315,4 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2005, Ullrich von Bassewitz */
|
/* (C) 2005-2008, Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -91,7 +91,7 @@ static void CE_Done (CfgExpr* E)
|
|||||||
{
|
{
|
||||||
/* If the type is a string, we must delete the string buffer */
|
/* If the type is a string, we must delete the string buffer */
|
||||||
if (E->Type == ceString) {
|
if (E->Type == ceString) {
|
||||||
DoneStrBuf (&E->SVal);
|
SB_Done (&E->SVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2003 Ullrich von Bassewitz */
|
/* (C) 2000-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -112,7 +112,7 @@ static int ConDesCompare (void* Data, const void* E1, const void* E2)
|
|||||||
Cmp = 1;
|
Cmp = 1;
|
||||||
} else {
|
} else {
|
||||||
/* Use the name in this case */
|
/* Use the name in this case */
|
||||||
Cmp = strcmp (GetString (Exp1->Name), GetString (Exp2->Name));
|
Cmp = SB_Compare (GetStrBuf (Exp1->Name), GetStrBuf (Exp2->Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reverse the result for decreasing order */
|
/* Reverse the result for decreasing order */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2005 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -203,7 +203,7 @@ static Memory* CfgFindMemory (unsigned Name)
|
|||||||
static Memory* CfgGetMemory (unsigned Name)
|
static Memory* CfgGetMemory (unsigned Name)
|
||||||
/* Find the memory are with the given name. Print an error on an invalid name */
|
/* Find the memory are with the given name. Print an error on an invalid name */
|
||||||
{
|
{
|
||||||
Memory* M = CfgFindMemory (Name);
|
Memory* M = CfgFindMemory (Name);
|
||||||
if (M == 0) {
|
if (M == 0) {
|
||||||
CfgError ("Invalid memory area `%s'", GetString (Name));
|
CfgError ("Invalid memory area `%s'", GetString (Name));
|
||||||
}
|
}
|
||||||
@@ -1557,13 +1557,14 @@ void CfgRead (void)
|
|||||||
static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
|
static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
|
||||||
/* Create the defines for a RUN segment */
|
/* Create the defines for a RUN segment */
|
||||||
{
|
{
|
||||||
char Buf [256];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
xsprintf (Buf, sizeof (Buf), "__%s_RUN__", GetString (S->Name));
|
SB_Printf (&Buf, "__%s_RUN__", GetString (S->Name));
|
||||||
CreateMemoryExport (GetStringId (Buf), S->Run, SegAddr - S->Run->Start);
|
CreateMemoryExport (GetStrBufId (&Buf), S->Run, SegAddr - S->Run->Start);
|
||||||
xsprintf (Buf, sizeof (Buf), "__%s_SIZE__", GetString (S->Name));
|
SB_Printf (&Buf, "__%s_SIZE__", GetString (S->Name));
|
||||||
CreateConstExport (GetStringId (Buf), S->Seg->Size);
|
CreateConstExport (GetStrBufId (&Buf), S->Seg->Size);
|
||||||
S->Flags |= SF_RUN_DEF;
|
S->Flags |= SF_RUN_DEF;
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1571,11 +1572,12 @@ static void CreateRunDefines (SegDesc* S, unsigned long SegAddr)
|
|||||||
static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
|
static void CreateLoadDefines (SegDesc* S, unsigned long SegAddr)
|
||||||
/* Create the defines for a LOAD segment */
|
/* Create the defines for a LOAD segment */
|
||||||
{
|
{
|
||||||
char Buf [256];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
xsprintf (Buf, sizeof (Buf), "__%s_LOAD__", GetString (S->Name));
|
SB_Printf (&Buf, "__%s_LOAD__", GetString (S->Name));
|
||||||
CreateMemoryExport (GetStringId (Buf), S->Load, SegAddr - S->Load->Start);
|
CreateMemoryExport (GetStrBufId (&Buf), S->Load, SegAddr - S->Load->Start);
|
||||||
S->Flags |= SF_LOAD_DEF;
|
S->Flags |= SF_LOAD_DEF;
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1697,13 +1699,14 @@ unsigned CfgAssignSegments (void)
|
|||||||
|
|
||||||
/* If requested, define symbols for start and size of the memory area */
|
/* If requested, define symbols for start and size of the memory area */
|
||||||
if (M->Flags & MF_DEFINE) {
|
if (M->Flags & MF_DEFINE) {
|
||||||
char Buf [256];
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
sprintf (Buf, "__%s_START__", GetString (M->Name));
|
SB_Printf (&Buf, "__%s_START__", GetString (M->Name));
|
||||||
CreateMemoryExport (GetStringId (Buf), M, 0);
|
CreateMemoryExport (GetStrBufId (&Buf), M, 0);
|
||||||
sprintf (Buf, "__%s_SIZE__", GetString (M->Name));
|
SB_Printf (&Buf, "__%s_SIZE__", GetString (M->Name));
|
||||||
CreateConstExport (GetStringId (Buf), M->Size);
|
CreateConstExport (GetStrBufId (&Buf), M->Size);
|
||||||
sprintf (Buf, "__%s_LAST__", GetString (M->Name));
|
SB_Printf (&Buf, "__%s_LAST__", GetString (M->Name));
|
||||||
CreateMemoryExport (GetStringId (Buf), M, M->FillLevel);
|
CreateMemoryExport (GetStrBufId (&Buf), M, M->FillLevel);
|
||||||
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next memory area */
|
/* Next memory area */
|
||||||
@@ -1728,7 +1731,7 @@ void CfgWriteTarget (void)
|
|||||||
if (F->MemList) {
|
if (F->MemList) {
|
||||||
|
|
||||||
/* Is there an output file? */
|
/* Is there an output file? */
|
||||||
if (strlen (GetString (F->Name)) > 0) {
|
if (SB_GetLen (GetStrBuf (F->Name)) > 0) {
|
||||||
|
|
||||||
/* Assign a proper binary format */
|
/* Assign a proper binary format */
|
||||||
if (F->Format == BINFMT_DEFAULT) {
|
if (F->Format == BINFMT_DEFAULT) {
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2001-2003 Ullrich von Bassewitz */
|
/* (C) 2001-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -36,9 +36,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ld65 */
|
/* ld65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
@@ -54,12 +55,17 @@
|
|||||||
void Warning (const char* Format, ...)
|
void Warning (const char* Format, ...)
|
||||||
/* Print a warning message */
|
/* Print a warning message */
|
||||||
{
|
{
|
||||||
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "%s: Warning: ", ProgName);
|
SB_VPrintf (&S, Format, ap);
|
||||||
vfprintf (stderr, Format, ap);
|
|
||||||
putc ('\n', stderr);
|
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
SB_Terminate (&S);
|
||||||
|
|
||||||
|
fprintf (stderr, "%s: Warning: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,12 +73,18 @@ void Warning (const char* Format, ...)
|
|||||||
void Error (const char* Format, ...)
|
void Error (const char* Format, ...)
|
||||||
/* Print an error message and die */
|
/* Print an error message and die */
|
||||||
{
|
{
|
||||||
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "%s: Error: ", ProgName);
|
SB_VPrintf (&S, Format, ap);
|
||||||
vfprintf (stderr, Format, ap);
|
|
||||||
putc ('\n', stderr);
|
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
SB_Terminate (&S);
|
||||||
|
|
||||||
|
fprintf (stderr, "%s: Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
|
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,14 +93,20 @@ void Error (const char* Format, ...)
|
|||||||
void Internal (const char* Format, ...)
|
void Internal (const char* Format, ...)
|
||||||
/* Print an internal error message and die */
|
/* Print an internal error message and die */
|
||||||
{
|
{
|
||||||
|
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
fprintf (stderr, "%s: Internal error: ", ProgName);
|
SB_VPrintf (&S, Format, ap);
|
||||||
vfprintf (stderr, Format, ap);
|
|
||||||
putc ('\n', stderr);
|
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
SB_Terminate (&S);
|
||||||
|
|
||||||
|
fprintf (stderr, "%s: Internal Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||||
|
|
||||||
|
SB_Done (&S);
|
||||||
|
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2005 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstra<EFBFBD>e 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -620,7 +620,7 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
|||||||
/* Unresolved external */
|
/* Unresolved external */
|
||||||
Import* Imp = E->ImpList;
|
Import* Imp = E->ImpList;
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Unresolved external `%s' referenced in:\n",
|
"Unresolved external `%s' referenced in:\n",
|
||||||
GetString (E->Name));
|
GetString (E->Name));
|
||||||
while (Imp) {
|
while (Imp) {
|
||||||
const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
|
const char* Name = GetSourceFileName (Imp->Obj, Imp->Pos.Name);
|
||||||
@@ -636,8 +636,8 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
|||||||
static int CmpExpName (const void* K1, const void* K2)
|
static int CmpExpName (const void* K1, const void* K2)
|
||||||
/* Compare function for qsort */
|
/* Compare function for qsort */
|
||||||
{
|
{
|
||||||
return strcmp (GetString ((*(Export**)K1)->Name),
|
return SB_Compare (GetStrBuf ((*(Export**)K1)->Name),
|
||||||
GetString ((*(Export**)K2)->Name));
|
GetStrBuf ((*(Export**)K2)->Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -728,7 +728,7 @@ void PrintExportMap (FILE* F)
|
|||||||
/* Print unreferenced symbols only if explictly requested */
|
/* Print unreferenced symbols only if explictly requested */
|
||||||
if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) {
|
if (VerboseMap || E->ImpCount > 0 || IS_EXP_CONDES (E->Type)) {
|
||||||
fprintf (F,
|
fprintf (F,
|
||||||
"%-25s %06lX %c%c%c%c ",
|
"%-25s %06lX %c%c%c%c ",
|
||||||
GetString (E->Name),
|
GetString (E->Name),
|
||||||
GetExportVal (E),
|
GetExportVal (E),
|
||||||
E->ImpCount? 'R' : ' ',
|
E->ImpCount? 'R' : ' ',
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1999-2003 Ullrich von Bassewitz */
|
/* (C) 1999-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -283,34 +283,23 @@ unsigned ReadStr (FILE* F)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned Id;
|
unsigned Id;
|
||||||
char* B;
|
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||||
char Buf[256];
|
|
||||||
|
|
||||||
/* Read the length */
|
/* Read the length */
|
||||||
unsigned Len = ReadVar (F);
|
unsigned Len = ReadVar (F);
|
||||||
|
|
||||||
/* If the string is short enough, use our buffer on the stack, otherwise
|
/* Expand the string buffer memory */
|
||||||
* allocate space on the heap.
|
SB_Realloc (&Buf, Len);
|
||||||
*/
|
|
||||||
if (Len < sizeof (Buf)) {
|
|
||||||
B = Buf;
|
|
||||||
} else {
|
|
||||||
B = xmalloc (Len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the string */
|
/* Read the string */
|
||||||
ReadData (F, B, Len);
|
ReadData (F, SB_GetBuf (&Buf), Len);
|
||||||
|
Buf.Len = Len;
|
||||||
/* Terminate the string */
|
|
||||||
B[Len] = '\0';
|
|
||||||
|
|
||||||
/* Insert it into the string pool and remember the id */
|
/* Insert it into the string pool and remember the id */
|
||||||
Id = GetStringId (B);
|
Id = GetStrBufId (&Buf);
|
||||||
|
|
||||||
/* If we had allocated memory before, free it now */
|
/* Free the memory buffer */
|
||||||
if (B != Buf) {
|
SB_Done (&Buf);
|
||||||
xfree (B);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the string id */
|
/* Return the string id */
|
||||||
return Id;
|
return Id;
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2008, Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -95,7 +95,7 @@ void CfgWarning (const char* Format, ...)
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf));
|
Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf));
|
||||||
DoneStrBuf (&Buf);
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ void CfgError (const char* Format, ...)
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf));
|
Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf));
|
||||||
DoneStrBuf (&Buf);
|
SB_Done (&Buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ StringPool StrPool = STATIC_STRINGPOOL_INITIALIZER;
|
|||||||
void InitStrPool (void)
|
void InitStrPool (void)
|
||||||
/* Initialize the string pool */
|
/* Initialize the string pool */
|
||||||
{
|
{
|
||||||
/* We insert a first string here, which will have id zero. This means
|
/* We insert a first string here, which will have id zero. This means
|
||||||
* that we can treat index zero later as invalid.
|
* that we can treat index zero later as invalid.
|
||||||
*/
|
*/
|
||||||
SP_Add (&StrPool, "<invalid message #0>");
|
SP_AddStr (&StrPool, "<invalid message #0>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003 Ullrich von Bassewitz */
|
/* (C) 2003-2008 Ullrich von Bassewitz */
|
||||||
/* R<EFBFBD>merstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
@@ -64,8 +64,8 @@ extern StringPool StrPool;
|
|||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE unsigned GetStringId (const char* S)
|
INLINE unsigned GetStrBufId (const StrBuf* S)
|
||||||
/* Return the id of the given string */
|
/* Return the id of the given string buffer */
|
||||||
{
|
{
|
||||||
return SP_Add (&StrPool, S);
|
return SP_Add (&StrPool, S);
|
||||||
}
|
}
|
||||||
@@ -74,13 +74,33 @@ INLINE unsigned GetStringId (const char* S)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE const char* GetString (unsigned Index)
|
INLINE unsigned GetStringId (const char* S)
|
||||||
|
/* Return the id of the given string */
|
||||||
|
{
|
||||||
|
return SP_AddStr (&StrPool, S);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define GetStringId(S) SP_Add (&StrPool, (S))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE const StrBuf* GetStrBuf (unsigned Index)
|
||||||
/* Convert a string index into a string */
|
/* Convert a string index into a string */
|
||||||
{
|
{
|
||||||
return SP_Get (&StrPool, Index);
|
return SP_Get (&StrPool, Index);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetString(Index) SP_Get (&StrPool, (Index))
|
# define GetStrBuf(Index) SP_Get (&StrPool, (Index))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE const char* GetString (unsigned Index)
|
||||||
|
/* Convert a string index into a string */
|
||||||
|
{
|
||||||
|
return SB_GetConstBuf (SP_Get (&StrPool, Index));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define GetString(Index) SB_GetConstBuf (SP_Get (&StrPool, (Index)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void InitStrPool (void);
|
void InitStrPool (void);
|
||||||
|
|||||||
Reference in New Issue
Block a user