1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-09 22:29:35 +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)
/* Set the name of a segment */
void g_segname (segment_t Seg)
/* 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 */
DataSeg* S;
switch (Seg) {
case SEG_RODATA: S = CS->ROData; 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;
}
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 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
@ -122,8 +122,8 @@ void g_usedata (void);
void g_usebss (void);
/* Switch to the bss segment */
void g_segname (segment_t Seg, const char* Name);
/* Set the name of a segment */
void g_segname (segment_t Seg);
/* 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);
/* 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);
/* 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);
/* 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);
/* 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)
/* 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 */
const char* Name = SB_GetConstBuf (&S);
/* Check if we have a first argument named "pop" */
if (strcmp (Ident, "pop") == 0) {
/* Check if the name is valid */
if (ValidSegName (Name)) {
/* Pop the old value */
PopSegName (Seg);
/* Set the new name */
g_segname (Seg, Name);
/* Set the segment name */
g_segname (Seg);
} else {
/* Done */
return;
/* Segment name is invalid */
Error ("Illegal segment name: `%s'", Name);
/* Check if we have a first argument named "push" */
} else if (strcmp (Ident, "push") == 0) {
}
Push = 1;
SB_SkipWhite (B);
if (SB_Get (B) != ',') {
Error ("Comma expected");
return;
}
SB_SkipWhite (B);
} else {
Error ("String literal expected");
} else {
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 */
DoneStrBuf (&S);
}
@ -237,7 +274,7 @@ static void FlagPragma (StrBuf* B, IntStack* Stack)
if (IS_GetCount (Stack) < 2) {
Error ("Cannot pop, stack is empty");
} else {
IS_Drop (Stack);
IS_Drop (Stack);
}
/* No other arguments allowed */
return;

View File

@ -42,12 +42,14 @@
#include "coll.h"
#include "scanner.h"
#include "segnames.h"
#include "strstack.h"
#include "xmalloc.h"
/* cc65 */
#include "codeent.h"
#include "codeseg.h"
#include "dataseg.h"
#include "error.h"
#include "textseg.h"
#include "segments.h"
@ -66,7 +68,7 @@ Segments* CS = 0;
Segments* GS = 0;
/* 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
* 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)
/* Initialize the segment names */
{
SegmentNames [SEG_BSS] = xstrdup (SEGNAME_BSS);
SegmentNames [SEG_CODE] = xstrdup (SEGNAME_CODE);
SegmentNames [SEG_DATA] = xstrdup (SEGNAME_DATA);
SegmentNames [SEG_RODATA] = xstrdup (SEGNAME_RODATA);
SS_Push (&SegmentNames[SEG_BSS], SEGNAME_BSS);
SS_Push (&SegmentNames[SEG_CODE], SEGNAME_CODE);
SS_Push (&SegmentNames[SEG_DATA], SEGNAME_DATA);
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 */
{
/* Free the old name and set a new one */
xfree (SegmentNames [Seg]);
SegmentNames [Seg] = xstrdup (Name);
SS_Set (&SegmentNames[Seg], 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 */
S->Text = NewTextSeg (Func);
S->Code = NewCodeSeg (SegmentNames[SEG_CODE], Func);
S->Data = NewDataSeg (SegmentNames[SEG_DATA], Func);
S->ROData = NewDataSeg (SegmentNames[SEG_RODATA], Func);
S->BSS = NewDataSeg (SegmentNames[SEG_BSS], Func);
S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func);
S->Data = NewDataSeg (GetSegName (SEG_DATA), Func);
S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func);
S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func);
S->CurDSeg = SEG_DATA;
/* Return the new struct */

View File

@ -105,9 +105,18 @@ extern Segments* GS;
void InitSegNames (void);
/* 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 */
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);
/* Make the new segment list current but remember the old one */