DS80C400 support, the beginning
[fw/sdcc] / src / SDCCmain.c
index b7132c0c2b9b2766f6b4e71d4a5f73d8d38e7a6d..033b5afb29386e0aae792984688f567a7af02a10 100644 (file)
 #include "SDCCdebug.h"
 #include "SDCCargs.h"
 
-#if NATIVE_WIN32
+#ifdef _WIN32
 #include <process.h>
-#endif
-
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
+#else
 #include <sys/stat.h>
 #include <unistd.h>
 #endif
 
-/** Name of the environment variable checked for other instalations. */
-#define SDCCDIR_NAME "SDCCDIR"
-
 //REMOVE ME!!!
 extern int yyparse ();
 
@@ -60,16 +55,19 @@ char *dstPath = "";         /* path for the output files; */
                                /* "" is equivalent with cwd */
 char *moduleName;              /* module name is source file without path and extension */
                                /* can be NULL while linking without compiling */
+/*
+ * in following definitions fixed length arrays are very dangerous!
+ * Sets should be used instead. See definition of asmOptions.
+ */
 const char *preArgv[128];      /* pre-processor arguments  */
 int currRegBank = 0;
-int RegBankUsed[4]={1, 0, 0, 0};       /*JCF: Reg Bank 0 used by default*/
+int RegBankUsed[4]={1, 0, 0, 0}; /*JCF: Reg Bank 0 used by default*/
 struct optimize optimize;
 struct options options;
-char *VersionString = SDCC_VERSION_STR;
 int preProcOnly = 0;
 int noAssemble = 0;
+set *asmOptions = NULL;         /* set of assembler options */
 char *linkOptions[128];
-const char *asmOptions[128];
 char *libFiles[128];
 int nlibFiles = 0;
 char *libPaths[128];
@@ -88,10 +86,6 @@ int ds390_jammed = 0;
 char scratchFileName[PATH_MAX];
 char buffer[PATH_MAX * 2];
 
-// In MSC VC6 default search path for exe's to path for this
-
-char DefaultExePath[128];
-
 #define OPTION_HELP    "-help"
 
 #define LENGTH(_a)     (sizeof(_a)/sizeof(*(_a)))
@@ -117,7 +111,7 @@ char DefaultExePath[128];
 #define OPTION_NO_LABEL_OPT     "--nolabelopt"
 #define OPTION_NO_LOOP_INV     "--noinvariant"
 #define OPTION_NO_LOOP_IND     "--noinduction"
-#define OPTION_LESS_PEDANTIC   "--lesspedantic"
+#define OPTION_LESS_PEDANTIC   "--less-pedantic"
 #define OPTION_NO_GCSE         "--nogcse"
 #define OPTION_SHORT_IS_8BITS  "--short-is-8bits"
 #define OPTION_TINI_LIBID      "--tini-libid"
@@ -242,14 +236,14 @@ unsupportedOptTable[] = {
 /** List of all default constant macros.
  */
 static const char *_baseValues[] = {
-  "cpp", "{bindir}{sep}sdcpp",
+  "cpp", "sdcpp",
   "cppextraopts", "",
   /* Path seperator character */
   "sep", DIR_SEPARATOR_STRING,
   NULL
 };
 
-static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 -DSDCC=1 {cppextraopts} {fullsrcfilename} {cppoutfilename}";
+static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 -DSDCC=1 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
 
 PORT *port;
 
@@ -279,6 +273,9 @@ static PORT *_ports[] =
 #if !OPT_DISABLE_XA51
   &xa51_port,
 #endif
+#if !OPT_DISABLE_DS400
+  &ds400_port, 
+#endif 
 };
 
 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
@@ -383,7 +380,7 @@ printVersionInfo ()
   for (i = 0; i < NUM_PORTS; i++)
     fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
 
-  fprintf (stderr, " %s"
+  fprintf (stderr, " " SDCC_VERSION_STR
 #ifdef SDCC_SUB_VERSION_STR
           "/" SDCC_SUB_VERSION_STR
 #endif
@@ -401,8 +398,6 @@ printVersionInfo ()
 #else
           " (UNIX) \n"
 #endif
-
-          ,VersionString
     );
 }
 
