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
80 char DefaultExePath[_MAX_PATH];
84 /* Far functions, far data */
85 #define OPTION_LARGE_MODEL "-model-large"
86 /* Far functions, near data */
87 #define OPTION_MEDIUM_MODEL "-model-medium"
88 #define OPTION_SMALL_MODEL "-model-small"
89 #define OPTION_FLAT24_MODEL "-model-flat24"
90 #define OPTION_STACK_AUTO "-stack-auto"
91 #define OPTION_STACK_10BIT "-stack-10bit"
92 #define OPTION_XSTACK "-xstack"
93 #define OPTION_GENERIC "-generic"
94 #define OPTION_NO_GCSE "-nogcse"
95 #define OPTION_NO_LOOP_INV "-noinvariant"
96 #define OPTION_NO_LOOP_IND "-noinduction"
97 #define OPTION_NO_JTBOUND "-nojtbound"
98 #define OPTION_NO_LOOPREV "-noloopreverse"
99 #define OPTION_XREGS "-regextend"
100 #define OPTION_COMP_ONLY "-compile-only"
101 #define OPTION_DUMP_RAW "-dumpraw"
102 #define OPTION_DUMP_GCSE "-dumpgcse"
103 #define OPTION_DUMP_LOOP "-dumploop"
104 #define OPTION_DUMP_KILL "-dumpdeadcode"
105 #define OPTION_DUMP_RANGE "-dumpliverange"
106 #define OPTION_DUMP_PACK "-dumpregpack"
107 #define OPTION_DUMP_RASSGN "-dumpregassign"
108 #define OPTION_DUMP_ALL "-dumpall"
109 #define OPTION_XRAM_LOC "-xram-loc"
110 #define OPTION_IRAM_SIZE "-iram-size"
111 #define OPTION_XSTACK_LOC "-xstack-loc"
112 #define OPTION_CODE_LOC "-code-loc"
113 #define OPTION_STACK_LOC "-stack-loc"
114 #define OPTION_DATA_LOC "-data-loc"
115 #define OPTION_IDATA_LOC "-idata-loc"
116 #define OPTION_PEEP_FILE "-peep-file"
117 #define OPTION_LIB_PATH "-lib-path"
118 #define OPTION_INTLONG_RENT "-int-long-reent"
119 #define OPTION_FLOAT_RENT "-float-reent"
120 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
121 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
122 #define OPTION_CYCLOMATIC "-cyclomatic"
123 #define OPTION_NOOVERLAY "-nooverlay"
124 #define OPTION_MAINRETURN "-main-return"
125 #define OPTION_NOPEEP "-no-peep"
126 #define OPTION_ASMPEEP "-peep-asm"
127 #define OPTION_DEBUG "-debug"
128 #define OPTION_NODEBUG "-nodebug"
129 #define OPTION_VERSION "-version"
130 #define OPTION_STKAFTRDATA "-stack-after-data"
131 #define OPTION_PREPROC_ONLY "-preprocessonly"
132 #define OPTION_C1_MODE "-c1mode"
133 #define OPTION_HELP "-help"
134 #define OPTION_CALLEE_SAVES "-callee-saves"
135 #define OPTION_NOREGPARMS "-noregparms"
136 #define OPTION_NOSTDLIB "-nostdlib"
137 #define OPTION_NOSTDINC "-nostdinc"
138 #define OPTION_VERBOSE "-verbose"
139 #define OPTION_ANSIINT "-ansiint"
140 static const char *_preCmd[] =
142 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
143 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
148 static PORT *_ports[] =
150 #if !OPT_DISABLE_MCS51
153 #if !OPT_DISABLE_GBZ80
162 #if !OPT_DISABLE_DS390
168 #if !OPT_DISABLE_I186
171 #if !OPT_DISABLE_TLCS900H
176 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
179 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
181 extern void pic14glue ();
183 /** Sets the port to the one given by the command line option.
184 @param The name minus the option (eg 'mcs51')
185 @return 0 on success.
188 _setPort (const char *name)
191 for (i = 0; i < NUM_PORTS; i++)
193 if (!strcmp (_ports[i]->target, name))
199 /* Error - didnt find */
200 werror (E_UNKNOWN_TARGET, name);
205 _validatePorts (void)
208 for (i = 0; i < NUM_PORTS; i++)
210 if (_ports[i]->magic != PORT_MAGIC)
212 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
218 #ifdef USE_SYSTEM_SYSTEM_CALLS
220 buildCmdLine (char *into, const char **cmds,
221 const char *p1, const char *p2,
222 const char *p3, const char **list)
224 const char *p, *from;
234 /* See if it has a '$' anywhere - if not, just copy */
235 if ((p = strchr (from, '$')))
237 strncat (into, from, p - from);
258 const char **tmp = list;
274 strcat (into, from); // this includes the ".asm" from "$1.asm"
281 buildCmdLine (char *into, char **args, const char **cmds,
282 const char *p1, const char *p2,
283 const char *p3, const char **list)
285 const char *p, *from;
296 /* See if it has a '$' anywhere - if not, just copy */
297 if ((p = strchr (from, '$')))
299 strncpy (into, from, p - from);
300 /* NULL terminate it */
301 into[p - from] = '\0';
320 const char **tmp = list;
326 into += strlen (into) + 1;
339 if (strlen (into) == 0)
341 into += strlen (into) + 1;
347 /*-----------------------------------------------------------------*/
348 /* printVersionInfo - prints the version info */
349 /*-----------------------------------------------------------------*/
357 for (i = 0; i < NUM_PORTS; i++)
358 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
359 fprintf (stderr, " %s"
360 #ifdef SDCC_SUB_VERSION_STR
361 "/" SDCC_SUB_VERSION_STR
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 /*-----------------------------------------------------------------*/
1267 #if defined(_MSC_VER)
1270 {DefaultExePath, NULL}; // TODO : Fill in some default search list
1274 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1280 #ifdef USE_SYSTEM_SYSTEM_CALLS
1282 my_system (const char *cmd)
1284 int argsStart, e, i = 0;
1285 char *cmdLine = NULL;
1287 argsStart = strstr (cmd, " ") - cmd;
1289 // try to find the command in predefined path's
1292 cmdLine = (char *) malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1293 strcpy (cmdLine, try_dir[i]); // the path
1295 strcat (cmdLine, "/");
1296 strncat (cmdLine, cmd, argsStart); // the command
1298 strcat (cmdLine, ".exe");
1299 /* 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))
1539 buildCmdLine (buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1540 if (my_system (argv[0], argv))
1542 perror ("Cannot exec linker");
1548 if (strcmp (srcFileName, "temp") == 0)
1550 /* rename "temp.cdb" to "firstRelFile.cdb" */
1551 char *f = strtok (strdup (relFiles[0]), ".");
1552 f = strcat (f, ".cdb");
1553 rename ("temp.cdb", f);
1558 /*-----------------------------------------------------------------*/
1559 /* assemble - spawns the assembler with arguments */
1560 /*-----------------------------------------------------------------*/
1562 assemble (char **envp)
1564 #ifdef USE_SYSTEM_SYSTEM_CALLS
1565 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1566 if (my_system (buffer))
1571 char *argv[128]; /* assembler arguments */
1573 buildCmdLine (buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1575 if (my_system (argv[0], argv))
1577 perror ("Cannot exec assembler");
1585 /*-----------------------------------------------------------------*/
1586 /* preProcess - spawns the preprocessor with arguments */
1587 /*-----------------------------------------------------------------*/
1589 preProcess (char **envp)
1591 #ifndef USE_SYSTEM_SYSTEM_CALLS
1598 if (!options.c1mode)
1600 /* if using external stack define the macro */
1601 if (options.useXstack)
1602 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1604 /* set the macro for stack autos */
1605 if (options.stackAuto)
1606 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1608 /* set the macro for stack autos */
1609 if (options.stack10bit)
1610 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1612 /* set the macro for large model */
1613 switch (options.model)
1616 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1619 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1622 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1625 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1628 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1631 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1636 /* add port (processor information to processor */
1637 sprintf (procDef, "-DSDCC_%s", port->target);
1638 _addToList (preArgv, procDef);
1641 preOutName = strdup (tmpnam (NULL));
1643 if (options.verbose)
1644 printf ("sdcc: Calling preprocessor...\n");
1646 #ifdef USE_SYSTEM_SYSTEM_CALLS
1647 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1648 preOutName, srcFileName, preArgv);
1649 if (my_system (buffer))
1654 buildCmdLine (buffer, argv, _preCmd, fullSrcFileName,
1655 preOutName, srcFileName, preArgv);
1657 if (my_system (argv[0], argv))
1659 unlink (preOutName);
1660 perror ("Cannot exec Preprocessor");
1670 preOutName = fullSrcFileName;
1673 yyin = fopen (preOutName, "r");
1676 perror ("Preproc file not found\n");
1684 _findPort (int argc, char **argv)
1691 if (!strncmp (*argv, "-m", 2))
1693 _setPort (*argv + 2);
1699 /* Use the first in the list */
1705 * initialises and calls the parser
1709 main (int argc, char **argv, char **envp)
1711 /* turn all optimizations off by default */
1712 memset (&optimize, 0, sizeof (struct optimize));
1714 /*printVersionInfo (); */
1716 _findPort (argc, argv);
1717 /* Initalise the port. */
1721 #if defined(_MSC_VER)
1726 // Create a default exe search path from the path to the sdcc command
1728 strcpy (DefaultExePath, argv[0]);
1730 for (i = strlen (DefaultExePath); i > 0; i--)
1731 if (DefaultExePath[i] == '\\')
1733 DefaultExePath[i] = '\0';
1738 DefaultExePath[0] = '\0';
1743 setDefaultOptions ();
1744 parseCmdLine (argc, argv);
1748 port->finaliseOptions ();
1750 /* if no input then printUsage & exit */
1751 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1766 if (options.verbose)
1767 printf ("sdcc: Generating code...\n");
1773 /* TSD PIC port hack - if the PIC port option is enabled
1774 and SDCC is used to generate PIC code, then we will
1775 generate .asm files in gpasm's format instead of SDCC's
1778 #if !OPT_DISABLE_PIC
1788 if (!options.c1mode)
1790 if (options.verbose)
1791 printf ("sdcc: Calling assembler...\n");
1806 if (!options.cc_only &&
1810 (srcFileName || nrelFiles))
1812 if (port->linker.do_link)
1813 port->linker.do_link ();
1818 if (yyin && yyin != stdin)
1821 if (preOutName && !options.c1mode)
1823 unlink (preOutName);