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 //printf ("%s\n", from);
215 /* See if it has a '$' anywhere - if not, just copy */
216 if ((p = strchr(from, '$'))) {
217 strncat(into, from, p - from);
236 const char **tmp = list;
239 //printf ("list: %s\n", *tmp);
251 strcat(into, from); // this include the ".asm" from "$1.asm"
256 void buildCmdLine(char *into, char **args, const char **cmds,
257 const char *p1, const char *p2,
258 const char *p3, const char **list)
260 const char *p, *from;
270 /* See if it has a '$' anywhere - if not, just copy */
271 if ((p = strchr(from, '$'))) {
272 strncpy(into, from, p - from);
273 /* NULL terminate it */
291 const char **tmp = list;
295 into += strlen(into)+1;
308 if (strlen(into) == 0)
310 into += strlen(into)+1;
316 /*-----------------------------------------------------------------*/
317 /* printVersionInfo - prints the version info */
318 /*-----------------------------------------------------------------*/
319 void printVersionInfo ()
325 for (i=0; i<NUM_PORTS; i++)
326 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
327 fprintf(stderr, " %s"
328 #ifdef SDCC_SUB_VERSION_STR
329 "/" SDCC_SUB_VERSION_STR
346 /*-----------------------------------------------------------------*/
347 /* printUsage - prints command line syntax */
348 /*-----------------------------------------------------------------*/
353 "Usage : [options] filename\n"
355 "\t-m<proc> - Target processor <proc>. Default %s\n"
356 "\t Try --version for supported values of <proc>\n"
357 "\t--model-large - Large Model\n"
358 "\t--model-small - Small Model (default)\n"
359 "\t--stack-auto - Stack automatic variables\n"
360 "\t--xstack - Use external stack\n"
361 "\t--xram-loc <nnnn> - External Ram start location\n"
362 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
363 "\t--code-loc <nnnn> - Code Segment Location\n"
364 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
365 "\t--data-loc <nnnn> - Direct data start location\n"
366 "\t--idata-loc <nnnn> - Indirect data start location\n"
367 "\t--iram-size <nnnn> - Internal Ram size\n"
368 "\t--nojtbound - Don't generate boundary check for jump tables\n"
369 "\t--generic - All unqualified ptrs converted to '_generic'\n"
370 "PreProcessor Options :-\n"
371 "\t-Dmacro - Define Macro\n"
372 "\t-Ipath - Include \"*.h\" path\n"
373 "Note: this is NOT a complete list of options see docs for details\n",
379 /*-----------------------------------------------------------------*/
380 /* parseWithComma - separates string with comma */
381 /*-----------------------------------------------------------------*/
382 void parseWithComma (char **dest,char *src)
387 /* skip the initial white spaces */
388 while (isspace(*src)) src++;
402 /*-----------------------------------------------------------------*/
403 /* setDefaultOptions - sets the default options */
404 /*-----------------------------------------------------------------*/
405 static void setDefaultOptions()
409 for ( i = 0 ; i < 128 ; i++)
410 preArgv[i] = asmOptions [i] =
411 linkOptions[i] = relFiles[i] = libFiles[i] =
414 /* first the options part */
415 options.stack_loc = 0; /* stack pointer initialised to 0 */
416 options.xstack_loc= 0; /* xternal stack starts at 0 */
417 options.code_loc = 0; /* code starts at 0 */
418 options.data_loc = 0x0030; /* data starts at 0x0030 */
419 options.xdata_loc = 0;
420 options.idata_loc = 0x80;
421 options.genericPtr = 1; /* default on */
423 options.model = port->general.default_model;
428 /* now for the optimizations */
429 /* turn on the everything */
430 optimize.global_cse = 1;
435 optimize.loopInvariant = 1;
436 optimize.loopInduction = 1;
438 port->setDefaultOptions();
441 /*-----------------------------------------------------------------*/
442 /* processFile - determines the type of file from the extension */
443 /*-----------------------------------------------------------------*/
444 static void processFile (char *s)
448 /* get the file extension */
449 fext = s + strlen(s);
450 while ((fext != s) && *fext != '.') fext--;
452 /* now if no '.' then we don't know what the file type is
453 so give a warning and return */
455 werror(W_UNKNOWN_FEXT,s);
459 /* otherwise depending on the file type */
460 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
461 /* source file name : not if we already have a
464 werror(W_TOO_MANY_SRC,s);
468 /* the only source file */
469 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
470 werror(E_FILE_OPEN_ERR,s);
474 /* copy the file name into the buffer */
477 /* get rid of the "." */
479 ALLOC(srcFileName,strlen(buffer)+1);
480 strcpy(srcFileName,buffer);
482 /* get rid of any path information
483 for the module name; do this by going
484 backwards till we get to either '/' or '\' or ':'
485 or start of buffer */
486 fext = buffer + strlen(buffer);
487 while (fext != buffer &&
488 *(fext -1) != '\\' &&
492 ALLOC(moduleName,strlen(fext)+1);
493 strcpy(moduleName,fext);
498 /* if the extention is type .rel or .r or .REL or .R
499 addtional object file will be passed to the linker */
500 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
501 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
502 strcmp(fext, port->linker.rel_ext) == 0)
504 relFiles[nrelFiles++] = s;
508 /* if .lib or .LIB */
509 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
510 libFiles[nlibFiles++] = s;
514 werror(W_UNKNOWN_FEXT,s);
518 static void _processC1Arg(char *s)
521 if (options.out_name) {
522 werror(W_TOO_MANY_SRC,s);
525 options.out_name = strdup(s);
532 static void _addToList(const char **list, const char *str)
534 /* This is the bad way to do things :) */
539 werror(E_OUT_OF_MEM,__FILE__, 0);
545 static void _setModel(int model, const char *sz)
547 if (port->general.supported_models & model)
548 options.model = model;
550 werror(W_UNSUPPORTED_MODEL, sz, port->target);
553 /*-----------------------------------------------------------------*/
554 /* parseCmdLine - parses the command line and sets the options */
555 /*-----------------------------------------------------------------*/
556 int parseCmdLine ( int argc, char **argv )
561 /* go thru all whole command line */
562 for ( i = 1; i < argc; i++ ) {
567 if (argv[i][0] == '-' && argv[i][1] == '-') {
569 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
574 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
575 options.regExtend = 1;
579 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
580 _setModel(MODEL_LARGE, argv[i]);
584 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
585 _setModel(MODEL_MEDIUM, argv[i]);
589 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
590 _setModel(MODEL_SMALL, argv[i]);
594 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
595 _setModel(MODEL_FLAT24, argv[i]);
599 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
600 options.stack10bit = 1;
604 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
605 options.stackAuto = 1;
609 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
610 options.dump_raw = 1;
614 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
615 options.cyclomatic = 1;
619 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
620 options.dump_gcse = 1;
624 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
625 options.dump_loop = 1;
629 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
630 options.dump_kill = 1;
634 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
635 options.intlong_rent = 1;
639 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
640 options.float_rent = 1;
644 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
645 options.dump_range = 1;
649 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
650 options.dump_pack = 1;
654 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
655 options.dump_rassgn = 1;
659 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
664 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
669 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
670 options.noOverlay = 1;
674 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
675 options.stackOnData = 1;
679 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
684 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
690 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
691 options.dump_rassgn =
697 options.dump_raw = 1;
701 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
706 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
707 options.genericPtr = 1;
711 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
716 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
721 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
726 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
731 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
732 options.noregparms = 1;
736 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
737 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
739 &argv[i][1+strlen(OPTION_PEEP_FILE)];
741 options.peep_file = argv[++i];
745 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
746 if (argv[i][1+strlen(OPTION_LIB_PATH)])
747 libPaths[nlibPaths++] =
748 &argv[i][1+strlen(OPTION_PEEP_FILE)];
750 libPaths[nlibPaths++] = argv[++i];
754 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
756 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
758 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
761 (int) floatFromVal(constVal(argv[++i]));
765 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
766 options.useXstack = 1;
770 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
771 options.mainreturn = 1;
775 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
776 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
777 parseWithComma(options.calleeSaves
778 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
780 parseWithComma(options.calleeSaves,argv[++i]);
784 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
786 if (argv[i][1+strlen(OPTION_STACK_LOC)])
788 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
791 (int) floatFromVal(constVal(argv[++i]));
795 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
797 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
799 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
802 (unsigned int) floatFromVal(constVal(argv[++i]));
806 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
808 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
810 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
813 (int) floatFromVal(constVal(argv[++i]));
817 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
823 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
825 if (argv[i][1+strlen(OPTION_DATA_LOC)])
827 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
830 (int) floatFromVal(constVal(argv[++i]));
834 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
836 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
838 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
841 (int) floatFromVal(constVal(argv[++i]));
845 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
847 if (argv[i][1+strlen(OPTION_CODE_LOC)])
849 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
852 (int) floatFromVal(constVal(argv[++i]));
857 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
858 optimize.noJTabBoundary = 1;
862 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
863 optimize.global_cse = 0;
867 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
868 optimize.loopInvariant = 0;
872 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
873 optimize.loopInduction = 0;
877 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
878 optimize.noLoopReverse = 1;
882 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
887 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
892 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
897 if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
902 if (!port->parseOption(&argc, argv, &i))
904 werror(W_UNKNOWN_OPTION,argv[i]);
912 /* these are undocumented options */
913 /* if preceded by '/' then turn off certain optmizations, used
914 for debugging only these are also the legacy options from
915 version 1.xx will be removed gradually.
916 It may be an absolute filename.
918 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
919 switch (argv[i][1]) {
922 optimize.ptrArithmetic=0;
926 switch (argv[i][2]) {
931 optimize.label4 = 0 ;
949 switch (argv[i][2]) {
951 optimize.loopInvariant = 0;
954 optimize.loopInduction = 0;
961 optimize.global_cse = 0;
968 /* if preceded by '-' then option */
969 if ( *argv[i] == '-' ) {
970 switch (argv[i][1]) {
981 /* Used to select the port */
982 if (_setPort(argv[i] + 2)) {
983 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
988 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
992 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
995 case 'X' : /* use external stack */
996 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
1000 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
1003 case 'p' : /* stack pointer intial value */
1005 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
1009 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
1013 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
1017 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
1021 options.cc_only = 1;
1025 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
1030 libPaths[nlibPaths++] = &argv[i][2];
1032 libPaths[nlibPaths++] = argv[++i];
1036 /* linker options */
1037 if (argv[i][2] == 'l') {
1039 parseWithComma(linkOptions,&argv[i][3]);
1041 parseWithComma(linkOptions,argv[++i]);
1043 /* assembler options */
1044 if (argv[i][2] == 'a') {
1046 parseWithComma((char **)asmOptions,&argv[i][3]);
1048 parseWithComma((char **)asmOptions,argv[++i]);
1051 werror(W_UNKNOWN_OPTION,argv[i]);
1068 /* preprocessor options */
1072 _addToList(preArgv, "-M");
1077 _addToList(preArgv, "-C");
1086 char sOpt = argv[i][1] ;
1089 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1094 rest = &argv[i][2] ;
1096 if ( argv[i][1] == 'Y' )
1099 sprintf(buffer, "-%c%s", sOpt, rest);
1100 _addToList(preArgv, buffer);
1105 if (!port->parseOption(&argc, argv, &i))
1106 werror(W_UNKNOWN_OPTION,argv[i]);
1111 if (!port->parseOption(&argc, argv, &i)) {
1112 /* no option must be a filename */
1114 _processC1Arg(argv[i]);
1116 processFile(argv[i]);
1120 /* set up external stack location if not explicitly specified */
1121 if ( !options.xstack_loc )
1122 options.xstack_loc = options.xdata_loc ;
1124 /* if debug option is set the open the cdbFile */
1125 if (!options.nodebug && srcFileName) {
1126 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1127 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1128 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1130 /* add a module record */
1131 fprintf(cdbFile,"M:%s\n",moduleName);
1137 /*-----------------------------------------------------------------*/
1138 /* my_system - will call a program with arguments */
1139 /*-----------------------------------------------------------------*/
1141 #ifdef USE_SYSTEM_SYSTEM_CALLS
1142 int my_system (const char *cmd)
1145 /* Mung slashes into backslashes to keep WIndoze happy. */
1161 //printf ("my_system(%s)\n",cmd);
1163 printf ("+ %s\n", cmd);
1165 return (system(cmd));
1168 #if defined(_MSC_VER)
1170 char *try_dir[]= {NULL}; // TODO : Fill in some default search list
1174 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1178 int my_system (const char *cmd, char **cmd_argv)
1180 char *dir, *got= NULL; int i= 0;
1182 while (!got && try_dir[i])
1184 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1185 strcpy(dir, try_dir[i]);
1190 strcat(dir, ".exe");
1192 /* Mung slashes into backslashes to keep WIndoze happy. */
1208 if (access(dir, X_OK) == 0)
1217 char **pCmd = cmd_argv;
1220 printf("%s ", *pCmd);
1228 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1232 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1234 perror("Cannot exec process ");
1242 /*-----------------------------------------------------------------*/
1243 /* linkEdit : - calls the linkage editor with options */
1244 /*-----------------------------------------------------------------*/
1245 static void linkEdit (char **envp)
1248 #ifndef USE_SYSTEM_SYSTEM_CALLS
1255 srcFileName = "temp";
1257 /* first we need to create the <filename>.lnk file */
1258 sprintf(buffer,"%s.lnk",srcFileName);
1259 if (!(lnkfile = fopen(buffer,"w"))) {
1260 werror(E_FILE_OPEN_ERR,buffer);
1264 /* now write the options */
1265 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1267 /* if iram size specified */
1268 if (options.iram_size)
1269 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1271 /*if (options.debug) */
1272 fprintf(lnkfile,"-z\n");
1274 #define WRITE_SEG_LOC(N, L) \
1275 segName = strdup(N); \
1276 c = strtok(segName, " \t"); \
1277 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1278 if (segName) { free(segName); }
1280 /* code segment start */
1281 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1283 /* data segment start */
1284 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1287 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1290 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1292 /* bit segment start */
1293 WRITE_SEG_LOC(BIT_NAME, 0);
1295 /* add the extra linker options */
1296 for (i=0; linkOptions[i] ; i++)
1297 fprintf(lnkfile,"%s\n",linkOptions[i]);
1299 /* other library paths if specified */
1300 for (i = 0 ; i < nlibPaths ; i++ )
1301 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1303 /* standard library path */
1304 if (!options.nostdlib) {
1305 if (IS_DS390_PORT) {
1308 switch(options.model)
1320 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1325 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1327 /* standard library files */
1328 if (strcmp(port->target, "ds390")==0) {
1329 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1331 fprintf (lnkfile,"-l %s\n",STD_LIB);
1332 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1333 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1334 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1337 /* additional libraries if any */
1338 for (i = 0 ; i < nlibFiles; i++)
1339 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1341 /* put in the object files */
1342 if (strcmp(srcFileName,"temp"))
1343 fprintf (lnkfile,"%s ",srcFileName);
1345 for (i = 0 ; i < nrelFiles ; i++ )
1346 fprintf (lnkfile,"%s\n",relFiles[i]);
1348 fprintf (lnkfile,"\n-e\n");
1351 if (options.verbose)
1352 printf ("sdcc: Calling linker...\n");
1354 #ifdef USE_SYSTEM_SYSTEM_CALLS
1355 buildCmdLine(buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1356 // ignore linker errors for now, not tested
1359 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1360 if (my_system(argv[0], argv)) {
1361 perror("Cannot exec linker");
1367 if (strcmp(srcFileName,"temp") == 0) {
1368 /* rename "temp.cdb" to "firstRelFile.cdb" */
1369 char *f = strtok(strdup(relFiles[0]),".");
1370 f = strcat(f,".cdb");
1371 rename("temp.cdb",f);
1376 /*-----------------------------------------------------------------*/
1377 /* assemble - spawns the assembler with arguments */
1378 /*-----------------------------------------------------------------*/
1379 static void assemble (char **envp)
1381 #ifdef USE_SYSTEM_SYSTEM_CALLS
1382 buildCmdLine(buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1383 if (my_system(buffer)) {
1384 fprintf (stderr, "sdcc: aborted while assembling, look above for messages (if any :)\n");
1388 char *argv[128]; /* assembler arguments */
1390 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1392 if (my_system(argv[0], argv)) {
1393 perror("Cannot exec assembler");
1401 /*-----------------------------------------------------------------*/
1402 /* preProcess - spawns the preprocessor with arguments */
1403 /*-----------------------------------------------------------------*/
1404 static int preProcess (char **envp)
1406 #ifndef USE_SYSTEM_SYSTEM_CALLS
1413 if (!options.c1mode) {
1414 /* if using external stack define the macro */
1415 if ( options.useXstack )
1416 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1418 /* set the macro for stack autos */
1419 if ( options.stackAuto )
1420 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1422 /* set the macro for stack autos */
1423 if ( options.stack10bit )
1424 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1426 /* set the macro for large model */
1427 switch(options.model)
1430 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1433 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1436 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1439 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1442 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1445 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1450 /* add port (processor information to processor */
1451 sprintf(procDef,"-DSDCC_%s",port->target);
1452 _addToList(preArgv,procDef);
1455 preOutName = strdup(tmpnam(NULL));
1457 if (options.verbose)
1458 printf ("sdcc: Calling preprocessor...\n");
1460 #ifdef USE_SYSTEM_SYSTEM_CALLS
1461 buildCmdLine(buffer, _preCmd, fullSrcFileName,
1462 preOutName, srcFileName, preArgv);
1465 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1466 preOutName, srcFileName, preArgv);
1468 if (my_system(argv[0], argv)) {
1469 unlink (preOutName);
1470 perror("Cannot exec Preprocessor");
1479 preOutName = fullSrcFileName;
1482 yyin = fopen(preOutName, "r");
1484 perror("Preproc file not found\n");
1491 static void _findPort(int argc, char **argv)
1497 if (!strncmp(*argv, "-m", 2)) {
1498 _setPort(*argv + 2);
1504 /* Use the first in the list */
1510 * initialises and calls the parser
1513 int main ( int argc, char **argv , char **envp)
1515 /* turn all optimizations off by default */
1516 memset(&optimize,0,sizeof(struct optimize));
1518 /*printVersionInfo ();*/
1520 _findPort(argc, argv);
1521 /* Initalise the port. */
1525 setDefaultOptions();
1526 parseCmdLine(argc,argv);
1530 port->finaliseOptions();
1532 /* if no input then printUsage & exit */
1533 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1546 if (options.verbose)
1547 printf ("sdcc: Generating code...\n");
1553 /* TSD PIC port hack - if the PIC port option is enabled
1554 and SDCC is used to generate PIC code, then we will
1555 generate .asm files in gpasm's format instead of SDCC's
1558 #if !OPT_DISABLE_PIC
1568 if (!options.c1mode)
1570 if (options.verbose)
1571 printf ("sdcc: Calling assembler...\n");
1586 if (!options.cc_only &&
1590 (srcFileName || nrelFiles)) {
1591 if (port->linker.do_link)
1592 port->linker.do_link();
1597 if (yyin && yyin != stdin)
1600 if (preOutName && !options.c1mode) {