Use 'ao-dbg' instead of 's51' to communicate with TeleMetrum
[fw/sdcc] / src / SDCCmain.c
index 2c89171d08991fec84f611091526c23200b3b55c..8b1194ba888fa19275225c1249df88a9d786ab50 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,21 +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 OPTION_HELP     "-help"
-
 #define LENGTH(_a)      (sizeof(_a)/sizeof(*(_a)))
 
-#define OPTION_STACK_8BIT       "--stack-8bit"
+#define OPTION_HELP             "--help"
 #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"
@@ -112,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"
@@ -122,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"
@@ -142,11 +139,13 @@ 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[] = {
     { 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" },
@@ -155,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" },
@@ -165,58 +163,42 @@ 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" },
     { 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." },
     { 'p',  NULL,                   NULL, "Select port specific processor e.g. -mpic14 -p16f84" },
     { 0,    OPTION_LARGE_MODEL,     NULL, "external data space is used" },
-    { 0,    OPTION_MEDIUM_MODEL,    NULL, "not supported" },
+    { 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" },
@@ -232,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" },
 
@@ -251,23 +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 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 },
-#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
+    { 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 }
@@ -306,7 +283,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 {cppstd}{cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
 
 PORT *port;
 
@@ -367,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
@@ -376,7 +353,6 @@ static void
 _setProcessor (char *_processor)
 {
   port->processor = _processor;
-  fprintf(stderr,"Processor: %s\n",_processor);
 }
 
 static void
@@ -413,7 +389,7 @@ _findPort (int argc, char **argv)
     }
 
   /* Use the first in the list */
-        port = _ports[0];
+  port = _ports[0];
 }
 
 /* search through the command line options for the processor */
@@ -437,38 +413,25 @@ _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
-           " #%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
-printOptions(const OPTION *optionsTable)
+printOptions(const OPTION *optionsTable, FILE *stream)
 {
   int i;
   for (i = 0;
@@ -479,11 +442,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 : "",
@@ -496,50 +459,64 @@ 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;
 
-  for (p = strtok(src, ","); p != NULL; p = strtok(NULL, ","))
-    addSet(dest, Safe_strdup(p));
+  p = src;
+  while (src < end)
+    {
+      dbuf_init (&dbuf, 16);
+
+      while (p < end && ',' != *p)
+        ++p;
+      dbuf_append (&dbuf, src, p - src);
+
+      /* null terminate the buffer */
+      dbuf_c_str (&dbuf);
+      addSet(dest, dbuf_detach (&dbuf));
+
+      src = ++p;
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -554,7 +531,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;
@@ -563,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;
 
@@ -588,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;
         }
 
@@ -619,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);
 
-      for (fext = moduleName; *fext; fext++)
-        if (!isalnum ((unsigned char)*fext))
-          *fext = '_';
+      dbuf_splitPath (dbuf_c_str (&path), NULL, &ext);
+      dbuf_destroy (&path);
+
+      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
-     addtional 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)
+     additional object file will be passed to the linker */
+  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
@@ -712,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(-1);
+          exit (EXIT_FAILURE);
         }
       else
         {
@@ -727,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
@@ -742,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
+      else
         {
-            /* Not an option, so can't be unsupported :) */
-            return 0;
+          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;
+    }
+  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;
+    }
 }
 
 /*-----------------------------------------------------------------*/
@@ -869,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;
         }
@@ -882,16 +913,19 @@ parseCmdLine (int argc, char **argv)
       /* options */
       if (argv[i][0] == '-' && argv[i][1] == '-')
         {
-          if (strcmp (argv[i], OPTION_HELP) == 0)
+          if (strcmp (argv[i], OPTION_USE_STDOUT) == 0)
             {
-              printUsage ();
-              exit (0);
+              if (options.use_stdout == 0)
+                {
+                  options.use_stdout = 1;
+                  dup2(STDOUT_FILENO, STDERR_FILENO);
+                }
+              continue;
             }
-
-          if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
+          if (strcmp (argv[i], OPTION_HELP) == 0)
             {
-              options.stack10bit = 0;
-              continue;
+              printUsage ();
+              exit (EXIT_SUCCESS);
             }
 
           if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
@@ -924,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 =
@@ -942,93 +970,21 @@ 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 ();
-              exit (0);
-              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);
+              printVersionInfo (stdout);
+              exit (EXIT_SUCCESS);
               continue;
             }
 
           if (strcmp (argv[i], OPTION_XRAM_SIZE) == 0)
             {
-              options.xram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
+              options.xram_size = getIntArg(OPTION_XRAM_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);
-              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;
@@ -1083,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;
             }
 
