fixed bug #631653
[fw/sdcc] / src / SDCCmain.c
index 19e9e7cf2d3b0dd7feb951ddbb9c32c15b61557e..06d3641a915dc8a049dd30d49f30cc58cfa70672 100644 (file)
@@ -34,8 +34,6 @@
 
 #if NATIVE_WIN32
 #include <process.h>
-#else
-#include "spawn.h"
 #endif
 
 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
@@ -124,6 +122,8 @@ char DefaultExePath[128];
 #define OPTION_SHORT_IS_8BITS  "--short-is-8bits"
 #define OPTION_TINI_LIBID      "--tini-libid"
 #define OPTION_NO_XINIT_OPT     "--no-xinit-opt"
+#define OPTION_XRAM_SIZE       "--xram-size"
+#define OPTION_CODE_SIZE       "--code-size"
 
 static const OPTION 
 optionsTable[] = {
@@ -149,7 +149,6 @@ optionsTable[] = {
     { 0,    OPTION_STACK_8BIT,      NULL, "use the 8bit stack for the ds390 (not supported yet)" },
     { 0,    "--stack-10bit",        &options.stack10bit, "use the 10bit stack for ds390 (default)" },
     { 0,    "--xstack",             &options.useXstack, "Use external stack" },
-    { 0,    "--generic",            &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
     { 0,    OPTION_NO_GCSE,         NULL, "Disable the GCSE optimisation" },
     { 0,    OPTION_NO_LOOP_INV,     NULL, "Disable optimisation of invariants" },
     { 0,    OPTION_NO_LOOP_IND,     NULL, NULL },
@@ -167,9 +166,11 @@ optionsTable[] = {
     { 0,    "--dumptree",           &options.dump_tree, "dump front-end AST before generating iCode" },
     { 0,    OPTION_DUMP_ALL,        NULL, "Dump the internal structure at all stages" },
     { 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_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 },
@@ -188,7 +189,6 @@ optionsTable[] = {
     { 0,    "--peep-asm",           &options.asmpeep, NULL },
     { 0,    "--debug",              &options.debug, "Enable debugging symbol output" },
     { 'v',  OPTION_VERSION,         NULL, "Display sdcc's version" },
-    { 0,    "--stack-after-data",   &options.stackOnData, "initialize the stackpointer with the last byte use in DSEG" },
     { 'E',  "--preprocessonly",     &preProcOnly, "Preprocess only, do not compile" },
     { 0,    "--c1mode",             &options.c1mode, "Act in c1 mode.  The input is preprocessed code, the output is assembly code." },
     { 0,    "--help",               NULL, "Display this help" },
@@ -226,8 +226,6 @@ typedef struct {
 
 static const UNSUPPORTEDOPT 
 unsupportedOptTable[] = {
-    { 'a',  NULL,      "use --stack-auto instead." },
-    { 'g',  NULL,      "use --generic instead" },
     { 'X',  NULL,      "use --xstack-loc instead" },
     { 'x',  NULL,      "use --xstack instead" },
     { 'i',  NULL,      "use --idata-loc instead" },
@@ -387,16 +385,18 @@ printVersionInfo ()
            " (" __DATE__ ")"
 #ifdef __CYGWIN__
           " (CYGWIN)\n"
+#elif defined __MINGW32__
+          " (MINGW32) \n"
 #else
-#ifdef __DJGPP__
+#  ifdef __DJGPP__
           " (DJGPP) \n"
-#else
-#if defined(_MSC_VER)
+#  else
+#    if defined(_MSC_VER)
           " (WIN32) \n"
-#else
+#    else
           " (UNIX) \n"
-#endif
-#endif
+#    endif
+#  endif
 #endif
 
           ,VersionString
@@ -492,7 +492,6 @@ setDefaultOptions ()
   options.data_loc = 0;                /* JCF: By default let the linker locate data */
   options.xdata_loc = 0;
   options.idata_loc = 0x80;
-  options.genericPtr = 1;      /* default on */
   options.nopeep = 0;
   options.model = port->general.default_model;
   options.nostdlib = 0;
@@ -549,7 +548,8 @@ processFile (char *s)
        }
 
       /* the only source file */
-      if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
+      fullSrcFileName = s;
+      if (!(srcFile = fopen (fullSrcFileName, "r")))
        {
          werror (E_FILE_OPEN_ERR, s);
          exit (1);
@@ -614,24 +614,6 @@ processFile (char *s)
 
 }
 
-static void
-_processC1Arg (char *s)
-{
-  if (fullSrcFileName)
-    {
-      if (options.out_name)
-       {
-         werror (W_TOO_MANY_SRC, s);
-         return;
-       }
-      options.out_name = Safe_strdup (s);
-    }
-  else
-    {
-      processFile (s);
-    }
-}
-
 static void
 _setModel (int model, const char *sz)
 {
@@ -925,6 +907,19 @@ parseCmdLine (int argc, char **argv)
                 continue;
            }
 
+         if (strcmp (argv[i], OPTION_XRAM_SIZE) == 0)
+           {
+                options.xram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
+                options.xram_size_set = TRUE;
+                continue;
+           }
+
+         if (strcmp (argv[i], OPTION_CODE_SIZE) == 0)
+           {
+                options.code_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
+                continue;
+           }
+
          if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
            {
                 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
@@ -1118,13 +1113,13 @@ parseCmdLine (int argc, char **argv)
                if (argv[i][2] == ' ' || argv[i][2] == '\0')
                  {
                    i++;
-                    if (i >= argc) 
+                    if (i >= argc)
                       {
                           /* No argument. */
                           werror(E_ARGUMENT_MISSING, argv[i-1]);
                           break;
                       }
-                    else 
+                    else
                       {
                           rest = argv[i];
                       }
@@ -1150,10 +1145,7 @@ parseCmdLine (int argc, char **argv)
       if (!port->parseOption (&argc, argv, &i))
        {
          /* no option must be a filename */
-         if (options.c1mode)
-           _processC1Arg (argv[i]);
-         else
-           processFile (argv[i]);
+          processFile (argv[i]);
        }
     }
 
@@ -1219,7 +1211,7 @@ linkEdit (char **envp)
 {
   FILE *lnkfile;
   char *segName, *c;
-  int i;
+  int i, system_ret;
 
   /* first we need to create the <filename>.lnk file */
   sprintf (scratchFileName, "%s.lnk", dstFileName);
@@ -1236,6 +1228,14 @@ linkEdit (char **envp)
   if (options.iram_size)
     fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
 
+  /* if xram size specified */
+  if (options.xram_size_set)
+    fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
+
+  /* if code size specified */
+  if (options.code_size)
+    fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
+
   if (options.debug)
     fprintf (lnkfile, "-z\n");
 
@@ -1265,8 +1265,8 @@ linkEdit (char **envp)
   WRITE_SEG_LOC (BIT_NAME, 0);
 
   /* JCF: stack start */
-  if(options.stack_loc) {
-       WRITE_SEG_LOC ("SSEG", options.stack_loc & 0xff);
+  if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
+       WRITE_SEG_LOC ("SSEG", options.stack_loc);
   }
 
   /* add the extra linker options */
@@ -1341,10 +1341,33 @@ linkEdit (char **envp)
   if (options.verbose)
     printf ("sdcc: Calling linker...\n");
 
+  /* build linker output filename */
+
+  /* -o option overrides default name? */
+  if (fullDstFileName)
+    {
+      strcpy (scratchFileName, fullDstFileName);
+    }
+  else
+    {
+      /* the linked file gets the name of the first modul */
+      if (fullSrcFileName)
+        {
+          strcpy (scratchFileName, dstFileName);
+        }
+      else
+        {
+          strcpy (scratchFileName, relFiles[0]);
+          /* strip ".rel" extension */
+          *strrchr (scratchFileName, '.') = '\0';
+        }
+      strcat (scratchFileName, options.out_fmt ? ".S19" : ".ihx");
+    }
+
   if (port->linker.cmd)
     {
       char buffer2[PATH_MAX];
-      buildCmdLine (buffer2, port->linker.cmd, dstFileName, NULL, NULL, NULL);
+      buildCmdLine (buffer2, port->linker.cmd, dstFileName, scratchFileName, NULL, NULL);
       buildCmdLine2 (buffer, buffer2);
     }
   else
@@ -1352,26 +1375,48 @@ linkEdit (char **envp)
       buildCmdLine2 (buffer, port->linker.mcmd);
     }
 
-  if (my_system (buffer))
-    {
-      exit (1);
-    }
+  system_ret = my_system (buffer);
+  /* TODO: most linker don't have a -o parameter */
   /* -o option overrides default name? */
   if (fullDstFileName)
     {
+      char *p, *q;
       /* the linked file gets the name of the first modul */
       if (fullSrcFileName)
-    {
+        {
           strcpy (scratchFileName, dstFileName);
+          p = strlen (scratchFileName) + scratchFileName;
         }
       else
         {
           strcpy (scratchFileName, relFiles[0]);
-          /* strip ".rel" extension */
-          *strrchr (scratchFileName, '.') = '\0';
+          /* strip "rel" extension */
+          p = strrchr (scratchFileName, '.') + 1;
         }
-      strcat (scratchFileName, options.out_fmt ? ".S19" : ".ihx");
+      strcpy (p, options.out_fmt ? "S19" : "ihx");
       rename (scratchFileName, fullDstFileName);
+
+      q = strrchr (fullDstFileName, '.');
+      if (q)
+        {
+          /* point after the '.' of the extension */
+          q++;
+        }
+      else
+        {
+          /* no extension: append new extensions */
+          q = strlen (fullDstFileName) + fullDstFileName;
+        }
+      strcpy (p, "map");
+      strcpy (q, "map");
+      rename (scratchFileName, fullDstFileName);
+      strcpy (p, "mem");
+      strcpy (q, "mem");
+      rename (scratchFileName, fullDstFileName);
+    }
+  if (system_ret)
+    {
+      exit (1);
     }
 }
 
@@ -1381,11 +1426,22 @@ linkEdit (char **envp)
 static void
 assemble (char **envp)
 {
+    /* build assembler output filename */
+
+    /* -o option overrides default name? */
+    if (options.cc_only && fullDstFileName) {
+        strcpy (scratchFileName, fullDstFileName);
+    } else {
+        /* the assembled file gets the name of the first modul */
+        strcpy (scratchFileName, dstFileName);
+        strcat (scratchFileName, port->linker.rel_ext);
+    }
+
     if (port->assembler.do_assemble) {
        port->assembler.do_assemble(asmOptions);
        return ;
     } else if (port->assembler.cmd) {
-        buildCmdLine (buffer, port->assembler.cmd, dstFileName, NULL,
+        buildCmdLine (buffer, port->assembler.cmd, dstFileName, scratchFileName,
                      options.debug ? port->assembler.debug_opts : port->assembler.plain_opts,
                      asmOptions);
     } else {
@@ -1398,10 +1454,11 @@ assemble (char **envp)
        */
        exit (1);
     }
+    /* TODO: most assembler don't have a -o parameter */
     /* -o option overrides default name? */
     if (options.cc_only && fullDstFileName) {
         strcpy (scratchFileName, dstFileName);
-        strcat (scratchFileName, ".rel");
+        strcat (scratchFileName, port->linker.rel_ext);
         rename (scratchFileName, fullDstFileName);
     }
 }
@@ -1468,8 +1525,13 @@ preProcess (char **envp)
       }
 
       setMainValue ("cppextraopts", join(preArgv));
-      
-      if (!preProcOnly)
+
+      if (preProcOnly)
+        {
+          if (fullDstFileName)
+              preOutName = Safe_strdup (fullDstFileName);
+        }
+      else
           preOutName = Safe_strdup (tempfilename ());
 
       /* Have to set cppoutfilename to something, even if just pre-processing. */
@@ -1655,20 +1717,20 @@ initValues (void)
   if (options.cc_only && fullDstFileName)
     /* compile + assemble and -o given: -o specifies name of object file */
     {
-      setMainValue ("z80objdstfilename", fullDstFileName);
+      setMainValue ("objdstfilename", fullDstFileName);
     }
   else
     {
-      setMainValue ("z80objdstfilename", "{z80stdobjdstfilename}");
+      setMainValue ("objdstfilename", "{stdobjdstfilename}");
     }
   if (fullDstFileName)
     /* if we're linking, -o gives the final file name */
     {
-      setMainValue ("z80linkdstfilename", fullDstFileName);
+      setMainValue ("linkdstfilename", fullDstFileName);
     }
   else
     {
-      setMainValue ("z80linkdstfilename", "{z80stdlinkdstfilename}");
+      setMainValue ("linkdstfilename", "{stdlinkdstfilename}");
     }
 
 }
@@ -1730,7 +1792,7 @@ main (int argc, char **argv, char **envp)
 
   /* if no input then printUsage & exit */
   if ((!options.c1mode && !fullSrcFileName && !nrelFiles) ||
-      (options.c1mode && !fullSrcFileName && !options.out_name))
+      (options.c1mode && !fullSrcFileName))
     {
       printUsage ();
       exit (0);
@@ -1739,12 +1801,15 @@ main (int argc, char **argv, char **envp)
   initValues ();
   _discoverPaths (argv[0]);
 
+  /* initMem() is expensive, but
+     initMem() must called before port->finaliseOptions ().
+     And the z80 port needs port->finaliseOptions(),
+     even if we're only linking. */
+  initMem ();
+  port->finaliseOptions ();
+
   if (fullSrcFileName)
     {
-
-      initMem ();
-
-      port->finaliseOptions ();
       preProcess (envp);
 
       initSymt ();