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_LESS_PEDANTIC "-lesspedantic"
135 static const char *_preCmd[] =
137 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
138 "$l", "$1", "$2", NULL
143 static PORT *_ports[] =
145 #if !OPT_DISABLE_MCS51
148 #if !OPT_DISABLE_GBZ80
157 #if !OPT_DISABLE_DS390
163 #if !OPT_DISABLE_I186
166 #if !OPT_DISABLE_TLCS900H
171 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
174 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
176 extern void picglue ();
178 /** Sets the port to the one given by the command line option.
179 @param The name minus the option (eg 'mcs51')
180 @return 0 on success.
183 _setPort (const char *name)
186 for (i = 0; i < NUM_PORTS; i++)
188 if (!strcmp (_ports[i]->target, name))
194 /* Error - didnt find */
195 werror (E_UNKNOWN_TARGET, name);
200 _validatePorts (void)
203 for (i = 0; i < NUM_PORTS; i++)
205 if (_ports[i]->magic != PORT_MAGIC)
207 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
214 buildCmdLine (char *into, const char **cmds,
215 const char *p1, const char *p2,
216 const char *p3, const char **list)
218 const char *p, *from;
228 /* See if it has a '$' anywhere - if not, just copy */
229 if ((p = strchr (from, '$')))
231 strncat (into, from, p - from);
252 const char **tmp = list;
268 strcat (into, from); // this includes the ".asm" from "$1.asm"
274 /*-----------------------------------------------------------------*/
275 /* printVersionInfo - prints the version info */
276 /*-----------------------------------------------------------------*/
284 for (i = 0; i < NUM_PORTS; i++)
285 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
287 fprintf (stderr, " %s"
288 #ifdef SDCC_SUB_VERSION_STR
289 "/" SDCC_SUB_VERSION_STR
297 #if defined(_MSC_VER)
309 /*-----------------------------------------------------------------*/
310 /* printUsage - prints command line syntax */
311 /*-----------------------------------------------------------------*/
317 "Usage : [options] filename\n"
319 "\t-m<proc> - Target processor <proc>. Default %s\n"
320 "\t Try --version for supported values of <proc>\n"
321 "\t--model-large - Large Model\n"
322 "\t--model-small - Small Model (default)\n"
323 "\t--stack-auto - Stack automatic variables\n"
324 "\t--xstack - Use external stack\n"
325 "\t--xram-loc <nnnn> - External Ram start location\n"
326 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
327 "\t--code-loc <nnnn> - Code Segment Location\n"
328 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
329 "\t--data-loc <nnnn> - Direct data start location\n"
330 "\t--idata-loc <nnnn> - Indirect data start location\n"
331 "\t--iram-size <nnnn> - Internal Ram size\n"
332 "\t--nojtbound - Don't generate boundary check for jump tables\n"
333 "\t--generic - All unqualified ptrs converted to '_generic'\n"
334 "PreProcessor Options :-\n"
335 "\t-Dmacro - Define Macro\n"
336 "\t-Ipath - Include \"*.h\" path\n"
337 "Note: this is NOT a complete list of options see docs for details\n",
343 /*-----------------------------------------------------------------*/
344 /* parseWithComma - separates string with comma */
345 /*-----------------------------------------------------------------*/
347 parseWithComma (char **dest, char *src)
351 strtok (src, "\n \t");
352 /* skip the initial white spaces */
353 while (isspace (*src))
370 /*-----------------------------------------------------------------*/
371 /* setDefaultOptions - sets the default options */
372 /*-----------------------------------------------------------------*/
378 for (i = 0; i < 128; i++)
379 preArgv[i] = asmOptions[i] =
380 linkOptions[i] = relFiles[i] = libFiles[i] =
383 /* first the options part */
384 options.stack_loc = 0; /* stack pointer initialised to 0 */
385 options.xstack_loc = 0; /* xternal stack starts at 0 */
386 options.code_loc = 0; /* code starts at 0 */
387 options.data_loc = 0x0030; /* data starts at 0x0030 */
388 options.xdata_loc = 0;
389 options.idata_loc = 0x80;
390 options.genericPtr = 1; /* default on */
392 options.model = port->general.default_model;
393 options.nostdlib = 0;
394 options.nostdinc = 0;
397 options.stack10bit=0;
399 /* now for the optimizations */
400 /* turn on the everything */
401 optimize.global_cse = 1;
406 optimize.loopInvariant = 1;
407 optimize.loopInduction = 1;
409 /* now for the ports */
410 port->setDefaultOptions ();
413 /*-----------------------------------------------------------------*/
414 /* processFile - determines the type of file from the extension */
415 /*-----------------------------------------------------------------*/
417 processFile (char *s)
421 /* get the file extension */
422 fext = s + strlen (s);
423 while ((fext != s) && *fext != '.')
426 /* now if no '.' then we don't know what the file type is
427 so give a warning and return */
430 werror (W_UNKNOWN_FEXT, s);
434 /* otherwise depending on the file type */
435 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
437 /* source file name : not if we already have a
441 werror (W_TOO_MANY_SRC, s);
445 /* the only source file */
446 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
448 werror (E_FILE_OPEN_ERR, s);
452 /* copy the file name into the buffer */
455 /* get rid of the "." */
456 strtok (buffer, ".");
457 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
458 strcpy (srcFileName, buffer);
460 /* get rid of any path information
461 for the module name; do this by going
462 backwards till we get to either '/' or '\' or ':'
463 or start of buffer */
464 fext = buffer + strlen (buffer);
465 while (fext != buffer &&
466 *(fext - 1) != '\\' &&
467 *(fext - 1) != '/' &&
470 moduleName = Safe_calloc (1, strlen (fext) + 1);
471 strcpy (moduleName, fext);
476 /* if the extention is type .rel or .r or .REL or .R
477 addtional object file will be passed to the linker */
478 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
479 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
480 strcmp (fext, port->linker.rel_ext) == 0)
482 relFiles[nrelFiles++] = s;
486 /* if .lib or .LIB */
487 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
489 libFiles[nlibFiles++] = s;
493 werror (W_UNKNOWN_FEXT, s);
498 _processC1Arg (char *s)
502 if (options.out_name)
504 werror (W_TOO_MANY_SRC, s);
507 options.out_name = strdup (s);
516 _addToList (const char **list, const char *str)
518 /* This is the bad way to do things :) */
521 *list = strdup (str);
524 werror (E_OUT_OF_MEM, __FILE__, 0);
531 _setModel (int model, const char *sz)
533 if (port->general.supported_models & model)
534 options.model = model;
536 werror (W_UNSUPPORTED_MODEL, sz, port->target);
539 /*-----------------------------------------------------------------*/
540 /* parseCmdLine - parses the command line and sets the options */
541 /*-----------------------------------------------------------------*/
543 parseCmdLine (int argc, char **argv)
548 /* go thru all whole command line */
549 for (i = 1; i < argc; i++)
555 if (argv[i][0] == '-' && argv[i][1] == '-')
558 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
564 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
566 options.regExtend = 1;
570 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
572 _setModel (MODEL_LARGE, argv[i]);
576 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
578 _setModel (MODEL_MEDIUM, argv[i]);
582 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
584 _setModel (MODEL_SMALL, argv[i]);
588 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
590 _setModel (MODEL_FLAT24, argv[i]);
594 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
596 options.stack10bit = 1;
600 if (strcmp (&argv[i][1], OPTION_STACK_8BIT) == 0)
602 options.stack10bit = 0;
606 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
608 options.stackAuto = 1;
612 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
614 options.dump_raw = 1;
618 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
620 options.cyclomatic = 1;
624 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
626 options.dump_gcse = 1;
630 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
632 options.dump_loop = 1;
636 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
638 options.dump_kill = 1;
642 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
644 options.intlong_rent = 1;
648 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
650 options.float_rent = 1;
654 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
656 options.dump_range = 1;
660 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
662 options.dump_pack = 1;
666 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
668 options.dump_rassgn = 1;
672 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
678 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
684 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
686 options.noOverlay = 1;
690 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
692 options.stackOnData = 1;
696 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
702 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
709 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
711 options.dump_rassgn =
717 options.dump_raw = 1;
721 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
727 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
729 options.genericPtr = 1;
733 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
739 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
745 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
751 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
757 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
759 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
761 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
763 options.peep_file = argv[++i];
767 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
769 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
770 libPaths[nlibPaths++] =
771 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
773 libPaths[nlibPaths++] = argv[++i];
777 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
780 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
782 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
785 (int) floatFromVal (constVal (argv[++i]));
789 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
791 options.useXstack = 1;
795 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
797 options.mainreturn = 1;
801 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
803 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
804 parseWithComma (options.calleeSaves
805 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
807 parseWithComma (options.calleeSaves, argv[++i]);
811 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
814 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
816 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
819 (int) floatFromVal (constVal (argv[++i]));
823 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
826 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
828 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
831 (unsigned int) floatFromVal (constVal (argv[++i]));
835 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
838 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
840 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
843 (int) floatFromVal (constVal (argv[++i]));
847 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
854 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
857 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
859 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
862 (int) floatFromVal (constVal (argv[++i]));
866 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
869 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
871 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
874 (int) floatFromVal (constVal (argv[++i]));
878 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
881 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
883 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
886 (int) floatFromVal (constVal (argv[++i]));
891 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
893 optimize.noJTabBoundary = 1;
897 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
899 optimize.global_cse = 0;
903 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
905 optimize.loopInvariant = 0;
909 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
911 optimize.loopInduction = 0;
915 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
917 optimize.noLoopReverse = 1;
921 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
923 options.nostdlib = 1;
927 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
929 options.nostdinc = 1;
933 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
939 if (strcmp (argv[i] +1, OPTION_LESS_PEDANTIC) == 0)
941 setErrorLogLevel(ERROR_LEVEL_WARNINGS);
945 if (!port->parseOption (&argc, argv, &i))
947 werror (W_UNKNOWN_OPTION, argv[i]);
956 /* if preceded by '-' then option */
971 /* Used to select the port */
972 _setPort (argv[i] + 2);
976 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
980 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
983 case 'X': /* use external stack */
984 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
988 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
991 case 'p': /* stack pointer intial value */
993 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
997 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1001 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1005 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1009 options.cc_only = 1;
1013 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1018 libPaths[nlibPaths++] = &argv[i][2];
1020 libPaths[nlibPaths++] = argv[++i];
1024 /* linker options */
1025 if (argv[i][2] == 'l')
1028 parseWithComma (linkOptions, &argv[i][3]);
1030 parseWithComma (linkOptions, argv[++i]);
1034 /* assembler options */
1035 if (argv[i][2] == 'a')
1038 parseWithComma ((char **) asmOptions, &argv[i][3]);
1040 parseWithComma ((char **) asmOptions, argv[++i]);
1045 werror (W_UNKNOWN_OPTION, argv[i]);
1058 printVersionInfo ();
1062 /* preprocessor options */
1066 _addToList (preArgv, "-M");
1071 _addToList (preArgv, "-C");
1080 char sOpt = argv[i][1];
1083 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1091 if (argv[i][1] == 'Y')
1094 sprintf (buffer, "-%c%s", sOpt, rest);
1095 _addToList (preArgv, buffer);
1100 if (!port->parseOption (&argc, argv, &i))
1101 werror (W_UNKNOWN_OPTION, argv[i]);
1106 if (!port->parseOption (&argc, argv, &i))
1108 /* no option must be a filename */
1110 _processC1Arg (argv[i]);
1112 processFile (argv[i]);
1116 /* set up external stack location if not explicitly specified */
1117 if (!options.xstack_loc)
1118 options.xstack_loc = options.xdata_loc;
1120 /* if debug option is set the open the cdbFile */
1121 if (!options.nodebug && srcFileName)
1123 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1124 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1125 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1128 /* add a module record */
1129 fprintf (cdbFile, "M:%s\n", moduleName);
1135 /*-----------------------------------------------------------------*/
1136 /* my_system - will call a program with arguments */
1137 /*-----------------------------------------------------------------*/
1142 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1144 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1148 my_system (const char *cmd)
1150 int argsStart, e, i = 0;
1151 char *cmdLine = NULL;
1153 argsStart = strstr (cmd, " ") - cmd;
1155 // try to find the command in predefined path's
1158 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1159 strcpy (cmdLine, try_dir[i]); // the path
1161 strcat (cmdLine, DIR_SEPARATOR_STRING);
1162 strncat (cmdLine, cmd, argsStart); // the command
1165 strcat (cmdLine, ".exe");
1168 if (access (cmdLine, X_OK) == 0)
1171 strcat (cmdLine, cmd + argsStart);
1181 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1186 // command found in predefined path
1187 e = system (cmdLine);
1199 /*-----------------------------------------------------------------*/
1200 /* linkEdit : - calls the linkage editor with options */
1201 /*-----------------------------------------------------------------*/
1203 linkEdit (char **envp)
1210 srcFileName = "temp";
1212 /* first we need to create the <filename>.lnk file */
1213 sprintf (buffer, "%s.lnk", srcFileName);
1214 if (!(lnkfile = fopen (buffer, "w")))
1216 werror (E_FILE_OPEN_ERR, buffer);
1220 /* now write the options */
1221 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1223 /* if iram size specified */
1224 if (options.iram_size)
1225 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1227 /*if (options.debug) */
1228 fprintf (lnkfile, "-z\n");
1230 #define WRITE_SEG_LOC(N, L) \
1231 segName = strdup(N); \
1232 c = strtok(segName, " \t"); \
1233 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1234 if (segName) { free(segName); }
1236 /* code segment start */
1237 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1239 /* data segment start */
1240 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1243 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1246 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1248 /* bit segment start */
1249 WRITE_SEG_LOC (BIT_NAME, 0);
1251 /* add the extra linker options */
1252 for (i = 0; linkOptions[i]; i++)
1253 fprintf (lnkfile, "%s\n", linkOptions[i]);
1255 /* other library paths if specified */
1256 for (i = 0; i < nlibPaths; i++)
1257 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1259 /* standard library path */
1260 if (!options.nostdlib)
1262 if (TARGET_IS_DS390)
1268 switch (options.model)
1280 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1285 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1287 /* standard library files */
1288 if (strcmp (port->target, "ds390") == 0)
1290 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1292 fprintf (lnkfile, "-l %s\n", STD_LIB);
1293 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1294 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1295 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1298 /* additional libraries if any */
1299 for (i = 0; i < nlibFiles; i++)
1300 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1302 /* put in the object files */
1303 if (strcmp (srcFileName, "temp"))
1304 fprintf (lnkfile, "%s ", srcFileName);
1306 for (i = 0; i < nrelFiles; i++)
1307 fprintf (lnkfile, "%s\n", relFiles[i]);
1309 fprintf (lnkfile, "\n-e\n");
1312 if (options.verbose)
1313 printf ("sdcc: Calling linker...\n");
1315 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1316 if (my_system (buffer))
1321 if (strcmp (srcFileName, "temp") == 0)
1323 /* rename "temp.cdb" to "firstRelFile.cdb" */
1324 char *f = strtok (strdup (relFiles[0]), ".");
1325 f = strcat (f, ".cdb");
1326 rename ("temp.cdb", f);
1331 /*-----------------------------------------------------------------*/
1332 /* assemble - spawns the assembler with arguments */
1333 /*-----------------------------------------------------------------*/
1335 assemble (char **envp)
1337 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1338 if (my_system (buffer))
1340 /* either system() or the assembler itself has reported an error
1341 perror ("Cannot exec assembler");
1349 /*-----------------------------------------------------------------*/
1350 /* preProcess - spawns the preprocessor with arguments */
1351 /*-----------------------------------------------------------------*/
1353 preProcess (char **envp)
1359 if (!options.c1mode)
1361 /* if using external stack define the macro */
1362 if (options.useXstack)
1363 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1365 /* set the macro for stack autos */
1366 if (options.stackAuto)
1367 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1369 /* set the macro for stack autos */
1370 if (options.stack10bit)
1371 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1373 /* set the macro for large model */
1374 switch (options.model)
1377 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1380 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1383 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1386 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1389 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1392 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1396 /* standard include path */
1397 if (!options.nostdinc) {
1398 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1401 /* add port (processor information to processor */
1402 sprintf (procDef, "-DSDCC_%s", port->target);
1403 _addToList (preArgv, procDef);
1404 sprintf (procDef, "-D__%s", port->target);
1405 _addToList (preArgv, procDef);
1408 preOutName = strdup (tmpnam (NULL));
1410 if (options.verbose)
1411 printf ("sdcc: Calling preprocessor...\n");
1413 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1414 preOutName, srcFileName, preArgv);
1415 if (my_system (buffer))
1417 // @FIX: Dario Vecchio 03-05-2001
1420 unlink (preOutName);
1432 preOutName = fullSrcFileName;
1435 yyin = fopen (preOutName, "r");
1438 perror ("Preproc file not found\n");
1446 _findPort (int argc, char **argv)
1453 if (!strncmp (*argv, "-m", 2))
1455 _setPort (*argv + 2);
1461 /* Use the first in the list */
1467 * initialises and calls the parser
1471 main (int argc, char **argv, char **envp)
1473 /* turn all optimizations off by default */
1474 memset (&optimize, 0, sizeof (struct optimize));
1476 /*printVersionInfo (); */
1479 fprintf (stderr, "Build error: no ports are enabled.\n");
1483 _findPort (argc, argv);
1484 /* Initalise the port. */
1488 // Create a default exe search path from the path to the sdcc command
1492 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1494 strcpy (DefaultExePath, argv[0]);
1495 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1496 try_dir[0] = DefaultExePath;
1500 setDefaultOptions ();
1501 parseCmdLine (argc, argv);
1505 port->finaliseOptions ();
1507 /* if no input then printUsage & exit */
1508 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1523 if (options.verbose)
1524 printf ("sdcc: Generating code...\n");
1530 if (TARGET_IS_PIC) {
1531 /* TSD PIC port hack - if the PIC port option is enabled
1532 and SDCC is used to generate PIC code, then we will
1533 generate .asm files in gpasm's format instead of SDCC's
1536 #if !OPT_DISABLE_PIC
1545 // @FIX: Dario Vecchio 03-05-2001
1548 if (yyin && yyin != stdin)
1550 unlink (preOutName);
1556 if (!options.c1mode)
1558 if (options.verbose)
1559 printf ("sdcc: Calling assembler...\n");
1565 // @FIX: Dario Vecchio 03-05-2001
1568 if (yyin && yyin != stdin)
1570 unlink (preOutName);
1582 if (!options.cc_only &&
1586 (srcFileName || nrelFiles))
1588 if (port->linker.do_link)
1589 port->linker.do_link ();
1594 if (yyin && yyin != stdin)
1597 if (preOutName && !options.c1mode)
1599 unlink (preOutName);