@@ -1125,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 */
@@ -1155,7 +1115,7 @@ parseCmdLine (int argc, char **argv)
               verifyShortOption(argv[i]);
 
               printUsage ();
-              exit (0);
+              exit (EXIT_SUCCESS);
               break;
 
             case 'm':
@@ -1183,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;
               }
@@ -1247,8 +1206,8 @@ parseCmdLine (int argc, char **argv)
             case 'v':
               verifyShortOption(argv[i]);
 
-              printVersionInfo ();
-              exit (0);
+              printVersionInfo (stdout);
+              exit (EXIT_SUCCESS);
               break;
 
               /* preprocessor options */
@@ -1261,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':
@@ -1307,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]);
         }
     }
 
@@ -1357,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: */
@@ -1368,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 */
     }
@@ -1412,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)
@@ -1429,11 +1403,21 @@ 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;
 }
 
+/*-----------------------------------------------------------------*/
+/* 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             */
 /*-----------------------------------------------------------------*/
@@ -1447,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;
 
@@ -1468,15 +1453,15 @@ 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_IS_Z80 || TARGET_IS_GBZ80)
+      if (TARGET_Z80_LIKE)
         {
           fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
             out_fmt, dstFileName);
@@ -1488,7 +1473,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)
@@ -1505,18 +1490,21 @@ 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_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+      if (!(TARGET_Z80_LIKE)) /*Not for the z80, gbz80*/
         {
 
           /* code segment start */
@@ -1524,18 +1512,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)
             {
@@ -1574,15 +1569,27 @@ 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)
                 {
                 case MODEL_SMALL:
-                  c = "small";
+                  if (options.stackAuto)
+                    c = "small-stack-auto";
+                  else
+                    c = "small";
+                  break;
+                case MODEL_MEDIUM:
+                  if (options.stackAuto)
+                    c = "medium-stack-auto";
+                  else
+                    c = "medium";
                   break;
                 case MODEL_LARGE:
-                  c = "large";
+                  if (options.stackAuto)
+                    c = "large-stack-auto";
+                  else
+                    c = "large";
                   break;
                 case MODEL_FLAT24:
                   /* c = "flat24"; */
@@ -1599,7 +1606,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:
@@ -1647,7 +1654,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
@@ -1664,8 +1671,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);
@@ -1689,8 +1695,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;
@@ -1775,7 +1780,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\"", "\"");
@@ -1812,6 +1817,7 @@ linkEdit (char **envp)
   /*  if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer); */
 
   system_ret = my_system (buffer);
+
   /* TODO: most linker don't have a -o parameter */
   /* -o option overrides default name? */
   if (fullDstFileName)
@@ -1840,8 +1846,8 @@ linkEdit (char **envp)
       strncatz (scratchFileName,
         options.out_fmt ? ".S19" : ".ihx",
         sizeof(scratchFileName));
-      if (strcmp (fullDstFileName, scratchFileName))
-        unlink (fullDstFileName);
+      if (FILENAME_CMP (fullDstFileName, scratchFileName))
+        remove (fullDstFileName);
       rename (scratchFileName, fullDstFileName);
 
       strncpyz (buffer, fullDstFileName, sizeof(buffer));
@@ -1856,15 +1862,15 @@ linkEdit (char **envp)
       strncatz (scratchFileName, ".map", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".map", sizeof(buffer));
-      if (strcmp (scratchFileName, buffer))
-        unlink (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))
-        unlink (buffer);
+      if (FILENAME_CMP (scratchFileName, buffer))
+        remove (buffer);
       rename (scratchFileName, buffer);
       if (options.debug)
         {
@@ -1872,20 +1878,20 @@ linkEdit (char **envp)
           strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
           *q = 0;
           strncatz(buffer, ".cdb", sizeof(buffer));
-          if (strcmp (scratchFileName, buffer))
-            unlink (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))
-            unlink (buffer);
+          if (FILENAME_CMP (scratchFileName, buffer))
+            remove (buffer);
           rename (scratchFileName, buffer);
         }
     }
   if (system_ret)
     {
-      exit (1);
+      exit (EXIT_FAILURE);
     }
 }
 
@@ -1922,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? */
@@ -1932,7 +1938,7 @@ assemble (char **envp)
                   port->linker.rel_ext,
                   sizeof(scratchFileName));
         if (strcmp (scratchFileName, fullDstFileName))
-          unlink (fullDstFileName);
+          remove (fullDstFileName);
         rename (scratchFileName, fullDstFileName);
     }
 }
