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 -------------------------------------------------------------------------*/
25 //#define USE_SYSTEM_SYSTEM_CALLS
38 // This is a bit messy because we define link ourself
39 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
44 // No unistd.h in Borland C++
45 extern int access(const char *, int);
53 FILE *srcFile ;/* source file */
54 FILE *cdbFile = NULL ;/* debugger information output file */
55 char *fullSrcFileName ;/* full name for the source file */
56 char *srcFileName ;/* source file name with the .c stripped */
57 char *moduleName ;/* module name is srcFilename stripped of any path */
58 const char *preArgv[128] ;/* pre-processor arguments */
60 struct optimize optimize ;
61 struct options options ;
62 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
63 short preProcOnly = 0;
65 char *linkOptions[128];
66 const char *asmOptions[128];
73 bool verboseExec = FALSE;
76 // In MSC VC6 default search path for exe's to path for this
80 char DefaultExePath[_MAX_PATH] ;
84 /* Far functions, far data */
85 #define OPTION_LARGE_MODEL "-model-large"
86 /* Far functions, near data */
87 #define OPTION_MEDIUM_MODEL "-model-medium"
88 #define OPTION_SMALL_MODEL "-model-small"
89 #define OPTION_FLAT24_MODEL "-model-flat24"
90 #define OPTION_STACK_AUTO "-stack-auto"
91 #define OPTION_STACK_10BIT "-stack-10bit"
92 #define OPTION_XSTACK "-xstack"
93 #define OPTION_GENERIC "-generic"
94 #define OPTION_NO_GCSE "-nogcse"
95 #define OPTION_NO_LOOP_INV "-noinvariant"
96 #define OPTION_NO_LOOP_IND "-noinduction"
97 #define OPTION_NO_JTBOUND "-nojtbound"
98 #define OPTION_NO_LOOPREV "-noloopreverse"
99 #define OPTION_XREGS "-regextend"
100 #define OPTION_COMP_ONLY "-compile-only"
101 #define OPTION_DUMP_RAW "-dumpraw"
102 #define OPTION_DUMP_GCSE "-dumpgcse"
103 #define OPTION_DUMP_LOOP "-dumploop"
104 #define OPTION_DUMP_KILL "-dumpdeadcode"
105 #define OPTION_DUMP_RANGE "-dumpliverange"
106 #define OPTION_DUMP_PACK "-dumpregpack"
107 #define OPTION_DUMP_RASSGN "-dumpregassign"
108 #define OPTION_DUMP_ALL "-dumpall"
109 #define OPTION_XRAM_LOC "-xram-loc"
110 #define OPTION_IRAM_SIZE "-iram-size"
111 #define OPTION_XSTACK_LOC "-xstack-loc"
112 #define OPTION_CODE_LOC "-code-loc"
113 #define OPTION_STACK_LOC "-stack-loc"
114 #define OPTION_DATA_LOC "-data-loc"
115 #define OPTION_IDATA_LOC "-idata-loc"
116 #define OPTION_PEEP_FILE "-peep-file"
117 #define OPTION_LIB_PATH "-lib-path"
118 #define OPTION_INTLONG_RENT "-int-long-reent"
119 #define OPTION_FLOAT_RENT "-float-reent"
120 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
121 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
122 #define OPTION_CYCLOMATIC "-cyclomatic"
123 #define OPTION_NOOVERLAY "-nooverlay"
124 #define OPTION_MAINRETURN "-main-return"
125 #define OPTION_NOPEEP "-no-peep"
126 #define OPTION_ASMPEEP "-peep-asm"
127 #define OPTION_DEBUG "-debug"
128 #define OPTION_NODEBUG "-nodebug"
129 #define OPTION_VERSION "-version"
130 #define OPTION_STKAFTRDATA "-stack-after-data"
131 #define OPTION_PREPROC_ONLY "-preprocessonly"
132 #define OPTION_C1_MODE "-c1mode"
133 #define OPTION_HELP "-help"
134 #define OPTION_CALLEE_SAVES "-callee-saves"
135 #define OPTION_NOREGPARMS "-noregparms"
136 #define OPTION_NOSTDLIB "-nostdlib"
137 #define OPTION_NOSTDINC "-nostdinc"
138 #define OPTION_VERBOSE "-verbose"
139 #define OPTION_ANSIINT "-ansiint"
140 static const char *_preCmd[] = {
141 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
142 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
147 static PORT *_ports[] = {
148 #if !OPT_DISABLE_MCS51
151 #if !OPT_DISABLE_GBZ80
160 #if !OPT_DISABLE_DS390
166 #if !OPT_DISABLE_I186
169 #if !OPT_DISABLE_TLCS900H
174 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
177 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
179 extern void pic14glue();
181 /** Sets the port to the one given by the command line option.
182 @param The name minus the option (eg 'mcs51')
183 @return 0 on success.
185 static int _setPort(const char *name)
188 for (i=0; i<NUM_PORTS; i++) {
189 if (!strcmp(_ports[i]->target, name)) {
194 /* Error - didnt find */
195 werror(E_UNKNOWN_TARGET,name);
199 static void _validatePorts(void)
202 for (i=0; i<NUM_PORTS; i++) {
203 if (_ports[i]->magic != PORT_MAGIC) {
204 printf("Error: port %s is incomplete.\n", _ports[i]->target);
210 #ifdef USE_SYSTEM_SYSTEM_CALLS
211 void buildCmdLine(char *into, const char **cmds,
212 const char *p1, const char *p2,
213 const char *p3, const char **list)
215 const char *p, *from;
224 /* See if it has a '$' anywhere - if not, just copy */
225 if ((p = strchr(from, '$'))) {
226 strncat(into, from, p - from);
245 const char **tmp = list;
259 strcat(into, from); // this includes the ".asm" from "$1.asm"
264 void buildCmdLine(char *into, char **args, const char **cmds,
265 const char *p1, const char *p2,
266 const char *p3, const char **list)
268 const char *p, *from;
278 /* See if it has a '$' anywhere - if not, just copy */
279 if ((p = strchr(from, '$'))) {
280 strncpy(into, from, p - from);
281 /* NULL terminate it */
299 const char **tmp = list;
303 into += strlen(into)+1;
316 if (strlen(into) == 0)
318 into += strlen(into)+1;
324 /*-----------------------------------------------------------------*/
325 /* printVersionInfo - prints the version info */
326 /*-----------------------------------------------------------------*/
327 void printVersionInfo ()
333 for (i=0; i<NUM_PORTS; i++)
334 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
335 fprintf(stderr, " %s"
336 #ifdef SDCC_SUB_VERSION_STR
337 "/" SDCC_SUB_VERSION_STR
354 /*-----------------------------------------------------------------*/
355 /* printUsage - prints command line syntax */
356 /*-----------------------------------------------------------------*/
361 "Usage : [options] filename\n"
363 "\t-m<proc> - Target processor <proc>. Default %s\n"
364 "\t Try --version for supported values of <proc>\n"
365 "\t--model-large - Large Model\n"
366 "\t--model-small - Small Model (default)\n"
367 "\t--stack-auto - Stack automatic variables\n"
368 "\t--xstack - Use external stack\n"
369 "\t--xram-loc <nnnn> - External Ram start location\n"
370 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
371 "\t--code-loc <nnnn> - Code Segment Location\n"
372 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
373 "\t--data-loc <nnnn> - Direct data start location\n"
374 "\t--idata-loc <nnnn> - Indirect data start location\n"
375 "\t--iram-size <nnnn> - Internal Ram size\n"
376 "\t--nojtbound - Don't generate boundary check for jump tables\n"
377 "\t--generic - All unqualified ptrs converted to '_generic'\n"
378 "PreProcessor Options :-\n"
379 "\t-Dmacro - Define Macro\n"
380 "\t-Ipath - Include \"*.h\" path\n"
381 "Note: this is NOT a complete list of options see docs for details\n",
387 /*-----------------------------------------------------------------*/
388 /* parseWithComma - separates string with comma */
389 /*-----------------------------------------------------------------*/
390 void parseWithComma (char **dest,char *src)
395 /* skip the initial white spaces */
396 while (isspace(*src)) src++;
410 /*-----------------------------------------------------------------*/
411 /* setDefaultOptions - sets the default options */
412 /*-----------------------------------------------------------------*/
413 static void setDefaultOptions()
417 for ( i = 0 ; i < 128 ; i++)
418 preArgv[i] = asmOptions [i] =
419 linkOptions[i] = relFiles[i] = libFiles[i] =
422 /* first the options part */
423 options.stack_loc = 0; /* stack pointer initialised to 0 */
424 options.xstack_loc= 0; /* xternal stack starts at 0 */
425 options.code_loc = 0; /* code starts at 0 */
426 options.data_loc = 0x0030; /* data starts at 0x0030 */
427 options.xdata_loc = 0;
428 options.idata_loc = 0x80;
429 options.genericPtr = 1; /* default on */
431 options.model = port->general.default_model;
436 /* now for the optimizations */
437 /* turn on the everything */
438 optimize.global_cse = 1;
443 optimize.loopInvariant = 1;
444 optimize.loopInduction = 1;
446 port->setDefaultOptions();
449 /*-----------------------------------------------------------------*/
450 /* processFile - determines the type of file from the extension */
451 /*-----------------------------------------------------------------*/
452 static void processFile (char *s)
456 /* get the file extension */
457 fext = s + strlen(s);
458 while ((fext != s) && *fext != '.') fext--;
460 /* now if no '.' then we don't know what the file type is
461 so give a warning and return */
463 werror(W_UNKNOWN_FEXT,s);
467 /* otherwise depending on the file type */
468 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
469 /* source file name : not if we already have a
472 werror(W_TOO_MANY_SRC,s);
476 /* the only source file */
477 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
478 werror(E_FILE_OPEN_ERR,s);
482 /* copy the file name into the buffer */
485 /* get rid of the "." */
487 srcFileName = Safe_calloc(1,strlen(buffer)+1);
488 strcpy(srcFileName,buffer);
490 /* get rid of any path information
491 for the module name; do this by going
492 backwards till we get to either '/' or '\' or ':'
493 or start of buffer */
494 fext = buffer + strlen(buffer);
495 while (fext != buffer &&
496 *(fext -1) != '\\' &&
500 moduleName = Safe_calloc(1,strlen(fext)+1);
501 strcpy(moduleName,fext);
506 /* if the extention is type .rel or .r or .REL or .R
507 addtional object file will be passed to the linker */
508 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
509 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
510 strcmp(fext, port->linker.rel_ext) == 0)
512 relFiles[nrelFiles++] = s;
516 /* if .lib or .LIB */
517 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
518 libFiles[nlibFiles++] = s;
522 werror(W_UNKNOWN_FEXT,s);
526 static void _processC1Arg(char *s)
529 if (options.out_name) {
530 werror(W_TOO_MANY_SRC,s);
533 options.out_name = strdup(s);
540 static void _addToList(const char **list, const char *str)
542 /* This is the bad way to do things :) */
547 werror(E_OUT_OF_MEM,__FILE__, 0);
553 static void _setModel(int model, const char *sz)
555 if (port->general.supported_models & model)
556 options.model = model;
558 werror(W_UNSUPPORTED_MODEL, sz, port->target);
561 /*-----------------------------------------------------------------*/
562 /* parseCmdLine - parses the command line and sets the options */
563 /*-----------------------------------------------------------------*/
564 int parseCmdLine ( int argc, char **argv )
569 /* go thru all whole command line */
570 for ( i = 1; i < argc; i++ ) {
575 if (argv[i][0] == '-' && argv[i][1] == '-') {
577 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
582 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
583 options.regExtend = 1;
587 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
588 _setModel(MODEL_LARGE, argv[i]);
592 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
593 _setModel(MODEL_MEDIUM, argv[i]);
597 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
598 _setModel(MODEL_SMALL, argv[i]);
602 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
603 _setModel(MODEL_FLAT24, argv[i]);
607 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
608 options.stack10bit = 1;
612 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
613 options.stackAuto = 1;
617 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
618 options.dump_raw = 1;
622 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
623 options.cyclomatic = 1;
627 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
628 options.dump_gcse = 1;
632 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
633 options.dump_loop = 1;
637 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
638 options.dump_kill = 1;
642 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
643 options.intlong_rent = 1;
647 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
648 options.float_rent = 1;
652 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
653 options.dump_range = 1;
657 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
658 options.dump_pack = 1;
662 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
663 options.dump_rassgn = 1;
667 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
672 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
677 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
678 options.noOverlay = 1;
682 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
683 options.stackOnData = 1;
687 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
692 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
698 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
699 options.dump_rassgn =
705 options.dump_raw = 1;
709 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
714 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
715 options.genericPtr = 1;
719 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
724 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
729 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
734 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
739 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
740 options.noregparms = 1;
744 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
745 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
747 &argv[i][1+strlen(OPTION_PEEP_FILE)];
749 options.peep_file = argv[++i];
753 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
754 if (argv[i][1+strlen(OPTION_LIB_PATH)])
755 libPaths[nlibPaths++] =
756 &argv[i][1+strlen(OPTION_PEEP_FILE)];
758 libPaths[nlibPaths++] = argv[++i];
762 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
764 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
766 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
769 (int) floatFromVal(constVal(argv[++i]));
773 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
774 options.useXstack = 1;
778 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
779 options.mainreturn = 1;
783 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
784 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
785 parseWithComma(options.calleeSaves
786 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
788 parseWithComma(options.calleeSaves,argv[++i]);
792 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
794 if (argv[i][1+strlen(OPTION_STACK_LOC)])
796 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
799 (int) floatFromVal(constVal(argv[++i]));
803 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
805 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
807 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
810 (unsigned int) floatFromVal(constVal(argv[++i]));
814 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
816 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
818 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
821 (int) floatFromVal(constVal(argv[++i]));
825 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
831 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
833 if (argv[i][1+strlen(OPTION_DATA_LOC)])
835 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
838 (int) floatFromVal(constVal(argv[++i]));
842 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
844 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
846 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
849 (int) floatFromVal(constVal(argv[++i]));
853 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
855 if (argv[i][1+strlen(OPTION_CODE_LOC)])
857 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
860 (int) floatFromVal(constVal(argv[++i]));
865 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
866 optimize.noJTabBoundary = 1;
870 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
871 optimize.global_cse = 0;
875 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
876 optimize.loopInvariant = 0;
880 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
881 optimize.loopInduction = 0;
885 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
886 optimize.noLoopReverse = 1;
890 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
895 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
900 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
905 if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
910 if (!port->parseOption(&argc, argv, &i))
912 werror(W_UNKNOWN_OPTION,argv[i]);
920 /* these are undocumented options */
921 /* if preceded by '/' then turn off certain optmizations, used
922 for debugging only these are also the legacy options from
923 version 1.xx will be removed gradually.
924 It may be an absolute filename.
926 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
927 switch (argv[i][1]) {
930 optimize.ptrArithmetic=0;
934 switch (argv[i][2]) {
939 optimize.label4 = 0 ;
957 switch (argv[i][2]) {
959 optimize.loopInvariant = 0;
962 optimize.loopInduction = 0;
969 optimize.global_cse = 0;
976 /* if preceded by '-' then option */
977 if ( *argv[i] == '-' ) {
978 switch (argv[i][1]) {
989 /* Used to select the port */
990 if (_setPort(argv[i] + 2)) {
991 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
996 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
1000 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
1003 case 'X' : /* use external stack */
1004 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
1008 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
1011 case 'p' : /* stack pointer intial value */
1013 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
1017 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
1021 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
1025 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
1029 options.cc_only = 1;
1033 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
1038 libPaths[nlibPaths++] = &argv[i][2];
1040 libPaths[nlibPaths++] = argv[++i];
1044 /* linker options */
1045 if (argv[i][2] == 'l') {
1047 parseWithComma(linkOptions,&argv[i][3]);
1049 parseWithComma(linkOptions,argv[++i]);
1051 /* assembler options */
1052 if (argv[i][2] == 'a') {
1054 parseWithComma((char **)asmOptions,&argv[i][3]);
1056 parseWithComma((char **)asmOptions,argv[++i]);
1059 werror(W_UNKNOWN_OPTION,argv[i]);
1076 /* preprocessor options */
1080 _addToList(preArgv, "-M");
1085 _addToList(preArgv, "-C");
1094 char sOpt = argv[i][1] ;
1097 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1102 rest = &argv[i][2] ;
1104 if ( argv[i][1] == 'Y' )
1107 sprintf(buffer, "-%c%s", sOpt, rest);
1108 _addToList(preArgv, buffer);
1113 if (!port->parseOption(&argc, argv, &i))
1114 werror(W_UNKNOWN_OPTION,argv[i]);
1119 if (!port->parseOption(&argc, argv, &i)) {
1120 /* no option must be a filename */
1122 _processC1Arg(argv[i]);
1124 processFile(argv[i]);
1128 /* set up external stack location if not explicitly specified */
1129 if ( !options.xstack_loc )
1130 options.xstack_loc = options.xdata_loc ;
1132 /* if debug option is set the open the cdbFile */
1133 if (!options.nodebug && srcFileName) {
1134 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1135 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1136 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1138 /* add a module record */
1139 fprintf(cdbFile,"M:%s\n",moduleName);
1145 /*-----------------------------------------------------------------*/
1146 /* my_system - will call a program with arguments */
1147 /*-----------------------------------------------------------------*/
1149 #if defined(_MSC_VER)
1151 char *try_dir[]= {DefaultExePath, NULL}; // TODO : Fill in some default search list
1155 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1156 char *try_dir[]= {NULL};
1160 #ifdef USE_SYSTEM_SYSTEM_CALLS
1161 int my_system (const char *cmd)
1163 int argsStart, e, i=0;
1166 argsStart=strstr(cmd, " ")-cmd;
1168 // try to find the command in predefined path's
1169 while (try_dir[i]) {
1170 cmdLine = (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1171 strcpy(cmdLine, try_dir[i]); // the path
1172 strcat(cmdLine, "/");
1173 strncat(cmdLine, cmd, argsStart); // the command
1175 strcat(cmdLine, ".exe");
1176 /* Mung slashes into backslashes to keep WIndoze happy. */
1187 if (access(cmdLine, X_OK) == 0) {
1189 strcat(cmdLine, cmd+argsStart);
1198 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1202 // command found in predefined path
1214 int my_system (const char *cmd, char **cmd_argv)
1216 char *dir, *got= NULL; int i= 0;
1218 while (!got && try_dir[i])
1220 dir= (char*)Safe_malloc(strlen(try_dir[i])+strlen(cmd)+10);
1221 strcpy(dir, try_dir[i]);
1226 strcat(dir, ".exe");
1228 /* Mung slashes into backslashes to keep WIndoze happy. */
1244 if (access(dir, X_OK) == 0)
1253 char **pCmd = cmd_argv;
1256 printf("%s ", *pCmd);
1264 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1268 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1270 perror("Cannot exec process ");
1278 /*-----------------------------------------------------------------*/
1279 /* linkEdit : - calls the linkage editor with options */
1280 /*-----------------------------------------------------------------*/
1281 static void linkEdit (char **envp)
1284 #ifndef USE_SYSTEM_SYSTEM_CALLS
1291 srcFileName = "temp";
1293 /* first we need to create the <filename>.lnk file */
1294 sprintf(buffer,"%s.lnk",srcFileName);
1295 if (!(lnkfile = fopen(buffer,"w"))) {
1296 werror(E_FILE_OPEN_ERR,buffer);
1300 /* now write the options */
1301 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1303 /* if iram size specified */
1304 if (options.iram_size)
1305 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1307 /*if (options.debug) */
1308 fprintf(lnkfile,"-z\n");
1310 #define WRITE_SEG_LOC(N, L) \
1311 segName = strdup(N); \
1312 c = strtok(segName, " \t"); \
1313 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1314 if (segName) { free(segName); }
1316 /* code segment start */
1317 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1319 /* data segment start */
1320 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1323 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1326 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1328 /* bit segment start */
1329 WRITE_SEG_LOC(BIT_NAME, 0);
1331 /* add the extra linker options */
1332 for (i=0; linkOptions[i] ; i++)
1333 fprintf(lnkfile,"%s\n",linkOptions[i]);
1335 /* other library paths if specified */
1336 for (i = 0 ; i < nlibPaths ; i++ )
1337 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1339 /* standard library path */
1340 if (!options.nostdlib) {
1341 if (IS_DS390_PORT) {
1344 switch(options.model)
1356 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1361 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1363 /* standard library files */
1364 if (strcmp(port->target, "ds390")==0) {
1365 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1367 fprintf (lnkfile,"-l %s\n",STD_LIB);
1368 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1369 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1370 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1373 /* additional libraries if any */
1374 for (i = 0 ; i < nlibFiles; i++)
1375 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1377 /* put in the object files */
1378 if (strcmp(srcFileName,"temp"))
1379 fprintf (lnkfile,"%s ",srcFileName);
1381 for (i = 0 ; i < nrelFiles ; i++ )
1382 fprintf (lnkfile,"%s\n",relFiles[i]);
1384 fprintf (lnkfile,"\n-e\n");
1387 if (options.verbose)
1388 printf ("sdcc: Calling linker...\n");
1390 #ifdef USE_SYSTEM_SYSTEM_CALLS
1391 buildCmdLine(buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1392 if (my_system(buffer)) {
1396 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1397 if (my_system(argv[0], argv)) {
1398 perror("Cannot exec linker");
1404 if (strcmp(srcFileName,"temp") == 0) {
1405 /* rename "temp.cdb" to "firstRelFile.cdb" */
1406 char *f = strtok(strdup(relFiles[0]),".");
1407 f = strcat(f,".cdb");
1408 rename("temp.cdb",f);
1413 /*-----------------------------------------------------------------*/
1414 /* assemble - spawns the assembler with arguments */
1415 /*-----------------------------------------------------------------*/
1416 static void assemble (char **envp)
1418 #ifdef USE_SYSTEM_SYSTEM_CALLS
1419 buildCmdLine(buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1420 if (my_system(buffer)) {
1424 char *argv[128]; /* assembler arguments */
1426 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1428 if (my_system(argv[0], argv)) {
1429 perror("Cannot exec assembler");
1437 /*-----------------------------------------------------------------*/
1438 /* preProcess - spawns the preprocessor with arguments */
1439 /*-----------------------------------------------------------------*/
1440 static int preProcess (char **envp)
1442 #ifndef USE_SYSTEM_SYSTEM_CALLS
1449 if (!options.c1mode) {
1450 /* if using external stack define the macro */
1451 if ( options.useXstack )
1452 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1454 /* set the macro for stack autos */
1455 if ( options.stackAuto )
1456 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1458 /* set the macro for stack autos */
1459 if ( options.stack10bit )
1460 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1462 /* set the macro for large model */
1463 switch(options.model)
1466 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1469 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1472 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1475 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1478 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1481 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1486 /* add port (processor information to processor */
1487 sprintf(procDef,"-DSDCC_%s",port->target);
1488 _addToList(preArgv,procDef);
1491 preOutName = strdup(tmpnam(NULL));
1493 if (options.verbose)
1494 printf ("sdcc: Calling preprocessor...\n");
1496 #ifdef USE_SYSTEM_SYSTEM_CALLS
1497 buildCmdLine(buffer, _preCmd, fullSrcFileName,
1498 preOutName, srcFileName, preArgv);
1499 if (my_system(buffer)) {
1503 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1504 preOutName, srcFileName, preArgv);
1506 if (my_system(argv[0], argv)) {
1507 unlink (preOutName);
1508 perror("Cannot exec Preprocessor");
1517 preOutName = fullSrcFileName;
1520 yyin = fopen(preOutName, "r");
1522 perror("Preproc file not found\n");
1529 static void _findPort(int argc, char **argv)
1535 if (!strncmp(*argv, "-m", 2)) {
1536 _setPort(*argv + 2);
1542 /* Use the first in the list */
1548 * initialises and calls the parser
1551 int main ( int argc, char **argv , char **envp)
1553 /* turn all optimizations off by default */
1554 memset(&optimize,0,sizeof(struct optimize));
1556 /*printVersionInfo ();*/
1558 _findPort(argc, argv);
1559 /* Initalise the port. */
1563 #if defined(_MSC_VER)
1568 // Create a default exe search path from the path to the sdcc command
1570 strcpy(DefaultExePath,argv[0]) ;
1572 for(i = strlen(DefaultExePath) ; i > 0 ; i--)
1573 if (DefaultExePath[i] == '\\')
1575 DefaultExePath[i] = '\0' ;
1580 DefaultExePath[0] = '\0' ;
1585 setDefaultOptions();
1586 parseCmdLine(argc,argv);
1590 port->finaliseOptions();
1592 /* if no input then printUsage & exit */
1593 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1606 if (options.verbose)
1607 printf ("sdcc: Generating code...\n");
1613 /* TSD PIC port hack - if the PIC port option is enabled
1614 and SDCC is used to generate PIC code, then we will
1615 generate .asm files in gpasm's format instead of SDCC's
1618 #if !OPT_DISABLE_PIC
1628 if (!options.c1mode)
1630 if (options.verbose)
1631 printf ("sdcc: Calling assembler...\n");
1646 if (!options.cc_only &&
1650 (srcFileName || nrelFiles)) {
1651 if (port->linker.do_link)
1652 port->linker.do_link();
1657 if (yyin && yyin != stdin)
1660 if (preOutName && !options.c1mode) {