Fixed a parameter allocation bug
[fw/sdcc] / src / SDCCmain.c
index 2ad90c4ca9e5305f129d991b2c8092423f069c5d..be3101f9266bc5132a4ac2c28b480a2d0db2129b 100644 (file)
 
 #include "common.h"
 #include <ctype.h>
+
+#if NATIVE_WIN32
+#include <process.h>
+#else
 #include "spawn.h"
+#endif
 
 /* This is a bit messy.  We cant include unistd.h as it defines
    'link' which we also use.
@@ -69,10 +74,14 @@ bool verboseExec = FALSE;
 //extern int wait (int *);
 char    *preOutName;
 
+/* Far functions, far data */
 #define OPTION_LARGE_MODEL "-model-large"
+/* Far functions, near data */
+#define OPTION_MEDIUM_MODEL "-model-medium"
 #define OPTION_SMALL_MODEL "-model-small"
 #define OPTION_FLAT24_MODEL "-model-flat24"
 #define OPTION_STACK_AUTO  "-stack-auto"
+#define OPTION_STACK_10BIT "-stack-10bit"
 #define OPTION_XSTACK      "-xstack"
 #define OPTION_GENERIC     "-generic"
 #define OPTION_NO_GCSE     "-nogcse"
@@ -109,9 +118,11 @@ char    *preOutName;
 #define OPTION_NOPEEP      "-no-peep"
 #define OPTION_ASMPEEP     "-peep-asm"
 #define OPTION_DEBUG       "-debug"
+#define OPTION_NODEBUG    "-nodebug"
 #define OPTION_VERSION     "-version"
 #define OPTION_STKAFTRDATA "-stack-after-data"
 #define OPTION_PREPROC_ONLY "-preprocessonly"
+#define OPTION_C1_MODE   "-c1mode"
 #define OPTION_HELP         "-help"
 #define OPTION_CALLEE_SAVES "-callee-saves"
 #define OPTION_NOREGPARMS   "-noregparms"
@@ -121,16 +132,41 @@ static const char *_preCmd[] = {
     "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
 };
 
+#if !OPT_DISABLE_MCS51
 extern PORT mcs51_port;
-extern PORT z80_port;
+#endif
+#if !OPT_DISABLE_GBZ80
 extern PORT gbz80_port;
+#endif
+#if !OPT_DISABLE_Z80
+extern PORT z80_port;
+#endif
+#if !OPT_DISABLE_AVR
+extern PORT avr_port;
+#endif
+#if !OPT_DISABLE_DS390
+extern PORT ds390_port;
+#endif
+
 
 PORT *port;
 
 static PORT *_ports[] = {
-    &mcs51_port,
+#if !OPT_DISABLE_MCS51
+   &mcs51_port,
+#endif
+#if !OPT_DISABLE_GBZ80
+    &gbz80_port,
+#endif
+#if !OPT_DISABLE_Z80
     &z80_port,
-    &gbz80_port
+#endif
+#if !OPT_DISABLE_AVR
+    &avr_port,
+#endif
+#if !OPT_DISABLE_DS390
+    &ds390_port,
+#endif
 };
 
 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
@@ -149,10 +185,11 @@ static int _setPort(const char *name)
        }
     }
     /* Error - didnt find */
-    return 1;
+    werror(E_UNKNOWN_TARGET,name);
+    exit(1);
 }
 
