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
366 #if defined(_MSC_VER)
378 /*-----------------------------------------------------------------*/
379 /* printUsage - prints command line syntax */
380 /*-----------------------------------------------------------------*/
386 "Usage : [options] filename\n"
388 "\t-m<proc> - Target processor <proc>. Default %s\n"
389 "\t Try --version for supported values of <proc>\n"
390 "\t--model-large - Large Model\n"
391 "\t--model-small - Small Model (default)\n"
392 "\t--stack-auto - Stack automatic variables\n"
393 "\t--xstack - Use external stack\n"
394 "\t--xram-loc <nnnn> - External Ram start location\n"
395 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
396 "\t--code-loc <nnnn> - Code Segment Location\n"
397 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
398 "\t--data-loc <nnnn> - Direct data start location\n"
399 "\t--idata-loc <nnnn> - Indirect data start location\n"
400 "\t--iram-size <nnnn> - Internal Ram size\n"
401 "\t--nojtbound - Don't generate boundary check for jump tables\n"
402 "\t--generic - All unqualified ptrs converted to '_generic'\n"
403 "PreProcessor Options :-\n"
404 "\t-Dmacro - Define Macro\n"
405 "\t-Ipath - Include \"*.h\" path\n"
406 "Note: this is NOT a complete list of options see docs for details\n",
412 /*-----------------------------------------------------------------*/
413 /* parseWithComma - separates string with comma */
414 /*-----------------------------------------------------------------*/
416 parseWithComma (char **dest, char *src)
420 strtok (src, "\n \t");
421 /* skip the initial white spaces */
422 while (isspace (*src))
439 /*-----------------------------------------------------------------*/
440 /* setDefaultOptions - sets the default options */
441 /*-----------------------------------------------------------------*/
447 for (i = 0; i < 128; i++)
448 preArgv[i] = asmOptions[i] =
449 linkOptions[i] = relFiles[i] = libFiles[i] =
452 /* first the options part */
453 options.stack_loc = 0; /* stack pointer initialised to 0 */
454 options.xstack_loc = 0; /* xternal stack starts at 0 */
455 options.code_loc = 0; /* code starts at 0 */
456 options.data_loc = 0x0030; /* data starts at 0x0030 */
457 options.xdata_loc = 0;
458 options.idata_loc = 0x80;
459 options.genericPtr = 1; /* default on */
461 options.model = port->general.default_model;
462 options.nostdlib = 0;
463 options.nostdinc = 0;
466 /* now for the optimizations */
467 /* turn on the everything */
468 optimize.global_cse = 1;
473 optimize.loopInvariant = 1;
474 optimize.loopInduction = 1;
476 port->setDefaultOptions ();
479 /*-----------------------------------------------------------------*/
480 /* processFile - determines the type of file from the extension */
481 /*-----------------------------------------------------------------*/
483 processFile (char *s)
487 /* get the file extension */
488 fext = s + strlen (s);
489 while ((fext != s) && *fext != '.')
492 /* now if no '.' then we don't know what the file type is
493 so give a warning and return */
496 werror (W_UNKNOWN_FEXT, s);
500 /* otherwise depending on the file type */
501 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
503 /* source file name : not if we already have a
507 werror (W_TOO_MANY_SRC, s);
511 /* the only source file */
512 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
514 werror (E_FILE_OPEN_ERR, s);
518 /* copy the file name into the buffer */
521 /* get rid of the "." */
522 strtok (buffer, ".");
523 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
524 strcpy (srcFileName, buffer);
526 /* get rid of any path information
527 for the module name; do this by going
528 backwards till we get to either '/' or '\' or ':'
529 or start of buffer */
530 fext = buffer + strlen (buffer);
531 while (fext != buffer &&
532 *(fext - 1) != '\\' &&
533 *(fext - 1) != '/' &&
536 moduleName = Safe_calloc (1, strlen (fext) + 1);
537 strcpy (moduleName, fext);
542 /* if the extention is type .rel or .r or .REL or .R
543 addtional object file will be passed to the linker */
544 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
545 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
546 strcmp (fext, port->linker.rel_ext) == 0)
548 relFiles[nrelFiles++] = s;
552 /* if .lib or .LIB */
553 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
555 libFiles[nlibFiles++] = s;
559 werror (W_UNKNOWN_FEXT, s);
564 _processC1Arg (char *s)
568 if (options.out_name)
570 werror (W_TOO_MANY_SRC, s);
573 options.out_name = strdup (s);
582 _addToList (const char **list, const char *str)
584 /* This is the bad way to do things :) */
587 *list = strdup (str);
590 werror (E_OUT_OF_MEM, __FILE__, 0);
597 _setModel (int model, const char *sz)
599 if (port->general.supported_models & model)
600 options.model = model;
602 werror (W_UNSUPPORTED_MODEL, sz, port->target);
605 /*-----------------------------------------------------------------*/
606 /* parseCmdLine - parses the command line and sets the options */
607 /*-----------------------------------------------------------------*/
609 parseCmdLine (int argc, char **argv)
614 /* go thru all whole command line */
615 for (i = 1; i < argc; i++)
621 if (argv[i][0] == '-' && argv[i][1] == '-')
624 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
630 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
632 options.regExtend = 1;
636 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
638 _setModel (MODEL_LARGE, argv[i]);
642 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
644 _setModel (MODEL_MEDIUM, argv[i]);
648 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
650 _setModel (MODEL_SMALL, argv[i]);
654 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
656 _setModel (MODEL_FLAT24, argv[i]);
660 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
662 options.stack10bit = 1;
666 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
668 options.stackAuto = 1;
672 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
674 options.dump_raw = 1;
678 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
680 options.cyclomatic = 1;
684 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
686 options.dump_gcse = 1;
690 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
692 options.dump_loop = 1;
696 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
698 options.dump_kill = 1;
702 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
704 options.intlong_rent = 1;
708 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
710 options.float_rent = 1;
714 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
716 options.dump_range = 1;
720 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
722 options.dump_pack = 1;
726 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
728 options.dump_rassgn = 1;
732 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
738 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
744 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
746 options.noOverlay = 1;
750 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
752 options.stackOnData = 1;
756 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
762 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
769 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
771 options.dump_rassgn =
777 options.dump_raw = 1;
781 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
787 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
789 options.genericPtr = 1;
793 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
799 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
805 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
811 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
817 if (strcmp (&argv[i][1], OPTION_NOREGPARMS) == 0)
819 options.noregparms = 1;
823 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
825 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
827 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
829 options.peep_file = argv[++i];
833 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
835 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
836 libPaths[nlibPaths++] =
837 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
839 libPaths[nlibPaths++] = argv[++i];
843 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
846 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
848 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
851 (int) floatFromVal (constVal (argv[++i]));
855 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
857 options.useXstack = 1;
861 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
863 options.mainreturn = 1;
867 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
869 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
870 parseWithComma (options.calleeSaves
871 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
873 parseWithComma (options.calleeSaves, argv[++i]);
877 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
880 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
882 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
885 (int) floatFromVal (constVal (argv[++i]));
889 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
892 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
894 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
897 (unsigned int) floatFromVal (constVal (argv[++i]));
901 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
904 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
906 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
909 (int) floatFromVal (constVal (argv[++i]));
913 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
920 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
923 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
925 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
928 (int) floatFromVal (constVal (argv[++i]));
932 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
935 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
937 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
940 (int) floatFromVal (constVal (argv[++i]));
944 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
947 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
949 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
952 (int) floatFromVal (constVal (argv[++i]));
957 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
959 optimize.noJTabBoundary = 1;
963 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
965 optimize.global_cse = 0;
969 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
971 optimize.loopInvariant = 0;
975 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
977 optimize.loopInduction = 0;
981 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
983 optimize.noLoopReverse = 1;
987 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
989 options.nostdlib = 1;
993 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
995 options.nostdinc = 1;
999 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
1001 options.verbose = 1;
1005 if (strcmp (&argv[i][1], OPTION_ANSIINT) == 0)
1007 options.ANSIint = 1;
1011 if (!port->parseOption (&argc, argv, &i))
1013 werror (W_UNKNOWN_OPTION, argv[i]);
1021 /* these are undocumented options */
1022 /* if preceded by '/' then turn off certain optmizations, used
1023 for debugging only these are also the legacy options from
1024 version 1.xx will be removed gradually.
1025 It may be an absolute filename.
1027 if (*argv[i] == '/' && strlen (argv[i]) < 3)
1033 optimize.ptrArithmetic = 0;
1043 optimize.label4 = 0;
1046 optimize.label1 = 0;
1049 optimize.label2 = 0;
1052 optimize.label3 = 0;
1055 optimize.label4 = 0;
1064 optimize.loopInvariant = 0;
1067 optimize.loopInduction = 0;
1074 optimize.global_cse = 0;
1081 /* if preceded by '-' then option */
1082 if (*argv[i] == '-')
1096 /* Used to select the port */
1097 if (_setPort (argv[i] + 2))
1099 werror (W_UNSUPP_OPTION, "-m", "Unrecognised processor");
1104 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
1108 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
1111 case 'X': /* use external stack */
1112 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
1116 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
1119 case 'p': /* stack pointer intial value */
1121 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
1125 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1129 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1133 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1137 options.cc_only = 1;
1141 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1146 libPaths[nlibPaths++] = &argv[i][2];
1148 libPaths[nlibPaths++] = argv[++i];
1152 /* linker options */
1153 if (argv[i][2] == 'l')
1156 parseWithComma (linkOptions, &argv[i][3]);
1158 parseWithComma (linkOptions, argv[++i]);
1162 /* assembler options */
1163 if (argv[i][2] == 'a')
1166 parseWithComma ((char **) asmOptions, &argv[i][3]);
1168 parseWithComma ((char **) asmOptions, argv[++i]);
1173 werror (W_UNKNOWN_OPTION, argv[i]);
1186 printVersionInfo ();
1190 /* preprocessor options */
1194 _addToList (preArgv, "-M");
1199 _addToList (preArgv, "-C");
1208 char sOpt = argv[i][1];
1211 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1219 if (argv[i][1] == 'Y')
1222 sprintf (buffer, "-%c%s", sOpt, rest);
1223 _addToList (preArgv, buffer);
1228 if (!port->parseOption (&argc, argv, &i))
1229 werror (W_UNKNOWN_OPTION, argv[i]);
1234 if (!port->parseOption (&argc, argv, &i))
1236 /* no option must be a filename */
1238 _processC1Arg (argv[i]);
1240 processFile (argv[i]);
1244 /* set up external stack location if not explicitly specified */
1245 if (!options.xstack_loc)
1246 options.xstack_loc = options.xdata_loc;
1248 /* if debug option is set the open the cdbFile */
1249 if (!options.nodebug && srcFileName)
1251 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1252 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1253 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1256 /* add a module record */
1257 fprintf (cdbFile, "M:%s\n", moduleName);
1263 /*-----------------------------------------------------------------*/
1264 /* my_system - will call a program with arguments */
1265 /*-----------------------------------------------------------------*/
1270 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1272 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1275 #ifdef USE_SYSTEM_SYSTEM_CALLS
1277 my_system (const char *cmd)
1279 int argsStart, e, i = 0;
1280 char *cmdLine = NULL;
1282 argsStart = strstr (cmd, " ") - cmd;
1284 // try to find the command in predefined path's
1287 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1288 strcpy (cmdLine, try_dir[i]); // the path
1290 strcat (cmdLine, DIR_SEPARATOR_STRING);
1291 strncat (cmdLine, cmd, argsStart); // the command
1294 strcat (cmdLine, ".exe");
1297 /* Mung slashes into backslashes to keep WIndoze happy. */
1312 if (access (cmdLine, X_OK) == 0)
1315 strcat (cmdLine, cmd + argsStart);
1325 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1330 // command found in predefined path
1331 e = system (cmdLine);
1345 my_system (const char *cmd, char **cmd_argv)
1347 char *dir, *got = NULL;
1350 while (!got && try_dir[i])
1352 dir = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1353 strcpy (dir, try_dir[i]);
1358 strcat (dir, ".exe");
1360 /* Mung slashes into backslashes to keep WIndoze happy. */
1376 if (access (dir, X_OK) == 0)
1386 char **pCmd = cmd_argv;
1390 printf ("%s ", *pCmd);
1398 i = spawnv (P_WAIT, got, cmd_argv) == -1;
1402 i = spawnvp (P_WAIT, cmd, cmd_argv) == -1;
1405 perror ("Cannot exec process ");
1413 /*-----------------------------------------------------------------*/
1414 /* linkEdit : - calls the linkage editor with options */
1415 /*-----------------------------------------------------------------*/
1417 linkEdit (char **envp)
1420 #ifndef USE_SYSTEM_SYSTEM_CALLS
1427 srcFileName = "temp";
1429 /* first we need to create the <filename>.lnk file */
1430 sprintf (buffer, "%s.lnk", srcFileName);
1431 if (!(lnkfile = fopen (buffer, "w")))
1433 werror (E_FILE_OPEN_ERR, buffer);
1437 /* now write the options */
1438 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1440 /* if iram size specified */
1441 if (options.iram_size)
1442 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1444 /*if (options.debug) */
1445 fprintf (lnkfile, "-z\n");
1447 #define WRITE_SEG_LOC(N, L) \
1448 segName = strdup(N); \
1449 c = strtok(segName, " \t"); \
1450 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1451 if (segName) { free(segName); }
1453 /* code segment start */
1454 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1456 /* data segment start */
1457 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1460 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1463 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1465 /* bit segment start */
1466 WRITE_SEG_LOC (BIT_NAME, 0);
1468 /* add the extra linker options */
1469 for (i = 0; linkOptions[i]; i++)
1470 fprintf (lnkfile, "%s\n", linkOptions[i]);
1472 /* other library paths if specified */
1473 for (i = 0; i < nlibPaths; i++)
1474 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1476 /* standard library path */
1477 if (!options.nostdlib)
1485 switch (options.model)
1497 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1502 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1504 /* standard library files */
1505 if (strcmp (port->target, "ds390") == 0)
1507 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1509 fprintf (lnkfile, "-l %s\n", STD_LIB);
1510 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1511 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1512 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1515 /* additional libraries if any */
1516 for (i = 0; i < nlibFiles; i++)
1517 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1519 /* put in the object files */
1520 if (strcmp (srcFileName, "temp"))
1521 fprintf (lnkfile, "%s ", srcFileName);
1523 for (i = 0; i < nrelFiles; i++)
1524 fprintf (lnkfile, "%s\n", relFiles[i]);
1526 fprintf (lnkfile, "\n-e\n");
1529 if (options.verbose)
1530 printf ("sdcc: Calling linker...\n");
1532 #ifdef USE_SYSTEM_SYSTEM_CALLS
1533 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1534 if (my_system (buffer))
1536 /* either system() or the linker itself has reported an error
1537 perror ("Cannot exec linker");
1542 buildCmdLine (buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1543 if (my_system (argv[0], argv))
1545 perror ("Cannot exec linker");
1551 if (strcmp (srcFileName, "temp") == 0)
1553 /* rename "temp.cdb" to "firstRelFile.cdb" */
1554 char *f = strtok (strdup (relFiles[0]), ".");
1555 f = strcat (f, ".cdb");
1556 rename ("temp.cdb", f);
1561 /*-----------------------------------------------------------------*/
1562 /* assemble - spawns the assembler with arguments */
1563 /*-----------------------------------------------------------------*/
1565 assemble (char **envp)
1567 #ifdef USE_SYSTEM_SYSTEM_CALLS
1568 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1569 if (my_system (buffer))
1571 /* either system() or the assembler itself has reported an error
1572 perror ("Cannot exec assembler");
1577 char *argv[128]; /* assembler arguments */
1579 buildCmdLine (buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1581 if (my_system (argv[0], argv))
1583 perror ("Cannot exec assembler");
1591 /*-----------------------------------------------------------------*/
1592 /* preProcess - spawns the preprocessor with arguments */
1593 /*-----------------------------------------------------------------*/
1595 preProcess (char **envp)
1597 #ifndef USE_SYSTEM_SYSTEM_CALLS
1604 if (!options.c1mode)
1606 /* if using external stack define the macro */
1607 if (options.useXstack)
1608 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1610 /* set the macro for stack autos */
1611 if (options.stackAuto)
1612 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1614 /* set the macro for stack autos */
1615 if (options.stack10bit)
1616 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1618 /* set the macro for large model */
1619 switch (options.model)
1622 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1625 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1628 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1631 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1634 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1637 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1642 /* add port (processor information to processor */
1643 sprintf (procDef, "-DSDCC_%s", port->target);
1644 _addToList (preArgv, procDef);
1647 preOutName = strdup (tmpnam (NULL));
1649 if (options.verbose)
1650 printf ("sdcc: Calling preprocessor...\n");
1652 #ifdef USE_SYSTEM_SYSTEM_CALLS
1653 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1654 preOutName, srcFileName, preArgv);
1655 if (my_system (buffer))
1657 /* either system() or the preprocessor itself has reported an error
1658 perror ("Cannot exec Preprocessor");
1663 buildCmdLine (buffer, argv, _preCmd, fullSrcFileName,
1664 preOutName, srcFileName, preArgv);
1666 if (my_system (argv[0], argv))
1668 unlink (preOutName);
1669 perror ("Cannot exec Preprocessor");
1679 preOutName = fullSrcFileName;
1682 yyin = fopen (preOutName, "r");
1685 perror ("Preproc file not found\n");
1693 _findPort (int argc, char **argv)
1700 if (!strncmp (*argv, "-m", 2))
1702 _setPort (*argv + 2);
1708 /* Use the first in the list */
1714 * initialises and calls the parser
1718 main (int argc, char **argv, char **envp)
1720 /* turn all optimizations off by default */
1721 memset (&optimize, 0, sizeof (struct optimize));
1723 /*printVersionInfo (); */
1725 _findPort (argc, argv);
1726 /* Initalise the port. */
1730 // Create a default exe search path from the path to the sdcc command
1734 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1736 strcpy (DefaultExePath, argv[0]);
1737 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1738 try_dir[0] = DefaultExePath;
1742 setDefaultOptions ();
1743 parseCmdLine (argc, argv);
1747 port->finaliseOptions ();
1749 /* if no input then printUsage & exit */
1750 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1765 if (options.verbose)
1766 printf ("sdcc: Generating code...\n");
1772 /* TSD PIC port hack - if the PIC port option is enabled
1773 and SDCC is used to generate PIC code, then we will
1774 generate .asm files in gpasm's format instead of SDCC's
1777 #if !OPT_DISABLE_PIC
1787 if (!options.c1mode)
1789 if (options.verbose)
1790 printf ("sdcc: Calling assembler...\n");
1805 if (!options.cc_only &&
1809 (srcFileName || nrelFiles))
1811 if (port->linker.do_link)
1812 port->linker.do_link ();
1817 if (yyin && yyin != stdin)
1820 if (preOutName && !options.c1mode)
1822 unlink (preOutName);