@@ -475,6 +470,26 @@ parseWithComma (char **dest, char *src)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* setParseWithComma - separates string with comma to a set        */
+/*-----------------------------------------------------------------*/
+void
+setParseWithComma (set **dest, char *src)
+{
+  char *p;
+
+  /* skip the initial white spaces */
+  while (isspace (*src))
+    src++;
+
+  if ((p = strtok(src, ",")) != NULL) {
+    do
+    {
+      addSet(dest, p);
+    } while ((p = strtok(NULL, ",")) != NULL);
+  }
+}
+
 /*-----------------------------------------------------------------*/
 /* setDefaultOptions - sets the default options                    */
 /*-----------------------------------------------------------------*/
@@ -484,9 +499,7 @@ setDefaultOptions ()
   int i;
 
   for (i = 0; i < 128; i++)
-    preArgv[i] = asmOptions[i] =
-      linkOptions[i] = relFiles[i] = libFiles[i] =
-      libPaths[i] = NULL;
+    preArgv[i] = linkOptions[i] = relFiles[i] = libFiles[i] = libPaths[i] = NULL;
 
   /* first the options part */
   options.stack_loc = 0;       /* stack pointer initialised to 0 */
@@ -1088,7 +1101,7 @@ parseCmdLine (int argc, char **argv)
               /* assembler options */
              else if (argv[i][2] == 'a')
                 {
-                  parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
+                  setParseWithComma (&asmOptions, getStringArg("-Wa", argv, &i, argc));
                 }
               else
                 {
@@ -1145,7 +1158,8 @@ parseCmdLine (int argc, char **argv)
                if (sOpt == 'Y')
                  sOpt = 'I';
 
-               SNPRINTF (buffer, sizeof(buffer), "-%c%s", sOpt, rest);
+                SNPRINTF (buffer, sizeof(buffer),
+                  ((sOpt == 'I') ? "-%c\"%s\"": "-%c%s"), sOpt, rest);
                addToList (preArgv, buffer);
              }
              break;
@@ -1346,7 +1360,21 @@ linkEdit (char **envp)
          break;
        case MODEL_FLAT24:
          /* c = "flat24"; */
-         c = "ds390";
+           if (TARGET_IS_DS390)
+           {
+               c = "ds390";
+           }
+           else if (TARGET_IS_DS400)
+           {
+               c = "ds400";
+           }
+           else
+           {
+               fprintf(stderr, 
+                       "Add support for your FLAT24 target in %s @ line %d\n",
+                       __FILE__, __LINE__);
+               exit(-1);
+           }
          break;
        case MODEL_PAGE0:
          c = "xa51";
@@ -1362,7 +1390,21 @@ linkEdit (char **envp)
 #if !OPT_DISABLE_DS390
       if (options.model == MODEL_FLAT24)
        {
-         fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
+           if (TARGET_IS_DS390)
+           {
+               fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
+           }
+           else if (TARGET_IS_DS400)
+           {
+               fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
+           }
+           else
+           {
+               fprintf(stderr, 
+                       "Add support for your FLAT24 target in %s @ line %d\n",
+                       __FILE__, __LINE__);
+               exit(-1);
+           }       
        }
 #endif
 
@@ -1598,7 +1640,7 @@ preProcess (char **envp)
 
       /* standard include path */
       if (!options.nostdinc) {
-       addToList (preArgv, "-I{includedir}");
+       addToList (preArgv, "-I\"{includedir}\"");
       }
 
       setMainValue ("cppextraopts", join(preArgv));
@@ -1610,8 +1652,8 @@ preProcess (char **envp)
        }
       else
        {
-         /* Have to set cppoutfilename to something, even if piping */
-         setMainValue ("cppoutfilename", "");
+         /* Piping: set cppoutfilename to NULL, to avoid empty quotes */
+         setMainValue ("cppoutfilename", NULL);
        }
 
       if (options.verbose)
