1 /*-------------------------------------------------------------------------
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
34 // This is a bit messy because we define link ourself
35 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
40 // No unistd.h in Borland C++
41 extern int access(const char *, int);
48 FILE *srcFile ;/* source file */
49 FILE *cdbFile = NULL ;/* debugger information output file */
50 char *fullSrcFileName ;/* full name for the source file */
51 char *srcFileName ;/* source file name with the .c stripped */
52 char *moduleName ;/* module name is srcFilename stripped of any path */
53 const char *preArgv[128] ;/* pre-processor arguments */
55 struct optimize optimize ;
56 struct options options ;
57 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
58 short preProcOnly = 0;
60 char *linkOptions[128];
61 const char *asmOptions[128];
68 bool verboseExec = FALSE;
71 /* Far functions, far data */
72 #define OPTION_LARGE_MODEL "-model-large"
73 /* Far functions, near data */
74 #define OPTION_MEDIUM_MODEL "-model-medium"
75 #define OPTION_SMALL_MODEL "-model-small"
76 #define OPTION_FLAT24_MODEL "-model-flat24"
77 #define OPTION_STACK_AUTO "-stack-auto"
78 #define OPTION_STACK_10BIT "-stack-10bit"
79 #define OPTION_XSTACK "-xstack"
80 #define OPTION_GENERIC "-generic"
81 #define OPTION_NO_GCSE "-nogcse"
82 #define OPTION_NO_LOOP_INV "-noinvariant"
83 #define OPTION_NO_LOOP_IND "-noinduction"
84 #define OPTION_NO_JTBOUND "-nojtbound"
85 #define OPTION_NO_LOOPREV "-noloopreverse"
86 #define OPTION_XREGS "-regextend"
87 #define OPTION_COMP_ONLY "-compile-only"
88 #define OPTION_DUMP_RAW "-dumpraw"
89 #define OPTION_DUMP_GCSE "-dumpgcse"
90 #define OPTION_DUMP_LOOP "-dumploop"
91 #define OPTION_DUMP_KILL "-dumpdeadcode"
92 #define OPTION_DUMP_RANGE "-dumpliverange"
93 #define OPTION_DUMP_PACK "-dumpregpack"
94 #define OPTION_DUMP_RASSGN "-dumpregassign"
95 #define OPTION_DUMP_ALL "-dumpall"
96 #define OPTION_XRAM_LOC "-xram-loc"
97 #define OPTION_IRAM_SIZE "-iram-size"
98 #define OPTION_XSTACK_LOC "-xstack-loc"
99 #define OPTION_CODE_LOC "-code-loc"
100 #define OPTION_STACK_LOC "-stack-loc"
101 #define OPTION_DATA_LOC "-data-loc"
102 #define OPTION_IDATA_LOC "-idata-loc"
103 #define OPTION_PEEP_FILE "-peep-file"
104 #define OPTION_LIB_PATH "-lib-path"
105 #define OPTION_INTLONG_RENT "-int-long-reent"
106 #define OPTION_FLOAT_RENT "-float-reent"
107 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
108 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
109 #define OPTION_CYCLOMATIC "-cyclomatic"
110 #define OPTION_NOOVERLAY "-nooverlay"
111 #define OPTION_MAINRETURN "-main-return"
112 #define OPTION_NOPEEP "-no-peep"
113 #define OPTION_ASMPEEP "-peep-asm"
114 #define OPTION_DEBUG "-debug"
115 #define OPTION_NODEBUG "-nodebug"
116 #define OPTION_VERSION "-version"
117 #define OPTION_STKAFTRDATA "-stack-after-data"
118 #define OPTION_PREPROC_ONLY "-preprocessonly"
119 #define OPTION_C1_MODE "-c1mode"
120 #define OPTION_HELP "-help"
121 #define OPTION_CALLEE_SAVES "-callee-saves"
122 #define OPTION_NOREGPARMS "-noregparms"
123 #define OPTION_NOSTDLIB "-nostdlib"
124 #define OPTION_NOSTDINC "-nostdinc"
125 #define OPTION_VERBOSE "-verbose"
126 #define OPTION_ANSIINT "-ansiint"
127 static const char *_preCmd[] = {
128 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
129 "$l", "-I" SDCC_INCLUDE_DIR, "$1", "$2", NULL
134 static PORT *_ports[] = {
135 #if !OPT_DISABLE_MCS51
138 #if !OPT_DISABLE_GBZ80
147 #if !OPT_DISABLE_DS390
155 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
158 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
160 extern void pic14glue();
162 /** Sets the port to the one given by the command line option.
163 @param The name minus the option (eg 'mcs51')
164 @return 0 on success.
166 static int _setPort(const char *name)
169 for (i=0; i<NUM_PORTS; i++) {
170 if (!strcmp(_ports[i]->target, name)) {
175 /* Error - didnt find */
176 werror(E_UNKNOWN_TARGET,name);
180 void buildCmdLine(char *into, char **args, const char **cmds,
181 const char *p1, const char *p2,
182 const char *p3, const char **list)
184 const char *p, *from;
194 /* See if it has a '$' anywhere - if not, just copy */
195 if ((p = strchr(from, '$'))) {
196 strncpy(into, from, p - from);
197 /* NULL terminate it */
215 const char **tmp = list;
219 into += strlen(into)+1;
232 if (strlen(into) == 0)
234 into += strlen(into)+1;
239 /*-----------------------------------------------------------------*/
240 /* printVersionInfo - prints the version info */
241 /*-----------------------------------------------------------------*/
242 void printVersionInfo ()
248 for (i=0; i<NUM_PORTS; i++)
249 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
250 fprintf(stderr, " %s"
251 #ifdef SDCC_SUB_VERSION_STR
252 "/" SDCC_SUB_VERSION_STR
269 /*-----------------------------------------------------------------*/
270 /* printUsage - prints command line syntax */
271 /*-----------------------------------------------------------------*/
276 "Usage : [options] filename\n"
278 "\t-m<proc> - Target processor <proc>. Default %s\n"
279 "\t Try --version for supported values of <proc>\n"
280 "\t--model-large - Large Model\n"
281 "\t--model-small - Small Model (default)\n"
282 "\t--stack-auto - Stack automatic variables\n"
283 "\t--xstack - Use external stack\n"
284 "\t--xram-loc <nnnn> - External Ram start location\n"
285 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
286 "\t--code-loc <nnnn> - Code Segment Location\n"
287 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
288 "\t--data-loc <nnnn> - Direct data start location\n"
289 "\t--idata-loc <nnnn> - Indirect data start location\n"
290 "\t--iram-size <nnnn> - Internal Ram size\n"
291 "\t--nojtbound - Don't generate boundary check for jump tables\n"
292 "\t--generic - All unqualified ptrs converted to '_generic'\n"
293 "PreProcessor Options :-\n"
294 "\t-Dmacro - Define Macro\n"
295 "\t-Ipath - Include \"*.h\" path\n"
296 "Note: this is NOT a complete list of options see docs for details\n",
302 /*-----------------------------------------------------------------*/
303 /* parseWithComma - separates string with comma */
304 /*-----------------------------------------------------------------*/
305 void parseWithComma (char **dest,char *src)
310 /* skip the initial white spaces */
311 while (isspace(*src)) src++;
325 /*-----------------------------------------------------------------*/
326 /* setDefaultOptions - sets the default options */
327 /*-----------------------------------------------------------------*/
328 static void setDefaultOptions()
332 for ( i = 0 ; i < 128 ; i++)
333 preArgv[i] = asmOptions [i] =
334 linkOptions[i] = relFiles[i] = libFiles[i] =
337 /* first the options part */
338 options.stack_loc = 0; /* stack pointer initialised to 0 */
339 options.xstack_loc= 0; /* xternal stack starts at 0 */
340 options.code_loc = 0; /* code starts at 0 */
341 options.data_loc = 0x0030; /* data starts at 0x0030 */
342 options.xdata_loc = 0;
343 options.idata_loc = 0x80;
344 options.genericPtr = 1; /* default on */
346 options.model = port->general.default_model;
351 /* now for the optimizations */
352 /* turn on the everything */
353 optimize.global_cse = 1;
358 optimize.loopInvariant = 1;
359 optimize.loopInduction = 1;
361 port->setDefaultOptions();
364 /*-----------------------------------------------------------------*/
365 /* processFile - determines the type of file from the extension */
366 /*-----------------------------------------------------------------*/
367 static void processFile (char *s)
371 /* get the file extension */
372 fext = s + strlen(s);
373 while ((fext != s) && *fext != '.') fext--;
375 /* now if no '.' then we don't know what the file type is
376 so give a warning and return */
378 werror(W_UNKNOWN_FEXT,s);
382 /* otherwise depending on the file type */
383 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
384 /* source file name : not if we already have a
387 werror(W_TOO_MANY_SRC,s);
391 /* the only source file */
392 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
393 werror(E_FILE_OPEN_ERR,s);
397 /* copy the file name into the buffer */
400 /* get rid of the "." */
402 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
403 strcpy(srcFileName,buffer);
405 /* get rid of any path information
406 for the module name; do this by going
407 backwards till we get to either '/' or '\' or ':'
408 or start of buffer */
409 fext = buffer + strlen(buffer);
410 while (fext != buffer &&
411 *(fext -1) != '\\' &&
415 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
416 strcpy(moduleName,fext);
421 /* if the extention is type .rel or .r or .REL or .R
422 addtional object file will be passed to the linker */
423 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
424 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
425 strcmp(fext, port->linker.rel_ext) == 0)
427 relFiles[nrelFiles++] = s;
431 /* if .lib or .LIB */
432 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
433 libFiles[nlibFiles++] = s;
437 werror(W_UNKNOWN_FEXT,s);
441 static void _processC1Arg(char *s)
444 if (options.out_name) {
445 werror(W_TOO_MANY_SRC,s);
448 options.out_name = strdup(s);
455 static void _addToList(const char **list, const char *str)
457 /* This is the bad way to do things :) */
462 werror(E_OUT_OF_MEM,__FILE__, 0);
468 static void _setModel(int model, const char *sz)
470 if (port->general.supported_models & model)
471 options.model = model;
473 werror(W_UNSUPPORTED_MODEL, sz, port->target);
476 /*-----------------------------------------------------------------*/
477 /* parseCmdLine - parses the command line and sets the options */
478 /*-----------------------------------------------------------------*/
479 int parseCmdLine ( int argc, char **argv )
484 /* go thru all whole command line */
485 for ( i = 1; i < argc; i++ ) {
490 if (argv[i][0] == '-' && argv[i][1] == '-') {
492 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
497 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
498 options.regExtend = 1;
502 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
503 _setModel(MODEL_LARGE, argv[i]);
507 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
508 _setModel(MODEL_MEDIUM, argv[i]);
512 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
513 _setModel(MODEL_SMALL, argv[i]);
517 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
518 _setModel(MODEL_FLAT24, argv[i]);
522 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
523 options.stack10bit = 1;
527 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
528 options.stackAuto = 1;
532 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
533 options.dump_raw = 1;
537 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
538 options.cyclomatic = 1;
542 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
543 options.dump_gcse = 1;
547 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
548 options.dump_loop = 1;
552 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
553 options.dump_kill = 1;
557 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
558 options.intlong_rent = 1;
562 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
563 options.float_rent = 1;
567 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
568 options.dump_range = 1;
572 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
573 options.dump_pack = 1;
577 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
578 options.dump_rassgn = 1;
582 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
587 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
592 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
593 options.noOverlay = 1;
597 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
598 options.stackOnData = 1;
602 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
607 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
613 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
614 options.dump_rassgn =
620 options.dump_raw = 1;
624 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
629 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
630 options.genericPtr = 1;
634 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
639 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
644 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
649 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
654 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
655 options.noregparms = 1;
659 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
660 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
662 &argv[i][1+strlen(OPTION_PEEP_FILE)];
664 options.peep_file = argv[++i];
668 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
669 if (argv[i][1+strlen(OPTION_LIB_PATH)])
670 libPaths[nlibPaths++] =
671 &argv[i][1+strlen(OPTION_PEEP_FILE)];
673 libPaths[nlibPaths++] = argv[++i];
677 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
679 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
681 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
684 (int) floatFromVal(constVal(argv[++i]));
688 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
689 options.useXstack = 1;
693 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
694 options.mainreturn = 1;
698 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
699 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
700 parseWithComma(options.calleeSaves
701 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
703 parseWithComma(options.calleeSaves,argv[++i]);
707 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
709 if (argv[i][1+strlen(OPTION_STACK_LOC)])
711 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
714 (int) floatFromVal(constVal(argv[++i]));
718 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
720 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
722 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
725 (unsigned int) floatFromVal(constVal(argv[++i]));
729 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
731 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
733 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
736 (int) floatFromVal(constVal(argv[++i]));
740 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
746 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
748 if (argv[i][1+strlen(OPTION_DATA_LOC)])
750 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
753 (int) floatFromVal(constVal(argv[++i]));
757 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
759 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
761 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
764 (int) floatFromVal(constVal(argv[++i]));
768 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
770 if (argv[i][1+strlen(OPTION_CODE_LOC)])
772 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
775 (int) floatFromVal(constVal(argv[++i]));
780 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
781 optimize.noJTabBoundary = 1;
785 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
786 optimize.global_cse = 0;
790 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
791 optimize.loopInvariant = 0;
795 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
796 optimize.loopInduction = 0;
800 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
801 optimize.noLoopReverse = 1;
805 if (strcmp(&argv[i][1],OPTION_NOSTDLIB) == 0) {
810 if (strcmp(&argv[i][1],OPTION_NOSTDINC) == 0) {
815 if (strcmp(&argv[i][1],OPTION_VERBOSE) == 0) {
820 if (strcmp(&argv[i][1],OPTION_ANSIINT) == 0) {
825 if (!port->parseOption(&argc, argv, &i))
827 werror(W_UNKNOWN_OPTION,argv[i]);
835 /* these are undocumented options */
836 /* if preceded by '/' then turn off certain optmizations, used
837 for debugging only these are also the legacy options from
838 version 1.xx will be removed gradually.
839 It may be an absolute filename.
841 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
842 switch (argv[i][1]) {
845 optimize.ptrArithmetic=0;
849 switch (argv[i][2]) {
854 optimize.label4 = 0 ;
872 switch (argv[i][2]) {
874 optimize.loopInvariant = 0;
877 optimize.loopInduction = 0;
884 optimize.global_cse = 0;
891 /* if preceded by '-' then option */
892 if ( *argv[i] == '-' ) {
893 switch (argv[i][1]) {
904 /* Used to select the port */
905 if (_setPort(argv[i] + 2)) {
906 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
911 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
915 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
918 case 'X' : /* use external stack */
919 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
923 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
926 case 'p' : /* stack pointer intial value */
928 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
932 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
936 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
940 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
948 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
953 libPaths[nlibPaths++] = &argv[i][2];
955 libPaths[nlibPaths++] = argv[++i];
960 if (argv[i][2] == 'l') {
962 parseWithComma(linkOptions,&argv[i][3]);
964 parseWithComma(linkOptions,argv[++i]);
966 /* assembler options */
967 if (argv[i][2] == 'a') {
969 parseWithComma((char **)asmOptions,&argv[i][3]);
971 parseWithComma((char **)asmOptions,argv[++i]);
974 werror(W_UNKNOWN_OPTION,argv[i]);
991 /* preprocessor options */
995 _addToList(preArgv, "-M");
1000 _addToList(preArgv, "-C");
1009 char sOpt = argv[i][1] ;
1012 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1017 rest = &argv[i][2] ;
1019 if ( argv[i][1] == 'Y' )
1022 sprintf(buffer, "-%c%s", sOpt, rest);
1023 _addToList(preArgv, buffer);
1028 if (!port->parseOption(&argc, argv, &i))
1029 werror(W_UNKNOWN_OPTION,argv[i]);
1034 if (!port->parseOption(&argc, argv, &i)) {
1035 /* no option must be a filename */
1037 _processC1Arg(argv[i]);
1039 processFile(argv[i]);
1043 /* set up external stack location if not explicitly specified */
1044 if ( !options.xstack_loc )
1045 options.xstack_loc = options.xdata_loc ;
1047 /* if debug option is set the open the cdbFile */
1048 if (!options.nodebug && srcFileName) {
1049 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1050 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1051 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1053 /* add a module record */
1054 fprintf(cdbFile,"M:%s\n",moduleName);
1060 /*-----------------------------------------------------------------*/
1061 /* my_system - will call a program with arguments */
1062 /*-----------------------------------------------------------------*/
1064 #if defined(_MSC_VER)
1066 char *try_dir[]= {NULL}; // TODO : Fill in some default search list
1070 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1074 int my_system (const char *cmd, char **cmd_argv)
1076 char *dir, *got= NULL; int i= 0;
1078 while (!got && try_dir[i])
1080 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1081 strcpy(dir, try_dir[i]);
1086 strcat(dir, ".exe");
1088 /* Mung slashes into backslashes to keep WIndoze happy. */
1104 if (access(dir, X_OK) == 0)
1113 char **pCmd = cmd_argv;
1116 printf("%s ", *pCmd);
1124 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1128 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1130 perror("Cannot exec process ");
1137 /*-----------------------------------------------------------------*/
1138 /* linkEdit : - calls the linkage editor with options */
1139 /*-----------------------------------------------------------------*/
1140 static void linkEdit (char **envp)
1148 srcFileName = "temp";
1150 /* first we need to create the <filename>.lnk file */
1151 sprintf(buffer,"%s.lnk",srcFileName);
1152 if (!(lnkfile = fopen(buffer,"w"))) {
1153 werror(E_FILE_OPEN_ERR,buffer);
1157 /* now write the options */
1158 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1160 /* if iram size specified */
1161 if (options.iram_size)
1162 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1164 /*if (options.debug) */
1165 fprintf(lnkfile,"-z\n");
1167 #define WRITE_SEG_LOC(N, L) \
1168 segName = strdup(N); \
1169 c = strtok(segName, " \t"); \
1170 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1171 if (segName) { free(segName); }
1173 /* code segment start */
1174 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1176 /* data segment start */
1177 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1180 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1183 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1185 /* bit segment start */
1186 WRITE_SEG_LOC(BIT_NAME, 0);
1188 /* add the extra linker options */
1189 for (i=0; linkOptions[i] ; i++)
1190 fprintf(lnkfile,"%s\n",linkOptions[i]);
1192 /* other library paths if specified */
1193 for (i = 0 ; i < nlibPaths ; i++ )
1194 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1196 /* standard library path */
1197 if (!options.nostdlib) {
1198 if (IS_DS390_PORT) {
1201 switch(options.model)
1213 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1218 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1220 /* standard library files */
1221 if (strcmp(port->target, "ds390")==0) {
1222 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1224 fprintf (lnkfile,"-l %s\n",STD_LIB);
1225 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1226 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1227 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1230 /* additional libraries if any */
1231 for (i = 0 ; i < nlibFiles; i++)
1232 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1234 /* put in the object files */
1235 if (strcmp(srcFileName,"temp"))
1236 fprintf (lnkfile,"%s ",srcFileName);
1238 for (i = 0 ; i < nrelFiles ; i++ )
1239 fprintf (lnkfile,"%s\n",relFiles[i]);
1241 fprintf (lnkfile,"\n-e\n");
1244 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1246 if (options.verbose)
1247 printf ("sdcc: Calling linker...\n");
1248 if (my_system(argv[0], argv)) {
1249 perror("Cannot exec linker");
1253 if (strcmp(srcFileName,"temp") == 0) {
1254 /* rename "temp.cdb" to "firstRelFile.cdb" */
1255 char *f = strtok(strdup(relFiles[0]),".");
1256 f = strcat(f,".cdb");
1257 rename("temp.cdb",f);
1262 /*-----------------------------------------------------------------*/
1263 /* assemble - spawns the assembler with arguments */
1264 /*-----------------------------------------------------------------*/
1265 static void assemble (char **envp)
1267 char *argv[128]; /* assembler arguments */
1269 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1271 if (my_system(argv[0], argv)) {
1272 perror("Cannot exec assember");
1279 /*-----------------------------------------------------------------*/
1280 /* preProcess - spawns the preprocessor with arguments */
1281 /*-----------------------------------------------------------------*/
1282 static int preProcess (char **envp)
1289 if (!options.c1mode) {
1290 /* if using external stack define the macro */
1291 if ( options.useXstack )
1292 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1294 /* set the macro for stack autos */
1295 if ( options.stackAuto )
1296 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1298 /* set the macro for stack autos */
1299 if ( options.stack10bit )
1300 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1302 /* set the macro for large model */
1303 switch(options.model)
1306 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1309 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1312 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1315 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1318 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1321 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1326 /* add port (processor information to processor */
1327 sprintf(procDef,"-DSDCC_%s",port->target);
1328 _addToList(preArgv,procDef);
1331 preOutName = strdup(tmpnam(NULL));
1333 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1334 preOutName, srcFileName, preArgv);
1336 if (options.verbose)
1337 printf ("sdcc: Calling preprocessor...\n");
1339 if (my_system(argv[0], argv)) {
1340 unlink (preOutName);
1341 perror("Cannot exec Preprocessor");
1349 preOutName = fullSrcFileName;
1352 yyin = fopen(preOutName, "r");
1354 perror("Preproc file not found\n");
1361 static void _findPort(int argc, char **argv)
1365 if (!strncmp(*argv, "-m", 2)) {
1366 _setPort(*argv + 2);
1372 /* Use the first in the list */
1378 * initialises and calls the parser
1381 int main ( int argc, char **argv , char **envp)
1383 /* turn all optimizations off by default */
1384 memset(&optimize,0,sizeof(struct optimize));
1386 /*printVersionInfo ();*/
1388 _findPort(argc, argv);
1389 /* Initalise the port. */
1393 setDefaultOptions();
1394 parseCmdLine(argc,argv);
1398 port->finaliseOptions();
1400 /* if no input then printUsage & exit */
1401 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1414 if (options.verbose)
1415 printf ("sdcc: Generating code...\n");
1421 /* TSD PIC port hack - if the PIC port option is enabled
1422 and SDCC is used to generate PIC code, then we will
1423 generate .asm files in gpasm's format instead of SDCC's
1426 #if !OPT_DISABLE_PIC
1436 if (!options.c1mode)
1438 if (options.verbose)
1439 printf ("sdcc: Calling assembler...\n");
1454 if (!options.cc_only &&
1458 (srcFileName || nrelFiles)) {
1459 if (port->linker.do_link)
1460 port->linker.do_link();
1465 if (yyin && yyin != stdin)
1468 if (preOutName && !options.c1mode) {