* Makefile.in, configure.in, configure,
[fw/sdcc] / src / SDCCmain.c
index 8cb6954b63add725be2b44154093529f8767fa5c..12909d3b01abdb824a3eb09c0f60bd690b8c5223 100644 (file)
@@ -32,6 +32,7 @@
 #include "common.h"
 #include <ctype.h>
 #include "newalloc.h"
+#include "dbuf_string.h"
 #include "SDCCerr.h"
 #include "BuildCmd.h"
 #include "MySystem.h"
@@ -87,20 +88,19 @@ set *libDirsSet = NULL;         /* list of lib search directories */
 int ds390_jammed = 0;
 #endif
 
-/* Globally accessible scratch buffer for file names. */
+/* Globally accessible scratch buffer for file names.
+   TODO: replace them with local buffers */
 char scratchFileName[PATH_MAX];
 char buffer[PATH_MAX * 2];
 
 #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"
 #define OPTION_LARGE_MODEL      "--model-large"
 #define OPTION_MEDIUM_MODEL     "--model-medium"
 #define OPTION_SMALL_MODEL      "--model-small"
-#define OPTION_FLAT24_MODEL     "--model-flat24"
 #define OPTION_DUMP_ALL         "--dumpall"
 #define OPTION_PEEP_FILE        "--peep-file"
 #define OPTION_LIB_PATH         "--lib-path"
@@ -111,7 +111,6 @@ char buffer[PATH_MAX * 2];
 #define OPTION_IDATA_LOC        "--idata-loc"
 #define OPTION_XRAM_LOC         "--xram-loc"
 #define OPTION_CODE_LOC         "--code-loc"
-#define OPTION_STACK_SIZE       "--stack-size"
 #define OPTION_IRAM_SIZE        "--iram-size"
 #define OPTION_XRAM_SIZE        "--xram-size"
 #define OPTION_CODE_SIZE        "--code-size"
@@ -121,18 +120,17 @@ char buffer[PATH_MAX * 2];
 #define OPTION_NO_LOOP_IND      "--noinduction"
 #define OPTION_LESS_PEDANTIC    "--less-pedantic"
 #define OPTION_DISABLE_WARNING  "--disable-warning"
+#define OPTION_WERROR           "--Werror"
 #define OPTION_NO_GCSE          "--nogcse"
 #define OPTION_SHORT_IS_8BITS   "--short-is-8bits"
-#define OPTION_TINI_LIBID       "--tini-libid"
 #define OPTION_NO_XINIT_OPT     "--no-xinit-opt"
 #define OPTION_NO_CCODE_IN_ASM  "--no-c-code-in-asm"
 #define OPTION_ICODE_IN_ASM     "--i-code-in-asm"
 #define OPTION_PRINT_SEARCH_DIRS "--print-search-dirs"
 #define OPTION_MSVC_ERROR_STYLE "--vc"
 #define OPTION_USE_STDOUT       "--use-stdout"
-#define OPTION_PACK_IRAM        "--pack-iram"
-#define OPTION_NO_PACK_IRAM     "--no-pack-iram"
 #define OPTION_NO_PEEP_COMMENTS "--no-peep-comments"
+#define OPTION_VERBOSE_ASM      "--fverbose-asm"
 #define OPTION_OPT_CODE_SPEED   "--opt-code-speed"
 #define OPTION_OPT_CODE_SIZE    "--opt-code-size"
 #define OPTION_STD_C89          "--std-c89"
@@ -141,6 +139,8 @@ char buffer[PATH_MAX * 2];
 #define OPTION_STD_SDCC99       "--std-sdcc99"
 #define OPTION_CODE_SEG         "--codeseg"
 #define OPTION_CONST_SEG        "--constseg"
