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", "-I" SDCC_INCLUDE_DIR, "$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 pic14glue ();
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);
286 fprintf (stderr, " %s"
287 #ifdef SDCC_SUB_VERSION_STR
288 "/" 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 if (_setPort (argv[i] + 2))
1039 werror (W_UNSUPP_OPTION, "-m", "Unrecognised processor");
1044 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
1048 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
1051 case 'X': /* use external stack */
1052 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
1056 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
1059 case 'p': /* stack pointer intial value */
1061 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
1065 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
1069 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
1073 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1077 options.cc_only = 1;
1081 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1086 libPaths[nlibPaths++] = &argv[i][2];
1088 libPaths[nlibPaths++] = argv[++i];
1092 /* linker options */
1093 if (argv[i][2] == 'l')
1096 parseWithComma (linkOptions, &argv[i][3]);
1098 parseWithComma (linkOptions, argv[++i]);
1102 /* assembler options */
1103 if (argv[i][2] == 'a')
1106 parseWithComma ((char **) asmOptions, &argv[i][3]);
1108 parseWithComma ((char **) asmOptions, argv[++i]);
1113 werror (W_UNKNOWN_OPTION, argv[i]);
1126 printVersionInfo ();
1130 /* preprocessor options */
1134 _addToList (preArgv, "-M");
1139 _addToList (preArgv, "-C");
1148 char sOpt = argv[i][1];
1151 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1159 if (argv[i][1] == 'Y')
1162 sprintf (buffer, "-%c%s", sOpt, rest);
1163 _addToList (preArgv, buffer);
1168 if (!port->parseOption (&argc, argv, &i))
1169 werror (W_UNKNOWN_OPTION, argv[i]);
1174 if (!port->parseOption (&argc, argv, &i))
1176 /* no option must be a filename */
1178 _processC1Arg (argv[i]);
1180 processFile (argv[i]);
1184 /* set up external stack location if not explicitly specified */
1185 if (!options.xstack_loc)
1186 options.xstack_loc = options.xdata_loc;
1188 /* if debug option is set the open the cdbFile */
1189 if (!options.nodebug && srcFileName)
1191 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1192 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1193 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1196 /* add a module record */
1197 fprintf (cdbFile, "M:%s\n", moduleName);
1203 /*-----------------------------------------------------------------*/
1204 /* my_system - will call a program with arguments */
1205 /*-----------------------------------------------------------------*/
1210 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1212 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1216 my_system (const char *cmd)
1218 int argsStart, e, i = 0;
1219 char *cmdLine = NULL;
1221 argsStart = strstr (cmd, " ") - cmd;
1223 // try to find the command in predefined path's
1226 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1227 strcpy (cmdLine, try_dir[i]); // the path
1229 strcat (cmdLine, DIR_SEPARATOR_STRING);
1230 strncat (cmdLine, cmd, argsStart); // the command
1233 strcat (cmdLine, ".exe");
1236 if (access (cmdLine, X_OK) == 0)
1239 strcat (cmdLine, cmd + argsStart);
1249 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1254 // command found in predefined path
1255 e = system (cmdLine);
1267 /*-----------------------------------------------------------------*/
1268 /* linkEdit : - calls the linkage editor with options */
1269 /*-----------------------------------------------------------------*/
1271 linkEdit (char **envp)
1278 srcFileName = "temp";
1280 /* first we need to create the <filename>.lnk file */
1281 sprintf (buffer, "%s.lnk", srcFileName);
1282 if (!(lnkfile = fopen (buffer, "w")))
1284 werror (E_FILE_OPEN_ERR, buffer);
1288 /* now write the options */
1289 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1291 /* if iram size specified */
1292 if (options.iram_size)
1293 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1295 /*if (options.debug) */
1296 fprintf (lnkfile, "-z\n");
1298 #define WRITE_SEG_LOC(N, L) \
1299 segName = strdup(N); \
1300 c = strtok(segName, " \t"); \
1301 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1302 if (segName) { free(segName); }
1304 /* code segment start */
1305 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1307 /* data segment start */
1308 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1311 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1314 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1316 /* bit segment start */
1317 WRITE_SEG_LOC (BIT_NAME, 0);
1319 /* add the extra linker options */
1320 for (i = 0; linkOptions[i]; i++)
1321 fprintf (lnkfile, "%s\n", linkOptions[i]);
1323 /* other library paths if specified */
1324 for (i = 0; i < nlibPaths; i++)
1325 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1327 /* standard library path */
1328 if (!options.nostdlib)
1336 switch (options.model)
1348 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1353 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1355 /* standard library files */
1356 if (strcmp (port->target, "ds390") == 0)
1358 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1360 fprintf (lnkfile, "-l %s\n", STD_LIB);
1361 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1362 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1363 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1366 /* additional libraries if any */
1367 for (i = 0; i < nlibFiles; i++)
1368 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1370 /* put in the object files */
1371 if (strcmp (srcFileName, "temp"))
1372 fprintf (lnkfile, "%s ", srcFileName);
1374 for (i = 0; i < nrelFiles; i++)
1375 fprintf (lnkfile, "%s\n", relFiles[i]);
1377 fprintf (lnkfile, "\n-e\n");
1380 if (options.verbose)
1381 printf ("sdcc: Calling linker...\n");
1383 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1384 if (my_system (buffer))
1389 if (strcmp (srcFileName, "temp") == 0)
1391 /* rename "temp.cdb" to "firstRelFile.cdb" */
1392 char *f = strtok (strdup (relFiles[0]), ".");
1393 f = strcat (f, ".cdb");
1394 rename ("temp.cdb", f);
1399 /*-----------------------------------------------------------------*/
1400 /* assemble - spawns the assembler with arguments */
1401 /*-----------------------------------------------------------------*/
1403 assemble (char **envp)
1405 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1406 if (my_system (buffer))
1408 /* either system() or the assembler itself has reported an error
1409 perror ("Cannot exec assembler");
1417 /*-----------------------------------------------------------------*/
1418 /* preProcess - spawns the preprocessor with arguments */
1419 /*-----------------------------------------------------------------*/
1421 preProcess (char **envp)
1427 if (!options.c1mode)
1429 /* if using external stack define the macro */
1430 if (options.useXstack)
1431 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1433 /* set the macro for stack autos */
1434 if (options.stackAuto)
1435 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1437 /* set the macro for stack autos */
1438 if (options.stack10bit)
1439 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1441 /* set the macro for large model */
1442 switch (options.model)
1445 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1448 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1451 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1454 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1457 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1460 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1465 /* add port (processor information to processor */
1466 sprintf (procDef, "-DSDCC_%s", port->target);
1467 _addToList (preArgv, procDef);
1468 sprintf (procDef, "-D__%s", port->target);
1469 _addToList (preArgv, procDef);
1472 preOutName = strdup (tmpnam (NULL));
1474 if (options.verbose)
1475 printf ("sdcc: Calling preprocessor...\n");
1477 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1478 preOutName, srcFileName, preArgv);
1479 if (my_system (buffer))
1489 preOutName = fullSrcFileName;
1492 yyin = fopen (preOutName, "r");
1495 perror ("Preproc file not found\n");
1503 _findPort (int argc, char **argv)
1510 if (!strncmp (*argv, "-m", 2))
1512 _setPort (*argv + 2);
1518 /* Use the first in the list */
1524 * initialises and calls the parser
1528 main (int argc, char **argv, char **envp)
1530 /* turn all optimizations off by default */
1531 memset (&optimize, 0, sizeof (struct optimize));
1533 /*printVersionInfo (); */
1535 _findPort (argc, argv);
1536 /* Initalise the port. */
1540 // Create a default exe search path from the path to the sdcc command
1544 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1546 strcpy (DefaultExePath, argv[0]);
1547 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1548 try_dir[0] = DefaultExePath;
1552 setDefaultOptions ();
1553 parseCmdLine (argc, argv);
1557 port->finaliseOptions ();
1559 /* if no input then printUsage & exit */
1560 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1575 if (options.verbose)
1576 printf ("sdcc: Generating code...\n");
1583 /* TSD PIC port hack - if the PIC port option is enabled
1584 and SDCC is used to generate PIC code, then we will
1585 generate .asm files in gpasm's format instead of SDCC's
1595 if (!options.c1mode)
1597 if (options.verbose)
1598 printf ("sdcc: Calling assembler...\n");
1612 if (!options.cc_only &&
1616 (srcFileName || nrelFiles))
1618 if (port->linker.do_link)
1619 port->linker.do_link ();
1624 if (yyin && yyin != stdin)
1627 if (preOutName && !options.c1mode)
1629 unlink (preOutName);