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, "Compile only; do not assemble or link" },
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, "external data space is used" },
139 { 0, OPTION_MEDIUM_MODEL, NULL, "not supported" },
140 { 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" },
141 { 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" },
142 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
143 { 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" },
144 { 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" },
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 and assemble, but do not 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, "<nnnn> External Ram start location" },
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, "<file> use this extra peep-hole file" },
169 { 0, OPTION_LIB_PATH, NULL, "<path> use this path to search for libraries" },
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, "initialize the stackpointer with the last byte use in DSEG" },
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, "<func[,func,...]> 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, "Do not include the standard include directory in the search path" },
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)" },
192 { 0, "--profile", &options.profile, "On supported ports, generate extra profiling information" }
195 /** Table of all unsupported options and help text to display when one
199 /** shortOpt as in OPTIONS. */
201 /** longOpt as in OPTIONS. */
203 /** Message to display inside W_UNSUPPORTED_OPT when this option
208 static const UNSUPPORTEDOPT
209 unsupportedOptTable[] = {
210 { 'a', NULL, "use --stack-auto instead." },
211 { 'g', NULL, "use --generic instead" },
212 { 'X', NULL, "use --xstack-loc instead" },
213 { 'x', NULL, "use --xstack instead" },
214 { 'p', NULL, "use --stack-loc instead" },
215 { 'P', NULL, "use --stack-loc instead" },
216 { 'i', NULL, "use --idata-loc instead" },
217 { 'r', NULL, "use --xdata-loc instead" },
218 { 's', NULL, "use --code-loc instead" },
219 { 'Y', NULL, "use -I instead" }
222 static const char *_preCmd[] =
224 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
225 "$l", "$1", "$2", NULL
230 static PORT *_ports[] =
232 #if !OPT_DISABLE_MCS51
235 #if !OPT_DISABLE_GBZ80
244 #if !OPT_DISABLE_DS390
250 #if !OPT_DISABLE_I186
253 #if !OPT_DISABLE_TLCS900H
258 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
261 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
263 extern void picglue ();
265 /** Sets the port to the one given by the command line option.
266 @param The name minus the option (eg 'mcs51')
267 @return 0 on success.
270 _setPort (const char *name)
273 for (i = 0; i < NUM_PORTS; i++)
275 if (!strcmp (_ports[i]->target, name))
281 /* Error - didnt find */
282 werror (E_UNKNOWN_TARGET, name);
287 _validatePorts (void)
290 for (i = 0; i < NUM_PORTS; i++)
292 if (_ports[i]->magic != PORT_MAGIC)
294 wassertl (0, "Port definition structure is incomplete");
298 /*-----------------------------------------------------------------*/
299 /* printVersionInfo - prints the version info */
300 /*-----------------------------------------------------------------*/
308 for (i = 0; i < NUM_PORTS; i++)
309 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
311 fprintf (stderr, " %s"
312 #ifdef SDCC_SUB_VERSION_STR
313 "/" SDCC_SUB_VERSION_STR
321 #if defined(_MSC_VER)
333 /*-----------------------------------------------------------------*/
334 /* printUsage - prints command line syntax */
335 /*-----------------------------------------------------------------*/
342 "Usage : sdcc [options] filename\n"
346 for (i = 0; i < LENGTH(optionsTable); i++) {
347 fprintf(stdout, " %c%c %-20s %s\n",
348 optionsTable[i].shortOpt !=0 ? '-' : ' ',
349 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
350 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
351 optionsTable[i].help != NULL ? optionsTable[i].help : ""
357 /*-----------------------------------------------------------------*/
358 /* parseWithComma - separates string with comma */
359 /*-----------------------------------------------------------------*/
361 parseWithComma (char **dest, char *src)
365 strtok (src, "\r\n \t");
366 /* skip the initial white spaces */
367 while (isspace (*src))
384 /*-----------------------------------------------------------------*/
385 /* setDefaultOptions - sets the default options */
386 /*-----------------------------------------------------------------*/
392 for (i = 0; i < 128; i++)
393 preArgv[i] = asmOptions[i] =
394 linkOptions[i] = relFiles[i] = libFiles[i] =
397 /* first the options part */
398 options.stack_loc = 0; /* stack pointer initialised to 0 */
399 options.xstack_loc = 0; /* xternal stack starts at 0 */
400 options.code_loc = 0; /* code starts at 0 */
401 options.data_loc = 0x0030; /* data starts at 0x0030 */
402 options.xdata_loc = 0;
403 options.idata_loc = 0x80;
404 options.genericPtr = 1; /* default on */
406 options.model = port->general.default_model;
407 options.nostdlib = 0;
408 options.nostdinc = 0;
410 options.shortis8bits = 0;
412 options.stack10bit=0;
414 /* now for the optimizations */
415 /* turn on the everything */
416 optimize.global_cse = 1;
421 optimize.loopInvariant = 1;
422 optimize.loopInduction = 1;
424 /* now for the ports */
425 port->setDefaultOptions ();
428 /*-----------------------------------------------------------------*/
429 /* processFile - determines the type of file from the extension */
430 /*-----------------------------------------------------------------*/
432 processFile (char *s)
436 /* get the file extension */
437 fext = s + strlen (s);
438 while ((fext != s) && *fext != '.')
441 /* now if no '.' then we don't know what the file type is
442 so give a warning and return */
445 werror (W_UNKNOWN_FEXT, s);
449 /* otherwise depending on the file type */
450 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
452 /* source file name : not if we already have a
456 werror (W_TOO_MANY_SRC, s);
460 /* the only source file */
461 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
463 werror (E_FILE_OPEN_ERR, s);
467 /* copy the file name into the buffer */
470 /* get rid of the "." */
471 strtok (buffer, ".");
472 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
473 strcpy (srcFileName, buffer);
475 /* get rid of any path information
476 for the module name; do this by going
477 backwards till we get to either '/' or '\' or ':'
478 or start of buffer */
479 fext = buffer + strlen (buffer);
480 while (fext != buffer &&
481 *(fext - 1) != '\\' &&
482 *(fext - 1) != '/' &&
485 moduleName = Safe_calloc (1, strlen (fext) + 1);
486 strcpy (moduleName, fext);
491 /* if the extention is type .rel or .r or .REL or .R
492 addtional object file will be passed to the linker */
493 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
494 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
495 strcmp (fext, port->linker.rel_ext) == 0)
497 relFiles[nrelFiles++] = s;
501 /* if .lib or .LIB */
502 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
504 libFiles[nlibFiles++] = s;
508 werror (W_UNKNOWN_FEXT, s);
513 _processC1Arg (char *s)
517 if (options.out_name)
519 werror (W_TOO_MANY_SRC, s);
522 options.out_name = strdup (s);
531 _addToList (const char **list, const char *str)
533 /* This is the bad way to do things :) */
536 *list = strdup (str);
539 werror (E_OUT_OF_MEM, __FILE__, 0);
546 _setModel (int model, const char *sz)
548 if (port->general.supported_models & model)
549 options.model = model;
551 werror (W_UNSUPPORTED_MODEL, sz, port->target);
554 /** Gets the string argument to this option. If the option is '--opt'
555 then for input of '--optxyz' or '--opt xyz' returns xyz.
558 getStringArg(const char *szStart, char **argv, int *pi, int argc)
560 if (argv[*pi][strlen(szStart)])
562 return &argv[*pi][strlen(szStart)];
569 werror (E_ARGUMENT_MISSING, szStart);
570 /* Die here rather than checking for errors later. */
580 /** Gets the integer argument to this option using the same rules as
584 getIntArg(const char *szStart, char **argv, int *pi, int argc)
586 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
590 verifyShortOption(const char *opt)
592 if (strlen(opt) != 2)
594 werror (W_EXCESS_SHORT_OPTIONS, opt);
599 tryHandleUnsupportedOpt(char **argv, int *pi)
601 if (argv[*pi][0] == '-')
603 const char *longOpt = "";
607 if (argv[*pi][1] == '-')
614 shortOpt = argv[*pi][1];
616 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
618 if (unsupportedOptTable[i].shortOpt == shortOpt ||
619 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
620 // Found an unsupported opt.
622 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
623 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
627 // Didn't find in the table
632 // Not an option, so can't be unsupported :)
638 tryHandleSimpleOpt(char **argv, int *pi)
640 if (argv[*pi][0] == '-')
642 const char *longOpt = "";
646 if (argv[*pi][1] == '-')
653 shortOpt = argv[*pi][1];
656 for (i = 0; i < LENGTH(optionsTable); i++)
658 if (optionsTable[i].shortOpt == shortOpt ||
659 (longOpt && optionsTable[i].longOpt &&
660 strcmp(optionsTable[i].longOpt, longOpt) == 0))
663 // If it is a flag then we can handle it here
664 if (optionsTable[i].pparameter != NULL)
666 if (optionsTable[i].shortOpt == shortOpt)
668 verifyShortOption(argv[*pi]);
671 (*optionsTable[i].pparameter)++;
675 // Not a flag. Handled manually later.
680 // Didn't find in the table
685 // Not an option, so can't be handled.
690 /*-----------------------------------------------------------------*/
691 /* parseCmdLine - parses the command line and sets the options */
692 /*-----------------------------------------------------------------*/
694 parseCmdLine (int argc, char **argv)
698 /* go thru all whole command line */
699 for (i = 1; i < argc; i++)
704 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
709 if (tryHandleSimpleOpt(argv, &i) == TRUE)
715 if (argv[i][0] == '-' && argv[i][1] == '-')
717 if (strcmp (argv[i], OPTION_HELP) == 0)
723 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
725 options.stack10bit = 0;
729 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
735 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
737 _setModel (MODEL_LARGE, argv[i]);
741 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
743 _setModel (MODEL_MEDIUM, argv[i]);
747 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
749 _setModel (MODEL_SMALL, argv[i]);
753 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
755 _setModel (MODEL_FLAT24, argv[i]);
759 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
761 options.dump_rassgn =
767 options.dump_raw = 1;
771 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
773 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
777 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
779 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i, argc);
783 if (strcmp (argv[i], OPTION_VERSION) == 0)
790 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
792 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
796 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
798 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
802 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
804 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
808 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
810 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
814 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
816 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
820 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
822 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
826 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
828 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
832 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
834 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
838 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
840 optimize.global_cse = 0;
844 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
846 optimize.loopInvariant = 0;
850 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
852 optimize.loopInduction = 0;
856 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
858 setErrorLogLevel(ERROR_LEVEL_WARNING);
862 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
864 options.shortis8bits=1;
868 if (!port->parseOption (&argc, argv, &i))
870 werror (W_UNKNOWN_OPTION, argv[i]);
878 /* if preceded by '-' then option */
884 verifyShortOption(argv[i]);
891 /* Used to select the port */
892 _setPort (argv[i] + 2);
896 verifyShortOption(argv[i]);
902 libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
906 libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
911 if (argv[i][2] == 'l')
913 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
917 /* assembler options */
918 if (argv[i][2] == 'a')
920 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
924 werror (W_UNKNOWN_OPTION, argv[i]);
930 verifyShortOption(argv[i]);
936 /* preprocessor options */
940 _addToList (preArgv, "-M");
945 _addToList (preArgv, "-C");
954 char sOpt = argv[i][1];
957 if (argv[i][2] == ' ' || argv[i][2] == '\0')
963 werror(E_ARGUMENT_MISSING, argv[i-1]);
977 sprintf (buffer, "-%c%s", sOpt, rest);
978 _addToList (preArgv, buffer);
983 if (!port->parseOption (&argc, argv, &i))
984 werror (W_UNKNOWN_OPTION, argv[i]);
989 if (!port->parseOption (&argc, argv, &i))
991 /* no option must be a filename */
993 _processC1Arg (argv[i]);
995 processFile (argv[i]);
999 /* set up external stack location if not explicitly specified */
1000 if (!options.xstack_loc)
1001 options.xstack_loc = options.xdata_loc;
1003 /* if debug option is set the open the cdbFile */
1004 if (options.debug && srcFileName)
1006 sprintf (scratchFileName, "%s.cdb", srcFileName);
1007 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1008 werror (E_FILE_OPEN_ERR, scratchFileName);
1011 /* add a module record */
1012 fprintf (cdbFile, "M:%s\n", moduleName);
1018 /*-----------------------------------------------------------------*/
1019 /* linkEdit : - calls the linkage editor with options */
1020 /*-----------------------------------------------------------------*/
1022 linkEdit (char **envp)
1029 srcFileName = "temp";
1031 /* first we need to create the <filename>.lnk file */
1032 sprintf (scratchFileName, "%s.lnk", srcFileName);
1033 if (!(lnkfile = fopen (scratchFileName, "w")))
1035 werror (E_FILE_OPEN_ERR, scratchFileName);
1039 /* now write the options */
1040 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1042 /* if iram size specified */
1043 if (options.iram_size)
1044 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1047 fprintf (lnkfile, "-z\n");
1049 #define WRITE_SEG_LOC(N, L) \
1050 segName = strdup(N); \
1051 c = strtok(segName, " \t"); \
1052 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1053 if (segName) { free(segName); }
1055 /* code segment start */
1056 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1058 /* data segment start */
1059 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1062 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1065 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1067 /* bit segment start */
1068 WRITE_SEG_LOC (BIT_NAME, 0);
1070 /* add the extra linker options */
1071 for (i = 0; linkOptions[i]; i++)
1072 fprintf (lnkfile, "%s\n", linkOptions[i]);
1074 /* other library paths if specified */
1075 for (i = 0; i < nlibPaths; i++)
1076 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1078 /* standard library path */
1079 if (!options.nostdlib)
1082 if (TARGET_IS_DS390)
1089 switch (options.model)
1102 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1107 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1109 /* standard library files */
1110 /* if (strcmp (port->target, "ds390") == 0) */
1111 if (options.model == MODEL_FLAT24)
1113 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1115 fprintf (lnkfile, "-l %s\n", STD_LIB);
1116 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1117 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1118 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1121 /* additional libraries if any */
1122 for (i = 0; i < nlibFiles; i++)
1123 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1125 /* put in the object files */
1126 if (strcmp (srcFileName, "temp"))
1127 fprintf (lnkfile, "%s ", srcFileName);
1129 for (i = 0; i < nrelFiles; i++)
1130 fprintf (lnkfile, "%s\n", relFiles[i]);
1132 fprintf (lnkfile, "\n-e\n");
1135 if (options.verbose)
1136 printf ("sdcc: Calling linker...\n");
1138 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1139 if (my_system (buffer))
1144 if (strcmp (srcFileName, "temp") == 0)
1146 /* rename "temp.cdb" to "firstRelFile.cdb" */
1147 char *f = strtok (strdup (relFiles[0]), ".");
1148 f = strcat (f, ".cdb");
1149 rename ("temp.cdb", f);
1154 /*-----------------------------------------------------------------*/
1155 /* assemble - spawns the assembler with arguments */
1156 /*-----------------------------------------------------------------*/
1158 assemble (char **envp)
1160 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1161 if (my_system (buffer))
1163 /* either system() or the assembler itself has reported an error
1164 perror ("Cannot exec assembler");
1172 /*-----------------------------------------------------------------*/
1173 /* preProcess - spawns the preprocessor with arguments */
1174 /*-----------------------------------------------------------------*/
1176 preProcess (char **envp)
1182 if (!options.c1mode)
1184 /* if using external stack define the macro */
1185 if (options.useXstack)
1186 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1188 /* set the macro for stack autos */
1189 if (options.stackAuto)
1190 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1192 /* set the macro for stack autos */
1193 if (options.stack10bit)
1194 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1196 /* set the macro for large model */
1197 switch (options.model)
1200 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1203 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1206 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1209 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1212 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1215 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1219 /* standard include path */
1220 if (!options.nostdinc) {
1221 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1224 /* add port (processor information to processor */
1225 sprintf (procDef, "-DSDCC_%s", port->target);
1226 _addToList (preArgv, procDef);
1227 sprintf (procDef, "-D__%s", port->target);
1228 _addToList (preArgv, procDef);
1231 preOutName = strdup (tmpnam (NULL));
1233 if (options.verbose)
1234 printf ("sdcc: Calling preprocessor...\n");
1236 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1237 preOutName, srcFileName, preArgv);
1238 if (my_system (buffer))
1240 // @FIX: Dario Vecchio 03-05-2001
1243 unlink (preOutName);
1257 preOutName = fullSrcFileName;
1260 yyin = fopen (preOutName, "r");
1263 perror ("Preproc file not found\n");
1271 _findPort (int argc, char **argv)
1277 if (!strncmp (*argv, "-m", 2))
1279 _setPort (*argv + 2);
1284 /* Use the first in the list */
1290 * initialises and calls the parser
1294 main (int argc, char **argv, char **envp)
1296 /* turn all optimizations off by default */
1297 memset (&optimize, 0, sizeof (struct optimize));
1299 /*printVersionInfo (); */
1302 fprintf (stderr, "Build error: no ports are enabled.\n");
1306 _findPort (argc, argv);
1307 /* Initalise the port. */
1311 // Create a default exe search path from the path to the sdcc command
1315 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1317 strcpy (DefaultExePath, argv[0]);
1318 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1319 ExePathList[0] = DefaultExePath;
1323 setDefaultOptions ();
1324 parseCmdLine (argc, argv);
1326 if (getenv("SDCPP"))
1328 _preCmd[0] = getenv("SDCPP");
1331 /* if no input then printUsage & exit */
1332 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1333 (options.c1mode && !srcFileName && !options.out_name))
1345 port->finaliseOptions ();
1352 if (options.verbose)
1353 printf ("sdcc: Generating code...\n");
1359 if (TARGET_IS_PIC) {
1360 /* TSD PIC port hack - if the PIC port option is enabled
1361 and SDCC is used to generate PIC code, then we will
1362 generate .asm files in gpasm's format instead of SDCC's
1365 #if !OPT_DISABLE_PIC
1374 // @FIX: Dario Vecchio 03-05-2001
1377 if (yyin && yyin != stdin)
1379 unlink (preOutName);
1385 if (!options.c1mode && !noAssemble)
1387 if (options.verbose)
1388 printf ("sdcc: Calling assembler...\n");
1394 // @FIX: Dario Vecchio 03-05-2001
1397 if (yyin && yyin != stdin)
1399 unlink (preOutName);
1403 #if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
1416 if (preOutName && !options.c1mode)
1418 unlink (preOutName);
1422 if (!options.cc_only &&
1426 (srcFileName || nrelFiles))
1428 if (port->linker.do_link)
1429 port->linker.do_link ();
1434 if (yyin && yyin != stdin)