+#define OPTION_DOLLARS_IN_IDENT "--fdollars-in-identifiers"
+#define OPTION_UNSIGNED_CHAR    "--funsigned-char"
 
 static const OPTION
 optionsTable[] = {
@@ -154,7 +154,6 @@ optionsTable[] = {
     { 'I',  NULL,                   NULL, "Add to the include (*.h) path, as in -Ipath" },
     { 'A',  NULL,                   NULL, NULL },
     { 'U',  NULL,                   NULL, NULL },
-    { 'C',  NULL,                   NULL, "Preprocessor option" },
     { 'M',  NULL,                   NULL, "Preprocessor option" },
     { 'W',  NULL,                   NULL, "Pass through options to the pre-processor (p), assembler (a) or linker (l)" },
     { 'S',  NULL,                   &noAssemble, "Compile only; do not assemble or link" },
@@ -169,12 +168,15 @@ optionsTable[] = {
     { 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" },
     { 0,    OPTION_DISABLE_WARNING, NULL, "<nnnn> Disable specific warning" },
+    { 0,    OPTION_WERROR,          NULL, "Treat the warnings as errors" },
     { 0,    "--debug",              &options.debug, "Enable debugging symbol output" },
     { 0,    "--cyclomatic",         &options.cyclomatic, "Display complexity of compiled functions" },
     { 0,    OPTION_STD_C89,         NULL, "Use C89 standard only" },
     { 0,    OPTION_STD_SDCC89,      NULL, "Use C89 standard with SDCC extensions (default)" },
     { 0,    OPTION_STD_C99,         NULL, "Use C99 standard only (incomplete)" },
     { 0,    OPTION_STD_SDCC99,      NULL, "Use C99 standard with SDCC extensions (incomplete)" },
+    { 0,    OPTION_DOLLARS_IN_IDENT, &options.dollars_in_ident, "Permit '$' as an identifier character" },
+    { 0,    OPTION_UNSIGNED_CHAR,   &options.unsigned_char, "Make \"char\" unsigned by default" },
 
     { 0,    NULL,                   NULL, "Code generation options"},
     { 'm',  NULL,                   NULL, "Set the port to use e.g. -mz80." },
@@ -182,40 +184,21 @@ optionsTable[] = {
     { 0,    OPTION_LARGE_MODEL,     NULL, "external data space is used" },
     { 0,    OPTION_MEDIUM_MODEL,    NULL, "external paged data space is used" },
     { 0,    OPTION_SMALL_MODEL,     NULL, "internal data space is used (default)" },
-#if !OPT_DISABLE_DS390
-    { 0,    OPTION_FLAT24_MODEL,    NULL, "use the flat24 model for the ds390 (default)" },
-    { 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)" },
-#endif
     { 0,    "--stack-auto",         &options.stackAuto, "Stack automatic variables" },
     { 0,    "--xstack",             &options.useXstack, "Use external stack" },
-    { 0,    "--int-long-reent",     &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
-    { 0,    "--float-reent",        &options.float_rent, "Use reenterant calls on the float support functions" },
+    { 0,    "--int-long-reent",     &options.intlong_rent, "Use reentrant calls on the int and long support functions" },
+    { 0,    "--float-reent",        &options.float_rent, "Use reentrant calls on the float support functions" },
     { 0,    "--main-return",        &options.mainreturn, "Issue a return after main()" },
     { 0,    "--xram-movc",          &options.xram_movc, "Use movc instead of movx to read xram (xdata)" },
-    { 0,    OPTION_CALLEE_SAVES,    NULL, "<func[,func,...]> Cause the called function to save registers insted of the caller" },
+    { 0,    OPTION_CALLEE_SAVES,    &options.calleeSavesSet, "<func[,func,...]> Cause the called function to save registers insted of the caller", CLAT_SET },
     { 0,    "--profile",            &options.profile, "On supported ports, generate extra profiling information" },
     { 0,    "--fommit-frame-pointer", &options.ommitFramePtr, "Leave out the frame pointer." },
     { 0,    "--all-callee-saves",   &options.all_callee_saves, "callee will always save registers used" },
-#if !OPT_DISABLE_DS390
-    { 0,    "--use-accelerator",    &options.useAccelerator,"generate code for  DS390 Arithmetic Accelerator"},
-#endif
     { 0,    "--stack-probe",        &options.stack_probe,"insert call to function __stack_probe at each function prologue"},
-#if !OPT_DISABLE_TININative
-    { 0,    "--tini-libid",         NULL,"<nnnn> LibraryID used in -mTININative"},
-#endif
-#if !OPT_DISABLE_DS390
-    { 0,    "--protect-sp-update",  &options.protect_sp_update,"DS390 - will disable interrupts during ESP:SP updates"},
-#endif
-#if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51
-    { 0,    "--parms-in-bank1",     &options.parms_in_bank1,"MCS51/DS390 - use Bank1 for parameter passing"},
-#endif
     { 0,    OPTION_NO_XINIT_OPT,    &options.noXinitOpt, "don't memcpy initialized xram from code"},
     { 0,    OPTION_NO_CCODE_IN_ASM, &options.noCcodeInAsm, "don't include c-code as comments in the asm file"},
     { 0,    OPTION_NO_PEEP_COMMENTS, &options.noPeepComments, "don't include peephole optimizer comments"},
-#if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
-    { 0,    "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
-#endif
+    { 0,    OPTION_VERBOSE_ASM,     &options.verboseAsm, "include code generator comments"},
     { 0,    OPTION_SHORT_IS_8BITS,  NULL, "Make short 8 bits (for old times sake)" },
     { 0,    OPTION_CODE_SEG,        NULL, "<name> use this name for the code segment" },
     { 0,    OPTION_CONST_SEG,       NULL, "<name> use this name for the const segment" },
@@ -231,7 +214,7 @@ optionsTable[] = {
     { 0,    "--no-peep",            &options.nopeep, "Disable the peephole assembly file optimisation" },
     { 0,    "--no-reg-params",      &options.noRegParams, "On some ports, disable passing some parameters in registers" },
     { 0,    "--peep-asm",           &options.asmpeep, "Enable peephole optimization on inline assembly" },
-    { 0,    OPTION_PEEP_FILE,       NULL, "<file> use this extra peephole file" },
+    { 0,    OPTION_PEEP_FILE,       &options.peep_file, "<file> use this extra peephole file", CLAT_STRING },
     { 0,    OPTION_OPT_CODE_SPEED,  NULL, "Optimize for code speed rather than size" },
     { 0,    OPTION_OPT_CODE_SIZE,   NULL, "Optimize for code size rather than speed" },
 
@@ -250,25 +233,18 @@ optionsTable[] = {
     { 0,    NULL,                   NULL, "Linker options" },
     { 'l',  NULL,                   NULL, "Include the given library in the link" },
     { 'L',  NULL,                   NULL, "Add the next field to the library search path" },
-    { 0,    OPTION_LIB_PATH,        NULL, "<path> use this path to search for libraries" },
+    { 0,    OPTION_LIB_PATH,        &libPathsSet, "<path> use this path to search for libraries", CLAT_ADD_SET },
     { 0,    OPTION_OUT_FMT_IHX,     NULL, "Output in Intel hex format" },
     { 0,    OPTION_OUT_FMT_S19,     NULL, "Output in S19 hex format" },
-    { 0,    OPTION_XRAM_LOC,        NULL, "<nnnn> External Ram start location" },
+    { 0,    OPTION_XRAM_LOC,        &options.xdata_loc, "<nnnn> External Ram start location", CLAT_INTEGER },
     { 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 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_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
+    { 0,    OPTION_IRAM_SIZE,       &options.iram_size, "<nnnn> Internal Ram size", CLAT_INTEGER },
+    { 0,    OPTION_XSTACK_LOC,      &options.xstack_loc, "<nnnn> External Stack start location", CLAT_INTEGER },
+    { 0,    OPTION_CODE_LOC,        &options.code_loc, "<nnnn> Code Segment Location", CLAT_INTEGER },
+    { 0,    OPTION_CODE_SIZE,       &options.code_size, "<nnnn> Code Segment size", CLAT_INTEGER },
+    { 0,    OPTION_STACK_LOC,       &options.stack_loc, "<nnnn> Stack pointer initial value", CLAT_INTEGER },
+    { 0,    OPTION_DATA_LOC,        &options.data_loc, "<nnnn> Direct data start location", CLAT_INTEGER },
+    { 0,    OPTION_IDATA_LOC,       &options.idata_loc, NULL, CLAT_INTEGER },
 
     /* End of options */
     { 0,    NULL }
@@ -307,7 +283,7 @@ static const char *_baseValues[] = {
   NULL
 };
 
-static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
+static const char *_preCmd = "{cpp} -nostdinc -Wall {cppstd}{cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
 
 PORT *port;
 
@@ -368,7 +344,7 @@ _setPort (const char *name)
     }
   /* Error - didnt find */
   werror (E_UNKNOWN_TARGET, name);
-  exit (1);
+  exit (EXIT_FAILURE);
 }
 
 /* Override the default processor with the one specified
@@ -450,21 +426,8 @@ printVersionInfo (FILE *stream)
 #ifdef SDCC_SUB_VERSION_STR
            "/" SDCC_SUB_VERSION_STR
 #endif
-           " #%s (" __DATE__ ")"
-#ifdef __CYGWIN__
-           " (CYGWIN)\n"
-#elif defined __MINGW32__
-           " (MINGW32)\n"
-#elif defined __DJGPP__
-           " (DJGPP)\n"
-#elif defined(_MSC_VER)
-           " (MSVC)\n"
-#elif defined(__BORLANDC__)
-           " (BORLANDC)\n"
-#else
-           " (UNIX) \n"
-#endif
-    , getBuildNumber() );
+           " #%s (%s) (%s)\n",
+           getBuildNumber(), getBuildDate(), getBuildEnvironment() );
 }
 
 static void
@@ -539,20 +502,21 @@ setParseWithComma (set **dest, const char *src)
     --end;
   ++end;
 
-  dbuf_init(&dbuf, 16);
-
   p = src;
   while (src < end)
     {
+      dbuf_init (&dbuf, 16);
+
       while (p < end && ',' != *p)
         ++p;
-      dbuf_append(&dbuf, src, p - src);
-      addSet(dest, Safe_strdup(dbuf_c_str(&dbuf)));
-      dbuf_set_size(&dbuf, 0);
+      dbuf_append (&dbuf, src, p - src);
+
+      /* null terminate the buffer */
+      dbuf_c_str (&dbuf);
+      addSet(dest, dbuf_detach (&dbuf));
+
       src = ++p;
     }
-
-  dbuf_destroy(&dbuf);
 }
 
 /*-----------------------------------------------------------------*/
@@ -576,8 +540,8 @@ setDefaultOptions (void)
   options.shortis8bits = 0;
   options.std_sdcc = 1;           /* enable SDCC language extensions */
   options.std_c99 = 0;            /* default to C89 until more C99 support */
-  options.code_seg = CODE_NAME;   /* default to CSEG for generated code */
-  options.const_seg = CONST_NAME; /* default to CONST for generated code */
+  options.code_seg = CODE_NAME ? Safe_strdup(CODE_NAME) : NULL; /* default to CSEG for generated code */
+  options.const_seg = CONST_NAME ? Safe_strdup(CONST_NAME) : NULL; /* default to CONST for generated code */
 
   options.stack10bit=0;
 
@@ -601,29 +565,42 @@ setDefaultOptions (void)
 static void
 processFile (char *s)
 {
-  char *fext = NULL;
+  const char *extp;
+  struct dbuf_s ext;
+  struct dbuf_s path;
 
-  /* get the file extension */
-  fext = s + strlen (s);
-  while ((fext != s) && *fext != '.')
-    fext--;
+  dbuf_init (&ext, 128);
+  dbuf_init (&path, 128);
 
-  /* now if no '.' then we don't know what the file type is
+  /* get the file extension.
+     If no '.' then we don't know what the file type is
      so give a warning and return */
-  if (fext == s)
+  if (!dbuf_splitFile (s, &path, &ext))
     {
       werror (W_UNKNOWN_FEXT, s);
+
+      dbuf_destroy (&ext);
+      dbuf_destroy (&path);
+
       return;
     }
 
   /* otherwise depending on the file type */
-  if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0)
+  extp = dbuf_c_str (&ext);
+  if (STRCASECMP (extp, ".c") == 0)
     {
+      char *p;
+
+      dbuf_destroy (&ext);
+
       /* source file name : not if we already have a
          source file */
       if (fullSrcFileName)
         {
           werror (W_TOO_MANY_SRC, s);
+
+          dbuf_destroy (&path);
+
           return;
         }
 
@@ -632,71 +609,54 @@ processFile (char *s)
       if (!(srcFile = fopen (fullSrcFileName, "r")))
         {
           werror (E_FILE_OPEN_ERR, s);
-          exit (1);
-        }
-
-      /* copy the file name into the buffer */
-      strncpyz (buffer, s, sizeof(buffer));
 
-      /* get rid of the "."-extension */
+          dbuf_destroy (&path);
 
-      /* is there a dot at all? */
-      if (strrchr (buffer, '.') &&
-          /* is the dot in the filename, not in the path? */
-          (strrchr (buffer, DIR_SEPARATOR_CHAR) < strrchr (buffer, '.')))
-        {
-          *strrchr (buffer, '.') = '\0';
+          exit (EXIT_FAILURE);
         }
 
       /* get rid of any path information
          for the module name; */
-      fext = buffer + strlen (buffer);
-#if NATIVE_WIN32
-      /* do this by going backwards till we
-         get '\' or ':' or start of buffer */
-      while (fext != buffer &&
-             *(fext - 1) != DIR_SEPARATOR_CHAR &&
-             *(fext - 1) != ':')
-        {
-          fext--;
-        }
-#else
-      /* do this by going backwards till we
-         get '/' or start of buffer */
-      while (fext != buffer &&
-             *(fext - 1) != DIR_SEPARATOR_CHAR)
-        {
-          fext--;
-        }
-#endif
-      moduleNameBase = Safe_strdup ( fext );
-      moduleName = Safe_strdup ( fext );
+      dbuf_init (&ext, 128);
+
+      dbuf_splitPath (dbuf_c_str (&path), NULL, &ext);
+      dbuf_destroy (&path);
 
-      for (fext = moduleName; *fext; fext++)
-        if (!isalnum ((unsigned char)*fext))
-          *fext = '_';
+      moduleNameBase = Safe_strdup (dbuf_c_str (&ext));
+      moduleName = dbuf_detach (&ext);
+
+      for (p = moduleName; *p; ++p)
+        if (!isalnum ((unsigned char)*p))
+          *p = '_';
       return;
     }
 
   /* if the extention is type .rel or .r or .REL or .R
      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)
+  if (STRCASECMP (extp, ".r") == 0 || STRCASECMP (extp, ".rel") == 0 ||
+      strcmp (extp, port->linker.rel_ext) == 0)
     {
-      addSet(&relFilesSet, Safe_strdup(s));
+      dbuf_destroy (&ext);
+      dbuf_destroy (&path);
+
+      addSet (&relFilesSet, Safe_strdup (s));
       return;
     }
 
   /* if .lib or .LIB */
-  if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
+  if (STRCASECMP (extp, ".lib") == 0)
     {
-      addSet(&libFilesSet, Safe_strdup(s));
+      dbuf_destroy (&ext);
+      dbuf_destroy (&path);
+
+      addSet (&libFilesSet, Safe_strdup (s));
       return;
     }
 
-  werror (W_UNKNOWN_FEXT, s);
+  dbuf_destroy (&ext);
+  dbuf_destroy (&path);
 
+  werror (W_UNKNOWN_FEXT, s);
 }
 
 static void
@@ -725,7 +685,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(EXIT_FAILURE);
+          exit (EXIT_FAILURE);
         }
       else
         {
@@ -740,7 +700,18 @@ getStringArg(const char *szStart, char **argv, int *pi, int argc)
 int
 getIntArg(const char *szStart, char **argv, int *pi, int argc)
 {
-  return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
+  char *p;
+  int val;
+  char *str = getStringArg(szStart, argv, pi, argc);
+
+  val = strtol(str, &p, 0);
+  if (p == str || *p != '\0')
+    {
+      werror (E_BAD_INT_ARGUMENT, szStart);
+      /* Die here rather than checking for errors later. */
+      exit (EXIT_FAILURE);
+    }
+  return val;
 }
 
 static void
@@ -755,117 +726,158 @@ verifyShortOption(const char *opt)
 static bool
 tryHandleUnsupportedOpt(char **argv, int *pi)
 {
-    if (argv[*pi][0] == '-')
-        {
-            const char *longOpt = "";
-            char shortOpt = -1;
-            int i;
+  if (argv[*pi][0] == '-')
+    {
+      const char *longOpt = "";
+      char shortOpt = -1;
+      int i;
 
-            if (argv[*pi][1] == '-')
-                {
-                    /* Long option. */
-                    longOpt = argv[*pi];
-                }
-            else
-                {
-                    shortOpt = argv[*pi][1];
-                }
-            for (i = 0; i < LENGTH(unsupportedOptTable); i++)
-                {
-                    if (unsupportedOptTable[i].shortOpt == shortOpt ||
-                        (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
-                        /* Found an unsupported opt. */
-                        char buffer[100];
-                        SNPRINTF(buffer, sizeof(buffer),
-                                 "%s%c%c",
-                                 longOpt ? longOpt : "",
-                                 shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
-                        werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
-                        return 1;
-                    }
-                }
-            /* Didn't find in the table */
-            return 0;
+      if (argv[*pi][1] == '-')
+        {
+          /* Long option. */
+          longOpt = argv[*pi];
+        }
+      else
+        {
+          shortOpt = argv[*pi][1];
         }
-    else
+      for (i = 0; i < LENGTH(unsupportedOptTable); i++)
         {
-            /* Not an option, so can't be unsupported :) */
-            return 0;
+          if (unsupportedOptTable[i].shortOpt == shortOpt ||
+              (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt)))
+            {
+              /* Found an unsupported opt. */
+              char buffer[100];
+              SNPRINTF(buffer, sizeof(buffer),
+                "%s%c%c",
+                longOpt ? longOpt : "",
+                shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
+              werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
+              return 1;
+            }
+        }
+      /* Didn't find in the table */
+      return 0;
+    }
+  else
+    {
+      /* Not an option, so can't be unsupported :) */
+      return 0;
     }
 }
 
 static bool
-scanOptionsTable(const OPTION *optionsTable, char shortOpt, const char *longOpt, char **argv, int *pi)
+scanOptionsTable(const OPTION *optionsTable, char shortOpt, const char *longOpt, char **argv, int *pi, int argc)
 {
   int i;
+
   for (i = 0;
        optionsTable[i].shortOpt != 0 || optionsTable[i].longOpt != NULL
        || optionsTable[i].help != NULL;
        i++)
     {
-      if (optionsTable[i].shortOpt == shortOpt ||
-          (longOpt && optionsTable[i].longOpt &&
-           strcmp(optionsTable[i].longOpt, longOpt) == 0))
+      if (optionsTable[i].shortOpt == shortOpt)
         {
-
-          /* If it is a flag then we can handle it here */
           if (optionsTable[i].pparameter != NULL)
             {
-              if (optionsTable[i].shortOpt == shortOpt)
+              verifyShortOption(argv[*pi]);
+
+              (*(int *)optionsTable[i].pparameter)++;
+
+              return TRUE;
+            }
+        }
+      else
+        {
+          size_t len = optionsTable[i].longOpt ? strlen (optionsTable[i].longOpt) : 0;
+
+          if (longOpt &&
+            (optionsTable[i].arg_type != CLAT_BOOLEAN ||
+            (optionsTable[i].arg_type == CLAT_BOOLEAN && len == strlen (longOpt) && optionsTable[i].longOpt)) &&
+            strncmp (optionsTable[i].longOpt, longOpt, len) == 0)
+            {
+              /* If it is a flag then we can handle it here */
+              if (optionsTable[i].pparameter != NULL)
                 {
-                  verifyShortOption(argv[*pi]);
+                  switch (optionsTable[i].arg_type)
+                    {
+                    case CLAT_BOOLEAN:
+                      (*(int *)optionsTable[i].pparameter)++;
+                      break;
+
+                    case CLAT_INTEGER:
+                      *(int *)optionsTable[i].pparameter = getIntArg (optionsTable[i].longOpt, argv, pi, argc);
+                      break;
+
+                    case CLAT_STRING:
+                      if (*(char **)optionsTable[i].pparameter)
+                        Safe_free(*(char **)optionsTable[i].pparameter);
+                      *(char **)optionsTable[i].pparameter = Safe_strdup (getStringArg (optionsTable[i].longOpt, argv, pi, argc));
+                      break;
+
+                    case CLAT_SET:
+                      if (*(set **)optionsTable[i].pparameter)
+                        {
+                          deleteSet ((set **)optionsTable[i].pparameter);
+                        }
+                      setParseWithComma ((set **)optionsTable[i].pparameter, getStringArg (optionsTable[i].longOpt, argv, pi, argc));
+                      break;
+
+                    case CLAT_ADD_SET:
+                      addSet((set **)optionsTable[i].pparameter, Safe_strdup (getStringArg (optionsTable[i].longOpt, argv, pi, argc)));
+                      break;
+                    }
+                  return TRUE;
+                }
+              else
+                {
+                  /* Not a flag.  Handled manually later. */
+                  return FALSE;
                 }
-
-              (*optionsTable[i].pparameter)++;
-              return 1;
             }
-          else {
-            /* Not a flag.  Handled manually later. */
-            return 0;
-          }
         }
     }
   /* Didn't find in the table */
-  return 0;
+  return FALSE;
 }
 
 static bool
-tryHandleSimpleOpt(char **argv, int *pi)
+tryHandleSimpleOpt(char **argv, int *pi, int argc)
 {
-    if (argv[*pi][0] == '-')
-        {
-            const char *longOpt = "";
-            char shortOpt = -1;
+  if (argv[*pi][0] == '-')
+    {
+      const char *longOpt = "";
+      char shortOpt = -1;
 
-            if (argv[*pi][1] == '-')
-                {
-                    /* Long option. */
-                    longOpt = argv[*pi];
-                }
-            else
-                {
-                    shortOpt = argv[*pi][1];
-                }
+      if (argv[*pi][1] == '-')
+        {
+          /* Long option. */
+          longOpt = argv[*pi];
+        }
+      else
+        {
+          shortOpt = argv[*pi][1];
+        }
 
-            if (scanOptionsTable(optionsTable, shortOpt, longOpt, argv, pi))
-              {
-                return 1;
-              }
-            else if (port && port->poptions &&
-                     scanOptionsTable(port->poptions, shortOpt, longOpt, argv, pi))
-              {
-                return 1;
-              }
-            else
-              {
-                return 0;
-              }
+      if (scanOptionsTable(optionsTable, shortOpt, longOpt, argv, pi, argc))
+        {
+          return TRUE;
         }
-    else
+      else if (port && port->poptions &&
+               scanOptionsTable(port->poptions, shortOpt, longOpt, argv, pi, argc))
         {
-            /* Not an option, so can't be handled. */
-            return 0;
+          return TRUE;
         }
+      else
+        {
+          return FALSE;
+        }
+    }
+  else
+    {
+      /* Not an option, so can't be handled. */
+      return FALSE;
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -882,12 +894,18 @@ parseCmdLine (int argc, char **argv)
       if (i >= argc)
         break;
 
+      /* check port specific options before general ones */
+      if (port->parseOption (&argc, argv, &i) == TRUE)
+        {
+          continue;
+        }
+
       if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
         {
           continue;
         }
 
-      if (tryHandleSimpleOpt(argv, &i) == TRUE)
+      if (tryHandleSimpleOpt(argv, &i, argc) == TRUE)
         {
           continue;
         }
@@ -910,12 +928,6 @@ parseCmdLine (int argc, char **argv)
               exit (EXIT_SUCCESS);
             }
 
-          if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
-            {
-              options.stack10bit = 0;
-              continue;
-            }
-
           if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
             {
               options.out_fmt = 0;
@@ -946,12 +958,6 @@ parseCmdLine (int argc, char **argv)
               continue;
             }
 
-          if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
-            {
-              _setModel (MODEL_FLAT24, argv[i]);
-              continue;
-            }
-
           if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
             {
               options.dump_rassgn =
@@ -964,18 +970,6 @@ parseCmdLine (int argc, char **argv)
               continue;
             }
 
-          if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
-            {
-              options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
-            {
-              addSet(&libPathsSet, Safe_strdup(getStringArg(OPTION_LIB_PATH, argv, &i, argc)));
-              continue;
-            }
-
           if (strcmp (argv[i], OPTION_VERSION) == 0)
             {
               printVersionInfo (stdout);
@@ -983,42 +977,6 @@ parseCmdLine (int argc, char **argv)
               continue;
             }
 
-          if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
-            {
-              setParseWithComma(&options.calleeSavesSet, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
-            {
-              options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
-            {
-              options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_STACK_SIZE) == 0)
-            {
-              options.stack_size = getIntArg(OPTION_STACK_SIZE, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
-            {
-              options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
-            {
-              options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
-              continue;
-            }
-
           if (strcmp (argv[i], OPTION_XRAM_SIZE) == 0)
             {
               options.xram_size = getIntArg(OPTION_XRAM_SIZE, argv, &i, argc);
@@ -1026,31 +984,7 @@ parseCmdLine (int argc, char **argv)
               continue;
             }
 
-          if (strcmp (argv[i], OPTION_CODE_SIZE) == 0)
-            {
-              options.code_size = getIntArg(OPTION_CODE_SIZE, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
-            {
-              options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
-            {
-              options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
-            {
-              options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
-              continue;
-            }
-
-          if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
+            if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
             {
               optimize.global_cse = 0;
               continue;
@@ -1105,15 +1039,16 @@ parseCmdLine (int argc, char **argv)
               continue;
             }
 
-          if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
+          if (strcmp (argv[i], OPTION_WERROR) == 0)
             {
-              options.shortis8bits=1;
+              setWError(1);
+              addSet(&preArgvSet, Safe_strdup("-Werror"));
               continue;
             }
 
-          if (strcmp (argv[i], OPTION_TINI_LIBID) == 0)
+          if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
             {
-              options.tini_libid = getIntArg(OPTION_TINI_LIBID, argv, &i, argc);
+              options.shortis8bits=1;
               continue;
             }
 
@@ -1147,25 +1082,28 @@ parseCmdLine (int argc, char **argv)
 
           if (strcmp (argv[i], OPTION_CODE_SEG) == 0)
             {
-              options.code_seg = getStringArg(OPTION_CODE_SEG, argv, &i, argc);
+              struct dbuf_s segname;
+
+              dbuf_init (&segname, 16);
+              dbuf_printf (&segname, "%-8s(CODE)", getStringArg (OPTION_CODE_SEG, argv, &i, argc));
+              if (options.code_seg) Safe_free(options.code_seg);
+              options.code_seg = dbuf_detach (&segname);
               continue;
             }
 
           if (strcmp (argv[i], OPTION_CONST_SEG) == 0)
             {
-              options.const_seg = getStringArg(OPTION_CONST_SEG, argv, &i, argc);
-              continue;
-            }
+              struct dbuf_s segname;
 
-          if (!port->parseOption (&argc, argv, &i))
-            {
-              werror (W_UNKNOWN_OPTION, argv[i]);
-              continue;
-            }
-          else
-            {
+              dbuf_init (&segname, 16);
+              dbuf_printf (&segname, "%-8s(CODE)", getStringArg (OPTION_CONST_SEG, argv, &i, argc));
+              if (options.const_seg) Safe_free(options.const_seg);
+              options.const_seg = dbuf_detach (&segname);
               continue;
             }
+
+          werror (W_UNKNOWN_OPTION, argv[i]);
+          continue;
         }
 
       /* if preceded by  '-' then option */
@@ -1205,41 +1143,40 @@ parseCmdLine (int argc, char **argv)
 
             case 'o':
               {
-                char *p;
+                char *outName = getStringArg("-o", argv, &i, argc);
+                size_t len = strlen(outName);
 
-                /* copy the file name into the buffer */
-                strncpyz(buffer, getStringArg("-o", argv, &i, argc),
-                         sizeof(buffer));
                 /* point to last character */
-                p = buffer + strlen (buffer) - 1;
-                if (*p == DIR_SEPARATOR_CHAR)
+                if (IS_DIR_SEPARATOR(outName[len - 1]))
                   {
                     /* only output path specified */
-                    dstPath = Safe_strdup (buffer);
+                    dstPath = Safe_malloc(len);
+                    memcpy(dstPath, outName, len - 1);
+                    dstPath[len - 1] = '\0';
                     fullDstFileName = NULL;
                   }
                 else
                   {
-                    fullDstFileName = Safe_strdup (buffer);
+                    struct dbuf_s path;
 
-                    /* get rid of the "."-extension */
+                    dbuf_init (&path, 128);
+                    fullDstFileName = Safe_strdup (outName);
 
-                    /* is there a dot at all? */
-                    if (strrchr (buffer, '.') &&
-                        /* is the dot in the filename, not in the path? */
-                        (strrchr (buffer, DIR_SEPARATOR_CHAR) < strrchr (buffer, '.')))
-                      *strrchr (buffer, '.') = '\0';
+                    /* get rid of the "."-extension */
+                    dbuf_splitFile (outName, &path, NULL);
 
-                    dstFileName = Safe_strdup (buffer);
+                    dbuf_c_str (&path);
+                    dstFileName = dbuf_detach (&path);
 
+                    dbuf_init (&path, 128);
                     /* strip module name to get path */
-                    p = strrchr (buffer, DIR_SEPARATOR_CHAR);
-                    if (p)
+                    if (dbuf_splitPath (dstFileName, &path, NULL))
                       {
-                        /* path with trailing / */
-                        p[1] = '\0';
-                        dstPath = Safe_strdup (buffer);
+                        dbuf_c_str (&path);
+                        dstPath = dbuf_detach (&path);
                       }
+                    else
+                      dbuf_destroy (&path);
                   }
                 break;
               }
@@ -1270,7 +1207,7 @@ parseCmdLine (int argc, char **argv)
               verifyShortOption(argv[i]);
 
               printVersionInfo (stdout);
-              exit (0);
+              exit (EXIT_SUCCESS);
               break;
 
               /* preprocessor options */
@@ -1283,11 +1220,6 @@ parseCmdLine (int argc, char **argv)
                   addSet(&preArgvSet, Safe_strdup("-M"));
                 break;
               }
-            case 'C':
-              {
-                addSet(&preArgvSet, Safe_strdup("-C"));
-                break;
-              }
 
             case 'd':
             case 'D':
@@ -1329,23 +1261,19 @@ parseCmdLine (int argc, char **argv)
               break;
 
             default:
-              if (!port->parseOption (&argc, argv, &i))
-                werror (W_UNKNOWN_OPTION, argv[i]);
+              werror (W_UNKNOWN_OPTION, argv[i]);
             }
           continue;
         }
 
-      if (!port->parseOption (&argc, argv, &i))
+      /* no option must be a filename */
+      if (options.c1mode)
         {
-          /* no option must be a filename */
-          if (options.c1mode)
-            {
-              werror (W_NO_FILE_ARG_IN_C1, argv[i]);
-            }
-          else
-            {
-              processFile (argv[i]);
-            }
+          werror (W_NO_FILE_ARG_IN_C1, argv[i]);
+        }
+      else
+        {
+          processFile (argv[i]);
         }
     }
 
@@ -1379,7 +1307,16 @@ parseCmdLine (int argc, char **argv)
       if (!dstFileName)
         {
           werror (E_NEED_OPT_O_IN_C1);
-          exit (1);
+          exit (EXIT_FAILURE);
+        }
+      else
+        {
+          char *p;
+
+          moduleName = Safe_strdup(dstFileName);
+          for (p = moduleName; *p; ++p)
+            if (!isalnum ((unsigned char)*p))
+              *p = '_';
         }
     }
   /* if no dstFileName given with -o, we've to find one: */
@@ -1390,35 +1327,50 @@ parseCmdLine (int argc, char **argv)
       /* use the modulename from the C-source */
       if (fullSrcFileName)
         {
-          size_t bufSize = strlen (dstPath) + strlen (moduleNameBase) + 1;
+          struct dbuf_s path;
 
-          dstFileName = Safe_alloc (bufSize);
-          strncpyz (dstFileName, dstPath, bufSize);
-          strncatz (dstFileName, moduleNameBase, bufSize);
+          if (*dstPath != '\0')
+            {
+              dbuf_init(&path, 128);
+              dbuf_makePath (&path, dstPath, moduleNameBase);
+              dbuf_c_str (&path);
+              dstFileName = dbuf_detach (&path);
+            }
+          else
+            dstFileName = Safe_strdup(moduleNameBase);
         }
       /* use the modulename from the first object file */
       else if ((s = peekSet(relFilesSet)) != NULL)
         {
-          char *objectName;
-          size_t bufSize;
-
-          strncpyz (buffer, s, sizeof(buffer));
-          /* remove extension (it must be .rel) */
-          *strrchr (buffer, '.') = '\0';
-          /* remove path */
-          objectName = strrchr (buffer, DIR_SEPARATOR_CHAR);
-          if (objectName)
+          struct dbuf_s file;
+
+          dbuf_init(&file, 128);
+
+          /* get rid of the "."-extension */
+          dbuf_splitFile (s, &file, NULL);
+
+          dbuf_c_str (&file);
+          s = dbuf_detach (&file);
+
+          dbuf_init (&file, 128);
+
+          dbuf_splitPath (s, NULL, &file);
+
+          if (*dstPath != '\0')
             {
-              ++objectName;
+              struct dbuf_s path;
+
+              dbuf_init(&path, 128);
+              dbuf_makePath (&path, dstPath, dbuf_c_str (&file));
+              dbuf_destroy (&file);
+              dbuf_c_str (&path);
+              dstFileName = dbuf_detach (&path);
             }
           else
             {
-              objectName = buffer;
+              dbuf_c_str (&file);
+              dstFileName = dbuf_detach (&file);
             }
-          bufSize = strlen (dstPath) + strlen (objectName) + 1;
-          dstFileName = Safe_alloc (bufSize);
-          strncpyz (dstFileName, dstPath, bufSize);
-          strncatz (dstFileName, objectName, bufSize);
         }
       /* else no module given: help text is displayed */
     }
@@ -1434,11 +1386,11 @@ parseCmdLine (int argc, char **argv)
   if (TARGET_IS_MCS51)
     {
       options.float_rent++;
-    }
 
-  /* set up external stack location if not explicitly specified */
-  if (!options.xstack_loc)
-    options.xstack_loc = options.xdata_loc;
+      /* set up external stack location if not explicitly specified */
+      if (!options.xstack_loc)
+        options.xstack_loc = options.xdata_loc;
+    }
 
   /* if debug option is set then open the cdbFile */
   if (options.debug && fullSrcFileName)
@@ -1455,6 +1407,17 @@ parseCmdLine (int argc, char **argv)
   return 0;
 }
 
+/*-----------------------------------------------------------------*/
+/* finalizeOptions - finalize (post-process( options               */
+/*-----------------------------------------------------------------*/
+static void
+finalizeOptions (void)
+{
+  /* no peephole comments if not verbose asm */
+  if (!options.verboseAsm)
+    options.noPeepComments = 1;
+}
+
 /*-----------------------------------------------------------------*/
 /* linkEdit : - calls the linkage editor  with options             */
 /*-----------------------------------------------------------------*/
@@ -1468,8 +1431,9 @@ linkEdit (char **envp)
   char linkerScriptFileName[PATH_MAX];
 
   linkerScriptFileName[0] = 0;
+  c = NULL;
 
-  if(port->linker.needLinkerScript)
+  if (port->linker.needLinkerScript)
     {
       char out_fmt;
 
@@ -1489,12 +1453,12 @@ linkEdit (char **envp)
         }
 
       /* first we need to create the <filename>.lnk file */
-      SNPRINTF (linkerScriptFileName, sizeof(scratchFileName),
+      SNPRINTF (linkerScriptFileName, sizeof(linkerScriptFileName),
         "%s.lnk", dstFileName);
       if (!(lnkfile = fopen (linkerScriptFileName, "w")))
         {
           werror (E_FILE_OPEN_ERR, linkerScriptFileName);
-          exit (1);
+          exit (EXIT_FAILURE);
         }
 
       if (TARGET_Z80_LIKE)
@@ -1526,16 +1490,19 @@ linkEdit (char **envp)
           /* if code size specified */
           if (options.code_size)
             fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
-
-          if (options.debug)
-            fprintf (lnkfile, "-z\n");
         }
 
+      if (options.debug)
+        fprintf (lnkfile, "-z\n");
+
 #define WRITE_SEG_LOC(N, L) \
-  segName = Safe_strdup(N); \
-  c = strtok(segName, " \t"); \
-  fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
-  if (segName) { Safe_free(segName); }
+  if (N) \
+  { \
+    segName = Safe_strdup(N); \
+    c = strtok(segName, " \t"); \
+    fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
+    if (segName) { Safe_free(segName); } \
+  }
 
       if (!(TARGET_Z80_LIKE)) /*Not for the z80, gbz80*/
         {
@@ -1639,7 +1606,7 @@ linkEdit (char **envp)
                       fprintf(stderr,
                         "Add support for your FLAT24 target in %s @ line %d\n",
                         __FILE__, __LINE__);
-                      exit(EXIT_FAILURE);
+                      exit (EXIT_FAILURE);
                     }
                   break;
                 case MODEL_PAGE0:
@@ -1687,7 +1654,7 @@ linkEdit (char **envp)
                   fprintf(stderr,
                     "Add support for your FLAT24 target in %s @ line %d\n",
                     __FILE__, __LINE__);
-                  exit(EXIT_FAILURE);
+                  exit (EXIT_FAILURE);
                 }
               }
 #endif
@@ -1851,12 +1818,6 @@ linkEdit (char **envp)
 
   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)
@@ -1885,7 +1846,7 @@ linkEdit (char **envp)
       strncatz (scratchFileName,
         options.out_fmt ? ".S19" : ".ihx",
         sizeof(scratchFileName));
-      if (STRCMP (fullDstFileName, scratchFileName))
+      if (FILENAME_CMP (fullDstFileName, scratchFileName))
         remove (fullDstFileName);
       rename (scratchFileName, fullDstFileName);
 
@@ -1901,14 +1862,14 @@ linkEdit (char **envp)
       strncatz (scratchFileName, ".map", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".map", sizeof(buffer));
-      if (STRCMP (scratchFileName, buffer))
+      if (FILENAME_CMP (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))
+      if (FILENAME_CMP (scratchFileName, buffer))
         remove (buffer);
       rename (scratchFileName, buffer);
       if (options.debug)
@@ -1917,20 +1878,20 @@ linkEdit (char **envp)
           strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
           *q = 0;
           strncatz(buffer, ".cdb", sizeof(buffer));
-          if (STRCMP (scratchFileName, buffer))
+          if (FILENAME_CMP (scratchFileName, buffer))
             remove (buffer);
           rename (scratchFileName, buffer);
           /* and the OMF file without extension: */
           *p = 0;
           *q = 0;
-          if (STRCMP (scratchFileName, buffer))
+          if (FILENAME_CMP (scratchFileName, buffer))
             remove (buffer);
           rename (scratchFileName, buffer);
         }
     }
   if (system_ret)
     {
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 }
 
@@ -1967,7 +1928,7 @@ assemble (char **envp)
         /* either system() or the assembler itself has reported an error
            perror ("Cannot exec assembler");
         */
-        exit (1);
+        exit (EXIT_FAILURE);
     }
     /* TODO: most assembler don't have a -o parameter */
     /* -o option overrides default name? */
@@ -2007,6 +1968,10 @@ preProcess (char **envp)
           addSet(&preArgvSet, buf);
         }
 
+      /* if using dollar signs in identifiers */
+      if (options.dollars_in_ident)
+        addSet(&preArgvSet, Safe_strdup("-fdollars-in-identifiers"));
+
       /* if using external stack define the macro */
       if (options.useXstack)
         addSet(&preArgvSet, Safe_strdup("-DSDCC_USE_XSTACK"));
@@ -2049,6 +2014,14 @@ preProcess (char **envp)
           break;
         }
 
+      /* set macro corresponding to compiler option */
+      if (options.intlong_rent)
+        addSet(&preArgvSet, Safe_strdup("-DSDCC_INT_LONG_REENT"));
+
+      /* set macro corresponding to compiler option */
+      if (options.float_rent)
+        addSet(&preArgvSet, Safe_strdup("-DSDCC_FLOAT_REENT"));
+
       /* add SDCC version number */
       {
         char buf[20];
@@ -2057,19 +2030,26 @@ preProcess (char **envp)
         addSet(&preArgvSet, Safe_strdup(buf));
       }
 
+      /* add SDCC revision number */
+      {
+        char buf[25];
+        SNPRINTF(buf, sizeof(buf), "-DSDCC_REVISION=%s", getBuildNumber());
+        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));
+        SNPRINTF(&proc[0], 512, "-DSDCC_PROCESSOR=\"%s\"", port->processor);
+        addSet(&preArgvSet, Safe_strdup(proc));
       }
 
       /* standard include path */
       if (!options.nostdinc) {
-        inclList = appendStrSet(includeDirsSet, "-I\"", "\"");
+        inclList = appendStrSet(includeDirsSet, "-isystem \"", "\"");
         mergeSets(&preArgvSet, inclList);
       }
 
@@ -2095,18 +2075,17 @@ preProcess (char **envp)
 
       if (preProcOnly) {
         if (my_system (buffer)) {
-          exit (1);
+          exit (EXIT_FAILURE);
         }
 
-        exit (0);
+        exit (EXIT_SUCCESS);
       }
 
       yyin = my_popen (buffer);
       if (yyin == NULL) {
           perror ("Preproc file not found");
-          exit (1);
+          exit (EXIT_FAILURE);
       }
-      addSetHead (&pipeSet, yyin);
     }
 
   return 0;
