1 /*-------------------------------------------------------------------------
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
38 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
43 extern int yyparse ();
45 FILE *srcFile; /* source file */
46 FILE *cdbFile = NULL; /* debugger information output file */
47 char *fullSrcFileName; /* full name for the source file */
48 char *srcFileName; /* source file name with the .c stripped */
49 char *moduleName; /* module name is srcFilename stripped of any path */
50 const char *preArgv[128]; /* pre-processor arguments */
52 struct optimize optimize;
53 struct options options;
54 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
57 char *linkOptions[128];
58 const char *asmOptions[128];
65 bool verboseExec = FALSE;
68 // Globally accessible scratch buffer for file names.
69 char scratchFileName[FILENAME_MAX];
71 // In MSC VC6 default search path for exe's to path for this
73 char DefaultExePath[128];
75 #define OPTION_HELP "-help"
77 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
79 #define OPTION_STACK_8BIT "--stack-8bit"
80 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
81 #define OPTION_LARGE_MODEL "--model-large"
82 #define OPTION_MEDIUM_MODEL "--model-medium"
83 #define OPTION_SMALL_MODEL "--model-small"
84 #define OPTION_FLAT24_MODEL "--model-flat24"
85 #define OPTION_DUMP_ALL "--dumpall"
86 #define OPTION_PEEP_FILE "--peep-file"
87 #define OPTION_LIB_PATH "--lib-path"
88 #define OPTION_XSTACK_LOC "--xstack-loc"
89 #define OPTION_CALLEE_SAVES "--callee-saves"
90 #define OPTION_STACK_LOC "--stack-loc"
91 #define OPTION_XRAM_LOC "--xram-loc"
92 #define OPTION_IRAM_SIZE "--iram-size"
93 #define OPTION_VERSION "--version"
94 #define OPTION_DATA_LOC "--data-loc"
95 #define OPTION_CODE_LOC "--code-loc"
96 #define OPTION_IDATA_LOC "--idata-loc"
97 #define OPTION_NO_LOOP_INV "--noinvariant"
98 #define OPTION_NO_LOOP_IND "--noinduction"
99 #define OPTION_LESS_PEDANTIC "--lesspedantic"
100 #define OPTION_NO_GCSE "--nogcse"
101 #define OPTION_SHORT_IS_8BITS "--short-is-8bits"
103 /** Table of all options supported by all ports.
105 * A reference for all options.
106 * An easy way to maintain help for the options.
107 * Automatic support for setting flags on simple options.
110 /** The short option character e.g. 'h' for -h. 0 for none. */
112 /** Long option e.g. "--help". Includes the -- prefix. NULL for
115 /** Pointer to an int that will be incremented every time the
116 option is encountered. May be NULL.
119 /** Help text to go with this option. May be NULL. */
125 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
126 { 'd', NULL, NULL, NULL },
127 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
128 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
129 { 'A', NULL, NULL, NULL },
130 { 'U', NULL, NULL, NULL },
131 { 'C', NULL, NULL, "Preprocessor option" },
132 { 'M', NULL, NULL, "Preprocessor option" },
133 { 'V', NULL, &verboseExec, "Execute verbosely. Show sub commands as they are run" },
134 { 'S', NULL, &noAssemble, "Assemble only" },
135 { 'W', NULL, NULL, "Pass through options to the assembler (a) or linker (l)" },
136 { 'L', NULL, NULL, "Add the next field to the library search path" },
137 { 'l', NULL, NULL, "Include the given library in the link" },
138 { 0, OPTION_LARGE_MODEL, NULL, "Far functions, far data" },
139 { 0, OPTION_MEDIUM_MODEL, NULL, "Far functions, near data" },
140 { 0, OPTION_SMALL_MODEL, NULL, "Small model (default)" },
141 { 0, OPTION_FLAT24_MODEL, NULL, NULL },
142 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
143 { 0, OPTION_STACK_8BIT, NULL, NULL },
144 { 0, "--stack-10bit", &options.stack10bit, NULL },
145 { 0, "--xstack", &options.useXstack, "Use external stack" },
146 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
147 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
148 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
149 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
150 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
151 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
152 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or link" },
153 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
154 { 0, "--dumpgcse", &options.dump_gcse, NULL },
155 { 0, "--dumploop", &options.dump_loop, NULL },
156 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
157 { 0, "--dumpliverange", &options.dump_range, NULL },
158 { 0, "--dumpregpack", &options.dump_pack, NULL },
159 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
160 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
161 { 0, OPTION_XRAM_LOC, NULL, NULL },
162 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
163 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
164 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
165 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
166 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
167 { 0, OPTION_IDATA_LOC, NULL, NULL },
168 { 0, OPTION_PEEP_FILE, NULL, NULL },
169 { 0, OPTION_LIB_PATH, NULL, NULL },
170 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
171 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
172 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
173 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
174 { 0, "--cyclomatic", &options.cyclomatic, NULL },
175 { 0, "--nooverlay", &options.noOverlay, NULL },
176 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
177 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
178 { 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
179 { 0, "--peep-asm", &options.asmpeep, NULL },
180 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
181 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
182 { 0, "--stack-after-data", &options.stackOnData, NULL },
183 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
184 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
185 { 0, "--help", NULL, "Display this help" },
186 { 0, OPTION_CALLEE_SAVES, NULL, "Cause the called function to save registers insted of the caller" },
187 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
188 { 0, "--nostdinc", &options.nostdinc, NULL },
189 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
190 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
191 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }
194 /** Table of all unsupported options and help text to display when one
198 /** shortOpt as in OPTIONS. */
200 /** longOpt as in OPTIONS. */
202 /** Message to display inside W_UNSUPPORTED_OPT when this option
207 static const UNSUPPORTEDOPT
208 unsupportedOptTable[] = {
209 { 'a', NULL, "use --stack-auto instead." },
210 { 'g', NULL, "use --generic instead" },
211 { 'X', NULL, "use --xstack-loc instead" },
212 { 'x', NULL, "use --xstack instead" },
213 { 'p', NULL, "use --stack-loc instead" },
214 { 'P', NULL, "use --stack-loc instead" },
215 { 'i', NULL, "use --idata-loc instead" },
216 { 'r', NULL, "use --xdata-loc instead" },
217 { 's', NULL, "use --code-loc instead" },
218 { 'Y', NULL, "use -I instead" }
221 static const char *_preCmd[] =
223 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
224 "$l", "$1", "$2", NULL
229 static PORT *_ports[] =
231 #if !OPT_DISABLE_MCS51
234 #if !OPT_DISABLE_GBZ80
243 #if !OPT_DISABLE_DS390
249 #if !OPT_DISABLE_I186
252 #if !OPT_DISABLE_TLCS900H
257 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
260 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
262 extern void picglue ();
264 /** Sets the port to the one given by the command line option.
265 @param The name minus the option (eg 'mcs51')
266 @return 0 on success.
269 _setPort (const char *name)
272 for (i = 0; i < NUM_PORTS; i++)
274 if (!strcmp (_ports[i]->target, name))
280 /* Error - didnt find */
281 werror (E_UNKNOWN_TARGET, name);
286 _validatePorts (void)
289 for (i = 0; i < NUM_PORTS; i++)
291 if (_ports[i]->magic != PORT_MAGIC)
293 wassertl (0, "Port definition structure is incomplete");
297 /*-----------------------------------------------------------------*/
298 /* printVersionInfo - prints the version info */
299 /*-----------------------------------------------------------------*/
307 for (i = 0; i < NUM_PORTS; i++)
308 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
310 fprintf (stderr, " %s"
311 #ifdef SDCC_SUB_VERSION_STR
312 "/" SDCC_SUB_VERSION_STR
320 #if defined(_MSC_VER)
333 "\t-m<proc> - Target processor <proc>. Default %s\n"
334 "\t Try --version for supported values of <proc>\n"
335 "\t--model-large - Large Model\n"
336 "\t--model-small - Small Model (default)\n"
337 "\t--stack-auto - Stack automatic variables\n"
338 "\t--xstack - Use external stack\n"
339 "\t--xram-loc <nnnn> - External Ram start location\n"
340 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
341 "\t--code-loc <nnnn> - Code Segment Location\n"
342 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
343 "\t--data-loc <nnnn> - Direct data start location\n"
344 "\t--idata-loc <nnnn> - Indirect data start location\n"
345 "\t--iram-size <nnnn> - Internal Ram size\n"
346 "\t--nojtbound - Don't generate boundary check for jump tables\n"
347 "\t--generic - All unqualified ptrs converted to '_generic'\n"
348 "PreProcessor Options :-\n"
349 "\t-Dmacro - Define Macro\n"
350 "\t-Ipath - Include \"*.h\" path\n"
351 "Note: this is NOT a complete list of options see docs for details\n",
353 /*-----------------------------------------------------------------*/
354 /* printUsage - prints command line syntax */
355 /*-----------------------------------------------------------------*/
362 "Usage : sdcc [options] filename\n"
366 for (i = 0; i < LENGTH(optionsTable); i++) {
367 fprintf(stdout, " %c%c %-20s %s\n",
368 optionsTable[i].shortOpt !=0 ? '-' : ' ',
369 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
370 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
371 optionsTable[i].help != NULL ? optionsTable[i].help : ""
377 /*-----------------------------------------------------------------*/
378 /* parseWithComma - separates string with comma */
379 /*-----------------------------------------------------------------*/
381 parseWithComma (char **dest, char *src)
385 strtok (src, "\n \t");
386 /* skip the initial white spaces */
387 while (isspace (*src))
404 /*-----------------------------------------------------------------*/
405 /* setDefaultOptions - sets the default options */
406 /*-----------------------------------------------------------------*/
412 for (i = 0; i < 128; i++)
413 preArgv[i] = asmOptions[i] =
414 linkOptions[i] = relFiles[i] = libFiles[i] =
417 /* first the options part */
418 options.stack_loc = 0; /* stack pointer initialised to 0 */
419 options.xstack_loc = 0; /* xternal stack starts at 0 */
420 options.code_loc = 0; /* code starts at 0 */
421 options.data_loc = 0x0030; /* data starts at 0x0030 */
422 options.xdata_loc = 0;
423 options.idata_loc = 0x80;
424 options.genericPtr = 1; /* default on */
426 options.model = port->general.default_model;
427 options.nostdlib = 0;
428 options.nostdinc = 0;
430 options.shortis8bits = 1;
432 options.stack10bit=0;
434 /* now for the optimizations */
435 /* turn on the everything */
436 optimize.global_cse = 1;
441 optimize.loopInvariant = 1;
442 optimize.loopInduction = 1;
444 /* now for the ports */
445 port->setDefaultOptions ();
448 /*-----------------------------------------------------------------*/
449 /* processFile - determines the type of file from the extension */
450 /*-----------------------------------------------------------------*/
452 processFile (char *s)
456 /* get the file extension */
457 fext = s + strlen (s);
458 while ((fext != s) && *fext != '.')
461 /* now if no '.' then we don't know what the file type is
462 so give a warning and return */
465 werror (W_UNKNOWN_FEXT, s);
469 /* otherwise depending on the file type */
470 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
472 /* source file name : not if we already have a
476 werror (W_TOO_MANY_SRC, s);
480 /* the only source file */
481 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
483 werror (E_FILE_OPEN_ERR, s);
487 /* copy the file name into the buffer */
490 /* get rid of the "." */
491 strtok (buffer, ".");
492 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
493 strcpy (srcFileName, buffer);
495 /* get rid of any path information
496 for the module name; do this by going
497 backwards till we get to either '/' or '\' or ':'
498 or start of buffer */
499 fext = buffer + strlen (buffer);
500 while (fext != buffer &&
501 *(fext - 1) != '\\' &&
502 *(fext - 1) != '/' &&
505 moduleName = Safe_calloc (1, strlen (fext) + 1);
506 strcpy (moduleName, fext);
511 /* if the extention is type .rel or .r or .REL or .R
512 addtional object file will be passed to the linker */
513 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
514 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
515 strcmp (fext, port->linker.rel_ext) == 0)
517 relFiles[nrelFiles++] = s;
521 /* if .lib or .LIB */
522 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
524 libFiles[nlibFiles++] = s;
528 werror (W_UNKNOWN_FEXT, s);
533 _processC1Arg (char *s)
537 if (options.out_name)
539 werror (W_TOO_MANY_SRC, s);
542 options.out_name = strdup (s);
551 _addToList (const char **list, const char *str)
553 /* This is the bad way to do things :) */
556 *list = strdup (str);
559 werror (E_OUT_OF_MEM, __FILE__, 0);
566 _setModel (int model, const char *sz)
568 if (port->general.supported_models & model)
569 options.model = model;
571 werror (W_UNSUPPORTED_MODEL, sz, port->target);
574 /** Gets the string argument to this option. If the option is '--opt'
575 then for input of '--optxyz' or '--opt xyz' returns xyz.
578 getStringArg(const char *szStart, char **argv, int *pi)
580 if (argv[*pi][strlen(szStart)]) {
581 return &argv[*pi][strlen(szStart)];
584 return argv[++(*pi)];
588 /** Gets the integer argument to this option using the same rules as
592 getIntArg(const char *szStart, char **argv, int *pi)
594 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi)));
598 tryHandleUnsupportedOpt(char **argv, int *pi)
600 if (argv[*pi][0] == '-')
602 const char *longOpt = "";
606 if (argv[*pi][1] == '-')
613 shortOpt = argv[*pi][1];
615 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
617 if (unsupportedOptTable[i].shortOpt == shortOpt ||
618 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
619 // Found an unsupported opt.
621 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
622 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
626 // Didn't find in the table
631 // Not an option, so can't be unsupported :)
637 tryHandleSimpleOpt(char **argv, int *pi)
639 if (argv[*pi][0] == '-')
641 const char *longOpt = "";
645 if (argv[*pi][1] == '-')
652 shortOpt = argv[*pi][1];
655 for (i = 0; i < LENGTH(optionsTable); i++)
657 if (optionsTable[i].shortOpt == shortOpt ||
658 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
660 // If it is a flag then we can handle it here
661 if (optionsTable[i].pparameter != NULL)
663 (*optionsTable[i].pparameter)++;
667 // Not a flag. Handled manually later.
672 // Didn't find in the table
677 // Not an option, so can't be handled.
682 /*-----------------------------------------------------------------*/
683 /* parseCmdLine - parses the command line and sets the options */
684 /*-----------------------------------------------------------------*/
686 parseCmdLine (int argc, char **argv)
690 /* go thru all whole command line */
691 for (i = 1; i < argc; i++)
696 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
701 if (tryHandleSimpleOpt(argv, &i) == TRUE)
707 if (argv[i][0] == '-' && argv[i][1] == '-')
709 if (strcmp (argv[i], OPTION_HELP) == 0)
715 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
717 options.stack10bit = 0;
721 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
727 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
729 _setModel (MODEL_LARGE, argv[i]);
733 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
735 _setModel (MODEL_MEDIUM, argv[i]);
739 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
741 _setModel (MODEL_SMALL, argv[i]);
745 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
747 _setModel (MODEL_FLAT24, argv[i]);
751 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
753 options.dump_rassgn =
759 options.dump_raw = 1;
763 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
765 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i);
769 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
771 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i);
775 if (strcmp (argv[i], OPTION_VERSION) == 0)
782 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
784 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i));
788 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
790 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i);
794 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
796 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i);
800 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
802 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i);
806 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
808 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i);
812 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
814 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i);
818 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
820 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i);
824 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
826 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i);
830 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
832 optimize.global_cse = 0;
836 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
838 optimize.loopInvariant = 0;
842 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
844 optimize.loopInduction = 0;
848 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
850 setErrorLogLevel(ERROR_LEVEL_WARNING);
854 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0) {
855 options.shortis8bits=1;
859 if (!port->parseOption (&argc, argv, &i))
861 werror (W_UNKNOWN_OPTION, argv[i]);
869 /* if preceded by '-' then option */
880 /* Used to select the port */
881 _setPort (argv[i] + 2);
889 libPaths[nlibPaths++] = getStringArg("-L", argv, &i);
893 libFiles[nlibFiles++] = getStringArg("-l", argv, &i);
898 if (argv[i][2] == 'l')
900 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i));
904 /* assembler options */
905 if (argv[i][2] == 'a')
907 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i));
911 werror (W_UNKNOWN_OPTION, argv[i]);
921 /* preprocessor options */
925 _addToList (preArgv, "-M");
930 _addToList (preArgv, "-C");
939 char sOpt = argv[i][1];
942 if (argv[i][2] == ' ' || argv[i][2] == '\0')
948 werror(E_ARGUMENT_MISSING, argv[i-1]);
962 sprintf (buffer, "-%c%s", sOpt, rest);
963 _addToList (preArgv, buffer);
968 if (!port->parseOption (&argc, argv, &i))
969 werror (W_UNKNOWN_OPTION, argv[i]);
974 if (!port->parseOption (&argc, argv, &i))
976 /* no option must be a filename */
978 _processC1Arg (argv[i]);
980 processFile (argv[i]);
984 /* set up external stack location if not explicitly specified */
985 if (!options.xstack_loc)
986 options.xstack_loc = options.xdata_loc;
988 /* if debug option is set the open the cdbFile */
989 if (options.debug && srcFileName)
991 sprintf (scratchFileName, "%s.cdb", srcFileName);
992 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
993 werror (E_FILE_OPEN_ERR, scratchFileName);
996 /* add a module record */
997 fprintf (cdbFile, "M:%s\n", moduleName);
1003 /*-----------------------------------------------------------------*/
1004 /* linkEdit : - calls the linkage editor with options */
1005 /*-----------------------------------------------------------------*/
1007 linkEdit (char **envp)
1014 srcFileName = "temp";
1016 /* first we need to create the <filename>.lnk file */
1017 sprintf (scratchFileName, "%s.lnk", srcFileName);
1018 if (!(lnkfile = fopen (scratchFileName, "w")))
1020 werror (E_FILE_OPEN_ERR, scratchFileName);
1024 /* now write the options */
1025 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1027 /* if iram size specified */
1028 if (options.iram_size)
1029 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1032 fprintf (lnkfile, "-z\n");
1034 #define WRITE_SEG_LOC(N, L) \
1035 segName = strdup(N); \
1036 c = strtok(segName, " \t"); \
1037 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1038 if (segName) { free(segName); }
1040 /* code segment start */
1041 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1043 /* data segment start */
1044 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1047 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1050 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1052 /* bit segment start */
1053 WRITE_SEG_LOC (BIT_NAME, 0);
1055 /* add the extra linker options */
1056 for (i = 0; linkOptions[i]; i++)
1057 fprintf (lnkfile, "%s\n", linkOptions[i]);
1059 /* other library paths if specified */
1060 for (i = 0; i < nlibPaths; i++)
1061 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1063 /* standard library path */
1064 if (!options.nostdlib)
1066 if (TARGET_IS_DS390)
1072 switch (options.model)
1084 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1089 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1091 /* standard library files */
1092 if (strcmp (port->target, "ds390") == 0)
1094 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1096 fprintf (lnkfile, "-l %s\n", STD_LIB);
1097 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1098 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1099 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1102 /* additional libraries if any */
1103 for (i = 0; i < nlibFiles; i++)
1104 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1106 /* put in the object files */
1107 if (strcmp (srcFileName, "temp"))
1108 fprintf (lnkfile, "%s ", srcFileName);
1110 for (i = 0; i < nrelFiles; i++)
1111 fprintf (lnkfile, "%s\n", relFiles[i]);
1113 fprintf (lnkfile, "\n-e\n");
1116 if (options.verbose)
1117 printf ("sdcc: Calling linker...\n");
1119 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1120 if (my_system (buffer))
1125 if (strcmp (srcFileName, "temp") == 0)
1127 /* rename "temp.cdb" to "firstRelFile.cdb" */
1128 char *f = strtok (strdup (relFiles[0]), ".");
1129 f = strcat (f, ".cdb");
1130 rename ("temp.cdb", f);
1135 /*-----------------------------------------------------------------*/
1136 /* assemble - spawns the assembler with arguments */
1137 /*-----------------------------------------------------------------*/
1139 assemble (char **envp)
1141 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1142 if (my_system (buffer))
1144 /* either system() or the assembler itself has reported an error
1145 perror ("Cannot exec assembler");
1153 /*-----------------------------------------------------------------*/
1154 /* preProcess - spawns the preprocessor with arguments */
1155 /*-----------------------------------------------------------------*/
1157 preProcess (char **envp)
1163 if (!options.c1mode)
1165 /* if using external stack define the macro */
1166 if (options.useXstack)
1167 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1169 /* set the macro for stack autos */
1170 if (options.stackAuto)
1171 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1173 /* set the macro for stack autos */
1174 if (options.stack10bit)
1175 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1177 /* set the macro for large model */
1178 switch (options.model)
1181 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1184 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1187 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1190 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1193 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1196 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1200 /* standard include path */
1201 if (!options.nostdinc) {
1202 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1205 /* add port (processor information to processor */
1206 sprintf (procDef, "-DSDCC_%s", port->target);
1207 _addToList (preArgv, procDef);
1208 sprintf (procDef, "-D__%s", port->target);
1209 _addToList (preArgv, procDef);
1212 preOutName = strdup (tmpnam (NULL));
1214 if (options.verbose)
1215 printf ("sdcc: Calling preprocessor...\n");
1217 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1218 preOutName, srcFileName, preArgv);
1219 if (my_system (buffer))
1221 // @FIX: Dario Vecchio 03-05-2001
1224 unlink (preOutName);
1238 preOutName = fullSrcFileName;
1241 yyin = fopen (preOutName, "r");
1244 perror ("Preproc file not found\n");
1252 _findPort (int argc, char **argv)
1258 if (!strncmp (*argv, "-m", 2))
1260 _setPort (*argv + 2);
1265 /* Use the first in the list */
1271 * initialises and calls the parser
1275 main (int argc, char **argv, char **envp)
1277 /* turn all optimizations off by default */
1278 memset (&optimize, 0, sizeof (struct optimize));
1280 /*printVersionInfo (); */
1283 fprintf (stderr, "Build error: no ports are enabled.\n");
1287 _findPort (argc, argv);
1288 /* Initalise the port. */
1292 // Create a default exe search path from the path to the sdcc command
1296 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1298 strcpy (DefaultExePath, argv[0]);
1299 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1300 ExePathList[0] = DefaultExePath;
1304 setDefaultOptions ();
1305 parseCmdLine (argc, argv);
1309 port->finaliseOptions ();
1311 /* if no input then printUsage & exit */
1312 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1313 (options.c1mode && !srcFileName && !options.out_name))
1328 if (options.verbose)
1329 printf ("sdcc: Generating code...\n");
1335 if (TARGET_IS_PIC) {
1336 /* TSD PIC port hack - if the PIC port option is enabled
1337 and SDCC is used to generate PIC code, then we will
1338 generate .asm files in gpasm's format instead of SDCC's
1341 #if !OPT_DISABLE_PIC
1350 // @FIX: Dario Vecchio 03-05-2001
1353 if (yyin && yyin != stdin)
1355 unlink (preOutName);
1361 if (!options.c1mode && !noAssemble)
1363 if (options.verbose)
1364 printf ("sdcc: Calling assembler...\n");
1370 // @FIX: Dario Vecchio 03-05-2001
1373 if (yyin && yyin != stdin)
1375 unlink (preOutName);
1389 if (!options.cc_only &&
1393 (srcFileName || nrelFiles))
1395 if (port->linker.do_link)
1396 port->linker.do_link ();
1401 if (yyin && yyin != stdin)
1404 if (preOutName && !options.c1mode)
1406 unlink (preOutName);