-static void _buildCmdLine(char *into, char **args, const char **cmds, 
+void buildCmdLine(char *into, char **args, const char **cmds, 
                          const char *p1, const char *p2, 
                          const char *p3, const char **list)
 {
@@ -169,6 +206,8 @@ static void _buildCmdLine(char *into, char **args, const char **cmds,
        /* See if it has a '$' anywhere - if not, just copy */
        if ((p = strchr(from, '$'))) {
            strncpy(into, from, p - from);
+           /* NULL terminate it */
+           into[p-from] = '\0';
            from = p+2;
            p++;
            switch (*p) {
@@ -220,8 +259,11 @@ void       printVersionInfo ()
             "SDCC : ");
     for (i=0; i<NUM_PORTS; i++)
        fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
-
-    fprintf(stderr, " %s `"
+    fprintf(stderr, " %s"
+#ifdef SDCC_SUB_VERSION_STR
+           "/" SDCC_SUB_VERSION_STR
+#endif
+           " ` "
 #ifdef __CYGWIN32__
                " (CYGWIN32)\n"
 #else
@@ -231,6 +273,7 @@ void        printVersionInfo ()
                " (UNIX) \n"
 # endif
 #endif
+
            , VersionString
            );
 }
@@ -262,7 +305,7 @@ void        printUsage ()
                 "PreProcessor Options :-\n"
                 "\t-Dmacro             -       Define Macro\n"          
                 "\t-Ipath              -       Include \"*.h\" path\n"
-                "Note: this is a complete list of options see docs for details\n",
+                "Note: this is NOT a complete list of options see docs for details\n",
                 _ports[0]->target
                 );             
        exit (0);
@@ -312,6 +355,7 @@ static void setDefaultOptions()
     options.idata_loc = 0x80;
     options.genericPtr = 1;   /* default on */
     options.nopeep    = 0;
+    options.model = port->general.default_model;
 
     /* now for the optimizations */
     /* turn on the everything */
@@ -345,7 +389,7 @@ static void processFile (char *s)
     }
 
     /* otherwise depending on the file type */
-    if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0) {
+    if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
        /* source file name : not if we already have a 
           source file */
        if (srcFileName) {
@@ -386,8 +430,9 @@ static void processFile (char *s)
     /* 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,".R") == 0 || strcmp(fext,".REL") == 0 ||
+       strcmp(fext, port->linker.rel_ext) == 0)
+       {
        relFiles[nrelFiles++] = s;
        return ;
     }
@@ -402,6 +447,20 @@ static void processFile (char *s)
   
 }
 
+static void _processC1Arg(char *s)
+{
+    if (srcFileName) {
+       if (options.out_name) {
+           werror(W_TOO_MANY_SRC,s);
+           return;
+       }
+       options.out_name = strdup(s);
+    }
+    else {
+       processFile(s);
+    }
+}
+
 static void _addToList(const char **list, const char *str)
 {
     /* This is the bad way to do things :) */
@@ -415,6 +474,14 @@ static void _addToList(const char **list, const char *str)
     *(++list) = NULL;
 }
 
+static void _setModel(int model, const char *sz)
+{
+    if (port->general.supported_models & model)
+       options.model = model;
+    else
+       werror(W_UNSUPPORTED_MODEL, sz, port->target);
+}
+
 /*-----------------------------------------------------------------*/
 /* parseCmdLine - parses the command line and sets the options     */
 /*-----------------------------------------------------------------*/
@@ -442,19 +509,29 @@ int   parseCmdLine ( int argc, char **argv )
            }
 
            if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
-               options.model = MODEL_LARGE;
+               _setModel(MODEL_LARGE, argv[i]);
+                continue;
+           }
+
+           if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
+               _setModel(MODEL_MEDIUM, argv[i]);
                 continue;
            }
            
            if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
-               options.model = MODEL_SMALL;
+               _setModel(MODEL_SMALL, argv[i]);
                 continue;
            }
            
            if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
-               options.model = MODEL_FLAT24;
+               _setModel(MODEL_FLAT24, argv[i]);
                 continue;
-           }       
+           }
+           
+           if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
+               options.stack10bit = 1;
+               continue;
+           }
 
            if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
                options.stackAuto = 1;
@@ -536,6 +613,11 @@ int   parseCmdLine ( int argc, char **argv )
                 continue;
            }
 
+           if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
+               options.c1mode = 1;
+                continue;
+           }
+
            
            if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
                options.dump_rassgn = 
@@ -573,6 +655,11 @@ int   parseCmdLine ( int argc, char **argv )
                 continue;
            }
 
+           if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
+               options.nodebug = 1;            
+                continue;
+           }
+
            if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
                options.noregparms = 1;         
                 continue;