@@ -2114,9 +2093,9 @@ preProcess (char **envp)
 
 /* Set bin paths */
 static void
-setBinPaths(const char *argv0)
+setBinPaths (const char *argv0)
 {
-  char *p;
+  const char *p;
   char buf[PATH_MAX];
 
   /*
@@ -2130,22 +2109,22 @@ setBinPaths(const char *argv0)
   /* do it in reverse mode, so that addSetHead() can be used
      instead of slower addSet() */
 
-  if ((p = getBinPath(argv0)) != NULL)
-    addSetHead(&binPathSet, Safe_strdup(p));
+  if ((p = getBinPath (argv0)) != NULL)
+    addSetHead (&binPathSet, (void *)p);
 
-  if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
-    SNPRINTF(buf, sizeof buf, "%s" PREFIX2BIN_DIR, p);
-    addSetHead(&binPathSet, Safe_strdup(buf));
+  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
-setIncludePath(void)
+setIncludePath (void)
 {
   char *p;
-  char *p2=NULL;
-  set *tempSet=NULL;
+  char *p2 = NULL;
+  set *tempSet = NULL;
 
   /*
    * Search logic:
@@ -2163,28 +2142,28 @@ setIncludePath(void)
   if (options.nostdinc)
       return;
 
-  tempSet = appendStrSet(dataDirsSet, NULL, INCLUDE_DIR_SUFFIX);
-  includeDirsSet = appendStrSet(tempSet, NULL, DIR_SEPARATOR_STRING);
-  includeDirsSet = appendStrSet(includeDirsSet, NULL, port->target);
-  mergeSets(&includeDirsSet, tempSet);
+  tempSet = appendStrSet (dataDirsSet, NULL, INCLUDE_DIR_SUFFIX);
+  includeDirsSet = appendStrSet (tempSet, NULL, DIR_SEPARATOR_STRING);
+  includeDirsSet = appendStrSet (includeDirsSet, NULL, port->target);
+  mergeSets (&includeDirsSet, tempSet);
 
-  if ((p = getenv(SDCC_INCLUDE_NAME)) != NULL)
-  {
-    addSetHead(&includeDirsSet, p);
-    p2=Safe_alloc(strlen(p)+strlen(DIR_SEPARATOR_STRING)+strlen(port->target)+1);
-    if(p2!=NULL)
+  if ((p = getenv (SDCC_INCLUDE_NAME)) != NULL)
     {
-        strcpy(p2, p);
-        strcat(p2, DIR_SEPARATOR_STRING);
-        strcat(p2, port->target);
-        addSetHead(&includeDirsSet, p2);
+      addSetHead(&includeDirsSet, p);
+      p2=Safe_alloc(strlen(p)+strlen(DIR_SEPARATOR_STRING)+strlen(port->target)+1);
+      if (p2 != NULL)
+        {
+          strcpy (p2, p);
+          strcat (p2, DIR_SEPARATOR_STRING);
+          strcat (p2, port->target);
+          addSetHead (&includeDirsSet, p2);
+        }
     }
-  }
 }
 
 /* Set system lib path */
 static void
-setLibPath(void)
+setLibPath (void)
 {
   char *p;
 
@@ -2200,17 +2179,17 @@ setLibPath(void)
   if (options.nostdlib)
       return;
 
-  libDirsSet = appendStrSet(dataDirsSet, NULL, LIB_DIR_SUFFIX);
+  libDirsSet = appendStrSet (dataDirsSet, NULL, LIB_DIR_SUFFIX);
 
-  if ((p = getenv(SDCC_LIB_NAME)) != NULL)
-    addSetHead(&libDirsSet, p);
+  if ((p = getenv (SDCC_LIB_NAME)) != NULL)
+    addSetHead (&libDirsSet, p);
 }
 
 /* Set data path */
 static void
-setDataPaths(const char *argv0)
+setDataPaths (const char *argv0)
 {
-  char *p;
+  const char *p;
   char buf[PATH_MAX];
 
   /*
@@ -2221,27 +2200,28 @@ setDataPaths(const char *argv0)
    * 3. - DATADIR (only on *nix)
    */
 
-  if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
-    SNPRINTF(buf, sizeof buf, "%s" PREFIX2DATA_DIR, p);
-    addSet(&dataDirsSet, Safe_strdup(buf));
+  if ((p = getenv (SDCC_DIR_NAME)) != NULL) {
+    SNPRINTF (buf, sizeof buf, "%s" PREFIX2DATA_DIR, p);
+    addSet (&dataDirsSet, Safe_strdup (buf));
   }
 
-  if ((p = getBinPath(argv0)) != NULL) {
-    SNPRINTF(buf, sizeof buf, "%s" BIN2DATA_DIR, p);
-    addSet(&dataDirsSet, Safe_strdup(buf));
+  if ((p = getBinPath (argv0)) != NULL) {
+    SNPRINTF (buf, sizeof buf, "%s" BIN2DATA_DIR, p);
+    Safe_free ((void *)p);
+    addSet (&dataDirsSet, Safe_strdup(buf));
   }
 
 #ifdef _WIN32
-  if (peekSet(dataDirsSet) == NULL) {
+  if (peekSet (dataDirsSet) == NULL) {
     /* this should never happen... */
-    wassertl(0, "Can't get binary path");
+    wassertl (0, "Can't get binary path");
   }
 #else
-  addSet(&dataDirsSet, Safe_strdup(DATADIR));
+  addSet (&dataDirsSet, Safe_strdup (DATADIR));
 #endif
 
-  setIncludePath();
-  setLibPath();
+  setIncludePath ();
+  setLibPath ();
 }
 
 static void
@@ -2274,6 +2254,20 @@ initValues (void)
       setMainValue ("linkdstfilename", "{stdlinkdstfilename}");
     }
 
+  /*
+   * Make sure the preprocessor is called with the "-std" option
+   * corresponding to the --std used to start sdcc
+   */
+  if (options.std_c99)
+    {
+      if (!options.std_sdcc)
+        setMainValue ("cppstd", "-std=c99 ");
+    }
+  else
+    {
+      if (!options.std_sdcc)
+        setMainValue ("cppstd", "-std=c89 ");
+    }
 }
 
 static void doPrintSearchDirs(void)
@@ -2317,7 +2311,7 @@ sig_handler (int signal)
       break;
     }
   fprintf (stderr, "Caught signal %d: %s\n", signal, sig_string);
-  exit (1);
+  exit (EXIT_FAILURE);
 }
 
 /*
@@ -2331,21 +2325,19 @@ main (int argc, char **argv, char **envp)
   /* turn all optimizations off by default */
   memset (&optimize, 0, sizeof (struct optimize));
 
