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:
parent
7a5d4f3138
commit
40dc3582a9
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user