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 -------------------------------------------------------------------------*/
31 #include "SDCCmacro.h"
40 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
45 /** Name of the environment variable checked for other instalations. */
46 #define SDCCDIR_NAME "SDCCDIR"
49 extern int yyparse ();
51 FILE *srcFile; /* source file */
52 FILE *cdbFile = NULL; /* debugger information output file */
53 char *fullSrcFileName; /* full name for the source file */
54 char *srcFileName; /* source file name with the .c stripped */
55 char *moduleName; /* module name is srcFilename stripped of any path */
56 const char *preArgv[128]; /* pre-processor arguments */
58 struct optimize optimize;
59 struct options options;
60 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
63 char *linkOptions[128];
64 const char *asmOptions[128];
71 bool verboseExec = FALSE;
74 /* uncomment JAMIN_DS390 to always override and use ds390 port
75 for mcs51 work. This is temporary, for compatibility testing. */
76 /* #define JAMIN_DS390 */
81 // Globally accessible scratch buffer for file names.
82 char scratchFileName[PATH_MAX];
83 char buffer[PATH_MAX];
85 // In MSC VC6 default search path for exe's to path for this
87 char DefaultExePath[128];
89 #define OPTION_HELP "-help"
91 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
93 #define OPTION_STACK_8BIT "--stack-8bit"
94 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
95 #define OPTION_LARGE_MODEL "--model-large"
96 #define OPTION_MEDIUM_MODEL "--model-medium"
97 #define OPTION_SMALL_MODEL "--model-small"
98 #define OPTION_FLAT24_MODEL "--model-flat24"
99 #define OPTION_DUMP_ALL "--dumpall"
100 #define OPTION_PEEP_FILE "--peep-file"
101 #define OPTION_LIB_PATH "--lib-path"
102 #define OPTION_XSTACK_LOC "--xstack-loc"
103 #define OPTION_CALLEE_SAVES "--callee-saves"
104 #define OPTION_STACK_LOC "--stack-loc"
105 #define OPTION_XRAM_LOC "--xram-loc"
106 #define OPTION_IRAM_SIZE "--iram-size"
107 #define OPTION_VERSION "--version"
108 #define OPTION_DATA_LOC "--data-loc"
109 #define OPTION_CODE_LOC "--code-loc"
110 #define OPTION_IDATA_LOC "--idata-loc"
111 #define OPTION_NO_LOOP_INV "--noinvariant"
112 #define OPTION_NO_LOOP_IND "--noinduction"
113 #define OPTION_LESS_PEDANTIC "--lesspedantic"
114 #define OPTION_NO_GCSE "--nogcse"
115 #define OPTION_SHORT_IS_8BITS "--short-is-8bits"
117 /** Table of all options supported by all ports.
119 * A reference for all options.
120 * An easy way to maintain help for the options.
121 * Automatic support for setting flags on simple options.
124 /** The short option character e.g. 'h' for -h. 0 for none. */
126 /** Long option e.g. "--help". Includes the -- prefix. NULL for
129 /** Pointer to an int that will be incremented every time the
130 option is encountered. May be NULL.
133 /** Help text to go with this option. May be NULL. */
139 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
140 { 'd', NULL, NULL, NULL },
141 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
142 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
143 { 'A', NULL, NULL, NULL },
144 { 'U', NULL, NULL, NULL },
145 { 'C', NULL, NULL, "Preprocessor option" },
146 { 'M', NULL, NULL, "Preprocessor option" },
147 { 'V', NULL, &verboseExec, "Execute verbosely. Show sub commands as they are run" },
148 { 'S', NULL, &noAssemble, "Compile only; do not assemble or link" },
149 { 'W', NULL, NULL, "Pass through options to the pre-processor (p), assembler (a) or linker (l)" },
150 { 'L', NULL, NULL, "Add the next field to the library search path" },
151 { 'l', NULL, NULL, "Include the given library in the link" },
152 { 0, OPTION_LARGE_MODEL, NULL, "external data space is used" },
153 { 0, OPTION_MEDIUM_MODEL, NULL, "not supported" },
154 { 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" },
155 { 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" },
156 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
157 { 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" },
158 { 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" },
159 { 0, "--xstack", &options.useXstack, "Use external stack" },
160 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
161 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
162 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
163 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
164 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
165 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
166 { 'c', "--compile-only", &options.cc_only, "Compile and assemble, but do not link" },
167 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
168 { 0, "--dumpgcse", &options.dump_gcse, NULL },
169 { 0, "--dumploop", &options.dump_loop, NULL },
170 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
171 { 0, "--dumpliverange", &options.dump_range, NULL },
172 { 0, "--dumpregpack", &options.dump_pack, NULL },
173 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
174 { 0, "--dumptree", &options.dump_tree, NULL },
175 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
176 { 0, OPTION_XRAM_LOC, NULL, "<nnnn> External Ram start location" },
177 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
178 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
179 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
180 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
181 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
182 { 0, OPTION_IDATA_LOC, NULL, NULL },
183 { 0, OPTION_PEEP_FILE, NULL, "<file> use this extra peep-hole file" },
184 { 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
185 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
186 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
187 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
188 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
189 { 0, "--cyclomatic", &options.cyclomatic, NULL },
190 { 0, "--nooverlay", &options.noOverlay, NULL },
191 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
192 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
193 { 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
194 { 0, "--peep-asm", &options.asmpeep, NULL },
195 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
196 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
197 { 0, "--stack-after-data", &options.stackOnData, "initialize the stackpointer with the last byte use in DSEG" },
198 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
199 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
200 { 0, "--help", NULL, "Display this help" },
201 { 0, OPTION_CALLEE_SAVES, NULL, "<func[,func,...]> Cause the called function to save registers insted of the caller" },
202 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
203 { 0, "--nostdinc", &options.nostdinc, "Do not include the standard include directory in the search path" },
204 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
205 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
206 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" },
207 { 0, "--profile", &options.profile, "On supported ports, generate extra profiling information" },
208 { 0, "--fommit-frame-pointer", &options.ommitFramePtr, "Leave out the frame pointer." }
211 /** Table of all unsupported options and help text to display when one
215 /** shortOpt as in OPTIONS. */
217 /** longOpt as in OPTIONS. */
219 /** Message to display inside W_UNSUPPORTED_OPT when this option
224 static const UNSUPPORTEDOPT
225 unsupportedOptTable[] = {
226 { 'a', NULL, "use --stack-auto instead." },
227 { 'g', NULL, "use --generic instead" },
228 { 'X', NULL, "use --xstack-loc instead" },
229 { 'x', NULL, "use --xstack instead" },
230 { 'p', NULL, "use --stack-loc instead" },
231 { 'P', NULL, "use --stack-loc instead" },
232 { 'i', NULL, "use --idata-loc instead" },
233 { 'r', NULL, "use --xdata-loc instead" },
234 { 's', NULL, "use --code-loc instead" },
235 { 'Y', NULL, "use -I instead" }
238 /** List of all default constant macros.
240 static const char *_baseValues[] = {
241 "cpp", "{bindir}{sep}sdcpp",
243 /* Path seperator character */
244 "sep", DIR_SEPARATOR_STRING,
248 static const char *_preCmd = "{cpp} -Wall -lang-c++ -DSDCC=1 {cppextraopts} {fullsrcfilename} {cppoutfilename}";
252 static PORT *_ports[] =
254 #if !OPT_DISABLE_MCS51
257 #if !OPT_DISABLE_GBZ80
266 #if !OPT_DISABLE_DS390
272 #if !OPT_DISABLE_I186
275 #if !OPT_DISABLE_TLCS900H
280 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
283 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
285 extern void picglue ();
287 /** Sets the port to the one given by the command line option.
288 @param The name minus the option (eg 'mcs51')
289 @return 0 on success.
292 _setPort (const char *name)
295 for (i = 0; i < NUM_PORTS; i++)
297 if (!strcmp (_ports[i]->target, name))
303 /* Error - didnt find */
304 werror (E_UNKNOWN_TARGET, name);
309 _validatePorts (void)
312 for (i = 0; i < NUM_PORTS; i++)
314 if (_ports[i]->magic != PORT_MAGIC)
316 wassertl (0, "Port definition structure is incomplete");
322 _findPort (int argc, char **argv)
328 if (!strncmp (*argv, "-m", 2))
330 _setPort (*argv + 2);
335 /* Use the first in the list */
339 /*-----------------------------------------------------------------*/
340 /* printVersionInfo - prints the version info */
341 /*-----------------------------------------------------------------*/
349 for (i = 0; i < NUM_PORTS; i++)
350 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
352 fprintf (stderr, " %s"
353 #ifdef SDCC_SUB_VERSION_STR
354 "/" SDCC_SUB_VERSION_STR
363 #if defined(_MSC_VER)
375 /*-----------------------------------------------------------------*/
376 /* printUsage - prints command line syntax */
377 /*-----------------------------------------------------------------*/
384 "Usage : sdcc [options] filename\n"
388 for (i = 0; i < LENGTH(optionsTable); i++) {
389 fprintf(stdout, " %c%c %-20s %s\n",
390 optionsTable[i].shortOpt !=0 ? '-' : ' ',
391 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
392 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
393 optionsTable[i].help != NULL ? optionsTable[i].help : ""
399 /*-----------------------------------------------------------------*/
400 /* parseWithComma - separates string with comma */
401 /*-----------------------------------------------------------------*/
403 parseWithComma (char **dest, char *src)
407 strtok (src, "\r\n \t");
408 /* skip the initial white spaces */
409 while (isspace (*src))
426 /*-----------------------------------------------------------------*/
427 /* setDefaultOptions - sets the default options */
428 /*-----------------------------------------------------------------*/
434 for (i = 0; i < 128; i++)
435 preArgv[i] = asmOptions[i] =
436 linkOptions[i] = relFiles[i] = libFiles[i] =
439 /* first the options part */
440 options.stack_loc = 0; /* stack pointer initialised to 0 */
441 options.xstack_loc = 0; /* xternal stack starts at 0 */
442 options.code_loc = 0; /* code starts at 0 */
443 options.data_loc = 0x0030; /* data starts at 0x0030 */
444 options.xdata_loc = 0;
445 options.idata_loc = 0x80;
446 options.genericPtr = 1; /* default on */
448 options.model = port->general.default_model;
449 options.nostdlib = 0;
450 options.nostdinc = 0;
452 options.shortis8bits = 0;
454 options.stack10bit=0;
456 /* now for the optimizations */
457 /* turn on the everything */
458 optimize.global_cse = 1;
463 optimize.loopInvariant = 1;
464 optimize.loopInduction = 1;
466 /* now for the ports */
467 port->setDefaultOptions ();
470 /*-----------------------------------------------------------------*/
471 /* processFile - determines the type of file from the extension */
472 /*-----------------------------------------------------------------*/
474 processFile (char *s)
478 /* get the file extension */
479 fext = s + strlen (s);
480 while ((fext != s) && *fext != '.')
483 /* now if no '.' then we don't know what the file type is
484 so give a warning and return */
487 werror (W_UNKNOWN_FEXT, s);
491 /* otherwise depending on the file type */
492 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
494 /* source file name : not if we already have a
498 werror (W_TOO_MANY_SRC, s);
502 /* the only source file */
503 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
505 werror (E_FILE_OPEN_ERR, s);
509 /* copy the file name into the buffer */
512 /* get rid of the "." */
513 strtok (buffer, ".");
514 srcFileName = Safe_alloc ( strlen (buffer) + 1);
515 strcpy (srcFileName, buffer);
517 /* get rid of any path information
518 for the module name; do this by going
519 backwards till we get to either '/' or '\' or ':'
520 or start of buffer */
521 fext = buffer + strlen (buffer);
522 while (fext != buffer &&
523 *(fext - 1) != '\\' &&
524 *(fext - 1) != '/' &&
527 moduleName = Safe_alloc ( strlen (fext) + 1);
528 strcpy (moduleName, fext);
533 /* if the extention is type .rel or .r or .REL or .R
534 addtional object file will be passed to the linker */
535 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
536 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
537 strcmp (fext, port->linker.rel_ext) == 0)
539 relFiles[nrelFiles++] = s;
543 /* if .lib or .LIB */
544 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
546 libFiles[nlibFiles++] = s;
550 werror (W_UNKNOWN_FEXT, s);
555 _processC1Arg (char *s)
559 if (options.out_name)
561 werror (W_TOO_MANY_SRC, s);
564 options.out_name = Safe_strdup (s);
573 _setModel (int model, const char *sz)
575 if (port->general.supported_models & model)
576 options.model = model;
578 werror (W_UNSUPPORTED_MODEL, sz, port->target);
581 /** Gets the string argument to this option. If the option is '--opt'
582 then for input of '--optxyz' or '--opt xyz' returns xyz.
585 getStringArg(const char *szStart, char **argv, int *pi, int argc)
587 if (argv[*pi][strlen(szStart)])
589 return &argv[*pi][strlen(szStart)];
596 werror (E_ARGUMENT_MISSING, szStart);
597 /* Die here rather than checking for errors later. */
607 /** Gets the integer argument to this option using the same rules as
611 getIntArg(const char *szStart, char **argv, int *pi, int argc)
613 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
617 verifyShortOption(const char *opt)
619 if (strlen(opt) != 2)
621 werror (W_EXCESS_SHORT_OPTIONS, opt);
626 tryHandleUnsupportedOpt(char **argv, int *pi)
628 if (argv[*pi][0] == '-')
630 const char *longOpt = "";
634 if (argv[*pi][1] == '-')
641 shortOpt = argv[*pi][1];
643 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
645 if (unsupportedOptTable[i].shortOpt == shortOpt ||
646 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
647 // Found an unsupported opt.
649 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
650 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
654 // Didn't find in the table
659 // Not an option, so can't be unsupported :)
665 tryHandleSimpleOpt(char **argv, int *pi)
667 if (argv[*pi][0] == '-')
669 const char *longOpt = "";
673 if (argv[*pi][1] == '-')
680 shortOpt = argv[*pi][1];
683 for (i = 0; i < LENGTH(optionsTable); i++)
685 if (optionsTable[i].shortOpt == shortOpt ||
686 (longOpt && optionsTable[i].longOpt &&
687 strcmp(optionsTable[i].longOpt, longOpt) == 0))
690 // If it is a flag then we can handle it here
691 if (optionsTable[i].pparameter != NULL)
693 if (optionsTable[i].shortOpt == shortOpt)
695 verifyShortOption(argv[*pi]);
698 (*optionsTable[i].pparameter)++;
702 // Not a flag. Handled manually later.
707 // Didn't find in the table
712 // Not an option, so can't be handled.
717 /*-----------------------------------------------------------------*/
718 /* parseCmdLine - parses the command line and sets the options */
719 /*-----------------------------------------------------------------*/
721 parseCmdLine (int argc, char **argv)
725 /* go thru all whole command line */
726 for (i = 1; i < argc; i++)
731 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
736 if (tryHandleSimpleOpt(argv, &i) == TRUE)
742 if (argv[i][0] == '-' && argv[i][1] == '-')
744 if (strcmp (argv[i], OPTION_HELP) == 0)
750 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
752 options.stack10bit = 0;
756 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
762 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
764 _setModel (MODEL_LARGE, argv[i]);
768 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
770 _setModel (MODEL_MEDIUM, argv[i]);
774 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
776 _setModel (MODEL_SMALL, argv[i]);
780 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
782 _setModel (MODEL_FLAT24, argv[i]);
786 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
788 options.dump_rassgn =
794 options.dump_raw = 1;
798 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
800 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
804 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
806 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i, argc);
810 if (strcmp (argv[i], OPTION_VERSION) == 0)
817 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
819 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
823 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
825 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
829 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
831 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
835 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
837 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
841 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
843 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
847 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
849 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
853 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
855 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
859 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
861 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
865 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
867 optimize.global_cse = 0;
871 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
873 optimize.loopInvariant = 0;
877 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
879 optimize.loopInduction = 0;
883 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
885 options.lessPedantic = 1;
886 setErrorLogLevel(ERROR_LEVEL_WARNING);
890 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
892 options.shortis8bits=1;
896 if (!port->parseOption (&argc, argv, &i))
898 werror (W_UNKNOWN_OPTION, argv[i]);
906 /* if preceded by '-' then option */
912 verifyShortOption(argv[i]);
919 /* Used to select the port */
920 _setPort (argv[i] + 2);
924 verifyShortOption(argv[i]);
930 libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
934 libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
938 /* pre-processer options */
939 if (argv[i][2] == 'p')
941 parseWithComma ((char **)preArgv, getStringArg("-Wp", argv, &i, argc));
944 else if (argv[i][2] == 'l')
946 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
948 /* assembler options */
949 else if (argv[i][2] == 'a')
951 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
955 werror (W_UNKNOWN_OPTION, argv[i]);
960 verifyShortOption(argv[i]);
966 /* preprocessor options */
970 addToList (preArgv, "-M");
975 addToList (preArgv, "-C");
984 char sOpt = argv[i][1];
987 if (argv[i][2] == ' ' || argv[i][2] == '\0')
993 werror(E_ARGUMENT_MISSING, argv[i-1]);
1007 sprintf (buffer, "-%c%s", sOpt, rest);
1008 addToList (preArgv, buffer);
1013 if (!port->parseOption (&argc, argv, &i))
1014 werror (W_UNKNOWN_OPTION, argv[i]);
1019 if (!port->parseOption (&argc, argv, &i))
1021 /* no option must be a filename */
1023 _processC1Arg (argv[i]);
1025 processFile (argv[i]);
1029 /* set up external stack location if not explicitly specified */
1030 if (!options.xstack_loc)
1031 options.xstack_loc = options.xdata_loc;
1033 /* if debug option is set the open the cdbFile */
1034 if (options.debug && srcFileName)
1036 sprintf (scratchFileName, "%s.cdb", srcFileName);
1037 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1038 werror (E_FILE_OPEN_ERR, scratchFileName);
1041 /* add a module record */
1042 fprintf (cdbFile, "M:%s\n", moduleName);
1048 /*-----------------------------------------------------------------*/
1049 /* linkEdit : - calls the linkage editor with options */
1050 /*-----------------------------------------------------------------*/
1052 linkEdit (char **envp)
1059 srcFileName = "temp";
1061 /* first we need to create the <filename>.lnk file */
1062 sprintf (scratchFileName, "%s.lnk", srcFileName);
1063 if (!(lnkfile = fopen (scratchFileName, "w")))
1065 werror (E_FILE_OPEN_ERR, scratchFileName);
1069 /* now write the options */
1070 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1072 /* if iram size specified */
1073 if (options.iram_size)
1074 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1077 fprintf (lnkfile, "-z\n");
1079 #define WRITE_SEG_LOC(N, L) \
1080 segName = Safe_strdup(N); \
1081 c = strtok(segName, " \t"); \
1082 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1083 if (segName) { Safe_free(segName); }
1085 /* code segment start */
1086 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1088 /* data segment start */
1089 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1092 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1095 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1097 /* bit segment start */
1098 WRITE_SEG_LOC (BIT_NAME, 0);
1100 /* add the extra linker options */
1101 for (i = 0; linkOptions[i]; i++)
1102 fprintf (lnkfile, "%s\n", linkOptions[i]);
1104 /* other library paths if specified */
1105 for (i = 0; i < nlibPaths; i++)
1106 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1108 /* standard library path */
1109 if (!options.nostdlib)
1112 if (TARGET_IS_DS390)
1119 switch (options.model)
1132 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1137 mfprintf (lnkfile, getRuntimeVariables(), "-k {libdir}{sep}%s\n", c);
1139 /* standard library files */
1140 /* if (strcmp (port->target, "ds390") == 0) */
1141 if (options.model == MODEL_FLAT24)
1143 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1145 fprintf (lnkfile, "-l %s\n", STD_LIB);
1146 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1147 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1148 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1151 /* additional libraries if any */
1152 for (i = 0; i < nlibFiles; i++)
1153 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1155 /* put in the object files */
1156 if (strcmp (srcFileName, "temp"))
1157 fprintf (lnkfile, "%s ", srcFileName);
1159 for (i = 0; i < nrelFiles; i++)
1160 fprintf (lnkfile, "%s\n", relFiles[i]);
1162 fprintf (lnkfile, "\n-e\n");
1165 if (options.verbose)
1166 printf ("sdcc: Calling linker...\n");
1168 if (port->linker.cmd)
1170 char buffer2[PATH_MAX];
1171 buildCmdLine (buffer2, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1172 buildCmdLine2 (buffer, buffer2);
1176 buildCmdLine2 (buffer, port->linker.mcmd);
1179 if (my_system (buffer))
1184 if (strcmp (srcFileName, "temp") == 0)
1186 /* rename "temp.cdb" to "firstRelFile.cdb" */
1187 char *f = strtok (Safe_strdup (relFiles[0]), ".");
1188 f = strcat (f, ".cdb");
1189 rename ("temp.cdb", f);
1194 /*-----------------------------------------------------------------*/
1195 /* assemble - spawns the assembler with arguments */
1196 /*-----------------------------------------------------------------*/
1198 assemble (char **envp)
1200 if (port->assembler.cmd)
1202 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL,
1203 options.debug ? port->assembler.debug_opts : port->assembler.plain_opts,
1208 buildCmdLine2 (buffer, port->assembler.mcmd);
1211 if (my_system (buffer))
1213 /* either system() or the assembler itself has reported an error
1214 perror ("Cannot exec assembler");
1220 /*-----------------------------------------------------------------*/
1221 /* preProcess - spawns the preprocessor with arguments */
1222 /*-----------------------------------------------------------------*/
1224 preProcess (char **envp)
1228 if (!options.c1mode)
1230 /* if using external stack define the macro */
1231 if (options.useXstack)
1232 addToList (preArgv, "-DSDCC_USE_XSTACK");
1234 /* set the macro for stack autos */
1235 if (options.stackAuto)
1236 addToList (preArgv, "-DSDCC_STACK_AUTO");
1238 /* set the macro for stack autos */
1239 if (options.stack10bit)
1240 addToList (preArgv, "-DSDCC_STACK_TENBIT");
1242 /* set the macro for no overlay */
1243 if (options.noOverlay)
1244 addToList (preArgv, "-DSDCC_NOOVERLAY");
1246 /* set the macro for large model */
1247 switch (options.model)
1250 addToList (preArgv, "-DSDCC_MODEL_LARGE");
1253 addToList (preArgv, "-DSDCC_MODEL_SMALL");
1256 addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1259 addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1262 addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1265 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1269 /* add port (processor information to processor */
1270 addToList (preArgv, "-DSDCC_{port}");
1271 addToList (preArgv, "-D__{port}");
1273 /* standard include path */
1274 if (!options.nostdinc) {
1275 addToList (preArgv, "-I{includedir}");
1278 setMainValue ("cppextraopts", join(preArgv));
1281 preOutName = Safe_strdup (tempfilename ());
1283 /* Have to set cppoutfilename to something, even if just pre-processing. */
1284 setMainValue ("cppoutfilename", preOutName ? preOutName : "");
1286 if (options.verbose)
1287 printf ("sdcc: Calling preprocessor...\n");
1289 buildCmdLine2 (buffer, _preCmd);
1291 if (my_system (buffer))
1293 // @FIX: Dario Vecchio 03-05-2001
1296 unlink (preOutName);
1297 Safe_free (preOutName);
1310 preOutName = fullSrcFileName;
1313 yyin = fopen (preOutName, "r");
1316 perror ("Preproc file not found\n");
1324 _setPaths (const char *pprefix)
1327 Given the prefix and how the directories were layed out at
1328 configure time, see if the library and include directories are
1329 where expected. If so, set.
1331 getPathDifference (buffer, PREFIX, SDCC_INCLUDE_DIR);
1332 strcpy (scratchFileName, pprefix);
1333 strcat (scratchFileName, buffer);
1335 if (pathExists (scratchFileName))
1337 setMainValue ("includedir", scratchFileName);
1344 getPathDifference (buffer, PREFIX, SDCC_LIB_DIR);
1345 strcpy (scratchFileName, pprefix);
1346 strcat (scratchFileName, buffer);
1348 if (pathExists (scratchFileName))
1350 setMainValue ("libdir", scratchFileName);
1361 _discoverPaths (const char *argv0)
1364 1. Try the SDCCDIR environment variable.
1365 2. If (1) fails, and if the argv[0] includes a path, attempt to find the include
1366 and library paths with respect to that. Note that under win32
1367 argv[0] is always the full path to the program.
1368 3. If (1) and (2) fail, fall back to the compile time defaults.
1370 Detecting assumes the same layout as when configured. If the
1371 directories have been further moved about then discovery will
1375 /* Some input cases:
1376 "c:\fish\sdcc\bin\sdcc"
1378 "/home/fish/bin/sdcc"
1380 Note that ./sdcc is explicitly not supported as there isn't
1383 /* bindir is handled differently to the lib and include directories.
1384 It's rather unfortunate, but required due to the different
1385 install and development layouts. Logic is different as well.
1388 if (strchr (argv0, DIR_SEPARATOR_CHAR))
1390 strcpy (scratchFileName, argv0);
1391 *strrchr (scratchFileName, DIR_SEPARATOR_CHAR) = '\0';
1392 setMainValue ("bindir", scratchFileName);
1393 ExePathList[0] = Safe_strdup (scratchFileName);
1395 else if (getenv (SDCCDIR_NAME) != NULL)
1397 getPathDifference (buffer, PREFIX, BINDIR);
1398 strcpy (scratchFileName, getenv (SDCCDIR_NAME));
1399 strcat (scratchFileName, buffer);
1400 setMainValue ("bindir", scratchFileName);
1401 ExePathList[0] = Safe_strdup (scratchFileName);
1405 setMainValue ("bindir", BINDIR);
1406 ExePathList[0] = BINDIR;
1412 if (getenv (SDCCDIR_NAME) != NULL)
1414 if (_setPaths (getenv (SDCCDIR_NAME)))
1416 /* Successfully set. */
1421 /* Include and lib weren't where expected. */
1425 if (strchr (argv0, DIR_SEPARATOR_CHAR))
1427 char *pbase = getPrefixFromBinPath (argv0);
1431 /* A bad path. Skip. */
1435 if (_setPaths (pbase))
1437 /* Successfully set. */
1442 /* Include and lib weren't where expected. */
1447 setMainValue ("includedir", SDCC_INCLUDE_DIR);
1448 setMainValue ("libdir", SDCC_LIB_DIR);
1455 populateMainValues (_baseValues);
1456 setMainValue ("port", port->target);
1457 setMainValue ("objext", port->linker.rel_ext);
1458 setMainValue ("asmext", port->assembler.file_ext);
1460 setMainValue ("fullsrcfilename", fullSrcFileName ? fullSrcFileName : "fullsrcfilename");
1461 setMainValue ("srcfilename", srcFileName ? srcFileName : "srcfilename");
1466 * initialises and calls the parser
1470 main (int argc, char **argv, char **envp)
1472 /* turn all optimizations off by default */
1473 memset (&optimize, 0, sizeof (struct optimize));
1475 /*printVersionInfo (); */
1478 fprintf (stderr, "Build error: no ports are enabled.\n");
1482 _findPort (argc, argv);
1484 if (strcmp(port->target, "mcs51") == 0) {
1485 printf("DS390 jammed in A\n");
1490 /* Initalise the port. */
1494 // Create a default exe search path from the path to the sdcc command
1497 setDefaultOptions ();
1500 options.model = MODEL_SMALL;
1501 options.stack10bit=0;
1504 parseCmdLine (argc, argv);
1506 /* if no input then printUsage & exit */
1507 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1508 (options.c1mode && !srcFileName && !options.out_name))
1515 _discoverPaths (argv[0]);
1523 port->finaliseOptions ();
1530 if (options.verbose)
1531 printf ("sdcc: Generating code...\n");
1537 if (TARGET_IS_PIC) {
1538 /* TSD PIC port hack - if the PIC port option is enabled
1539 and SDCC is used to generate PIC code, then we will
1540 generate .asm files in gpasm's format instead of SDCC's
1543 #if !OPT_DISABLE_PIC
1552 // @FIX: Dario Vecchio 03-05-2001
1555 if (yyin && yyin != stdin)
1557 unlink (preOutName);
1558 Safe_free (preOutName);
1563 if (!options.c1mode && !noAssemble)
1565 if (options.verbose)
1566 printf ("sdcc: Calling assembler...\n");
1572 // @FIX: Dario Vecchio 03-05-2001
1575 if (yyin && yyin != stdin)
1577 unlink (preOutName);
1578 Safe_free (preOutName);
1581 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1594 if (preOutName && !options.c1mode)
1596 unlink (preOutName);
1597 Safe_free (preOutName);
1600 if (!options.cc_only &&
1604 (srcFileName || nrelFiles))
1606 if (port->linker.do_link)
1607 port->linker.do_link ();
1612 if (yyin && yyin != stdin)