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))
192 if (strcmp(name,"ds390")==0) {
193 options.model=MODEL_FLAT24;
194 options.stack10bit=1;
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
370 #if defined(_MSC_VER)
382 /*-----------------------------------------------------------------*/
383 /* printUsage - prints command line syntax */
384 /*-----------------------------------------------------------------*/
390 "Usage : [options] filename\n"
392 "\t-m<proc> - Target processor <proc>. Default %s\n"
393 "\t Try --version for supported values of <proc>\n"
394 "\t--model-large - Large Model\n"
395 "\t--model-small - Small Model (default)\n"
396 "\t--stack-auto - Stack automatic variables\n"
397 "\t--xstack - Use external stack\n"
398 "\t--xram-loc <nnnn> - External Ram start location\n"
399 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
400 "\t--code-loc <nnnn> - Code Segment Location\n"
401 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
402 "\t--data-loc <nnnn> - Direct data start location\n"
403 "\t--idata-loc <nnnn> - Indirect data start location\n"
404 "\t--iram-size <nnnn> - Internal Ram size\n"
405 "\t--nojtbound - Don't generate boundary check for jump tables\n"
406 "\t--generic - All unqualified ptrs converted to '_generic'\n"
407 "PreProcessor Options :-\n"
408 "\t-Dmacro - Define Macro\n"
409 "\t-Ipath - Include \"*.h\" path\n"
410 "Note: this is NOT a complete list of options see docs for details\n",
416 /*-----------------------------------------------------------------*/
417 /* parseWithComma - separates string with comma */
418 /*-----------------------------------------------------------------*/
420 parseWithComma (char **dest, char *src)
424 strtok (src, "\n \t");
425 /* skip the initial white spaces */
426 while (isspace (*src))
443 /*-----------------------------------------------------------------*/
444 /* setDefaultOptions - sets the default options */
445 /*-----------------------------------------------------------------*/
451 for (i = 0; i < 128; i++)
452 preArgv[i] = asmOptions[i] =
453 linkOptions[i] = relFiles[i] = libFiles[i] =
456 /* first the options part */
457 options.stack_loc = 0; /* stack pointer initialised to 0 */
458 options.xstack_loc = 0; /* xternal stack starts at 0 */
459 options.code_loc = 0; /* code starts at 0 */
460 options.data_loc = 0x0030; /* data starts at 0x0030 */
461 options.xdata_loc = 0;
462 options.idata_loc = 0x80;
463 options.genericPtr = 1; /* default on */
465 options.model = port->general.default_model;
466 options.nostdlib = 0;
467 options.nostdinc = 0;
470 /* now for the optimizations */
471 /* turn on the everything */
472 optimize.global_cse = 1;
477 optimize.loopInvariant = 1;
478 optimize.loopInduction = 1;
480 port->setDefaultOptions ();
483 /*-----------------------------------------------------------------*/
484 /* processFile - determines the type of file from the extension */
485 /*-----------------------------------------------------------------*/
487 processFile (char *s)
491 /* get the file extension */
492 fext = s + strlen (s);
493 while ((fext != s) && *fext != '.')
496 /* now if no '.' then we don't know what the file type is
497 so give a warning and return */
500 werror (W_UNKNOWN_FEXT, s);
504 /* otherwise depending on the file type */
505 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
507 /* source file name : not if we already have a
511 werror (W_TOO_MANY_SRC, s);
515 /* the only source file */
516 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
518 werror (E_FILE_OPEN_ERR, s);
522 /* copy the file name into the buffer */
525 /* get rid of the "." */
526 strtok (buffer, ".");
527 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
528 strcpy (srcFileName, buffer);
530 /* get rid of any path information
531 for the module name; do this by going
532 backwards till we get to either '/' or '\' or ':'
533 or start of buffer */
534 fext = buffer + strlen (buffer);
535 while (fext != buffer &&
536 *(fext - 1) != '\\' &&
537 *(fext - 1) != '/' &&
540 moduleName = Safe_calloc (1, strlen (fext) + 1);
541 strcpy (moduleName, fext);
546 /* if the extention is type .rel or .r or .REL or .R
547 addtional object file will be passed to the linker */
548 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
549 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
550 strcmp (fext, port->linker.rel_ext) == 0)
552 relFiles[nrelFiles++] = s;
556 /* if .lib or .LIB */
557 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
559 libFiles[nlibFiles++] = s;
563 werror (W_UNKNOWN_FEXT, s);
568 _processC1Arg (char *s)
572 if (options.out_name)
574 werror (W_TOO_MANY_SRC, s);
577 options.out_name = strdup (s);
586 _addToList (const char **list, const char *str)
588 /* This is the bad way to do things :) */
591 *list = strdup (str);
594 werror (E_OUT_OF_MEM, __FILE__, 0);
601 _setModel (int model, const char *sz)
603 if (port->general.supported_models & model)
604 options.model = model;
606 werror (W_UNSUPPORTED_MODEL, sz, port->target);
609 /*-----------------------------------------------------------------*/
610 /* parseCmdLine - parses the command line and sets the options */
611 /*-----------------------------------------------------------------*/
613 parseCmdLine (int argc, char **argv)
618 /* go thru all whole command line */
619 for (i = 1; i < argc; i++)
625 if (argv[i][0] == '-' && argv[i][1] == '-')
628 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
634 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
636 options.regExtend = 1;
640 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
642 _setModel (MODEL_LARGE, argv[i]);
646 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
648 _setModel (MODEL_MEDIUM, argv[i]);
652 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
654 _setModel (MODEL_SMALL, argv[i]);
658 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
660 _setModel (MODEL_FLAT24, argv[i]);
664 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
666 options.stack10bit = 1;
670 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
672 options.stackAuto = 1;
676 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
678 options.dump_raw = 1;
682 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
684 options.cyclomatic = 1;
688 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
690 options.dump_gcse = 1;
694 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
696 options.dump_loop = 1;
700 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
702 options.dump_kill = 1;
706 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
708 options.intlong_rent = 1;
712 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
714 options.float_rent = 1;
718 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
720 options.dump_range = 1;
724 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
726 options.dump_pack = 1;
730 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
732 options.dump_rassgn = 1;
736 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
742 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
748 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
750 options.noOverlay = 1;
754 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
756 options.stackOnData = 1;
760 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
766 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
773 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
775 options.dump_rassgn =
781 options.dump_raw = 1;
785 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
791 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
793 options.genericPtr = 1;
797 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
803 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
809 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
815 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
821 if (strcmp (&argv[i][1], OPTION_NOREGPARMS) == 0)
823 options.noregparms = 1;
827 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
829 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
831 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
833 options.peep_file = argv[++i];
837 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
839 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
840 libPaths[nlibPaths++] =
841 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
843 libPaths[nlibPaths++] = argv[++i];
847 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
850 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
852 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
855 (int) floatFromVal (constVal (argv[++i]));
859 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
861 options.useXstack = 1;
865 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
867 options.mainreturn = 1;
871 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
873 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
874 parseWithComma (options.calleeSaves
875 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
877 parseWithComma (options.calleeSaves, argv[++i]);
881 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
884 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
886 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
889 (int) floatFromVal (constVal (argv[++i]));
893 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
896 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
898 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
901 (unsigned int) floatFromVal (constVal (argv[++i]));
905 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
908 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
910 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
913 (int) floatFromVal (constVal (argv[++i]));
917 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
924 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
927 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
929 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
932 (int) floatFromVal (constVal (argv[++i]));
936 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
939 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
941 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
944 (int) floatFromVal (constVal (argv[++i]));
948 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
951 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
953 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
956 (int) floatFromVal (constVal (argv[++i]));
961 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
963 optimize.noJTabBoundary = 1;
967 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
969 optimize.global_cse = 0;
973 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
975 optimize.loopInvariant = 0;
979 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
981 optimize.loopInduction = 0;
985 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
987 optimize.noLoopReverse = 1;
991 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
993 options.nostdlib = 1;
997 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
999 options.nostdinc = 1;
1003 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
1005 options.verbose = 1;
1009 if (strcmp (&argv[i][1], OPTION_ANSIINT) == 0)
1011 options.ANSIint = 1;
1015 if (!port->parseOption (&argc, argv, &i))
1017 werror (W_UNKNOWN_OPTION, argv[i]);
1025 /* these are undocumented options */
1026 /* if preceded by '/' then turn off certain optmizations, used
1027 for debugging only these are also the legacy options from
1028 version 1.xx will be removed gradually.
1029 It may be an absolute filename.
1031 if (*argv[i] == '/' && strlen (argv[i]) < 3)
1037 optimize.ptrArithmetic = 0;
1047 optimize.label4 = 0;
1050 optimize.label1 = 0;
1053 optimize.label2 = 0;
1056 optimize.label3 = 0;
1059 optimize.label4 = 0;
1068 optimize.loopInvariant = 0;
1071 optimize.loopInduction = 0;
1078 optimize.global_cse = 0;
1085 /* if preceded by '-' then option */
1086 if (*argv[i] == '-')
1100 /* Used to select the port */
1101 if (_setPort (argv[i] + 2))
1103 werror (W_UNSUPP_OPTION, "-m", "Unrecognised processor");
1108 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
1112 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
1115 case 'X': /* use external stack */
1116 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
1120 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
1123 case 'p': /* stack pointer intial value */
1125 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
1129 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1133 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1137 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1141 options.cc_only = 1;
1145 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1150 libPaths[nlibPaths++] = &argv[i][2];
1152 libPaths[nlibPaths++] = argv[++i];
1156 /* linker options */
1157 if (argv[i][2] == 'l')
1160 parseWithComma (linkOptions, &argv[i][3]);
1162 parseWithComma (linkOptions, argv[++i]);
1166 /* assembler options */
1167 if (argv[i][2] == 'a')
1170 parseWithComma ((char **) asmOptions, &argv[i][3]);
1172 parseWithComma ((char **) asmOptions, argv[++i]);
1177 werror (W_UNKNOWN_OPTION, argv[i]);
1190 printVersionInfo ();
1194 /* preprocessor options */
1198 _addToList (preArgv, "-M");
1203 _addToList (preArgv, "-C");
1212 char sOpt = argv[i][1];
1215 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1223 if (argv[i][1] == 'Y')
1226 sprintf (buffer, "-%c%s", sOpt, rest);
1227 _addToList (preArgv, buffer);
1232 if (!port->parseOption (&argc, argv, &i))
1233 werror (W_UNKNOWN_OPTION, argv[i]);
1238 if (!port->parseOption (&argc, argv, &i))
1240 /* no option must be a filename */
1242 _processC1Arg (argv[i]);
1244 processFile (argv[i]);
1248 /* set up external stack location if not explicitly specified */
1249 if (!options.xstack_loc)
1250 options.xstack_loc = options.xdata_loc;
1252 /* if debug option is set the open the cdbFile */
1253 if (!options.nodebug && srcFileName)
1255 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1256 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1257 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1260 /* add a module record */
1261 fprintf (cdbFile, "M:%s\n", moduleName);
1267 /*-----------------------------------------------------------------*/
1268 /* my_system - will call a program with arguments */
1269 /*-----------------------------------------------------------------*/
1274 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1276 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1279 #ifdef USE_SYSTEM_SYSTEM_CALLS
1281 my_system (const char *cmd)
1283 int argsStart, e, i = 0;
1284 char *cmdLine = NULL;
1286 argsStart = strstr (cmd, " ") - cmd;
1288 // try to find the command in predefined path's
1291 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1292 strcpy (cmdLine, try_dir[i]); // the path
1294 strcat (cmdLine, DIR_SEPARATOR_STRING);
1295 strncat (cmdLine, cmd, argsStart); // the command
1298 strcat (cmdLine, ".exe");
1301 /* Mung slashes into backslashes to keep WIndoze happy. */
1316 if (access (cmdLine, X_OK) == 0)
1319 strcat (cmdLine, cmd + argsStart);
1329 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1334 // command found in predefined path
1335 e = system (cmdLine);
1349 my_system (const char *cmd, char **cmd_argv)
1351 char *dir, *got = NULL;
1354 while (!got && try_dir[i])
1356 dir = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1357 strcpy (dir, try_dir[i]);
1362 strcat (dir, ".exe");
1364 /* Mung slashes into backslashes to keep WIndoze happy. */
1380 if (access (dir, X_OK) == 0)
1390 char **pCmd = cmd_argv;
1394 printf ("%s ", *pCmd);
1402 i = spawnv (P_WAIT, got, cmd_argv) == -1;
1406 i = spawnvp (P_WAIT, cmd, cmd_argv) == -1;
1409 perror ("Cannot exec process ");
1417 /*-----------------------------------------------------------------*/
1418 /* linkEdit : - calls the linkage editor with options */
1419 /*-----------------------------------------------------------------*/
1421 linkEdit (char **envp)
1424 #ifndef USE_SYSTEM_SYSTEM_CALLS
1431 srcFileName = "temp";
1433 /* first we need to create the <filename>.lnk file */
1434 sprintf (buffer, "%s.lnk", srcFileName);
1435 if (!(lnkfile = fopen (buffer, "w")))
1437 werror (E_FILE_OPEN_ERR, buffer);
1441 /* now write the options */
1442 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1444 /* if iram size specified */
1445 if (options.iram_size)
1446 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1448 /*if (options.debug) */
1449 fprintf (lnkfile, "-z\n");
1451 #define WRITE_SEG_LOC(N, L) \
1452 segName = strdup(N); \
1453 c = strtok(segName, " \t"); \
1454 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1455 if (segName) { free(segName); }
1457 /* code segment start */
1458 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1460 /* data segment start */
1461 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1464 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1467 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1469 /* bit segment start */
1470 WRITE_SEG_LOC (BIT_NAME, 0);
1472 /* add the extra linker options */
1473 for (i = 0; linkOptions[i]; i++)
1474 fprintf (lnkfile, "%s\n", linkOptions[i]);
1476 /* other library paths if specified */
1477 for (i = 0; i < nlibPaths; i++)
1478 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1480 /* standard library path */
1481 if (!options.nostdlib)
1489 switch (options.model)
1501 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1506 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1508 /* standard library files */
1509 if (strcmp (port->target, "ds390") == 0)
1511 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1513 fprintf (lnkfile, "-l %s\n", STD_LIB);
1514 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1515 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1516 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1519 /* additional libraries if any */
1520 for (i = 0; i < nlibFiles; i++)
1521 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1523 /* put in the object files */
1524 if (strcmp (srcFileName, "temp"))
1525 fprintf (lnkfile, "%s ", srcFileName);
1527 for (i = 0; i < nrelFiles; i++)
1528 fprintf (lnkfile, "%s\n", relFiles[i]);
1530 fprintf (lnkfile, "\n-e\n");
1533 if (options.verbose)
1534 printf ("sdcc: Calling linker...\n");
1536 #ifdef USE_SYSTEM_SYSTEM_CALLS
1537 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1538 if (my_system (buffer))
1540 /* either system() or the linker itself has reported an error
1541 perror ("Cannot exec linker");
1546 buildCmdLine (buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1547 if (my_system (argv[0], argv))
1549 perror ("Cannot exec linker");
1555 if (strcmp (srcFileName, "temp") == 0)
1557 /* rename "temp.cdb" to "firstRelFile.cdb" */
1558 char *f = strtok (strdup (relFiles[0]), ".");
1559 f = strcat (f, ".cdb");
1560 rename ("temp.cdb", f);
1565 /*-----------------------------------------------------------------*/
1566 /* assemble - spawns the assembler with arguments */
1567 /*-----------------------------------------------------------------*/
1569 assemble (char **envp)
1571 #ifdef USE_SYSTEM_SYSTEM_CALLS
1572 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1573 if (my_system (buffer))
1575 /* either system() or the assembler itself has reported an error
1576 perror ("Cannot exec assembler");
1581 char *argv[128]; /* assembler arguments */
1583 buildCmdLine (buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1585 if (my_system (argv[0], argv))
1587 perror ("Cannot exec assembler");
1595 /*-----------------------------------------------------------------*/
1596 /* preProcess - spawns the preprocessor with arguments */
1597 /*-----------------------------------------------------------------*/
1599 preProcess (char **envp)
1601 #ifndef USE_SYSTEM_SYSTEM_CALLS
1608 if (!options.c1mode)
1610 /* if using external stack define the macro */
1611 if (options.useXstack)
1612 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1614 /* set the macro for stack autos */
1615 if (options.stackAuto)
1616 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1618 /* set the macro for stack autos */
1619 if (options.stack10bit)
1620 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1622 /* set the macro for large model */
1623 switch (options.model)
1626 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1629 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1632 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1635 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1638 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1641 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1646 /* add port (processor information to processor */
1647 sprintf (procDef, "-DSDCC_%s", port->target);
1648 _addToList (preArgv, procDef);
1651 preOutName = strdup (tmpnam (NULL));
1653 if (options.verbose)
1654 printf ("sdcc: Calling preprocessor...\n");
1656 #ifdef USE_SYSTEM_SYSTEM_CALLS
1657 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1658 preOutName, srcFileName, preArgv);
1659 if (my_system (buffer))
1661 /* either system() or the preprocessor itself has reported an error
1662 perror ("Cannot exec Preprocessor");
1667 buildCmdLine (buffer, argv, _preCmd, fullSrcFileName,
1668 preOutName, srcFileName, preArgv);
1670 if (my_system (argv[0], argv))
1672 unlink (preOutName);
1673 perror ("Cannot exec Preprocessor");
1683 preOutName = fullSrcFileName;
1686 yyin = fopen (preOutName, "r");
1689 perror ("Preproc file not found\n");
1697 _findPort (int argc, char **argv)
1704 if (!strncmp (*argv, "-m", 2))
1706 _setPort (*argv + 2);
1712 /* Use the first in the list */
1718 * initialises and calls the parser
1722 main (int argc, char **argv, char **envp)
1724 /* turn all optimizations off by default */
1725 memset (&optimize, 0, sizeof (struct optimize));
1727 /*printVersionInfo (); */
1729 _findPort (argc, argv);
1730 /* Initalise the port. */
1734 // Create a default exe search path from the path to the sdcc command
1738 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1740 strcpy (DefaultExePath, argv[0]);
1741 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1742 try_dir[0] = DefaultExePath;
1746 setDefaultOptions ();
1747 parseCmdLine (argc, argv);
1751 port->finaliseOptions ();
1753 /* if no input then printUsage & exit */
1754 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1769 if (options.verbose)
1770 printf ("sdcc: Generating code...\n");
1776 /* TSD PIC port hack - if the PIC port option is enabled
1777 and SDCC is used to generate PIC code, then we will
1778 generate .asm files in gpasm's format instead of SDCC's
1781 #if !OPT_DISABLE_PIC
1791 if (!options.c1mode)
1793 if (options.verbose)
1794 printf ("sdcc: Calling assembler...\n");
1809 if (!options.cc_only &&
1813 (srcFileName || nrelFiles))
1815 if (port->linker.do_link)
1816 port->linker.do_link ();
1821 if (yyin && yyin != stdin)
1824 if (preOutName && !options.c1mode)
1826 unlink (preOutName);