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 { 0, OPTION_LARGE_MODEL, NULL, "Far functions, far data" },
138 { 0, OPTION_MEDIUM_MODEL, NULL, "Far functions, near data" },
139 { 0, OPTION_SMALL_MODEL, NULL, "Small model (default)" },
140 { 0, OPTION_FLAT24_MODEL, NULL, NULL },
141 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
142 { 0, OPTION_STACK_8BIT, NULL, NULL },
143 { 0, "--stack-10bit", &options.stack10bit, NULL },
144 { 0, "--xstack", &options.useXstack, "Use external stack" },
145 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
146 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
147 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
148 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
149 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
150 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
151 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or link" },
152 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
153 { 0, "--dumpgcse", &options.dump_gcse, NULL },
154 { 0, "--dumploop", &options.dump_loop, NULL },
155 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
156 { 0, "--dumpliverange", &options.dump_range, NULL },
157 { 0, "--dumpregpack", &options.dump_pack, NULL },
158 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
159 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
160 { 0, OPTION_XRAM_LOC, NULL, NULL },
161 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
162 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
163 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
164 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
165 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
166 { 0, OPTION_IDATA_LOC, NULL, NULL },
167 { 0, OPTION_PEEP_FILE, NULL, NULL },
168 { 0, OPTION_LIB_PATH, NULL, NULL },
169 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
170 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
171 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
172 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
173 { 0, "--cyclomatic", &options.cyclomatic, NULL },
174 { 0, "--nooverlay", &options.noOverlay, NULL },
175 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
176 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
177 { 0, "--peep-asm", &options.asmpeep, NULL },
178 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
179 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
180 { 0, "--stack-after-data", &options.stackOnData, NULL },
181 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
182 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
183 { 0, "--help", NULL, "Display this help" },
184 { 0, OPTION_CALLEE_SAVES, NULL, "Cause the called function to save registers insted of the caller" },
185 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
186 { 0, "--nostdinc", &options.nostdinc, NULL },
187 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
188 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
189 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }
192 /** Table of all unsupported options and help text to display when one
196 /** shortOpt as in OPTIONS. */
198 /** longOpt as in OPTIONS. */
200 /** Message to display inside W_UNSUPPORTED_OPT when this option
205 static const UNSUPPORTEDOPT
206 unsupportedOptTable[] = {
207 { 'a', NULL, "use --stack-auto instead." },
208 { 'g', NULL, "use --generic instead" },
209 { 'X', NULL, "use --xstack-loc instead" },
210 { 'x', NULL, "use --xstack instead" },
211 { 'p', NULL, "use --stack-loc instead" },
212 { 'P', NULL, "use --stack-loc instead" },
213 { 'i', NULL, "use --idata-loc instead" },
214 { 'r', NULL, "use --xdata-loc instead" },
215 { 's', NULL, "use --code-loc instead" },
216 { 'Y', NULL, "use -I instead" }
219 static const char *_preCmd[] =
221 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
222 "$l", "$1", "$2", NULL
227 static PORT *_ports[] =
229 #if !OPT_DISABLE_MCS51
232 #if !OPT_DISABLE_GBZ80
241 #if !OPT_DISABLE_DS390
247 #if !OPT_DISABLE_I186
250 #if !OPT_DISABLE_TLCS900H
255 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
258 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
260 extern void picglue ();
262 /** Sets the port to the one given by the command line option.
263 @param The name minus the option (eg 'mcs51')
264 @return 0 on success.
267 _setPort (const char *name)
270 for (i = 0; i < NUM_PORTS; i++)
272 if (!strcmp (_ports[i]->target, name))
278 /* Error - didnt find */
279 werror (E_UNKNOWN_TARGET, name);
284 _validatePorts (void)
287 for (i = 0; i < NUM_PORTS; i++)
289 if (_ports[i]->magic != PORT_MAGIC)
291 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
296 /*-----------------------------------------------------------------*/
297 /* printVersionInfo - prints the version info */
298 /*-----------------------------------------------------------------*/
306 for (i = 0; i < NUM_PORTS; i++)
307 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
309 fprintf (stderr, " %s"
310 #ifdef SDCC_SUB_VERSION_STR
311 "/" SDCC_SUB_VERSION_STR
319 #if defined(_MSC_VER)
332 "\t-m<proc> - Target processor <proc>. Default %s\n"
333 "\t Try --version for supported values of <proc>\n"
334 "\t--model-large - Large Model\n"
335 "\t--model-small - Small Model (default)\n"
336 "\t--stack-auto - Stack automatic variables\n"
337 "\t--xstack - Use external stack\n"
338 "\t--xram-loc <nnnn> - External Ram start location\n"
339 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
340 "\t--code-loc <nnnn> - Code Segment Location\n"
341 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
342 "\t--data-loc <nnnn> - Direct data start location\n"
343 "\t--idata-loc <nnnn> - Indirect data start location\n"
344 "\t--iram-size <nnnn> - Internal Ram size\n"
345 "\t--nojtbound - Don't generate boundary check for jump tables\n"
346 "\t--generic - All unqualified ptrs converted to '_generic'\n"
347 "PreProcessor Options :-\n"
348 "\t-Dmacro - Define Macro\n"
349 "\t-Ipath - Include \"*.h\" path\n"
350 "Note: this is NOT a complete list of options see docs for details\n",
352 /*-----------------------------------------------------------------*/
353 /* printUsage - prints command line syntax */
354 /*-----------------------------------------------------------------*/
361 "Usage : sdcc [options] filename\n"
365 for (i = 0; i < LENGTH(optionsTable); i++) {
366 fprintf(stdout, " %c%c %-20s %s\n",
367 optionsTable[i].shortOpt !=0 ? '-' : ' ',
368 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
369 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
370 optionsTable[i].help != NULL ? optionsTable[i].help : ""
376 /*-----------------------------------------------------------------*/
377 /* parseWithComma - separates string with comma */
378 /*-----------------------------------------------------------------*/
380 parseWithComma (char **dest, char *src)
384 strtok (src, "\n \t");
385 /* skip the initial white spaces */
386 while (isspace (*src))
403 /*-----------------------------------------------------------------*/
404 /* setDefaultOptions - sets the default options */
405 /*-----------------------------------------------------------------*/
411 for (i = 0; i < 128; i++)
412 preArgv[i] = asmOptions[i] =
413 linkOptions[i] = relFiles[i] = libFiles[i] =
416 /* first the options part */
417 options.stack_loc = 0; /* stack pointer initialised to 0 */
418 options.xstack_loc = 0; /* xternal stack starts at 0 */
419 options.code_loc = 0; /* code starts at 0 */
420 options.data_loc = 0x0030; /* data starts at 0x0030 */
421 options.xdata_loc = 0;
422 options.idata_loc = 0x80;
423 options.genericPtr = 1; /* default on */
425 options.model = port->general.default_model;
426 options.nostdlib = 0;
427 options.nostdinc = 0;
429 options.shortis8bits = 1;
431 options.stack10bit=0;
433 /* now for the optimizations */
434 /* turn on the everything */
435 optimize.global_cse = 1;
440 optimize.loopInvariant = 1;
441 optimize.loopInduction = 1;
443 /* now for the ports */
444 port->setDefaultOptions ();
447 /*-----------------------------------------------------------------*/
448 /* processFile - determines the type of file from the extension */
449 /*-----------------------------------------------------------------*/
451 processFile (char *s)
455 /* get the file extension */
456 fext = s + strlen (s);
457 while ((fext != s) && *fext != '.')
460 /* now if no '.' then we don't know what the file type is
461 so give a warning and return */
464 werror (W_UNKNOWN_FEXT, s);
468 /* otherwise depending on the file type */
469 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
471 /* source file name : not if we already have a
475 werror (W_TOO_MANY_SRC, s);
479 /* the only source file */
480 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
482 werror (E_FILE_OPEN_ERR, s);
486 /* copy the file name into the buffer */
489 /* get rid of the "." */
490 strtok (buffer, ".");
491 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
492 strcpy (srcFileName, buffer);
494 /* get rid of any path information
495 for the module name; do this by going
496 backwards till we get to either '/' or '\' or ':'
497 or start of buffer */
498 fext = buffer + strlen (buffer);
499 while (fext != buffer &&
500 *(fext - 1) != '\\' &&
501 *(fext - 1) != '/' &&
504 moduleName = Safe_calloc (1, strlen (fext) + 1);
505 strcpy (moduleName, fext);
510 /* if the extention is type .rel or .r or .REL or .R
511 addtional object file will be passed to the linker */
512 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
513 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
514 strcmp (fext, port->linker.rel_ext) == 0)
516 relFiles[nrelFiles++] = s;
520 /* if .lib or .LIB */
521 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
523 libFiles[nlibFiles++] = s;
527 werror (W_UNKNOWN_FEXT, s);
532 _processC1Arg (char *s)
536 if (options.out_name)
538 werror (W_TOO_MANY_SRC, s);
541 options.out_name = strdup (s);
550 _addToList (const char **list, const char *str)
552 /* This is the bad way to do things :) */
555 *list = strdup (str);
558 werror (E_OUT_OF_MEM, __FILE__, 0);
565 _setModel (int model, const char *sz)
567 if (port->general.supported_models & model)
568 options.model = model;
570 werror (W_UNSUPPORTED_MODEL, sz, port->target);
573 /** Gets the string argument to this option. If the option is '--opt'
574 then for input of '--optxyz' or '--opt xyz' returns xyz.
577 getStringArg(const char *szStart, char **argv, int *pi)
579 if (argv[*pi][strlen(szStart)]) {
580 return &argv[*pi][strlen(szStart)];
583 return argv[++(*pi)];
587 /** Gets the integer argument to this option using the same rules as
591 getIntArg(const char *szStart, char **argv, int *pi)
593 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi)));
597 tryHandleUnsupportedOpt(char **argv, int *pi)
599 if (argv[*pi][0] == '-')
601 const char *longOpt = "";
605 if (argv[*pi][1] == '-')
612 shortOpt = argv[*pi][1];
614 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
616 if (unsupportedOptTable[i].shortOpt == shortOpt ||
617 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
618 // Found an unsupported opt.
620 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
621 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
625 // Didn't find in the table
630 // Not an option, so can't be unsupported :)
636 tryHandleSimpleOpt(char **argv, int *pi)
638 if (argv[*pi][0] == '-')
640 const char *longOpt = "";
644 if (argv[*pi][1] == '-')
651 shortOpt = argv[*pi][1];
654 for (i = 0; i < LENGTH(optionsTable); i++)
656 if (optionsTable[i].shortOpt == shortOpt ||
657 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
659 // If it is a flag then we can handle it here
660 if (optionsTable[i].pparameter != NULL)
662 (*optionsTable[i].pparameter)++;
666 // Not a flag. Handled manually later.
671 // Didn't find in the table
676 // Not an option, so can't be handled.
681 /*-----------------------------------------------------------------*/
682 /* parseCmdLine - parses the command line and sets the options */
683 /*-----------------------------------------------------------------*/
685 parseCmdLine (int argc, char **argv)
689 /* go thru all whole command line */
690 for (i = 1; i < argc; i++)
695 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
700 if (tryHandleSimpleOpt(argv, &i) == TRUE)
706 if (argv[i][0] == '-' && argv[i][1] == '-')
708 if (strcmp (argv[i], OPTION_HELP) == 0)
714 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
716 options.stack10bit = 0;
720 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
726 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
728 _setModel (MODEL_LARGE, argv[i]);
732 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
734 _setModel (MODEL_MEDIUM, argv[i]);
738 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
740 _setModel (MODEL_SMALL, argv[i]);
744 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
746 _setModel (MODEL_FLAT24, argv[i]);
750 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
752 options.dump_rassgn =
758 options.dump_raw = 1;
762 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
764 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i);
768 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
770 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i);
774 if (strcmp (argv[i], OPTION_VERSION) == 0)
781 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
783 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i));
787 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
789 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i);
793 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
795 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i);
799 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
801 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i);
805 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
807 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i);
811 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
813 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i);
817 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
819 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i);
823 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
825 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i);
829 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
831 optimize.global_cse = 0;
835 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
837 optimize.loopInvariant = 0;
841 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
843 optimize.loopInduction = 0;
847 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
849 setErrorLogLevel(ERROR_LEVEL_WARNING);
853 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0) {
854 options.shortis8bits=1;
858 if (!port->parseOption (&argc, argv, &i))
860 werror (W_UNKNOWN_OPTION, argv[i]);
868 /* if preceded by '-' then option */
879 /* Used to select the port */
880 _setPort (argv[i] + 2);
888 libPaths[nlibPaths++] = getStringArg("-L", argv, &i);
893 if (argv[i][2] == 'l')
895 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i));
899 /* assembler options */
900 if (argv[i][2] == 'a')
902 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i));
906 werror (W_UNKNOWN_OPTION, argv[i]);
916 /* preprocessor options */
920 _addToList (preArgv, "-M");
925 _addToList (preArgv, "-C");
934 char sOpt = argv[i][1];
937 if (argv[i][2] == ' ' || argv[i][2] == '\0')
943 werror(E_ARGUMENT_MISSING, argv[i-1]);
957 sprintf (buffer, "-%c%s", sOpt, rest);
958 _addToList (preArgv, buffer);
963 if (!port->parseOption (&argc, argv, &i))
964 werror (W_UNKNOWN_OPTION, argv[i]);
969 if (!port->parseOption (&argc, argv, &i))
971 /* no option must be a filename */
973 _processC1Arg (argv[i]);
975 processFile (argv[i]);
979 /* set up external stack location if not explicitly specified */
980 if (!options.xstack_loc)
981 options.xstack_loc = options.xdata_loc;
983 /* if debug option is set the open the cdbFile */
984 if (options.debug && srcFileName)
986 sprintf (scratchFileName, "%s.cdb", srcFileName);
987 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
988 werror (E_FILE_OPEN_ERR, scratchFileName);
991 /* add a module record */
992 fprintf (cdbFile, "M:%s\n", moduleName);
998 /*-----------------------------------------------------------------*/
999 /* linkEdit : - calls the linkage editor with options */
1000 /*-----------------------------------------------------------------*/
1002 linkEdit (char **envp)
1009 srcFileName = "temp";
1011 /* first we need to create the <filename>.lnk file */
1012 sprintf (scratchFileName, "%s.lnk", srcFileName);
1013 if (!(lnkfile = fopen (scratchFileName, "w")))
1015 werror (E_FILE_OPEN_ERR, scratchFileName);
1019 /* now write the options */
1020 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1022 /* if iram size specified */
1023 if (options.iram_size)
1024 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1027 fprintf (lnkfile, "-z\n");
1029 #define WRITE_SEG_LOC(N, L) \
1030 segName = strdup(N); \
1031 c = strtok(segName, " \t"); \
1032 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1033 if (segName) { free(segName); }
1035 /* code segment start */
1036 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1038 /* data segment start */
1039 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1042 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1045 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1047 /* bit segment start */
1048 WRITE_SEG_LOC (BIT_NAME, 0);
1050 /* add the extra linker options */
1051 for (i = 0; linkOptions[i]; i++)
1052 fprintf (lnkfile, "%s\n", linkOptions[i]);
1054 /* other library paths if specified */
1055 for (i = 0; i < nlibPaths; i++)
1056 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1058 /* standard library path */
1059 if (!options.nostdlib)
1061 if (TARGET_IS_DS390)
1067 switch (options.model)
1079 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1084 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1086 /* standard library files */
1087 if (strcmp (port->target, "ds390") == 0)
1089 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1091 fprintf (lnkfile, "-l %s\n", STD_LIB);
1092 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1093 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1094 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1097 /* additional libraries if any */
1098 for (i = 0; i < nlibFiles; i++)
1099 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1101 /* put in the object files */
1102 if (strcmp (srcFileName, "temp"))
1103 fprintf (lnkfile, "%s ", srcFileName);
1105 for (i = 0; i < nrelFiles; i++)
1106 fprintf (lnkfile, "%s\n", relFiles[i]);
1108 fprintf (lnkfile, "\n-e\n");
1111 if (options.verbose)
1112 printf ("sdcc: Calling linker...\n");
1114 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1115 if (my_system (buffer))
1120 if (strcmp (srcFileName, "temp") == 0)
1122 /* rename "temp.cdb" to "firstRelFile.cdb" */
1123 char *f = strtok (strdup (relFiles[0]), ".");
1124 f = strcat (f, ".cdb");
1125 rename ("temp.cdb", f);
1130 /*-----------------------------------------------------------------*/
1131 /* assemble - spawns the assembler with arguments */
1132 /*-----------------------------------------------------------------*/
1134 assemble (char **envp)
1136 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1137 if (my_system (buffer))
1139 /* either system() or the assembler itself has reported an error
1140 perror ("Cannot exec assembler");
1148 /*-----------------------------------------------------------------*/
1149 /* preProcess - spawns the preprocessor with arguments */
1150 /*-----------------------------------------------------------------*/
1152 preProcess (char **envp)
1158 if (!options.c1mode)
1160 /* if using external stack define the macro */
1161 if (options.useXstack)
1162 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1164 /* set the macro for stack autos */
1165 if (options.stackAuto)
1166 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1168 /* set the macro for stack autos */
1169 if (options.stack10bit)
1170 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1172 /* set the macro for large model */
1173 switch (options.model)
1176 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1179 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1182 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1185 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1188 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1191 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1195 /* standard include path */
1196 if (!options.nostdinc) {
1197 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1200 /* add port (processor information to processor */
1201 sprintf (procDef, "-DSDCC_%s", port->target);
1202 _addToList (preArgv, procDef);
1203 sprintf (procDef, "-D__%s", port->target);
1204 _addToList (preArgv, procDef);
1207 preOutName = strdup (tmpnam (NULL));
1209 if (options.verbose)
1210 printf ("sdcc: Calling preprocessor...\n");
1212 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1213 preOutName, srcFileName, preArgv);
1214 if (my_system (buffer))
1216 // @FIX: Dario Vecchio 03-05-2001
1219 unlink (preOutName);
1233 preOutName = fullSrcFileName;
1236 yyin = fopen (preOutName, "r");
1239 perror ("Preproc file not found\n");
1247 _findPort (int argc, char **argv)
1253 if (!strncmp (*argv, "-m", 2))
1255 _setPort (*argv + 2);
1260 /* Use the first in the list */
1266 * initialises and calls the parser
1270 main (int argc, char **argv, char **envp)
1272 /* turn all optimizations off by default */
1273 memset (&optimize, 0, sizeof (struct optimize));
1275 /*printVersionInfo (); */
1278 fprintf (stderr, "Build error: no ports are enabled.\n");
1282 _findPort (argc, argv);
1283 /* Initalise the port. */
1287 // Create a default exe search path from the path to the sdcc command
1291 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1293 strcpy (DefaultExePath, argv[0]);
1294 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1295 ExePathList[0] = DefaultExePath;
1299 setDefaultOptions ();
1300 parseCmdLine (argc, argv);
1304 port->finaliseOptions ();
1306 /* if no input then printUsage & exit */
1307 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1308 (options.c1mode && !srcFileName && !options.out_name))
1323 if (options.verbose)
1324 printf ("sdcc: Generating code...\n");
1330 if (TARGET_IS_PIC) {
1331 /* TSD PIC port hack - if the PIC port option is enabled
1332 and SDCC is used to generate PIC code, then we will
1333 generate .asm files in gpasm's format instead of SDCC's
1336 #if !OPT_DISABLE_PIC
1345 // @FIX: Dario Vecchio 03-05-2001
1348 if (yyin && yyin != stdin)
1350 unlink (preOutName);
1356 if (!options.c1mode && !noAssemble)
1358 if (options.verbose)
1359 printf ("sdcc: Calling assembler...\n");
1365 // @FIX: Dario Vecchio 03-05-2001
1368 if (yyin && yyin != stdin)
1370 unlink (preOutName);
1384 if (!options.cc_only &&
1388 (srcFileName || nrelFiles))
1390 if (port->linker.do_link)
1391 port->linker.do_link ();
1396 if (yyin && yyin != stdin)
1399 if (preOutName && !options.c1mode)
1401 unlink (preOutName);