what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
#include <signal.h>
#include "common.h"
#include <ctype.h>
#include <unistd.h>
#endif
-//REMOVE ME!!!
-extern int yyparse ();
+/* REMOVE ME!!! */
+extern int yyparse (void);
FILE *srcFile; /* source file */
char *fullSrcFileName; /* full name for the source file; */
char *dstPath = ""; /* path for the output files; */
/* "" is equivalent with cwd */
char *moduleName; /* module name is source file without path and extension */
- /* can be NULL while linking without compiling */
-/*
- * in following definitions fixed length arrays are very dangerous!
- * Sets should be used instead. See definition of asmOptions.
- */
-const char *preArgv[128]; /* pre-processor arguments */
+ /* can be NULL while linking without compiling */
int currRegBank = 0;
-int RegBankUsed[4]={1, 0, 0, 0}; /*JCF: Reg Bank 0 used by default*/
+int RegBankUsed[4] = {1, 0, 0, 0}; /*JCF: Reg Bank 0 used by default*/
struct optimize optimize;
struct options options;
int preProcOnly = 0;
int noAssemble = 0;
-set *asmOptions = NULL; /* set of assembler options */
-set /*char*/ *linkOptions=NULL; /* set of linker options [128]; */
-char *libFiles[128];
-int nlibFiles = 0;
-char *libPaths[128];
-int nlibPaths = 0;
-char *relFiles[128];
-int nrelFiles = 0;
+set *preArgvSet = NULL; /* pre-processor arguments */
+set *asmOptionsSet = NULL; /* set of assembler options */
+set *linkOptionsSet = NULL; /* set of linker options */
+set *libFilesSet = NULL;
+set *libPathsSet = NULL;
+set *relFilesSet = NULL;
+set *dataDirsSet = NULL; /* list of data search directories */
+set *includeDirsSet = NULL; /* list of include search directories */
+set *libDirsSet = NULL; /* list of lib search directories */
/* uncomment JAMIN_DS390 to always override and use ds390 port
for mcs51 work. This is temporary, for compatibility testing. */
int ds390_jammed = 0;
#endif
-// Globally accessible scratch buffer for file names.
+/* Globally accessible scratch buffer for file names. */
char scratchFileName[PATH_MAX];
char buffer[PATH_MAX * 2];
#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"
static const OPTION
optionsTable[] = {
{ 0, OPTION_PEEP_FILE, NULL, "<file> use this extra peep-hole file" },
{ 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
{ 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 floar support functions" },
+ { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the float support functions" },
{ 0, OPTION_OUT_FMT_IHX, NULL, NULL },
{ 0, "--out-fmt-s19", &options.out_fmt, NULL },
{ 0, "--cyclomatic", &options.cyclomatic, NULL },
{ 0, OPTION_ICODE_IN_ASM, &options.iCodeInAsm, "include i-code as comments in the asm 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"},
+#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
/* End of options */
{ 0, NULL }
};
#if !OPT_DISABLE_DS390
&ds390_port,
#endif
-#if !OPT_DISABLE_PIC
- &pic_port,
-#endif
#if !OPT_DISABLE_PIC16
&pic16_port,
#endif
+#if !OPT_DISABLE_PIC
+ &pic_port,
+#endif
#if !OPT_DISABLE_TININative
&tininative_port,
#endif
#endif
#if !OPT_DISABLE_DS400
&ds400_port,
-#endif
+#endif
+#if !OPT_DISABLE_HC08
+ &hc08_port,
+#endif
};
#define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
-#if !OPT_DISABLE_PIC
-extern void picglue ();
-#endif
-#if !OPT_DISABLE_PIC16
-extern void pic16glue();
-#endif
-
/** Sets the port to the one given by the command line option.
@param The name minus the option (eg 'mcs51')
@return 0 on success.
/* printVersionInfo - prints the version info */
/*-----------------------------------------------------------------*/
void
-printVersionInfo ()
+printVersionInfo (void)
{
int i;
fprintf (stderr,
"SDCC : ");
- for (i = 0; i < NUM_PORTS; i++)
+ for (i = 0; i < NUM_PORTS; i++) {
fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
-
+#ifdef DEFAULT_PORT
+ fprintf(stderr, "%s", (&DEFAULT_PORT == _ports[i])?"*":"");
+#endif
+ }
+
fprintf (stderr, " " SDCC_VERSION_STR
#ifdef SDCC_SUB_VERSION_STR
"/" SDCC_SUB_VERSION_STR
/* printUsage - prints command line syntax */
/*-----------------------------------------------------------------*/
void
-printUsage ()
+printUsage (void)
{
int i;
printVersionInfo();
exit (0);
}
-/*-----------------------------------------------------------------*/
-/* parseWithComma - separates string with comma */
-/*-----------------------------------------------------------------*/
-void
-parseWithComma (char **dest, char *src)
-{
- int i = 0;
-
- strtok (src, "\r\n \t");
- /* skip the initial white spaces */
- while (isspace (*src))
- src++;
- dest[i++] = src;
- while (*src)
- {
- if (*src == ',')
- {
- *src = '\0';
- src++;
- if (*src)
- dest[i++] = src;
- continue;
- }
- src++;
- }
-}
-
/*-----------------------------------------------------------------*/
/* setParseWithComma - separates string with comma to a set */
/*-----------------------------------------------------------------*/
setParseWithComma (set **dest, char *src)
{
char *p;
+ int length;
/* skip the initial white spaces */
- while (isspace (*src))
+ while (isspace(*src))
src++;
+
+ /* skip the trailing white spaces */
+ length = strlen(src);
+ while (length && isspace(src[length-1]))
+ src[--length] = '\0';
- if ((p = strtok(src, ",")) != NULL) {
- do
- {
- addSet(dest, p);
- } while ((p = strtok(NULL, ",")) != NULL);
- }
+ for (p = strtok(src, ","); p != NULL; p = strtok(NULL, ","))
+ addSet(dest, Safe_strdup(p));
}
/*-----------------------------------------------------------------*/
/* setDefaultOptions - sets the default options */
/*-----------------------------------------------------------------*/
static void
-setDefaultOptions ()
+setDefaultOptions (void)
{
- int i;
-
- for (i = 0; i < 128; i++)
- preArgv[i] = /*linkOptions[i] = */relFiles[i] = libFiles[i] = libPaths[i] = NULL;
-
/* first the options part */
options.stack_loc = 0; /* stack pointer initialised to 0 */
options.xstack_loc = 0; /* xternal stack starts at 0 */
strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
strcmp (fext, port->linker.rel_ext) == 0)
{
- relFiles[nrelFiles++] = s;
+ addSet(&relFilesSet, Safe_strdup(s));
return;
}
/* if .lib or .LIB */
if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
{
- libFiles[nlibFiles++] = s;
+ addSet(&libFilesSet, Safe_strdup(s));
return;
}
/** Gets the string argument to this option. If the option is '--opt'
then for input of '--optxyz' or '--opt xyz' returns xyz.
*/
-static char *
+char *
getStringArg(const char *szStart, char **argv, int *pi, int argc)
{
if (argv[*pi][strlen(szStart)])
/** Gets the integer argument to this option using the same rules as
getStringArg.
*/
-static int
+int
getIntArg(const char *szStart, char **argv, int *pi, int argc)
{
return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
if (argv[*pi][1] == '-')
{
- // Long option.
+ /* Long option. */
longOpt = argv[*pi];
}
else
{
if (unsupportedOptTable[i].shortOpt == shortOpt ||
(longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
- // Found an unsupported opt.
+ /* Found an unsupported opt. */
char buffer[100];
SNPRINTF(buffer, sizeof(buffer),
"%s%c%c",
return 1;
}
}
- // Didn't find in the table
+ /* Didn't find in the table */
return 0;
}
else
{
- // Not an option, so can't be unsupported :)
+ /* Not an option, so can't be unsupported :) */
return 0;
}
}
strcmp(optionsTable[i].longOpt, longOpt) == 0))
{
- // If it is a flag then we can handle it here
+ /* If it is a flag then we can handle it here */
if (optionsTable[i].pparameter != NULL)
{
if (optionsTable[i].shortOpt == shortOpt)
return 1;
}
else {
- // Not a flag. Handled manually later.
+ /* Not a flag. Handled manually later. */
return 0;
}
}
}
- // Didn't find in the table
+ /* Didn't find in the table */
return 0;
}
if (argv[*pi][1] == '-')
{
- // Long option.
+ /* Long option. */
longOpt = argv[*pi];
}
else
}
else
{
- // Not an option, so can't be handled.
+ /* Not an option, so can't be handled. */
return 0;
}
}
if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
{
- libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i, argc);
+ addSet(&libPathsSet, Safe_strdup(getStringArg(OPTION_LIB_PATH, argv, &i, argc)));
continue;
}
if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
{
- parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
+ setParseWithComma(&options.calleeSavesSet, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
continue;
}
break;
case 'L':
- libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
+ addSet(&libPathsSet, Safe_strdup(getStringArg("-L", argv, &i, argc)));
break;
case 'l':
- libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
+ addSet(&libFilesSet, Safe_strdup(getStringArg("-l", argv, &i, argc)));
break;
case 'o':
/* pre-processer options */
if (argv[i][2] == 'p')
{
- parseWithComma ((char **)preArgv, getStringArg("-Wp", argv, &i, argc));
+ setParseWithComma(&preArgvSet, getStringArg("-Wp", argv, &i, argc));
}
/* linker options */
else if (argv[i][2] == 'l')
{
- setParseWithComma(&linkOptions, getStringArg("-Wl", argv, &i, argc));
+ setParseWithComma(&linkOptionsSet, getStringArg("-Wl", argv, &i, argc));
}
/* assembler options */
else if (argv[i][2] == 'a')
{
- setParseWithComma (&asmOptions, getStringArg("-Wa", argv, &i, argc));
+ setParseWithComma(&asmOptionsSet, getStringArg("-Wa", argv, &i, argc));
}
else
{
case 'M':
{
preProcOnly = 1;
- addToList (preArgv, "-M");
- break;
+ if (argv[i][2] == 'M')
+ addSet(&preArgvSet, Safe_strdup("-MM"));
+ else
+ addSet(&preArgvSet, Safe_strdup("-M"));
+ break;
}
case 'C':
{
- addToList (preArgv, "-C");
+ addSet(&preArgvSet, Safe_strdup("-C"));
break;
}
SNPRINTF (buffer, sizeof(buffer),
((sOpt == 'I') ? "-%c\"%s\"": "-%c%s"), sOpt, rest);
- addToList (preArgv, buffer);
+ addSet(&preArgvSet, Safe_strdup(buffer));
}
break;
/* some sanity checks in c1 mode */
if (options.c1mode)
{
- int i;
+ const char *s;
if (fullSrcFileName)
{
werror (W_NO_FILE_ARG_IN_C1, fullSrcFileName);
}
fullSrcFileName = NULL;
- for (i = 0; i < nrelFiles; ++i)
+ for (s = setFirstItem(relFilesSet); s != NULL; s = setNextItem(relFilesSet))
{
- werror (W_NO_FILE_ARG_IN_C1, relFiles[i]);
+ werror (W_NO_FILE_ARG_IN_C1, s);
}
- for (i = 0; i < nlibFiles; ++i)
+ for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
{
- werror (W_NO_FILE_ARG_IN_C1, libFiles[i]);
+ werror (W_NO_FILE_ARG_IN_C1, s);
}
- nrelFiles = nlibFiles = 0;
- if (options.cc_only || noAssemble || preProcOnly)
+ deleteSet(&relFilesSet);
+ deleteSet(&libFilesSet);
+
+ if (options.cc_only || noAssemble || preProcOnly)
{
werror (W_ILLEGAL_OPT_COMBINATION);
}
/* if no dstFileName given with -o, we've to find one: */
if (!dstFileName)
{
+ const char *s;
+
/* use the modulename from the C-source */
if (fullSrcFileName)
{
strncatz (dstFileName, moduleName, bufSize);
}
/* use the modulename from the first object file */
- else if (nrelFiles >= 1)
+ else if ((s = peekSet(relFilesSet)) != NULL)
{
char *objectName;
size_t bufSize;
- strncpyz (buffer, relFiles[0], sizeof(buffer));
+ strncpyz (buffer, s, sizeof(buffer));
/* remove extension (it must be .rel) */
*strrchr (buffer, '.') = '\0';
/* remove path */
if (options.debug && fullSrcFileName)
{
SNPRINTF (scratchFileName, sizeof(scratchFileName),
- "%s.adb", dstFileName); //JCF: Nov 30, 2002
+ "%s.adb", dstFileName); /*JCF: Nov 30, 2002*/
if(debugFile->openFile(scratchFileName))
debugFile->writeModule(moduleName);
else
werror (E_FILE_OPEN_ERR, scratchFileName);
}
+ MSVC_style(options.vc_err_style);
+ if(options.use_stdout) dup2(STDOUT_FILENO, STDERR_FILENO);
+
return 0;
}
{
FILE *lnkfile;
char *segName, *c;
- int i, system_ret;
+ int system_ret;
+ const char *s;
/* first we need to create the <filename>.lnk file */
SNPRINTF (scratchFileName, sizeof(scratchFileName),
exit (1);
}
- /* now write the options. JCF: added option 'y' */
- fprintf (lnkfile, "-myux%c\n", (options.out_fmt ? 's' : 'i'));
-
- /* if iram size specified */
- if (options.iram_size)
- fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
-
- /* if xram size specified */
- if (options.xram_size_set)
- fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
-
- /* if code size specified */
- if (options.code_size)
- fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
-
- if (options.debug)
- fprintf (lnkfile, "-z\n");
+ if (TARGET_IS_Z80 || TARGET_IS_GBZ80)
+ {
+ fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
+ (options.out_fmt ? 's' : 'i'), dstFileName);
+ }
+ else /*For all the other ports. Including pics???*/
+ {
+ fprintf (lnkfile, "-myux%c\n", (options.out_fmt ? 's' : 'i'));
+ }
+
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+ {
+ /* if iram size specified */
+ if (options.iram_size)
+ fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
+
+ /* if xram size specified */
+ if (options.xram_size_set)
+ fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
+
+ /* if code size specified */
+ if (options.code_size)
+ fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
+
+ if (options.debug)
+ fprintf (lnkfile, "-z\n");
+ }
#define WRITE_SEG_LOC(N, L) \
segName = Safe_strdup(N); \
fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
if (segName) { Safe_free(segName); }
- /* code segment start */
- WRITE_SEG_LOC (CODE_NAME, options.code_loc);
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+ {
- /* data segment start */
- if(options.data_loc){ /*JCF: If zero, the linker chooses the best place for data*/
- WRITE_SEG_LOC (DATA_NAME, options.data_loc);
- }
+ /* code segment start */
+ WRITE_SEG_LOC (CODE_NAME, options.code_loc);
- /* xdata start */
- WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
+ /* data segment start. If zero, the linker chooses
+ the best place for data*/
+ if(options.data_loc){
+ WRITE_SEG_LOC (DATA_NAME, options.data_loc);
+ }
- /* indirect data */
- if (IDATA_NAME) {
- WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
- }
+ /* xdata start */
+ WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
- /* bit segment start */
- WRITE_SEG_LOC (BIT_NAME, 0);
+ /* indirect data */
+ if (IDATA_NAME) {
+ WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+ }
- /* JCF: stack start */
- if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
- WRITE_SEG_LOC ("SSEG", options.stack_loc);
+ /* bit segment start */
+ WRITE_SEG_LOC (BIT_NAME, 0);
+
+ /* stack start */
+ if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
+ WRITE_SEG_LOC ("SSEG", options.stack_loc);
+ }
+ }
+ else /*For the z80, gbz80*/
+ {
+ WRITE_SEG_LOC ("_CODE", options.code_loc);
+ WRITE_SEG_LOC ("_DATA", options.data_loc);
+ }
+
+ /* If the port has any special linker area declarations, get 'em */
+ if (port->extraAreas.genExtraAreaLinkOptions)
+ {
+ port->extraAreas.genExtraAreaLinkOptions(lnkfile);
}
/* add the extra linker options */
- for (i = 0; i<elementsInSet(linkOptions); i++)
- fprintf (lnkfile, "%s\n", (char *)indexSet(linkOptions, i));
-
- /* other library paths if specified */
- for (i = 0; i < nlibPaths; i++)
- fprintf (lnkfile, "-k %s\n", libPaths[i]);
+ fputStrSet(lnkfile, linkOptionsSet);
+ /* other library paths if specified */
+ for (s = setFirstItem(libPathsSet); s != NULL; s = setNextItem(libPathsSet))
+ fprintf (lnkfile, "-k %s\n", s);
+
/* standard library path */
- if (!options.nostdlib)
+ if (!options.nostdlib)
{
- switch (options.model)
- {
- case MODEL_SMALL:
- c = "small";
- break;
- case MODEL_LARGE:
- c = "large";
- break;
- case MODEL_FLAT24:
- /* c = "flat24"; */
- if (TARGET_IS_DS390)
- {
- c = "ds390";
- }
- else if (TARGET_IS_DS400)
- {
- c = "ds400";
- }
- else
- {
- fprintf(stderr,
- "Add support for your FLAT24 target in %s @ line %d\n",
- __FILE__, __LINE__);
- exit(-1);
- }
- break;
- case MODEL_PAGE0:
- c = "xa51";
- break;
- default:
- werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
- c = "unknown";
- break;
- }
- mfprintf (lnkfile, getRuntimeVariables(), "-k {libdir}{sep}%s\n", c);
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+ {
+ switch (options.model)
+ {
+ case MODEL_SMALL:
+ c = "small";
+ break;
+ case MODEL_LARGE:
+ c = "large";
+ break;
+ case MODEL_FLAT24:
+ /* c = "flat24"; */
+ if (TARGET_IS_DS390)
+ {
+ c = "ds390";
+ }
+ else if (TARGET_IS_DS400)
+ {
+ c = "ds400";
+ }
+ else
+ {
+ fprintf(stderr,
+ "Add support for your FLAT24 target in %s @ line %d\n",
+ __FILE__, __LINE__);
+ exit(-1);
+ }
+ break;
+ case MODEL_PAGE0:
+ c = "xa51";
+ break;
+ default:
+ werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
+ c = "unknown";
+ break;
+ }
+ }
+ else /*for the z80, gbz80*/
+ {
+ if (TARGET_IS_HC08)
+ c = "hc08";
+ else if (TARGET_IS_Z80)
+ c = "z80";
+ else
+ c = "gbz80";
+ }
+ for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
+ mfprintf (lnkfile, getRuntimeVariables(), "-k %s{sep}%s\n", s, c);
+
/* standard library files */
#if !OPT_DISABLE_DS390
- if (options.model == MODEL_FLAT24)
- {
- if (TARGET_IS_DS390)
- {
- fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
- }
- else if (TARGET_IS_DS400)
- {
- fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
- }
- else
- {
- fprintf(stderr,
- "Add support for your FLAT24 target in %s @ line %d\n",
- __FILE__, __LINE__);
- exit(-1);
- }
- }
+ if (options.model == MODEL_FLAT24)
+ {
+ if (TARGET_IS_DS390)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
+ }
+ else if (TARGET_IS_DS400)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
+ }
+ else
+ {
+ fprintf(stderr,
+ "Add support for your FLAT24 target in %s @ line %d\n",
+ __FILE__, __LINE__);
+ exit(-1);
+ }
+ }
#endif
#if !OPT_DISABLE_XA51
#ifdef STD_XA51_LIB
- if (options.model == MODEL_PAGE0)
- {
- fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
- }
+ if (options.model == MODEL_PAGE0)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
+ }
#endif
#endif
- fprintf (lnkfile, "-l %s\n", STD_LIB);
- fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
- fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
- fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
+ if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80
+ || 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);
+ fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
+ fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
+ }
+ else if (TARGET_IS_HC08)
+ {
+ fprintf (lnkfile, "-l hc08\n");
+ }
+ else if (TARGET_IS_Z80)
+ {
+ fprintf (lnkfile, "-l z80\n");
+ }
+ else if (TARGET_IS_GBZ80)
+ {
+ fprintf (lnkfile, "-l gbz80\n");
+ }
}
/* additional libraries if any */
- for (i = 0; i < nlibFiles; i++)
- fprintf (lnkfile, "-l %s\n", libFiles[i]);
+ for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
+ fprintf (lnkfile, "-l %s\n", s);
+
+ /*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 && !options.nostdlib) /*For the z80, gbz80*/
+ {
+ char crt0path[PATH_MAX];
+ FILE * crt0fp;
+ for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
+ {
+ sprintf (crt0path, "%s%s%s%scrt0.o",
+ s, DIR_SEPARATOR_STRING, c, DIR_SEPARATOR_STRING);
+
+ crt0fp=fopen(crt0path, "r");
+ if(crt0fp!=NULL)/*Found it!*/
+ {
+ fclose(crt0fp);
+ #ifdef __CYGWIN__
+ {
+ /*The CYGWIN version of the z80-gbz80 linker is getting confused with
+ windows paths, so convert them to the CYGWIN format*/
+ char posix_path[PATH_MAX];
+ void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
+ cygwin_conv_to_full_posix_path(crt0path, posix_path);
+ strcpy(crt0path, posix_path);
+ }
+ #endif
+ fprintf (lnkfile, "%s\n", crt0path);
+ break;
+ }
+ }
+ if(s==NULL) fprintf (stderr, "Warning: couldn't find crt0.o\n");
+ }
/* put in the object files */
if (fullSrcFileName)
fprintf (lnkfile, "%s%s\n", dstFileName, port->linker.rel_ext);
- for (i = 0; i < nrelFiles; i++)
- fprintf (lnkfile, "%s\n", relFiles[i]);
+ fputStrSet(lnkfile, relFilesSet);
fprintf (lnkfile, "\n-e\n");
fclose (lnkfile);
}
else
{
- strncpyz (scratchFileName, relFiles[0], sizeof(scratchFileName));
+ s = peekSet(relFilesSet);
+
+ assert(s);
+
+ strncpyz (scratchFileName, s, sizeof(scratchFileName));
/* strip ".rel" extension */
*strrchr (scratchFileName, '.') = '\0';
}
char buffer2[PATH_MAX];
/* VR 030517 - gplink needs linker options to set the linker script,*/
- buildCmdLine (buffer2, port->linker.cmd, dstFileName, scratchFileName, NULL, linkOptions);
+ buildCmdLine (buffer2, port->linker.cmd, dstFileName, scratchFileName, NULL, linkOptionsSet);
- buildCmdLine2 (buffer, buffer2, sizeof(buffer));
+ buildCmdLine2 (buffer, sizeof(buffer), buffer2);
}
else
{
- buildCmdLine2 (buffer, port->linker.mcmd, sizeof(buffer));
+ buildCmdLine2 (buffer, sizeof(buffer), port->linker.mcmd);
}
-// if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer);
+/* 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 */
}
else
{
- strncpyz (scratchFileName, relFiles[0], sizeof(scratchFileName));
+ s = peekSet(relFilesSet);
+
+ assert(s);
+
+ strncpyz (scratchFileName, s, sizeof(scratchFileName));
/* strip ".rel" extension */
p = strrchr (scratchFileName, '.');
if (p)
strncatz (scratchFileName,
options.out_fmt ? ".S19" : ".ihx",
sizeof(scratchFileName));
+ if (strcmp (fullDstFileName, scratchFileName))
+ unlink (fullDstFileName);
rename (scratchFileName, fullDstFileName);
strncpyz (buffer, fullDstFileName, sizeof(buffer));
strncatz (scratchFileName, ".map", sizeof(scratchFileName));
*q = 0;
strncatz(buffer, ".map", sizeof(buffer));
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
rename (scratchFileName, buffer);
*p = 0;
strncatz (scratchFileName, ".mem", sizeof(scratchFileName));
*q = 0;
strncatz(buffer, ".mem", sizeof(buffer));
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
rename (scratchFileName, buffer);
+ if (options.debug)
+ {
+ *p = 0;
+ strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
+ *q = 0;
+ strncatz(buffer, ".cdb", sizeof(buffer));
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
+ rename (scratchFileName, buffer);
+ /* and the OMF file without extension: */
+ *p = 0;
+ *q = 0;
+ if (strcmp (scratchFileName, buffer))
+ unlink (buffer);
+ rename (scratchFileName, buffer);
+ }
}
if (system_ret)
{
}
if (port->assembler.do_assemble) {
- port->assembler.do_assemble(asmOptions);
+ port->assembler.do_assemble(asmOptionsSet);
return ;
} else if (port->assembler.cmd) {
buildCmdLine (buffer, port->assembler.cmd, dstFileName, scratchFileName,
options.debug ? port->assembler.debug_opts : port->assembler.plain_opts,
- asmOptions);
+ asmOptionsSet);
} else {
- buildCmdLine2 (buffer, port->assembler.mcmd, sizeof(buffer));
+ buildCmdLine2 (buffer, sizeof(buffer), port->assembler.mcmd);
}
if (my_system (buffer)) {
strncatz (scratchFileName,
port->linker.rel_ext,
sizeof(scratchFileName));
+ if (strcmp (scratchFileName, fullDstFileName))
+ unlink (fullDstFileName);
rename (scratchFileName, fullDstFileName);
}
}
}
else
{
+ const char *s;
+ set *inclList = NULL;
+
/* if using external stack define the macro */
if (options.useXstack)
- addToList (preArgv, "-DSDCC_USE_XSTACK");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_USE_XSTACK"));
/* set the macro for stack autos */
if (options.stackAuto)
- addToList (preArgv, "-DSDCC_STACK_AUTO");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_STACK_AUTO"));
/* set the macro for stack autos */
if (options.stack10bit)
- addToList (preArgv, "-DSDCC_STACK_TENBIT");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_STACK_TENBIT"));
/* set the macro for no overlay */
if (options.noOverlay)
- addToList (preArgv, "-DSDCC_NOOVERLAY");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_NOOVERLAY"));
/* set the macro for large model */
switch (options.model)
{
case MODEL_LARGE:
- addToList (preArgv, "-DSDCC_MODEL_LARGE");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_LARGE"));
break;
case MODEL_SMALL:
- addToList (preArgv, "-DSDCC_MODEL_SMALL");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_SMALL"));
break;
case MODEL_COMPACT:
- addToList (preArgv, "-DSDCC_MODEL_COMPACT");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_COMPACT"));
break;
case MODEL_MEDIUM:
- addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_MEDIUM"));
break;
case MODEL_FLAT24:
- addToList (preArgv, "-DSDCC_MODEL_FLAT24");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_FLAT24"));
break;
case MODEL_PAGE0:
- addToList (preArgv, "-DSDCC_MODEL_PAGE0");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_PAGE0"));
break;
default:
werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
}
/* add port (processor information to processor */
- addToList (preArgv, "-DSDCC_{port}");
- addToList (preArgv, "-D__{port}");
+ addSet(&preArgvSet, Safe_strdup("-DSDCC_{port}"));
+ addSet(&preArgvSet, Safe_strdup("-D__{port}"));
/* standard include path */
if (!options.nostdinc) {
- addToList (preArgv, "-I\"{includedir}\"");
+ inclList = appendStrSet(includeDirsSet, "-I\"", "\"");
+ mergeSets(&preArgvSet, inclList);
}
- setMainValue ("cppextraopts", join(preArgv));
+ setMainValue("cppextraopts", (s = joinStrSet(preArgvSet)));
+ Safe_free((void *)s);
+ if (inclList != NULL)
+ deleteSet(&inclList);
if (preProcOnly && fullDstFileName)
{
if (options.verbose)
printf ("sdcc: Calling preprocessor...\n");
- buildCmdLine2 (buffer, _preCmd, sizeof(buffer));
+ buildCmdLine2 (buffer, sizeof(buffer), _preCmd);
if (preProcOnly) {
if (my_system (buffer)) {
}
if (options.printSearchDirs) {
- printf("programs: ");
- if (NULL != (p = (char *)setFirstItem(binPathSet))) {
- printf("%s", p);
- while (NULL != (p = (char *)setNextItem(binPathSet)))
- printf(":%s", p);
- }
- putchar('\n');
+ printf("programs:\n");
+ fputStrSet(stdout, binPathSet);
}
}
/* Set system include path */
static void
-setIncludePath(const char *datadir)
+setIncludePath(void)
{
char *p;
- char buf[PATH_MAX];
/*
* Search logic:
* 4. - DATADIR/INCLUDE_DIR_SUFFIX (only on *nix)
*/
- if ((p = getenv(SDCC_INCLUDE_NAME)) == NULL) {
- SNPRINTF(buf, sizeof buf, "%s" INCLUDE_DIR_SUFFIX, datadir);
- p = buf;
- }
+ includeDirsSet = appendStrSet(dataDirsSet, NULL, INCLUDE_DIR_SUFFIX);
- if (options.printSearchDirs)
- printf("includedir: %s\n", p);
+ if ((p = getenv(SDCC_INCLUDE_NAME)) != NULL)
+ addSetHead(&includeDirsSet, p);
- setMainValue ("includedir", p);
+ if (options.printSearchDirs) {
+ printf("includedir:\n");
+ fputStrSet(stdout, includeDirsSet);
+ }
}
/* Set system lib path */
static void
-setLibPath(const char *datadir)
+setLibPath(void)
{
char *p;
- char buf[PATH_MAX];
/*
* Search logic:
* 4. - DATADIR/LIB_DIR_SUFFIX/<model> (only on *nix)
*/
- if ((p = getenv(SDCC_LIB_NAME)) == NULL) {
- SNPRINTF(buf, sizeof buf, "%s" LIB_DIR_SUFFIX, datadir);
- p = buf;
- }
+ libDirsSet = appendStrSet(dataDirsSet, NULL, LIB_DIR_SUFFIX);
- if (options.printSearchDirs)
- printf("libdir: %s\n", p);
+ if ((p = getenv(SDCC_LIB_NAME)) != NULL)
+ addSetHead(&libDirsSet, p);
- setMainValue ("libdir", p);
+ if (options.printSearchDirs) {
+ printf("libdir:\n");
+ fputStrSet(stdout, libDirsSet);
+ }
}
/* Set data path */
if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
SNPRINTF(buf, sizeof buf, "%s" PREFIX2DATA_DIR, p);
- p = buf;
+ addSet(&dataDirsSet, Safe_strdup(buf));
}
- else if ((p = getBinPath(argv0)) != NULL) {
+
+ if ((p = getBinPath(argv0)) != NULL) {
SNPRINTF(buf, sizeof buf, "%s" BIN2DATA_DIR, p);
- p = buf;
+ addSet(&dataDirsSet, Safe_strdup(buf));
}
+
#ifdef _WIN32
- else {
+ if (peekSet(dataDirsSet) == NULL) {
/* this should never happen... */
wassertl(0, "Can't get binary path");
- p = ".";
}
#else
- if (!pathExists(p))
- p = DATADIR; /* last resort */
+ addSet(&dataDirsSet, Safe_strdup(DATADIR));
#endif
- if (options.printSearchDirs)
- printf("datadir: %s\n", p);
-
- setIncludePath(p);
- setLibPath(p);
+ if (options.printSearchDirs) {
+ printf("datadir:\n");
+ fputStrSet(stdout, dataDirsSet);
+ }
- setMainValue ("datadir", p);
+ setIncludePath();
+ setLibPath();
}
static void
setDataPaths(argv[0]);
/* if no input then printUsage & exit */
- if (!options.c1mode && !fullSrcFileName && !nrelFiles) {
+ if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL) {
if (!options.printSearchDirs)
printUsage();
exit (1);
}
- if (TARGET_IS_PIC) {
- /* TSD PIC port hack - if the PIC port option is enabled
- and SDCC is used to generate PIC code, then we will
- generate .asm files in gpasm's format instead of SDCC's
- assembler's format
- */
-#if !OPT_DISABLE_PIC
- picglue ();
-#endif
+ if (port->general.do_glue != NULL)
+ (*port->general.do_glue)();
+ else
+ {
+ /* this shouldn't happen */
+ assert(FALSE);
+ /* in case of NDEBUG */
+ glue();
+ }
- } else
- if(TARGET_IS_PIC16) {
- /* PIC16 port misc improvements Vangelis Rokas - 6-May-2003
- Generate .asm files for gpasm (just like PIC target) but use
- pic16glue()
- */
-
-#if !OPT_DISABLE_PIC16
- pic16glue();
-#endif
- } else {
- glue ();
+ if (fatalError) {
+ exit (1);
}
if (!options.c1mode && !noAssemble)
!fatalError &&
!noAssemble &&
!options.c1mode &&
- (fullSrcFileName || nrelFiles))
+ (fullSrcFileName || peekSet(relFilesSet) != NULL))
{
if (port->linker.do_link)
port->linker.do_link ();