@@ -737,8 +824,10 @@ int   parseCmdLine ( int argc, char **argv )
        /* these are undocumented options */
        /* if preceded by '/' then turn off certain optmizations, used
           for debugging only these are also the legacy options from
-          version 1.xx will be removed gradually */
-       if ( *argv[i] == '/') {
+          version 1.xx will be removed gradually.
+          It may be an absolute filename.
+       */
+       if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
            switch (argv[i][1]) {
                
            case 'p':
@@ -889,11 +978,20 @@ int   parseCmdLine ( int argc, char **argv )
                break;
 
                /* preprocessor options */              
+           case 'M':
+             {
+               preProcOnly=1;
+               _addToList(preArgv, "-M");
+               break;
+             }
+           case 'C':
+             {
+               _addToList(preArgv, "-C");
+               break;
+             }
            case 'd':
            case 'D':
            case 'I':
-           case 'M':
-           case 'C':
            case 'A':
            case 'U':
                {
@@ -909,8 +1007,6 @@ int   parseCmdLine ( int argc, char **argv )
                    
                    if ( argv[i][1] == 'Y' )
                        argv[i][1] = 'I';
-                   if (argv[i][1] == 'M')
-                       preProcOnly = 1;
 
                    sprintf(buffer, "-%c%s", sOpt, rest);
                    _addToList(preArgv, buffer);
@@ -926,7 +1022,10 @@ int   parseCmdLine ( int argc, char **argv )
 
        if (!port->parseOption(&argc, argv, &i)) {
            /* no option must be a filename */
-           processFile(argv[i]);
+           if (options.c1mode)
+               _processC1Arg(argv[i]);
+           else
+               processFile(argv[i]);
        }
     }  
 
@@ -935,7 +1034,7 @@ int   parseCmdLine ( int argc, char **argv )
        options.xstack_loc = options.xdata_loc ;
 
     /* if debug option is set the open the cdbFile */
-    if (/* options.debug && */ srcFileName) {
+    if (!options.nodebug && srcFileName) {
        sprintf(cdbfnbuf,"%s.cdb",srcFileName);
        if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
            werror(E_FILE_OPEN_ERR,cdbfnbuf);
@@ -944,7 +1043,6 @@ int   parseCmdLine ( int argc, char **argv )
            fprintf(cdbFile,"M:%s\n",moduleName);
        }
     }
-    port->finaliseOptions();
     return 0;
 }
 
@@ -954,15 +1052,40 @@ int   parseCmdLine ( int argc, char **argv )
 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
 int my_system (const char *cmd, char **cmd_argv)
 {    
-
     char *dir, *got= NULL; int i= 0;
-    while (!got && try_dir[i]) {
-       dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
-       strcpy(dir, try_dir[i]); strcat(dir, "/"); strcat(dir, cmd);
-       if (access(dir, X_OK) == 0)
-           got= strdup(dir);
-       free(dir);
-       i++;
+
+    while (!got && try_dir[i])
+    {
+        dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
+        strcpy(dir, try_dir[i]);
+        strcat(dir, "/");
+        strcat(dir, cmd);
+
+#if NATIVE_WIN32
+        strcat(dir, ".exe");
+
+        /* Mung slashes into backslashes to keep WIndoze happy. */
+       {
+           char *r;
+           r = dir;
+           
+           while (*r)
+               {
+                   if (*r == '/')
+                       {
+                           *r = '\\';
+                       }
+                   r++;
+               }
+       }
+#endif
+
+        if (access(dir, X_OK) == 0)
+        {
+            got= strdup(dir);
+        }
+        free(dir);
+        i++;
     }
 #if FEATURE_VERBOSE_EXEC
     if (verboseExec) {
@@ -1042,21 +1165,25 @@ static void linkEdit (char **envp)
        fprintf(lnkfile,"%s\n",linkOptions[i]);
 
     /* standard library path */
-    switch(options.model)
-    {
+    if (strcmp(port->target,"ds390")==0) {
+      c="ds390";
+    } else {
+      switch(options.model)
+       {
         case MODEL_SMALL:
-                   c = "small";
-                   break;
+         c = "small";
+         break;
                case MODEL_LARGE:
-                   c = "large";
-                   break;
+         c = "large";
+         break;
                case MODEL_FLAT24:
-                   c = "flat24";
-                   break;
+         c = "flat24";
+         break;
         default:
-            werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
-            c = "unknown";
-            break;
+         werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
+         c = "unknown";
+         break;
+       }
     }
     fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
            
@@ -1065,6 +1192,9 @@ static void linkEdit (char **envp)
        fprintf (lnkfile,"-k %s\n",libPaths[i]);
         
     /* standard library files */
+    if (strcmp(port->target, "ds390")==0) {
+      fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
+    }
     fprintf (lnkfile,"-l %s\n",STD_LIB);
     fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
     fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
@@ -1084,7 +1214,7 @@ static void linkEdit (char **envp)
     fprintf (lnkfile,"\n-e\n");
     fclose(lnkfile);
 
-    _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
+    buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
 
     /* call the linker */
     if (my_system(argv[0], argv)) {
@@ -1108,7 +1238,7 @@ static void assemble (char **envp)
 {
     char *argv[128];  /* assembler arguments */
 
-    _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
+    buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
 
     if (my_system(argv[0], argv)) {
        perror("Cannot exec assember");
@@ -1128,52 +1258,67 @@ static int preProcess (char **envp)
 
     preOutName = NULL;
 
-    /* if using external stack define the macro */
-    if ( options.useXstack )
-       _addToList(preArgv, "-DSDCC_USE_XSTACK");
-    
-    /* set the macro for stack autos   */
-    if ( options.stackAuto )
-       _addToList(preArgv, "-DSDCC_STACK_AUTO");
+    if (!options.c1mode) {
+       /* if using external stack define the macro */
+       if ( options.useXstack )
+           _addToList(preArgv, "-DSDCC_USE_XSTACK");
+       
+       /* set the macro for stack autos        */
+       if ( options.stackAuto )
+           _addToList(preArgv, "-DSDCC_STACK_AUTO");
+           
+       /* set the macro for stack autos        */
+       if ( options.stack10bit )
+           _addToList(preArgv, "-DSDCC_STACK_TENBIT"); 
     
-    /* set the macro for large model   */
-    switch(options.model)
-    {
-        case MODEL_LARGE:
-           _addToList(preArgv, "-DSDCC_MODEL_LARGE");
-           break;
-       case MODEL_SMALL:
-           _addToList(preArgv, "-DSDCC_MODEL_SMALL");
-           break;
-       case MODEL_FLAT24:
-           _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
-           break;
-       default:
-           werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
-           break;
-    }      
+       /* set the macro for large model        */
+       switch(options.model)
+           {
+           case MODEL_LARGE:
+               _addToList(preArgv, "-DSDCC_MODEL_LARGE");
+               break;
+           case MODEL_SMALL:
+               _addToList(preArgv, "-DSDCC_MODEL_SMALL");
+               break;
+           case MODEL_COMPACT:
+               _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
+               break;
+           case MODEL_MEDIUM:
+               _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
+               break;
+           case MODEL_FLAT24:
+               _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
+               break;
+           default:
+               werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
+               break;
+           }       
            
     
-    /* add port (processor information to processor */
-    sprintf(procDef,"-DSDCC_%s",port->target);
-    _addToList(preArgv,procDef);
+       /* add port (processor information to processor */
+       sprintf(procDef,"-DSDCC_%s",port->target);
+       _addToList(preArgv,procDef);
 
-    if (!preProcOnly)
-       preOutName = strdup(tmpnam(NULL));
+       if (!preProcOnly)
+           preOutName = strdup(tmpnam(NULL));
 
-    _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName, 
-                 preOutName, srcFileName, preArgv);
+       buildCmdLine(buffer, argv, _preCmd, fullSrcFileName, 
+                     preOutName, srcFileName, preArgv);
 
-    if (my_system(argv[0], argv)) {
-       unlink (preOutName);
-       perror("Cannot exec Preprocessor");
-       exit(1);
-    }
+       if (my_system(argv[0], argv)) {
+           unlink (preOutName);
+           perror("Cannot exec Preprocessor");
+           exit(1);
+       }
 
-    if (preProcOnly)
-       exit(0);
+       if (preProcOnly)
+           exit(0);
+    }
+    else {
+       preOutName = fullSrcFileName;
+    }
 
-    yyin = fopen(preOutName,"r");
+    yyin = fopen(preOutName, "r");
     if (yyin == NULL) {
        perror("Preproc file not found\n");
        exit(1);
@@ -1206,23 +1351,26 @@ int main ( int argc, char **argv , char **envp)
 {
     /* turn all optimizations off by default */
     memset(&optimize,0,sizeof(struct optimize));
-    
+
     /*printVersionInfo ();*/
 
     _findPort(argc, argv);
     /* Initalise the port. */
     if (port->init)
        port->init();
-    
+
     setDefaultOptions();
     parseCmdLine(argc,argv);
 
+    initMem();
+
+    port->finaliseOptions();
+
     /* if no input then printUsage & exit */
-    if (!srcFileName && !nrelFiles) {
+    if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
        printUsage();
        exit(0);
     }
-
        
     if (srcFileName)
        preProcess(envp) ;
@@ -1230,7 +1378,6 @@ int main ( int argc, char **argv , char **envp)
     if (srcFileName) {
 
        initSymt();
-       initMem();                  
        initiCode();
        initCSupport ();
        initPeepHole();
@@ -1238,8 +1385,11 @@ int main ( int argc, char **argv , char **envp)
 
        if (!fatalError) {
            glue();
-           assemble(envp);
-       }
+           if (!options.c1mode)
+               assemble(envp);
+       } else {
+           return 1;
+        }
        
     }
     
@@ -1249,16 +1399,22 @@ int main ( int argc, char **argv , char **envp)
     if (!options.cc_only && 
        !fatalError      &&
        !noAssemble      &&
-       (srcFileName || nrelFiles))
-       linkEdit (envp);
+       !options.c1mode  &&
+       (srcFileName || nrelFiles)) {
+       if (port->linker.do_link)
+           port->linker.do_link();
+       else
+           linkEdit (envp);
+    }
 
     if (yyin && yyin != stdin)
        fclose(yyin);
 
-    if (preOutName) {
-       unlink(preOutName);
-       free(preOutName);
+    if (preOutName && !options.c1mode) {
+        unlink(preOutName);
+        free(preOutName);
     }
+
     return 0;
     
 }