]> git.sur5r.net Git - cc65/blobdiff - src/cc65/main.c
Working on the new backend
[cc65] / src / cc65 / main.c
index 083e323b6a65df39b5dd99a51e96cbb000382eea..6f3d0bbcfb009daf2802c8dba25aa046d455f8a3 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
+/* (C) 2000-2001 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@musoftware.de                                            */
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <ctype.h>
 #include <errno.h>
 
-#include "../common/cmdline.h"
-#include "../common/fname.h"
-#include "../common/version.h"
-#include "../common/xmalloc.h"
-
+/* common */
+#include "abend.h"
+#include "chartype.h"
+#include "cmdline.h"
+#include "fname.h"
+#include "print.h"
+#include "target.h"
+#include "tgttrans.h"
+#include "version.h"
+#include "xmalloc.h"
+
+/* cc65 */
 #include "asmcode.h"
 #include "compile.h"
 #include "cpu.h"
 #include "incpath.h"
 #include "input.h"
 #include "macrotab.h"
-#include "optimize.h"
 #include "scanner.h"
-
-
-
-/*****************************************************************************/
-/*                                  data                                    */
-/*****************************************************************************/
-
-
-
-/* Names of the target systems sorted by target name */
-static const char* TargetNames [] = {
-    "none",
-    "atari",
-    "c64",
-    "c128",
-    "ace",
-    "plus4",
-    "cbm610",
-    "pet",
-    "nes",
-    "apple2",
-    "geos",
-};
+#include "segname.h"
 
 
 
@@ -93,7 +76,7 @@ static void Usage (void)
             "Short options:\n"
                     "  -d\t\t\tDebug mode\n"
                     "  -g\t\t\tAdd debug info to object file\n"
-                    "  -h\t\t\tPrint this help\n"
+                    "  -h\t\t\tHelp (this text)\n"
                     "  -j\t\t\tDefault characters are signed\n"
                     "  -o name\t\tName the output file\n"
                     "  -t sys\t\tSet the target system\n"
@@ -101,7 +84,7 @@ static void Usage (void)
                     "  -A\t\t\tStrict ANSI mode\n"
                     "  -Cl\t\t\tMake local variables static\n"
                     "  -Dsym[=defn]\t\tDefine a symbol\n"
-                    "  -I path\t\tSet an include directory search path\n"
+                    "  -I dir\t\tSet an include directory search path\n"
                     "  -O\t\t\tOptimize code\n"
                     "  -Oi\t\t\tOptimize code, inline more code\n"
                     "  -Or\t\t\tEnable register variables\n"
@@ -112,11 +95,19 @@ static void Usage (void)
             "\n"
             "Long options:\n"
                     "  --ansi\t\tStrict ANSI mode\n"
+            "  --bss-name seg\tSet the name of the BSS segment\n"
+                    "  --check-stack\t\tGenerate stack overflow checks\n"
+                    "  --code-name seg\tSet the name of the CODE segment\n"
+            "  --codesize x\tAccept larger code by factor x\n"
                     "  --cpu type\t\tSet cpu type\n"
+                    "  --data-name seg\tSet the name of the DATA segment\n"
+                    "  --debug\t\tDebug mode\n"
                     "  --debug-info\t\tAdd debug info to object file\n"
             "  --help\t\tHelp (this text)\n"
                     "  --include-dir dir\tSet an include directory search path\n"
+                    "  --rodata-name seg\tSet the name of the RODATA segment\n"
                     "  --signed-chars\tDefault characters are signed\n"
+                    "  --static-locals\tMake local variables static\n"
                     "  --target sys\t\tSet the target system\n"
                     "  --verbose\t\tIncrease verbosity\n"
                     "  --version\t\tPrint the compiler version number\n",
@@ -134,35 +125,10 @@ static void cbmsys (const char* sys)
 
 
 
