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_NOREGPARMS "-noregparms"
131 #define OPTION_NOSTDLIB "-nostdlib"
132 #define OPTION_NOSTDINC "-nostdinc"
133 #define OPTION_VERBOSE "-verbose"
134 #define OPTION_ANSIINT "-ansiint"
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_NOREGPARMS) == 0)
759 options.noregparms = 1;
763 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
765 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
767 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
769 options.peep_file = argv[++i];
773 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
775 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
776 libPaths[nlibPaths++] =
777 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
779 libPaths[nlibPaths++] = argv[++i];
783 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
786 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
788 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
791 (int) floatFromVal (constVal (argv[++i]));
795 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
797 options.useXstack = 1;
801 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
803 options.mainreturn = 1;
807 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
809 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
810 parseWithComma (options.calleeSaves
811 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
813 parseWithComma (options.calleeSaves, argv[++i]);
817 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
820 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
822 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
825 (int) floatFromVal (constVal (argv[++i]));
829 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
832 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
834 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
837 (unsigned int) floatFromVal (constVal (argv[++i]));
841 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
844 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
846 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
849 (int) floatFromVal (constVal (argv[++i]));
853 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
860 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
863 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
865 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
868 (int) floatFromVal (constVal (argv[++i]));
872 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
875 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
877 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
880 (int) floatFromVal (constVal (argv[++i]));
884 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
887 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
889 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
892 (int) floatFromVal (constVal (argv[++i]));
897 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
899 optimize.noJTabBoundary = 1;
903 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
905 optimize.global_cse = 0;
909 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
911 optimize.loopInvariant = 0;
915 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
917 optimize.loopInduction = 0;
921 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
923 optimize.noLoopReverse = 1;
927 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
929 options.nostdlib = 1;
933 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
935 options.nostdinc = 1;
939 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
945 if (strcmp (&argv[i][1], OPTION_ANSIINT) == 0)
951 if (!port->parseOption (&argc, argv, &i))
953 werror (W_UNKNOWN_OPTION, argv[i]);
961 /* these are undocumented options */
962 /* if preceded by '/' then turn off certain optmizations, used
963 for debugging only these are also the legacy options from
964 version 1.xx will be removed gradually.
965 It may be an absolute filename.
967 if (*argv[i] == '/' && strlen (argv[i]) < 3)
973 optimize.ptrArithmetic = 0;
1004 optimize.loopInvariant = 0;
1007 optimize.loopInduction = 0;
1014 optimize.global_cse = 0;
1021 /* if preceded by '-' then option */
1022 if (*argv[i] == '-')
1036 /* Used to select the port */
1037 _setPort (argv[i] + 2);
1041 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
1045 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
1048 case 'X': /* use external stack */
1049 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
1053 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
1056 case 'p': /* stack pointer intial value */
1058 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
1062 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1066 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1070 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1074 options.cc_only = 1;
1078 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1083 libPaths[nlibPaths++] = &argv[i][2];
1085 libPaths[nlibPaths++] = argv[++i];
1089 /* linker options */
1090 if (argv[i][2] == 'l')
1093 parseWithComma (linkOptions, &argv[i][3]);
1095 parseWithComma (linkOptions, argv[++i]);
1099 /* assembler options */
1100 if (argv[i][2] == 'a')
1103 parseWithComma ((char **) asmOptions, &argv[i][3]);
1105 parseWithComma ((char **) asmOptions, argv[++i]);
1110 werror (W_UNKNOWN_OPTION, argv[i]);
1123 printVersionInfo ();
1127 /* preprocessor options */
1131 _addToList (preArgv, "-M");
1136 _addToList (preArgv, "-C");
1145 char sOpt = argv[i][1];
1148 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1156 if (argv[i][1] == 'Y')
1159 sprintf (buffer, "-%c%s", sOpt, rest);
1160 _addToList (preArgv, buffer);
1165 if (!port->parseOption (&argc, argv, &i))
1166 werror (W_UNKNOWN_OPTION, argv[i]);
1171 if (!port->parseOption (&argc, argv, &i))
1173 /* no option must be a filename */
1175 _processC1Arg (argv[i]);
1177 processFile (argv[i]);
1181 /* set up external stack location if not explicitly specified */
1182 if (!options.xstack_loc)
1183 options.xstack_loc = options.xdata_loc;
1185 /* if debug option is set the open the cdbFile */
1186 if (!options.nodebug && srcFileName)
1188 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1189 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1190 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1193 /* add a module record */
1194 fprintf (cdbFile, "M:%s\n", moduleName);
1200 /*-----------------------------------------------------------------*/
1201 /* my_system - will call a program with arguments */
1202 /*-----------------------------------------------------------------*/
1207 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1209 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1213 my_system (const char *cmd)
1215 int argsStart, e, i = 0;
1216 char *cmdLine = NULL;
1218 argsStart = strstr (cmd, " ") - cmd;
1220 // try to find the command in predefined path's
1223 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1224 strcpy (cmdLine, try_dir[i]); // the path
1226 strcat (cmdLine, DIR_SEPARATOR_STRING);
1227 strncat (cmdLine, cmd, argsStart); // the command
1230 strcat (cmdLine, ".exe");
1233 if (access (cmdLine, X_OK) == 0)
1236 strcat (cmdLine, cmd + argsStart);
1246 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1251 // command found in predefined path
1252 e = system (cmdLine);
1264 /*-----------------------------------------------------------------*/
1265 /* linkEdit : - calls the linkage editor with options */
1266 /*-----------------------------------------------------------------*/
1268 linkEdit (char **envp)
1275 srcFileName = "temp";
1277 /* first we need to create the <filename>.lnk file */
1278 sprintf (buffer, "%s.lnk", srcFileName);
1279 if (!(lnkfile = fopen (buffer, "w")))
1281 werror (E_FILE_OPEN_ERR, buffer);
1285 /* now write the options */
1286 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1288 /* if iram size specified */
1289 if (options.iram_size)
1290 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1292 /*if (options.debug) */
1293 fprintf (lnkfile, "-z\n");
1295 #define WRITE_SEG_LOC(N, L) \
1296 segName = strdup(N); \
1297 c = strtok(segName, " \t"); \
1298 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1299 if (segName) { free(segName); }
1301 /* code segment start */
1302 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1304 /* data segment start */
1305 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1308 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1311 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1313 /* bit segment start */
1314 WRITE_SEG_LOC (BIT_NAME, 0);
1316 /* add the extra linker options */
1317 for (i = 0; linkOptions[i]; i++)
1318 fprintf (lnkfile, "%s\n", linkOptions[i]);
1320 /* other library paths if specified */
1321 for (i = 0; i < nlibPaths; i++)
1322 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1324 /* standard library path */
1325 if (!options.nostdlib)
1327 if (TARGET_IS_DS390)
1333 switch (options.model)
1345 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1350 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1352 /* standard library files */
1353 if (strcmp (port->target, "ds390") == 0)
1355 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1357 fprintf (lnkfile, "-l %s\n", STD_LIB);
1358 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1359 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1360 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1363 /* additional libraries if any */
1364 for (i = 0; i < nlibFiles; i++)
1365 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1367 /* put in the object files */
1368 if (strcmp (srcFileName, "temp"))
1369 fprintf (lnkfile, "%s ", srcFileName);
1371 for (i = 0; i < nrelFiles; i++)
1372 fprintf (lnkfile, "%s\n", relFiles[i]);
1374 fprintf (lnkfile, "\n-e\n");
1377 if (options.verbose)
1378 printf ("sdcc: Calling linker...\n");
1380 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1381 if (my_system (buffer))
1386 if (strcmp (srcFileName, "temp") == 0)
1388 /* rename "temp.cdb" to "firstRelFile.cdb" */
1389 char *f = strtok (strdup (relFiles[0]), ".");
1390 f = strcat (f, ".cdb");
1391 rename ("temp.cdb", f);
1396 /*-----------------------------------------------------------------*/
1397 /* assemble - spawns the assembler with arguments */
1398 /*-----------------------------------------------------------------*/
1400 assemble (char **envp)
1402 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1403 if (my_system (buffer))
1405 /* either system() or the assembler itself has reported an error
1406 perror ("Cannot exec assembler");
1414 /*-----------------------------------------------------------------*/
1415 /* preProcess - spawns the preprocessor with arguments */
1416 /*-----------------------------------------------------------------*/
1418 preProcess (char **envp)
1424 if (!options.c1mode)
1426 /* if using external stack define the macro */
1427 if (options.useXstack)
1428 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1430 /* set the macro for stack autos */
1431 if (options.stackAuto)
1432 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1434 /* set the macro for stack autos */
1435 if (options.stack10bit)
1436 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1438 /* set the macro for large model */
1439 switch (options.model)
1442 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1445 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1448 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1451 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1454 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1457 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1461 /* standard include path */
1462 if (!options.nostdinc) {
1463 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1466 /* add port (processor information to processor */
1467 sprintf (procDef, "-DSDCC_%s", port->target);
1468 _addToList (preArgv, procDef);
1469 sprintf (procDef, "-D__%s", port->target);
1470 _addToList (preArgv, procDef);
1473 preOutName = strdup (tmpnam (NULL));
1475 if (options.verbose)
1476 printf ("sdcc: Calling preprocessor...\n");
1478 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1479 preOutName, srcFileName, preArgv);
1480 if (my_system (buffer))
1490 preOutName = fullSrcFileName;
1493 yyin = fopen (preOutName, "r");
1496 perror ("Preproc file not found\n");
1504 _findPort (int argc, char **argv)
1511 if (!strncmp (*argv, "-m", 2))
1513 _setPort (*argv + 2);
1519 /* Use the first in the list */
1525 * initialises and calls the parser
1529 main (int argc, char **argv, char **envp)
1531 /* turn all optimizations off by default */
1532 memset (&optimize, 0, sizeof (struct optimize));
1534 /*printVersionInfo (); */
1537 fprintf (stderr, "Build error: no ports are enabled.\n");
1541 _findPort (argc, argv);
1542 /* Initalise the port. */
1546 // Create a default exe search path from the path to the sdcc command
1550 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1552 strcpy (DefaultExePath, argv[0]);
1553 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1554 try_dir[0] = DefaultExePath;
1558 setDefaultOptions ();
1559 parseCmdLine (argc, argv);
1563 port->finaliseOptions ();
1565 /* if no input then printUsage & exit */
1566 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1581 if (options.verbose)
1582 printf ("sdcc: Generating code...\n");
1588 if (TARGET_IS_PIC) {
1589 /* TSD PIC port hack - if the PIC port option is enabled
1590 and SDCC is used to generate PIC code, then we will
1591 generate .asm files in gpasm's format instead of SDCC's
1602 if (!options.c1mode)
1604 if (options.verbose)
1605 printf ("sdcc: Calling assembler...\n");
1619 if (!options.cc_only &&
1623 (srcFileName || nrelFiles))
1625 if (port->linker.do_link)
1626 port->linker.do_link ();
1631 if (yyin && yyin != stdin)
1634 if (preOutName && !options.c1mode)
1636 unlink (preOutName);