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 -------------------------------------------------------------------------*/
25 #define USE_SYSTEM_SYSTEM_CALLS
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++
45 extern int access (const char *, int);
51 extern int yyparse ();
53 FILE *srcFile; /* source file */
54 FILE *cdbFile = NULL; /* debugger information output file */
55 char *fullSrcFileName; /* full name for the source file */
56 char *srcFileName; /* source file name with the .c stripped */
57 char *moduleName; /* module name is srcFilename stripped of any path */
58 const char *preArgv[128]; /* pre-processor arguments */
60 struct optimize optimize;
61 struct options options;
62 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
63 short preProcOnly = 0;
65 char *linkOptions[128];
66 const char *asmOptions[128];
73 bool verboseExec = FALSE;
76 // In MSC VC6 default search path for exe's to path for this
78 char DefaultExePath[128];
80 /* Far functions, far data */
81 #define OPTION_LARGE_MODEL "-model-large"
82 /* Far functions, near data */
83 #define OPTION_MEDIUM_MODEL "-model-medium"
84 #define OPTION_SMALL_MODEL "-model-small"
85 #define OPTION_FLAT24_MODEL "-model-flat24"
86 #define OPTION_STACK_AUTO "-stack-auto"
87 #define OPTION_STACK_10BIT "-stack-10bit"
88 #define OPTION_XSTACK "-xstack"
89 #define OPTION_GENERIC "-generic"
90 #define OPTION_NO_GCSE "-nogcse"
91 #define OPTION_NO_LOOP_INV "-noinvariant"
92 #define OPTION_NO_LOOP_IND "-noinduction"
93 #define OPTION_NO_JTBOUND "-nojtbound"
94 #define OPTION_NO_LOOPREV "-noloopreverse"
95 #define OPTION_XREGS "-regextend"
96 #define OPTION_COMP_ONLY "-compile-only"
97 #define OPTION_DUMP_RAW "-dumpraw"
98 #define OPTION_DUMP_GCSE "-dumpgcse"
99 #define OPTION_DUMP_LOOP "-dumploop"
100 #define OPTION_DUMP_KILL "-dumpdeadcode"
101 #define OPTION_DUMP_RANGE "-dumpliverange"
102 #define OPTION_DUMP_PACK "-dumpregpack"
103 #define OPTION_DUMP_RASSGN "-dumpregassign"
104 #define OPTION_DUMP_ALL "-dumpall"
105 #define OPTION_XRAM_LOC "-xram-loc"
106 #define OPTION_IRAM_SIZE "-iram-size"
107 #define OPTION_XSTACK_LOC "-xstack-loc"
108 #define OPTION_CODE_LOC "-code-loc"
109 #define OPTION_STACK_LOC "-stack-loc"
110 #define OPTION_DATA_LOC "-data-loc"
111 #define OPTION_IDATA_LOC "-idata-loc"
112 #define OPTION_PEEP_FILE "-peep-file"
113 #define OPTION_LIB_PATH "-lib-path"
114 #define OPTION_INTLONG_RENT "-int-long-reent"
115 #define OPTION_FLOAT_RENT "-float-reent"
116 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
117 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
118 #define OPTION_CYCLOMATIC "-cyclomatic"
119 #define OPTION_NOOVERLAY "-nooverlay"
120 #define OPTION_MAINRETURN "-main-return"
121 #define OPTION_NOPEEP "-no-peep"
122 #define OPTION_ASMPEEP "-peep-asm"
123 #define OPTION_DEBUG "-debug"
124 #define OPTION_NODEBUG "-nodebug"
125 #define OPTION_VERSION "-version"
126 #define OPTION_STKAFTRDATA "-stack-after-data"
127 #define OPTION_PREPROC_ONLY "-preprocessonly"
128 #define OPTION_C1_MODE "-c1mode"
129 #define OPTION_HELP "-help"
130 #define OPTION_CALLEE_SAVES "-callee-saves"
131 #define OPTION_NOREGPARMS "-noregparms"
132 #define OPTION_NOSTDLIB "-nostdlib"
133 #define OPTION_NOSTDINC "-nostdinc"
134 #define OPTION_VERBOSE "-verbose"
135 #define OPTION_ANSIINT "-ansiint"
136 static const char *_preCmd[] =
138 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
139 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
144 static PORT *_ports[] =
146 #if !OPT_DISABLE_MCS51
149 #if !OPT_DISABLE_GBZ80
158 #if !OPT_DISABLE_DS390
164 #if !OPT_DISABLE_I186
167 #if !OPT_DISABLE_TLCS900H
172 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
175 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
177 extern void pic14glue ();
179 /** Sets the port to the one given by the command line option.
180 @param The name minus the option (eg 'mcs51')
181 @return 0 on success.
184 _setPort (const char *name)
187 for (i = 0; i < NUM_PORTS; i++)
189 if (!strcmp (_ports[i]->target, name))
195 /* Error - didnt find */
196 werror (E_UNKNOWN_TARGET, name);
201 _validatePorts (void)
204 for (i = 0; i < NUM_PORTS; i++)
206 if (_ports[i]->magic != PORT_MAGIC)
208 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
214 #ifdef USE_SYSTEM_SYSTEM_CALLS
216 buildCmdLine (char *into, const char **cmds,
217 const char *p1, const char *p2,
218 const char *p3, const char **list)
220 const char *p, *from;
230 /* See if it has a '$' anywhere - if not, just copy */
231 if ((p = strchr (from, '$')))
233 strncat (into, from, p - from);
254 const char **tmp = list;
270 strcat (into, from); // this includes the ".asm" from "$1.asm"
277 buildCmdLine (char *into, char **args, const char **cmds,
278 const char *p1, const char *p2,
279 const char *p3, const char **list)
281 const char *p, *from;
292 /* See if it has a '$' anywhere - if not, just copy */
293 if ((p = strchr (from, '$')))
295 strncpy (into, from, p - from);
296 /* NULL terminate it */
297 into[p - from] = '\0';
316 const char **tmp = list;
322 into += strlen (into) + 1;
335 if (strlen (into) == 0)
337 into += strlen (into) + 1;
343 /*-----------------------------------------------------------------*/
344 /* printVersionInfo - prints the version info */
345 /*-----------------------------------------------------------------*/
353 for (i = 0; i < NUM_PORTS; i++)
354 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
355 fprintf (stderr, " %s"
356 #ifdef SDCC_SUB_VERSION_STR
357 "/" SDCC_SUB_VERSION_STR
374 /*-----------------------------------------------------------------*/
375 /* printUsage - prints command line syntax */
376 /*-----------------------------------------------------------------*/
382 "Usage : [options] filename\n"
384 "\t-m<proc> - Target processor <proc>. Default %s\n"
385 "\t Try --version for supported values of <proc>\n"
386 "\t--model-large - Large Model\n"
387 "\t--model-small - Small Model (default)\n"
388 "\t--stack-auto - Stack automatic variables\n"
389 "\t--xstack - Use external stack\n"
390 "\t--xram-loc <nnnn> - External Ram start location\n"
391 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
392 "\t--code-loc <nnnn> - Code Segment Location\n"
393 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
394 "\t--data-loc <nnnn> - Direct data start location\n"
395 "\t--idata-loc <nnnn> - Indirect data start location\n"
396 "\t--iram-size <nnnn> - Internal Ram size\n"
397 "\t--nojtbound - Don't generate boundary check for jump tables\n"
398 "\t--generic - All unqualified ptrs converted to '_generic'\n"
399 "PreProcessor Options :-\n"
400 "\t-Dmacro - Define Macro\n"
401 "\t-Ipath - Include \"*.h\" path\n"
402 "Note: this is NOT a complete list of options see docs for details\n",
408 /*-----------------------------------------------------------------*/
409 /* parseWithComma - separates string with comma */
410 /*-----------------------------------------------------------------*/
412 parseWithComma (char **dest, char *src)
416 strtok (src, "\n \t");
417 /* skip the initial white spaces */
418 while (isspace (*src))
435 /*-----------------------------------------------------------------*/
436 /* setDefaultOptions - sets the default options */
437 /*-----------------------------------------------------------------*/
443 for (i = 0; i < 128; i++)
444 preArgv[i] = asmOptions[i] =
445 linkOptions[i] = relFiles[i] = libFiles[i] =
448 /* first the options part */
449 options.stack_loc = 0; /* stack pointer initialised to 0 */
450 options.xstack_loc = 0; /* xternal stack starts at 0 */
451 options.code_loc = 0; /* code starts at 0 */
452 options.data_loc = 0x0030; /* data starts at 0x0030 */
453 options.xdata_loc = 0;
454 options.idata_loc = 0x80;
455 options.genericPtr = 1; /* default on */
457 options.model = port->general.default_model;
458 options.nostdlib = 0;
459 options.nostdinc = 0;
462 /* now for the optimizations */
463 /* turn on the everything */
464 optimize.global_cse = 1;
469 optimize.loopInvariant = 1;
470 optimize.loopInduction = 1;
472 port->setDefaultOptions ();
475 /*-----------------------------------------------------------------*/
476 /* processFile - determines the type of file from the extension */
477 /*-----------------------------------------------------------------*/
479 processFile (char *s)
483 /* get the file extension */
484 fext = s + strlen (s);
485 while ((fext != s) && *fext != '.')
488 /* now if no '.' then we don't know what the file type is
489 so give a warning and return */
492 werror (W_UNKNOWN_FEXT, s);
496 /* otherwise depending on the file type */
497 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
499 /* source file name : not if we already have a
503 werror (W_TOO_MANY_SRC, s);
507 /* the only source file */
508 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
510 werror (E_FILE_OPEN_ERR, s);
514 /* copy the file name into the buffer */
517 /* get rid of the "." */
518 strtok (buffer, ".");
519 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
520 strcpy (srcFileName, buffer);
522 /* get rid of any path information
523 for the module name; do this by going
524 backwards till we get to either '/' or '\' or ':'
525 or start of buffer */
526 fext = buffer + strlen (buffer);
527 while (fext != buffer &&
528 *(fext - 1) != '\\' &&
529 *(fext - 1) != '/' &&
532 moduleName = Safe_calloc (1, strlen (fext) + 1);
533 strcpy (moduleName, fext);
538 /* if the extention is type .rel or .r or .REL or .R
539 addtional object file will be passed to the linker */
540 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
541 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
542 strcmp (fext, port->linker.rel_ext) == 0)
544 relFiles[nrelFiles++] = s;
548 /* if .lib or .LIB */
549 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
551 libFiles[nlibFiles++] = s;
555 werror (W_UNKNOWN_FEXT, s);
560 _processC1Arg (char *s)
564 if (options.out_name)
566 werror (W_TOO_MANY_SRC, s);
569 options.out_name = strdup (s);
578 _addToList (const char **list, const char *str)
580 /* This is the bad way to do things :) */
583 *list = strdup (str);
586 werror (E_OUT_OF_MEM, __FILE__, 0);
593 _setModel (int model, const char *sz)
595 if (port->general.supported_models & model)
596 options.model = model;
598 werror (W_UNSUPPORTED_MODEL, sz, port->target);
601 /*-----------------------------------------------------------------*/
602 /* parseCmdLine - parses the command line and sets the options */
603 /*-----------------------------------------------------------------*/
605 parseCmdLine (int argc, char **argv)
610 /* go thru all whole command line */
611 for (i = 1; i < argc; i++)
617 if (argv[i][0] == '-' && argv[i][1] == '-')
620 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
626 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
628 options.regExtend = 1;
632 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
634 _setModel (MODEL_LARGE, argv[i]);
638 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
640 _setModel (MODEL_MEDIUM, argv[i]);
644 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
646 _setModel (MODEL_SMALL, argv[i]);
650 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
652 _setModel (MODEL_FLAT24, argv[i]);
656 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
658 options.stack10bit = 1;
662 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
664 options.stackAuto = 1;
668 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
670 options.dump_raw = 1;
674 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
676 options.cyclomatic = 1;
680 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
682 options.dump_gcse = 1;
686 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
688 options.dump_loop = 1;
692 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
694 options.dump_kill = 1;
698 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
700 options.intlong_rent = 1;
704 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
706 options.float_rent = 1;
710 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
712 options.dump_range = 1;
716 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
718 options.dump_pack = 1;
722 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
724 options.dump_rassgn = 1;
728 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
734 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
740 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
742 options.noOverlay = 1;
746 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
748 options.stackOnData = 1;
752 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
758 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
765 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
767 options.dump_rassgn =
773 options.dump_raw = 1;
777 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
783 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
785 options.genericPtr = 1;
789 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
795 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
801 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
807 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
813 if (strcmp (&argv[i][1], OPTION_NOREGPARMS) == 0)
815 options.noregparms = 1;
819 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
821 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
823 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
825 options.peep_file = argv[++i];
829 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
831 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
832 libPaths[nlibPaths++] =
833 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
835 libPaths[nlibPaths++] = argv[++i];
839 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
842 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
844 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
847 (int) floatFromVal (constVal (argv[++i]));
851 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
853 options.useXstack = 1;
857 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
859 options.mainreturn = 1;
863 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
865 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
866 parseWithComma (options.calleeSaves
867 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
869 parseWithComma (options.calleeSaves, argv[++i]);
873 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
876 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
878 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
881 (int) floatFromVal (constVal (argv[++i]));
885 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
888 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
890 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
893 (unsigned int) floatFromVal (constVal (argv[++i]));
897 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
900 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
902 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
905 (int) floatFromVal (constVal (argv[++i]));
909 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
916 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
919 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
921 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
924 (int) floatFromVal (constVal (argv[++i]));
928 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
931 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
933 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
936 (int) floatFromVal (constVal (argv[++i]));
940 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
943 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
945 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
948 (int) floatFromVal (constVal (argv[++i]));
953 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
955 optimize.noJTabBoundary = 1;
959 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
961 optimize.global_cse = 0;
965 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
967 optimize.loopInvariant = 0;
971 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
973 optimize.loopInduction = 0;
977 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
979 optimize.noLoopReverse = 1;
983 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
985 options.nostdlib = 1;
989 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
991 options.nostdinc = 1;
995 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
1001 if (strcmp (&argv[i][1], OPTION_ANSIINT) == 0)
1003 options.ANSIint = 1;
1007 if (!port->parseOption (&argc, argv, &i))
1009 werror (W_UNKNOWN_OPTION, argv[i]);
1017 /* these are undocumented options */
1018 /* if preceded by '/' then turn off certain optmizations, used
1019 for debugging only these are also the legacy options from
1020 version 1.xx will be removed gradually.
1021 It may be an absolute filename.
1023 if (*argv[i] == '/' && strlen (argv[i]) < 3)
1029 optimize.ptrArithmetic = 0;
1039 optimize.label4 = 0;
1042 optimize.label1 = 0;
1045 optimize.label2 = 0;
1048 optimize.label3 = 0;
1051 optimize.label4 = 0;
1060 optimize.loopInvariant = 0;
1063 optimize.loopInduction = 0;
1070 optimize.global_cse = 0;
1077 /* if preceded by '-' then option */
1078 if (*argv[i] == '-')
1092 /* Used to select the port */
1093 if (_setPort (argv[i] + 2))
1095 werror (W_UNSUPP_OPTION, "-m", "Unrecognised processor");
1100 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
1104 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
1107 case 'X': /* use external stack */
1108 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
1112 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
1115 case 'p': /* stack pointer intial value */
1117 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
1121 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1125 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1129 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1133 options.cc_only = 1;
1137 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1142 libPaths[nlibPaths++] = &argv[i][2];
1144 libPaths[nlibPaths++] = argv[++i];
1148 /* linker options */
1149 if (argv[i][2] == 'l')
1152 parseWithComma (linkOptions, &argv[i][3]);
1154 parseWithComma (linkOptions, argv[++i]);
1158 /* assembler options */
1159 if (argv[i][2] == 'a')
1162 parseWithComma ((char **) asmOptions, &argv[i][3]);
1164 parseWithComma ((char **) asmOptions, argv[++i]);
1169 werror (W_UNKNOWN_OPTION, argv[i]);
1182 printVersionInfo ();
1186 /* preprocessor options */
1190 _addToList (preArgv, "-M");
1195 _addToList (preArgv, "-C");
1204 char sOpt = argv[i][1];
1207 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1215 if (argv[i][1] == 'Y')
1218 sprintf (buffer, "-%c%s", sOpt, rest);
1219 _addToList (preArgv, buffer);
1224 if (!port->parseOption (&argc, argv, &i))
1225 werror (W_UNKNOWN_OPTION, argv[i]);
1230 if (!port->parseOption (&argc, argv, &i))
1232 /* no option must be a filename */
1234 _processC1Arg (argv[i]);
1236 processFile (argv[i]);
1240 /* set up external stack location if not explicitly specified */
1241 if (!options.xstack_loc)
1242 options.xstack_loc = options.xdata_loc;
1244 /* if debug option is set the open the cdbFile */
1245 if (!options.nodebug && srcFileName)
1247 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1248 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1249 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1252 /* add a module record */
1253 fprintf (cdbFile, "M:%s\n", moduleName);
1259 /*-----------------------------------------------------------------*/
1260 /* my_system - will call a program with arguments */
1261 /*-----------------------------------------------------------------*/
1263 #if defined(_MSC_VER)
1266 {DefaultExePath, NULL}; // TODO : Fill in some default search list
1270 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1272 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1276 #ifdef USE_SYSTEM_SYSTEM_CALLS
1278 my_system (const char *cmd)
1280 int argsStart, e, i = 0;
1281 char *cmdLine = NULL;
1283 argsStart = strstr (cmd, " ") - cmd;
1285 // try to find the command in predefined path's
1288 cmdLine = (char *) malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1289 strcpy (cmdLine, try_dir[i]); // the path
1291 strcat (cmdLine, "/");
1292 strncat (cmdLine, cmd, argsStart); // the command
1294 strcat (cmdLine, ".exe");
1295 /* Mung slashes into backslashes to keep WIndoze happy. */
1308 if (access (cmdLine, X_OK) == 0)
1311 strcat (cmdLine, cmd + argsStart);
1321 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1326 // command found in predefined path
1327 e = system (cmdLine);
1341 my_system (const char *cmd, char **cmd_argv)
1343 char *dir, *got = NULL;
1346 while (!got && try_dir[i])
1348 dir = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1349 strcpy (dir, try_dir[i]);
1354 strcat (dir, ".exe");
1356 /* Mung slashes into backslashes to keep WIndoze happy. */
1372 if (access (dir, X_OK) == 0)
1382 char **pCmd = cmd_argv;
1386 printf ("%s ", *pCmd);
1394 i = spawnv (P_WAIT, got, cmd_argv) == -1;
1398 i = spawnvp (P_WAIT, cmd, cmd_argv) == -1;
1401 perror ("Cannot exec process ");
1409 /*-----------------------------------------------------------------*/
1410 /* linkEdit : - calls the linkage editor with options */
1411 /*-----------------------------------------------------------------*/
1413 linkEdit (char **envp)
1416 #ifndef USE_SYSTEM_SYSTEM_CALLS
1423 srcFileName = "temp";
1425 /* first we need to create the <filename>.lnk file */
1426 sprintf (buffer, "%s.lnk", srcFileName);
1427 if (!(lnkfile = fopen (buffer, "w")))
1429 werror (E_FILE_OPEN_ERR, buffer);
1433 /* now write the options */
1434 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1436 /* if iram size specified */
1437 if (options.iram_size)
1438 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1440 /*if (options.debug) */
1441 fprintf (lnkfile, "-z\n");
1443 #define WRITE_SEG_LOC(N, L) \
1444 segName = strdup(N); \
1445 c = strtok(segName, " \t"); \
1446 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1447 if (segName) { free(segName); }
1449 /* code segment start */
1450 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1452 /* data segment start */
1453 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1456 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1459 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1461 /* bit segment start */
1462 WRITE_SEG_LOC (BIT_NAME, 0);
1464 /* add the extra linker options */
1465 for (i = 0; linkOptions[i]; i++)
1466 fprintf (lnkfile, "%s\n", linkOptions[i]);
1468 /* other library paths if specified */
1469 for (i = 0; i < nlibPaths; i++)
1470 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1472 /* standard library path */
1473 if (!options.nostdlib)
1481 switch (options.model)
1493 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1498 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1500 /* standard library files */
1501 if (strcmp (port->target, "ds390") == 0)
1503 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1505 fprintf (lnkfile, "-l %s\n", STD_LIB);
1506 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1507 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1508 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1511 /* additional libraries if any */
1512 for (i = 0; i < nlibFiles; i++)
1513 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1515 /* put in the object files */
1516 if (strcmp (srcFileName, "temp"))
1517 fprintf (lnkfile, "%s ", srcFileName);
1519 for (i = 0; i < nrelFiles; i++)
1520 fprintf (lnkfile, "%s\n", relFiles[i]);
1522 fprintf (lnkfile, "\n-e\n");
1525 if (options.verbose)
1526 printf ("sdcc: Calling linker...\n");
1528 #ifdef USE_SYSTEM_SYSTEM_CALLS
1529 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1530 if (my_system (buffer))
1532 /* either system() or the linker itself has reported an error
1533 perror ("Cannot exec linker");
1538 buildCmdLine (buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1539 if (my_system (argv[0], argv))
1541 perror ("Cannot exec linker");
1547 if (strcmp (srcFileName, "temp") == 0)
1549 /* rename "temp.cdb" to "firstRelFile.cdb" */
1550 char *f = strtok (strdup (relFiles[0]), ".");
1551 f = strcat (f, ".cdb");
1552 rename ("temp.cdb", f);
1557 /*-----------------------------------------------------------------*/
1558 /* assemble - spawns the assembler with arguments */
1559 /*-----------------------------------------------------------------*/
1561 assemble (char **envp)
1563 #ifdef USE_SYSTEM_SYSTEM_CALLS
1564 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1565 if (my_system (buffer))
1567 /* either system() or the assembler itself has reported an error
1568 perror ("Cannot exec assembler");
1573 char *argv[128]; /* assembler arguments */
1575 buildCmdLine (buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1577 if (my_system (argv[0], argv))
1579 perror ("Cannot exec assembler");
1587 /*-----------------------------------------------------------------*/
1588 /* preProcess - spawns the preprocessor with arguments */
1589 /*-----------------------------------------------------------------*/
1591 preProcess (char **envp)
1593 #ifndef USE_SYSTEM_SYSTEM_CALLS
1600 if (!options.c1mode)
1602 /* if using external stack define the macro */
1603 if (options.useXstack)
1604 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1606 /* set the macro for stack autos */
1607 if (options.stackAuto)
1608 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1610 /* set the macro for stack autos */
1611 if (options.stack10bit)
1612 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1614 /* set the macro for large model */
1615 switch (options.model)
1618 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1621 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1624 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1627 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1630 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1633 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1638 /* add port (processor information to processor */
1639 sprintf (procDef, "-DSDCC_%s", port->target);
1640 _addToList (preArgv, procDef);
1643 preOutName = strdup (tmpnam (NULL));
1645 if (options.verbose)
1646 printf ("sdcc: Calling preprocessor...\n");
1648 #ifdef USE_SYSTEM_SYSTEM_CALLS
1649 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1650 preOutName, srcFileName, preArgv);
1651 if (my_system (buffer))
1653 /* either system() or the preprocessor itself has reported an error
1654 perror ("Cannot exec Preprocessor");
1659 buildCmdLine (buffer, argv, _preCmd, fullSrcFileName,
1660 preOutName, srcFileName, preArgv);
1662 if (my_system (argv[0], argv))
1664 unlink (preOutName);
1665 perror ("Cannot exec Preprocessor");
1675 preOutName = fullSrcFileName;
1678 yyin = fopen (preOutName, "r");
1681 perror ("Preproc file not found\n");
1689 _findPort (int argc, char **argv)
1696 if (!strncmp (*argv, "-m", 2))
1698 _setPort (*argv + 2);
1704 /* Use the first in the list */
1710 * initialises and calls the parser
1714 main (int argc, char **argv, char **envp)
1716 /* turn all optimizations off by default */
1717 memset (&optimize, 0, sizeof (struct optimize));
1719 /*printVersionInfo (); */
1721 _findPort (argc, argv);
1722 /* Initalise the port. */
1726 #if defined(_MSC_VER)
1731 // Create a default exe search path from the path to the sdcc command
1733 strcpy (DefaultExePath, argv[0]);
1735 for (i = strlen (DefaultExePath); i > 0; i--)
1736 if (DefaultExePath[i] == '\\')
1738 DefaultExePath[i] = '\0';
1743 DefaultExePath[0] = '\0';
1747 if (strchr(argv[0], '/'))
1749 strcpy(DefaultExePath, argv[0]);
1750 *(strrchr(DefaultExePath, '/')) = 0;
1751 try_dir[0] = DefaultExePath;
1756 setDefaultOptions ();
1757 parseCmdLine (argc, argv);
1761 port->finaliseOptions ();
1763 /* if no input then printUsage & exit */
1764 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1779 if (options.verbose)
1780 printf ("sdcc: Generating code...\n");
1786 /* TSD PIC port hack - if the PIC port option is enabled
1787 and SDCC is used to generate PIC code, then we will
1788 generate .asm files in gpasm's format instead of SDCC's
1791 #if !OPT_DISABLE_PIC
1801 if (!options.c1mode)
1803 if (options.verbose)
1804 printf ("sdcc: Calling assembler...\n");
1819 if (!options.cc_only &&
1823 (srcFileName || nrelFiles))
1825 if (port->linker.do_link)
1826 port->linker.do_link ();
1831 if (yyin && yyin != stdin)
1834 if (preOutName && !options.c1mode)
1836 unlink (preOutName);