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_8BITS "--short-is-8bits"
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 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or link" },
162 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
163 { 0, "--dumpgcse", &options.dump_gcse, NULL },
164 { 0, "--dumploop", &options.dump_loop, NULL },
165 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
166 { 0, "--dumpliverange", &options.dump_range, NULL },
167 { 0, "--dumpregpack", &options.dump_pack, NULL },
168 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
169 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
170 { 0, OPTION_XRAM_LOC, NULL, NULL },
171 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
172 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
173 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
174 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
175 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
176 { 0, OPTION_IDATA_LOC, NULL, NULL },
177 { 0, OPTION_PEEP_FILE, NULL, NULL },
178 { 0, OPTION_LIB_PATH, NULL, NULL },
179 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
180 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
181 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
182 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
183 { 0, "--cyclomatic", &options.cyclomatic, NULL },
184 { 0, "--nooverlay", &options.noOverlay, NULL },
185 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
186 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
187 { 0, "--peep-asm", &options.asmpeep, NULL },
188 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
189 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
190 { 0, "--stack-after-data", &options.stackOnData, NULL },
191 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
192 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
193 { 0, "--help", NULL, "Display this help" },
194 { 0, OPTION_CALLEE_SAVES, NULL, "Cause the called function to save registers insted of the caller" },
195 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
196 { 0, "--nostdinc", &options.nostdinc, NULL },
197 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
198 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
199 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }
202 /** Table of all unsupported options and help text to display when one
206 /** shortOpt as in OPTIONS. */
208 /** longOpt as in OPTIONS. */
210 /** Message to display inside W_UNSUPPORTED_OPT when this option
215 static const UNSUPPORTEDOPT
216 unsupportedOptTable[] = {
217 { 'a', NULL, "use --stack-auto instead." },
218 { 'g', NULL, "use --generic instead" },
219 { 'X', NULL, "use --xstack-loc instead" },
220 { 'x', NULL, "use --xstack instead" },
221 { 'p', NULL, "use --stack-loc instead" },
222 { 'P', NULL, "use --stack-loc instead" },
223 { 'i', NULL, "use --idata-loc instead" },
224 { 'r', NULL, "use --xdata-loc instead" },
225 { 's', NULL, "use --code-loc instead" },
226 { 'Y', NULL, "use -I instead" }
229 static const char *_preCmd[] =
231 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
232 "$l", "$1", "$2", NULL
237 static PORT *_ports[] =
239 #if !OPT_DISABLE_MCS51
242 #if !OPT_DISABLE_GBZ80
251 #if !OPT_DISABLE_DS390
257 #if !OPT_DISABLE_I186
260 #if !OPT_DISABLE_TLCS900H
265 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
268 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
270 extern void picglue ();
272 /** Sets the port to the one given by the command line option.
273 @param The name minus the option (eg 'mcs51')
274 @return 0 on success.
277 _setPort (const char *name)
280 for (i = 0; i < NUM_PORTS; i++)
282 if (!strcmp (_ports[i]->target, name))
288 /* Error - didnt find */
289 werror (E_UNKNOWN_TARGET, name);
294 _validatePorts (void)
297 for (i = 0; i < NUM_PORTS; i++)
299 if (_ports[i]->magic != PORT_MAGIC)
301 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
306 /*-----------------------------------------------------------------*/
307 /* printVersionInfo - prints the version info */
308 /*-----------------------------------------------------------------*/
316 for (i = 0; i < NUM_PORTS; i++)
317 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
319 fprintf (stderr, " %s"
320 #ifdef SDCC_SUB_VERSION_STR
321 "/" SDCC_SUB_VERSION_STR
329 #if defined(_MSC_VER)
342 "\t-m<proc> - Target processor <proc>. Default %s\n"
343 "\t Try --version for supported values of <proc>\n"
344 "\t--model-large - Large Model\n"
345 "\t--model-small - Small Model (default)\n"
346 "\t--stack-auto - Stack automatic variables\n"
347 "\t--xstack - Use external stack\n"
348 "\t--xram-loc <nnnn> - External Ram start location\n"
349 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
350 "\t--code-loc <nnnn> - Code Segment Location\n"
351 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
352 "\t--data-loc <nnnn> - Direct data start location\n"
353 "\t--idata-loc <nnnn> - Indirect data start location\n"
354 "\t--iram-size <nnnn> - Internal Ram size\n"
355 "\t--nojtbound - Don't generate boundary check for jump tables\n"
356 "\t--generic - All unqualified ptrs converted to '_generic'\n"
357 "PreProcessor Options :-\n"
358 "\t-Dmacro - Define Macro\n"
359 "\t-Ipath - Include \"*.h\" path\n"
360 "Note: this is NOT a complete list of options see docs for details\n",
362 /*-----------------------------------------------------------------*/
363 /* printUsage - prints command line syntax */
364 /*-----------------------------------------------------------------*/
371 "Usage : sdcc [options] filename\n"
375 for (i = 0; i < LENGTH(optionsTable); i++) {
376 fprintf(stdout, " %c%c %-20s %s\n",
377 optionsTable[i].shortOpt !=0 ? '-' : ' ',
378 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
379 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
380 optionsTable[i].help != NULL ? optionsTable[i].help : ""
386 /*-----------------------------------------------------------------*/
387 /* parseWithComma - separates string with comma */
388 /*-----------------------------------------------------------------*/
390 parseWithComma (char **dest, char *src)
394 strtok (src, "\n \t");
395 /* skip the initial white spaces */
396 while (isspace (*src))
413 /*-----------------------------------------------------------------*/
414 /* setDefaultOptions - sets the default options */
415 /*-----------------------------------------------------------------*/
421 for (i = 0; i < 128; i++)
422 preArgv[i] = asmOptions[i] =
423 linkOptions[i] = relFiles[i] = libFiles[i] =
426 /* first the options part */
427 options.stack_loc = 0; /* stack pointer initialised to 0 */
428 options.xstack_loc = 0; /* xternal stack starts at 0 */
429 options.code_loc = 0; /* code starts at 0 */
430 options.data_loc = 0x0030; /* data starts at 0x0030 */
431 options.xdata_loc = 0;
432 options.idata_loc = 0x80;
433 options.genericPtr = 1; /* default on */
435 options.model = port->general.default_model;
436 options.nostdlib = 0;
437 options.nostdinc = 0;
439 options.shortis8bits = 1;
441 options.stack10bit=0;
443 /* now for the optimizations */
444 /* turn on the everything */
445 optimize.global_cse = 1;
450 optimize.loopInvariant = 1;
451 optimize.loopInduction = 1;
453 /* now for the ports */
454 port->setDefaultOptions ();
457 /*-----------------------------------------------------------------*/
458 /* processFile - determines the type of file from the extension */
459 /*-----------------------------------------------------------------*/
461 processFile (char *s)
465 /* get the file extension */
466 fext = s + strlen (s);
467 while ((fext != s) && *fext != '.')
470 /* now if no '.' then we don't know what the file type is
471 so give a warning and return */
474 werror (W_UNKNOWN_FEXT, s);
478 /* otherwise depending on the file type */
479 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
481 /* source file name : not if we already have a
485 werror (W_TOO_MANY_SRC, s);
489 /* the only source file */
490 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
492 werror (E_FILE_OPEN_ERR, s);
496 /* copy the file name into the buffer */
499 /* get rid of the "." */
500 strtok (buffer, ".");
501 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
502 strcpy (srcFileName, buffer);
504 /* get rid of any path information
505 for the module name; do this by going
506 backwards till we get to either '/' or '\' or ':'
507 or start of buffer */
508 fext = buffer + strlen (buffer);
509 while (fext != buffer &&
510 *(fext - 1) != '\\' &&
511 *(fext - 1) != '/' &&
514 moduleName = Safe_calloc (1, strlen (fext) + 1);
515 strcpy (moduleName, fext);
520 /* if the extention is type .rel or .r or .REL or .R
521 addtional object file will be passed to the linker */
522 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
523 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
524 strcmp (fext, port->linker.rel_ext) == 0)
526 relFiles[nrelFiles++] = s;
530 /* if .lib or .LIB */
531 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
533 libFiles[nlibFiles++] = s;
537 werror (W_UNKNOWN_FEXT, s);
542 _processC1Arg (char *s)
546 if (options.out_name)
548 werror (W_TOO_MANY_SRC, s);
551 options.out_name = strdup (s);
560 _addToList (const char **list, const char *str)
562 /* This is the bad way to do things :) */
565 *list = strdup (str);
568 werror (E_OUT_OF_MEM, __FILE__, 0);
575 _setModel (int model, const char *sz)
577 if (port->general.supported_models & model)
578 options.model = model;
580 werror (W_UNSUPPORTED_MODEL, sz, port->target);
583 /** Gets the string argument to this option. If the option is '--opt'
584 then for input of '--optxyz' or '--opt xyz' returns xyz.
587 getStringArg(const char *szStart, char **argv, int *pi)
589 if (argv[*pi][strlen(szStart)]) {
590 return &argv[*pi][strlen(szStart)];
593 return argv[++(*pi)];
597 /** Gets the integer argument to this option using the same rules as
601 getIntArg(const char *szStart, char **argv, int *pi)
603 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi)));
607 tryHandleUnsupportedOpt(char **argv, int *pi)
609 if (argv[*pi][0] == '-')
611 const char *longOpt = "";
615 if (argv[*pi][1] == '-')
622 shortOpt = argv[*pi][1];
624 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
626 if (unsupportedOptTable[i].shortOpt == shortOpt ||
627 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
628 // Found an unsupported opt.
630 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
631 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
635 // Didn't find in the table
640 // Not an option, so can't be unsupported :)
646 tryHandleSimpleOpt(char **argv, int *pi)
648 if (argv[*pi][0] == '-')
650 const char *longOpt = "";
654 if (argv[*pi][1] == '-')
661 shortOpt = argv[*pi][1];
664 for (i = 0; i < LENGTH(optionsTable); i++)
666 if (optionsTable[i].shortOpt == shortOpt ||
667 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
669 // If it is a flag then we can handle it here
670 if (optionsTable[i].pparameter != NULL)
672 (*optionsTable[i].pparameter)++;
676 // Not a flag. Handled manually later.
681 // Didn't find in the table
686 // Not an option, so can't be handled.
691 /*-----------------------------------------------------------------*/
692 /* parseCmdLine - parses the command line and sets the options */
693 /*-----------------------------------------------------------------*/
695 parseCmdLine (int argc, char **argv)
699 /* go thru all whole command line */
700 for (i = 1; i < argc; i++)
705 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
710 if (tryHandleSimpleOpt(argv, &i) == TRUE)
716 if (argv[i][0] == '-' && argv[i][1] == '-')
718 if (strcmp (argv[i], OPTION_HELP) == 0)
724 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
726 options.stack10bit = 0;
730 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
736 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
738 _setModel (MODEL_LARGE, argv[i]);
742 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
744 _setModel (MODEL_MEDIUM, argv[i]);
748 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
750 _setModel (MODEL_SMALL, argv[i]);
754 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
756 _setModel (MODEL_FLAT24, argv[i]);
760 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
762 options.dump_rassgn =
768 options.dump_raw = 1;
772 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
774 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i);
778 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
780 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i);
784 if (strcmp (argv[i], OPTION_VERSION) == 0)
791 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
793 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i));
797 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
799 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i);
803 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
805 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i);
809 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
811 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i);
815 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
817 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i);
821 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
823 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i);
827 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
829 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i);
833 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
835 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i);
839 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
841 optimize.global_cse = 0;
845 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
847 optimize.loopInvariant = 0;
851 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
853 optimize.loopInduction = 0;
857 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
859 setErrorLogLevel(ERROR_LEVEL_WARNING);
863 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 */
889 /* Used to select the port */
890 _setPort (argv[i] + 2);
898 libPaths[nlibPaths++] = getStringArg("-L", argv, &i);
903 if (argv[i][2] == 'l')
905 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i));
909 /* assembler options */
910 if (argv[i][2] == 'a')
912 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i));
916 werror (W_UNKNOWN_OPTION, argv[i]);
926 /* preprocessor options */
930 _addToList (preArgv, "-M");
935 _addToList (preArgv, "-C");
944 char sOpt = argv[i][1];
947 if (argv[i][2] == ' ' || argv[i][2] == '\0')
953 werror(E_ARGUMENT_MISSING, argv[i-1]);
967 sprintf (buffer, "-%c%s", sOpt, rest);
968 _addToList (preArgv, buffer);
973 if (!port->parseOption (&argc, argv, &i))
974 werror (W_UNKNOWN_OPTION, argv[i]);
979 if (!port->parseOption (&argc, argv, &i))
981 /* no option must be a filename */
983 _processC1Arg (argv[i]);
985 processFile (argv[i]);
989 /* set up external stack location if not explicitly specified */
990 if (!options.xstack_loc)
991 options.xstack_loc = options.xdata_loc;
993 /* if debug option is set the open the cdbFile */
994 if (options.debug && srcFileName)
996 sprintf (scratchFileName, "%s.cdb", srcFileName);
997 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
998 werror (E_FILE_OPEN_ERR, scratchFileName);
1001 /* add a module record */
1002 fprintf (cdbFile, "M:%s\n", moduleName);
1008 /*-----------------------------------------------------------------*/
1009 /* linkEdit : - calls the linkage editor with options */
1010 /*-----------------------------------------------------------------*/
1012 linkEdit (char **envp)
1019 srcFileName = "temp";
1021 /* first we need to create the <filename>.lnk file */
1022 sprintf (scratchFileName, "%s.lnk", srcFileName);
1023 if (!(lnkfile = fopen (scratchFileName, "w")))
1025 werror (E_FILE_OPEN_ERR, scratchFileName);
1029 /* now write the options */
1030 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1032 /* if iram size specified */
1033 if (options.iram_size)
1034 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1037 fprintf (lnkfile, "-z\n");
1039 #define WRITE_SEG_LOC(N, L) \
1040 segName = strdup(N); \
1041 c = strtok(segName, " \t"); \
1042 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1043 if (segName) { free(segName); }
1045 /* code segment start */
1046 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1048 /* data segment start */
1049 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1052 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1055 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1057 /* bit segment start */
1058 WRITE_SEG_LOC (BIT_NAME, 0);
1060 /* add the extra linker options */
1061 for (i = 0; linkOptions[i]; i++)
1062 fprintf (lnkfile, "%s\n", linkOptions[i]);
1064 /* other library paths if specified */
1065 for (i = 0; i < nlibPaths; i++)
1066 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1068 /* standard library path */
1069 if (!options.nostdlib)
1071 if (TARGET_IS_DS390)
1077 switch (options.model)
1089 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1094 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1096 /* standard library files */
1097 if (strcmp (port->target, "ds390") == 0)
1099 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1101 fprintf (lnkfile, "-l %s\n", STD_LIB);
1102 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1103 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1104 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1107 /* additional libraries if any */
1108 for (i = 0; i < nlibFiles; i++)
1109 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1111 /* put in the object files */
1112 if (strcmp (srcFileName, "temp"))
1113 fprintf (lnkfile, "%s ", srcFileName);
1115 for (i = 0; i < nrelFiles; i++)
1116 fprintf (lnkfile, "%s\n", relFiles[i]);
1118 fprintf (lnkfile, "\n-e\n");
1121 if (options.verbose)
1122 printf ("sdcc: Calling linker...\n");
1124 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1125 if (my_system (buffer))
1130 if (strcmp (srcFileName, "temp") == 0)
1132 /* rename "temp.cdb" to "firstRelFile.cdb" */
1133 char *f = strtok (strdup (relFiles[0]), ".");
1134 f = strcat (f, ".cdb");
1135 rename ("temp.cdb", f);
1140 /*-----------------------------------------------------------------*/
1141 /* assemble - spawns the assembler with arguments */
1142 /*-----------------------------------------------------------------*/
1144 assemble (char **envp)
1146 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1147 if (my_system (buffer))
1149 /* either system() or the assembler itself has reported an error
1150 perror ("Cannot exec assembler");
1158 /*-----------------------------------------------------------------*/
1159 /* preProcess - spawns the preprocessor with arguments */
1160 /*-----------------------------------------------------------------*/
1162 preProcess (char **envp)
1168 if (!options.c1mode)
1170 /* if using external stack define the macro */
1171 if (options.useXstack)
1172 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1174 /* set the macro for stack autos */
1175 if (options.stackAuto)
1176 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1178 /* set the macro for stack autos */
1179 if (options.stack10bit)
1180 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1182 /* set the macro for large model */
1183 switch (options.model)
1186 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1189 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1192 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1195 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1198 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1201 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1205 /* standard include path */
1206 if (!options.nostdinc) {
1207 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1210 /* add port (processor information to processor */
1211 sprintf (procDef, "-DSDCC_%s", port->target);
1212 _addToList (preArgv, procDef);
1213 sprintf (procDef, "-D__%s", port->target);
1214 _addToList (preArgv, procDef);
1217 preOutName = strdup (tmpnam (NULL));
1219 if (options.verbose)
1220 printf ("sdcc: Calling preprocessor...\n");
1222 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1223 preOutName, srcFileName, preArgv);
1224 if (my_system (buffer))
1226 // @FIX: Dario Vecchio 03-05-2001
1229 unlink (preOutName);
1243 preOutName = fullSrcFileName;
1246 yyin = fopen (preOutName, "r");
1249 perror ("Preproc file not found\n");
1257 _findPort (int argc, char **argv)
1263 if (!strncmp (*argv, "-m", 2))
1265 _setPort (*argv + 2);
1270 /* Use the first in the list */
1276 * initialises and calls the parser
1280 main (int argc, char **argv, char **envp)
1282 /* turn all optimizations off by default */
1283 memset (&optimize, 0, sizeof (struct optimize));
1285 /*printVersionInfo (); */
1288 fprintf (stderr, "Build error: no ports are enabled.\n");
1292 _findPort (argc, argv);
1293 /* Initalise the port. */
1297 // Create a default exe search path from the path to the sdcc command
1301 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1303 strcpy (DefaultExePath, argv[0]);
1304 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1305 ExePathList[0] = DefaultExePath;
1309 setDefaultOptions ();
1310 parseCmdLine (argc, argv);
1314 port->finaliseOptions ();
1316 /* if no input then printUsage & exit */
1317 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1318 (options.c1mode && !srcFileName && !options.out_name))
1333 if (options.verbose)
1334 printf ("sdcc: Generating code...\n");
1340 if (TARGET_IS_PIC) {
1341 /* TSD PIC port hack - if the PIC port option is enabled
1342 and SDCC is used to generate PIC code, then we will
1343 generate .asm files in gpasm's format instead of SDCC's
1346 #if !OPT_DISABLE_PIC
1355 // @FIX: Dario Vecchio 03-05-2001
1358 if (yyin && yyin != stdin)
1360 unlink (preOutName);
1366 if (!options.c1mode && !noAssemble)
1368 if (options.verbose)
1369 printf ("sdcc: Calling assembler...\n");
1375 // @FIX: Dario Vecchio 03-05-2001
1378 if (yyin && yyin != stdin)
1380 unlink (preOutName);
1394 if (!options.cc_only &&
1398 (srcFileName || nrelFiles))
1400 if (port->linker.do_link)
1401 port->linker.do_link ();
1406 if (yyin && yyin != stdin)
1409 if (preOutName && !options.c1mode)
1411 unlink (preOutName);