@@ -1952,6 +1958,20 @@ preProcess (char **envp)
       const char *s;
       set *inclList = NULL;
 
+      if (NULL != port->linker.rel_ext)
+        {
+#define OBJ_EXT_STR     "-obj-ext="
+#define OBJ_EXT_LEN     ((sizeof OBJ_EXT_STR) - 1)
+          char *buf = Safe_alloc(strlen(port->linker.rel_ext) + (OBJ_EXT_LEN + 1));
+          strcpy(buf, OBJ_EXT_STR);
+          strcpy(&buf[OBJ_EXT_LEN], port->linker.rel_ext);
+          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"));
@@ -1968,6 +1988,9 @@ preProcess (char **envp)
       if (options.noOverlay)
         addSet(&preArgvSet, Safe_strdup("-DSDCC_NOOVERLAY"));
 
+      if (options.unsigned_char)
+        addSet(&preArgvSet, Safe_strdup("-DSDCC_CHAR_UNSIGNED"));
+
       /* set the macro for large model  */
       switch (options.model)
         {
@@ -1994,13 +2017,42 @@ 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];
+        SNPRINTF(buf, sizeof(buf), "-DSDCC=%d%d%d",
+                 SDCC_VERSION_HI, SDCC_VERSION_LO, SDCC_VERSION_P);
+        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));
+      }
+
       /* standard include path */
       if (!options.nostdinc) {
-        inclList = appendStrSet(includeDirsSet, "-I\"", "\"");
+        inclList = appendStrSet(includeDirsSet, "-isystem \"", "\"");
         mergeSets(&preArgvSet, inclList);
       }
 
@@ -2022,23 +2074,21 @@ preProcess (char **envp)
 
       if (options.verbose)
         printf ("sdcc: Calling preprocessor...\n");
-
       buildCmdLine2 (buffer, sizeof(buffer), _preCmd);
 
       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;
@@ -2046,9 +2096,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];
 
   /*
@@ -2062,29 +2112,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));
   }
-
-#if 0
-  if (options.printSearchDirs) {
-    printf("programs:\n");
-    fputStrSet(stdout, binPathSet);
-  }
-#endif
 }
 
 /* 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:
@@ -2102,35 +2145,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);
+        }
     }
-  }
-
-#if 0
-  if (options.printSearchDirs) {
-    printf("includedir:\n");
-    fputStrSet(stdout, includeDirsSet);
-  }
-#endif
 }
 
 /* Set system lib path */
 static void
-setLibPath(void)
+setLibPath (void)
 {
   char *p;
 
@@ -2146,24 +2182,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 0
-  if (options.printSearchDirs) {
-    printf("libdir:\n");
-    fputStrSet(stdout, libDirsSet);
-  }
-#endif
+  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];
 
   /*
@@ -2174,34 +2203,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
 
-#if 0
-  if (options.printSearchDirs) {
-    printf("datadir:\n");
-    fputStrSet(stdout, dataDirsSet);
-  }
-#endif
-
-  setIncludePath();
-  setLibPath();
+  setIncludePath ();
+  setLibPath ();
 }
 
 static void
@@ -2234,6 +2257,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)
@@ -2277,7 +2314,7 @@ sig_handler (int signal)
       break;
     }
   fprintf (stderr, "Caught signal %d: %s\n", signal, sig_string);
-  exit (1);
+  exit (EXIT_FAILURE);
 }
 
 /*
@@ -2291,23 +2328,19 @@ 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);
-  }
-
-  /* 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 purpuse is to call exit() to remove temp files */
-  if (!getenv("SDCC_LEAVE_SIGNALS"))
+     it's only purpose is to call exit() to remove temp files */
+  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);
     }
 
@@ -2320,9 +2353,9 @@ 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");
-          _setPort ("ds390");
+  if (strcmp (port->target, "mcs51") == 0) {
+    printf ("DS390 jammed in A\n");
+    _setPort ("ds390");
     ds390_jammed = 1;
   }
 #endif
@@ -2340,34 +2373,44 @@ main (int argc, char **argv, char **envp)
     options.stack10bit=0;
   }
 #endif
+
   parseCmdLine (argc, argv);
 
+  if (options.verbose && NULL != port->processor)
+    printf("Processor: %s\n", port->processor);
+
   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) {
-    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 ().
      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);
@@ -2383,27 +2426,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)
         {
@@ -2415,14 +2456,17 @@ 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");
+
       if (port->linker.do_link)
         port->linker.do_link ();
       else