-  if (NUM_PORTS==0) {
-    fprintf (stderr, "Build error: no ports are enabled.\n");
-    exit (1);
-  }
-
-  /* install atexit handler */
-  atexit(rm_tmpfiles);
+  if (NUM_PORTS == 0)
+    {
+      fprintf (stderr, "Build error: no ports are enabled.\n");
+      exit (EXIT_FAILURE);
+    }
 
   /* install signal handler;
      it's only purpose is to call exit() to remove temp files */
-  if (!getenv("SDCC_LEAVE_SIGNALS"))
+  if (!getenv ("SDCC_LEAVE_SIGNALS"))
     {
       signal (SIGABRT, sig_handler);
       signal (SIGTERM, sig_handler);
-      signal (SIGINT , sig_handler);
+      signal (SIGINT, sig_handler);
       signal (SIGSEGV, sig_handler);
     }
 
@@ -2358,8 +2350,8 @@ main (int argc, char **argv, char **envp)
   _findPort (argc, argv);
 
 #ifdef JAMIN_DS390
-  if (strcmp(port->target, "mcs51") == 0) {
-    printf("DS390 jammed in A\n");
+  if (strcmp (port->target, "mcs51") == 0) {
+    printf ("DS390 jammed in A\n");
     _setPort ("ds390");
     ds390_jammed = 1;
   }
@@ -2386,14 +2378,14 @@ main (int argc, char **argv, char **envp)
 
   initValues ();
 
-  setBinPaths(argv[0]);
-  setDataPaths(argv[0]);
+  setBinPaths (argv[0]);
+  setDataPaths (argv[0]);
 
-  if(port->initPaths)
-        port->initPaths();
+  if (port->initPaths)
+    port->initPaths();
 
-  if(options.printSearchDirs)
-        doPrintSearchDirs();
+  if (options.printSearchDirs)
+    doPrintSearchDirs();
 
   /* if no input then printUsage & exit */
   if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL)
