mirror of
https://github.com/cc65/cc65.git
synced 2024-12-27 00:29:31 +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:
parent
7a5d4f3138
commit
40dc3582a9
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,29 +155,66 @@ 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 */
|
||||
{
|
||||
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)) {
|
||||
|
||||
/* Check if we have a first argument named "pop" */
|
||||
if (strcmp (Ident, "pop") == 0) {
|
||||
|
||||
/* Pop the old value */
|
||||
PopSegName (Seg);
|
||||
|
||||
/* Set the segment name */
|
||||
g_segname (Seg);
|
||||
|
||||
/* Done */
|
||||
return;
|
||||
|
||||
/* 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 ("Invalid pragma arguments");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* A string argument must follow */
|
||||
if (!SB_GetString (B, &S)) {
|
||||
Error ("String literal expected");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the string */
|
||||
const char* Name = SB_GetConstBuf (&S);
|
||||
Name = SB_GetConstBuf (&S);
|
||||
|
||||
/* Check if the name is valid */
|
||||
if (ValidSegName (Name)) {
|
||||
|
||||
/* Set the new name */
|
||||
g_segname (Seg, Name);
|
||||
|
||||
} else {
|
||||
|
||||
if (!ValidSegName (Name)) {
|
||||
/* Segment name is invalid */
|
||||
Error ("Illegal segment name: `%s'", Name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the new name */
|
||||
if (Push) {
|
||||
PushSegName (Seg, Name);
|
||||
} else {
|
||||
Error ("String literal expected");
|
||||
SetSegName (Seg, Name);
|
||||
}
|
||||
g_segname (Seg);
|
||||
|
||||
/* Call the string buf destructor */
|
||||
DoneStrBuf (&S);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user