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
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);
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 /* Far functions, far data */
75 #define OPTION_LARGE_MODEL "-model-large"
76 /* Far functions, near data */
77 #define OPTION_MEDIUM_MODEL "-model-medium"
78 #define OPTION_SMALL_MODEL "-model-small"
79 #define OPTION_FLAT24_MODEL "-model-flat24"
80 #define OPTION_STACK_AUTO "-stack-auto"
81 #define OPTION_STACK_10BIT "-stack-10bit"
82 #define OPTION_XSTACK "-xstack"
83 #define OPTION_GENERIC "-generic"
84 #define OPTION_NO_GCSE "-nogcse"
85 #define OPTION_NO_LOOP_INV "-noinvariant"
86 #define OPTION_NO_LOOP_IND "-noinduction"
87 #define OPTION_NO_JTBOUND "-nojtbound"
88 #define OPTION_NO_LOOPREV "-noloopreverse"
89 #define OPTION_XREGS "-regextend"
90 #define OPTION_COMP_ONLY "-compile-only"
91 #define OPTION_DUMP_RAW "-dumpraw"
92 #define OPTION_DUMP_GCSE "-dumpgcse"
93 #define OPTION_DUMP_LOOP "-dumploop"
94 #define OPTION_DUMP_KILL "-dumpdeadcode"
95 #define OPTION_DUMP_RANGE "-dumpliverange"
96 #define OPTION_DUMP_PACK "-dumpregpack"
97 #define OPTION_DUMP_RASSGN "-dumpregassign"
98 #define OPTION_DUMP_ALL "-dumpall"
99 #define OPTION_XRAM_LOC "-xram-loc"
100 #define OPTION_IRAM_SIZE "-iram-size"
101 #define OPTION_XSTACK_LOC "-xstack-loc"
102 #define OPTION_CODE_LOC "-code-loc"
103 #define OPTION_STACK_LOC "-stack-loc"
104 #define OPTION_DATA_LOC "-data-loc"
105 #define OPTION_IDATA_LOC "-idata-loc"
106 #define OPTION_PEEP_FILE "-peep-file"
107 #define OPTION_LIB_PATH "-lib-path"
108 #define OPTION_INTLONG_RENT "-int-long-reent"
109 #define OPTION_FLOAT_RENT "-float-reent"
110 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
111 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
112 #define OPTION_CYCLOMATIC "-cyclomatic"
113 #define OPTION_NOOVERLAY "-nooverlay"
114 #define OPTION_MAINRETURN "-main-return"
115 #define OPTION_NOPEEP "-no-peep"
116 #define OPTION_ASMPEEP "-peep-asm"
117 #define OPTION_DEBUG "-debug"
118 #define OPTION_NODEBUG "-nodebug"
119 #define OPTION_VERSION "-version"
120 #define OPTION_STKAFTRDATA "-stack-after-data"
121 #define OPTION_PREPROC_ONLY "-preprocessonly"
122 #define OPTION_C1_MODE "-c1mode"
123 #define OPTION_HELP "-help"
124 #define OPTION_CALLEE_SAVES "-callee-saves"
125 #define OPTION_NOREGPARMS "-noregparms"
126 #define OPTION_NOSTDLIB "-nostdlib"
127 #define OPTION_NOSTDINC "-nostdinc"
128 #define OPTION_VERBOSE "-verbose"
129 #define OPTION_ANSIINT "-ansiint"
130 static const char *_preCmd[] = {
131 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
132 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
137 static PORT *_ports[] = {
138 #if !OPT_DISABLE_MCS51
141 #if !OPT_DISABLE_GBZ80
150 #if !OPT_DISABLE_DS390
156 #if !OPT_DISABLE_I186
159 #if !OPT_DISABLE_TLCS900H
164 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
167 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
169 extern void pic14glue();
171 /** Sets the port to the one given by the command line option.
172 @param The name minus the option (eg 'mcs51')
173 @return 0 on success.
175 static int _setPort(const char *name)
178 for (i=0; i<NUM_PORTS; i++) {
179 if (!strcmp(_ports[i]->target, name)) {
184 /* Error - didnt find */
185 werror(E_UNKNOWN_TARGET,name);
189 static void _validatePorts(void)
192 for (i=0; i<NUM_PORTS; i++) {
193 if (_ports[i]->magic != PORT_MAGIC) {
194 printf("Error: port %s is incomplete.\n", _ports[i]->target);
200 #ifdef USE_SYSTEM_SYSTEM_CALLS
201 void buildCmdLine(char *into, const char **cmds,
202 const char *p1, const char *p2,
203 const char *p3, const char **list)
205 const char *p, *from;
214 /* See if it has a '$' anywhere - if not, just copy */
215 if ((p = strchr(from, '$'))) {
216 strncat(into, from, p - from);
235 const char **tmp = list;
249 strcat(into, from); // this includes the ".asm" from "$1.asm"
254 void buildCmdLine(char *into, char **args, const char **cmds,
255 const char *p1, const char *p2,
256 const char *p3, const char **list)
258 const char *p, *from;
268 /* See if it has a '$' anywhere - if not, just copy */
269 if ((p = strchr(from, '$'))) {
270 strncpy(into, from, p - from);
271 /* NULL terminate it */
289 const char **tmp = list;
293 into += strlen(into)+1;
306 if (strlen(into) == 0)
308 into += strlen(into)+1;
314 /*-----------------------------------------------------------------*/
315 /* printVersionInfo - prints the version info */
316 /*-----------------------------------------------------------------*/
317 void printVersionInfo ()
323 for (i=0; i<NUM_PORTS; i++)
324 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
325 fprintf(stderr, " %s"
326 #ifdef SDCC_SUB_VERSION_STR
327 "/" SDCC_SUB_VERSION_STR
344 /*-----------------------------------------------------------------*/
345 /* printUsage - prints command line syntax */
346 /*-----------------------------------------------------------------*/
351 "Usage : [options] filename\n"
353 "\t-m<proc> - Target processor <proc>. Default %s\n"
354 "\t Try --version for supported values of <proc>\n"
355 "\t--model-large - Large Model\n"
356 "\t--model-small - Small Model (default)\n"
357 "\t--stack-auto - Stack automatic variables\n"
358 "\t--xstack - Use external stack\n"
359 "\t--xram-loc <nnnn> - External Ram start location\n"
360 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
361 "\t--code-loc <nnnn> - Code Segment Location\n"
362 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
363 "\t--data-loc <nnnn> - Direct data start location\n"
364 "\t--idata-loc <nnnn> - Indirect data start location\n"
365 "\t--iram-size <nnnn> - Internal Ram size\n"
366 "\t--nojtbound - Don't generate boundary check for jump tables\n"
367 "\t--generic - All unqualified ptrs converted to '_generic'\n"
368 "PreProcessor Options :-\n"
369 "\t-Dmacro - Define Macro\n"
370 "\t-Ipath - Include \"*.h\" path\n"
371 "Note: this is NOT a complete list of options see docs for details\n",
377 /*-----------------------------------------------------------------*/
378 /* parseWithComma - separates string with comma */
379 /*-----------------------------------------------------------------*/
380 void parseWithComma (char **dest,char *src)
385 /* skip the initial white spaces */
386 while (isspace(*src)) src++;
400 /*-----------------------------------------------------------------*/
401 /* setDefaultOptions - sets the default options */
402 /*-----------------------------------------------------------------*/
403 static void setDefaultOptions()
407 for ( i = 0 ; i < 128 ; i++)
408 preArgv[i] = asmOptions [i] =
409 linkOptions[i] = relFiles[i] = libFiles[i] =
412 /* first the options part */
413 options.stack_loc = 0; /* stack pointer initialised to 0 */
414 options.xstack_loc= 0; /* xternal stack starts at 0 */
415 options.code_loc = 0; /* code starts at 0 */
416 options.data_loc = 0x0030; /* data starts at 0x0030 */
417 options.xdata_loc = 0;
418 options.idata_loc = 0x80;
419 options.genericPtr = 1; /* default on */
421 options.model = port->general.default_model;
426 /* now for the optimizations */
427 /* turn on the everything */
428 optimize.global_cse = 1;
433 optimize.loopInvariant = 1;
434 optimize.loopInduction = 1;
436 port->setDefaultOptions();
439 /*-----------------------------------------------------------------*/
440 /* processFile - determines the type of file from the extension */
441 /*-----------------------------------------------------------------*/
442 static void processFile (char *s)
446 /* get the file extension */
447 fext = s + strlen(s);
448 while ((fext != s) && *fext != '.') fext--;
450 /* now if no '.' then we don't know what the file type is
451 so give a warning and return */
453 werror(W_UNKNOWN_FEXT,s);
457 /* otherwise depending on the file type */
458 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
459 /* source file name : not if we already have a
462 werror(W_TOO_MANY_SRC,s);
466 /* the only source file */
467 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
468 werror(E_FILE_OPEN_ERR,s);
472 /* copy the file name into the buffer */
475 /* get rid of the "." */
477 ALLOC(srcFileName,strlen(buffer)+1);
478 strcpy(srcFileName,buffer);
480 /* get rid of any path information
481 for the module name; do this by going
482 backwards till we get to either '/' or '\' or ':'
483 or start of buffer */
484 fext = buffer + strlen(buffer);
485 while (fext != buffer &&
486 *(fext -1) != '\\' &&
490 ALLOC(moduleName,strlen(fext)+1);
491 strcpy(moduleName,fext);
496 /* if the extention is type .rel or .r or .REL or .R
497 addtional object file will be passed to the linker */
498 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
499 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
500 strcmp(fext, port->linker.rel_ext) == 0)
502 relFiles[nrelFiles++] = s;
506 /* if .lib or .LIB */
507 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
508 libFiles[nlibFiles++] = s;
512 werror(W_UNKNOWN_FEXT,s);
516 static void _processC1Arg(char *s)
519 if (options.out_name) {
520 werror(W_TOO_MANY_SRC,s);
523 options.out_name = strdup(s);
530 static void _addToList(const char **list, const char *str)
532 /* This is the bad way to do things :) */
537 werror(E_OUT_OF_MEM,__FILE__, 0);
543 static void _setModel(int model, const char *sz)
545 if (port->general.supported_models & model)
546 options.model = model;
548 werror(W_UNSUPPORTED_MODEL, sz, port->target);
551 /*-----------------------------------------------------------------*/
552 /* parseCmdLine - parses the command line and sets the options */
553 /*-----------------------------------------------------------------*/
554 int parseCmdLine ( int argc, char **argv )
559 /* go thru all whole command line */
560 for ( i = 1; i < argc; i++ ) {
565 if (argv[i][0] == '-' && argv[i][1] == '-') {
567 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
572 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
573 options.regExtend = 1;
577 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
578 _setModel(MODEL_LARGE, argv[i]);
582 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
583 _setModel(MODEL_MEDIUM, argv[i]);
587 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
588 _setModel(MODEL_SMALL, argv[i]);
592 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
593 _setModel(MODEL_FLAT24, argv[i]);
597 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
598 options.stack10bit = 1;
602 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
603 options.stackAuto = 1;
607 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
608 options.dump_raw = 1;
612 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
613 options.cyclomatic = 1;
617 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
618 options.dump_gcse = 1;
622 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
623 options.dump_loop = 1;
627 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
628 options.dump_kill = 1;
632 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
633 options.intlong_rent = 1;
637 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
638 options.float_rent = 1;
642 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
643 options.dump_range = 1;
647 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
648 options.dump_pack = 1;
652 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
653 options.dump_rassgn = 1;
657 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
662 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
667 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
668 options.noOverlay = 1;
672 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
673 options.stackOnData = 1;
677 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
682 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
688 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
689 options.dump_rassgn =
695 options.dump_raw = 1;
699 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
704 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
705 options.genericPtr = 1;
709 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
714 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
719 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
724 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
729 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
730 options.noregparms = 1;
734 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
735 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
737 &argv[i][1+strlen(OPTION_PEEP_FILE)];
739 options.peep_file = argv[++i];
743 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
744 if (argv[i][1+strlen(OPTION_LIB_PATH)])
745 libPaths[nlibPaths++] =
746 &argv[i][1+strlen(OPTION_PEEP_FILE)];
748 libPaths[nlibPaths++] = argv[++i];
752 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
754 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
756 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
759 (int) floatFromVal(constVal(argv[++i]));
763 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
764 options.useXstack = 1;
768 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
769 options.mainreturn = 1;
773 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
774 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
775 parseWithComma(options.calleeSaves
776 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
778 parseWithComma(options.calleeSaves,argv[++i]);
782 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
784 if (argv[i][1+strlen(OPTION_STACK_LOC)])
786 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
789 (int) floatFromVal(constVal(argv[++i]));
793 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
795 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
797 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
800 (unsigned int) floatFromVal(constVal(argv[++i]));
804 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
806 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
808 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
811 (int) floatFromVal(constVal(argv[++i]));
815 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
821 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
823 if (argv[i][1+strlen(OPTION_DATA_LOC)])
825 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
828 (int) floatFromVal(constVal(argv[++i]));
832 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
834 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
836 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
839 (int) floatFromVal(constVal(argv[++i]));
843 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
845 if (argv[i][1+strlen(OPTION_CODE_LOC)])
847 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
850 (int) floatFromVal(constVal(argv[++i]));
855 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
856 optimize.noJTabBoundary = 1;
860 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
861 optimize.global_cse = 0;
865 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
866 optimize.loopInvariant = 0;
870 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
871 optimize.loopInduction = 0;
875 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
876 optimize.noLoopReverse = 1;
880 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
885 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
890 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
895 if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
900 if (!port->parseOption(&argc, argv, &i))
902 werror(W_UNKNOWN_OPTION,argv[i]);
910 /* these are undocumented options */
911 /* if preceded by '/' then turn off certain optmizations, used
912 for debugging only these are also the legacy options from
913 version 1.xx will be removed gradually.
914 It may be an absolute filename.
916 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
917 switch (argv[i][1]) {
920 optimize.ptrArithmetic=0;
924 switch (argv[i][2]) {
929 optimize.label4 = 0 ;
947 switch (argv[i][2]) {
949 optimize.loopInvariant = 0;
952 optimize.loopInduction = 0;
959 optimize.global_cse = 0;
966 /* if preceded by '-' then option */
967 if ( *argv[i] == '-' ) {
968 switch (argv[i][1]) {
979 /* Used to select the port */
980 if (_setPort(argv[i] + 2)) {
981 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
986 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
990 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
993 case 'X' : /* use external stack */
994 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
998 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
1001 case 'p' : /* stack pointer intial value */
1003 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
1007 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
1011 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
1015 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
1019 options.cc_only = 1;
1023 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
1028 libPaths[nlibPaths++] = &argv[i][2];
1030 libPaths[nlibPaths++] = argv[++i];
1034 /* linker options */
1035 if (argv[i][2] == 'l') {
1037 parseWithComma(linkOptions,&argv[i][3]);
1039 parseWithComma(linkOptions,argv[++i]);
1041 /* assembler options */
1042 if (argv[i][2] == 'a') {
1044 parseWithComma((char **)asmOptions,&argv[i][3]);
1046 parseWithComma((char **)asmOptions,argv[++i]);
1049 werror(W_UNKNOWN_OPTION,argv[i]);
1066 /* preprocessor options */
1070 _addToList(preArgv, "-M");
1075 _addToList(preArgv, "-C");
1084 char sOpt = argv[i][1] ;
1087 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1092 rest = &argv[i][2] ;
1094 if ( argv[i][1] == 'Y' )
1097 sprintf(buffer, "-%c%s", sOpt, rest);
1098 _addToList(preArgv, buffer);
1103 if (!port->parseOption(&argc, argv, &i))
1104 werror(W_UNKNOWN_OPTION,argv[i]);
1109 if (!port->parseOption(&argc, argv, &i)) {
1110 /* no option must be a filename */
1112 _processC1Arg(argv[i]);
1114 processFile(argv[i]);
1118 /* set up external stack location if not explicitly specified */
1119 if ( !options.xstack_loc )
1120 options.xstack_loc = options.xdata_loc ;
1122 /* if debug option is set the open the cdbFile */
1123 if (!options.nodebug && srcFileName) {
1124 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1125 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1126 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1128 /* add a module record */
1129 fprintf(cdbFile,"M:%s\n",moduleName);
1135 /*-----------------------------------------------------------------*/
1136 /* my_system - will call a program with arguments */
1137 /*-----------------------------------------------------------------*/
1139 #if defined(_MSC_VER)
1141 char *try_dir[]= {NULL}; // TODO : Fill in some default search list
1145 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1146 char *try_dir[]= {NULL};
1150 #ifdef USE_SYSTEM_SYSTEM_CALLS
1151 int my_system (const char *cmd)
1153 int argsStart, e, i=0;
1156 argsStart=strstr(cmd, " ")-cmd;
1158 // try to find the command in predefined path's
1159 while (try_dir[i]) {
1160 cmdLine = (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1161 strcpy(cmdLine, try_dir[i]); // the path
1162 strcat(cmdLine, "/");
1163 strncat(cmdLine, cmd, argsStart); // the command
1165 strcat(cmdLine, ".exe");
1166 /* Mung slashes into backslashes to keep WIndoze happy. */
1177 if (access(cmdLine, X_OK) == 0) {
1179 strcat(cmdLine, cmd+argsStart);
1188 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1192 // command found in predefined path
1202 int my_system (const char *cmd, char **cmd_argv)
1204 char *dir, *got= NULL; int i= 0;
1206 while (!got && try_dir[i])
1208 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1209 strcpy(dir, try_dir[i]);
1214 strcat(dir, ".exe");
1216 /* Mung slashes into backslashes to keep WIndoze happy. */
1232 if (access(dir, X_OK) == 0)
1241 char **pCmd = cmd_argv;
1244 printf("%s ", *pCmd);
1252 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1256 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1258 perror("Cannot exec process ");
1266 /*-----------------------------------------------------------------*/
1267 /* linkEdit : - calls the linkage editor with options */
1268 /*-----------------------------------------------------------------*/
1269 static void linkEdit (char **envp)
1272 #ifndef USE_SYSTEM_SYSTEM_CALLS
1279 srcFileName = "temp";
1281 /* first we need to create the <filename>.lnk file */
1282 sprintf(buffer,"%s.lnk",srcFileName);
1283 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) {
1329 if (IS_DS390_PORT) {
1332 switch(options.model)
1344 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1349 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1351 /* standard library files */
1352 if (strcmp(port->target, "ds390")==0) {
1353 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1355 fprintf (lnkfile,"-l %s\n",STD_LIB);
1356 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1357 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1358 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1361 /* additional libraries if any */
1362 for (i = 0 ; i < nlibFiles; i++)
1363 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1365 /* put in the object files */
1366 if (strcmp(srcFileName,"temp"))
1367 fprintf (lnkfile,"%s ",srcFileName);
1369 for (i = 0 ; i < nrelFiles ; i++ )
1370 fprintf (lnkfile,"%s\n",relFiles[i]);
1372 fprintf (lnkfile,"\n-e\n");
1375 if (options.verbose)
1376 printf ("sdcc: Calling linker...\n");
1378 #ifdef USE_SYSTEM_SYSTEM_CALLS
1379 buildCmdLine(buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1380 if (my_system(buffer)) {
1384 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1385 if (my_system(argv[0], argv)) {
1386 perror("Cannot exec linker");
1392 if (strcmp(srcFileName,"temp") == 0) {
1393 /* rename "temp.cdb" to "firstRelFile.cdb" */
1394 char *f = strtok(strdup(relFiles[0]),".");
1395 f = strcat(f,".cdb");
1396 rename("temp.cdb",f);
1401 /*-----------------------------------------------------------------*/
1402 /* assemble - spawns the assembler with arguments */
1403 /*-----------------------------------------------------------------*/
1404 static void assemble (char **envp)
1406 #ifdef USE_SYSTEM_SYSTEM_CALLS
1407 buildCmdLine(buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1408 if (my_system(buffer)) {
1412 char *argv[128]; /* assembler arguments */
1414 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1416 if (my_system(argv[0], argv)) {
1417 perror("Cannot exec assembler");
1425 /*-----------------------------------------------------------------*/
1426 /* preProcess - spawns the preprocessor with arguments */
1427 /*-----------------------------------------------------------------*/
1428 static int preProcess (char **envp)
1430 #ifndef USE_SYSTEM_SYSTEM_CALLS
1437 if (!options.c1mode) {
1438 /* if using external stack define the macro */
1439 if ( options.useXstack )
1440 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1442 /* set the macro for stack autos */
1443 if ( options.stackAuto )
1444 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1446 /* set the macro for stack autos */
1447 if ( options.stack10bit )
1448 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1450 /* set the macro for large model */
1451 switch(options.model)
1454 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1457 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1460 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1463 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1466 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1469 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1474 /* add port (processor information to processor */
1475 sprintf(procDef,"-DSDCC_%s",port->target);
1476 _addToList(preArgv,procDef);
1479 preOutName = strdup(tmpnam(NULL));
1481 if (options.verbose)
1482 printf ("sdcc: Calling preprocessor...\n");
1484 #ifdef USE_SYSTEM_SYSTEM_CALLS
1485 buildCmdLine(buffer, _preCmd, fullSrcFileName,
1486 preOutName, srcFileName, preArgv);
1487 if (my_system(buffer)) {
1491 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1492 preOutName, srcFileName, preArgv);
1494 if (my_system(argv[0], argv)) {
1495 unlink (preOutName);
1496 perror("Cannot exec Preprocessor");
1505 preOutName = fullSrcFileName;
1508 yyin = fopen(preOutName, "r");
1510 perror("Preproc file not found\n");
1517 static void _findPort(int argc, char **argv)
1523 if (!strncmp(*argv, "-m", 2)) {
1524 _setPort(*argv + 2);
1530 /* Use the first in the list */
1536 * initialises and calls the parser
1539 int main ( int argc, char **argv , char **envp)
1541 /* turn all optimizations off by default */
1542 memset(&optimize,0,sizeof(struct optimize));
1544 /*printVersionInfo ();*/
1546 _findPort(argc, argv);
1547 /* Initalise the port. */
1551 setDefaultOptions();
1552 parseCmdLine(argc,argv);
1556 port->finaliseOptions();
1558 /* if no input then printUsage & exit */
1559 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1572 if (options.verbose)
1573 printf ("sdcc: Generating code...\n");
1579 /* TSD PIC port hack - if the PIC port option is enabled
1580 and SDCC is used to generate PIC code, then we will
1581 generate .asm files in gpasm's format instead of SDCC's
1584 #if !OPT_DISABLE_PIC
1594 if (!options.c1mode)
1596 if (options.verbose)
1597 printf ("sdcc: Calling assembler...\n");
1612 if (!options.cc_only &&
1616 (srcFileName || nrelFiles)) {
1617 if (port->linker.do_link)
1618 port->linker.do_link();
1623 if (yyin && yyin != stdin)
1626 if (preOutName && !options.c1mode) {