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 -------------------------------------------------------------------------*/
36 // This is a bit messy because we define link ourself
37 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
42 // No unistd.h in Borland C++
43 extern int access (const char *, int);
49 extern int yyparse ();
51 FILE *srcFile; /* source file */
52 FILE *cdbFile = NULL; /* debugger information output file */
53 char *fullSrcFileName; /* full name for the source file */
54 char *srcFileName; /* source file name with the .c stripped */
55 char *moduleName; /* module name is srcFilename stripped of any path */
56 const char *preArgv[128]; /* pre-processor arguments */
58 struct optimize optimize;
59 struct options options;
60 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
61 short preProcOnly = 0;
63 char *linkOptions[128];
64 const char *asmOptions[128];
71 bool verboseExec = FALSE;
74 // In MSC VC6 default search path for exe's to path for this
76 char DefaultExePath[128];
78 /* Far functions, far data */
79 #define OPTION_LARGE_MODEL "-model-large"
80 /* Far functions, near data */
81 #define OPTION_MEDIUM_MODEL "-model-medium"
82 #define OPTION_SMALL_MODEL "-model-small"
83 #define OPTION_FLAT24_MODEL "-model-flat24"
84 #define OPTION_STACK_AUTO "-stack-auto"
85 #define OPTION_STACK_8BIT "-stack-8bit"
86 #define OPTION_STACK_10BIT "-stack-10bit"
87 #define OPTION_XSTACK "-xstack"
88 #define OPTION_GENERIC "-generic"
89 #define OPTION_NO_GCSE "-nogcse"
90 #define OPTION_NO_LOOP_INV "-noinvariant"
91 #define OPTION_NO_LOOP_IND "-noinduction"
92 #define OPTION_NO_JTBOUND "-nojtbound"
93 #define OPTION_NO_LOOPREV "-noloopreverse"
94 #define OPTION_XREGS "-regextend"
95 #define OPTION_COMP_ONLY "-compile-only"
96 #define OPTION_DUMP_RAW "-dumpraw"
97 #define OPTION_DUMP_GCSE "-dumpgcse"
98 #define OPTION_DUMP_LOOP "-dumploop"
99 #define OPTION_DUMP_KILL "-dumpdeadcode"
100 #define OPTION_DUMP_RANGE "-dumpliverange"
101 #define OPTION_DUMP_PACK "-dumpregpack"
102 #define OPTION_DUMP_RASSGN "-dumpregassign"
103 #define OPTION_DUMP_ALL "-dumpall"
104 #define OPTION_XRAM_LOC "-xram-loc"
105 #define OPTION_IRAM_SIZE "-iram-size"
106 #define OPTION_XSTACK_LOC "-xstack-loc"
107 #define OPTION_CODE_LOC "-code-loc"
108 #define OPTION_STACK_LOC "-stack-loc"
109 #define OPTION_DATA_LOC "-data-loc"
110 #define OPTION_IDATA_LOC "-idata-loc"
111 #define OPTION_PEEP_FILE "-peep-file"
112 #define OPTION_LIB_PATH "-lib-path"
113 #define OPTION_INTLONG_RENT "-int-long-reent"
114 #define OPTION_FLOAT_RENT "-float-reent"
115 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
116 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
117 #define OPTION_CYCLOMATIC "-cyclomatic"
118 #define OPTION_NOOVERLAY "-nooverlay"
119 #define OPTION_MAINRETURN "-main-return"
120 #define OPTION_NOPEEP "-no-peep"
121 #define OPTION_ASMPEEP "-peep-asm"
122 #define OPTION_DEBUG "-debug"
123 #define OPTION_NODEBUG "-nodebug"
124 #define OPTION_VERSION "-version"
125 #define OPTION_STKAFTRDATA "-stack-after-data"
126 #define OPTION_PREPROC_ONLY "-preprocessonly"
127 #define OPTION_C1_MODE "-c1mode"
128 #define OPTION_HELP "-help"
129 #define OPTION_CALLEE_SAVES "-callee-saves"
130 #define OPTION_NOSTDLIB "-nostdlib"
131 #define OPTION_NOSTDINC "-nostdinc"
132 #define OPTION_VERBOSE "-verbose"
133 #define OPTION_ANSIINT "-ansiint"
134 static const char *_preCmd[] =
136 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
137 "$l", "$1", "$2", NULL
142 static PORT *_ports[] =
144 #if !OPT_DISABLE_MCS51
147 #if !OPT_DISABLE_GBZ80
156 #if !OPT_DISABLE_DS390
162 #if !OPT_DISABLE_I186
165 #if !OPT_DISABLE_TLCS900H
170 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
173 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
175 extern void picglue ();
177 /** Sets the port to the one given by the command line option.
178 @param The name minus the option (eg 'mcs51')
179 @return 0 on success.
182 _setPort (const char *name)
185 for (i = 0; i < NUM_PORTS; i++)
187 if (!strcmp (_ports[i]->target, name))
193 /* Error - didnt find */
194 werror (E_UNKNOWN_TARGET, name);
199 _validatePorts (void)
202 for (i = 0; i < NUM_PORTS; i++)
204 if (_ports[i]->magic != PORT_MAGIC)
206 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
213 buildCmdLine (char *into, const char **cmds,
214 const char *p1, const char *p2,
215 const char *p3, const char **list)
217 const char *p, *from;
227 /* See if it has a '$' anywhere - if not, just copy */
228 if ((p = strchr (from, '$')))
230 strncat (into, from, p - from);
251 const char **tmp = list;
267 strcat (into, from); // this includes the ".asm" from "$1.asm"
273 /*-----------------------------------------------------------------*/
274 /* printVersionInfo - prints the version info */
275 /*-----------------------------------------------------------------*/
283 for (i = 0; i < NUM_PORTS; i++)
284 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
286 fprintf (stderr, " %s"
287 #ifdef SDCC_SUB_VERSION_STR
288 "/" SDCC_SUB_VERSION_STR
296 #if defined(_MSC_VER)
308 /*-----------------------------------------------------------------*/
309 /* printUsage - prints command line syntax */
310 /*-----------------------------------------------------------------*/
316 "Usage : [options] filename\n"
318 "\t-m<proc> - Target processor <proc>. Default %s\n"
319 "\t Try --version for supported values of <proc>\n"
320 "\t--model-large - Large Model\n"
321 "\t--model-small - Small Model (default)\n"
322 "\t--stack-auto - Stack automatic variables\n"
323 "\t--xstack - Use external stack\n"
324 "\t--xram-loc <nnnn> - External Ram start location\n"
325 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
326 "\t--code-loc <nnnn> - Code Segment Location\n"
327 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
328 "\t--data-loc <nnnn> - Direct data start location\n"
329 "\t--idata-loc <nnnn> - Indirect data start location\n"
330 "\t--iram-size <nnnn> - Internal Ram size\n"
331 "\t--nojtbound - Don't generate boundary check for jump tables\n"
332 "\t--generic - All unqualified ptrs converted to '_generic'\n"
333 "PreProcessor Options :-\n"
334 "\t-Dmacro - Define Macro\n"
335 "\t-Ipath - Include \"*.h\" path\n"
336 "Note: this is NOT a complete list of options see docs for details\n",
342 /*-----------------------------------------------------------------*/
343 /* parseWithComma - separates string with comma */
344 /*-----------------------------------------------------------------*/
346 parseWithComma (char **dest, char *src)
350 strtok (src, "\n \t");
351 /* skip the initial white spaces */
352 while (isspace (*src))
369 /*-----------------------------------------------------------------*/
370 /* setDefaultOptions - sets the default options */
371 /*-----------------------------------------------------------------*/
377 for (i = 0; i < 128; i++)
378 preArgv[i] = asmOptions[i] =
379 linkOptions[i] = relFiles[i] = libFiles[i] =
382 /* first the options part */
383 options.stack_loc = 0; /* stack pointer initialised to 0 */
384 options.xstack_loc = 0; /* xternal stack starts at 0 */
385 options.code_loc = 0; /* code starts at 0 */
386 options.data_loc = 0x0030; /* data starts at 0x0030 */
387 options.xdata_loc = 0;
388 options.idata_loc = 0x80;
389 options.genericPtr = 1; /* default on */
391 options.model = port->general.default_model;
392 options.nostdlib = 0;
393 options.nostdinc = 0;
396 options.stack10bit=0;
398 /* now for the optimizations */
399 /* turn on the everything */
400 optimize.global_cse = 1;
405 optimize.loopInvariant = 1;
406 optimize.loopInduction = 1;
408 /* now for the ports */
409 port->setDefaultOptions ();
412 /*-----------------------------------------------------------------*/
413 /* processFile - determines the type of file from the extension */
414 /*-----------------------------------------------------------------*/
416 processFile (char *s)
420 /* get the file extension */
421 fext = s + strlen (s);
422 while ((fext != s) && *fext != '.')
425 /* now if no '.' then we don't know what the file type is
426 so give a warning and return */
429 werror (W_UNKNOWN_FEXT, s);
433 /* otherwise depending on the file type */
434 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
436 /* source file name : not if we already have a
440 werror (W_TOO_MANY_SRC, s);
444 /* the only source file */
445 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
447 werror (E_FILE_OPEN_ERR, s);
451 /* copy the file name into the buffer */
454 /* get rid of the "." */
455 strtok (buffer, ".");
456 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
457 strcpy (srcFileName, buffer);
459 /* get rid of any path information
460 for the module name; do this by going
461 backwards till we get to either '/' or '\' or ':'
462 or start of buffer */
463 fext = buffer + strlen (buffer);
464 while (fext != buffer &&
465 *(fext - 1) != '\\' &&
466 *(fext - 1) != '/' &&
469 moduleName = Safe_calloc (1, strlen (fext) + 1);
470 strcpy (moduleName, fext);
475 /* if the extention is type .rel or .r or .REL or .R
476 addtional object file will be passed to the linker */
477 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
478 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
479 strcmp (fext, port->linker.rel_ext) == 0)
481 relFiles[nrelFiles++] = s;
485 /* if .lib or .LIB */
486 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
488 libFiles[nlibFiles++] = s;
492 werror (W_UNKNOWN_FEXT, s);
497 _processC1Arg (char *s)
501 if (options.out_name)
503 werror (W_TOO_MANY_SRC, s);
506 options.out_name = strdup (s);
515 _addToList (const char **list, const char *str)
517 /* This is the bad way to do things :) */
520 *list = strdup (str);
523 werror (E_OUT_OF_MEM, __FILE__, 0);
530 _setModel (int model, const char *sz)
532 if (port->general.supported_models & model)
533 options.model = model;
535 werror (W_UNSUPPORTED_MODEL, sz, port->target);
538 /*-----------------------------------------------------------------*/
539 /* parseCmdLine - parses the command line and sets the options */
540 /*-----------------------------------------------------------------*/
542 parseCmdLine (int argc, char **argv)
547 /* go thru all whole command line */
548 for (i = 1; i < argc; i++)
554 if (argv[i][0] == '-' && argv[i][1] == '-')
557 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
563 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
565 options.regExtend = 1;
569 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
571 _setModel (MODEL_LARGE, argv[i]);
575 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
577 _setModel (MODEL_MEDIUM, argv[i]);
581 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
583 _setModel (MODEL_SMALL, argv[i]);
587 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
589 _setModel (MODEL_FLAT24, argv[i]);
593 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
595 options.stack10bit = 1;
599 if (strcmp (&argv[i][1], OPTION_STACK_8BIT) == 0)
601 options.stack10bit = 0;
605 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
607 options.stackAuto = 1;
611 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
613 options.dump_raw = 1;
617 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
619 options.cyclomatic = 1;
623 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
625 options.dump_gcse = 1;
629 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
631 options.dump_loop = 1;
635 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
637 options.dump_kill = 1;
641 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
643 options.intlong_rent = 1;
647 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
649 options.float_rent = 1;
653 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
655 options.dump_range = 1;
659 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
661 options.dump_pack = 1;
665 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
667 options.dump_rassgn = 1;
671 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
677 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
683 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
685 options.noOverlay = 1;
689 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
691 options.stackOnData = 1;
695 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
701 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
708 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
710 options.dump_rassgn =
716 options.dump_raw = 1;
720 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
726 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
728 options.genericPtr = 1;
732 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
738 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
744 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
750 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
756 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
758 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
760 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
762 options.peep_file = argv[++i];
766 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
768 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
769 libPaths[nlibPaths++] =
770 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
772 libPaths[nlibPaths++] = argv[++i];
776 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
779 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
781 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
784 (int) floatFromVal (constVal (argv[++i]));
788 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
790 options.useXstack = 1;
794 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
796 options.mainreturn = 1;
800 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
802 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
803 parseWithComma (options.calleeSaves
804 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
806 parseWithComma (options.calleeSaves, argv[++i]);
810 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
813 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
815 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
818 (int) floatFromVal (constVal (argv[++i]));
822 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
825 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
827 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
830 (unsigned int) floatFromVal (constVal (argv[++i]));
834 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
837 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
839 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
842 (int) floatFromVal (constVal (argv[++i]));
846 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
853 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
856 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
858 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
861 (int) floatFromVal (constVal (argv[++i]));
865 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
868 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
870 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
873 (int) floatFromVal (constVal (argv[++i]));
877 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
880 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
882 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
885 (int) floatFromVal (constVal (argv[++i]));
890 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
892 optimize.noJTabBoundary = 1;
896 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
898 optimize.global_cse = 0;
902 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
904 optimize.loopInvariant = 0;
908 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
910 optimize.loopInduction = 0;
914 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
916 optimize.noLoopReverse = 1;
920 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
922 options.nostdlib = 1;
926 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
928 options.nostdinc = 1;
932 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
938 if (strcmp (&argv[i][1], OPTION_ANSIINT) == 0)
944 if (!port->parseOption (&argc, argv, &i))
946 werror (W_UNKNOWN_OPTION, argv[i]);
955 /* if preceded by '-' then option */
970 /* Used to select the port */
971 _setPort (argv[i] + 2);
975 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
979 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
982 case 'X': /* use external stack */
983 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
987 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
990 case 'p': /* stack pointer intial value */
992 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
996 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1000 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1004 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1008 options.cc_only = 1;
1012 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1017 libPaths[nlibPaths++] = &argv[i][2];
1019 libPaths[nlibPaths++] = argv[++i];
1023 /* linker options */
1024 if (argv[i][2] == 'l')
1027 parseWithComma (linkOptions, &argv[i][3]);
1029 parseWithComma (linkOptions, argv[++i]);
1033 /* assembler options */
1034 if (argv[i][2] == 'a')
1037 parseWithComma ((char **) asmOptions, &argv[i][3]);
1039 parseWithComma ((char **) asmOptions, argv[++i]);
1044 werror (W_UNKNOWN_OPTION, argv[i]);
1057 printVersionInfo ();
1061 /* preprocessor options */
1065 _addToList (preArgv, "-M");
1070 _addToList (preArgv, "-C");
1079 char sOpt = argv[i][1];
1082 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1090 if (argv[i][1] == 'Y')
1093 sprintf (buffer, "-%c%s", sOpt, rest);
1094 _addToList (preArgv, buffer);
1099 if (!port->parseOption (&argc, argv, &i))
1100 werror (W_UNKNOWN_OPTION, argv[i]);
1105 if (!port->parseOption (&argc, argv, &i))
1107 /* no option must be a filename */
1109 _processC1Arg (argv[i]);
1111 processFile (argv[i]);
1115 /* set up external stack location if not explicitly specified */
1116 if (!options.xstack_loc)
1117 options.xstack_loc = options.xdata_loc;
1119 /* if debug option is set the open the cdbFile */
1120 if (!options.nodebug && srcFileName)
1122 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1123 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1124 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1127 /* add a module record */
1128 fprintf (cdbFile, "M:%s\n", moduleName);
1134 /*-----------------------------------------------------------------*/
1135 /* my_system - will call a program with arguments */
1136 /*-----------------------------------------------------------------*/
1141 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1143 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1147 my_system (const char *cmd)
1149 int argsStart, e, i = 0;
1150 char *cmdLine = NULL;
1152 argsStart = strstr (cmd, " ") - cmd;
1154 // try to find the command in predefined path's
1157 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1158 strcpy (cmdLine, try_dir[i]); // the path
1160 strcat (cmdLine, DIR_SEPARATOR_STRING);
1161 strncat (cmdLine, cmd, argsStart); // the command
1164 strcat (cmdLine, ".exe");
1167 if (access (cmdLine, X_OK) == 0)
1170 strcat (cmdLine, cmd + argsStart);
1180 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1185 // command found in predefined path
1186 e = system (cmdLine);
1198 /*-----------------------------------------------------------------*/
1199 /* linkEdit : - calls the linkage editor with options */
1200 /*-----------------------------------------------------------------*/
1202 linkEdit (char **envp)
1209 srcFileName = "temp";
1211 /* first we need to create the <filename>.lnk file */
1212 sprintf (buffer, "%s.lnk", srcFileName);
1213 if (!(lnkfile = fopen (buffer, "w")))
1215 werror (E_FILE_OPEN_ERR, buffer);
1219 /* now write the options */
1220 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1222 /* if iram size specified */
1223 if (options.iram_size)
1224 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1226 /*if (options.debug) */
1227 fprintf (lnkfile, "-z\n");
1229 #define WRITE_SEG_LOC(N, L) \
1230 segName = strdup(N); \
1231 c = strtok(segName, " \t"); \
1232 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1233 if (segName) { free(segName); }
1235 /* code segment start */
1236 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1238 /* data segment start */
1239 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1242 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1245 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1247 /* bit segment start */
1248 WRITE_SEG_LOC (BIT_NAME, 0);
1250 /* add the extra linker options */
1251 for (i = 0; linkOptions[i]; i++)
1252 fprintf (lnkfile, "%s\n", linkOptions[i]);
1254 /* other library paths if specified */
1255 for (i = 0; i < nlibPaths; i++)
1256 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1258 /* standard library path */
1259 if (!options.nostdlib)
1261 if (TARGET_IS_DS390)
1267 switch (options.model)
1279 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1284 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1286 /* standard library files */
1287 if (strcmp (port->target, "ds390") == 0)
1289 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1291 fprintf (lnkfile, "-l %s\n", STD_LIB);
1292 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1293 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1294 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1297 /* additional libraries if any */
1298 for (i = 0; i < nlibFiles; i++)
1299 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1301 /* put in the object files */
1302 if (strcmp (srcFileName, "temp"))
1303 fprintf (lnkfile, "%s ", srcFileName);
1305 for (i = 0; i < nrelFiles; i++)
1306 fprintf (lnkfile, "%s\n", relFiles[i]);
1308 fprintf (lnkfile, "\n-e\n");
1311 if (options.verbose)
1312 printf ("sdcc: Calling linker...\n");
1314 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1315 if (my_system (buffer))
1320 if (strcmp (srcFileName, "temp") == 0)
1322 /* rename "temp.cdb" to "firstRelFile.cdb" */
1323 char *f = strtok (strdup (relFiles[0]), ".");
1324 f = strcat (f, ".cdb");
1325 rename ("temp.cdb", f);
1330 /*-----------------------------------------------------------------*/
1331 /* assemble - spawns the assembler with arguments */
1332 /*-----------------------------------------------------------------*/
1334 assemble (char **envp)
1336 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1337 if (my_system (buffer))
1339 /* either system() or the assembler itself has reported an error
1340 perror ("Cannot exec assembler");
1348 /*-----------------------------------------------------------------*/
1349 /* preProcess - spawns the preprocessor with arguments */
1350 /*-----------------------------------------------------------------*/
1352 preProcess (char **envp)
1358 if (!options.c1mode)
1360 /* if using external stack define the macro */
1361 if (options.useXstack)
1362 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1364 /* set the macro for stack autos */
1365 if (options.stackAuto)
1366 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1368 /* set the macro for stack autos */
1369 if (options.stack10bit)
1370 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1372 /* set the macro for large model */
1373 switch (options.model)
1376 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1379 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1382 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1385 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1388 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1391 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1395 /* standard include path */
1396 if (!options.nostdinc) {
1397 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1400 /* add port (processor information to processor */
1401 sprintf (procDef, "-DSDCC_%s", port->target);
1402 _addToList (preArgv, procDef);
1403 sprintf (procDef, "-D__%s", port->target);
1404 _addToList (preArgv, procDef);
1407 preOutName = strdup (tmpnam (NULL));
1409 if (options.verbose)
1410 printf ("sdcc: Calling preprocessor...\n");
1412 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1413 preOutName, srcFileName, preArgv);
1414 if (my_system (buffer))
1424 preOutName = fullSrcFileName;
1427 yyin = fopen (preOutName, "r");
1430 perror ("Preproc file not found\n");
1438 _findPort (int argc, char **argv)
1445 if (!strncmp (*argv, "-m", 2))
1447 _setPort (*argv + 2);
1453 /* Use the first in the list */
1459 * initialises and calls the parser
1463 main (int argc, char **argv, char **envp)
1465 /* turn all optimizations off by default */
1466 memset (&optimize, 0, sizeof (struct optimize));
1468 /*printVersionInfo (); */
1471 fprintf (stderr, "Build error: no ports are enabled.\n");
1475 _findPort (argc, argv);
1476 /* Initalise the port. */
1480 // Create a default exe search path from the path to the sdcc command
1484 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1486 strcpy (DefaultExePath, argv[0]);
1487 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1488 try_dir[0] = DefaultExePath;
1492 setDefaultOptions ();
1493 parseCmdLine (argc, argv);
1497 port->finaliseOptions ();
1499 /* if no input then printUsage & exit */
1500 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1515 if (options.verbose)
1516 printf ("sdcc: Generating code...\n");
1522 if (TARGET_IS_PIC) {
1523 /* TSD PIC port hack - if the PIC port option is enabled
1524 and SDCC is used to generate PIC code, then we will
1525 generate .asm files in gpasm's format instead of SDCC's
1528 #if !OPT_DISABLE_PIC
1539 if (!options.c1mode)
1541 if (options.verbose)
1542 printf ("sdcc: Calling assembler...\n");
1556 if (!options.cc_only &&
1560 (srcFileName || nrelFiles))
1562 if (port->linker.do_link)
1563 port->linker.do_link ();
1568 if (yyin && yyin != stdin)
1571 if (preOutName && !options.c1mode)
1573 unlink (preOutName);