@@ -2409,8 +2401,13 @@ main (int argc, char **argv, char **envp)
      And the z80 port needs port->finaliseOptions(),
      even if we're only linking. */
   initMem ();
+
+  /* finalize target specific options */
   port->finaliseOptions ();
 
+  /* finalize common options */
+  finalizeOptions ();
+
   if (fullSrcFileName || options.c1mode)
     {
       preProcess (envp);
@@ -2426,27 +2423,25 @@ main (int argc, char **argv, char **envp)
 
       yyparse ();
 
-      if (pclose(yyin))
-        fatalError = 1;
-      deleteSetItem(&pipeSet, yyin);
+      if (!options.c1mode)
+        if (pclose(yyin))
+          fatalError = 1;
 
-      if (fatalError) {
-        exit (1);
-      }
+      if (fatalError)
+        exit (EXIT_FAILURE);
 
       if (port->general.do_glue != NULL)
-        (*port->general.do_glue)();
+        (*port->general.do_glue) ();
       else
         {
           /* this shouldn't happen */
-          assert(FALSE);
+          assert (FALSE);
           /* in case of NDEBUG */
-          glue();
+          glue ();
         }
 
-      if (fatalError) {
-        exit (1);
-      }
+      if (fatalError)
+        exit (EXIT_FAILURE);
 
       if (!options.c1mode && !noAssemble)
         {
@@ -2458,13 +2453,13 @@ main (int argc, char **argv, char **envp)
   closeDumpFiles();
 
   if (options.debug && debugFile)
-    debugFile->closeFile();
+    debugFile->closeFile ();
 
   if (!options.cc_only &&
       !fatalError &&
       !noAssemble &&
       !options.c1mode &&
-      (fullSrcFileName || peekSet(relFilesSet) != NULL))
+      (fullSrcFileName || peekSet (relFilesSet) != NULL))
     {
       if (options.verbose)
         printf ("sdcc: Calling linker...\n");