]> git.sur5r.net Git - cc65/commitdiff
Allow push/pop arguments for segment name #pragmas
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 8 Mar 2004 22:33:27 +0000 (22:33 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 8 Mar 2004 22:33:27 +0000 (22:33 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2907 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codegen.c
src/cc65/codegen.h
src/cc65/main.c
src/cc65/pragma.c
src/cc65/segments.c
src/cc65/segments.h

index f6c5a69d47f4c1e367c5e252936862515490141f..060d3a9d4cbc4c1fae6bffad29bb2146442916b3 100644 (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));
     }
 }
 
index 258bb6b2d859487a2ebca192f3e850ea6b943cbd..72feb2eacbbae1adc177e6dd0087e585d0d27784 100644 (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 */
 
 
 
index 80ceaf7eb1c4ed29284158ebf951606e2a891663..85dc615c9a81bd3877d7dc90771960ca8220976b 100644 (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);
 }
 
 
index 5ee35a23436058c35123151cdc0dc70ee1bcf14a..2872515cf40213d3e78e04148a201e08f1c8e14a 100644 (file)
@@ -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 */
 {
-    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 {
+        } 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;
index dabb4a4a601e59ad5ae62aeff86b9ba73918db7a..57f1a80479f7f39243f1a43c8821d461a2515381 100644 (file)
 #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 */
index 81496ed1fbed664fd936a44e61579545fa4998dd..6d6ad2facceb1e53bbc5f4fc7a668563279ed402 100644 (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 */