* src/port.h: added TARGET_Z80_LIKE macro
[fw/sdcc] / src / SDCCmain.c
index f8b61bd741ba23bb163640d6815f186ae319e6d5..8cb6954b63add725be2b44154093529f8767fa5c 100644 (file)
@@ -91,10 +91,9 @@ int ds390_jammed = 0;
 char scratchFileName[PATH_MAX];
 char buffer[PATH_MAX * 2];
 
-#define OPTION_HELP     "-help"
-
 #define LENGTH(_a)      (sizeof(_a)/sizeof(*(_a)))
 
+#define OPTION_HELP             "--help"
 #define OPTION_STACK_8BIT       "--stack-8bit"
 #define OPTION_OUT_FMT_IHX      "--out-fmt-ihx"
 #define OPTION_OUT_FMT_S19      "--out-fmt-s19"
@@ -146,7 +145,7 @@ char buffer[PATH_MAX * 2];
 static const OPTION
 optionsTable[] = {
     { 0,    NULL,                   NULL, "General options" },
-    { 0,    "--help",               NULL, "Display this help" },
+    { 0,    OPTION_HELP,            NULL, "Display this help" },
     { 'v',  OPTION_VERSION,         NULL, "Display sdcc's version" },
     { 0,    "--verbose",            &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
     { 'V',  NULL,                   &options.verboseExec, "Execute verbosely.  Show sub commands as they are run" },
@@ -165,7 +164,7 @@ optionsTable[] = {
     { 'o',  NULL,                   NULL, "Place the output into the given path resp. file" },
     { 0,    OPTION_PRINT_SEARCH_DIRS, &options.printSearchDirs, "display the directories in the compiler's search path"},
     { 0,    OPTION_MSVC_ERROR_STYLE, &options.vc_err_style, "messages are compatible with Micro$oft visual studio"},
-    { 0,    OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
+    { 0,    OPTION_USE_STDOUT,      NULL, "send errors to stdout instead of stderr"},
     { 0,    "--nostdlib",           &options.nostdlib, "Do not include the standard library directory in the search path" },
     { 0,    "--nostdinc",           &options.nostdinc, "Do not include the standard include directory in the search path" },
     { 0,    OPTION_LESS_PEDANTIC,   NULL, "Disable some of the more pedantic warnings" },
@@ -257,14 +256,16 @@ optionsTable[] = {
     { 0,    OPTION_XRAM_LOC,        NULL, "<nnnn> External Ram start location" },
     { 0,    OPTION_XRAM_SIZE,       NULL, "<nnnn> External Ram size" },
     { 0,    OPTION_IRAM_SIZE,       NULL, "<nnnn> Internal Ram size" },
-    { 0,    OPTION_XSTACK_LOC,      NULL, "<nnnn> External Ram start location" },
+    { 0,    OPTION_XSTACK_LOC,      NULL, "<nnnn> External Stack start location" },
     { 0,    OPTION_CODE_LOC,        NULL, "<nnnn> Code Segment Location" },
     { 0,    OPTION_CODE_SIZE,       NULL, "<nnnn> Code Segment size" },
     { 0,    OPTION_STACK_LOC,       NULL, "<nnnn> Stack pointer initial value" },
     { 0,    OPTION_DATA_LOC,        NULL, "<nnnn> Direct data start location" },
     { 0,    OPTION_IDATA_LOC,       NULL, NULL },
+#if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51 || !OPT_DISABLE_PIC
+    { 0,    OPTION_STACK_SIZE,      NULL,"MCS51/DS390/PIC - Tells the linker to allocate this space for stack"},
+#endif
 #if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51
-    { 0,    OPTION_STACK_SIZE,      NULL,"MCS51/DS390 - Tells the linker to allocate this space for stack"},
     { 0,    OPTION_PACK_IRAM,       NULL,"MCS51/DS390 - Tells the linker to pack variables in internal ram (default)"},
     { 0,    OPTION_NO_PACK_IRAM,    &options.no_pack_iram,"MCS51/DS390 - Tells the linker not to pack variables in internal ram"},
 #endif
@@ -306,7 +307,7 @@ static const char *_baseValues[] = {
   NULL
 };
 
-static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 -DSDCC=1 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
+static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
 
 PORT *port;
 
@@ -436,16 +437,16 @@ _findProcessor (int argc, char **argv)
 /* printVersionInfo - prints the version info        */
 /*-----------------------------------------------------------------*/
 void
-printVersionInfo (void)
+printVersionInfo (FILE *stream)
 {
   int i;
 
-  fprintf (stderr,
+  fprintf (stream,
            "SDCC : ");
   for (i = 0; i < NUM_PORTS; i++)
-    fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
+    fprintf (stream, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
 
-  fprintf (stderr, " " SDCC_VERSION_STR
+  fprintf (stream, " " SDCC_VERSION_STR
 #ifdef SDCC_SUB_VERSION_STR
            "/" SDCC_SUB_VERSION_STR
 #endif
@@ -467,7 +468,7 @@ printVersionInfo (void)
 }
 
 static void
-printOptions(const OPTION *optionsTable)
+printOptions(const OPTION *optionsTable, FILE *stream)
 {
   int i;
   for (i = 0;
@@ -478,11 +479,11 @@ printOptions(const OPTION *optionsTable)
       if (!optionsTable[i].shortOpt && !optionsTable[i].longOpt
           && optionsTable[i].help)
         {
-          fprintf (stdout, "\n%s:\n", optionsTable[i].help);
+          fprintf (stream, "\n%s:\n", optionsTable[i].help);
         }
       else
         {
-          fprintf(stdout, "  %c%c  %-20s  %s\n",
+          fprintf(stream, "  %c%c  %-20s  %s\n",
                   optionsTable[i].shortOpt !=0 ? '-' : ' ',
                   optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
                   optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
@@ -495,50 +496,63 @@ printOptions(const OPTION *optionsTable)
 /*-----------------------------------------------------------------*/
 /* printUsage - prints command line syntax         */
 /*-----------------------------------------------------------------*/
-void
+static void
 printUsage (void)
 {
     int i;
-    printVersionInfo();
-    fprintf (stdout,
+    FILE *stream = stderr;
+
+    printVersionInfo (stream);
+    fprintf (stream,
              "Usage : sdcc [options] filename\n"
              "Options :-\n"
              );
 
-    printOptions(optionsTable);
+    printOptions (optionsTable, stream);
 
     for (i = 0; i < NUM_PORTS; i++)
       {
         if (_ports[i]->poptions != NULL)
           {
-            fprintf (stdout, "\nSpecial options for the %s port:\n", _ports[i]->target);
-            printOptions (_ports[i]->poptions);
+            fprintf (stream, "\nSpecial options for the %s port:\n", _ports[i]->target);
+            printOptions (_ports[i]->poptions, stream);
           }
       }
-
-    exit (0);
 }
 
 /*-----------------------------------------------------------------*/
 /* setParseWithComma - separates string with comma to a set        */
 /*-----------------------------------------------------------------*/
 void
-setParseWithComma (set **dest, char *src)
+setParseWithComma (set **dest, const char *src)
 {
-  char *p;
-  int length;
+  const char *p, *end;
+  struct dbuf_s dbuf;
 
   /* skip the initial white spaces */
   while (isspace((unsigned char)*src))
-    src++;
+    ++src;
 
   /* skip the trailing white spaces */
-  length = strlen(src);
-  while (length && isspace((unsigned char)src[length-1]))
-    src[--length] = '\0';
+  end = &src[strlen(src) - 1];
+  while (end >= src && isspace((unsigned char)*end))
+    --end;
+  ++end;
+
+  dbuf_init(&dbuf, 16);
+
+  p = src;
+  while (src < end)
+    {
+      while (p < end && ',' != *p)
+        ++p;
+      dbuf_append(&dbuf, src, p - src);
+      addSet(dest, Safe_strdup(dbuf_c_str(&dbuf)));
+      dbuf_set_size(&dbuf, 0);
+      src = ++p;
+    }
 
-  for (p = strtok(src, ","); p != NULL; p = strtok(NULL, ","))
-    addSet(dest, Safe_strdup(p));
+  dbuf_destroy(&dbuf);
 }
 
 /*-----------------------------------------------------------------*/
@@ -553,7 +567,7 @@ setDefaultOptions (void)
   options.code_loc = 0;           /* code starts at 0 */
   options.data_loc = 0;           /* JCF: By default let the linker locate data */
   options.xdata_loc = 0;
-  options.idata_loc = 0x80;
+  options.idata_loc = 0;          /* MB: No need to limit idata to 0x80-0xFF */
   options.nopeep = 0;
   options.model = port->general.default_model;
   options.nostdlib = 0;
@@ -631,7 +645,7 @@ processFile (char *s)
           /* is the dot in the filename, not in the path? */
           (strrchr (buffer, DIR_SEPARATOR_CHAR) < strrchr (buffer, '.')))
         {
-        *strrchr (buffer, '.') = '\0';
+          *strrchr (buffer, '.') = '\0';
         }
 
       /* get rid of any path information
@@ -644,7 +658,7 @@ processFile (char *s)
              *(fext - 1) != DIR_SEPARATOR_CHAR &&
              *(fext - 1) != ':')
         {
-        fext--;
+          fext--;
         }
 #else
       /* do this by going backwards till we
@@ -665,7 +679,7 @@ processFile (char *s)
     }
 
   /* if the extention is type .rel or .r or .REL or .R
-     addtional object file will be passed to the linker */
+     additional object file will be passed to the linker */
   if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
       strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
       strcmp (fext, port->linker.rel_ext) == 0)
@@ -711,7 +725,7 @@ getStringArg(const char *szStart, char **argv, int *pi, int argc)
         {
           werror (E_ARGUMENT_MISSING, szStart);
           /* Die here rather than checking for errors later. */
-          exit(-1);
+          exit(EXIT_FAILURE);
         }
       else
         {
@@ -881,10 +895,19 @@ parseCmdLine (int argc, char **argv)
       /* options */
       if (argv[i][0] == '-' && argv[i][1] == '-')
         {
+          if (strcmp (argv[i], OPTION_USE_STDOUT) == 0)
+            {
+              if (options.use_stdout == 0)
+                {
+                  options.use_stdout = 1;
+                  dup2(STDOUT_FILENO, STDERR_FILENO);
+                }
+              continue;
+            }
           if (strcmp (argv[i], OPTION_HELP) == 0)
             {
               printUsage ();
-              exit (0);
+              exit (EXIT_SUCCESS);
             }
 
           if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
@@ -955,8 +978,8 @@ parseCmdLine (int argc, char **argv)
 
           if (strcmp (argv[i], OPTION_VERSION) == 0)
             {
-              printVersionInfo ();
-              exit (0);
+              printVersionInfo (stdout);
+              exit (EXIT_SUCCESS);
               continue;
             }
 
@@ -1154,7 +1177,7 @@ parseCmdLine (int argc, char **argv)
               verifyShortOption(argv[i]);
 
               printUsage ();
-              exit (0);
+              exit (EXIT_SUCCESS);
               break;
 
             case 'm':
@@ -1246,7 +1269,7 @@ parseCmdLine (int argc, char **argv)
             case 'v':
               verifyShortOption(argv[i]);
 
-              printVersionInfo ();
+              printVersionInfo (stdout);
               exit (0);
               break;
 
@@ -1428,7 +1451,6 @@ parseCmdLine (int argc, char **argv)
         werror (E_FILE_OPEN_ERR, scratchFileName);
     }
   MSVC_style(options.vc_err_style);
-  if(options.use_stdout) dup2(STDOUT_FILENO, STDERR_FILENO);
 
   return 0;
 }
@@ -1475,7 +1497,7 @@ linkEdit (char **envp)
           exit (1);
         }
 
-      if (TARGET_IS_Z80 || TARGET_IS_GBZ80)
+      if (TARGET_Z80_LIKE)
         {
           fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
             out_fmt, dstFileName);
@@ -1487,7 +1509,7 @@ linkEdit (char **envp)
               fprintf (lnkfile, "-Y\n");
         }
 
-      if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+      if (!(TARGET_Z80_LIKE)) /*Not for the z80, gbz80*/
         {
           /* if iram size specified */
           if (options.iram_size)
@@ -1515,7 +1537,7 @@ linkEdit (char **envp)
   fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
   if (segName) { Safe_free(segName); }
 
-      if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+      if (!(TARGET_Z80_LIKE)) /*Not for the z80, gbz80*/
         {
 
           /* code segment start */
@@ -1523,18 +1545,25 @@ linkEdit (char **envp)
 
           /* data segment start. If zero, the linker chooses
              the best place for data */
-          if(options.data_loc)
+          if (options.data_loc)
             {
               WRITE_SEG_LOC (DATA_NAME, options.data_loc);
             }
 
           /* xdata segment start. If zero, the linker chooses
              the best place for xdata */
-          if(options.xdata_loc)
+          if (options.xdata_loc)
             {
               WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
             }
 
+          /* pdata/xstack segment start. If zero, the linker
+             chooses the best place for them */
+          if (options.xstack_loc)
+            {
+              WRITE_SEG_LOC (PDATA_NAME, options.xstack_loc);
+            }
+
           /* indirect data */
           if (IDATA_NAME)
             {
@@ -1573,7 +1602,7 @@ linkEdit (char **envp)
       /* standard library path */
       if (!options.nostdlib)
         {
-          if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+          if (!(TARGET_Z80_LIKE || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
             {
               switch (options.model)
                 {
@@ -1610,7 +1639,7 @@ linkEdit (char **envp)
                       fprintf(stderr,
                         "Add support for your FLAT24 target in %s @ line %d\n",
                         __FILE__, __LINE__);
-                      exit(-1);
+                      exit(EXIT_FAILURE);
                     }
                   break;
                 case MODEL_PAGE0:
@@ -1658,7 +1687,7 @@ linkEdit (char **envp)
                   fprintf(stderr,
                     "Add support for your FLAT24 target in %s @ line %d\n",
                     __FILE__, __LINE__);
-                  exit(-1);
+                  exit(EXIT_FAILURE);
                 }
               }
 #endif
@@ -1675,8 +1704,7 @@ linkEdit (char **envp)
             {
               fprintf (lnkfile, "-l mcs51\n");
             }
-          if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80
-            || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+          if (!(TARGET_Z80_LIKE || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
             { /*Why the z80 port is not using the standard libraries?*/
               fprintf (lnkfile, "-l %s\n", STD_LIB);
               fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
@@ -1700,8 +1728,7 @@ linkEdit (char **envp)
       /*For the z80 and gbz80 ports, try to find where crt0.o is...
       It is very important for this file to be first on the linking proccess
       so the areas are set in the correct order, expecially _GSINIT*/
-      if ((TARGET_IS_Z80 || TARGET_IS_GBZ80) &&
-        !options.no_std_crt0) /*For the z80, gbz80*/
+      if ((TARGET_Z80_LIKE) && !options.no_std_crt0) /*For the z80, gbz80*/
         {
           char crt0path[PATH_MAX];
           FILE * crt0fp;
@@ -1786,7 +1813,7 @@ linkEdit (char **envp)
       set *tempSet=NULL, *libSet=NULL;
 
       strcpy(buffer3, linkerScriptFileName);
-      if(TARGET_IS_PIC16 || TARGET_IS_PIC) {
+      if(/*TARGET_IS_PIC16 ||*/ TARGET_IS_PIC) {
 
          /* use $l to set the linker include directories */
          tempSet = appendStrSet(libDirsSet, "-I\"", "\"");
@@ -1823,6 +1850,13 @@ linkEdit (char **envp)
   /*  if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer); */
 
   system_ret = my_system (buffer);
+
+#ifdef _WIN32
+  #define STRCMP stricmp
+#else
+  #define STRCMP strcmp
+#endif
+
   /* TODO: most linker don't have a -o parameter */
   /* -o option overrides default name? */
   if (fullDstFileName)
@@ -1851,8 +1885,8 @@ linkEdit (char **envp)
       strncatz (scratchFileName,
         options.out_fmt ? ".S19" : ".ihx",
         sizeof(scratchFileName));
-      if (strcmp (fullDstFileName, scratchFileName))
-        unlink (fullDstFileName);
+      if (STRCMP (fullDstFileName, scratchFileName))
+        remove (fullDstFileName);
       rename (scratchFileName, fullDstFileName);
 
       strncpyz (buffer, fullDstFileName, sizeof(buffer));
@@ -1867,15 +1901,15 @@ linkEdit (char **envp)
       strncatz (scratchFileName, ".map", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".map", sizeof(buffer));
-      if (strcmp (scratchFileName, buffer))
-        unlink (buffer);
+      if (STRCMP (scratchFileName, buffer))
+        remove (buffer);
       rename (scratchFileName, buffer);
       *p = 0;
       strncatz (scratchFileName, ".mem", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".mem", sizeof(buffer));
-      if (strcmp (scratchFileName, buffer))
-        unlink (buffer);
+      if (STRCMP (scratchFileName, buffer))
+        remove (buffer);
       rename (scratchFileName, buffer);
       if (options.debug)
         {
@@ -1883,14 +1917,14 @@ linkEdit (char **envp)
           strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
           *q = 0;
           strncatz(buffer, ".cdb", sizeof(buffer));
-          if (strcmp (scratchFileName, buffer))
-            unlink (buffer);
+          if (STRCMP (scratchFileName, buffer))
+            remove (buffer);
           rename (scratchFileName, buffer);
           /* and the OMF file without extension: */
           *p = 0;
           *q = 0;
-          if (strcmp (scratchFileName, buffer))
-            unlink (buffer);
+          if (STRCMP (scratchFileName, buffer))
+            remove (buffer);
           rename (scratchFileName, buffer);
         }
     }
@@ -1943,7 +1977,7 @@ assemble (char **envp)
                   port->linker.rel_ext,
                   sizeof(scratchFileName));
         if (strcmp (scratchFileName, fullDstFileName))
-          unlink (fullDstFileName);
+          remove (fullDstFileName);
         rename (scratchFileName, fullDstFileName);
     }
 }
@@ -2015,10 +2049,24 @@ preProcess (char **envp)
           break;
         }
 
+      /* add SDCC version number */
+      {
+        char buf[20];
+        SNPRINTF(buf, sizeof(buf), "-DSDCC=%d%d%d",
+                 SDCC_VERSION_HI, SDCC_VERSION_LO, SDCC_VERSION_P);
+        addSet(&preArgvSet, Safe_strdup(buf));
+      }
+
       /* add port (processor information to processor */
       addSet(&preArgvSet, Safe_strdup("-DSDCC_{port}"));
       addSet(&preArgvSet, Safe_strdup("-D__{port}"));
 
+      if (port && port->processor && TARGET_IS_PIC) {
+        char proc[512];
+       SNPRINTF(&proc[0], 512, "-DSDCC_PROCESSOR=\"%s\"", port->processor);
+       addSet(&preArgvSet, Safe_strdup(proc));
+      }
+
       /* standard include path */
       if (!options.nostdinc) {
         inclList = appendStrSet(includeDirsSet, "-I\"", "\"");
@@ -2283,8 +2331,6 @@ main (int argc, char **argv, char **envp)
   /* turn all optimizations off by default */
   memset (&optimize, 0, sizeof (struct optimize));
 
-  /*printVersionInfo (); */
-
   if (NUM_PORTS==0) {
     fprintf (stderr, "Build error: no ports are enabled.\n");
     exit (1);
@@ -2294,7 +2340,7 @@ main (int argc, char **argv, char **envp)
   atexit(rm_tmpfiles);
 
   /* install signal handler;
-     it's only purpuse is to call exit() to remove temp files */
+     it's only purpose is to call exit() to remove temp files */
   if (!getenv("SDCC_LEAVE_SIGNALS"))
     {
       signal (SIGABRT, sig_handler);
@@ -2350,12 +2396,13 @@ main (int argc, char **argv, char **envp)
         doPrintSearchDirs();
 
   /* if no input then printUsage & exit */
-  if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL) {
-    if (!options.printSearchDirs)
+  if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL)
+    {
+      if (options.printSearchDirs)
+        exit (EXIT_SUCCESS);
       printUsage();
-
-    exit(0);
-  }
+      exit (EXIT_FAILURE);
+    }
 
   /* initMem() is expensive, but
      initMem() must called before port->finaliseOptions ().