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 // Globally accessible scratch buffer for file names.
79 char scratchFileName[FILENAME_MAX];
81 // In MSC VC6 default search path for exe's to path for this
83 char DefaultExePath[128];
85 #define OPTION_HELP "-help"
87 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
89 #define OPTION_STACK_8BIT "--stack-8bit"
90 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
91 #define OPTION_LARGE_MODEL "--model-large"
92 #define OPTION_MEDIUM_MODEL "--model-medium"
93 #define OPTION_SMALL_MODEL "--model-small"
94 #define OPTION_FLAT24_MODEL "--model-flat24"
95 #define OPTION_DUMP_ALL "--dumpall"
96 #define OPTION_PEEP_FILE "--peep-file"
97 #define OPTION_LIB_PATH "--lib-path"
98 #define OPTION_XSTACK_LOC "--xstack-loc"
99 #define OPTION_CALLEE_SAVES "--callee-saves"
100 #define OPTION_STACK_LOC "--stack-loc"
101 #define OPTION_XRAM_LOC "--xram-loc"
102 #define OPTION_IRAM_SIZE "--iram-size"
103 #define OPTION_VERSION "--version"
104 #define OPTION_DATA_LOC "--data-loc"
105 #define OPTION_CODE_LOC "--code-loc"
106 #define OPTION_IDATA_LOC "--idata-loc"
107 #define OPTION_NO_LOOP_INV "--noinvariant"
108 #define OPTION_NO_LOOP_IND "--noinduction"
109 #define OPTION_LESS_PEDANTIC "--lesspedantic"
110 #define OPTION_NO_GCSE "--nogcse"
111 #define OPTION_SHORT_IS_CHAR "--short-is-char"
113 /** Table of all options supported by all ports.
115 * A reference for all options.
116 * An easy way to maintain help for the options.
117 * Automatic support for setting flags on simple options.
120 /** The short option character e.g. 'h' for -h. 0 for none. */
122 /** Long option e.g. "--help". Includes the -- prefix. NULL for
125 /** Pointer to an int that will be incremented every time the
126 option is encountered. May be NULL.
129 /** Help text to go with this option. May be NULL. */
135 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
136 { 'd', NULL, NULL, NULL },
137 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
138 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
139 { 'A', NULL, NULL, NULL },
140 { 'U', NULL, NULL, NULL },
141 { 'C', NULL, NULL, "Preprocessor option" },
142 { 'M', NULL, NULL, "Preprocessor option" },
143 { 'V', NULL, &verboseExec, "Execute verbosely. Show sub commands as they are run" },
144 { 'S', NULL, &noAssemble, "Assemble only" },
145 { 'W', NULL, NULL, "Pass through options to the assembler (a) or linker (l)" },
146 { 'L', NULL, NULL, "Add the next field to the library search path" },
147 { 0, OPTION_LARGE_MODEL, NULL, "Far functions, far data" },
148 { 0, OPTION_MEDIUM_MODEL, NULL, "Far functions, near data" },
149 { 0, OPTION_SMALL_MODEL, NULL, "Small model (default)" },
150 { 0, OPTION_FLAT24_MODEL, NULL, NULL },
151 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
152 { 0, OPTION_STACK_8BIT, NULL, NULL },
153 { 0, "--stack-10bit", &options.stack10bit, NULL },
154 { 0, "--xstack", &options.useXstack, "Use external stack" },
155 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
156 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
157 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
158 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
159 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
160 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
161 { 0, "--regextend", &options.regExtend, NULL },
162 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or link" },
163 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
164 { 0, "--dumpgcse", &options.dump_gcse, NULL },
165 { 0, "--dumploop", &options.dump_loop, NULL },
166 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
167 { 0, "--dumpliverange", &options.dump_range, NULL },
168 { 0, "--dumpregpack", &options.dump_pack, NULL },
169 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
170 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
171 { 0, OPTION_XRAM_LOC, NULL, NULL },
172 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
173 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
174 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
175 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
176 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
177 { 0, OPTION_IDATA_LOC, NULL, NULL },
178 { 0, OPTION_PEEP_FILE, NULL, NULL },
179 { 0, OPTION_LIB_PATH, NULL, NULL },
180 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
181 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
182 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
183 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
184 { 0, "--cyclomatic", &options.cyclomatic, NULL },
185 { 0, "--nooverlay", &options.noOverlay, NULL },
186 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
187 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
188 { 0, "--peep-asm", &options.asmpeep, NULL },
189 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
190 { 0, "--nodebug", &options.nodebug, "Disable debugging symbol output" },
191 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
192 { 0, "--stack-after-data", &options.stackOnData, NULL },
193 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
194 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
195 { 0, "--help", NULL, "Display this help" },
196 { 0, OPTION_CALLEE_SAVES, NULL, "Cause the called function to save registers insted of the caller" },
197 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
198 { 0, "--nostdinc", &options.nostdinc, NULL },
199 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
200 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
201 { 0, "--short-is-int", &options.shortisint, "Make short the same size as int" },
202 { 0, OPTION_SHORT_IS_CHAR, NULL, "Make short the same size as char (default)" }
205 /** Table of all unsupported options and help text to display when one
209 /** shortOpt as in OPTIONS. */
211 /** longOpt as in OPTIONS. */
213 /** Message to display inside W_UNSUPPORTED_OPT when this option
218 static const UNSUPPORTEDOPT
219 unsupportedOptTable[] = {
220 { 'a', NULL, "use --stack-auto instead." },
221 { 'g', NULL, "use --generic instead" },
222 { 'X', NULL, "use --xstack-loc instead" },
223 { 'x', NULL, "use --xstack instead" },
224 { 'p', NULL, "use --stack-loc instead" },
225 { 'P', NULL, "use --stack-loc instead" },
226 { 'i', NULL, "use --idata-loc instead" },
227 { 'r', NULL, "use --xdata-loc instead" },
228 { 's', NULL, "use --code-loc instead" },
229 { 'Y', NULL, "use -I instead" }
232 static const char *_preCmd[] =
234 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
235 "$l", "$1", "$2", NULL
240 static PORT *_ports[] =
242 #if !OPT_DISABLE_MCS51
245 #if !OPT_DISABLE_GBZ80
254 #if !OPT_DISABLE_DS390
260 #if !OPT_DISABLE_I186
263 #if !OPT_DISABLE_TLCS900H
268 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
271 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
273 extern void picglue ();
275 /** Sets the port to the one given by the command line option.
276 @param The name minus the option (eg 'mcs51')
277 @return 0 on success.
280 _setPort (const char *name)
283 for (i = 0; i < NUM_PORTS; i++)
285 if (!strcmp (_ports[i]->target, name))
291 /* Error - didnt find */
292 werror (E_UNKNOWN_TARGET, name);
297 _validatePorts (void)
300 for (i = 0; i < NUM_PORTS; i++)
302 if (_ports[i]->magic != PORT_MAGIC)
304 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
309 /*-----------------------------------------------------------------*/
310 /* printVersionInfo - prints the version info */
311 /*-----------------------------------------------------------------*/
319 for (i = 0; i < NUM_PORTS; i++)
320 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
322 fprintf (stderr, " %s"
323 #ifdef SDCC_SUB_VERSION_STR
324 "/" SDCC_SUB_VERSION_STR
332 #if defined(_MSC_VER)
345 "\t-m<proc> - Target processor <proc>. Default %s\n"
346 "\t Try --version for supported values of <proc>\n"
347 "\t--model-large - Large Model\n"
348 "\t--model-small - Small Model (default)\n"
349 "\t--stack-auto - Stack automatic variables\n"
350 "\t--xstack - Use external stack\n"
351 "\t--xram-loc <nnnn> - External Ram start location\n"
352 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
353 "\t--code-loc <nnnn> - Code Segment Location\n"
354 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
355 "\t--data-loc <nnnn> - Direct data start location\n"
356 "\t--idata-loc <nnnn> - Indirect data start location\n"
357 "\t--iram-size <nnnn> - Internal Ram size\n"
358 "\t--nojtbound - Don't generate boundary check for jump tables\n"
359 "\t--generic - All unqualified ptrs converted to '_generic'\n"
360 "PreProcessor Options :-\n"
361 "\t-Dmacro - Define Macro\n"
362 "\t-Ipath - Include \"*.h\" path\n"
363 "Note: this is NOT a complete list of options see docs for details\n",
365 /*-----------------------------------------------------------------*/
366 /* printUsage - prints command line syntax */
367 /*-----------------------------------------------------------------*/
374 "Usage : sdcc [options] filename\n"
378 for (i = 0; i < LENGTH(optionsTable); i++) {
379 fprintf(stdout, " %c%c %-20s %s\n",
380 optionsTable[i].shortOpt !=0 ? '-' : ' ',
381 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
382 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
383 optionsTable[i].help != NULL ? optionsTable[i].help : ""
389 /*-----------------------------------------------------------------*/
390 /* parseWithComma - separates string with comma */
391 /*-----------------------------------------------------------------*/
393 parseWithComma (char **dest, char *src)
397 strtok (src, "\n \t");
398 /* skip the initial white spaces */
399 while (isspace (*src))
416 /*-----------------------------------------------------------------*/
417 /* setDefaultOptions - sets the default options */
418 /*-----------------------------------------------------------------*/
424 for (i = 0; i < 128; i++)
425 preArgv[i] = asmOptions[i] =
426 linkOptions[i] = relFiles[i] = libFiles[i] =
429 /* first the options part */
430 options.stack_loc = 0; /* stack pointer initialised to 0 */
431 options.xstack_loc = 0; /* xternal stack starts at 0 */
432 options.code_loc = 0; /* code starts at 0 */
433 options.data_loc = 0x0030; /* data starts at 0x0030 */
434 options.xdata_loc = 0;
435 options.idata_loc = 0x80;
436 options.genericPtr = 1; /* default on */
438 options.model = port->general.default_model;
439 options.nostdlib = 0;
440 options.nostdinc = 0;
442 options.shortisint = 0;
444 options.stack10bit=0;
446 /* now for the optimizations */
447 /* turn on the everything */
448 optimize.global_cse = 1;
453 optimize.loopInvariant = 1;
454 optimize.loopInduction = 1;
456 /* now for the ports */
457 port->setDefaultOptions ();
460 /*-----------------------------------------------------------------*/
461 /* processFile - determines the type of file from the extension */
462 /*-----------------------------------------------------------------*/
464 processFile (char *s)
468 /* get the file extension */
469 fext = s + strlen (s);
470 while ((fext != s) && *fext != '.')
473 /* now if no '.' then we don't know what the file type is
474 so give a warning and return */
477 werror (W_UNKNOWN_FEXT, s);
481 /* otherwise depending on the file type */
482 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
484 /* source file name : not if we already have a
488 werror (W_TOO_MANY_SRC, s);
492 /* the only source file */
493 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
495 werror (E_FILE_OPEN_ERR, s);
499 /* copy the file name into the buffer */
502 /* get rid of the "." */
503 strtok (buffer, ".");
504 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
505 strcpy (srcFileName, buffer);
507 /* get rid of any path information
508 for the module name; do this by going
509 backwards till we get to either '/' or '\' or ':'
510 or start of buffer */
511 fext = buffer + strlen (buffer);
512 while (fext != buffer &&
513 *(fext - 1) != '\\' &&
514 *(fext - 1) != '/' &&
517 moduleName = Safe_calloc (1, strlen (fext) + 1);
518 strcpy (moduleName, fext);
523 /* if the extention is type .rel or .r or .REL or .R
524 addtional object file will be passed to the linker */
525 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
526 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
527 strcmp (fext, port->linker.rel_ext) == 0)
529 relFiles[nrelFiles++] = s;
533 /* if .lib or .LIB */
534 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
536 libFiles[nlibFiles++] = s;
540 werror (W_UNKNOWN_FEXT, s);
545 _processC1Arg (char *s)
549 if (options.out_name)
551 werror (W_TOO_MANY_SRC, s);
554 options.out_name = strdup (s);
563 _addToList (const char **list, const char *str)
565 /* This is the bad way to do things :) */
568 *list = strdup (str);
571 werror (E_OUT_OF_MEM, __FILE__, 0);
578 _setModel (int model, const char *sz)
580 if (port->general.supported_models & model)
581 options.model = model;
583 werror (W_UNSUPPORTED_MODEL, sz, port->target);
586 /** Gets the string argument to this option. If the option is '--opt'
587 then for input of '--optxyz' or '--opt xyz' returns xyz.
590 getStringArg(const char *szStart, char **argv, int *pi)
592 if (argv[*pi][strlen(szStart)]) {
593 return &argv[*pi][strlen(szStart)];
596 return argv[++(*pi)];
600 /** Gets the integer argument to this option using the same rules as
604 getIntArg(const char *szStart, char **argv, int *pi)
606 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi)));
610 tryHandleUnsupportedOpt(char **argv, int *pi)
612 if (argv[*pi][0] == '-')
614 const char *longOpt = "";
618 if (argv[*pi][1] == '-')
625 shortOpt = argv[*pi][1];
627 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
629 if (unsupportedOptTable[i].shortOpt == shortOpt ||
630 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
631 // Found an unsupported opt.
633 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
634 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
638 // Didn't find in the table
643 // Not an option, so can't be unsupported :)
649 tryHandleSimpleOpt(char **argv, int *pi)
651 if (argv[*pi][0] == '-')
653 const char *longOpt = "";
657 if (argv[*pi][1] == '-')
664 shortOpt = argv[*pi][1];
667 for (i = 0; i < LENGTH(optionsTable); i++)
669 if (optionsTable[i].shortOpt == shortOpt ||
670 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
672 // If it is a flag then we can handle it here
673 if (optionsTable[i].pparameter != NULL)
675 (*optionsTable[i].pparameter)++;
679 // Not a flag. Handled manually later.
684 // Didn't find in the table
689 // Not an option, so can't be handled.
694 /*-----------------------------------------------------------------*/
695 /* parseCmdLine - parses the command line and sets the options */
696 /*-----------------------------------------------------------------*/
698 parseCmdLine (int argc, char **argv)
702 /* go thru all whole command line */
703 for (i = 1; i < argc; i++)
708 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
713 if (tryHandleSimpleOpt(argv, &i) == TRUE)
719 if (argv[i][0] == '-' && argv[i][1] == '-')
721 if (strcmp (argv[i], OPTION_HELP) == 0)
727 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
729 options.stack10bit = 0;
733 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
739 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
741 _setModel (MODEL_LARGE, argv[i]);
745 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
747 _setModel (MODEL_MEDIUM, argv[i]);
751 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
753 _setModel (MODEL_SMALL, argv[i]);
757 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
759 _setModel (MODEL_FLAT24, argv[i]);
763 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
765 options.dump_rassgn =
771 options.dump_raw = 1;
775 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
777 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i);
781 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
783 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i);
787 if (strcmp (argv[i], OPTION_VERSION) == 0)
794 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
796 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i));
800 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
802 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i);
806 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
808 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i);
812 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
814 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i);
818 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
820 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i);
824 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
826 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i);
830 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
832 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i);
836 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
838 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i);
842 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
844 optimize.global_cse = 0;
848 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
850 optimize.loopInvariant = 0;
854 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
856 optimize.loopInduction = 0;
860 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
862 setErrorLogLevel(ERROR_LEVEL_WARNING);
866 if (strcmp (&argv[i][1], OPTION_SHORT_IS_CHAR) == 0) {
867 options.shortisint=0;
871 if (!port->parseOption (&argc, argv, &i))
873 werror (W_UNKNOWN_OPTION, argv[i]);
881 /* if preceded by '-' then option */
892 /* Used to select the port */
893 _setPort (argv[i] + 2);
901 libPaths[nlibPaths++] = getStringArg("-L", argv, &i);
906 if (argv[i][2] == 'l')
908 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i));
912 /* assembler options */
913 if (argv[i][2] == 'a')
915 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i));
919 werror (W_UNKNOWN_OPTION, argv[i]);
929 /* preprocessor options */
933 _addToList (preArgv, "-M");
938 _addToList (preArgv, "-C");
947 char sOpt = argv[i][1];
950 if (argv[i][2] == ' ' || argv[i][2] == '\0')
956 werror(E_ARGUMENT_MISSING, argv[i-1]);
970 sprintf (buffer, "-%c%s", sOpt, rest);
971 _addToList (preArgv, buffer);
976 if (!port->parseOption (&argc, argv, &i))
977 werror (W_UNKNOWN_OPTION, argv[i]);
982 if (!port->parseOption (&argc, argv, &i))
984 /* no option must be a filename */
986 _processC1Arg (argv[i]);
988 processFile (argv[i]);
992 /* set up external stack location if not explicitly specified */
993 if (!options.xstack_loc)
994 options.xstack_loc = options.xdata_loc;
996 /* if debug option is set the open the cdbFile */
997 if (!options.nodebug && srcFileName)
999 sprintf (scratchFileName, "%s.cdb", srcFileName);
1000 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1001 werror (E_FILE_OPEN_ERR, scratchFileName);
1004 /* add a module record */
1005 fprintf (cdbFile, "M:%s\n", moduleName);
1011 /*-----------------------------------------------------------------*/
1012 /* linkEdit : - calls the linkage editor with options */
1013 /*-----------------------------------------------------------------*/
1015 linkEdit (char **envp)
1022 srcFileName = "temp";
1024 /* first we need to create the <filename>.lnk file */
1025 sprintf (scratchFileName, "%s.lnk", srcFileName);
1026 if (!(lnkfile = fopen (scratchFileName, "w")))
1028 werror (E_FILE_OPEN_ERR, scratchFileName);
1032 /* now write the options */
1033 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1035 /* if iram size specified */
1036 if (options.iram_size)
1037 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1039 /*if (options.debug) */
1040 fprintf (lnkfile, "-z\n");
1042 #define WRITE_SEG_LOC(N, L) \
1043 segName = strdup(N); \
1044 c = strtok(segName, " \t"); \
1045 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1046 if (segName) { free(segName); }
1048 /* code segment start */
1049 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1051 /* data segment start */
1052 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1055 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1058 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1060 /* bit segment start */
1061 WRITE_SEG_LOC (BIT_NAME, 0);
1063 /* add the extra linker options */
1064 for (i = 0; linkOptions[i]; i++)
1065 fprintf (lnkfile, "%s\n", linkOptions[i]);
1067 /* other library paths if specified */
1068 for (i = 0; i < nlibPaths; i++)
1069 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1071 /* standard library path */
1072 if (!options.nostdlib)
1074 if (TARGET_IS_DS390)
1080 switch (options.model)
1092 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1097 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1099 /* standard library files */
1100 if (strcmp (port->target, "ds390") == 0)
1102 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1104 fprintf (lnkfile, "-l %s\n", STD_LIB);
1105 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1106 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1107 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1110 /* additional libraries if any */
1111 for (i = 0; i < nlibFiles; i++)
1112 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1114 /* put in the object files */
1115 if (strcmp (srcFileName, "temp"))
1116 fprintf (lnkfile, "%s ", srcFileName);
1118 for (i = 0; i < nrelFiles; i++)
1119 fprintf (lnkfile, "%s\n", relFiles[i]);
1121 fprintf (lnkfile, "\n-e\n");
1124 if (options.verbose)
1125 printf ("sdcc: Calling linker...\n");
1127 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1128 if (my_system (buffer))
1133 if (strcmp (srcFileName, "temp") == 0)
1135 /* rename "temp.cdb" to "firstRelFile.cdb" */
1136 char *f = strtok (strdup (relFiles[0]), ".");
1137 f = strcat (f, ".cdb");
1138 rename ("temp.cdb", f);
1143 /*-----------------------------------------------------------------*/
1144 /* assemble - spawns the assembler with arguments */
1145 /*-----------------------------------------------------------------*/
1147 assemble (char **envp)
1149 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1150 if (my_system (buffer))
1152 /* either system() or the assembler itself has reported an error
1153 perror ("Cannot exec assembler");
1161 /*-----------------------------------------------------------------*/
1162 /* preProcess - spawns the preprocessor with arguments */
1163 /*-----------------------------------------------------------------*/
1165 preProcess (char **envp)
1171 if (!options.c1mode)
1173 /* if using external stack define the macro */
1174 if (options.useXstack)
1175 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1177 /* set the macro for stack autos */
1178 if (options.stackAuto)
1179 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1181 /* set the macro for stack autos */
1182 if (options.stack10bit)
1183 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1185 /* set the macro for large model */
1186 switch (options.model)
1189 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1192 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1195 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1198 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1201 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1204 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1208 /* standard include path */
1209 if (!options.nostdinc) {
1210 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1213 /* add port (processor information to processor */
1214 sprintf (procDef, "-DSDCC_%s", port->target);
1215 _addToList (preArgv, procDef);
1216 sprintf (procDef, "-D__%s", port->target);
1217 _addToList (preArgv, procDef);
1220 preOutName = strdup (tmpnam (NULL));
1222 if (options.verbose)
1223 printf ("sdcc: Calling preprocessor...\n");
1225 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1226 preOutName, srcFileName, preArgv);
1227 if (my_system (buffer))
1229 // @FIX: Dario Vecchio 03-05-2001
1232 unlink (preOutName);
1246 preOutName = fullSrcFileName;
1249 yyin = fopen (preOutName, "r");
1252 perror ("Preproc file not found\n");
1260 _findPort (int argc, char **argv)
1266 if (!strncmp (*argv, "-m", 2))
1268 _setPort (*argv + 2);
1273 /* Use the first in the list */
1279 * initialises and calls the parser
1283 main (int argc, char **argv, char **envp)
1285 /* turn all optimizations off by default */
1286 memset (&optimize, 0, sizeof (struct optimize));
1288 /*printVersionInfo (); */
1291 fprintf (stderr, "Build error: no ports are enabled.\n");
1295 _findPort (argc, argv);
1296 /* Initalise the port. */
1300 // Create a default exe search path from the path to the sdcc command
1304 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1306 strcpy (DefaultExePath, argv[0]);
1307 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1308 ExePathList[0] = DefaultExePath;
1312 setDefaultOptions ();
1313 parseCmdLine (argc, argv);
1317 port->finaliseOptions ();
1319 /* if no input then printUsage & exit */
1320 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1321 (options.c1mode && !srcFileName && !options.out_name))
1336 if (options.verbose)
1337 printf ("sdcc: Generating code...\n");
1343 if (TARGET_IS_PIC) {
1344 /* TSD PIC port hack - if the PIC port option is enabled
1345 and SDCC is used to generate PIC code, then we will
1346 generate .asm files in gpasm's format instead of SDCC's
1349 #if !OPT_DISABLE_PIC
1358 // @FIX: Dario Vecchio 03-05-2001
1361 if (yyin && yyin != stdin)
1363 unlink (preOutName);
1369 if (!options.c1mode)
1371 if (options.verbose)
1372 printf ("sdcc: Calling assembler...\n");
1378 // @FIX: Dario Vecchio 03-05-2001
1381 if (yyin && yyin != stdin)
1383 unlink (preOutName);
1397 if (!options.cc_only &&
1401 (srcFileName || nrelFiles))
1403 if (port->linker.do_link)
1404 port->linker.do_link ();
1409 if (yyin && yyin != stdin)
1412 if (preOutName && !options.c1mode)
1414 unlink (preOutName);