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 { 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, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }
204 /** Table of all unsupported options and help text to display when one
208 /** shortOpt as in OPTIONS. */
210 /** longOpt as in OPTIONS. */
212 /** Message to display inside W_UNSUPPORTED_OPT when this option
217 static const UNSUPPORTEDOPT
218 unsupportedOptTable[] = {
219 { 'a', NULL, "use --stack-auto instead." },
220 { 'g', NULL, "use --generic instead" },
221 { 'X', NULL, "use --xstack-loc instead" },
222 { 'x', NULL, "use --xstack instead" },
223 { 'p', NULL, "use --stack-loc instead" },
224 { 'P', NULL, "use --stack-loc instead" },
225 { 'i', NULL, "use --idata-loc instead" },
226 { 'r', NULL, "use --xdata-loc instead" },
227 { 's', NULL, "use --code-loc instead" },
228 { 'Y', NULL, "use -I instead" }
231 static const char *_preCmd[] =
233 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
234 "$l", "$1", "$2", NULL
239 static PORT *_ports[] =
241 #if !OPT_DISABLE_MCS51
244 #if !OPT_DISABLE_GBZ80
253 #if !OPT_DISABLE_DS390
259 #if !OPT_DISABLE_I186
262 #if !OPT_DISABLE_TLCS900H
267 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
270 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
272 extern void picglue ();
274 /** Sets the port to the one given by the command line option.
275 @param The name minus the option (eg 'mcs51')
276 @return 0 on success.
279 _setPort (const char *name)
282 for (i = 0; i < NUM_PORTS; i++)
284 if (!strcmp (_ports[i]->target, name))
290 /* Error - didnt find */
291 werror (E_UNKNOWN_TARGET, name);
296 _validatePorts (void)
299 for (i = 0; i < NUM_PORTS; i++)
301 if (_ports[i]->magic != PORT_MAGIC)
303 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
308 /*-----------------------------------------------------------------*/
309 /* printVersionInfo - prints the version info */
310 /*-----------------------------------------------------------------*/
318 for (i = 0; i < NUM_PORTS; i++)
319 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
321 fprintf (stderr, " %s"
322 #ifdef SDCC_SUB_VERSION_STR
323 "/" SDCC_SUB_VERSION_STR
331 #if defined(_MSC_VER)
344 "\t-m<proc> - Target processor <proc>. Default %s\n"
345 "\t Try --version for supported values of <proc>\n"
346 "\t--model-large - Large Model\n"
347 "\t--model-small - Small Model (default)\n"
348 "\t--stack-auto - Stack automatic variables\n"
349 "\t--xstack - Use external stack\n"
350 "\t--xram-loc <nnnn> - External Ram start location\n"
351 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
352 "\t--code-loc <nnnn> - Code Segment Location\n"
353 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
354 "\t--data-loc <nnnn> - Direct data start location\n"
355 "\t--idata-loc <nnnn> - Indirect data start location\n"
356 "\t--iram-size <nnnn> - Internal Ram size\n"
357 "\t--nojtbound - Don't generate boundary check for jump tables\n"
358 "\t--generic - All unqualified ptrs converted to '_generic'\n"
359 "PreProcessor Options :-\n"
360 "\t-Dmacro - Define Macro\n"
361 "\t-Ipath - Include \"*.h\" path\n"
362 "Note: this is NOT a complete list of options see docs for details\n",
364 /*-----------------------------------------------------------------*/
365 /* printUsage - prints command line syntax */
366 /*-----------------------------------------------------------------*/
373 "Usage : sdcc [options] filename\n"
377 for (i = 0; i < LENGTH(optionsTable); i++) {
378 fprintf(stdout, " %c%c %-20s %s\n",
379 optionsTable[i].shortOpt !=0 ? '-' : ' ',
380 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
381 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
382 optionsTable[i].help != NULL ? optionsTable[i].help : ""
388 /*-----------------------------------------------------------------*/
389 /* parseWithComma - separates string with comma */
390 /*-----------------------------------------------------------------*/
392 parseWithComma (char **dest, char *src)
396 strtok (src, "\n \t");
397 /* skip the initial white spaces */
398 while (isspace (*src))
415 /*-----------------------------------------------------------------*/
416 /* setDefaultOptions - sets the default options */
417 /*-----------------------------------------------------------------*/
423 for (i = 0; i < 128; i++)
424 preArgv[i] = asmOptions[i] =
425 linkOptions[i] = relFiles[i] = libFiles[i] =
428 /* first the options part */
429 options.stack_loc = 0; /* stack pointer initialised to 0 */
430 options.xstack_loc = 0; /* xternal stack starts at 0 */
431 options.code_loc = 0; /* code starts at 0 */
432 options.data_loc = 0x0030; /* data starts at 0x0030 */
433 options.xdata_loc = 0;
434 options.idata_loc = 0x80;
435 options.genericPtr = 1; /* default on */
437 options.model = port->general.default_model;
438 options.nostdlib = 0;
439 options.nostdinc = 0;
441 options.shortis8bits = 1;
443 options.stack10bit=0;
445 /* now for the optimizations */
446 /* turn on the everything */
447 optimize.global_cse = 1;
452 optimize.loopInvariant = 1;
453 optimize.loopInduction = 1;
455 /* now for the ports */
456 port->setDefaultOptions ();
459 /*-----------------------------------------------------------------*/
460 /* processFile - determines the type of file from the extension */
461 /*-----------------------------------------------------------------*/
463 processFile (char *s)
467 /* get the file extension */
468 fext = s + strlen (s);
469 while ((fext != s) && *fext != '.')
472 /* now if no '.' then we don't know what the file type is
473 so give a warning and return */
476 werror (W_UNKNOWN_FEXT, s);
480 /* otherwise depending on the file type */
481 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
483 /* source file name : not if we already have a
487 werror (W_TOO_MANY_SRC, s);
491 /* the only source file */
492 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
494 werror (E_FILE_OPEN_ERR, s);
498 /* copy the file name into the buffer */
501 /* get rid of the "." */
502 strtok (buffer, ".");
503 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
504 strcpy (srcFileName, buffer);
506 /* get rid of any path information
507 for the module name; do this by going
508 backwards till we get to either '/' or '\' or ':'
509 or start of buffer */
510 fext = buffer + strlen (buffer);
511 while (fext != buffer &&
512 *(fext - 1) != '\\' &&
513 *(fext - 1) != '/' &&
516 moduleName = Safe_calloc (1, strlen (fext) + 1);
517 strcpy (moduleName, fext);
522 /* if the extention is type .rel or .r or .REL or .R
523 addtional object file will be passed to the linker */
524 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
525 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
526 strcmp (fext, port->linker.rel_ext) == 0)
528 relFiles[nrelFiles++] = s;
532 /* if .lib or .LIB */
533 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
535 libFiles[nlibFiles++] = s;
539 werror (W_UNKNOWN_FEXT, s);
544 _processC1Arg (char *s)
548 if (options.out_name)
550 werror (W_TOO_MANY_SRC, s);
553 options.out_name = strdup (s);
562 _addToList (const char **list, const char *str)
564 /* This is the bad way to do things :) */
567 *list = strdup (str);
570 werror (E_OUT_OF_MEM, __FILE__, 0);
577 _setModel (int model, const char *sz)
579 if (port->general.supported_models & model)
580 options.model = model;
582 werror (W_UNSUPPORTED_MODEL, sz, port->target);
585 /** Gets the string argument to this option. If the option is '--opt'
586 then for input of '--optxyz' or '--opt xyz' returns xyz.
589 getStringArg(const char *szStart, char **argv, int *pi)
591 if (argv[*pi][strlen(szStart)]) {
592 return &argv[*pi][strlen(szStart)];
595 return argv[++(*pi)];
599 /** Gets the integer argument to this option using the same rules as
603 getIntArg(const char *szStart, char **argv, int *pi)
605 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi)));
609 tryHandleUnsupportedOpt(char **argv, int *pi)
611 if (argv[*pi][0] == '-')
613 const char *longOpt = "";
617 if (argv[*pi][1] == '-')
624 shortOpt = argv[*pi][1];
626 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
628 if (unsupportedOptTable[i].shortOpt == shortOpt ||
629 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
630 // Found an unsupported opt.
632 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
633 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
637 // Didn't find in the table
642 // Not an option, so can't be unsupported :)
648 tryHandleSimpleOpt(char **argv, int *pi)
650 if (argv[*pi][0] == '-')
652 const char *longOpt = "";
656 if (argv[*pi][1] == '-')
663 shortOpt = argv[*pi][1];
666 for (i = 0; i < LENGTH(optionsTable); i++)
668 if (optionsTable[i].shortOpt == shortOpt ||
669 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
671 // If it is a flag then we can handle it here
672 if (optionsTable[i].pparameter != NULL)
674 (*optionsTable[i].pparameter)++;
678 // Not a flag. Handled manually later.
683 // Didn't find in the table
688 // Not an option, so can't be handled.
693 /*-----------------------------------------------------------------*/
694 /* parseCmdLine - parses the command line and sets the options */
695 /*-----------------------------------------------------------------*/
697 parseCmdLine (int argc, char **argv)
701 /* go thru all whole command line */
702 for (i = 1; i < argc; i++)
707 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
712 if (tryHandleSimpleOpt(argv, &i) == TRUE)
718 if (argv[i][0] == '-' && argv[i][1] == '-')
720 if (strcmp (argv[i], OPTION_HELP) == 0)
726 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
728 options.stack10bit = 0;
732 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
738 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
740 _setModel (MODEL_LARGE, argv[i]);
744 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
746 _setModel (MODEL_MEDIUM, argv[i]);
750 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
752 _setModel (MODEL_SMALL, argv[i]);
756 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
758 _setModel (MODEL_FLAT24, argv[i]);
762 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
764 options.dump_rassgn =
770 options.dump_raw = 1;
774 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
776 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i);
780 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
782 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i);
786 if (strcmp (argv[i], OPTION_VERSION) == 0)
793 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
795 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i));
799 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
801 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i);
805 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
807 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i);
811 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
813 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i);
817 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
819 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i);
823 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
825 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i);
829 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
831 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i);
835 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
837 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i);
841 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
843 optimize.global_cse = 0;
847 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
849 optimize.loopInvariant = 0;
853 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
855 optimize.loopInduction = 0;
859 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
861 setErrorLogLevel(ERROR_LEVEL_WARNING);
865 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0) {
866 options.shortis8bits=1;
870 if (!port->parseOption (&argc, argv, &i))
872 werror (W_UNKNOWN_OPTION, argv[i]);
880 /* if preceded by '-' then option */
891 /* Used to select the port */
892 _setPort (argv[i] + 2);
900 libPaths[nlibPaths++] = getStringArg("-L", argv, &i);
905 if (argv[i][2] == 'l')
907 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i));
911 /* assembler options */
912 if (argv[i][2] == 'a')
914 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i));
918 werror (W_UNKNOWN_OPTION, argv[i]);
928 /* preprocessor options */
932 _addToList (preArgv, "-M");
937 _addToList (preArgv, "-C");
946 char sOpt = argv[i][1];
949 if (argv[i][2] == ' ' || argv[i][2] == '\0')
955 werror(E_ARGUMENT_MISSING, argv[i-1]);
969 sprintf (buffer, "-%c%s", sOpt, rest);
970 _addToList (preArgv, buffer);
975 if (!port->parseOption (&argc, argv, &i))
976 werror (W_UNKNOWN_OPTION, argv[i]);
981 if (!port->parseOption (&argc, argv, &i))
983 /* no option must be a filename */
985 _processC1Arg (argv[i]);
987 processFile (argv[i]);
991 /* set up external stack location if not explicitly specified */
992 if (!options.xstack_loc)
993 options.xstack_loc = options.xdata_loc;
995 /* if debug option is set the open the cdbFile */
996 if (!options.nodebug && srcFileName)
998 sprintf (scratchFileName, "%s.cdb", srcFileName);
999 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
1000 werror (E_FILE_OPEN_ERR, scratchFileName);
1003 /* add a module record */
1004 fprintf (cdbFile, "M:%s\n", moduleName);
1010 /*-----------------------------------------------------------------*/
1011 /* linkEdit : - calls the linkage editor with options */
1012 /*-----------------------------------------------------------------*/
1014 linkEdit (char **envp)
1021 srcFileName = "temp";
1023 /* first we need to create the <filename>.lnk file */
1024 sprintf (scratchFileName, "%s.lnk", srcFileName);
1025 if (!(lnkfile = fopen (scratchFileName, "w")))
1027 werror (E_FILE_OPEN_ERR, scratchFileName);
1031 /* now write the options */
1032 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1034 /* if iram size specified */
1035 if (options.iram_size)
1036 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1038 /*if (options.debug) */
1039 fprintf (lnkfile, "-z\n");
1041 #define WRITE_SEG_LOC(N, L) \
1042 segName = strdup(N); \
1043 c = strtok(segName, " \t"); \
1044 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1045 if (segName) { free(segName); }
1047 /* code segment start */
1048 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1050 /* data segment start */
1051 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1054 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1057 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1059 /* bit segment start */
1060 WRITE_SEG_LOC (BIT_NAME, 0);
1062 /* add the extra linker options */
1063 for (i = 0; linkOptions[i]; i++)
1064 fprintf (lnkfile, "%s\n", linkOptions[i]);
1066 /* other library paths if specified */
1067 for (i = 0; i < nlibPaths; i++)
1068 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1070 /* standard library path */
1071 if (!options.nostdlib)
1073 if (TARGET_IS_DS390)
1079 switch (options.model)
1091 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1096 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1098 /* standard library files */
1099 if (strcmp (port->target, "ds390") == 0)
1101 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1103 fprintf (lnkfile, "-l %s\n", STD_LIB);
1104 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1105 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1106 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1109 /* additional libraries if any */
1110 for (i = 0; i < nlibFiles; i++)
1111 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1113 /* put in the object files */
1114 if (strcmp (srcFileName, "temp"))
1115 fprintf (lnkfile, "%s ", srcFileName);
1117 for (i = 0; i < nrelFiles; i++)
1118 fprintf (lnkfile, "%s\n", relFiles[i]);
1120 fprintf (lnkfile, "\n-e\n");
1123 if (options.verbose)
1124 printf ("sdcc: Calling linker...\n");
1126 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1127 if (my_system (buffer))
1132 if (strcmp (srcFileName, "temp") == 0)
1134 /* rename "temp.cdb" to "firstRelFile.cdb" */
1135 char *f = strtok (strdup (relFiles[0]), ".");
1136 f = strcat (f, ".cdb");
1137 rename ("temp.cdb", f);
1142 /*-----------------------------------------------------------------*/
1143 /* assemble - spawns the assembler with arguments */
1144 /*-----------------------------------------------------------------*/
1146 assemble (char **envp)
1148 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1149 if (my_system (buffer))
1151 /* either system() or the assembler itself has reported an error
1152 perror ("Cannot exec assembler");
1160 /*-----------------------------------------------------------------*/
1161 /* preProcess - spawns the preprocessor with arguments */
1162 /*-----------------------------------------------------------------*/
1164 preProcess (char **envp)
1170 if (!options.c1mode)
1172 /* if using external stack define the macro */
1173 if (options.useXstack)
1174 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1176 /* set the macro for stack autos */
1177 if (options.stackAuto)
1178 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1180 /* set the macro for stack autos */
1181 if (options.stack10bit)
1182 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1184 /* set the macro for large model */
1185 switch (options.model)
1188 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1191 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1194 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1197 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1200 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1203 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1207 /* standard include path */
1208 if (!options.nostdinc) {
1209 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1212 /* add port (processor information to processor */
1213 sprintf (procDef, "-DSDCC_%s", port->target);
1214 _addToList (preArgv, procDef);
1215 sprintf (procDef, "-D__%s", port->target);
1216 _addToList (preArgv, procDef);
1219 preOutName = strdup (tmpnam (NULL));
1221 if (options.verbose)
1222 printf ("sdcc: Calling preprocessor...\n");
1224 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1225 preOutName, srcFileName, preArgv);
1226 if (my_system (buffer))
1228 // @FIX: Dario Vecchio 03-05-2001
1231 unlink (preOutName);
1245 preOutName = fullSrcFileName;
1248 yyin = fopen (preOutName, "r");
1251 perror ("Preproc file not found\n");
1259 _findPort (int argc, char **argv)
1265 if (!strncmp (*argv, "-m", 2))
1267 _setPort (*argv + 2);
1272 /* Use the first in the list */
1278 * initialises and calls the parser
1282 main (int argc, char **argv, char **envp)
1284 /* turn all optimizations off by default */
1285 memset (&optimize, 0, sizeof (struct optimize));
1287 /*printVersionInfo (); */
1290 fprintf (stderr, "Build error: no ports are enabled.\n");
1294 _findPort (argc, argv);
1295 /* Initalise the port. */
1299 // Create a default exe search path from the path to the sdcc command
1303 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1305 strcpy (DefaultExePath, argv[0]);
1306 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1307 ExePathList[0] = DefaultExePath;
1311 setDefaultOptions ();
1312 parseCmdLine (argc, argv);
1316 port->finaliseOptions ();
1318 /* if no input then printUsage & exit */
1319 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1320 (options.c1mode && !srcFileName && !options.out_name))
1335 if (options.verbose)
1336 printf ("sdcc: Generating code...\n");
1342 if (TARGET_IS_PIC) {
1343 /* TSD PIC port hack - if the PIC port option is enabled
1344 and SDCC is used to generate PIC code, then we will
1345 generate .asm files in gpasm's format instead of SDCC's
1348 #if !OPT_DISABLE_PIC
1357 // @FIX: Dario Vecchio 03-05-2001
1360 if (yyin && yyin != stdin)
1362 unlink (preOutName);
1368 if (!options.c1mode)
1370 if (options.verbose)
1371 printf ("sdcc: Calling assembler...\n");
1377 // @FIX: Dario Vecchio 03-05-2001
1380 if (yyin && yyin != stdin)
1382 unlink (preOutName);
1396 if (!options.cc_only &&
1400 (srcFileName || nrelFiles))
1402 if (port->linker.do_link)
1403 port->linker.do_link ();
1408 if (yyin && yyin != stdin)
1411 if (preOutName && !options.c1mode)
1413 unlink (preOutName);