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 #include "SDCCmacro.h"
40 #include "SDCCdebug.h"
51 extern int yyparse (void);
53 FILE *srcFile; /* source file */
54 char *fullSrcFileName; /* full name for the source file; */
55 /* can be NULL while c1mode or linking without compiling */
56 char *fullDstFileName; /* full name for the output file; */
57 /* only given by -o, otherwise NULL */
58 char *dstFileName; /* destination file name without extension */
59 char *dstPath = ""; /* path for the output files; */
60 /* "" is equivalent with cwd */
61 char *moduleName; /* module name is source file without path and extension */
62 /* can be NULL while linking without compiling */
64 int RegBankUsed[4] = {1, 0, 0, 0}; /*JCF: Reg Bank 0 used by default*/
65 struct optimize optimize;
66 struct options options;
69 set *preArgvSet = NULL; /* pre-processor arguments */
70 set *asmOptionsSet = NULL; /* set of assembler options */
71 set *linkOptionsSet = NULL; /* set of linker options */
72 set *libFilesSet = NULL;
73 set *libPathsSet = NULL;
74 set *relFilesSet = NULL;
75 set *dataDirsSet = NULL; /* list of data search directories */
76 set *includeDirsSet = NULL; /* list of include search directories */
77 set *libDirsSet = NULL; /* list of lib search directories */
79 /* uncomment JAMIN_DS390 to always override and use ds390 port
80 for mcs51 work. This is temporary, for compatibility testing. */
81 /* #define JAMIN_DS390 */
86 /* Globally accessible scratch buffer for file names. */
87 char scratchFileName[PATH_MAX];
88 char buffer[PATH_MAX * 2];
90 #define OPTION_HELP "-help"
92 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
94 #define OPTION_STACK_8BIT "--stack-8bit"
95 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
96 #define OPTION_LARGE_MODEL "--model-large"
97 #define OPTION_MEDIUM_MODEL "--model-medium"
98 #define OPTION_SMALL_MODEL "--model-small"
99 #define OPTION_FLAT24_MODEL "--model-flat24"
100 #define OPTION_DUMP_ALL "--dumpall"
101 #define OPTION_PEEP_FILE "--peep-file"
102 #define OPTION_LIB_PATH "--lib-path"
103 #define OPTION_XSTACK_LOC "--xstack-loc"
104 #define OPTION_CALLEE_SAVES "--callee-saves"
105 #define OPTION_STACK_LOC "--stack-loc"
106 #define OPTION_XRAM_LOC "--xram-loc"
107 #define OPTION_IRAM_SIZE "--iram-size"
108 #define OPTION_VERSION "--version"
109 #define OPTION_DATA_LOC "--data-loc"
110 #define OPTION_CODE_LOC "--code-loc"
111 #define OPTION_IDATA_LOC "--idata-loc"
112 #define OPTION_NO_LABEL_OPT "--nolabelopt"
113 #define OPTION_NO_LOOP_INV "--noinvariant"
114 #define OPTION_NO_LOOP_IND "--noinduction"
115 #define OPTION_LESS_PEDANTIC "--less-pedantic"
116 #define OPTION_NO_GCSE "--nogcse"
117 #define OPTION_SHORT_IS_8BITS "--short-is-8bits"
118 #define OPTION_TINI_LIBID "--tini-libid"
119 #define OPTION_NO_XINIT_OPT "--no-xinit-opt"
120 #define OPTION_XRAM_SIZE "--xram-size"
121 #define OPTION_CODE_SIZE "--code-size"
122 #define OPTION_NO_CCODE_IN_ASM "--no-c-code-in-asm"
123 #define OPTION_ICODE_IN_ASM "--i-code-in-asm"
124 #define OPTION_PRINT_SEARCH_DIRS "--print-search-dirs"
125 #define OPTION_MSVC_ERROR_STYLE "--vc"
126 #define OPTION_USE_STDOUT "--use-stdout"
127 #define OPTION_STACK_SIZE "--stack-size"
128 #define OPTION_PACK_IRAM "--pack-iram"
129 #define OPTION_NO_PEEP_COMMENTS "--no-peep-comments"
133 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
134 { 'p', NULL, NULL, "Select port specific processor e.g. -mpic14 -p16f84" },
135 { 'd', NULL, NULL, NULL },
136 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
137 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
138 { 'A', NULL, NULL, NULL },
139 { 'U', NULL, NULL, NULL },
140 { 'C', NULL, NULL, "Preprocessor option" },
141 { 'M', NULL, NULL, "Preprocessor option" },
142 { 'V', NULL, &options.verboseExec, "Execute verbosely. Show sub commands as they are run" },
143 { 'S', NULL, &noAssemble, "Compile only; do not assemble or link" },
144 { 'W', NULL, NULL, "Pass through options to the pre-processor (p), assembler (a) or linker (l)" },
145 { 'L', NULL, NULL, "Add the next field to the library search path" },
146 { 'l', NULL, NULL, "Include the given library in the link" },
147 { 0, OPTION_LARGE_MODEL, NULL, "external data space is used" },
148 { 0, OPTION_MEDIUM_MODEL, NULL, "not supported" },
149 { 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" },
150 #if !OPT_DISABLE_DS390
151 { 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" },
153 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
154 #if !OPT_DISABLE_DS390
155 { 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" },
156 { 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" },
158 { 0, "--xstack", &options.useXstack, "Use external stack" },
159 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
160 { 0, OPTION_NO_LABEL_OPT, NULL, "Disable label optimisation" },
161 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
162 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
163 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
164 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
165 { 'c', "--compile-only", &options.cc_only, "Compile and assemble, but do not link" },
166 { 'o', NULL, NULL, "Place the output into the given path resp. file" },
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, "dump front-end AST before generating iCode" },
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_XRAM_SIZE, NULL, "<nnnn> External Ram size" },
178 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
179 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
180 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
181 { 0, OPTION_CODE_SIZE, NULL, "<nnnn> Code Segment size" },
182 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
183 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
184 { 0, OPTION_IDATA_LOC, NULL, NULL },
185 { 0, OPTION_PEEP_FILE, NULL, "<file> use this extra peep-hole file" },
186 { 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
187 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
188 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the float support functions" },
189 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
190 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
191 { 0, "--cyclomatic", &options.cyclomatic, NULL },
192 { 0, "--nooverlay", &options.noOverlay, NULL },
193 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
194 { 0, "--xram-movc", &options.xram_movc, "Use movc instead of movx to read xram (xdata)" },
195 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
196 { 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
197 { 0, "--peep-asm", &options.asmpeep, NULL },
198 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
199 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
200 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
201 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The standard input is preprocessed code, the output is assembly code." },
202 { 0, "--help", NULL, "Display this help" },
203 { 0, OPTION_CALLEE_SAVES, NULL, "<func[,func,...]> Cause the called function to save registers insted of the caller" },
204 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
205 { 0, "--nostdinc", &options.nostdinc, "Do not include the standard include directory in the search path" },
206 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
207 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
208 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" },
209 { 0, "--profile", &options.profile, "On supported ports, generate extra profiling information" },
210 { 0, "--fommit-frame-pointer", &options.ommitFramePtr, "Leave out the frame pointer." },
211 { 0, "--all-callee-saves", &options.all_callee_saves, "callee will always save registers used" },
212 #if !OPT_DISABLE_DS390
213 { 0, "--use-accelerator", &options.useAccelerator,"generate code for DS390 Arithmetic Accelerator"},
215 { 0, "--stack-probe", &options.stack_probe,"insert call to function __stack_probe at each function prologue"},
216 #if !OPT_DISABLE_TININative
217 { 0, "--tini-libid", NULL,"<nnnn> LibraryID used in -mTININative"},
219 #if !OPT_DISABLE_DS390
220 { 0, "--protect-sp-update", &options.protect_sp_update,"DS390 - will disable interrupts during ESP:SP updates"},
222 #if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51
223 { 0, "--parms-in-bank1", &options.parms_in_bank1,"MCS51/DS390 - use Bank1 for parameter passing"},
224 { 0, OPTION_STACK_SIZE, NULL,"MCS51/DS390 - Tells the linker to allocate this space for stack"},
225 { 0, OPTION_PACK_IRAM, &options.pack_iram,"MCS51/DS390 - Tells the linker to pack variables in internal ram"},
227 { 0, OPTION_NO_XINIT_OPT, &options.noXinitOpt, "don't memcpy initialized xram from code"},
228 { 0, OPTION_NO_CCODE_IN_ASM, &options.noCcodeInAsm, "don't include c-code as comments in the asm file"},
229 { 0, OPTION_ICODE_IN_ASM, &options.iCodeInAsm, "include i-code as comments in the asm file"},
230 { 0, OPTION_NO_PEEP_COMMENTS, &options.noPeepComments, "don't include peephole optimizer comments"},
231 { 0, OPTION_PRINT_SEARCH_DIRS, &options.printSearchDirs, "display the directories in the compiler's search path"},
232 { 0, OPTION_MSVC_ERROR_STYLE, &options.vc_err_style, "messages are compatible with Micro$oft visual studio"},
233 { 0, OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
234 #if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
235 { 0, "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
241 /** Table of all unsupported options and help text to display when one
245 /** shortOpt as in OPTIONS. */
247 /** longOpt as in OPTIONS. */
249 /** Message to display inside W_UNSUPPORTED_OPT when this option
254 static const UNSUPPORTEDOPT
255 unsupportedOptTable[] = {
256 { 'X', NULL, "use --xstack-loc instead" },
257 { 'x', NULL, "use --xstack instead" },
258 { 'i', NULL, "use --idata-loc instead" },
259 { 'r', NULL, "use --xdata-loc instead" },
260 { 's', NULL, "use --code-loc instead" },
261 { 'Y', NULL, "use -I instead" }
264 /** List of all default constant macros.
266 static const char *_baseValues[] = {
269 /* Path seperator character */
270 "sep", DIR_SEPARATOR_STRING,
274 static const char *_preCmd = "{cpp} -nostdinc -Wall -std=c99 -DSDCC=1 {cppextraopts} \"{fullsrcfilename}\" \"{cppoutfilename}\"";
278 static PORT *_ports[] =
280 #if !OPT_DISABLE_MCS51
283 #if !OPT_DISABLE_GBZ80
292 #if !OPT_DISABLE_DS390
295 #if !OPT_DISABLE_PIC16
301 #if !OPT_DISABLE_TININative
304 #if !OPT_DISABLE_XA51
307 #if !OPT_DISABLE_DS400
310 #if !OPT_DISABLE_HC08
315 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
317 /** Sets the port to the one given by the command line option.
318 @param The name minus the option (eg 'mcs51')
319 @return 0 on success.
322 _setPort (const char *name)
325 for (i = 0; i < NUM_PORTS; i++)
327 if (!strcmp (_ports[i]->target, name))
333 /* Error - didnt find */
334 werror (E_UNKNOWN_TARGET, name);
338 /* Override the default processor with the one specified
339 * on the command line */
341 _setProcessor (char *_processor)
343 port->processor = _processor;
344 fprintf(stderr,"Processor: %s\n",_processor);
348 _validatePorts (void)
351 for (i = 0; i < NUM_PORTS; i++)
353 if (_ports[i]->magic != PORT_MAGIC)
355 /* Uncomment this line to debug which port is causing the problem
356 * (the target name is close to the beginning of the port struct
357 * and probably can be accessed just fine). */
358 fprintf(stderr,"%s :",_ports[i]->target);
359 wassertl (0, "Port definition structure is incomplete");
364 /* search through the command line options for the port */
366 _findPort (int argc, char **argv)
372 if (!strncmp (*argv, "-m", 2))
374 _setPort (*argv + 2);
380 /* Use the first in the list */
384 /* search through the command line options for the processor */
386 _findProcessor (int argc, char **argv)
390 if (!strncmp (*argv, "-p", 2))
392 _setProcessor (*argv + 2);
398 /* no error if processor was not specified. */
401 /*-----------------------------------------------------------------*/
402 /* printVersionInfo - prints the version info */
403 /*-----------------------------------------------------------------*/
405 printVersionInfo (void)
411 for (i = 0; i < NUM_PORTS; i++)
412 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
414 fprintf (stderr, " " SDCC_VERSION_STR
415 #ifdef SDCC_SUB_VERSION_STR
416 "/" SDCC_SUB_VERSION_STR
421 #elif defined __MINGW32__
423 #elif defined __DJGPP__
425 #elif defined(_MSC_VER)
427 #elif defined(__BORLANDC__)
436 printOptions(const OPTION *optionsTable)
439 for (i = 0; optionsTable[i].shortOpt != 0 || optionsTable[i].longOpt != NULL; i++)
441 fprintf(stdout, " %c%c %-20s %s\n",
442 optionsTable[i].shortOpt !=0 ? '-' : ' ',
443 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
444 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
445 optionsTable[i].help != NULL ? optionsTable[i].help : ""
450 /*-----------------------------------------------------------------*/
451 /* printUsage - prints command line syntax */
452 /*-----------------------------------------------------------------*/
459 "Usage : sdcc [options] filename\n"
463 printOptions(optionsTable);
465 for (i = 0; i < NUM_PORTS; i++)
467 if (_ports[i]->poptions != NULL)
469 fprintf (stdout, "\nSpecial options for the %s port:\n", _ports[i]->target);
470 printOptions (_ports[i]->poptions);
477 /*-----------------------------------------------------------------*/
478 /* setParseWithComma - separates string with comma to a set */
479 /*-----------------------------------------------------------------*/
481 setParseWithComma (set **dest, char *src)
486 /* skip the initial white spaces */
487 while (isspace(*src))
490 /* skip the trailing white spaces */
491 length = strlen(src);
492 while (length && isspace(src[length-1]))
493 src[--length] = '\0';
495 for (p = strtok(src, ","); p != NULL; p = strtok(NULL, ","))
496 addSet(dest, Safe_strdup(p));
499 /*-----------------------------------------------------------------*/
500 /* setDefaultOptions - sets the default options */
501 /*-----------------------------------------------------------------*/
503 setDefaultOptions (void)
505 /* first the options part */
506 options.stack_loc = 0; /* stack pointer initialised to 0 */
507 options.xstack_loc = 0; /* xternal stack starts at 0 */
508 options.code_loc = 0; /* code starts at 0 */
509 options.data_loc = 0; /* JCF: By default let the linker locate data */
510 options.xdata_loc = 0;
511 options.idata_loc = 0x80;
513 options.model = port->general.default_model;
514 options.nostdlib = 0;
515 options.nostdinc = 0;
517 options.shortis8bits = 0;
519 options.stack10bit=0;
521 /* now for the optimizations */
522 /* turn on the everything */
523 optimize.global_cse = 1;
528 optimize.loopInvariant = 1;
529 optimize.loopInduction = 1;
531 /* now for the ports */
532 port->setDefaultOptions ();
535 /*-----------------------------------------------------------------*/
536 /* processFile - determines the type of file from the extension */
537 /*-----------------------------------------------------------------*/
539 processFile (char *s)
543 /* get the file extension */
544 fext = s + strlen (s);
545 while ((fext != s) && *fext != '.')
548 /* now if no '.' then we don't know what the file type is
549 so give a warning and return */
552 werror (W_UNKNOWN_FEXT, s);
556 /* otherwise depending on the file type */
557 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0)
559 /* source file name : not if we already have a
563 werror (W_TOO_MANY_SRC, s);
567 /* the only source file */
569 if (!(srcFile = fopen (fullSrcFileName, "r")))
571 werror (E_FILE_OPEN_ERR, s);
575 /* copy the file name into the buffer */
576 strncpyz (buffer, s, sizeof(buffer));
578 /* get rid of the "."-extension */
580 /* is there a dot at all? */
581 if (strrchr (buffer, '.') &&
582 /* is the dot in the filename, not in the path? */
583 (strrchr (buffer, DIR_SEPARATOR_CHAR) < strrchr (buffer, '.')))
585 *strrchr (buffer, '.') = '\0';
588 /* get rid of any path information
589 for the module name; */
590 fext = buffer + strlen (buffer);
592 /* do this by going backwards till we
593 get '\' or ':' or start of buffer */
594 while (fext != buffer &&
595 *(fext - 1) != DIR_SEPARATOR_CHAR &&
601 /* do this by going backwards till we
602 get '/' or start of buffer */
603 while (fext != buffer &&
604 *(fext - 1) != DIR_SEPARATOR_CHAR)
609 moduleName = Safe_strdup ( fext );
613 /* if the extention is type .rel or .r or .REL or .R
614 addtional object file will be passed to the linker */
615 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
616 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
617 strcmp (fext, port->linker.rel_ext) == 0)
619 addSet(&relFilesSet, Safe_strdup(s));
623 /* if .lib or .LIB */
624 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
626 addSet(&libFilesSet, Safe_strdup(s));
630 werror (W_UNKNOWN_FEXT, s);
635 _setModel (int model, const char *sz)
637 if (port->general.supported_models & model)
638 options.model = model;
640 werror (W_UNSUPPORTED_MODEL, sz, port->target);
643 /** Gets the string argument to this option. If the option is '--opt'
644 then for input of '--optxyz' or '--opt xyz' returns xyz.
647 getStringArg(const char *szStart, char **argv, int *pi, int argc)
649 if (argv[*pi][strlen(szStart)])
651 return &argv[*pi][strlen(szStart)];
658 werror (E_ARGUMENT_MISSING, szStart);
659 /* Die here rather than checking for errors later. */
669 /** Gets the integer argument to this option using the same rules as
673 getIntArg(const char *szStart, char **argv, int *pi, int argc)
675 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
679 verifyShortOption(const char *opt)
681 if (strlen(opt) != 2)
683 werror (W_EXCESS_SHORT_OPTIONS, opt);
688 tryHandleUnsupportedOpt(char **argv, int *pi)
690 if (argv[*pi][0] == '-')
692 const char *longOpt = "";
696 if (argv[*pi][1] == '-')
703 shortOpt = argv[*pi][1];
705 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
707 if (unsupportedOptTable[i].shortOpt == shortOpt ||
708 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
709 /* Found an unsupported opt. */
711 SNPRINTF(buffer, sizeof(buffer),
713 longOpt ? longOpt : "",
714 shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
715 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
719 /* Didn't find in the table */
724 /* Not an option, so can't be unsupported :) */
730 scanOptionsTable(const OPTION *optionsTable, char shortOpt, const char *longOpt, char **argv, int *pi)
733 for (i = 0; optionsTable[i].shortOpt != 0 || optionsTable[i].longOpt != NULL; i++)
735 if (optionsTable[i].shortOpt == shortOpt ||
736 (longOpt && optionsTable[i].longOpt &&
737 strcmp(optionsTable[i].longOpt, longOpt) == 0))
740 /* If it is a flag then we can handle it here */
741 if (optionsTable[i].pparameter != NULL)
743 if (optionsTable[i].shortOpt == shortOpt)
745 verifyShortOption(argv[*pi]);
748 (*optionsTable[i].pparameter)++;
752 /* Not a flag. Handled manually later. */
757 /* Didn't find in the table */
762 tryHandleSimpleOpt(char **argv, int *pi)
764 if (argv[*pi][0] == '-')
766 const char *longOpt = "";
769 if (argv[*pi][1] == '-')
776 shortOpt = argv[*pi][1];
779 if (scanOptionsTable(optionsTable, shortOpt, longOpt, argv, pi))
783 else if (port && port->poptions &&
784 scanOptionsTable(port->poptions, shortOpt, longOpt, argv, pi))
795 /* Not an option, so can't be handled. */
800 /*-----------------------------------------------------------------*/
801 /* parseCmdLine - parses the command line and sets the options */
802 /*-----------------------------------------------------------------*/
804 parseCmdLine (int argc, char **argv)
808 /* go thru all whole command line */
809 for (i = 1; i < argc; i++)
814 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
819 if (tryHandleSimpleOpt(argv, &i) == TRUE)
825 if (argv[i][0] == '-' && argv[i][1] == '-')
827 if (strcmp (argv[i], OPTION_HELP) == 0)
833 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
835 options.stack10bit = 0;
839 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
845 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
847 _setModel (MODEL_LARGE, argv[i]);
851 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
853 _setModel (MODEL_MEDIUM, argv[i]);
857 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
859 _setModel (MODEL_SMALL, argv[i]);
863 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
865 _setModel (MODEL_FLAT24, argv[i]);
869 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
871 options.dump_rassgn =
877 options.dump_raw = 1;
881 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
883 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
887 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
889 addSet(&libPathsSet, Safe_strdup(getStringArg(OPTION_LIB_PATH, argv, &i, argc)));
893 if (strcmp (argv[i], OPTION_VERSION) == 0)
900 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
902 setParseWithComma(&options.calleeSavesSet, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
906 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
908 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
912 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
914 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
918 if (strcmp (argv[i], OPTION_STACK_SIZE) == 0)
920 options.stack_size = getIntArg(OPTION_STACK_SIZE, argv, &i, argc);
924 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
926 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
930 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
932 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
936 if (strcmp (argv[i], OPTION_XRAM_SIZE) == 0)
938 options.xram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
939 options.xram_size_set = TRUE;
943 if (strcmp (argv[i], OPTION_CODE_SIZE) == 0)
945 options.code_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
949 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
951 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
955 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
957 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
961 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
963 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
967 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
969 optimize.global_cse = 0;
973 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
975 optimize.loopInvariant = 0;
979 if (strcmp (argv[i], OPTION_NO_LABEL_OPT) == 0)
985 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
987 optimize.loopInduction = 0;
991 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
993 options.lessPedantic = 1;
994 setErrorLogLevel(ERROR_LEVEL_WARNING);
998 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
1000 options.shortis8bits=1;
1004 if (strcmp (argv[i], OPTION_TINI_LIBID) == 0)
1006 options.tini_libid = getIntArg(OPTION_TINI_LIBID, argv, &i, argc);
1010 if (!port->parseOption (&argc, argv, &i))
1012 werror (W_UNKNOWN_OPTION, argv[i]);
1020 /* if preceded by '-' then option */
1021 if (*argv[i] == '-')
1026 verifyShortOption(argv[i]);
1033 /* Used to select the port. But this has already been done. */
1037 /* Used to select the processor in port. But this has
1038 * already been done. */
1042 verifyShortOption(argv[i]);
1044 options.cc_only = 1;
1048 addSet(&libPathsSet, Safe_strdup(getStringArg("-L", argv, &i, argc)));
1052 addSet(&libFilesSet, Safe_strdup(getStringArg("-l", argv, &i, argc)));
1059 /* copy the file name into the buffer */
1060 strncpyz(buffer, getStringArg("-o", argv, &i, argc),
1062 /* point to last character */
1063 p = buffer + strlen (buffer) - 1;
1064 if (*p == DIR_SEPARATOR_CHAR)
1066 /* only output path specified */
1067 dstPath = Safe_strdup (buffer);
1068 fullDstFileName = NULL;
1072 fullDstFileName = Safe_strdup (buffer);
1074 /* get rid of the "."-extension */
1076 /* is there a dot at all? */
1077 if (strrchr (buffer, '.') &&
1078 /* is the dot in the filename, not in the path? */
1079 (strrchr (buffer, DIR_SEPARATOR_CHAR) < strrchr (buffer, '.')))
1080 *strrchr (buffer, '.') = '\0';
1082 dstFileName = Safe_strdup (buffer);
1084 /* strip module name to get path */
1085 p = strrchr (buffer, DIR_SEPARATOR_CHAR);
1088 /* path with trailing / */
1090 dstPath = Safe_strdup (buffer);
1097 /* pre-processer options */
1098 if (argv[i][2] == 'p')
1100 setParseWithComma(&preArgvSet, getStringArg("-Wp", argv, &i, argc));
1102 /* linker options */
1103 else if (argv[i][2] == 'l')
1105 setParseWithComma(&linkOptionsSet, getStringArg("-Wl", argv, &i, argc));
1107 /* assembler options */
1108 else if (argv[i][2] == 'a')
1110 setParseWithComma(&asmOptionsSet, getStringArg("-Wa", argv, &i, argc));
1114 werror (W_UNKNOWN_OPTION, argv[i]);
1119 verifyShortOption(argv[i]);
1121 printVersionInfo ();
1125 /* preprocessor options */
1129 if (argv[i][2] == 'M')
1130 addSet(&preArgvSet, Safe_strdup("-MM"));
1132 addSet(&preArgvSet, Safe_strdup("-M"));
1137 addSet(&preArgvSet, Safe_strdup("-C"));
1147 char sOpt = argv[i][1];
1150 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1156 werror(E_ARGUMENT_MISSING, argv[i-1]);
1170 SNPRINTF (buffer, sizeof(buffer),
1171 ((sOpt == 'I') ? "-%c\"%s\"": "-%c%s"), sOpt, rest);
1172 addSet(&preArgvSet, Safe_strdup(buffer));
1177 if (!port->parseOption (&argc, argv, &i))
1178 werror (W_UNKNOWN_OPTION, argv[i]);
1183 if (!port->parseOption (&argc, argv, &i))
1185 /* no option must be a filename */
1188 werror (W_NO_FILE_ARG_IN_C1, argv[i]);
1192 processFile (argv[i]);
1197 /* some sanity checks in c1 mode */
1202 if (fullSrcFileName)
1205 werror (W_NO_FILE_ARG_IN_C1, fullSrcFileName);
1207 fullSrcFileName = NULL;
1208 for (s = setFirstItem(relFilesSet); s != NULL; s = setNextItem(relFilesSet))
1210 werror (W_NO_FILE_ARG_IN_C1, s);
1212 for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
1214 werror (W_NO_FILE_ARG_IN_C1, s);
1216 deleteSet(&relFilesSet);
1217 deleteSet(&libFilesSet);
1219 if (options.cc_only || noAssemble || preProcOnly)
1221 werror (W_ILLEGAL_OPT_COMBINATION);
1223 options.cc_only = noAssemble = preProcOnly = 0;
1226 werror (E_NEED_OPT_O_IN_C1);
1230 /* if no dstFileName given with -o, we've to find one: */
1235 /* use the modulename from the C-source */
1236 if (fullSrcFileName)
1238 size_t bufSize = strlen (dstPath) + strlen (moduleName) + 1;
1240 dstFileName = Safe_alloc (bufSize);
1241 strncpyz (dstFileName, dstPath, bufSize);
1242 strncatz (dstFileName, moduleName, bufSize);
1244 /* use the modulename from the first object file */
1245 else if ((s = peekSet(relFilesSet)) != NULL)
1250 strncpyz (buffer, s, sizeof(buffer));
1251 /* remove extension (it must be .rel) */
1252 *strrchr (buffer, '.') = '\0';
1254 objectName = strrchr (buffer, DIR_SEPARATOR_CHAR);
1261 objectName = buffer;
1263 bufSize = strlen (dstPath) + strlen (objectName) + 1;
1264 dstFileName = Safe_alloc (bufSize);
1265 strncpyz (dstFileName, dstPath, bufSize);
1266 strncatz (dstFileName, objectName, bufSize);
1268 /* else no module given: help text is displayed */
1271 /* set up external stack location if not explicitly specified */
1272 if (!options.xstack_loc)
1273 options.xstack_loc = options.xdata_loc;
1275 /* if debug option is set then open the cdbFile */
1276 if (options.debug && fullSrcFileName)
1278 SNPRINTF (scratchFileName, sizeof(scratchFileName),
1279 "%s.adb", dstFileName); /*JCF: Nov 30, 2002*/
1280 if(debugFile->openFile(scratchFileName))
1281 debugFile->writeModule(moduleName);
1283 werror (E_FILE_OPEN_ERR, scratchFileName);
1285 MSVC_style(options.vc_err_style);
1286 if(options.use_stdout) dup2(STDOUT_FILENO, STDERR_FILENO);
1291 /*-----------------------------------------------------------------*/
1292 /* linkEdit : - calls the linkage editor with options */
1293 /*-----------------------------------------------------------------*/
1295 linkEdit (char **envp)
1303 if(port->linker.needLinkerScript)
1307 switch (options.out_fmt)
1310 out_fmt = 'i'; /* Intel hex */
1313 out_fmt = 's'; /* Motorola S19 */
1316 out_fmt = 't'; /* Elf */
1322 /* first we need to create the <filename>.lnk file */
1323 SNPRINTF (scratchFileName, sizeof(scratchFileName),
1324 "%s.lnk", dstFileName);
1325 if (!(lnkfile = fopen (scratchFileName, "w")))
1327 werror (E_FILE_OPEN_ERR, scratchFileName);
1331 if (TARGET_IS_Z80 || TARGET_IS_GBZ80)
1333 fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
1334 out_fmt, dstFileName);
1336 else /*For all the other ports. Including pics???*/
1338 fprintf (lnkfile, "-myux%c\n", out_fmt);
1339 if(options.pack_iram)
1340 fprintf (lnkfile, "-Y\n");
1343 if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
1345 /* if iram size specified */
1346 if (options.iram_size)
1347 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1349 /* if stack size specified*/
1350 if(options.stack_size)
1351 fprintf (lnkfile, "-A 0x%02x\n", options.stack_size);
1353 /* if xram size specified */
1354 if (options.xram_size_set)
1355 fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
1357 /* if code size specified */
1358 if (options.code_size)
1359 fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
1362 fprintf (lnkfile, "-z\n");
1365 #define WRITE_SEG_LOC(N, L) \
1366 segName = Safe_strdup(N); \
1367 c = strtok(segName, " \t"); \
1368 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1369 if (segName) { Safe_free(segName); }
1371 if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
1374 /* code segment start */
1375 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1377 /* data segment start. If zero, the linker chooses
1378 the best place for data */
1379 if(options.data_loc)
1381 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1385 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1390 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1393 /* bit segment start */
1394 WRITE_SEG_LOC (BIT_NAME, 0);
1397 if ( (options.stack_loc) && (options.stack_loc<0x100) )
1399 WRITE_SEG_LOC ("SSEG", options.stack_loc);
1402 else /*For the z80, gbz80*/
1404 WRITE_SEG_LOC ("_CODE", options.code_loc);
1405 WRITE_SEG_LOC ("_DATA", options.data_loc);
1408 /* If the port has any special linker area declarations, get 'em */
1409 if (port->extraAreas.genExtraAreaLinkOptions)
1411 port->extraAreas.genExtraAreaLinkOptions(lnkfile);
1414 /* add the extra linker options */
1415 fputStrSet(lnkfile, linkOptionsSet);
1417 /* command line defined library paths if specified */
1418 for (s = setFirstItem(libPathsSet); s != NULL; s = setNextItem(libPathsSet))
1419 fprintf (lnkfile, "-k %s\n", s);
1421 /* standard library path */
1422 if (!options.nostdlib)
1424 if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
1426 switch (options.model)
1436 if (TARGET_IS_DS390)
1440 else if (TARGET_IS_DS400)
1447 "Add support for your FLAT24 target in %s @ line %d\n",
1448 __FILE__, __LINE__);
1456 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1461 else /*for the z80, gbz80*/
1465 else if (TARGET_IS_Z80)
1470 for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
1471 mfprintf (lnkfile, getRuntimeVariables(), "-k %s{sep}%s\n", s, c);
1474 /* command line defined library files if specified */
1475 for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
1476 fprintf (lnkfile, "-l %s\n", s);
1478 /* standard library files */
1479 if (!options.nostdlib)
1481 #if !OPT_DISABLE_DS390
1482 if (options.model == MODEL_FLAT24)
1484 if (TARGET_IS_DS390)
1486 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1488 else if (TARGET_IS_DS400)
1490 fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
1495 "Add support for your FLAT24 target in %s @ line %d\n",
1496 __FILE__, __LINE__);
1502 #if !OPT_DISABLE_XA51
1504 if (options.model == MODEL_PAGE0)
1506 fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
1510 if (TARGET_IS_MCS51)
1512 fprintf (lnkfile, "-l mcs51\n");
1514 if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80
1515 || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
1516 { /*Why the z80 port is not using the standard libraries?*/
1517 fprintf (lnkfile, "-l %s\n", STD_LIB);
1518 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1519 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1520 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1522 else if (TARGET_IS_HC08)
1524 fprintf (lnkfile, "-l hc08\n");
1526 else if (TARGET_IS_Z80)
1528 fprintf (lnkfile, "-l z80\n");
1530 else if (TARGET_IS_GBZ80)
1532 fprintf (lnkfile, "-l gbz80\n");
1536 /*For the z80 and gbz80 ports, try to find where crt0.o is...
1537 It is very important for this file to be first on the linking proccess
1538 so the areas are set in the correct order, expecially _GSINIT*/
1539 if ((TARGET_IS_Z80 || TARGET_IS_GBZ80) &&
1540 !options.no_std_crt0 && !options.nostdlib) /*For the z80, gbz80*/
1542 char crt0path[PATH_MAX];
1544 for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
1546 sprintf (crt0path, "%s%s%s%scrt0.o",
1547 s, DIR_SEPARATOR_STRING, c, DIR_SEPARATOR_STRING);
1549 crt0fp=fopen(crt0path, "r");
1550 if(crt0fp!=NULL)/*Found it!*/
1555 /*The CYGWIN version of the z80-gbz80 linker is getting confused with
1556 windows paths, so convert them to the CYGWIN format*/
1557 char posix_path[PATH_MAX];
1558 void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
1559 cygwin_conv_to_full_posix_path(crt0path, posix_path);
1560 strcpy(crt0path, posix_path);
1563 fprintf (lnkfile, "%s\n", crt0path);
1567 if(s==NULL) fprintf (stderr, "Warning: couldn't find crt0.o\n");
1570 /* put in the object files */
1571 if (fullSrcFileName)
1572 fprintf (lnkfile, "%s%s\n", dstFileName, port->linker.rel_ext);
1574 fputStrSet(lnkfile, relFilesSet);
1576 fprintf (lnkfile, "\n-e\n");
1578 } /* if(port->linker.needLinkerScript) */
1580 if (options.verbose)
1581 printf ("sdcc: Calling linker...\n");
1583 /* build linker output filename */
1585 /* -o option overrides default name? */
1586 if (fullDstFileName)
1588 strncpyz (scratchFileName, fullDstFileName, sizeof(scratchFileName));
1592 /* the linked file gets the name of the first modul */
1593 if (fullSrcFileName)
1595 strncpyz (scratchFileName, dstFileName, sizeof(scratchFileName));
1599 s = peekSet(relFilesSet);
1603 strncpyz (scratchFileName, s, sizeof(scratchFileName));
1604 /* strip ".rel" extension */
1605 *strrchr (scratchFileName, '.') = '\0';
1607 strncatz (scratchFileName,
1608 options.out_fmt ? ".S19" : ".ihx",
1609 sizeof(scratchFileName));
1612 if (port->linker.cmd)
1614 char buffer2[PATH_MAX];
1617 if(TARGET_IS_PIC16) {
1618 /* use $3 to set the linker include directories */
1619 libSet = appendStrSet(libDirsSet, "-I\"", "\"");
1621 /* now add the libraries from command line */
1622 mergeSets(&libSet, libFilesSet);
1625 buildCmdLine (buffer2, port->linker.cmd, dstFileName, scratchFileName, (libSet?joinStrSet(libSet):NULL), linkOptionsSet);
1626 if(libSet)deleteSet(&libSet);
1628 buildCmdLine2 (buffer, sizeof(buffer), buffer2);
1632 buildCmdLine2 (buffer, sizeof(buffer), port->linker.mcmd);
1635 /* if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer); */
1637 system_ret = my_system (buffer);
1638 /* TODO: most linker don't have a -o parameter */
1639 /* -o option overrides default name? */
1640 if (fullDstFileName)
1643 /* the linked file gets the name of the first modul */
1644 if (fullSrcFileName)
1646 strncpyz (scratchFileName, dstFileName, sizeof(scratchFileName));
1647 p = strlen (scratchFileName) + scratchFileName;
1651 s = peekSet(relFilesSet);
1655 strncpyz (scratchFileName, s, sizeof(scratchFileName));
1656 /* strip ".rel" extension */
1657 p = strrchr (scratchFileName, '.');
1663 strncatz (scratchFileName,
1664 options.out_fmt ? ".S19" : ".ihx",
1665 sizeof(scratchFileName));
1666 if (strcmp (fullDstFileName, scratchFileName))
1667 unlink (fullDstFileName);
1668 rename (scratchFileName, fullDstFileName);
1670 strncpyz (buffer, fullDstFileName, sizeof(buffer));
1671 q = strrchr (buffer, '.');
1674 /* no extension: append new extensions */
1675 q = strlen (buffer) + buffer;
1679 strncatz (scratchFileName, ".map", sizeof(scratchFileName));
1681 strncatz(buffer, ".map", sizeof(buffer));
1682 if (strcmp (scratchFileName, buffer))
1684 rename (scratchFileName, buffer);
1686 strncatz (scratchFileName, ".mem", sizeof(scratchFileName));
1688 strncatz(buffer, ".mem", sizeof(buffer));
1689 if (strcmp (scratchFileName, buffer))
1691 rename (scratchFileName, buffer);
1695 strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
1697 strncatz(buffer, ".cdb", sizeof(buffer));
1698 if (strcmp (scratchFileName, buffer))
1700 rename (scratchFileName, buffer);
1701 /* and the OMF file without extension: */
1704 if (strcmp (scratchFileName, buffer))
1706 rename (scratchFileName, buffer);
1715 /*-----------------------------------------------------------------*/
1716 /* assemble - spawns the assembler with arguments */
1717 /*-----------------------------------------------------------------*/
1719 assemble (char **envp)
1721 /* build assembler output filename */
1723 /* -o option overrides default name? */
1724 if (options.cc_only && fullDstFileName) {
1725 strncpyz (scratchFileName, fullDstFileName, sizeof(scratchFileName));
1727 /* the assembled file gets the name of the first modul */
1728 strncpyz (scratchFileName, dstFileName, sizeof(scratchFileName));
1729 strncatz (scratchFileName, port->linker.rel_ext,
1730 sizeof(scratchFileName));
1733 if (port->assembler.do_assemble) {
1734 port->assembler.do_assemble(asmOptionsSet);
1736 } else if (port->assembler.cmd) {
1737 buildCmdLine (buffer, port->assembler.cmd, dstFileName, scratchFileName,
1738 options.debug ? port->assembler.debug_opts : port->assembler.plain_opts,
1741 buildCmdLine2 (buffer, sizeof(buffer), port->assembler.mcmd);
1744 if (my_system (buffer)) {
1745 /* either system() or the assembler itself has reported an error
1746 perror ("Cannot exec assembler");
1750 /* TODO: most assembler don't have a -o parameter */
1751 /* -o option overrides default name? */
1752 if (options.cc_only && fullDstFileName) {
1753 strncpyz (scratchFileName, dstFileName, sizeof(scratchFileName));
1754 strncatz (scratchFileName,
1755 port->linker.rel_ext,
1756 sizeof(scratchFileName));
1757 if (strcmp (scratchFileName, fullDstFileName))
1758 unlink (fullDstFileName);
1759 rename (scratchFileName, fullDstFileName);
1763 /*-----------------------------------------------------------------*/
1764 /* preProcess - spawns the preprocessor with arguments */
1765 /*-----------------------------------------------------------------*/
1767 preProcess (char **envp)
1776 set *inclList = NULL;
1778 /* if using external stack define the macro */
1779 if (options.useXstack)
1780 addSet(&preArgvSet, Safe_strdup("-DSDCC_USE_XSTACK"));
1782 /* set the macro for stack autos */
1783 if (options.stackAuto)
1784 addSet(&preArgvSet, Safe_strdup("-DSDCC_STACK_AUTO"));
1786 /* set the macro for stack autos */
1787 if (options.stack10bit)
1788 addSet(&preArgvSet, Safe_strdup("-DSDCC_STACK_TENBIT"));
1790 /* set the macro for no overlay */
1791 if (options.noOverlay)
1792 addSet(&preArgvSet, Safe_strdup("-DSDCC_NOOVERLAY"));
1794 /* set the macro for large model */
1795 switch (options.model)
1798 addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_LARGE"));
1801 addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_SMALL"));
1804 addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_COMPACT"));
1807 addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_MEDIUM"));
1810 addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_FLAT24"));
1813 addSet(&preArgvSet, Safe_strdup("-DSDCC_MODEL_PAGE0"));
1816 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1820 /* add port (processor information to processor */
1821 addSet(&preArgvSet, Safe_strdup("-DSDCC_{port}"));
1822 addSet(&preArgvSet, Safe_strdup("-D__{port}"));
1824 /* standard include path */
1825 if (!options.nostdinc) {
1826 inclList = appendStrSet(includeDirsSet, "-I\"", "\"");
1827 mergeSets(&preArgvSet, inclList);
1830 setMainValue("cppextraopts", (s = joinStrSet(preArgvSet)));
1831 Safe_free((void *)s);
1832 if (inclList != NULL)
1833 deleteSet(&inclList);
1835 if (preProcOnly && fullDstFileName)
1837 /* -E and -o given */
1838 setMainValue ("cppoutfilename", fullDstFileName);
1842 /* Piping: set cppoutfilename to NULL, to avoid empty quotes */
1843 setMainValue ("cppoutfilename", NULL);
1846 if (options.verbose)
1847 printf ("sdcc: Calling preprocessor...\n");
1849 buildCmdLine2 (buffer, sizeof(buffer), _preCmd);
1852 if (my_system (buffer)) {
1859 yyin = my_popen (buffer);
1861 perror ("Preproc file not found");
1864 addSetHead (&pipeSet, yyin);
1872 setBinPaths(const char *argv0)
1880 * 1. - $SDCCDIR/PREFIX2BIN_DIR
1881 * 2. - path(argv[0])
1885 /* do it in reverse mode, so that addSetHead() can be used
1886 instead of slower addSet() */
1888 if ((p = getBinPath(argv0)) != NULL)
1889 addSetHead(&binPathSet, Safe_strdup(p));
1891 if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
1892 SNPRINTF(buf, sizeof buf, "%s" PREFIX2BIN_DIR, p);
1893 addSetHead(&binPathSet, Safe_strdup(buf));
1896 if (options.printSearchDirs) {
1897 printf("programs:\n");
1898 fputStrSet(stdout, binPathSet);
1902 /* Set system include path */
1904 setIncludePath(void)
1911 * 1. - $SDCC_INCLUDE
1912 * 2. - $SDCC_HOME/PREFIX2DATA_DIR/INCLUDE_DIR_SUFFIX
1913 * 3. - path(argv[0])/BIN2DATA_DIR/INCLUDE_DIR_SUFFIX
1914 * 4. - DATADIR/INCLUDE_DIR_SUFFIX (only on *nix)
1917 includeDirsSet = appendStrSet(dataDirsSet, NULL, INCLUDE_DIR_SUFFIX);
1919 if ((p = getenv(SDCC_INCLUDE_NAME)) != NULL)
1920 addSetHead(&includeDirsSet, p);
1922 if (options.printSearchDirs) {
1923 printf("includedir:\n");
1924 fputStrSet(stdout, includeDirsSet);
1928 /* Set system lib path */
1938 * 2. - $SDCC_HOME/PREFIX2DATA_DIR/LIB_DIR_SUFFIX/<model>
1939 * 3. - path(argv[0])/BIN2DATA_DIR/LIB_DIR_SUFFIX/<model>
1940 * 4. - DATADIR/LIB_DIR_SUFFIX/<model> (only on *nix)
1943 libDirsSet = appendStrSet(dataDirsSet, NULL, LIB_DIR_SUFFIX);
1945 if ((p = getenv(SDCC_LIB_NAME)) != NULL)
1946 addSetHead(&libDirsSet, p);
1948 if (options.printSearchDirs) {
1949 printf("libdir:\n");
1950 fputStrSet(stdout, libDirsSet);
1956 setDataPaths(const char *argv0)
1964 * 1. - $SDCC_HOME/PREFIX2DATA_DIR
1965 * 2. - path(argv[0])/BIN2DATA_DIR
1966 * 3. - DATADIR (only on *nix)
1969 if ((p = getenv(SDCC_DIR_NAME)) != NULL) {
1970 SNPRINTF(buf, sizeof buf, "%s" PREFIX2DATA_DIR, p);
1971 addSet(&dataDirsSet, Safe_strdup(buf));
1974 if ((p = getBinPath(argv0)) != NULL) {
1975 SNPRINTF(buf, sizeof buf, "%s" BIN2DATA_DIR, p);
1976 addSet(&dataDirsSet, Safe_strdup(buf));
1980 if (peekSet(dataDirsSet) == NULL) {
1981 /* this should never happen... */
1982 wassertl(0, "Can't get binary path");
1985 addSet(&dataDirsSet, Safe_strdup(DATADIR));
1988 if (options.printSearchDirs) {
1989 printf("datadir:\n");
1990 fputStrSet(stdout, dataDirsSet);
2000 populateMainValues (_baseValues);
2001 setMainValue ("port", port->target);
2002 setMainValue ("objext", port->linker.rel_ext);
2003 setMainValue ("asmext", port->assembler.file_ext);
2005 setMainValue ("dstfilename", dstFileName);
2006 setMainValue ("fullsrcfilename", fullSrcFileName ? fullSrcFileName : "fullsrcfilename");
2008 if (options.cc_only && fullDstFileName)
2009 /* compile + assemble and -o given: -o specifies name of object file */
2011 setMainValue ("objdstfilename", fullDstFileName);
2015 setMainValue ("objdstfilename", "{stdobjdstfilename}");
2017 if (fullDstFileName)
2018 /* if we're linking, -o gives the final file name */
2020 setMainValue ("linkdstfilename", fullDstFileName);
2024 setMainValue ("linkdstfilename", "{stdlinkdstfilename}");
2030 sig_handler (int signal)
2037 sig_string = "SIGABRT";
2040 sig_string = "SIGTERM";
2043 sig_string = "SIGINT";
2046 sig_string = "SIGSEGV";
2049 sig_string = "Unknown?";
2052 fprintf (stderr, "Caught signal %d: %s\n", signal, sig_string);
2058 * initialises and calls the parser
2062 main (int argc, char **argv, char **envp)
2064 /* turn all optimizations off by default */
2065 memset (&optimize, 0, sizeof (struct optimize));
2067 /*printVersionInfo (); */
2070 fprintf (stderr, "Build error: no ports are enabled.\n");
2074 /* install atexit handler */
2075 atexit(rm_tmpfiles);
2077 /* install signal handler;
2078 it's only purpuse is to call exit() to remove temp files */
2079 if (!getenv("SDCC_LEAVE_SIGNALS"))
2081 signal (SIGABRT, sig_handler);
2082 signal (SIGTERM, sig_handler);
2083 signal (SIGINT , sig_handler);
2084 signal (SIGSEGV, sig_handler);
2087 /* Before parsing the command line options, do a
2088 * search for the port and processor and initialize
2089 * them if they're found. (We can't gurantee that these
2090 * will be the first options specified).
2093 _findPort (argc, argv);
2096 if (strcmp(port->target, "mcs51") == 0) {
2097 printf("DS390 jammed in A\n");
2103 _findProcessor (argc, argv);
2105 /* Initalise the port. */
2109 setDefaultOptions ();
2112 options.model = MODEL_SMALL;
2113 options.stack10bit=0;
2116 parseCmdLine (argc, argv);
2119 setBinPaths(argv[0]);
2120 setDataPaths(argv[0]);
2122 /* if no input then printUsage & exit */
2123 if (!options.c1mode && !fullSrcFileName && peekSet(relFilesSet) == NULL) {
2124 if (!options.printSearchDirs)
2130 /* initMem() is expensive, but
2131 initMem() must called before port->finaliseOptions ().
2132 And the z80 port needs port->finaliseOptions(),
2133 even if we're only linking. */
2135 port->finaliseOptions ();
2137 if (fullSrcFileName || options.c1mode)
2147 if (options.verbose)
2148 printf ("sdcc: Generating code...\n");
2153 deleteSetItem(&pipeSet, yyin);
2159 if (port->general.do_glue != NULL)
2160 (*port->general.do_glue)();
2163 /* this shouldn't happen */
2165 /* in case of NDEBUG */
2173 if (!options.c1mode && !noAssemble)
2175 if (options.verbose)
2176 printf ("sdcc: Calling assembler...\n");
2182 if (options.debug && debugFile)
2183 debugFile->closeFile();
2185 if (!options.cc_only &&
2189 (fullSrcFileName || peekSet(relFilesSet) != NULL))
2191 if (port->linker.do_link)
2192 port->linker.do_link ();