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 options.lessPedantic = 1;
866 setErrorLogLevel(ERROR_LEVEL_WARNING);
870 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
872 options.shortis8bits=1;
876 if (!port->parseOption (&argc, argv, &i))
878 werror (W_UNKNOWN_OPTION, argv[i]);
886 /* if preceded by '-' then option */
892 verifyShortOption(argv[i]);
899 /* Used to select the port */
900 _setPort (argv[i] + 2);
904 verifyShortOption(argv[i]);
910 libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
914 libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
919 if (argv[i][2] == 'l')
921 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
925 /* assembler options */
926 if (argv[i][2] == 'a')
928 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
932 werror (W_UNKNOWN_OPTION, argv[i]);
938 verifyShortOption(argv[i]);
944 /* preprocessor options */
948 _addToList (preArgv, "-M");
953 _addToList (preArgv, "-C");
962 char sOpt = argv[i][1];
965 if (argv[i][2] == ' ' || argv[i][2] == '\0')
971 werror(E_ARGUMENT_MISSING, argv[i-1]);
985 sprintf (buffer, "-%c%s", sOpt, rest);
986 _addToList (preArgv, buffer);
991 if (!port->parseOption (&argc, argv, &i))
992 werror (W_UNKNOWN_OPTION, argv[i]);
997 if (!port->parseOption (&argc, argv, &i))
999 /* no option must be a filename */
1001 _processC1Arg (argv[i]);
1003 processFile (argv[i]);
1007 /* set up external stack location if not explicitly specified */
1008 if (!options.xstack_loc)
1009 options.xstack_loc = options.xdata_loc;
1011 /* if debug option is set the open the cdbFile */
1012 if (options.debug && srcFileName)
1014 sprintf (scratchFileName, "%s.cdb", srcFileName);
1015 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1016 werror (E_FILE_OPEN_ERR, scratchFileName);
1019 /* add a module record */
1020 fprintf (cdbFile, "M:%s\n", moduleName);
1026 /*-----------------------------------------------------------------*/
1027 /* linkEdit : - calls the linkage editor with options */
1028 /*-----------------------------------------------------------------*/
1030 linkEdit (char **envp)
1037 srcFileName = "temp";
1039 /* first we need to create the <filename>.lnk file */
1040 sprintf (scratchFileName, "%s.lnk", srcFileName);
1041 if (!(lnkfile = fopen (scratchFileName, "w")))
1043 werror (E_FILE_OPEN_ERR, scratchFileName);
1047 /* now write the options */
1048 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1050 /* if iram size specified */
1051 if (options.iram_size)
1052 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1055 fprintf (lnkfile, "-z\n");
1057 #define WRITE_SEG_LOC(N, L) \
1058 segName = strdup(N); \
1059 c = strtok(segName, " \t"); \
1060 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1061 if (segName) { free(segName); }
1063 /* code segment start */
1064 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1066 /* data segment start */
1067 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1070 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1073 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1075 /* bit segment start */
1076 WRITE_SEG_LOC (BIT_NAME, 0);
1078 /* add the extra linker options */
1079 for (i = 0; linkOptions[i]; i++)
1080 fprintf (lnkfile, "%s\n", linkOptions[i]);
1082 /* other library paths if specified */
1083 for (i = 0; i < nlibPaths; i++)
1084 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1086 /* standard library path */
1087 if (!options.nostdlib)
1090 if (TARGET_IS_DS390)
1097 switch (options.model)
1110 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1115 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1117 /* standard library files */
1118 /* if (strcmp (port->target, "ds390") == 0) */
1119 if (options.model == MODEL_FLAT24)
1121 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1123 fprintf (lnkfile, "-l %s\n", STD_LIB);
1124 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1125 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1126 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1129 /* additional libraries if any */
1130 for (i = 0; i < nlibFiles; i++)
1131 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1133 /* put in the object files */
1134 if (strcmp (srcFileName, "temp"))
1135 fprintf (lnkfile, "%s ", srcFileName);
1137 for (i = 0; i < nrelFiles; i++)
1138 fprintf (lnkfile, "%s\n", relFiles[i]);
1140 fprintf (lnkfile, "\n-e\n");
1143 if (options.verbose)
1144 printf ("sdcc: Calling linker...\n");
1146 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1147 if (my_system (buffer))
1152 if (strcmp (srcFileName, "temp") == 0)
1154 /* rename "temp.cdb" to "firstRelFile.cdb" */
1155 char *f = strtok (strdup (relFiles[0]), ".");
1156 f = strcat (f, ".cdb");
1157 rename ("temp.cdb", f);
1162 /*-----------------------------------------------------------------*/
1163 /* assemble - spawns the assembler with arguments */
1164 /*-----------------------------------------------------------------*/
1166 assemble (char **envp)
1168 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1169 if (my_system (buffer))
1171 /* either system() or the assembler itself has reported an error
1172 perror ("Cannot exec assembler");
1180 /*-----------------------------------------------------------------*/
1181 /* preProcess - spawns the preprocessor with arguments */
1182 /*-----------------------------------------------------------------*/
1184 preProcess (char **envp)
1190 if (!options.c1mode)
1192 /* if using external stack define the macro */
1193 if (options.useXstack)
1194 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1196 /* set the macro for stack autos */
1197 if (options.stackAuto)
1198 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1200 /* set the macro for stack autos */
1201 if (options.stack10bit)
1202 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1204 /* set the macro for large model */
1205 switch (options.model)
1208 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1211 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1214 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1217 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1220 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1223 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1227 /* standard include path */
1228 if (!options.nostdinc) {
1229 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1232 /* add port (processor information to processor */
1233 sprintf (procDef, "-DSDCC_%s", port->target);
1234 _addToList (preArgv, procDef);
1235 sprintf (procDef, "-D__%s", port->target);
1236 _addToList (preArgv, procDef);
1239 preOutName = strdup (tmpnam (NULL));
1241 if (options.verbose)
1242 printf ("sdcc: Calling preprocessor...\n");
1244 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1245 preOutName, srcFileName, preArgv);
1246 if (my_system (buffer))
1248 // @FIX: Dario Vecchio 03-05-2001
1251 unlink (preOutName);
1265 preOutName = fullSrcFileName;
1268 yyin = fopen (preOutName, "r");
1271 perror ("Preproc file not found\n");
1279 _findPort (int argc, char **argv)
1285 if (!strncmp (*argv, "-m", 2))
1287 _setPort (*argv + 2);
1292 /* Use the first in the list */
1298 * initialises and calls the parser
1302 main (int argc, char **argv, char **envp)
1304 /* turn all optimizations off by default */
1305 memset (&optimize, 0, sizeof (struct optimize));
1307 /*printVersionInfo (); */
1310 fprintf (stderr, "Build error: no ports are enabled.\n");
1314 _findPort (argc, argv);
1316 if (strcmp(port->target, "mcs51") == 0) {
1317 printf("DS390 jammed in A\n");
1322 /* Initalise the port. */
1326 // Create a default exe search path from the path to the sdcc command
1330 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1332 strcpy (DefaultExePath, argv[0]);
1333 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1334 ExePathList[0] = DefaultExePath;
1338 setDefaultOptions ();
1341 options.model = MODEL_SMALL;
1342 options.stack10bit=0;
1345 parseCmdLine (argc, argv);
1347 if (getenv("SDCPP"))
1349 _preCmd[0] = getenv("SDCPP");
1352 /* if no input then printUsage & exit */
1353 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1354 (options.c1mode && !srcFileName && !options.out_name))
1366 port->finaliseOptions ();
1373 if (options.verbose)
1374 printf ("sdcc: Generating code...\n");
1380 if (TARGET_IS_PIC) {
1381 /* TSD PIC port hack - if the PIC port option is enabled
1382 and SDCC is used to generate PIC code, then we will
1383 generate .asm files in gpasm's format instead of SDCC's
1386 #if !OPT_DISABLE_PIC
1395 // @FIX: Dario Vecchio 03-05-2001
1398 if (yyin && yyin != stdin)
1400 unlink (preOutName);
1406 if (!options.c1mode && !noAssemble)
1408 if (options.verbose)
1409 printf ("sdcc: Calling assembler...\n");
1415 // @FIX: Dario Vecchio 03-05-2001
1418 if (yyin && yyin != stdin)
1420 unlink (preOutName);
1424 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1437 if (preOutName && !options.c1mode)
1439 unlink (preOutName);
1443 if (!options.cc_only &&
1447 (srcFileName || nrelFiles))
1449 if (port->linker.do_link)
1450 port->linker.do_link ();
1455 if (yyin && yyin != stdin)