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
37 // This is a bit messy because we define link ourself
38 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
43 // No unistd.h in Borland C++
44 extern int access(const char *, int);
52 FILE *srcFile ;/* source file */
53 FILE *cdbFile = NULL ;/* debugger information output file */
54 char *fullSrcFileName ;/* full name for the source file */
55 char *srcFileName ;/* source file name with the .c stripped */
56 char *moduleName ;/* module name is srcFilename stripped of any path */
57 const char *preArgv[128] ;/* pre-processor arguments */
59 struct optimize optimize ;
60 struct options options ;
61 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
62 short preProcOnly = 0;
64 char *linkOptions[128];
65 const char *asmOptions[128];
72 bool verboseExec = FALSE;
75 // In MSC VC6 default search path for exe's to path for this
79 char DefaultExePath[_MAX_PATH] ;
83 /* Far functions, far data */
84 #define OPTION_LARGE_MODEL "-model-large"
85 /* Far functions, near data */
86 #define OPTION_MEDIUM_MODEL "-model-medium"
87 #define OPTION_SMALL_MODEL "-model-small"
88 #define OPTION_FLAT24_MODEL "-model-flat24"
89 #define OPTION_STACK_AUTO "-stack-auto"
90 #define OPTION_STACK_10BIT "-stack-10bit"
91 #define OPTION_XSTACK "-xstack"
92 #define OPTION_GENERIC "-generic"
93 #define OPTION_NO_GCSE "-nogcse"
94 #define OPTION_NO_LOOP_INV "-noinvariant"
95 #define OPTION_NO_LOOP_IND "-noinduction"
96 #define OPTION_NO_JTBOUND "-nojtbound"
97 #define OPTION_NO_LOOPREV "-noloopreverse"
98 #define OPTION_XREGS "-regextend"
99 #define OPTION_COMP_ONLY "-compile-only"
100 #define OPTION_DUMP_RAW "-dumpraw"
101 #define OPTION_DUMP_GCSE "-dumpgcse"
102 #define OPTION_DUMP_LOOP "-dumploop"
103 #define OPTION_DUMP_KILL "-dumpdeadcode"
104 #define OPTION_DUMP_RANGE "-dumpliverange"
105 #define OPTION_DUMP_PACK "-dumpregpack"
106 #define OPTION_DUMP_RASSGN "-dumpregassign"
107 #define OPTION_DUMP_ALL "-dumpall"
108 #define OPTION_XRAM_LOC "-xram-loc"
109 #define OPTION_IRAM_SIZE "-iram-size"
110 #define OPTION_XSTACK_LOC "-xstack-loc"
111 #define OPTION_CODE_LOC "-code-loc"
112 #define OPTION_STACK_LOC "-stack-loc"
113 #define OPTION_DATA_LOC "-data-loc"
114 #define OPTION_IDATA_LOC "-idata-loc"
115 #define OPTION_PEEP_FILE "-peep-file"
116 #define OPTION_LIB_PATH "-lib-path"
117 #define OPTION_INTLONG_RENT "-int-long-reent"
118 #define OPTION_FLOAT_RENT "-float-reent"
119 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
120 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
121 #define OPTION_CYCLOMATIC "-cyclomatic"
122 #define OPTION_NOOVERLAY "-nooverlay"
123 #define OPTION_MAINRETURN "-main-return"
124 #define OPTION_NOPEEP "-no-peep"
125 #define OPTION_ASMPEEP "-peep-asm"
126 #define OPTION_DEBUG "-debug"
127 #define OPTION_NODEBUG "-nodebug"
128 #define OPTION_VERSION "-version"
129 #define OPTION_STKAFTRDATA "-stack-after-data"
130 #define OPTION_PREPROC_ONLY "-preprocessonly"
131 #define OPTION_C1_MODE "-c1mode"
132 #define OPTION_HELP "-help"
133 #define OPTION_CALLEE_SAVES "-callee-saves"
134 #define OPTION_NOREGPARMS "-noregparms"
135 #define OPTION_NOSTDLIB "-nostdlib"
136 #define OPTION_NOSTDINC "-nostdinc"
137 #define OPTION_VERBOSE "-verbose"
138 #define OPTION_ANSIINT "-ansiint"
139 static const char *_preCmd[] = {
140 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
141 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
146 static PORT *_ports[] = {
147 #if !OPT_DISABLE_MCS51
150 #if !OPT_DISABLE_GBZ80
159 #if !OPT_DISABLE_DS390
165 #if !OPT_DISABLE_I186
168 #if !OPT_DISABLE_TLCS900H
173 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
176 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
178 extern void pic14glue();
180 /** Sets the port to the one given by the command line option.
181 @param The name minus the option (eg 'mcs51')
182 @return 0 on success.
184 static int _setPort(const char *name)
187 for (i=0; i<NUM_PORTS; i++) {
188 if (!strcmp(_ports[i]->target, name)) {
193 /* Error - didnt find */
194 werror(E_UNKNOWN_TARGET,name);
198 static void _validatePorts(void)
201 for (i=0; i<NUM_PORTS; i++) {
202 if (_ports[i]->magic != PORT_MAGIC) {
203 printf("Error: port %s is incomplete.\n", _ports[i]->target);
209 #ifdef USE_SYSTEM_SYSTEM_CALLS
210 void buildCmdLine(char *into, const char **cmds,
211 const char *p1, const char *p2,
212 const char *p3, const char **list)
214 const char *p, *from;
223 /* See if it has a '$' anywhere - if not, just copy */
224 if ((p = strchr(from, '$'))) {
225 strncat(into, from, p - from);
244 const char **tmp = list;
258 strcat(into, from); // this includes the ".asm" from "$1.asm"
263 void buildCmdLine(char *into, char **args, const char **cmds,
264 const char *p1, const char *p2,
265 const char *p3, const char **list)
267 const char *p, *from;
277 /* See if it has a '$' anywhere - if not, just copy */
278 if ((p = strchr(from, '$'))) {
279 strncpy(into, from, p - from);
280 /* NULL terminate it */
298 const char **tmp = list;
302 into += strlen(into)+1;
315 if (strlen(into) == 0)
317 into += strlen(into)+1;
323 /*-----------------------------------------------------------------*/
324 /* printVersionInfo - prints the version info */
325 /*-----------------------------------------------------------------*/
326 void printVersionInfo ()
332 for (i=0; i<NUM_PORTS; i++)
333 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
334 fprintf(stderr, " %s"
335 #ifdef SDCC_SUB_VERSION_STR
336 "/" SDCC_SUB_VERSION_STR
353 /*-----------------------------------------------------------------*/
354 /* printUsage - prints command line syntax */
355 /*-----------------------------------------------------------------*/
360 "Usage : [options] filename\n"
362 "\t-m<proc> - Target processor <proc>. Default %s\n"
363 "\t Try --version for supported values of <proc>\n"
364 "\t--model-large - Large Model\n"
365 "\t--model-small - Small Model (default)\n"
366 "\t--stack-auto - Stack automatic variables\n"
367 "\t--xstack - Use external stack\n"
368 "\t--xram-loc <nnnn> - External Ram start location\n"
369 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
370 "\t--code-loc <nnnn> - Code Segment Location\n"
371 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
372 "\t--data-loc <nnnn> - Direct data start location\n"
373 "\t--idata-loc <nnnn> - Indirect data start location\n"
374 "\t--iram-size <nnnn> - Internal Ram size\n"
375 "\t--nojtbound - Don't generate boundary check for jump tables\n"
376 "\t--generic - All unqualified ptrs converted to '_generic'\n"
377 "PreProcessor Options :-\n"
378 "\t-Dmacro - Define Macro\n"
379 "\t-Ipath - Include \"*.h\" path\n"
380 "Note: this is NOT a complete list of options see docs for details\n",
386 /*-----------------------------------------------------------------*/
387 /* parseWithComma - separates string with comma */
388 /*-----------------------------------------------------------------*/
389 void parseWithComma (char **dest,char *src)
394 /* skip the initial white spaces */
395 while (isspace(*src)) src++;
409 /*-----------------------------------------------------------------*/
410 /* setDefaultOptions - sets the default options */
411 /*-----------------------------------------------------------------*/
412 static void setDefaultOptions()
416 for ( i = 0 ; i < 128 ; i++)
417 preArgv[i] = asmOptions [i] =
418 linkOptions[i] = relFiles[i] = libFiles[i] =
421 /* first the options part */
422 options.stack_loc = 0; /* stack pointer initialised to 0 */
423 options.xstack_loc= 0; /* xternal stack starts at 0 */
424 options.code_loc = 0; /* code starts at 0 */
425 options.data_loc = 0x0030; /* data starts at 0x0030 */
426 options.xdata_loc = 0;
427 options.idata_loc = 0x80;
428 options.genericPtr = 1; /* default on */
430 options.model = port->general.default_model;
435 /* now for the optimizations */
436 /* turn on the everything */
437 optimize.global_cse = 1;
442 optimize.loopInvariant = 1;
443 optimize.loopInduction = 1;
445 port->setDefaultOptions();
448 /*-----------------------------------------------------------------*/
449 /* processFile - determines the type of file from the extension */
450 /*-----------------------------------------------------------------*/
451 static void processFile (char *s)
455 /* get the file extension */
456 fext = s + strlen(s);
457 while ((fext != s) && *fext != '.') fext--;
459 /* now if no '.' then we don't know what the file type is
460 so give a warning and return */
462 werror(W_UNKNOWN_FEXT,s);
466 /* otherwise depending on the file type */
467 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
468 /* source file name : not if we already have a
471 werror(W_TOO_MANY_SRC,s);
475 /* the only source file */
476 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
477 werror(E_FILE_OPEN_ERR,s);
481 /* copy the file name into the buffer */
484 /* get rid of the "." */
486 srcFileName = Safe_calloc(strlen(buffer)+1);
487 strcpy(srcFileName,buffer);
489 /* get rid of any path information
490 for the module name; do this by going
491 backwards till we get to either '/' or '\' or ':'
492 or start of buffer */
493 fext = buffer + strlen(buffer);
494 while (fext != buffer &&
495 *(fext -1) != '\\' &&
499 moduleName = Safe_calloc(strlen(fext)+1);
500 strcpy(moduleName,fext);
505 /* if the extention is type .rel or .r or .REL or .R
506 addtional object file will be passed to the linker */
507 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
508 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
509 strcmp(fext, port->linker.rel_ext) == 0)
511 relFiles[nrelFiles++] = s;
515 /* if .lib or .LIB */
516 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
517 libFiles[nlibFiles++] = s;
521 werror(W_UNKNOWN_FEXT,s);
525 static void _processC1Arg(char *s)
528 if (options.out_name) {
529 werror(W_TOO_MANY_SRC,s);
532 options.out_name = strdup(s);
539 static void _addToList(const char **list, const char *str)
541 /* This is the bad way to do things :) */
546 werror(E_OUT_OF_MEM,__FILE__, 0);
552 static void _setModel(int model, const char *sz)
554 if (port->general.supported_models & model)
555 options.model = model;
557 werror(W_UNSUPPORTED_MODEL, sz, port->target);
560 /*-----------------------------------------------------------------*/
561 /* parseCmdLine - parses the command line and sets the options */
562 /*-----------------------------------------------------------------*/
563 int parseCmdLine ( int argc, char **argv )
568 /* go thru all whole command line */
569 for ( i = 1; i < argc; i++ ) {
574 if (argv[i][0] == '-' && argv[i][1] == '-') {
576 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
581 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
582 options.regExtend = 1;
586 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
587 _setModel(MODEL_LARGE, argv[i]);
591 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
592 _setModel(MODEL_MEDIUM, argv[i]);
596 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
597 _setModel(MODEL_SMALL, argv[i]);
601 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
602 _setModel(MODEL_FLAT24, argv[i]);
606 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
607 options.stack10bit = 1;
611 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
612 options.stackAuto = 1;
616 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
617 options.dump_raw = 1;
621 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
622 options.cyclomatic = 1;
626 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
627 options.dump_gcse = 1;
631 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
632 options.dump_loop = 1;
636 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
637 options.dump_kill = 1;
641 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
642 options.intlong_rent = 1;
646 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
647 options.float_rent = 1;
651 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
652 options.dump_range = 1;
656 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
657 options.dump_pack = 1;
661 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
662 options.dump_rassgn = 1;
666 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
671 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
676 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
677 options.noOverlay = 1;
681 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
682 options.stackOnData = 1;
686 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
691 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
697 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
698 options.dump_rassgn =
704 options.dump_raw = 1;
708 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
713 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
714 options.genericPtr = 1;
718 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
723 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
728 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
733 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
738 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
739 options.noregparms = 1;
743 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
744 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
746 &argv[i][1+strlen(OPTION_PEEP_FILE)];
748 options.peep_file = argv[++i];
752 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
753 if (argv[i][1+strlen(OPTION_LIB_PATH)])
754 libPaths[nlibPaths++] =
755 &argv[i][1+strlen(OPTION_PEEP_FILE)];
757 libPaths[nlibPaths++] = argv[++i];
761 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
763 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
765 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
768 (int) floatFromVal(constVal(argv[++i]));
772 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
773 options.useXstack = 1;
777 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
778 options.mainreturn = 1;
782 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
783 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
784 parseWithComma(options.calleeSaves
785 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
787 parseWithComma(options.calleeSaves,argv[++i]);
791 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
793 if (argv[i][1+strlen(OPTION_STACK_LOC)])
795 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
798 (int) floatFromVal(constVal(argv[++i]));
802 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
804 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
806 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
809 (unsigned int) floatFromVal(constVal(argv[++i]));
813 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
815 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
817 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
820 (int) floatFromVal(constVal(argv[++i]));
824 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
830 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
832 if (argv[i][1+strlen(OPTION_DATA_LOC)])
834 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
837 (int) floatFromVal(constVal(argv[++i]));
841 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
843 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
845 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
848 (int) floatFromVal(constVal(argv[++i]));
852 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
854 if (argv[i][1+strlen(OPTION_CODE_LOC)])
856 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
859 (int) floatFromVal(constVal(argv[++i]));
864 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
865 optimize.noJTabBoundary = 1;
869 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
870 optimize.global_cse = 0;
874 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
875 optimize.loopInvariant = 0;
879 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
880 optimize.loopInduction = 0;
884 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
885 optimize.noLoopReverse = 1;
889 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
894 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
899 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
904 if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
909 if (!port->parseOption(&argc, argv, &i))
911 werror(W_UNKNOWN_OPTION,argv[i]);
919 /* these are undocumented options */
920 /* if preceded by '/' then turn off certain optmizations, used
921 for debugging only these are also the legacy options from
922 version 1.xx will be removed gradually.
923 It may be an absolute filename.
925 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
926 switch (argv[i][1]) {
929 optimize.ptrArithmetic=0;
933 switch (argv[i][2]) {
938 optimize.label4 = 0 ;
956 switch (argv[i][2]) {
958 optimize.loopInvariant = 0;
961 optimize.loopInduction = 0;
968 optimize.global_cse = 0;
975 /* if preceded by '-' then option */
976 if ( *argv[i] == '-' ) {
977 switch (argv[i][1]) {
988 /* Used to select the port */
989 if (_setPort(argv[i] + 2)) {
990 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
995 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
999 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
1002 case 'X' : /* use external stack */
1003 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
1007 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
1010 case 'p' : /* stack pointer intial value */
1012 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
1016 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
1020 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
1024 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
1028 options.cc_only = 1;
1032 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
1037 libPaths[nlibPaths++] = &argv[i][2];
1039 libPaths[nlibPaths++] = argv[++i];
1043 /* linker options */
1044 if (argv[i][2] == 'l') {
1046 parseWithComma(linkOptions,&argv[i][3]);
1048 parseWithComma(linkOptions,argv[++i]);
1050 /* assembler options */
1051 if (argv[i][2] == 'a') {
1053 parseWithComma((char **)asmOptions,&argv[i][3]);
1055 parseWithComma((char **)asmOptions,argv[++i]);
1058 werror(W_UNKNOWN_OPTION,argv[i]);
1075 /* preprocessor options */
1079 _addToList(preArgv, "-M");
1084 _addToList(preArgv, "-C");
1093 char sOpt = argv[i][1] ;
1096 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1101 rest = &argv[i][2] ;
1103 if ( argv[i][1] == 'Y' )
1106 sprintf(buffer, "-%c%s", sOpt, rest);
1107 _addToList(preArgv, buffer);
1112 if (!port->parseOption(&argc, argv, &i))
1113 werror(W_UNKNOWN_OPTION,argv[i]);
1118 if (!port->parseOption(&argc, argv, &i)) {
1119 /* no option must be a filename */
1121 _processC1Arg(argv[i]);
1123 processFile(argv[i]);
1127 /* set up external stack location if not explicitly specified */
1128 if ( !options.xstack_loc )
1129 options.xstack_loc = options.xdata_loc ;
1131 /* if debug option is set the open the cdbFile */
1132 if (!options.nodebug && srcFileName) {
1133 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1134 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1135 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1137 /* add a module record */
1138 fprintf(cdbFile,"M:%s\n",moduleName);
1144 /*-----------------------------------------------------------------*/
1145 /* my_system - will call a program with arguments */
1146 /*-----------------------------------------------------------------*/
1148 #if defined(_MSC_VER)
1150 char *try_dir[]= {DefaultExePath, NULL}; // TODO : Fill in some default search list
1154 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1155 char *try_dir[]= {NULL};
1159 #ifdef USE_SYSTEM_SYSTEM_CALLS
1160 int my_system (const char *cmd)
1162 int argsStart, e, i=0;
1165 argsStart=strstr(cmd, " ")-cmd;
1167 // try to find the command in predefined path's
1168 while (try_dir[i]) {
1169 cmdLine = (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1170 strcpy(cmdLine, try_dir[i]); // the path
1171 strcat(cmdLine, "/");
1172 strncat(cmdLine, cmd, argsStart); // the command
1174 strcat(cmdLine, ".exe");
1175 /* Mung slashes into backslashes to keep WIndoze happy. */
1186 if (access(cmdLine, X_OK) == 0) {
1188 strcat(cmdLine, cmd+argsStart);
1197 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1201 // command found in predefined path
1213 int my_system (const char *cmd, char **cmd_argv)
1215 char *dir, *got= NULL; int i= 0;
1217 while (!got && try_dir[i])
1219 dir= (char*)Safe_malloc(strlen(try_dir[i])+strlen(cmd)+10);
1220 strcpy(dir, try_dir[i]);
1225 strcat(dir, ".exe");
1227 /* Mung slashes into backslashes to keep WIndoze happy. */
1243 if (access(dir, X_OK) == 0)
1252 char **pCmd = cmd_argv;
1255 printf("%s ", *pCmd);
1263 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1267 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1269 perror("Cannot exec process ");
1277 /*-----------------------------------------------------------------*/
1278 /* linkEdit : - calls the linkage editor with options */
1279 /*-----------------------------------------------------------------*/
1280 static void linkEdit (char **envp)
1283 #ifndef USE_SYSTEM_SYSTEM_CALLS
1290 srcFileName = "temp";
1292 /* first we need to create the <filename>.lnk file */
1293 sprintf(buffer,"%s.lnk",srcFileName);
1294 if (!(lnkfile = fopen(buffer,"w"))) {
1295 werror(E_FILE_OPEN_ERR,buffer);
1299 /* now write the options */
1300 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1302 /* if iram size specified */
1303 if (options.iram_size)
1304 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1306 /*if (options.debug) */
1307 fprintf(lnkfile,"-z\n");
1309 #define WRITE_SEG_LOC(N, L) \
1310 segName = strdup(N); \
1311 c = strtok(segName, " \t"); \
1312 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1313 if (segName) { free(segName); }
1315 /* code segment start */
1316 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1318 /* data segment start */
1319 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1322 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1325 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1327 /* bit segment start */
1328 WRITE_SEG_LOC(BIT_NAME, 0);
1330 /* add the extra linker options */
1331 for (i=0; linkOptions[i] ; i++)
1332 fprintf(lnkfile,"%s\n",linkOptions[i]);
1334 /* other library paths if specified */
1335 for (i = 0 ; i < nlibPaths ; i++ )
1336 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1338 /* standard library path */
1339 if (!options.nostdlib) {
1340 if (IS_DS390_PORT) {
1343 switch(options.model)
1355 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1360 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1362 /* standard library files */
1363 if (strcmp(port->target, "ds390")==0) {
1364 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1366 fprintf (lnkfile,"-l %s\n",STD_LIB);
1367 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1368 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1369 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1372 /* additional libraries if any */
1373 for (i = 0 ; i < nlibFiles; i++)
1374 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1376 /* put in the object files */
1377 if (strcmp(srcFileName,"temp"))
1378 fprintf (lnkfile,"%s ",srcFileName);
1380 for (i = 0 ; i < nrelFiles ; i++ )
1381 fprintf (lnkfile,"%s\n",relFiles[i]);
1383 fprintf (lnkfile,"\n-e\n");
1386 if (options.verbose)
1387 printf ("sdcc: Calling linker...\n");
1389 #ifdef USE_SYSTEM_SYSTEM_CALLS
1390 buildCmdLine(buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1391 if (my_system(buffer)) {
1395 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1396 if (my_system(argv[0], argv)) {
1397 perror("Cannot exec linker");
1403 if (strcmp(srcFileName,"temp") == 0) {
1404 /* rename "temp.cdb" to "firstRelFile.cdb" */
1405 char *f = strtok(strdup(relFiles[0]),".");
1406 f = strcat(f,".cdb");
1407 rename("temp.cdb",f);
1412 /*-----------------------------------------------------------------*/
1413 /* assemble - spawns the assembler with arguments */
1414 /*-----------------------------------------------------------------*/
1415 static void assemble (char **envp)
1417 #ifdef USE_SYSTEM_SYSTEM_CALLS
1418 buildCmdLine(buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1419 if (my_system(buffer)) {
1423 char *argv[128]; /* assembler arguments */
1425 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1427 if (my_system(argv[0], argv)) {
1428 perror("Cannot exec assembler");
1436 /*-----------------------------------------------------------------*/
1437 /* preProcess - spawns the preprocessor with arguments */
1438 /*-----------------------------------------------------------------*/
1439 static int preProcess (char **envp)
1441 #ifndef USE_SYSTEM_SYSTEM_CALLS
1448 if (!options.c1mode) {
1449 /* if using external stack define the macro */
1450 if ( options.useXstack )
1451 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1453 /* set the macro for stack autos */
1454 if ( options.stackAuto )
1455 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1457 /* set the macro for stack autos */
1458 if ( options.stack10bit )
1459 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1461 /* set the macro for large model */
1462 switch(options.model)
1465 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1468 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1471 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1474 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1477 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1480 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1485 /* add port (processor information to processor */
1486 sprintf(procDef,"-DSDCC_%s",port->target);
1487 _addToList(preArgv,procDef);
1490 preOutName = strdup(tmpnam(NULL));
1492 if (options.verbose)
1493 printf ("sdcc: Calling preprocessor...\n");
1495 #ifdef USE_SYSTEM_SYSTEM_CALLS
1496 buildCmdLine(buffer, _preCmd, fullSrcFileName,
1497 preOutName, srcFileName, preArgv);
1498 if (my_system(buffer)) {
1502 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1503 preOutName, srcFileName, preArgv);
1505 if (my_system(argv[0], argv)) {
1506 unlink (preOutName);
1507 perror("Cannot exec Preprocessor");
1516 preOutName = fullSrcFileName;
1519 yyin = fopen(preOutName, "r");
1521 perror("Preproc file not found\n");
1528 static void _findPort(int argc, char **argv)
1534 if (!strncmp(*argv, "-m", 2)) {
1535 _setPort(*argv + 2);
1541 /* Use the first in the list */
1547 * initialises and calls the parser
1550 int main ( int argc, char **argv , char **envp)
1552 /* turn all optimizations off by default */
1553 memset(&optimize,0,sizeof(struct optimize));
1555 /*printVersionInfo ();*/
1557 _findPort(argc, argv);
1558 /* Initalise the port. */
1562 #if defined(_MSC_VER)
1567 // Create a default exe search path from the path to the sdcc command
1569 strcpy(DefaultExePath,argv[0]) ;
1571 for(i = strlen(DefaultExePath) ; i > 0 ; i--)
1572 if (DefaultExePath[i] == '\\')
1574 DefaultExePath[i] = '\0' ;
1579 DefaultExePath[0] = '\0' ;
1584 setDefaultOptions();
1585 parseCmdLine(argc,argv);
1589 port->finaliseOptions();
1591 /* if no input then printUsage & exit */
1592 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1605 if (options.verbose)
1606 printf ("sdcc: Generating code...\n");
1612 /* TSD PIC port hack - if the PIC port option is enabled
1613 and SDCC is used to generate PIC code, then we will
1614 generate .asm files in gpasm's format instead of SDCC's
1617 #if !OPT_DISABLE_PIC
1627 if (!options.c1mode)
1629 if (options.verbose)
1630 printf ("sdcc: Calling assembler...\n");
1645 if (!options.cc_only &&
1649 (srcFileName || nrelFiles)) {
1650 if (port->linker.do_link)
1651 port->linker.do_link();
1656 if (yyin && yyin != stdin)
1659 if (preOutName && !options.c1mode) {