]> git.sur5r.net Git - cc65/commitdiff
Added symbol definitions on the command line and weak symbols in the config.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 26 Jul 2005 20:42:30 +0000 (20:42 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 26 Jul 2005 20:42:30 +0000 (20:42 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3552 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/config.c
src/ld65/main.c

index 098633323111351eaeed30c4a90a8945afbae2d3..eb7dbdee4ac63181e2e4bb765da31e82c206b1f8 100644 (file)
@@ -1335,7 +1335,7 @@ static void ParseFeatures (void)
 
 
            default:
-               Error ("Unexpected feature token");
+                       FAIL ("Unexpected feature token");
        }
 
        /* Skip the semicolon */
@@ -1359,7 +1359,7 @@ static void ParseSymbols (void)
     while (CfgTok == CFGTOK_IDENT) {
 
        long Val = 0L;
-        int  Weak;
+        int  Weak = 0;
 
        /* Remember the name */
        unsigned Name = GetStringId (CfgSVal);
@@ -1381,9 +1381,6 @@ static void ParseSymbols (void)
             Val = CfgIVal;
             CfgNextTok ();
 
-            /* Generate an export with the given value */
-            CreateConstExport (Name, Val);
-
         } else {
 
             /* Bitmask to remember the attributes we got already */
@@ -1453,7 +1450,18 @@ static void ParseSymbols (void)
                 Weak = 0;
             }
 
-            /* Generate an export with the given value */
+        }
+
+        /* Check if the symbol is already defined */
+        if (FindExport (Name) != 0) {
+            /* If the symbol is not marked as weak, this is an error.
+             * Otherwise ignore the symbol from the config.
+             */
+            if (!Weak) {
+                CfgError ("Symbol `%s' is already defined", GetString (Name));
+            }
+        } else {
+            /* The symbol is undefined, generate an export */
             CreateConstExport (Name, Val);
         }
 
index 41246a296cad5532a7c3319406d3078143cd7950..0564b53749904cc4d54a337840c101fbd21dc15b 100644 (file)
@@ -39,6 +39,7 @@
 #include <errno.h>
 
 /* common */
+#include "chartype.h"
 #include "cmdline.h"
 #include "filetype.h"
 #include "libdefs.h"
@@ -94,6 +95,7 @@ static void Usage (void)
             "  -(\t\t\tStart a library group\n"
             "  -)\t\t\tEnd a library group\n"
             "  -C name\t\tUse linker config file\n"
+            "  -D sym=val\t\tDefine a symbol\n"
             "  -L path\t\tSpecify a library search path\n"
             "  -Ln name\t\tCreate a VICE label file\n"
             "  -S addr\t\tSet the default start address\n"
@@ -109,6 +111,7 @@ static void Usage (void)
             "  --cfg-path path\tSpecify a config file search path\n"
             "  --config name\t\tUse linker config file\n"
             "  --dbgfile name\tGenerate debug information\n"
+            "  --define sym=val\tDefine a symbol\n"
             "  --dump-config name\tDump a builtin configuration\n"
             "  --end-group\t\tEnd a library group\n"
             "  --help\t\tHelp (this text)\n"
@@ -227,6 +230,52 @@ static void LinkFile (const char* Name, FILETYPE Type)
 
 
 
+static void DefineSymbol (const char* Def)
+/* Define a symbol from the command line */
+{
+    const char* P;
+    unsigned I;
+    long Val;
+    StrBuf SymName = AUTO_STRBUF_INITIALIZER;
+
+
+    /* The symbol must start with a character or underline */
+    if (Def [0] != '_' && !IsAlpha (Def [0])) {
+       InvDef (Def);
+    }
+    P = Def;
+
+    /* Copy the symbol, checking the remainder */
+    I = 0;
+    while (IsAlNum (*P) || *P == '_') {
+        SB_AppendChar (&SymName, *P++);
+    }
+    SB_Terminate (&SymName);
+
+    /* Do we have a value given? */
+    if (*P != '=') {
+        InvDef (Def);
+    } else {
+       /* We have a value */
+       ++P;
+       if (*P == '$') {
+           ++P;
+           if (sscanf (P, "%lx", &Val) != 1) {
+               InvDef (Def);
+           }
+       } else {
+           if (sscanf (P, "%li", &Val) != 1) {
+               InvDef (Def);
+           }
+               }
+    }
+
+    /* Define the new symbol */
+    CreateConstExport (GetStringId (SB_GetConstBuf (&SymName)), Val);
+}
+
+
+
 static void OptCfgPath (const char* Opt attribute ((unused)), const char* Arg)
 /* Specify a config file search path */
 {
@@ -262,6 +311,14 @@ static void OptDbgFile (const char* Opt attribute ((unused)), const char* Arg)
 
 
 
+static void OptDefine (const char* Opt attribute ((unused)), const char* Arg)
+/* Define a symbol on the command line */
+{
+    DefineSymbol (Arg);
+}
+
+
+
 static void OptDumpConfig (const char* Opt attribute ((unused)), const char* Arg)
 /* Dump a builtin linker configuration */
 {
@@ -406,6 +463,7 @@ int main (int argc, char* argv [])
                { "--cfg-path",         1,      OptCfgPath              },
                { "--config",           1,      OptConfig               },
        { "--dbgfile",          1,      OptDbgFile              },
+        { "--define",           1,      OptDefine               },
                { "--dump-config",      1,      OptDumpConfig           },
         { "--end-group",        0,      OptEndGroup             },
        { "--help",             0,      OptHelp                 },
@@ -490,6 +548,10 @@ int main (int argc, char* argv [])
                    OptConfig (Arg, GetArg (&I, 2));
                    break;
 
+                case 'D':
+                    OptDefine (Arg, GetArg (&I, 2));
+                    break;
+
                case 'L':
                    switch (Arg [2]) {
                         /* ## The first one is obsolete and will go */