1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-25 02:29:52 +00:00

Allow push/pop arguments for segment name #pragmas

git-svn-id: svn://svn.cc65.org/cc65/trunk@2907 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2004-03-08 22:33:27 +00:00
parent 7a5d4f3138
commit 40dc3582a9
6 changed files with 118 additions and 44 deletions

View File

@ -237,15 +237,11 @@ void g_usebss (void)
void g_segname (segment_t Seg, const char* Name) void g_segname (segment_t Seg)
/* Set the name of a segment */ /* Emit the name of a segment if necessary */
{ {
DataSeg* S;
/* Remember the new name */
NewSegName (Seg, Name);
/* Emit a segment directive for the data style segments */ /* Emit a segment directive for the data style segments */
DataSeg* S;
switch (Seg) { switch (Seg) {
case SEG_RODATA: S = CS->ROData; break; case SEG_RODATA: S = CS->ROData; break;
case SEG_DATA: S = CS->Data; break; case SEG_DATA: S = CS->Data; break;
@ -253,7 +249,7 @@ void g_segname (segment_t Seg, const char* Name)
default: S = 0; break; default: S = 0; break;
} }
if (S) { if (S) {
DS_AddLine (S, ".segment\t\"%s\"", Name); DS_AddLine (S, ".segment\t\"%s\"", GetSegName (Seg));
} }
} }

View File

@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2003 Ullrich von Bassewitz */ /* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */ /* Römerstrasse 52 */
/* D-70794 Filderstadt */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
@ -122,8 +122,8 @@ void g_usedata (void);
void g_usebss (void); void g_usebss (void);
/* Switch to the bss segment */ /* Switch to the bss segment */
void g_segname (segment_t Seg, const char* Name); void g_segname (segment_t Seg);
/* Set the name of a segment */ /* Emit the name of a segment if necessary */

View File

@ -340,7 +340,7 @@ static void OptBssName (const char* Opt attribute ((unused)), const char* Arg)
CheckSegName (Arg); CheckSegName (Arg);
/* Set the name */ /* Set the name */
NewSegName (SEG_BSS, Arg); SetSegName (SEG_BSS, Arg);
} }
@ -361,7 +361,7 @@ static void OptCodeName (const char* Opt attribute ((unused)), const char* Arg)
CheckSegName (Arg); CheckSegName (Arg);
/* Set the name */ /* Set the name */
NewSegName (SEG_CODE, Arg); SetSegName (SEG_CODE, Arg);
} }
@ -408,7 +408,7 @@ static void OptDataName (const char* Opt attribute ((unused)), const char* Arg)
CheckSegName (Arg); CheckSegName (Arg);
/* Set the name */ /* Set the name */
NewSegName (SEG_DATA, Arg); SetSegName (SEG_DATA, Arg);
} }
@ -605,7 +605,7 @@ static void OptRodataName (const char* Opt attribute ((unused)), const char* Arg
CheckSegName (Arg); CheckSegName (Arg);
/* Set the name */ /* Set the name */
NewSegName (SEG_RODATA, Arg); SetSegName (SEG_RODATA, Arg);
} }

View File

@ -155,30 +155,67 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
static void SegNamePragma (StrBuf* B, segment_t Seg) static void SegNamePragma (StrBuf* B, segment_t Seg)
/* Handle a pragma that expects a segment name parameter */ /* Handle a pragma that expects a segment name parameter */
{ {
StrBuf S; ident Ident;
StrBuf S;
const char* Name;
if (SB_GetString (B, &S)) { /* Try to read an identifier */
int Push = 0;
if (SB_GetSym (B, Ident)) {
/* Get the string */ /* Check if we have a first argument named "pop" */
const char* Name = SB_GetConstBuf (&S); if (strcmp (Ident, "pop") == 0) {
/* Check if the name is valid */ /* Pop the old value */
if (ValidSegName (Name)) { PopSegName (Seg);
/* Set the new name */ /* Set the segment name */
g_segname (Seg, Name); g_segname (Seg);
} else { /* Done */
return;
/* Segment name is invalid */ /* Check if we have a first argument named "push" */
Error ("Illegal segment name: `%s'", Name); } else if (strcmp (Ident, "push") == 0) {
} Push = 1;
SB_SkipWhite (B);
if (SB_Get (B) != ',') {
Error ("Comma expected");
return;
}
SB_SkipWhite (B);
} else { } else {
Error ("String literal expected"); Error ("Invalid pragma arguments");
return;
}
} }
/* A string argument must follow */
if (!SB_GetString (B, &S)) {
Error ("String literal expected");
return;
}
/* Get the string */
Name = SB_GetConstBuf (&S);
/* Check if the name is valid */
if (!ValidSegName (Name)) {
/* Segment name is invalid */
Error ("Illegal segment name: `%s'", Name);
return;
}
/* Set the new name */
if (Push) {
PushSegName (Seg, Name);
} else {
SetSegName (Seg, Name);
}
g_segname (Seg);
/* Call the string buf destructor */ /* Call the string buf destructor */
DoneStrBuf (&S); DoneStrBuf (&S);
} }

