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 /* uncomment JAMIN_DS390 to always override and use ds390 port
69 for mcs51 work. This is temporary, for compatibility testing. */
70 /* #define JAMIN_DS390 */
75 // Globally accessible scratch buffer for file names.
76 char scratchFileName[FILENAME_MAX];
78 // In MSC VC6 default search path for exe's to path for this
80 char DefaultExePath[128];
82 #define OPTION_HELP "-help"
84 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
86 #define OPTION_STACK_8BIT "--stack-8bit"
87 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
88 #define OPTION_LARGE_MODEL "--model-large"
89 #define OPTION_MEDIUM_MODEL "--model-medium"
90 #define OPTION_SMALL_MODEL "--model-small"
91 #define OPTION_FLAT24_MODEL "--model-flat24"
92 #define OPTION_DUMP_ALL "--dumpall"
93 #define OPTION_PEEP_FILE "--peep-file"
94 #define OPTION_LIB_PATH "--lib-path"
95 #define OPTION_XSTACK_LOC "--xstack-loc"
96 #define OPTION_CALLEE_SAVES "--callee-saves"
97 #define OPTION_STACK_LOC "--stack-loc"
98 #define OPTION_XRAM_LOC "--xram-loc"
99 #define OPTION_IRAM_SIZE "--iram-size"
100 #define OPTION_VERSION "--version"
101 #define OPTION_DATA_LOC "--data-loc"
102 #define OPTION_CODE_LOC "--code-loc"
103 #define OPTION_IDATA_LOC "--idata-loc"
104 #define OPTION_NO_LOOP_INV "--noinvariant"
105 #define OPTION_NO_LOOP_IND "--noinduction"
106 #define OPTION_LESS_PEDANTIC "--lesspedantic"
107 #define OPTION_NO_GCSE "--nogcse"
108 #define OPTION_SHORT_IS_8BITS "--short-is-8bits"
110 /** Table of all options supported by all ports.
112 * A reference for all options.
113 * An easy way to maintain help for the options.
114 * Automatic support for setting flags on simple options.
117 /** The short option character e.g. 'h' for -h. 0 for none. */
119 /** Long option e.g. "--help". Includes the -- prefix. NULL for
122 /** Pointer to an int that will be incremented every time the
123 option is encountered. May be NULL.
126 /** Help text to go with this option. May be NULL. */
132 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
133 { 'd', NULL, NULL, NULL },
134 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
135 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
136 { 'A', NULL, NULL, NULL },
137 { 'U', NULL, NULL, NULL },
138 { 'C', NULL, NULL, "Preprocessor option" },
139 { 'M', NULL, NULL, "Preprocessor option" },
140 { 'V', NULL, &verboseExec, "Execute verbosely. Show sub commands as they are run" },
141 { 'S', NULL, &noAssemble, "Compile only; do not assemble or link" },
142 { 'W', NULL, NULL, "Pass through options to the assembler (a) or linker (l)" },
143 { 'L', NULL, NULL, "Add the next field to the library search path" },
144 { 'l', NULL, NULL, "Include the given library in the link" },
145 { 0, OPTION_LARGE_MODEL, NULL, "external data space is used" },
146 { 0, OPTION_MEDIUM_MODEL, NULL, "not supported" },
147 { 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" },
148 { 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" },
149 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
150 { 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" },
151 { 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" },
152 { 0, "--xstack", &options.useXstack, "Use external stack" },
153 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
154 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
155 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
156 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
157 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
158 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
159 { 'c', "--compile-only", &options.cc_only, "Compile and assemble, but do not link" },
160 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
161 { 0, "--dumpgcse", &options.dump_gcse, NULL },
162 { 0, "--dumploop", &options.dump_loop, NULL },
163 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
164 { 0, "--dumpliverange", &options.dump_range, NULL },
165 { 0, "--dumpregpack", &options.dump_pack, NULL },
166 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
167 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
168 { 0, OPTION_XRAM_LOC, NULL, "<nnnn> External Ram start location" },
169 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
170 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
171 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
172 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
173 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
174 { 0, OPTION_IDATA_LOC, NULL, NULL },
175 { 0, OPTION_PEEP_FILE, NULL, "<file> use this extra peep-hole file" },
176 { 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
177 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
178 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
179 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
180 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
181 { 0, "--cyclomatic", &options.cyclomatic, NULL },
182 { 0, "--nooverlay", &options.noOverlay, NULL },
183 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
184 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
185 { 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
186 { 0, "--peep-asm", &options.asmpeep, NULL },
187 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
188 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
189 { 0, "--stack-after-data", &options.stackOnData, "initialize the stackpointer with the last byte use in DSEG" },
190 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
191 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
192 { 0, "--help", NULL, "Display this help" },
193 { 0, OPTION_CALLEE_SAVES, NULL, "<func[,func,...]> Cause the called function to save registers insted of the caller" },
194 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
195 { 0, "--nostdinc", &options.nostdinc, "Do not include the standard include directory in the search path" },
196 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
197 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
198 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" },
199 { 0, "--profile", &options.profile, "On supported ports, generate extra profiling information" }
202 /** Table of all unsupported options and help text to display when one
206 /** shortOpt as in OPTIONS. */
208 /** longOpt as in OPTIONS. */
210 /** Message to display inside W_UNSUPPORTED_OPT when this option
215 static const UNSUPPORTEDOPT
216 unsupportedOptTable[] = {
217 { 'a', NULL, "use --stack-auto instead." },
218 { 'g', NULL, "use --generic instead" },
219 { 'X', NULL, "use --xstack-loc instead" },
220 { 'x', NULL, "use --xstack instead" },
221 { 'p', NULL, "use --stack-loc instead" },
222 { 'P', NULL, "use --stack-loc instead" },
223 { 'i', NULL, "use --idata-loc instead" },
224 { 'r', NULL, "use --xdata-loc instead" },
225 { 's', NULL, "use --code-loc instead" },
226 { 'Y', NULL, "use -I instead" }
229 static const char *_preCmd[] =
231 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
232 "$l", "$1", "$2", NULL
237 static PORT *_ports[] =
239 #if !OPT_DISABLE_MCS51
242 #if !OPT_DISABLE_GBZ80
251 #if !OPT_DISABLE_DS390
257 #if !OPT_DISABLE_I186
260 #if !OPT_DISABLE_TLCS900H
265 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
268 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
270 extern void picglue ();
272 /** Sets the port to the one given by the command line option.
273 @param The name minus the option (eg 'mcs51')
274 @return 0 on success.
277 _setPort (const char *name)
280 for (i = 0; i < NUM_PORTS; i++)
282 if (!strcmp (_ports[i]->target, name))
288 /* Error - didnt find */
289 werror (E_UNKNOWN_TARGET, name);
294 _validatePorts (void)
297 for (i = 0; i < NUM_PORTS; i++)
299 if (_ports[i]->magic != PORT_MAGIC)
301 wassertl (0, "Port definition structure is incomplete");
305 /*-----------------------------------------------------------------*/
306 /* printVersionInfo - prints the version info */
307 /*-----------------------------------------------------------------*/
315 for (i = 0; i < NUM_PORTS; i++)
316 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
318 fprintf (stderr, " %s"
319 #ifdef SDCC_SUB_VERSION_STR
320 "/" SDCC_SUB_VERSION_STR
328 #if defined(_MSC_VER)
340 /*-----------------------------------------------------------------*/
341 /* printUsage - prints command line syntax */
342 /*-----------------------------------------------------------------*/
349 "Usage : sdcc [options] filename\n"
353 for (i = 0; i < LENGTH(optionsTable); i++) {
354 fprintf(stdout, " %c%c %-20s %s\n",
355 optionsTable[i].shortOpt !=0 ? '-' : ' ',
356 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
357 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
358 optionsTable[i].help != NULL ? optionsTable[i].help : ""
364 /*-----------------------------------------------------------------*/
365 /* parseWithComma - separates string with comma */
366 /*-----------------------------------------------------------------*/
368 parseWithComma (char **dest, char *src)
372 strtok (src, "\r\n \t");
373 /* skip the initial white spaces */
374 while (isspace (*src))
391 /*-----------------------------------------------------------------*/
392 /* setDefaultOptions - sets the default options */
393 /*-----------------------------------------------------------------*/
399 for (i = 0; i < 128; i++)
400 preArgv[i] = asmOptions[i] =
401 linkOptions[i] = relFiles[i] = libFiles[i] =
404 /* first the options part */
405 options.stack_loc = 0; /* stack pointer initialised to 0 */
406 options.xstack_loc = 0; /* xternal stack starts at 0 */
407 options.code_loc = 0; /* code starts at 0 */
408 options.data_loc = 0x0030; /* data starts at 0x0030 */
409 options.xdata_loc = 0;
410 options.idata_loc = 0x80;
411 options.genericPtr = 1; /* default on */
413 options.model = port->general.default_model;
414 options.nostdlib = 0;
415 options.nostdinc = 0;
417 options.shortis8bits = 0;
419 options.stack10bit=0;
421 /* now for the optimizations */
422 /* turn on the everything */
423 optimize.global_cse = 1;
428 optimize.loopInvariant = 1;
429 optimize.loopInduction = 1;
431 /* now for the ports */
432 port->setDefaultOptions ();
435 /*-----------------------------------------------------------------*/
436 /* processFile - determines the type of file from the extension */
437 /*-----------------------------------------------------------------*/
439 processFile (char *s)
443 /* get the file extension */
444 fext = s + strlen (s);
445 while ((fext != s) && *fext != '.')
448 /* now if no '.' then we don't know what the file type is
449 so give a warning and return */
452 werror (W_UNKNOWN_FEXT, s);
456 /* otherwise depending on the file type */
457 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
459 /* source file name : not if we already have a
463 werror (W_TOO_MANY_SRC, s);
467 /* the only source file */
468 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
470 werror (E_FILE_OPEN_ERR, s);
474 /* copy the file name into the buffer */
477 /* get rid of the "." */
478 strtok (buffer, ".");
479 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
480 strcpy (srcFileName, buffer);
482 /* get rid of any path information
483 for the module name; do this by going
484 backwards till we get to either '/' or '\' or ':'
485 or start of buffer */
486 fext = buffer + strlen (buffer);
487 while (fext != buffer &&
488 *(fext - 1) != '\\' &&
489 *(fext - 1) != '/' &&
492 moduleName = Safe_calloc (1, strlen (fext) + 1);
493 strcpy (moduleName, fext);
498 /* if the extention is type .rel or .r or .REL or .R
499 addtional object file will be passed to the linker */
500 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
501 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
502 strcmp (fext, port->linker.rel_ext) == 0)
504 relFiles[nrelFiles++] = s;
508 /* if .lib or .LIB */
509 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
511 libFiles[nlibFiles++] = s;
515 werror (W_UNKNOWN_FEXT, s);
520 _processC1Arg (char *s)
524 if (options.out_name)
526 werror (W_TOO_MANY_SRC, s);
529 options.out_name = strdup (s);
538 _addToList (const char **list, const char *str)
540 /* This is the bad way to do things :) */
543 *list = strdup (str);
546 werror (E_OUT_OF_MEM, __FILE__, 0);
553 _setModel (int model, const char *sz)
555 if (port->general.supported_models & model)
556 options.model = model;
558 werror (W_UNSUPPORTED_MODEL, sz, port->target);
561 /** Gets the string argument to this option. If the option is '--opt'
562 then for input of '--optxyz' or '--opt xyz' returns xyz.
565 getStringArg(const char *szStart, char **argv, int *pi, int argc)
567 if (argv[*pi][strlen(szStart)])
569 return &argv[*pi][strlen(szStart)];
576 werror (E_ARGUMENT_MISSING, szStart);
577 /* Die here rather than checking for errors later. */
587 /** Gets the integer argument to this option using the same rules as
591 getIntArg(const char *szStart, char **argv, int *pi, int argc)
593 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
597 verifyShortOption(const char *opt)
599 if (strlen(opt) != 2)
601 werror (W_EXCESS_SHORT_OPTIONS, opt);
606 tryHandleUnsupportedOpt(char **argv, int *pi)
608 if (argv[*pi][0] == '-')
610 const char *longOpt = "";
614 if (argv[*pi][1] == '-')
621 shortOpt = argv[*pi][1];
623 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
625 if (unsupportedOptTable[i].shortOpt == shortOpt ||
626 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
627 // Found an unsupported opt.
629 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
630 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
634 // Didn't find in the table
639 // Not an option, so can't be unsupported :)
645 tryHandleSimpleOpt(char **argv, int *pi)
647 if (argv[*pi][0] == '-')
649 const char *longOpt = "";
653 if (argv[*pi][1] == '-')
660 shortOpt = argv[*pi][1];
663 for (i = 0; i < LENGTH(optionsTable); i++)
665 if (optionsTable[i].shortOpt == shortOpt ||
666 (longOpt && optionsTable[i].longOpt &&
667 strcmp(optionsTable[i].longOpt, longOpt) == 0))
670 // If it is a flag then we can handle it here
671 if (optionsTable[i].pparameter != NULL)
673 if (optionsTable[i].shortOpt == shortOpt)
675 verifyShortOption(argv[*pi]);
678 (*optionsTable[i].pparameter)++;
682 // Not a flag. Handled manually later.
687 // Didn't find in the table
692 // Not an option, so can't be handled.
697 /*-----------------------------------------------------------------*/
698 /* parseCmdLine - parses the command line and sets the options */
699 /*-----------------------------------------------------------------*/
701 parseCmdLine (int argc, char **argv)
705 /* go thru all whole command line */
706 for (i = 1; i < argc; i++)
711 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
716 if (tryHandleSimpleOpt(argv, &i) == TRUE)
722 if (argv[i][0] == '-' && argv[i][1] == '-')
724 if (strcmp (argv[i], OPTION_HELP) == 0)
730 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
732 options.stack10bit = 0;
736 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
742 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
744 _setModel (MODEL_LARGE, argv[i]);
748 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
750 _setModel (MODEL_MEDIUM, argv[i]);
754 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
756 _setModel (MODEL_SMALL, argv[i]);
760 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
762 _setModel (MODEL_FLAT24, argv[i]);
766 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
768 options.dump_rassgn =
774 options.dump_raw = 1;
778 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
780 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
784 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
786 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i, argc);
790 if (strcmp (argv[i], OPTION_VERSION) == 0)
797 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
799 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
803 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
805 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
809 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
811 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
815 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
817 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
821 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
823 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
827 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
829 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
833 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
835 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
839 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
841 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
845 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
847 optimize.global_cse = 0;
851 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
853 optimize.loopInvariant = 0;
857 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
859 optimize.loopInduction = 0;
863 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
865 setErrorLogLevel(ERROR_LEVEL_WARNING);
869 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
871 options.shortis8bits=1;
875 if (!port->parseOption (&argc, argv, &i))
877 werror (W_UNKNOWN_OPTION, argv[i]);
885 /* if preceded by '-' then option */
891 verifyShortOption(argv[i]);
898 /* Used to select the port */
899 _setPort (argv[i] + 2);
903 verifyShortOption(argv[i]);
909 libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
913 libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
918 if (argv[i][2] == 'l')
920 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
924 /* assembler options */
925 if (argv[i][2] == 'a')
927 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
931 werror (W_UNKNOWN_OPTION, argv[i]);
937 verifyShortOption(argv[i]);
943 /* preprocessor options */
947 _addToList (preArgv, "-M");
952 _addToList (preArgv, "-C");
961 char sOpt = argv[i][1];
964 if (argv[i][2] == ' ' || argv[i][2] == '\0')
970 werror(E_ARGUMENT_MISSING, argv[i-1]);
984 sprintf (buffer, "-%c%s", sOpt, rest);
985 _addToList (preArgv, buffer);
990 if (!port->parseOption (&argc, argv, &i))
991 werror (W_UNKNOWN_OPTION, argv[i]);
996 if (!port->parseOption (&argc, argv, &i))
998 /* no option must be a filename */
1000 _processC1Arg (argv[i]);
1002 processFile (argv[i]);
1006 /* set up external stack location if not explicitly specified */
1007 if (!options.xstack_loc)
1008 options.xstack_loc = options.xdata_loc;
1010 /* if debug option is set the open the cdbFile */
1011 if (options.debug && srcFileName)
1013 sprintf (scratchFileName, "%s.cdb", srcFileName);
1014 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1015 werror (E_FILE_OPEN_ERR, scratchFileName);
1018 /* add a module record */
1019 fprintf (cdbFile, "M:%s\n", moduleName);
1025 /*-----------------------------------------------------------------*/
1026 /* linkEdit : - calls the linkage editor with options */
1027 /*-----------------------------------------------------------------*/
1029 linkEdit (char **envp)
1036 srcFileName = "temp";
1038 /* first we need to create the <filename>.lnk file */
1039 sprintf (scratchFileName, "%s.lnk", srcFileName);
1040 if (!(lnkfile = fopen (scratchFileName, "w")))
1042 werror (E_FILE_OPEN_ERR, scratchFileName);
1046 /* now write the options */
1047 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1049 /* if iram size specified */
1050 if (options.iram_size)
1051 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1054 fprintf (lnkfile, "-z\n");
1056 #define WRITE_SEG_LOC(N, L) \
1057 segName = strdup(N); \
1058 c = strtok(segName, " \t"); \
1059 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1060 if (segName) { free(segName); }
1062 /* code segment start */
1063 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1065 /* data segment start */
1066 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1069 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1072 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1074 /* bit segment start */
1075 WRITE_SEG_LOC (BIT_NAME, 0);
1077 /* add the extra linker options */
1078 for (i = 0; linkOptions[i]; i++)
1079 fprintf (lnkfile, "%s\n", linkOptions[i]);
1081 /* other library paths if specified */
1082 for (i = 0; i < nlibPaths; i++)
1083 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1085 /* standard library path */
1086 if (!options.nostdlib)
1089 if (TARGET_IS_DS390)
1096 switch (options.model)
1109 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1114 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1116 /* standard library files */
1117 /* if (strcmp (port->target, "ds390") == 0) */
1118 if (options.model == MODEL_FLAT24)
1120 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1122 fprintf (lnkfile, "-l %s\n", STD_LIB);
1123 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1124 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1125 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1128 /* additional libraries if any */
1129 for (i = 0; i < nlibFiles; i++)
1130 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1132 /* put in the object files */
1133 if (strcmp (srcFileName, "temp"))
1134 fprintf (lnkfile, "%s ", srcFileName);
1136 for (i = 0; i < nrelFiles; i++)
1137 fprintf (lnkfile, "%s\n", relFiles[i]);
1139 fprintf (lnkfile, "\n-e\n");
1142 if (options.verbose)
1143 printf ("sdcc: Calling linker...\n");
1145 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1146 if (my_system (buffer))
1151 if (strcmp (srcFileName, "temp") == 0)
1153 /* rename "temp.cdb" to "firstRelFile.cdb" */
1154 char *f = strtok (strdup (relFiles[0]), ".");
1155 f = strcat (f, ".cdb");
1156 rename ("temp.cdb", f);
1161 /*-----------------------------------------------------------------*/
1162 /* assemble - spawns the assembler with arguments */
1163 /*-----------------------------------------------------------------*/
1165 assemble (char **envp)
1167 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1168 if (my_system (buffer))
1170 /* either system() or the assembler itself has reported an error
1171 perror ("Cannot exec assembler");
1179 /*-----------------------------------------------------------------*/
1180 /* preProcess - spawns the preprocessor with arguments */
1181 /*-----------------------------------------------------------------*/
1183 preProcess (char **envp)
1189 if (!options.c1mode)
1191 /* if using external stack define the macro */
1192 if (options.useXstack)
1193 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1195 /* set the macro for stack autos */
1196 if (options.stackAuto)
1197 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1199 /* set the macro for stack autos */
1200 if (options.stack10bit)
1201 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1203 /* set the macro for large model */
1204 switch (options.model)
1207 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1210 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1213 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1216 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1219 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1222 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1226 /* standard include path */
1227 if (!options.nostdinc) {
1228 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1231 /* add port (processor information to processor */
1232 sprintf (procDef, "-DSDCC_%s", port->target);
1233 _addToList (preArgv, procDef);
1234 sprintf (procDef, "-D__%s", port->target);
1235 _addToList (preArgv, procDef);
1238 preOutName = strdup (tmpnam (NULL));
1240 if (options.verbose)
1241 printf ("sdcc: Calling preprocessor...\n");
1243 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1244 preOutName, srcFileName, preArgv);
1245 if (my_system (buffer))
1247 // @FIX: Dario Vecchio 03-05-2001
1250 unlink (preOutName);
1264 preOutName = fullSrcFileName;
1267 yyin = fopen (preOutName, "r");
1270 perror ("Preproc file not found\n");
1278 _findPort (int argc, char **argv)
1284 if (!strncmp (*argv, "-m", 2))
1286 _setPort (*argv + 2);
1291 /* Use the first in the list */
1297 * initialises and calls the parser
1301 main (int argc, char **argv, char **envp)
1303 /* turn all optimizations off by default */
1304 memset (&optimize, 0, sizeof (struct optimize));
1306 /*printVersionInfo (); */
1309 fprintf (stderr, "Build error: no ports are enabled.\n");
1313 _findPort (argc, argv);
1315 if (strcmp(port->target, "mcs51") == 0) {
1316 printf("DS390 jammed in A\n");
1321 /* Initalise the port. */
1325 // Create a default exe search path from the path to the sdcc command
1329 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1331 strcpy (DefaultExePath, argv[0]);
1332 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1333 ExePathList[0] = DefaultExePath;
1337 setDefaultOptions ();
1340 options.model = MODEL_SMALL;
1341 options.stack10bit=0;
1344 parseCmdLine (argc, argv);
1346 if (getenv("SDCPP"))
1348 _preCmd[0] = getenv("SDCPP");
1351 /* if no input then printUsage & exit */
1352 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1353 (options.c1mode && !srcFileName && !options.out_name))
1365 port->finaliseOptions ();
1372 if (options.verbose)
1373 printf ("sdcc: Generating code...\n");
1379 if (TARGET_IS_PIC) {
1380 /* TSD PIC port hack - if the PIC port option is enabled
1381 and SDCC is used to generate PIC code, then we will
1382 generate .asm files in gpasm's format instead of SDCC's
1385 #if !OPT_DISABLE_PIC
1394 // @FIX: Dario Vecchio 03-05-2001
1397 if (yyin && yyin != stdin)
1399 unlink (preOutName);
1405 if (!options.c1mode && !noAssemble)
1407 if (options.verbose)
1408 printf ("sdcc: Calling assembler...\n");
1414 // @FIX: Dario Vecchio 03-05-2001
1417 if (yyin && yyin != stdin)
1419 unlink (preOutName);
1423 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1436 if (preOutName && !options.c1mode)
1438 unlink (preOutName);
1442 if (!options.cc_only &&
1446 (srcFileName || nrelFiles))
1448 if (port->linker.do_link)
1449 port->linker.do_link ();
1454 if (yyin && yyin != stdin)