You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
+#include "common.h"
+#include <ctype.h>
#include "spawn.h"
-#include "SDCCglobl.h"
-#include "config.h"
+
+/* This is a bit messy. We cant include unistd.h as it defines
+ 'link' which we also use.
+*/
+int access(const char *path, int mode);
+#define X_OK 1
+int unlink(const char *path);
extern void initSymt ();
extern void initMem ();
char *fullSrcFileName ;/* full name for the source file */
char *srcFileName ;/* source file name with the .c stripped */
char *moduleName ;/* module name is srcFilename stripped of any path */
-char *preArgv[128] ;/* pre-processor arguments */
-int preArgc = 0 ;/* pre-processor argument count */
+const char *preArgv[128] ;/* pre-processor arguments */
int currRegBank = 0 ;
struct optimize optimize ;
struct options options ;
short preProcOnly = 0;
short noAssemble = 0;
char *linkOptions[128];
-char *asmOptions[128];
+const char *asmOptions[128];
char *libFiles[128] ;
int nlibFiles = 0;
char *libPaths[128] ;
#define OPTION_HELP "-help"
#define OPTION_CALLEE_SAVES "-callee-saves"
#define OPTION_NOREGPARMS "-noregparms"
+
+static const char *_preCmd[] = {
+ "sdcpp", "-version", "-Wall", "-lang-c++", "-DSDCC=1",
+ "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
+};
+
+extern PORT mcs51_port;
+extern PORT z80_port;
+
+PORT *port;
+
+static PORT *_ports[] = {
+ &mcs51_port,
+ &z80_port
+};
+
+#define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
+
+/** Sets the port to the one given by the command line option.
+ @param The name minus the option (eg 'mcs51')
+ @return 0 on success.
+*/
+static int _setPort(const char *name)
+{
+ int i;
+ for (i=0; i<NUM_PORTS; i++) {
+ if (!strcmp(_ports[i]->target, name)) {
+ port = _ports[i];
+ return 0;
+ }
+ }
+ /* Error - didnt find */
+ return 1;
+}
+
+static void _buildCmdLine(char *into, char **args, const char **cmds,
+ const char *p1, const char *p2,
+ const char *p3, const char **list)
+{
+ const char *p, *from;
+
+ while (*cmds) {
+ *args = into;
+ args++;
+
+ from = *cmds;
+ cmds++;
+ *into = '\0';
+
+ /* See if it has a '$' anywhere - if not, just copy */
+ if ((p = strchr(from, '$'))) {
+ strncpy(into, from, p - from);
+ from = p+2;
+ p++;
+ switch (*p) {
+ case '1':
+ if (p1)
+ strcat(into, p1);
+ break;
+ case '2':
+ if (p2)
+ strcat(into, p2);
+ break;
+ case '3':
+ if (p3)
+ strcat(into, p3);
+ break;
+ case 'l': {
+ const char **tmp = list;
+ if (tmp) {
+ while (*tmp) {
+ strcpy(into, *tmp);
+ into += strlen(into)+1;
+ *args = into;
+ args++;
+ tmp++;
+ }
+ }
+ break;
+ }
+ default:
+ assert(0);
+ }
+ }
+ strcat(into, from);
+ if (strlen(into) == 0)
+ args--;
+ into += strlen(into)+1;
+ }
+ *args = NULL;
+}
+
/*-----------------------------------------------------------------*/
/* printVersionInfo - prints the version info */
/*-----------------------------------------------------------------*/
void printVersionInfo ()
{
+ int i;
+ fprintf (stderr,
+ "SDCC : ");
+ for (i=0; i<NUM_PORTS; i++)
+ fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
- fprintf (stderr ,
- "SDCC : MCU 8051 %s "
+ fprintf(stderr, " %s `"
#ifdef __CYGWIN32__
" (CYGWIN32)\n"
#else
" (UNIX) \n"
# endif
#endif
- , VersionString
- );
+ , VersionString
+ );
}
/*-----------------------------------------------------------------*/
fprintf (stderr,
"Usage : [options] filename\n"
"Options :-\n"
+ "\t-m<proc> - Target processor <proc>. Default %s\n"
+ "\t Try --version for supported values of <proc>\n"
"\t--model-large - Large Model\n"
"\t--model-small - Small Model (default)\n"
"\t--stack-auto - Stack automatic variables\n"
"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 a complete list of options see docs for details\n",
+ _ports[0]->target
+ );
exit (0);
}
preArgv[i] = linkOptions [i] =
asmOptions[i] = relFiles[i] = libFiles[i] =
libPaths[i] = NULL ;
- preArgv[preArgc++] = "-version";
- preArgv[preArgc++] = "-Wall";
- preArgv[preArgc++] = "-lang-c++";
- preArgv[preArgc++] = "-DSDCC=1";
- preArgv[preArgc++] = "-I" SDCC_INCLUDE_DIR ;
/* first the options part */
options.stack_loc = 0; /* stack pointer initialised to 0 */
optimize.label4 = 1;
optimize.loopInvariant = 1;
optimize.loopInduction = 1;
+
+ port->setDefaultOptions();
}
/*-----------------------------------------------------------------*/
}
+static void _addToList(const char **list, const char *str)
+{
+ /* This is the bad way to do things :) */
+ while (*list)
+ list++;
+ *list = strdup(str);
+ if (!*list) {
+ werror(E_OUT_OF_MEM,__FILE__, 0);
+ exit (1);
+ }
+ *(++list) = NULL;
+}
/*-----------------------------------------------------------------*/
/* parseCmdLine - parses the command line and sets the options */
continue;
}
- werror(W_UNKNOWN_OPTION,argv[i]);
+ if (!port->parseOption(&argc, argv))
+ werror(W_UNKNOWN_OPTION,argv[i]);
}
/* these are undocumented options */
break;
case 'm':
- werror(W_UNSUPP_OPTION,"-mL/-mS","use --model-large/--model-small instead");
+ /* Used to select the port */
+ if (_setPort(argv[i] + 2)) {
+ werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
+ }
break;
case 'a' :
/* assembler options */
if (argv[i][2] == 'a') {
if (argv[i][3])
- parseWithComma(asmOptions,&argv[i][3]);
+ parseWithComma((char **)asmOptions,&argv[i][3]);
else
- parseWithComma(asmOptions,argv[++i]);
+ parseWithComma((char **)asmOptions,argv[++i]);
} else {
werror(W_UNKNOWN_OPTION,argv[i]);
else
rest = &argv[i][2] ;
- /* increase allocation for preprocessor argv
- if (!(preArgv = realloc(preArgv,(preArgc+1)*sizeof(char **)))) {
- werror (E_OUT_OF_MEM);
- exit (1);
- } */
if ( argv[i][1] == 'Y' )
argv[i][1] = 'I';
if (argv[i][1] == 'M')
preProcOnly = 1;
- if (!(preArgv[preArgc] = GC_malloc(strlen(rest)+3))) {
- werror(E_OUT_OF_MEM,__FILE__,strlen(rest)+3);
- exit (1);
- }
-
- sprintf(preArgv[preArgc],"-%c%s",sOpt,rest);
- preArgc++ ;
+ sprintf(buffer, "-%c%s", sOpt, rest);
+ _addToList(preArgv, buffer);
}
break ;
default:
- werror(W_UNKNOWN_OPTION,argv[i]);
+ if (!port->parseOption(&argc, argv))
+ werror(W_UNKNOWN_OPTION,argv[i]);
}
continue ;
}
- /* no option must be a filename */
- processFile(argv[i]);
-
-
+ if (!port->parseOption(&argc, argv)) {
+ /* no option must be a filename */
+ processFile(argv[i]);
+ }
}
/* set up external stack location if not explicitly specified */
fprintf(cdbFile,"M:%s\n",moduleName);
}
}
+ port->finaliseOptions();
return 0;
}
static void linkEdit (char **envp)
{
FILE *lnkfile ;
- char *lnkArgs[4];
+ char *argv[128];
+
int i;
if (!srcFileName)
srcFileName = "temp";
fprintf (lnkfile,"\n-e\n");
fclose(lnkfile);
- /* call the linker */
- lnkArgs[0] = "aslink";
- lnkArgs[1] = "-nf";
- lnkArgs[2] = srcFileName;
- lnkArgs[3] = NULL;
+ _buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
- if (my_system("aslink",lnkArgs)) {
+ /* call the linker */
+ if (my_system(argv[0], argv)) {
perror("Cannot exec linker");
exit(1);
}
/*-----------------------------------------------------------------*/
static void assemble (char **envp)
{
- char *asmArgs[128]; /* assembler arguments */
- int i = 2;
+ char *argv[128]; /* assembler arguments */
- asmArgs[0] = "asx8051";
-
-/* if (options.debug) */
- asmArgs[1] = "-plosgffc" ;
-/* else */
-/* asmArgs[1] = "-plosgff"; */
-
- /* add the extra options if any */
- for (; asmOptions[i-2] ; i++)
- asmArgs[i] = asmOptions[i-2];
-
- /* create the assembler file name */
- sprintf (buffer, srcFileName);
- strcat (buffer, ".asm");
- asmArgs[i++] = buffer;
-
- asmArgs[i] = 0; /* end of args */
+ _buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
- if (my_system("asx8051",asmArgs)) {
- perror("Cannot exec linker");
+ if (my_system(argv[0], argv)) {
+ perror("Cannot exec assember");
exit(1);
}
}
+
/*-----------------------------------------------------------------*/
/* preProcess - spawns the preprocessor with arguments */
/*-----------------------------------------------------------------*/
static int preProcess (char **envp)
{
-
+ char *argv[128];
+
+ preOutName = NULL;
+
/* if using external stack define the macro */
if ( options.useXstack )
- preArgv[preArgc++] = "-DSDCC_USE_XSTACK" ;
+ _addToList(preArgv, "-DSDCC_USE_XSTACK");
/* set the macro for stack autos */
if ( options.stackAuto )
- preArgv[preArgc++] = "-DSDCC_STACK_AUTO";
+ _addToList(preArgv, "-DSDCC_STACK_AUTO");
/* set the macro for large model */
if ( options.model )
- preArgv[preArgc++] = "-DSDCC_MODEL_LARGE" ;
+ _addToList(preArgv, "-DSDCC_MODEL_LARGE");
else
- preArgv[preArgc++] = "-DSDCC_MODEL_SMALL" ;
+ _addToList(preArgv, "-DSDCC_MODEL_SMALL");
- preArgv[preArgc++] = fullSrcFileName ;
if (!preProcOnly)
- preArgv[preArgc++] = preOutName = strdup(tmpnam(NULL));
- preArgv[preArgc] = NULL;
+ preOutName = strdup(tmpnam(NULL));
- preArgv[0] = "sdcpp";
+ _buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
+ preOutName, srcFileName, preArgv);
- if (my_system("sdcpp",preArgv)) {
+ if (my_system(argv[0], argv)) {
unlink (preOutName);
perror("Cannot exec Preprocessor");
exit(1);
return 0;
}
+static void _findPort(int argc, char **argv)
+{
+ argc--;
+ while (argc) {
+ if (!strncmp(*argv, "-m", 2)) {
+ _setPort(*argv + 2);
+ return;
+ }
+ argv++;
+ argc--;
+ }
+ /* Use the first in the list */
+ port = _ports[0];
+}
+
/*
* main routine
* initialises and calls the parser
/*printVersionInfo ();*/
+ _findPort(argc, argv);
setDefaultOptions();
- parseCmdLine (argc,argv);
+ parseCmdLine(argc,argv);
/* if no input then printUsage & exit */
if (!srcFileName && !nrelFiles) {