1 /*-------------------------------------------------------------------------
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
38 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
43 extern int yyparse ();
45 FILE *srcFile; /* source file */
46 FILE *cdbFile = NULL; /* debugger information output file */
47 char *fullSrcFileName; /* full name for the source file */
48 char *srcFileName; /* source file name with the .c stripped */
49 char *moduleName; /* module name is srcFilename stripped of any path */
50 const char *preArgv[128]; /* pre-processor arguments */
52 struct optimize optimize;
53 struct options options;
54 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
57 char *linkOptions[128];
58 const char *asmOptions[128];
65 bool verboseExec = FALSE;
68 // Globally accessible scratch buffer for file names.
69 char scratchFileName[FILENAME_MAX];
71 // In MSC VC6 default search path for exe's to path for this
73 char DefaultExePath[128];
75 #define OPTION_HELP "-help"
77 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
79 #define OPTION_STACK_8BIT "--stack-8bit"
80 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
81 #define OPTION_LARGE_MODEL "--model-large"
82 #define OPTION_MEDIUM_MODEL "--model-medium"
83 #define OPTION_SMALL_MODEL "--model-small"
84 #define OPTION_FLAT24_MODEL "--model-flat24"
85 #define OPTION_DUMP_ALL "--dumpall"
86 #define OPTION_PEEP_FILE "--peep-file"
87 #define OPTION_LIB_PATH "--lib-path"
88 #define OPTION_XSTACK_LOC "--xstack-loc"
89 #define OPTION_CALLEE_SAVES "--callee-saves"
90 #define OPTION_STACK_LOC "--stack-loc"
91 #define OPTION_XRAM_LOC "--xram-loc"
92 #define OPTION_IRAM_SIZE "--iram-size"
93 #define OPTION_VERSION "--version"
94 #define OPTION_DATA_LOC "--data-loc"
95 #define OPTION_CODE_LOC "--code-loc"
96 #define OPTION_IDATA_LOC "--idata-loc"
97 #define OPTION_NO_LOOP_INV "--noinvariant"
98 #define OPTION_NO_LOOP_IND "--noinduction"
99 #define OPTION_LESS_PEDANTIC "--lesspedantic"
100 #define OPTION_NO_GCSE "--nogcse"
101 #define OPTION_SHORT_IS_8BITS "--short-is-8bits"
103 /** Table of all options supported by all ports.
105 * A reference for all options.
106 * An easy way to maintain help for the options.
107 * Automatic support for setting flags on simple options.
110 /** The short option character e.g. 'h' for -h. 0 for none. */
112 /** Long option e.g. "--help". Includes the -- prefix. NULL for
115 /** Pointer to an int that will be incremented every time the
116 option is encountered. May be NULL.
119 /** Help text to go with this option. May be NULL. */
125 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
126 { 'd', NULL, NULL, NULL },
127 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
128 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
129 { 'A', NULL, NULL, NULL },
130 { 'U', NULL, NULL, NULL },
131 { 'C', NULL, NULL, "Preprocessor option" },
132 { 'M', NULL, NULL, "Preprocessor option" },
133 { 'V', NULL, &verboseExec, "Execute verbosely. Show sub commands as they are run" },
134 { 'S', NULL, &noAssemble, "Assemble only" },
135 { 'W', NULL, NULL, "Pass through options to the assembler (a) or linker (l)" },
136 { 'L', NULL, NULL, "Add the next field to the library search path" },
137 { 'l', NULL, NULL, "Include the given library in the link" },
138 { 0, OPTION_LARGE_MODEL, NULL, "external data space is used" },
139 { 0, OPTION_MEDIUM_MODEL, NULL, "not supported" },
140 { 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" },
141 { 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" },
142 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
143 { 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" },
144 { 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" },
145 { 0, "--xstack", &options.useXstack, "Use external stack" },
146 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
147 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
148 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
149 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
150 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
151 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
152 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or link" },
153 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
154 { 0, "--dumpgcse", &options.dump_gcse, NULL },
155 { 0, "--dumploop", &options.dump_loop, NULL },
156 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
157 { 0, "--dumpliverange", &options.dump_range, NULL },
158 { 0, "--dumpregpack", &options.dump_pack, NULL },
159 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
160 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
161 { 0, OPTION_XRAM_LOC, NULL, "<nnnn> External Ram start location" },
162 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
163 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
164 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
165 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
166 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
167 { 0, OPTION_IDATA_LOC, NULL, NULL },
168 { 0, OPTION_PEEP_FILE, NULL, "<file> use this extra peep-hole file" },
169 { 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
170 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
171 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
172 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
173 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
174 { 0, "--cyclomatic", &options.cyclomatic, NULL },
175 { 0, "--nooverlay", &options.noOverlay, NULL },
176 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
177 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
178 { 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
179 { 0, "--peep-asm", &options.asmpeep, NULL },
180 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
181 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
182 { 0, "--stack-after-data", &options.stackOnData, "initialize the stackpointer with the last byte use in DSEG" },
183 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
184 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
185 { 0, "--help", NULL, "Display this help" },
186 { 0, OPTION_CALLEE_SAVES, NULL, "<func[,func,...]> Cause the called function to save registers insted of the caller" },
187 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
188 { 0, "--nostdinc", &options.nostdinc, "Do not include the standard include directory in the search path" },
189 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
190 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
191 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }
194 /** Table of all unsupported options and help text to display when one
198 /** shortOpt as in OPTIONS. */
200 /** longOpt as in OPTIONS. */
202 /** Message to display inside W_UNSUPPORTED_OPT when this option
207 static const UNSUPPORTEDOPT
208 unsupportedOptTable[] = {
209 { 'a', NULL, "use --stack-auto instead." },
210 { 'g', NULL, "use --generic instead" },
211 { 'X', NULL, "use --xstack-loc instead" },
212 { 'x', NULL, "use --xstack instead" },
213 { 'p', NULL, "use --stack-loc instead" },
214 { 'P', NULL, "use --stack-loc instead" },
215 { 'i', NULL, "use --idata-loc instead" },
216 { 'r', NULL, "use --xdata-loc instead" },
217 { 's', NULL, "use --code-loc instead" },
218 { 'Y', NULL, "use -I instead" }
221 static const char *_preCmd[] =
223 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
224 "$l", "$1", "$2", NULL
229 static PORT *_ports[] =
231 #if !OPT_DISABLE_MCS51
234 #if !OPT_DISABLE_GBZ80
243 #if !OPT_DISABLE_DS390
249 #if !OPT_DISABLE_I186
252 #if !OPT_DISABLE_TLCS900H
257 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
260 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
262 extern void picglue ();
264 /** Sets the port to the one given by the command line option.
265 @param The name minus the option (eg 'mcs51')
266 @return 0 on success.
269 _setPort (const char *name)
272 for (i = 0; i < NUM_PORTS; i++)
274 if (!strcmp (_ports[i]->target, name))
280 /* Error - didnt find */
281 werror (E_UNKNOWN_TARGET, name);
286 _validatePorts (void)
289 for (i = 0; i < NUM_PORTS; i++)
291 if (_ports[i]->magic != PORT_MAGIC)
293 wassertl (0, "Port definition structure is incomplete");
297 /*-----------------------------------------------------------------*/
298 /* printVersionInfo - prints the version info */
299 /*-----------------------------------------------------------------*/
307 for (i = 0; i < NUM_PORTS; i++)
308 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
310 fprintf (stderr, " %s"
311 #ifdef SDCC_SUB_VERSION_STR
312 "/" SDCC_SUB_VERSION_STR
320 #if defined(_MSC_VER)
332 /*-----------------------------------------------------------------*/
333 /* printUsage - prints command line syntax */
334 /*-----------------------------------------------------------------*/
341 "Usage : sdcc [options] filename\n"
345 for (i = 0; i < LENGTH(optionsTable); i++) {
346 fprintf(stdout, " %c%c %-20s %s\n",
347 optionsTable[i].shortOpt !=0 ? '-' : ' ',
348 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
349 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
350 optionsTable[i].help != NULL ? optionsTable[i].help : ""
356 /*-----------------------------------------------------------------*/
357 /* parseWithComma - separates string with comma */
358 /*-----------------------------------------------------------------*/
360 parseWithComma (char **dest, char *src)
364 strtok (src, "\r\n \t");
365 /* skip the initial white spaces */
366 while (isspace (*src))
383 /*-----------------------------------------------------------------*/
384 /* setDefaultOptions - sets the default options */
385 /*-----------------------------------------------------------------*/
391 for (i = 0; i < 128; i++)
392 preArgv[i] = asmOptions[i] =
393 linkOptions[i] = relFiles[i] = libFiles[i] =
396 /* first the options part */
397 options.stack_loc = 0; /* stack pointer initialised to 0 */
398 options.xstack_loc = 0; /* xternal stack starts at 0 */
399 options.code_loc = 0; /* code starts at 0 */
400 options.data_loc = 0x0030; /* data starts at 0x0030 */
401 options.xdata_loc = 0;
402 options.idata_loc = 0x80;
403 options.genericPtr = 1; /* default on */
405 options.model = port->general.default_model;
406 options.nostdlib = 0;
407 options.nostdinc = 0;
409 options.shortis8bits = 0;
411 options.stack10bit=0;
413 /* now for the optimizations */
414 /* turn on the everything */
415 optimize.global_cse = 1;
420 optimize.loopInvariant = 1;
421 optimize.loopInduction = 1;
423 /* now for the ports */
424 port->setDefaultOptions ();
427 /*-----------------------------------------------------------------*/
428 /* processFile - determines the type of file from the extension */
429 /*-----------------------------------------------------------------*/
431 processFile (char *s)
435 /* get the file extension */
436 fext = s + strlen (s);
437 while ((fext != s) && *fext != '.')
440 /* now if no '.' then we don't know what the file type is
441 so give a warning and return */
444 werror (W_UNKNOWN_FEXT, s);
448 /* otherwise depending on the file type */
449 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
451 /* source file name : not if we already have a
455 werror (W_TOO_MANY_SRC, s);
459 /* the only source file */
460 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
462 werror (E_FILE_OPEN_ERR, s);
466 /* copy the file name into the buffer */
469 /* get rid of the "." */
470 strtok (buffer, ".");
471 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
472 strcpy (srcFileName, buffer);
474 /* get rid of any path information
475 for the module name; do this by going
476 backwards till we get to either '/' or '\' or ':'
477 or start of buffer */
478 fext = buffer + strlen (buffer);
479 while (fext != buffer &&
480 *(fext - 1) != '\\' &&
481 *(fext - 1) != '/' &&
484 moduleName = Safe_calloc (1, strlen (fext) + 1);
485 strcpy (moduleName, fext);
490 /* if the extention is type .rel or .r or .REL or .R
491 addtional object file will be passed to the linker */
492 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
493 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
494 strcmp (fext, port->linker.rel_ext) == 0)
496 relFiles[nrelFiles++] = s;
500 /* if .lib or .LIB */
501 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
503 libFiles[nlibFiles++] = s;
507 werror (W_UNKNOWN_FEXT, s);
512 _processC1Arg (char *s)
516 if (options.out_name)
518 werror (W_TOO_MANY_SRC, s);
521 options.out_name = strdup (s);
530 _addToList (const char **list, const char *str)
532 /* This is the bad way to do things :) */
535 *list = strdup (str);
538 werror (E_OUT_OF_MEM, __FILE__, 0);
545 _setModel (int model, const char *sz)
547 if (port->general.supported_models & model)
548 options.model = model;
550 werror (W_UNSUPPORTED_MODEL, sz, port->target);
553 /** Gets the string argument to this option. If the option is '--opt'
554 then for input of '--optxyz' or '--opt xyz' returns xyz.
557 getStringArg(const char *szStart, char **argv, int *pi, int argc)
559 if (argv[*pi][strlen(szStart)])
561 return &argv[*pi][strlen(szStart)];
568 werror (E_ARGUMENT_MISSING, szStart);
569 /* Die here rather than checking for errors later. */
579 /** Gets the integer argument to this option using the same rules as
583 getIntArg(const char *szStart, char **argv, int *pi, int argc)
585 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
589 verifyShortOption(const char *opt)
591 if (strlen(opt) != 2)
593 werror (W_EXCESS_SHORT_OPTIONS, opt);
598 tryHandleUnsupportedOpt(char **argv, int *pi)
600 if (argv[*pi][0] == '-')
602 const char *longOpt = "";
606 if (argv[*pi][1] == '-')
613 shortOpt = argv[*pi][1];
615 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
617 if (unsupportedOptTable[i].shortOpt == shortOpt ||
618 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
619 // Found an unsupported opt.
621 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
622 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
626 // Didn't find in the table
631 // Not an option, so can't be unsupported :)
637 tryHandleSimpleOpt(char **argv, int *pi)
639 if (argv[*pi][0] == '-')
641 const char *longOpt = "";
645 if (argv[*pi][1] == '-')
652 shortOpt = argv[*pi][1];
655 for (i = 0; i < LENGTH(optionsTable); i++)
657 if (optionsTable[i].shortOpt == shortOpt ||
658 (longOpt && optionsTable[i].longOpt &&
659 strcmp(optionsTable[i].longOpt, longOpt) == 0))
662 // If it is a flag then we can handle it here
663 if (optionsTable[i].pparameter != NULL)
665 if (optionsTable[i].shortOpt == shortOpt)
667 verifyShortOption(argv[*pi]);
670 (*optionsTable[i].pparameter)++;
674 // Not a flag. Handled manually later.
679 // Didn't find in the table
684 // Not an option, so can't be handled.
689 /*-----------------------------------------------------------------*/
690 /* parseCmdLine - parses the command line and sets the options */
691 /*-----------------------------------------------------------------*/
693 parseCmdLine (int argc, char **argv)
697 /* go thru all whole command line */
698 for (i = 1; i < argc; i++)
703 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
708 if (tryHandleSimpleOpt(argv, &i) == TRUE)
714 if (argv[i][0] == '-' && argv[i][1] == '-')
716 if (strcmp (argv[i], OPTION_HELP) == 0)
722 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
724 options.stack10bit = 0;
728 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
734 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
736 _setModel (MODEL_LARGE, argv[i]);
740 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
742 _setModel (MODEL_MEDIUM, argv[i]);
746 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
748 _setModel (MODEL_SMALL, argv[i]);
752 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
754 _setModel (MODEL_FLAT24, argv[i]);
758 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
760 options.dump_rassgn =
766 options.dump_raw = 1;
770 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
772 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
776 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
778 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i, argc);
782 if (strcmp (argv[i], OPTION_VERSION) == 0)
789 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
791 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
795 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
797 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
801 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
803 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
807 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
809 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
813 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
815 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
819 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
821 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
825 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
827 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
831 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
833 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
837 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
839 optimize.global_cse = 0;
843 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
845 optimize.loopInvariant = 0;
849 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
851 optimize.loopInduction = 0;
855 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
857 setErrorLogLevel(ERROR_LEVEL_WARNING);
861 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
863 options.shortis8bits=1;
867 if (!port->parseOption (&argc, argv, &i))
869 werror (W_UNKNOWN_OPTION, argv[i]);
877 /* if preceded by '-' then option */
883 verifyShortOption(argv[i]);
890 /* Used to select the port */
891 _setPort (argv[i] + 2);
895 verifyShortOption(argv[i]);
901 libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
905 libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
910 if (argv[i][2] == 'l')
912 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
916 /* assembler options */
917 if (argv[i][2] == 'a')
919 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
923 werror (W_UNKNOWN_OPTION, argv[i]);
929 verifyShortOption(argv[i]);
935 /* preprocessor options */
939 _addToList (preArgv, "-M");
944 _addToList (preArgv, "-C");
953 char sOpt = argv[i][1];
956 if (argv[i][2] == ' ' || argv[i][2] == '\0')
962 werror(E_ARGUMENT_MISSING, argv[i-1]);
976 sprintf (buffer, "-%c%s", sOpt, rest);
977 _addToList (preArgv, buffer);
982 if (!port->parseOption (&argc, argv, &i))
983 werror (W_UNKNOWN_OPTION, argv[i]);
988 if (!port->parseOption (&argc, argv, &i))
990 /* no option must be a filename */
992 _processC1Arg (argv[i]);
994 processFile (argv[i]);
998 /* set up external stack location if not explicitly specified */
999 if (!options.xstack_loc)
1000 options.xstack_loc = options.xdata_loc;
1002 /* if debug option is set the open the cdbFile */
1003 if (options.debug && srcFileName)
1005 sprintf (scratchFileName, "%s.cdb", srcFileName);
1006 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1007 werror (E_FILE_OPEN_ERR, scratchFileName);
1010 /* add a module record */
1011 fprintf (cdbFile, "M:%s\n", moduleName);
1017 /*-----------------------------------------------------------------*/
1018 /* linkEdit : - calls the linkage editor with options */
1019 /*-----------------------------------------------------------------*/
1021 linkEdit (char **envp)
1028 srcFileName = "temp";
1030 /* first we need to create the <filename>.lnk file */
1031 sprintf (scratchFileName, "%s.lnk", srcFileName);
1032 if (!(lnkfile = fopen (scratchFileName, "w")))
1034 werror (E_FILE_OPEN_ERR, scratchFileName);
1038 /* now write the options */
1039 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1041 /* if iram size specified */
1042 if (options.iram_size)
1043 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1046 fprintf (lnkfile, "-z\n");
1048 #define WRITE_SEG_LOC(N, L) \
1049 segName = strdup(N); \
1050 c = strtok(segName, " \t"); \
1051 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1052 if (segName) { free(segName); }
1054 /* code segment start */
1055 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1057 /* data segment start */
1058 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1061 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1064 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1066 /* bit segment start */
1067 WRITE_SEG_LOC (BIT_NAME, 0);
1069 /* add the extra linker options */
1070 for (i = 0; linkOptions[i]; i++)
1071 fprintf (lnkfile, "%s\n", linkOptions[i]);
1073 /* other library paths if specified */
1074 for (i = 0; i < nlibPaths; i++)
1075 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1077 /* standard library path */
1078 if (!options.nostdlib)
1080 if (TARGET_IS_DS390)
1086 switch (options.model)
1098 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1103 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1105 /* standard library files */
1106 if (strcmp (port->target, "ds390") == 0)
1108 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1110 fprintf (lnkfile, "-l %s\n", STD_LIB);
1111 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1112 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1113 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1116 /* additional libraries if any */
1117 for (i = 0; i < nlibFiles; i++)
1118 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1120 /* put in the object files */
1121 if (strcmp (srcFileName, "temp"))
1122 fprintf (lnkfile, "%s ", srcFileName);
1124 for (i = 0; i < nrelFiles; i++)
1125 fprintf (lnkfile, "%s\n", relFiles[i]);
1127 fprintf (lnkfile, "\n-e\n");
1130 if (options.verbose)
1131 printf ("sdcc: Calling linker...\n");
1133 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1134 if (my_system (buffer))
1139 if (strcmp (srcFileName, "temp") == 0)
1141 /* rename "temp.cdb" to "firstRelFile.cdb" */
1142 char *f = strtok (strdup (relFiles[0]), ".");
1143 f = strcat (f, ".cdb");
1144 rename ("temp.cdb", f);
1149 /*-----------------------------------------------------------------*/
1150 /* assemble - spawns the assembler with arguments */
1151 /*-----------------------------------------------------------------*/
1153 assemble (char **envp)
1155 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1156 if (my_system (buffer))
1158 /* either system() or the assembler itself has reported an error
1159 perror ("Cannot exec assembler");
1167 /*-----------------------------------------------------------------*/
1168 /* preProcess - spawns the preprocessor with arguments */
1169 /*-----------------------------------------------------------------*/
1171 preProcess (char **envp)
1177 if (!options.c1mode)
1179 /* if using external stack define the macro */
1180 if (options.useXstack)
1181 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1183 /* set the macro for stack autos */
1184 if (options.stackAuto)
1185 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1187 /* set the macro for stack autos */
1188 if (options.stack10bit)
1189 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1191 /* set the macro for large model */
1192 switch (options.model)
1195 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1198 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1201 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1204 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1207 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1210 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1214 /* standard include path */
1215 if (!options.nostdinc) {
1216 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1219 /* add port (processor information to processor */
1220 sprintf (procDef, "-DSDCC_%s", port->target);
1221 _addToList (preArgv, procDef);
1222 sprintf (procDef, "-D__%s", port->target);
1223 _addToList (preArgv, procDef);
1226 preOutName = strdup (tmpnam (NULL));
1228 if (options.verbose)
1229 printf ("sdcc: Calling preprocessor...\n");
1231 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1232 preOutName, srcFileName, preArgv);
1233 if (my_system (buffer))
1235 // @FIX: Dario Vecchio 03-05-2001
1238 unlink (preOutName);
1252 preOutName = fullSrcFileName;
1255 yyin = fopen (preOutName, "r");
1258 perror ("Preproc file not found\n");
1266 _findPort (int argc, char **argv)
1272 if (!strncmp (*argv, "-m", 2))
1274 _setPort (*argv + 2);
1279 /* Use the first in the list */
1285 * initialises and calls the parser
1289 main (int argc, char **argv, char **envp)
1291 /* turn all optimizations off by default */
1292 memset (&optimize, 0, sizeof (struct optimize));
1294 /*printVersionInfo (); */
1297 fprintf (stderr, "Build error: no ports are enabled.\n");
1301 _findPort (argc, argv);
1302 /* Initalise the port. */
1306 // Create a default exe search path from the path to the sdcc command
1310 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1312 strcpy (DefaultExePath, argv[0]);
1313 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1314 ExePathList[0] = DefaultExePath;
1318 setDefaultOptions ();
1319 parseCmdLine (argc, argv);
1323 port->finaliseOptions ();
1325 /* if no input then printUsage & exit */
1326 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1327 (options.c1mode && !srcFileName && !options.out_name))
1342 if (options.verbose)
1343 printf ("sdcc: Generating code...\n");
1349 if (TARGET_IS_PIC) {
1350 /* TSD PIC port hack - if the PIC port option is enabled
1351 and SDCC is used to generate PIC code, then we will
1352 generate .asm files in gpasm's format instead of SDCC's
1355 #if !OPT_DISABLE_PIC
1364 // @FIX: Dario Vecchio 03-05-2001
1367 if (yyin && yyin != stdin)
1369 unlink (preOutName);
1375 if (!options.c1mode && !noAssemble)
1377 if (options.verbose)
1378 printf ("sdcc: Calling assembler...\n");
1384 // @FIX: Dario Vecchio 03-05-2001
1387 if (yyin && yyin != stdin)
1389 unlink (preOutName);
1403 if (!options.cc_only &&
1407 (srcFileName || nrelFiles))
1409 if (port->linker.do_link)
1410 port->linker.do_link ();
1415 if (yyin && yyin != stdin)
1418 if (preOutName && !options.c1mode)
1420 unlink (preOutName);