@@ -1638,133 +1680,117 @@ preProcess (char **envp)
   return 0;
 }
 
-static bool
-_setPaths (const char *pprefix)
+/* Set bin paths */
+static void
+setBinPaths(const char *argv0)
 {
-  /* Logic:
-      Given the prefix and how the directories were layed out at
-      configure time, see if the library and include directories are
-      where expected.  If so, set.
-  */
-  getPathDifference (buffer, PREFIX, SDCC_INCLUDE_DIR);
-  strncpyz (scratchFileName, pprefix, sizeof(scratchFileName));
-  strncatz (scratchFileName, buffer, sizeof(scratchFileName));
-
-  if (pathExists (scratchFileName))
-    {
-      setMainValue ("includedir", scratchFileName);
-    }
-  else
-    {
-      return FALSE;
-    }
+  char *p;
+  char buf[PATH_MAX];
+
+  /*
+   * Search logic:
+   *
+   * 1. - $SDCCDIR/PREFIX2BIN_DIR
+   * 2. - path(argv[0])
+   * 3. - $PATH
+   */
 
-  getPathDifference (buffer, PREFIX, SDCC_LIB_DIR);
-  strncpyz (scratchFileName, pprefix, sizeof(scratchFileName));
-  strncatz (scratchFileName, buffer, sizeof(scratchFileName));
+  /* do it in reverse mode, so that addSetHead() can be used
+     instaed of slower addSet() */
 
-  if (pathExists (scratchFileName))
-    {
-      setMainValue ("libdir", scratchFileName);
-    }
-  else
-    {
-      return FALSE;
-    }
+  if ((p = getBinPath(argv0)) != NULL)
+    addSetHead(&binPathSet, Safe_strdup(p));
 
-  return TRUE;
+  if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
+    SNPRINTF(buf, sizeof buf, "%s" PREFIX2BIN_DIR, p);
+    addSetHead(&binPathSet, Safe_strdup(buf));
+  }
 }
 
+/* Set system include path */
 static void