-static int MapSys (const char* Name)
-/* Map a target name to a system code. Return -1 in case of an error */
-{
-    unsigned I;
-
-    /* Check for a numeric target */
-    if (isdigit (*Name)) {
-       int Target = atoi (Name);
-       if (Target >= 0 && Target < TGT_COUNT) {
-           return Target;
-       }
-    }
-
-    /* Check for a target string */
-    for (I = 0; I < TGT_COUNT; ++I) {
-       if (strcmp (TargetNames [I], Name) == 0) {
-           return I;
-       }
-    }
-    /* Not found */
-    return -1;
-}
-
-
-
 static void SetSys (const char* Sys)
 /* Define a target system */
 {
-    switch (Target = MapSys (Sys)) {
+    switch (Target = FindTarget (Sys)) {
 
        case TGT_NONE:
            break;
@@ -192,26 +158,55 @@ static void SetSys (const char* Sys)
            break;
 
        case TGT_PET:
-           cbmsys ("__PET__");
-           break;
+           cbmsys ("__PET__");
+           break;
 
-       case TGT_NES:
-           AddNumericMacro ("__NES__", 1);
-           break;
+       case TGT_BBC:
+           AddNumericMacro ("__BBC__", 1);
+           break;
 
-       case TGT_APPLE2:
-           AddNumericMacro ("__APPLE2__", 1);
-           break;
+       case TGT_APPLE2:
+           AddNumericMacro ("__APPLE2__", 1);
+           break;
 
-       case TGT_GEOS:
-           /* Do not handle as a CBM system */
-           AddNumericMacro ("__GEOS__", 1);
-           break;
+       case TGT_GEOS:
+           /* Do not handle as a CBM system */
+           AddNumericMacro ("__GEOS__", 1);
+           break;
 
-       default:
-           fputs ("Unknown system type\n", stderr);
-           exit (EXIT_FAILURE);
+       default:
+                   AbEnd ("Unknown target system type");
     }
+
+    /* Initialize the translation tables for the target system */
+    TgtTranslateInit ();
+}
+
+
+
+static void DoCreateDep (const char* OutputName)
+/* Create the dependency file */
+{
+    /* Make the dependency file name from the output file name */
+    char* DepName = MakeFilename (OutputName, ".u");
+
+    /* Open the file */
+    FILE* F = fopen (DepName, "w");
+    if (F == 0) {
+       Fatal ("Cannot open dependency file `%s': %s", DepName, strerror (errno));
+    }
+
+    /* Write the dependencies to the file */
+    WriteDependencies (F, OutputName);
+
+    /* Close the file, check for errors */
+    if (fclose (F) != 0) {
+       remove (DepName);
+       Fatal ("Cannot write to dependeny file (disk full?)");
+    }
+
+    /* Free the name */
+    xfree (DepName);
 }
 
 
@@ -222,12 +217,12 @@ static void DefineSym (const char* Def)
     const char* P = Def;
 
     /* The symbol must start with a character or underline */
-    if (Def [0] != '_' && !isalpha (Def [0])) {
+    if (Def [0] != '_' && !IsAlpha (Def [0])) {
        InvDef (Def);
     }
 
     /* Check the symbol name */
-    while (isalnum (*P) || *P == '_') {
+    while (IsAlNum (*P) || *P == '_') {
        ++P;
     }
 
@@ -237,7 +232,7 @@ static void DefineSym (const char* Def)
            InvDef (Def);
        }
        /* No value given. Define the macro with the value 1 */
-       AddNumericMacro (Def, 1);
+       AddNumericMacro (Def, 1);
     } else {
        /* We have a value, P points to the '=' character. Since the argument
         * is const, create a copy and replace the '=' in the copy by a zero
@@ -245,7 +240,7 @@ static void DefineSym (const char* Def)
                 */
        char* Q;
        unsigned Len = strlen (Def)+1;
-       char* S = xmalloc (Len);
+       char* S = (char*) xmalloc (Len);
        memcpy (S, Def, Len);
        Q = S + (P - Def);
        *Q++ = '\0';
@@ -260,6 +255,17 @@ static void DefineSym (const char* Def)
 
 
 
+static void CheckSegName (const char* Seg)
+/* Abort if the given name is not a valid segment name */
+{
+    /* Print an error and abort if the name is not ok */
+    if (!ValidSegName (Seg)) {
+       AbEnd ("Segment name `%s' is invalid", Seg);
+    }
+}
+
+
+
 static void OptAddSource (const char* Opt, const char* Arg)
 /* Add source lines as comments in generated assembler file */
 {
@@ -276,24 +282,93 @@ static void OptAnsi (const char* Opt, const char* Arg)
 
 
 
+static void OptBssName (const char* Opt, const char* Arg)
+/* Handle the --bss-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    NewSegName (SEG_BSS, Arg);
+}
+
+
+
+static void OptCheckStack (const char* Opt, const char* Arg)
+/* Handle the --check-stack option */
+{
+    CheckStack = 1;
+}
+
+
+
+static void OptCodeName (const char* Opt, const char* Arg)
+/* Handle the --code-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    NewSegName (SEG_CODE, Arg);
+}
+
+
+
+static void OptCodeSize (const char* Opt, const char* Arg)
+/* Handle the --codesize option */
+{
+    /* Numeric argument expected */
+    if (sscanf (Arg, "%u", &CodeSizeFactor) != 1 ||
+       CodeSizeFactor < 100 ||
+               CodeSizeFactor > 1000) {
+       AbEnd ("Argument for %s is invalid", Opt);
+    }
+}
+
+
+
+static void OptCreateDep (const char* Opt, const char* Arg)
+/* Handle the --create-dep option */
+{
+    CreateDep = 1;
+}
+
+
+
 static void OptCPU (const char* Opt, const char* Arg)
 /* Handle the --cpu option */
 {
-    if (Arg == 0) {
-       NeedArg (Opt);
-    }
     if (strcmp (Arg, "6502") == 0) {
                CPU = CPU_6502;
     } else if (strcmp (Arg, "65C02") == 0) {
        CPU = CPU_65C02;
     } else {
-       fprintf (stderr, "Invalid CPU: `%s'\n", Arg);
-       exit (EXIT_FAILURE);
+       AbEnd ("Invalid CPU: `%s'", Arg);
     }
 }
 
 
 
+static void OptDataName (const char* Opt, const char* Arg)
+/* Handle the --code-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    NewSegName (SEG_DATA, Arg);
+}
+
+
+
+static void OptDebug (const char* Opt, const char* Arg)
+/* Compiler debug mode */
+{
+    Debug = 1;
+}
+
+
+
 static void OptDebugInfo (const char* Opt, const char* Arg)
 /* Add debug info to the object file */
 {
@@ -314,14 +389,23 @@ static void OptHelp (const char* Opt, const char* Arg)
 static void OptIncludeDir (const char* Opt, const char* Arg)
 /* Add an include search path */
 {
-    if (Arg == 0) {
-       NeedArg (Opt);
-    }
     AddIncludePath (Arg, INC_SYS | INC_USER);
 }
 
 
 
+static void OptRodataName (const char* Opt, const char* Arg)
+/* Handle the --rodata-name option */
+{
+    /* Check for a valid name */
+    CheckSegName (Arg);
+
+    /* Set the name */
+    NewSegName (SEG_RODATA, Arg);
+}
+
+
+
 static void OptSignedChars (const char* Opt, const char* Arg)
 /* Make default characters signed */
 {
@@ -330,12 +414,17 @@ static void OptSignedChars (const char* Opt, const char* Arg)
 
 
 
+static void OptStaticLocals (const char* Opt, const char* Arg)
+/* Place local variables in static storage */
+{
+    StaticLocals = 1;
+}
+
+
+
 static void OptTarget (const char* Opt, const char* Arg)
 /* Set the target system */
 {
-    if (Arg == 0) {
-       NeedArg (Opt);
-    }
     SetSys (Arg);
 }
 
@@ -344,7 +433,7 @@ static void OptTarget (const char* Opt, const char* Arg)
 static void OptVerbose (const char* Opt, const char* Arg)
 /* Increase verbosity */
 {
-    ++Verbose;
+    ++Verbosity;
 }
 
 
@@ -363,16 +452,25 @@ int main (int argc, char* argv[])
 {
     /* Program long options */
     static const LongOpt OptTab[] = {
-       { "--add-source",       0,      OptAddSource            },
-       { "--ansi",             0,      OptAnsi                 },
-        { "--cpu",                     1,      OptCPU                  },
-       { "--debug-info",       0,      OptDebugInfo            },
-       { "--help",             0,      OptHelp                 },
+       { "--add-source",       0,      OptAddSource            },
+       { "--ansi",             0,      OptAnsi                 },
+       { "--bss-name",         1,      OptBssName              },
+               { "--check-stack",      0,      OptCheckStack           },
+       { "--code-name",        1,      OptCodeName             },
+       { "--codesize",         1,      OptCodeSize             },
+       { "--create-dep",       0,      OptCreateDep            },
+        { "--cpu",                     1,      OptCPU                  },
+       { "--data-name",        1,      OptDataName             },
+               { "--debug",            0,      OptDebug                },
+       { "--debug-info",       0,      OptDebugInfo            },
+       { "--help",             0,      OptHelp                 },
        { "--include-dir",      1,      OptIncludeDir           },
-       { "--signed-chars",     0,      OptSignedChars          },
-       { "--target",           1,      OptTarget               },
-       { "--verbose",          0,      OptVerbose              },
-       { "--version",          0,      OptVersion              },
+       { "--rodata-name",      1,      OptRodataName           },
+       { "--signed-chars",     0,      OptSignedChars          },
+               { "--static-locals",    0,      OptStaticLocals         },
+       { "--target",           1,      OptTarget               },
+       { "--verbose",          0,      OptVerbose              },
+       { "--version",          0,      OptVersion              },
     };
 
     int I;
@@ -382,16 +480,19 @@ int main (int argc, char* argv[])
     const char* InputFile  = 0;
 
     /* Initialize the cmdline module */
-    InitCmdLine (argc, argv, "cc65");
+    InitCmdLine (&argc, &argv, "cc65");
+
+    /* Initialize the default segment names */
+    InitSegNames ();
 
     /* Parse the command line */
     I = 1;
-    while (I < argc) {
+    while (I < (int)ArgCount) {
 
        const char* P;
 
                /* Get the argument */
-               const char* Arg = argv [I];
+               const char* Arg = ArgVec[I];
 
                /* Check for an option */
                if (Arg [0] == '-') {
@@ -400,10 +501,10 @@ int main (int argc, char* argv[])
 
                case '-':
                    LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
-                   break;
+                   break;
 
-               case 'd':       /* debug mode */
-                   Debug = 1;
+               case 'd':
+                   OptDebug (Arg, 0);
                    break;
 
                case 'h':
@@ -427,6 +528,10 @@ int main (int argc, char* argv[])
                    OptTarget (Arg, GetArg (&I, 2));
                    break;
 
+               case 'u':
+                   OptCreateDep (Arg, 0);
+                   break;
+
                case 'v':
                    OptVerbose (Arg, 0);
                    break;
@@ -440,8 +545,11 @@ int main (int argc, char* argv[])
                    while (*P) {
                        switch (*P++) {
                            case 'l':
-                               LocalsAreStatic = 1;
+                               OptStaticLocals (Arg, 0);
                                break;
+                           default:
+                               UnknownOption (Arg);
+                               break;
                        }
                    }
                    break;
@@ -456,21 +564,22 @@ int main (int argc, char* argv[])
 
                case 'O':
                    Optimize = 1;
-                   P = Arg + 2;
+                   P = Arg + 2;
                    while (*P) {
                        switch (*P++) {
-                           case 'f':
-                               sscanf (P, "%lx", (long*) &OptDisable);
+                           case 'f':
+                               sscanf (P, "%lx", (long*) &OptDisable);
                                break;
                            case 'i':
                                FavourSize = 0;
+                               CodeSizeFactor = 200;
                                break;
                            case 'r':
                                EnableRegVars = 1;
-                               break;
+                               break;
                            case 's':
                                InlineStdFuncs = 1;
-                               break;
+                               break;
                        }
                    }
                    break;
@@ -505,8 +614,7 @@ int main (int argc, char* argv[])
 
     /* Did we have a file spec on the command line? */
     if (InputFile == 0) {
-       fprintf (stderr, "%s: No input files\n", argv [0]);
-       exit (EXIT_FAILURE);
+       AbEnd ("No input files");
     }
 
     /* Open the input file */
@@ -517,6 +625,9 @@ int main (int argc, char* argv[])
        OutputFile = MakeFilename (InputFile, ".s");
     }
 
+
+
+
     /* Go! */
     Compile ();
 
@@ -525,15 +636,17 @@ int main (int argc, char* argv[])
 
        FILE* F;
 
-       /* Optimize the output if requested */
-       if (Optimize) {
-           OptDoOpt ();
-       }
+#if 0
+       /* Optimize the output if requested */
+       if (Optimize) {
+           OptDoOpt ();
+       }
+#endif
 
        /* Open the file */
        F = fopen (OutputFile, "w");
        if (F == 0) {
-           Fatal (FAT_CANNOT_OPEN_OUTPUT, strerror (errno));
+           Fatal ("Cannot open output file `%s': %s", OutputFile, strerror (errno));
        }
 
        /* Write the output to the file */
@@ -542,8 +655,14 @@ int main (int argc, char* argv[])
        /* Close the file, check for errors */
        if (fclose (F) != 0) {
            remove (OutputFile);
-           Fatal (FAT_CANNOT_WRITE_OUTPUT);
+           Fatal ("Cannot write to output file (disk full?)");
        }
+
+       /* Create dependencies if requested */
+       if (CreateDep) {
+           DoCreateDep (OutputFile);
+       }
+
     }
 
     /* Return an apropriate exit code */