+ break;
+
+ case 'v':
+ verifyShortOption(argv[i]);
+
+ printVersionInfo (stdout);
+ exit (EXIT_SUCCESS);
+ break;
+
+ /* preprocessor options */
+ case 'M':
+ {
+ preProcOnly = 1;
+ if (argv[i][2] == 'M')
+ addSet(&preArgvSet, Safe_strdup("-MM"));
+ else
+ addSet(&preArgvSet, Safe_strdup("-M"));
+ break;
+ }
+
+ case 'd':
+ case 'D':
+ case 'I':
+ case 'A':
+ case 'U':
+ {
+ char sOpt = argv[i][1];
+ char *rest;
+
+ if (argv[i][2] == ' ' || argv[i][2] == '\0')
+ {
+ i++;
+ if (i >= argc)
+ {
+ /* No argument. */
+ werror(E_ARGUMENT_MISSING, argv[i-1]);
+ break;
+ }
+ else
+ {
+ rest = argv[i];
+ }
+ }
+ else
+ rest = &argv[i][2];
+
+ if (sOpt == 'Y')
+ sOpt = 'I';
+
+ SNPRINTF (buffer, sizeof(buffer),
+ ((sOpt == 'I') ? "-%c\"%s\"": "-%c%s"), sOpt, rest);
+ addSet(&preArgvSet, Safe_strdup(buffer));
+ if(sOpt == 'I') {
+ addSet(&includeDirsSet, Safe_strdup(rest));
+ addSet(&userIncDirsSet, Safe_strdup(rest));
+ }
+ }
+ break;
+
+ default:
+ werror (W_UNKNOWN_OPTION, argv[i]);
+ }
+ continue;
+ }
+
+ /* no option must be a filename */
+ if (options.c1mode)
+ {
+ werror (W_NO_FILE_ARG_IN_C1, argv[i]);
+ }
+ else
+ {
+ processFile (argv[i]);
+ }
+ }
+
+ /* some sanity checks in c1 mode */
+ if (options.c1mode)
+ {
+ const char *s;
+
+ if (fullSrcFileName)
+ {
+ fclose (srcFile);
+ werror (W_NO_FILE_ARG_IN_C1, fullSrcFileName);
+ }
+ fullSrcFileName = NULL;
+ for (s = setFirstItem(relFilesSet); s != NULL; s = setNextItem(relFilesSet))
+ {
+ werror (W_NO_FILE_ARG_IN_C1, s);
+ }
+ for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
+ {
+ werror (W_NO_FILE_ARG_IN_C1, s);
+ }
+ deleteSet(&relFilesSet);
+ deleteSet(&libFilesSet);
+
+ if (options.cc_only || noAssemble || preProcOnly)
+ {
+ werror (W_ILLEGAL_OPT_COMBINATION);
+ }
+ options.cc_only = noAssemble = preProcOnly = 0;
+ if (!dstFileName)
+ {
+ werror (E_NEED_OPT_O_IN_C1);
+ 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: */
+ if (!dstFileName)
+ {
+ const char *s;
+
+ /* use the modulename from the C-source */
+ if (fullSrcFileName)
+ {
+ struct dbuf_s path;
+
+ 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)
+ {
+ 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')
+ {
+ 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
+ {
+ dbuf_c_str (&file);
+ dstFileName = dbuf_detach (&file);
+ }
+ }
+ /* else no module given: help text is displayed */
+ }
+
+ /* set int, long and float reentrancy based on stack-auto */
+ if (options.stackAuto)
+ {
+ options.intlong_rent++;
+ options.float_rent++;
+ }
+
+ /* mcs51 has an assembly coded float library that's always reentrant */
+ 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;
+ }
+
+ /* if debug option is set then open the cdbFile */
+ if (options.debug && fullSrcFileName)
+ {
+ SNPRINTF (scratchFileName, sizeof(scratchFileName),
+ "%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);
+
+ 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 */
+/*-----------------------------------------------------------------*/
+static void
+linkEdit (char **envp)
+{
+ FILE *lnkfile;
+ char *segName, *c;
+ int system_ret;
+ const char *s;
+ char linkerScriptFileName[PATH_MAX];
+
+ linkerScriptFileName[0] = 0;
+ c = NULL;
+
+ if (port->linker.needLinkerScript)
+ {
+ char out_fmt;
+
+ switch (options.out_fmt)
+ {
+ case 0:
+ out_fmt = 'i'; /* Intel hex */
+ break;
+ case 1:
+ out_fmt = 's'; /* Motorola S19 */
+ break;
+ case 2:
+ out_fmt = 't'; /* Elf */
+ break;
+ default:
+ out_fmt = 'i';
+ }
+
+ /* first we need to create the <filename>.lnk file */
+ SNPRINTF (linkerScriptFileName, sizeof(linkerScriptFileName),
+ "%s.lnk", dstFileName);
+ if (!(lnkfile = fopen (linkerScriptFileName, "w")))
+ {
+ werror (E_FILE_OPEN_ERR, linkerScriptFileName);
+ exit (EXIT_FAILURE);
+ }
+
+ if (TARGET_Z80_LIKE)
+ {
+ fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
+ out_fmt, dstFileName);
+ }
+ else /*For all the other ports. Including pics???*/
+ {
+ fprintf (lnkfile, "-myux%c\n", out_fmt);
+ if(!options.no_pack_iram)
+ fprintf (lnkfile, "-Y\n");
+ }
+
+ if (!(TARGET_Z80_LIKE)) /*Not for the z80, gbz80*/
+ {
+ /* if iram size specified */
+ if (options.iram_size)
+ fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
+
+ /* if stack size specified*/
+ if(options.stack_size)
+ fprintf (lnkfile, "-A 0x%02x\n", options.stack_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) \
+ if (N) \
+ { \
+ segName = Safe_strdup(N); \
+ c = strtok(segName, " \t"); \
+ fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
+ if (segName) { Safe_free(segName); } \
+ }
+
+ if (!(TARGET_Z80_LIKE)) /*Not for the z80, gbz80*/
+ {
+
+ /* code segment start */
+ WRITE_SEG_LOC (HOME_NAME, options.code_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);
+ }
+
+ /* xdata segment start. If zero, the linker chooses
+ the best place for xdata */
+ 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)
+ {
+ WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+ }
+
+ /* bit segment start */
+ WRITE_SEG_LOC (BIT_NAME, 0);
+
+ /* stack start */
+ if ( (options.stack_loc) && (options.stack_loc<0x100) &&
+ !TARGET_IS_HC08)
+ {
+ 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 */
+ fputStrSet(lnkfile, linkOptionsSet);
+
+ /* command line defined 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 (!(TARGET_Z80_LIKE || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+ {
+ switch (options.model)
+ {
+ case MODEL_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:
+ if (options.stackAuto)
+ c = "large-stack-auto";
+ else
+ 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 (EXIT_FAILURE);
+ }
+ 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);
+ }
+
+ /* command line defined library files if specified */
+ for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
+ fprintf (lnkfile, "-l %s\n", s);
+
+ /* standard library files */
+ if (!options.nostdlib)
+ {
+#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 (EXIT_FAILURE);
+ }
+ }
+#endif
+
+#if !OPT_DISABLE_XA51
+#ifdef STD_XA51_LIB
+ if (options.model == MODEL_PAGE0)
+ {
+ fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
+ }
+#endif
+#endif
+ if (TARGET_IS_MCS51)
+ {
+ fprintf (lnkfile, "-l mcs51\n");
+ }
+ 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);
+ 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");
+ }
+ }
+
+ /*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_Z80_LIKE) && !options.no_std_crt0) /*For the z80, gbz80*/
+ {
+ char crt0path[PATH_MAX];
+ FILE * crt0fp;
+ set *tempSet=NULL;
+
+ tempSet = appendStrSet(libDirsSet, NULL, DIR_SEPARATOR_STRING);
+ tempSet = appendStrSet(tempSet, NULL, c);
+ mergeSets(&tempSet, libPathsSet);
+
+ for (s = setFirstItem(tempSet); s != NULL; s = setNextItem(tempSet))
+ {
+ sprintf (crt0path, "%s%scrt0.o",
+ s, 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");
+ }