View File

@ -42,12 +42,14 @@
#include "coll.h" #include "coll.h"
#include "scanner.h" #include "scanner.h"
#include "segnames.h" #include "segnames.h"
#include "strstack.h"
#include "xmalloc.h" #include "xmalloc.h"
/* cc65 */ /* cc65 */
#include "codeent.h" #include "codeent.h"
#include "codeseg.h" #include "codeseg.h"
#include "dataseg.h" #include "dataseg.h"
#include "error.h"
#include "textseg.h" #include "textseg.h"
#include "segments.h" #include "segments.h"
@ -66,7 +68,7 @@ Segments* CS = 0;
Segments* GS = 0; Segments* GS = 0;
/* Actual names for the segments */ /* Actual names for the segments */
static char* SegmentNames[SEG_COUNT]; static StrStack SegmentNames[SEG_COUNT];
/* We're using a collection for the stack instead of a linked list. Since /* We're using a collection for the stack instead of a linked list. Since
* functions may not be nested (at least in the current implementation), the * functions may not be nested (at least in the current implementation), the
@ -86,20 +88,50 @@ static Collection SegmentStack = STATIC_COLLECTION_INITIALIZER;
void InitSegNames (void) void InitSegNames (void)
/* Initialize the segment names */ /* Initialize the segment names */
{ {
SegmentNames [SEG_BSS] = xstrdup (SEGNAME_BSS); SS_Push (&SegmentNames[SEG_BSS], SEGNAME_BSS);
SegmentNames [SEG_CODE] = xstrdup (SEGNAME_CODE); SS_Push (&SegmentNames[SEG_CODE], SEGNAME_CODE);
SegmentNames [SEG_DATA] = xstrdup (SEGNAME_DATA); SS_Push (&SegmentNames[SEG_DATA], SEGNAME_DATA);
SegmentNames [SEG_RODATA] = xstrdup (SEGNAME_RODATA); SS_Push (&SegmentNames[SEG_RODATA], SEGNAME_RODATA);
} }
void NewSegName (segment_t Seg, const char* Name) void SetSegName (segment_t Seg, const char* Name)
/* Set a new name for a segment */ /* Set a new name for a segment */
{ {
/* Free the old name and set a new one */ SS_Set (&SegmentNames[Seg], Name);
xfree (SegmentNames [Seg]); }
SegmentNames [Seg] = xstrdup (Name);
void PushSegName (segment_t Seg, const char* Name)
/* Push the current segment name and set a new name for a segment */
{
if (SS_IsFull (&SegmentNames[Seg])) {
Error ("Segment name stack overflow");
} else {
SS_Push (&SegmentNames[Seg], Name);
}
}
void PopSegName (segment_t Seg)
/* Restore a segment name from the segment name stack */
{
if (SS_GetCount (&SegmentNames[Seg]) < 2) {
Error ("Segment name stack is empty");
} else {
SS_Drop (&SegmentNames[Seg]);
}
}
const char* GetSegName (segment_t Seg)
/* Get the name of the given segment */
{
return SS_Get (&SegmentNames[Seg]);
} }
@ -112,10 +144,10 @@ static Segments* NewSegments (SymEntry* Func)
/* Initialize the fields */ /* Initialize the fields */
S->Text = NewTextSeg (Func); S->Text = NewTextSeg (Func);
S->Code = NewCodeSeg (SegmentNames[SEG_CODE], Func); S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func);
S->Data = NewDataSeg (SegmentNames[SEG_DATA], Func); S->Data = NewDataSeg (GetSegName (SEG_DATA), Func);
S->ROData = NewDataSeg (SegmentNames[SEG_RODATA], Func); S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func);
S->BSS = NewDataSeg (SegmentNames[SEG_BSS], Func); S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func);
S->CurDSeg = SEG_DATA; S->CurDSeg = SEG_DATA;
/* Return the new struct */ /* Return the new struct */

View File

@ -105,9 +105,18 @@ extern Segments* GS;
void InitSegNames (void); void InitSegNames (void);
/* Initialize the segment names */ /* Initialize the segment names */
void NewSegName (segment_t Seg, const char* Name); void SetSegName (segment_t Seg, const char* Name);
/* Set a new name for a segment */ /* Set a new name for a segment */
void PushSegName (segment_t Seg, const char* Name);
/* Push the current segment name and set a new name for a segment */
void PopSegName (segment_t Seg);
/* Restore a segment name from the segment name stack */
const char* GetSegName (segment_t Seg);
/* Get the name of the given segment */
Segments* PushSegments (struct SymEntry* Func); Segments* PushSegments (struct SymEntry* Func);
/* Make the new segment list current but remember the old one */ /* Make the new segment list current but remember the old one */