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 // This is a bit messy because we define link ourself
39 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
44 // No unistd.h in Borland C++
46 extern int access (const char *, int);
53 extern int yyparse ();
55 FILE *srcFile; /* source file */
56 FILE *cdbFile = NULL; /* debugger information output file */
57 char *fullSrcFileName; /* full name for the source file */
58 char *srcFileName; /* source file name with the .c stripped */
59 char *moduleName; /* module name is srcFilename stripped of any path */
60 const char *preArgv[128]; /* pre-processor arguments */
62 struct optimize optimize;
63 struct options options;
64 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
67 char *linkOptions[128];
68 const char *asmOptions[128];
75 bool verboseExec = FALSE;
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_CHAR "--short-is-char"
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, "Assemble only" },
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 { 0, OPTION_LARGE_MODEL, NULL, "Far functions, far data" },
145 { 0, OPTION_MEDIUM_MODEL, NULL, "Far functions, near data" },
146 { 0, OPTION_SMALL_MODEL, NULL, "Small model (default)" },
147 { 0, OPTION_FLAT24_MODEL, NULL, NULL },
148 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
149 { 0, OPTION_STACK_8BIT, NULL, NULL },
150 { 0, "--stack-10bit", &options.stack10bit, NULL },
151 { 0, "--xstack", &options.useXstack, "Use external stack" },
152 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
153 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
154 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
155 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
156 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
157 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
158 { 0, "--regextend", &options.regExtend, NULL },
159 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or 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, NULL },
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, NULL },
176 { 0, OPTION_LIB_PATH, NULL, NULL },
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, "--peep-asm", &options.asmpeep, NULL },
186 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
187 { 0, "--nodebug", &options.nodebug, "Disable debugging symbol output" },
188 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
189 { 0, "--stack-after-data", &options.stackOnData, NULL },
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, "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, NULL },
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, "--short-is-int", &options.shortisint, "Make short the same size as int" },
199 { 0, OPTION_SHORT_IS_CHAR, NULL, "Make short the same size as char (default)" }
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 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
306 /*-----------------------------------------------------------------*/
307 /* printVersionInfo - prints the version info */
308 /*-----------------------------------------------------------------*/
316 for (i = 0; i < NUM_PORTS; i++)
317 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
319 fprintf (stderr, " %s"
320 #ifdef SDCC_SUB_VERSION_STR
321 "/" SDCC_SUB_VERSION_STR
329 #if defined(_MSC_VER)
342 "\t-m<proc> - Target processor <proc>. Default %s\n"
343 "\t Try --version for supported values of <proc>\n"
344 "\t--model-large - Large Model\n"
345 "\t--model-small - Small Model (default)\n"
346 "\t--stack-auto - Stack automatic variables\n"
347 "\t--xstack - Use external stack\n"
348 "\t--xram-loc <nnnn> - External Ram start location\n"
349 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
350 "\t--code-loc <nnnn> - Code Segment Location\n"
351 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
352 "\t--data-loc <nnnn> - Direct data start location\n"
353 "\t--idata-loc <nnnn> - Indirect data start location\n"
354 "\t--iram-size <nnnn> - Internal Ram size\n"
355 "\t--nojtbound - Don't generate boundary check for jump tables\n"
356 "\t--generic - All unqualified ptrs converted to '_generic'\n"
357 "PreProcessor Options :-\n"
358 "\t-Dmacro - Define Macro\n"
359 "\t-Ipath - Include \"*.h\" path\n"
360 "Note: this is NOT a complete list of options see docs for details\n",
362 /*-----------------------------------------------------------------*/
363 /* printUsage - prints command line syntax */
364 /*-----------------------------------------------------------------*/
371 "Usage : sdcc [options] filename\n"
375 for (i = 0; i < LENGTH(optionsTable); i++) {
376 fprintf(stderr, " %c%c %-20s %s\n",
377 optionsTable[i].shortOpt !=0 ? '-' : ' ',
378 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
379 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
380 optionsTable[i].help != NULL ? optionsTable[i].help : ""
386 /*-----------------------------------------------------------------*/
387 /* parseWithComma - separates string with comma */
388 /*-----------------------------------------------------------------*/
390 parseWithComma (char **dest, char *src)
394 strtok (src, "\n \t");
395 /* skip the initial white spaces */
396 while (isspace (*src))
413 /*-----------------------------------------------------------------*/
414 /* setDefaultOptions - sets the default options */
415 /*-----------------------------------------------------------------*/
421 for (i = 0; i < 128; i++)
422 preArgv[i] = asmOptions[i] =
423 linkOptions[i] = relFiles[i] = libFiles[i] =
426 /* first the options part */
427 options.stack_loc = 0; /* stack pointer initialised to 0 */
428 options.xstack_loc = 0; /* xternal stack starts at 0 */
429 options.code_loc = 0; /* code starts at 0 */
430 options.data_loc = 0x0030; /* data starts at 0x0030 */
431 options.xdata_loc = 0;
432 options.idata_loc = 0x80;
433 options.genericPtr = 1; /* default on */
435 options.model = port->general.default_model;
436 options.nostdlib = 0;
437 options.nostdinc = 0;
439 options.shortisint = 0;
441 options.stack10bit=0;
443 /* now for the optimizations */
444 /* turn on the everything */
445 optimize.global_cse = 1;
450 optimize.loopInvariant = 1;
451 optimize.loopInduction = 1;
453 /* now for the ports */
454 port->setDefaultOptions ();
457 /*-----------------------------------------------------------------*/
458 /* processFile - determines the type of file from the extension */
459 /*-----------------------------------------------------------------*/
461 processFile (char *s)
465 /* get the file extension */
466 fext = s + strlen (s);
467 while ((fext != s) && *fext != '.')
470 /* now if no '.' then we don't know what the file type is
471 so give a warning and return */
474 werror (W_UNKNOWN_FEXT, s);
478 /* otherwise depending on the file type */
479 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
481 /* source file name : not if we already have a
485 werror (W_TOO_MANY_SRC, s);
489 /* the only source file */
490 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
492 werror (E_FILE_OPEN_ERR, s);
496 /* copy the file name into the buffer */
499 /* get rid of the "." */
500 strtok (buffer, ".");
501 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
502 strcpy (srcFileName, buffer);
504 /* get rid of any path information
505 for the module name; do this by going
506 backwards till we get to either '/' or '\' or ':'
507 or start of buffer */
508 fext = buffer + strlen (buffer);
509 while (fext != buffer &&
510 *(fext - 1) != '\\' &&
511 *(fext - 1) != '/' &&
514 moduleName = Safe_calloc (1, strlen (fext) + 1);
515 strcpy (moduleName, fext);
520 /* if the extention is type .rel or .r or .REL or .R
521 addtional object file will be passed to the linker */
522 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
523 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
524 strcmp (fext, port->linker.rel_ext) == 0)
526 relFiles[nrelFiles++] = s;
530 /* if .lib or .LIB */
531 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
533 libFiles[nlibFiles++] = s;
537 werror (W_UNKNOWN_FEXT, s);
542 _processC1Arg (char *s)
546 if (options.out_name)
548 werror (W_TOO_MANY_SRC, s);
551 options.out_name = strdup (s);
560 _addToList (const char **list, const char *str)
562 /* This is the bad way to do things :) */
565 *list = strdup (str);
568 werror (E_OUT_OF_MEM, __FILE__, 0);
575 _setModel (int model, const char *sz)
577 if (port->general.supported_models & model)
578 options.model = model;
580 werror (W_UNSUPPORTED_MODEL, sz, port->target);
583 /** Gets the string argument to this option. If the option is '--opt'
584 then for input of '--optxyz' or '--opt xyz' returns xyz.
587 getStringArg(const char *szStart, char **argv, int *pi)
589 if (argv[*pi][strlen(szStart)]) {
590 return &argv[*pi][strlen(szStart)];
593 return argv[++(*pi)];
597 /** Gets the integer argument to this option using the same rules as
601 getIntArg(const char *szStart, char **argv, int *pi)
603 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi)));
607 tryHandleUnsupportedOpt(char **argv, int *pi)
609 if (argv[*pi][0] == '-')
611 const char *longOpt = "";
615 if (argv[*pi][1] == '-')
622 shortOpt = argv[*pi][1];
624 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
626 if (unsupportedOptTable[i].shortOpt == shortOpt ||
627 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
628 // Found an unsupported opt.
630 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
631 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
635 // Didn't find in the table
640 // Not an option, so can't be unsupported :)
646 tryHandleSimpleOpt(char **argv, int *pi)
648 if (argv[*pi][0] == '-')
650 const char *longOpt = "";
654 if (argv[*pi][1] == '-')
661 shortOpt = argv[*pi][1];
664 for (i = 0; i < LENGTH(optionsTable); i++)
666 if (optionsTable[i].shortOpt == shortOpt ||
667 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
669 // If it is a flag then we can handle it here
670 if (optionsTable[i].pparameter != NULL)
672 (*optionsTable[i].pparameter)++;
676 // Not a flag. Handled manually later.
681 // Didn't find in the table
686 // Not an option, so can't be handled.
691 /*-----------------------------------------------------------------*/
692 /* parseCmdLine - parses the command line and sets the options */
693 /*-----------------------------------------------------------------*/
695 parseCmdLine (int argc, char **argv)
700 /* go thru all whole command line */
701 for (i = 1; i < argc; i++)
706 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
711 if (tryHandleSimpleOpt(argv, &i) == TRUE)
717 if (argv[i][0] == '-' && argv[i][1] == '-')
719 if (strcmp (argv[i], OPTION_HELP) == 0)
725 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
727 options.stack10bit = 0;
731 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
737 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
739 _setModel (MODEL_LARGE, argv[i]);
743 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
745 _setModel (MODEL_MEDIUM, argv[i]);
749 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
751 _setModel (MODEL_SMALL, argv[i]);
755 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
757 _setModel (MODEL_FLAT24, argv[i]);
761 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
763 options.dump_rassgn =
769 options.dump_raw = 1;
773 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
775 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i);
779 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
781 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i);
785 if (strcmp (argv[i], OPTION_VERSION) == 0)
792 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
794 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i));
798 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
800 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i);
804 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
806 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i);
810 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
812 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i);
816 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
818 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i);
822 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
824 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i);
828 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
830 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i);
834 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
836 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i);
840 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
842 optimize.global_cse = 0;
846 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
848 optimize.loopInvariant = 0;
852 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
854 optimize.loopInduction = 0;
858 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
860 setErrorLogLevel(ERROR_LEVEL_WARNING);
864 if (strcmp (&argv[i][1], OPTION_SHORT_IS_CHAR) == 0) {
865 options.shortisint=0;
869 if (!port->parseOption (&argc, argv, &i))
871 werror (W_UNKNOWN_OPTION, argv[i]);
879 /* if preceded by '-' then option */
890 /* Used to select the port */
891 _setPort (argv[i] + 2);
899 libPaths[nlibPaths++] = getStringArg("-L", argv, &i);
904 if (argv[i][2] == 'l')
906 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i));
910 /* assembler options */
911 if (argv[i][2] == 'a')
913 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i));
917 werror (W_UNKNOWN_OPTION, argv[i]);
927 /* preprocessor options */
931 _addToList (preArgv, "-M");
936 _addToList (preArgv, "-C");
945 char sOpt = argv[i][1];
948 if (argv[i][2] == ' ' || argv[i][2] == '\0')
954 werror(E_ARGUMENT_MISSING, argv[i-1]);
968 sprintf (buffer, "-%c%s", sOpt, rest);
969 _addToList (preArgv, buffer);
974 if (!port->parseOption (&argc, argv, &i))
975 werror (W_UNKNOWN_OPTION, argv[i]);
980 if (!port->parseOption (&argc, argv, &i))
982 /* no option must be a filename */
984 _processC1Arg (argv[i]);
986 processFile (argv[i]);
990 /* set up external stack location if not explicitly specified */
991 if (!options.xstack_loc)
992 options.xstack_loc = options.xdata_loc;
994 /* if debug option is set the open the cdbFile */
995 if (!options.nodebug && srcFileName)
997 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
998 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
999 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1002 /* add a module record */
1003 fprintf (cdbFile, "M:%s\n", moduleName);
1009 /*-----------------------------------------------------------------*/
1010 /* linkEdit : - calls the linkage editor with options */
1011 /*-----------------------------------------------------------------*/
1013 linkEdit (char **envp)
1020 srcFileName = "temp";
1022 /* first we need to create the <filename>.lnk file */
1023 sprintf (buffer, "%s.lnk", srcFileName);
1024 if (!(lnkfile = fopen (buffer, "w")))
1026 werror (E_FILE_OPEN_ERR, buffer);
1030 /* now write the options */
1031 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1033 /* if iram size specified */
1034 if (options.iram_size)
1035 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1037 /*if (options.debug) */
1038 fprintf (lnkfile, "-z\n");
1040 #define WRITE_SEG_LOC(N, L) \
1041 segName = strdup(N); \
1042 c = strtok(segName, " \t"); \
1043 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1044 if (segName) { free(segName); }
1046 /* code segment start */
1047 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1049 /* data segment start */
1050 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1053 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1056 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1058 /* bit segment start */
1059 WRITE_SEG_LOC (BIT_NAME, 0);
1061 /* add the extra linker options */
1062 for (i = 0; linkOptions[i]; i++)
1063 fprintf (lnkfile, "%s\n", linkOptions[i]);
1065 /* other library paths if specified */
1066 for (i = 0; i < nlibPaths; i++)
1067 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1069 /* standard library path */
1070 if (!options.nostdlib)
1072 if (TARGET_IS_DS390)
1078 switch (options.model)
1090 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1095 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1097 /* standard library files */
1098 if (strcmp (port->target, "ds390") == 0)
1100 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1102 fprintf (lnkfile, "-l %s\n", STD_LIB);
1103 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1104 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1105 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1108 /* additional libraries if any */
1109 for (i = 0; i < nlibFiles; i++)
1110 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1112 /* put in the object files */
1113 if (strcmp (srcFileName, "temp"))
1114 fprintf (lnkfile, "%s ", srcFileName);
1116 for (i = 0; i < nrelFiles; i++)
1117 fprintf (lnkfile, "%s\n", relFiles[i]);
1119 fprintf (lnkfile, "\n-e\n");
1122 if (options.verbose)
1123 printf ("sdcc: Calling linker...\n");
1125 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1126 if (my_system (buffer))
1131 if (strcmp (srcFileName, "temp") == 0)
1133 /* rename "temp.cdb" to "firstRelFile.cdb" */
1134 char *f = strtok (strdup (relFiles[0]), ".");
1135 f = strcat (f, ".cdb");
1136 rename ("temp.cdb", f);
1141 /*-----------------------------------------------------------------*/
1142 /* assemble - spawns the assembler with arguments */
1143 /*-----------------------------------------------------------------*/
1145 assemble (char **envp)
1147 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1148 if (my_system (buffer))
1150 /* either system() or the assembler itself has reported an error
1151 perror ("Cannot exec assembler");
1159 /*-----------------------------------------------------------------*/
1160 /* preProcess - spawns the preprocessor with arguments */
1161 /*-----------------------------------------------------------------*/
1163 preProcess (char **envp)
1169 if (!options.c1mode)
1171 /* if using external stack define the macro */
1172 if (options.useXstack)
1173 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1175 /* set the macro for stack autos */
1176 if (options.stackAuto)
1177 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1179 /* set the macro for stack autos */
1180 if (options.stack10bit)
1181 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1183 /* set the macro for large model */
1184 switch (options.model)
1187 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1190 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1193 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1196 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1199 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1202 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1206 /* standard include path */
1207 if (!options.nostdinc) {
1208 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1211 /* add port (processor information to processor */
1212 sprintf (procDef, "-DSDCC_%s", port->target);
1213 _addToList (preArgv, procDef);
1214 sprintf (procDef, "-D__%s", port->target);
1215 _addToList (preArgv, procDef);
1218 preOutName = strdup (tmpnam (NULL));
1220 if (options.verbose)
1221 printf ("sdcc: Calling preprocessor...\n");
1223 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1224 preOutName, srcFileName, preArgv);
1225 if (my_system (buffer))
1227 // @FIX: Dario Vecchio 03-05-2001
1230 unlink (preOutName);
1242 preOutName = fullSrcFileName;
1245 yyin = fopen (preOutName, "r");
1248 perror ("Preproc file not found\n");
1256 _findPort (int argc, char **argv)
1263 if (!strncmp (*argv, "-m", 2))
1265 _setPort (*argv + 2);
1271 /* Use the first in the list */
1277 * initialises and calls the parser
1281 main (int argc, char **argv, char **envp)
1283 /* turn all optimizations off by default */
1284 memset (&optimize, 0, sizeof (struct optimize));
1286 /*printVersionInfo (); */
1289 fprintf (stderr, "Build error: no ports are enabled.\n");
1293 _findPort (argc, argv);
1294 /* Initalise the port. */
1298 // Create a default exe search path from the path to the sdcc command
1302 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1304 strcpy (DefaultExePath, argv[0]);
1305 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1306 ExePathList[0] = DefaultExePath;
1310 setDefaultOptions ();
1311 parseCmdLine (argc, argv);
1315 port->finaliseOptions ();
1317 /* if no input then printUsage & exit */
1318 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1319 (options.c1mode && !srcFileName && !options.out_name))
1334 if (options.verbose)
1335 printf ("sdcc: Generating code...\n");
1341 if (TARGET_IS_PIC) {
1342 /* TSD PIC port hack - if the PIC port option is enabled
1343 and SDCC is used to generate PIC code, then we will
1344 generate .asm files in gpasm's format instead of SDCC's
1347 #if !OPT_DISABLE_PIC
1356 // @FIX: Dario Vecchio 03-05-2001
1359 if (yyin && yyin != stdin)
1361 unlink (preOutName);
1367 if (!options.c1mode)
1369 if (options.verbose)
1370 printf ("sdcc: Calling assembler...\n");
1376 // @FIX: Dario Vecchio 03-05-2001
1379 if (yyin && yyin != stdin)
1381 unlink (preOutName);
1395 if (!options.cc_only &&
1399 (srcFileName || nrelFiles))
1401 if (port->linker.do_link)
1402 port->linker.do_link ();
1407 if (yyin && yyin != stdin)
1410 if (preOutName && !options.c1mode)
1412 unlink (preOutName);