-_discoverPaths (const char *argv0)
+setIncludePath(const char *datadir)
 {
-  /* Logic:
-      1.  Try the SDCCDIR environment variable.
-      2.  If (1) fails, and if the argv[0] includes a path, attempt to find the include
-      and library paths with respect to that.  Note that under win32
-      argv[0] is always the full path to the program.
-      3.  If (1) and (2) fail, fall back to the compile time defaults.
-
-      Detecting assumes the same layout as when configured.  If the
-      directories have been further moved about then discovery will
-      fail.
-  */
-
-  /* Some input cases:
-        "c:\fish\sdcc\bin\sdcc"
-        "../bin/sdcc"
-        "/home/fish/bin/sdcc"
-
-      Note that ./sdcc is explicitly not supported as there isn't
-      enough information.
-  */
-  /* bindir is handled differently to the lib and include directories.
-     It's rather unfortunate, but required due to the different
-     install and development layouts.  Logic is different as well.
-     Sigh.
+  char *p;
+  char buf[PATH_MAX];
+
+  /*
+   * Search logic:
+   *
+   * 1. - $SDCC_INCLUDE
+   * 2. - $SDCC_HOME/PREFIX2DATA_DIR/INCLUDE_DIR_SUFFIX
+   * 3. - path(argv[0])/BIN2DATA_DIR/INCLUDE_DIR_SUFFIX
+   * 4. - DATADIR/INCLUDE_DIR_SUFFIX (only on *nix)
    */
-  if (strchr (argv0, DIR_SEPARATOR_CHAR))
-    {
-      strncpyz (scratchFileName, argv0, sizeof(scratchFileName));
-      *strrchr (scratchFileName, DIR_SEPARATOR_CHAR) = '\0';
-      setMainValue ("bindir", scratchFileName);
-      ExePathList[0] = Safe_strdup (scratchFileName);
-    }
-  else if (getenv (SDCCDIR_NAME) != NULL)
-    {
-      getPathDifference (buffer, PREFIX, BINDIR);
-      strncpyz (scratchFileName, getenv (SDCCDIR_NAME), sizeof(scratchFileName));
-      strncatz (scratchFileName, buffer, sizeof(scratchFileName));
-      setMainValue ("bindir", scratchFileName);
-      ExePathList[0] = Safe_strdup (scratchFileName);
-    }
-  else
-    {
-      setMainValue ("bindir", BINDIR);
-      ExePathList[0] = BINDIR;
-    }
 
-  do
-    {
-      /* Case 1 */
-      if (getenv (SDCCDIR_NAME) != NULL)
-        {
-          if (_setPaths (getenv (SDCCDIR_NAME)))
-            {
-              /* Successfully set. */
-              break;
-            }
-          else
-            {
-              /* Include and lib weren't where expected. */
-            }
-        }
-      /* Case 2 */
-      if (strchr (argv0, DIR_SEPARATOR_CHAR))
-        {
-          char *pbase = getPrefixFromBinPath (argv0);
+  if ((p = getenv(SDCC_INCLUDE_NAME)) == NULL) {
+    SNPRINTF(buf, sizeof buf, "%s" INCLUDE_DIR_SUFFIX, datadir);
+    p = buf;
+  }
 
-          if (pbase == NULL)
-            {
-              /* A bad path.  Skip. */
-            }
-          else
-            {
-              if (_setPaths (pbase))
-                {
-                  /* Successfully set. */
-                  break;
-                }
-              else
-                {
-                  /* Include and lib weren't where expected. */
-                }
-            }
-        }
-      /* Case 3 */
-      setMainValue ("includedir", SDCC_INCLUDE_DIR);
-      setMainValue ("libdir", SDCC_LIB_DIR);
-    } while (0);
+  setMainValue ("includedir", p);
+}
+
+/* Set system lib path */
+static void
+setLibPath(const char *datadir)
+{
+  char *p;
+  char buf[PATH_MAX];
+
+  /*
+   * Search logic:
+   *
+   * 1. - $SDCC_LIB
+   * 2. - $SDCC_HOME/PREFIX2DATA_DIR/LIB_DIR_SUFFIX/<model>
+   * 3. - path(argv[0])/BIN2DATA_DIR/LIB_DIR_SUFFIX/<model>
+   * 4. - DATADIR/LIB_DIR_SUFFIX/<model> (only on *nix)
+   */
+
+  if ((p = getenv(SDCC_LIB_NAME)) == NULL) {
+    SNPRINTF(buf, sizeof buf, "%s" LIB_DIR_SUFFIX, datadir);
+    p = buf;
+  }
+
+  setMainValue ("libdir", p);
+}
+
+/* Set data path */
+static void
+setDataPaths(const char *argv0)
+{
+  char *p;
+  char buf[PATH_MAX];
+
+  /*
+   * Search logic:
+   *
+   * 1. - $SDCC_HOME/PREFIX2DATA_DIR
+   * 2. - path(argv[0])/BIN2DATA_DIR
+   * 3. - DATADIR (only on *nix)
+   */
+
+  if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
+    SNPRINTF(buf, sizeof buf, "%s" PREFIX2DATA_DIR, p);
+    p = buf;
+  }
+  else {
+    if ((p = getBinPath(argv0)) == NULL)
+      p = ".";
+
+    SNPRINTF(buf, sizeof buf, "%s" BIN2DATA_DIR, p);
+    p = buf;
+
+#ifndef _WIN32  /* *nix paltform */
+    if (!pathExists(p))
+      p = DATADIR; /* last resort */
+#endif
+  }
+
+  setIncludePath(p);
+  setLibPath(p);
+
+  setMainValue ("datadir", p);
 }
 
 static void
@@ -1899,7 +1925,8 @@ main (int argc, char **argv, char **envp)
     }
 
   initValues ();
-  _discoverPaths (argv[0]);
+  setBinPaths(argv[0]);
+  setDataPaths(argv[0]);
 
   /* initMem() is expensive, but
      initMem() must called before port->finaliseOptions ().