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 -------------------------------------------------------------------------*/
34 // This is a bit messy because we define link ourself
40 // No unistd.h in Borland C++
41 extern int access(const char *, int);
48 FILE *srcFile ;/* source file */
49 FILE *cdbFile = NULL ;/* debugger information output file */
50 char *fullSrcFileName ;/* full name for the source file */
51 char *srcFileName ;/* source file name with the .c stripped */
52 char *moduleName ;/* module name is srcFilename stripped of any path */
53 const char *preArgv[128] ;/* pre-processor arguments */
55 struct optimize optimize ;
56 struct options options ;
57 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
58 short preProcOnly = 0;
60 char *linkOptions[128];
61 const char *asmOptions[128];
68 bool verboseExec = FALSE;
71 /* Far functions, far data */
72 #define OPTION_LARGE_MODEL "-model-large"
73 /* Far functions, near data */
74 #define OPTION_MEDIUM_MODEL "-model-medium"
75 #define OPTION_SMALL_MODEL "-model-small"
76 #define OPTION_FLAT24_MODEL "-model-flat24"
77 #define OPTION_STACK_AUTO "-stack-auto"
78 #define OPTION_STACK_10BIT "-stack-10bit"
79 #define OPTION_XSTACK "-xstack"
80 #define OPTION_GENERIC "-generic"
81 #define OPTION_NO_GCSE "-nogcse"
82 #define OPTION_NO_LOOP_INV "-noinvariant"
83 #define OPTION_NO_LOOP_IND "-noinduction"
84 #define OPTION_NO_JTBOUND "-nojtbound"
85 #define OPTION_NO_LOOPREV "-noloopreverse"
86 #define OPTION_XREGS "-regextend"
87 #define OPTION_COMP_ONLY "-compile-only"
88 #define OPTION_DUMP_RAW "-dumpraw"
89 #define OPTION_DUMP_GCSE "-dumpgcse"
90 #define OPTION_DUMP_LOOP "-dumploop"
91 #define OPTION_DUMP_KILL "-dumpdeadcode"
92 #define OPTION_DUMP_RANGE "-dumpliverange"
93 #define OPTION_DUMP_PACK "-dumpregpack"
94 #define OPTION_DUMP_RASSGN "-dumpregassign"
95 #define OPTION_DUMP_ALL "-dumpall"
96 #define OPTION_XRAM_LOC "-xram-loc"
97 #define OPTION_IRAM_SIZE "-iram-size"
98 #define OPTION_XSTACK_LOC "-xstack-loc"
99 #define OPTION_CODE_LOC "-code-loc"
100 #define OPTION_STACK_LOC "-stack-loc"
101 #define OPTION_DATA_LOC "-data-loc"
102 #define OPTION_IDATA_LOC "-idata-loc"
103 #define OPTION_PEEP_FILE "-peep-file"
104 #define OPTION_LIB_PATH "-lib-path"
105 #define OPTION_INTLONG_RENT "-int-long-reent"
106 #define OPTION_FLOAT_RENT "-float-reent"
107 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
108 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
109 #define OPTION_CYCLOMATIC "-cyclomatic"
110 #define OPTION_NOOVERLAY "-nooverlay"
111 #define OPTION_MAINRETURN "-main-return"
112 #define OPTION_NOPEEP "-no-peep"
113 #define OPTION_ASMPEEP "-peep-asm"
114 #define OPTION_DEBUG "-debug"
115 #define OPTION_NODEBUG "-nodebug"
116 #define OPTION_VERSION "-version"
117 #define OPTION_STKAFTRDATA "-stack-after-data"
118 #define OPTION_PREPROC_ONLY "-preprocessonly"
119 #define OPTION_C1_MODE "-c1mode"
120 #define OPTION_HELP "-help"
121 #define OPTION_CALLEE_SAVES "-callee-saves"
122 #define OPTION_NOREGPARMS "-noregparms"
123 #define OPTION_NOSTDLIB "-nostdlib"
124 #define OPTION_NOSTDINC "-nostdinc"
125 #define OPTION_VERBOSE "-verbose"
126 static const char *_preCmd[] = {
127 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
128 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
133 static PORT *_ports[] = {
134 #if !OPT_DISABLE_MCS51
137 #if !OPT_DISABLE_GBZ80
146 #if !OPT_DISABLE_DS390
151 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
153 /** Sets the port to the one given by the command line option.
154 @param The name minus the option (eg 'mcs51')
155 @return 0 on success.
157 static int _setPort(const char *name)
160 for (i=0; i<NUM_PORTS; i++) {
161 if (!strcmp(_ports[i]->target, name)) {
166 /* Error - didnt find */
167 werror(E_UNKNOWN_TARGET,name);
171 void buildCmdLine(char *into, char **args, const char **cmds,
172 const char *p1, const char *p2,
173 const char *p3, const char **list)
175 const char *p, *from;
185 /* See if it has a '$' anywhere - if not, just copy */
186 if ((p = strchr(from, '$'))) {
187 strncpy(into, from, p - from);
188 /* NULL terminate it */
206 const char **tmp = list;
210 into += strlen(into)+1;
223 if (strlen(into) == 0)
225 into += strlen(into)+1;
230 /*-----------------------------------------------------------------*/
231 /* printVersionInfo - prints the version info */
232 /*-----------------------------------------------------------------*/
233 void printVersionInfo ()
239 for (i=0; i<NUM_PORTS; i++)
240 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
241 fprintf(stderr, " %s"
242 #ifdef SDCC_SUB_VERSION_STR
243 "/" SDCC_SUB_VERSION_STR
260 /*-----------------------------------------------------------------*/
261 /* printUsage - prints command line syntax */
262 /*-----------------------------------------------------------------*/
267 "Usage : [options] filename\n"
269 "\t-m<proc> - Target processor <proc>. Default %s\n"
270 "\t Try --version for supported values of <proc>\n"
271 "\t--model-large - Large Model\n"
272 "\t--model-small - Small Model (default)\n"
273 "\t--stack-auto - Stack automatic variables\n"
274 "\t--xstack - Use external stack\n"
275 "\t--xram-loc <nnnn> - External Ram start location\n"
276 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
277 "\t--code-loc <nnnn> - Code Segment Location\n"
278 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
279 "\t--data-loc <nnnn> - Direct data start location\n"
280 "\t--idata-loc <nnnn> - Indirect data start location\n"
281 "\t--iram-size <nnnn> - Internal Ram size\n"
282 "\t--nojtbound - Don't generate boundary check for jump tables\n"
283 "\t--generic - All unqualified ptrs converted to '_generic'\n"
284 "PreProcessor Options :-\n"
285 "\t-Dmacro - Define Macro\n"
286 "\t-Ipath - Include \"*.h\" path\n"
287 "Note: this is NOT a complete list of options see docs for details\n",
293 /*-----------------------------------------------------------------*/
294 /* parseWithComma - separates string with comma */
295 /*-----------------------------------------------------------------*/
296 void parseWithComma (char **dest,char *src)
301 /* skip the initial white spaces */
302 while (isspace(*src)) src++;
316 /*-----------------------------------------------------------------*/
317 /* setDefaultOptions - sets the default options */
318 /*-----------------------------------------------------------------*/
319 static void setDefaultOptions()
323 for ( i = 0 ; i < 128 ; i++)
324 preArgv[i] = asmOptions [i] =
325 linkOptions[i] = relFiles[i] = libFiles[i] =
328 /* first the options part */
329 options.stack_loc = 0; /* stack pointer initialised to 0 */
330 options.xstack_loc= 0; /* xternal stack starts at 0 */
331 options.code_loc = 0; /* code starts at 0 */
332 options.data_loc = 0x0030; /* data starts at 0x0030 */
333 options.xdata_loc = 0;
334 options.idata_loc = 0x80;
335 options.genericPtr = 1; /* default on */
337 options.model = port->general.default_model;
342 /* now for the optimizations */
343 /* turn on the everything */
344 optimize.global_cse = 1;
349 optimize.loopInvariant = 1;
350 optimize.loopInduction = 1;
352 port->setDefaultOptions();
355 /*-----------------------------------------------------------------*/
356 /* processFile - determines the type of file from the extension */
357 /*-----------------------------------------------------------------*/
358 static void processFile (char *s)
362 /* get the file extension */
363 fext = s + strlen(s);
364 while ((fext != s) && *fext != '.') fext--;
366 /* now if no '.' then we don't know what the file type is
367 so give a warning and return */
369 werror(W_UNKNOWN_FEXT,s);
373 /* otherwise depending on the file type */
374 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
375 /* source file name : not if we already have a
378 werror(W_TOO_MANY_SRC,s);
382 /* the only source file */
383 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
384 werror(E_FILE_OPEN_ERR,s);
388 /* copy the file name into the buffer */
391 /* get rid of the "." */
393 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
394 strcpy(srcFileName,buffer);
396 /* get rid of any path information
397 for the module name; do this by going
398 backwards till we get to either '/' or '\' or ':'
399 or start of buffer */
400 fext = buffer + strlen(buffer);
401 while (fext != buffer &&
402 *(fext -1) != '\\' &&
406 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
407 strcpy(moduleName,fext);
412 /* if the extention is type .rel or .r or .REL or .R
413 addtional object file will be passed to the linker */
414 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
415 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
416 strcmp(fext, port->linker.rel_ext) == 0)
418 relFiles[nrelFiles++] = s;
422 /* if .lib or .LIB */
423 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
424 libFiles[nlibFiles++] = s;
428 werror(W_UNKNOWN_FEXT,s);
432 static void _processC1Arg(char *s)
435 if (options.out_name) {
436 werror(W_TOO_MANY_SRC,s);
439 options.out_name = strdup(s);
446 static void _addToList(const char **list, const char *str)
448 /* This is the bad way to do things :) */
453 werror(E_OUT_OF_MEM,__FILE__, 0);
459 static void _setModel(int model, const char *sz)
461 if (port->general.supported_models & model)
462 options.model = model;
464 werror(W_UNSUPPORTED_MODEL, sz, port->target);
467 /*-----------------------------------------------------------------*/
468 /* parseCmdLine - parses the command line and sets the options */
469 /*-----------------------------------------------------------------*/
470 int parseCmdLine ( int argc, char **argv )
475 /* go thru all whole command line */
476 for ( i = 1; i < argc; i++ ) {
481 if (argv[i][0] == '-' && argv[i][1] == '-') {
483 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
488 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
489 options.regExtend = 1;
493 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
494 _setModel(MODEL_LARGE, argv[i]);
498 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
499 _setModel(MODEL_MEDIUM, argv[i]);
503 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
504 _setModel(MODEL_SMALL, argv[i]);
508 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
509 _setModel(MODEL_FLAT24, argv[i]);
513 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
514 options.stack10bit = 1;
518 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
519 options.stackAuto = 1;
523 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
524 options.dump_raw = 1;
528 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
529 options.cyclomatic = 1;
533 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
534 options.dump_gcse = 1;
538 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
539 options.dump_loop = 1;
543 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
544 options.dump_kill = 1;
548 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
549 options.intlong_rent = 1;
553 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
554 options.float_rent = 1;
558 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
559 options.dump_range = 1;
563 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
564 options.dump_pack = 1;
568 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
569 options.dump_rassgn = 1;
573 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
578 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
583 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
584 options.noOverlay = 1;
588 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
589 options.stackOnData = 1;
593 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
598 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
604 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
605 options.dump_rassgn =
611 options.dump_raw = 1;
615 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
620 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
621 options.genericPtr = 1;
625 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
630 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
635 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
640 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
645 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
646 options.noregparms = 1;
650 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
651 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
653 &argv[i][1+strlen(OPTION_PEEP_FILE)];
655 options.peep_file = argv[++i];
659 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
660 if (argv[i][1+strlen(OPTION_LIB_PATH)])
661 libPaths[nlibPaths++] =
662 &argv[i][1+strlen(OPTION_PEEP_FILE)];
664 libPaths[nlibPaths++] = argv[++i];
668 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
670 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
672 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
675 (int) floatFromVal(constVal(argv[++i]));
679 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
680 options.useXstack = 1;
684 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
685 options.mainreturn = 1;
689 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
690 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
691 parseWithComma(options.calleeSaves
692 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
694 parseWithComma(options.calleeSaves,argv[++i]);
698 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
700 if (argv[i][1+strlen(OPTION_STACK_LOC)])
702 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
705 (int) floatFromVal(constVal(argv[++i]));
709 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
711 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
713 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
716 (unsigned int) floatFromVal(constVal(argv[++i]));
720 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
722 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
724 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
727 (int) floatFromVal(constVal(argv[++i]));
731 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
737 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
739 if (argv[i][1+strlen(OPTION_DATA_LOC)])
741 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
744 (int) floatFromVal(constVal(argv[++i]));
748 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
750 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
752 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
755 (int) floatFromVal(constVal(argv[++i]));
759 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
761 if (argv[i][1+strlen(OPTION_CODE_LOC)])
763 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
766 (int) floatFromVal(constVal(argv[++i]));
771 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
772 optimize.noJTabBoundary = 1;
776 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
777 optimize.global_cse = 0;
781 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
782 optimize.loopInvariant = 0;
786 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
787 optimize.loopInduction = 0;
791 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
792 optimize.noLoopReverse = 1;
796 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
801 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
806 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
811 if (!port->parseOption(&argc, argv, &i))
813 werror(W_UNKNOWN_OPTION,argv[i]);
821 /* these are undocumented options */
822 /* if preceded by '/' then turn off certain optmizations, used
823 for debugging only these are also the legacy options from
824 version 1.xx will be removed gradually.
825 It may be an absolute filename.
827 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
828 switch (argv[i][1]) {
831 optimize.ptrArithmetic=0;
835 switch (argv[i][2]) {
840 optimize.label4 = 0 ;
858 switch (argv[i][2]) {
860 optimize.loopInvariant = 0;
863 optimize.loopInduction = 0;
870 optimize.global_cse = 0;
877 /* if preceded by '-' then option */
878 if ( *argv[i] == '-' ) {
879 switch (argv[i][1]) {
890 /* Used to select the port */
891 if (_setPort(argv[i] + 2)) {
892 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
897 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
901 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
904 case 'X' : /* use external stack */
905 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
909 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
912 case 'p' : /* stack pointer intial value */
914 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
918 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
922 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
926 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
934 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
939 libPaths[nlibPaths++] = &argv[i][2];
941 libPaths[nlibPaths++] = argv[++i];
946 if (argv[i][2] == 'l') {
948 parseWithComma(linkOptions,&argv[i][3]);
950 parseWithComma(linkOptions,argv[++i]);
952 /* assembler options */
953 if (argv[i][2] == 'a') {
955 parseWithComma((char **)asmOptions,&argv[i][3]);
957 parseWithComma((char **)asmOptions,argv[++i]);
960 werror(W_UNKNOWN_OPTION,argv[i]);
977 /* preprocessor options */
981 _addToList(preArgv, "-M");
986 _addToList(preArgv, "-C");
995 char sOpt = argv[i][1] ;
998 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1003 rest = &argv[i][2] ;
1005 if ( argv[i][1] == 'Y' )
1008 sprintf(buffer, "-%c%s", sOpt, rest);
1009 _addToList(preArgv, buffer);
1014 if (!port->parseOption(&argc, argv, &i))
1015 werror(W_UNKNOWN_OPTION,argv[i]);
1020 if (!port->parseOption(&argc, argv, &i)) {
1021 /* no option must be a filename */
1023 _processC1Arg(argv[i]);
1025 processFile(argv[i]);
1029 /* set up external stack location if not explicitly specified */
1030 if ( !options.xstack_loc )
1031 options.xstack_loc = options.xdata_loc ;
1033 /* if debug option is set the open the cdbFile */
1034 if (!options.nodebug && srcFileName) {
1035 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1036 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1037 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1039 /* add a module record */
1040 fprintf(cdbFile,"M:%s\n",moduleName);
1046 /*-----------------------------------------------------------------*/
1047 /* my_system - will call a program with arguments */
1048 /*-----------------------------------------------------------------*/
1049 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1050 int my_system (const char *cmd, char **cmd_argv)
1052 char *dir, *got= NULL; int i= 0;
1054 while (!got && try_dir[i])
1056 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1057 strcpy(dir, try_dir[i]);
1062 strcat(dir, ".exe");
1064 /* Mung slashes into backslashes to keep WIndoze happy. */
1080 if (access(dir, X_OK) == 0)
1089 char **pCmd = cmd_argv;
1092 printf("%s ", *pCmd);
1099 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1101 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1103 perror("Cannot exec process ");
1110 /*-----------------------------------------------------------------*/
1111 /* linkEdit : - calls the linkage editor with options */
1112 /*-----------------------------------------------------------------*/
1113 static void linkEdit (char **envp)
1121 srcFileName = "temp";
1123 /* first we need to create the <filename>.lnk file */
1124 sprintf(buffer,"%s.lnk",srcFileName);
1125 if (!(lnkfile = fopen(buffer,"w"))) {
1126 werror(E_FILE_OPEN_ERR,buffer);
1130 /* now write the options */
1131 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1133 /* if iram size specified */
1134 if (options.iram_size)
1135 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1137 /*if (options.debug) */
1138 fprintf(lnkfile,"-z\n");
1140 #define WRITE_SEG_LOC(N, L) \
1141 segName = strdup(N); \
1142 c = strtok(segName, " \t"); \
1143 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1144 if (segName) { free(segName); }
1146 /* code segment start */
1147 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1149 /* data segment start */
1150 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1153 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1156 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1158 /* bit segment start */
1159 WRITE_SEG_LOC(BIT_NAME, 0);
1161 /* add the extra linker options */
1162 for (i=0; linkOptions[i] ; i++)
1163 fprintf(lnkfile,"%s\n",linkOptions[i]);
1165 /* other library paths if specified */
1166 for (i = 0 ; i < nlibPaths ; i++ )
1167 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1169 /* standard library path */
1170 if (!options.nostdlib) {
1171 if (IS_DS390_PORT) {
1174 switch(options.model)
1186 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1191 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1193 /* standard library files */
1194 if (strcmp(port->target, "ds390")==0) {
1195 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1197 fprintf (lnkfile,"-l %s\n",STD_LIB);
1198 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1199 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1200 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1203 /* additional libraries if any */
1204 for (i = 0 ; i < nlibFiles; i++)
1205 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1207 /* put in the object files */
1208 if (strcmp(srcFileName,"temp"))
1209 fprintf (lnkfile,"%s ",srcFileName);
1211 for (i = 0 ; i < nrelFiles ; i++ )
1212 fprintf (lnkfile,"%s\n",relFiles[i]);
1214 fprintf (lnkfile,"\n-e\n");
1217 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1219 if (options.verbose)
1220 printf ("sdcc: Calling linker...\n");
1221 if (my_system(argv[0], argv)) {
1222 perror("Cannot exec linker");
1226 if (strcmp(srcFileName,"temp") == 0) {
1227 /* rename "temp.cdb" to "firstRelFile.cdb" */
1228 char *f = strtok(strdup(relFiles[0]),".");
1229 f = strcat(f,".cdb");
1230 rename("temp.cdb",f);
1235 /*-----------------------------------------------------------------*/
1236 /* assemble - spawns the assembler with arguments */
1237 /*-----------------------------------------------------------------*/
1238 static void assemble (char **envp)
1240 char *argv[128]; /* assembler arguments */
1242 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1244 if (my_system(argv[0], argv)) {
1245 perror("Cannot exec assember");
1252 /*-----------------------------------------------------------------*/
1253 /* preProcess - spawns the preprocessor with arguments */
1254 /*-----------------------------------------------------------------*/
1255 static int preProcess (char **envp)
1262 if (!options.c1mode) {
1263 /* if using external stack define the macro */
1264 if ( options.useXstack )
1265 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1267 /* set the macro for stack autos */
1268 if ( options.stackAuto )
1269 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1271 /* set the macro for stack autos */
1272 if ( options.stack10bit )
1273 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1275 /* set the macro for large model */
1276 switch(options.model)
1279 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1282 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1285 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1288 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1291 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1294 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1299 /* add port (processor information to processor */
1300 sprintf(procDef,"-DSDCC_%s",port->target);
1301 _addToList(preArgv,procDef);
1304 preOutName = strdup(tmpnam(NULL));
1306 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1307 preOutName, srcFileName, preArgv);
1309 if (options.verbose)
1310 printf ("sdcc: Calling preprocessor...\n");
1312 if (my_system(argv[0], argv)) {
1313 unlink (preOutName);
1314 perror("Cannot exec Preprocessor");
1322 preOutName = fullSrcFileName;
1325 yyin = fopen(preOutName, "r");
1327 perror("Preproc file not found\n");
1334 static void _findPort(int argc, char **argv)
1338 if (!strncmp(*argv, "-m", 2)) {
1339 _setPort(*argv + 2);
1345 /* Use the first in the list */
1351 * initialises and calls the parser
1354 int main ( int argc, char **argv , char **envp)
1356 /* turn all optimizations off by default */
1357 memset(&optimize,0,sizeof(struct optimize));
1359 /*printVersionInfo ();*/
1361 _findPort(argc, argv);
1362 /* Initalise the port. */
1366 setDefaultOptions();
1367 parseCmdLine(argc,argv);
1371 port->finaliseOptions();
1373 /* if no input then printUsage & exit */
1374 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1387 if (options.verbose)
1388 printf ("sdcc: Generating code...\n");
1399 if (!options.c1mode)
1401 if (options.verbose)
1402 printf ("sdcc: Calling assembler...\n");
1417 if (!options.cc_only &&
1421 (srcFileName || nrelFiles)) {
1422 if (port->linker.do_link)
1423 port->linker.do_link();
1428 if (yyin && yyin != stdin)
1431 if (preOutName && !options.c1mode) {