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. We cant include unistd.h as it defines
35 'link' which we also use.
37 int access(const char *path, int mode);
39 int unlink(const char *path);
41 extern void initSymt ();
42 extern void initMem ();
43 extern void initExpr ();
44 extern void initiCode ();
45 extern void initCSupport ();
46 extern void initPeepHole ();
47 extern void createObject ();
48 extern int yyparse ();
50 extern struct value *constVal(char *s);
51 extern double floatFromVal(struct value *);
52 extern int fatalError ;
53 FILE *srcFile ;/* source file */
54 FILE *cdbFile = NULL ;/* debugger information output file */
55 char *fullSrcFileName ;/* full name for the source file */
56 char *srcFileName ;/* source file name with the .c stripped */
57 char *moduleName ;/* module name is srcFilename stripped of any path */
58 const char *preArgv[128] ;/* pre-processor arguments */
60 struct optimize optimize ;
61 struct options options ;
62 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a"*/;
63 short preProcOnly = 0;
65 char *linkOptions[128];
66 const char *asmOptions[128];
73 bool verboseExec = FALSE;
74 //extern int wait (int *);
77 /* Far functions, far data */
78 #define OPTION_LARGE_MODEL "-model-large"
79 /* Far functions, near data */
80 #define OPTION_MEDIUM_MODEL "-model-medium"
81 #define OPTION_SMALL_MODEL "-model-small"
82 #define OPTION_FLAT24_MODEL "-model-flat24"
83 #define OPTION_STACK_AUTO "-stack-auto"
84 #define OPTION_STACK_10BIT "-stack-10bit"
85 #define OPTION_XSTACK "-xstack"
86 #define OPTION_GENERIC "-generic"
87 #define OPTION_NO_GCSE "-nogcse"
88 #define OPTION_NO_LOOP_INV "-noinvariant"
89 #define OPTION_NO_LOOP_IND "-noinduction"
90 #define OPTION_NO_JTBOUND "-nojtbound"
91 #define OPTION_NO_LOOPREV "-noloopreverse"
92 #define OPTION_XREGS "-regextend"
93 #define OPTION_COMP_ONLY "-compile-only"
94 #define OPTION_DUMP_RAW "-dumpraw"
95 #define OPTION_DUMP_GCSE "-dumpgcse"
96 #define OPTION_DUMP_LOOP "-dumploop"
97 #define OPTION_DUMP_KILL "-dumpdeadcode"
98 #define OPTION_DUMP_RANGE "-dumpliverange"
99 #define OPTION_DUMP_PACK "-dumpregpack"
100 #define OPTION_DUMP_RASSGN "-dumpregassign"
101 #define OPTION_DUMP_ALL "-dumpall"
102 #define OPTION_XRAM_LOC "-xram-loc"
103 #define OPTION_IRAM_SIZE "-iram-size"
104 #define OPTION_XSTACK_LOC "-xstack-loc"
105 #define OPTION_CODE_LOC "-code-loc"
106 #define OPTION_STACK_LOC "-stack-loc"
107 #define OPTION_DATA_LOC "-data-loc"
108 #define OPTION_IDATA_LOC "-idata-loc"
109 #define OPTION_PEEP_FILE "-peep-file"
110 #define OPTION_LIB_PATH "-lib-path"
111 #define OPTION_INTLONG_RENT "-int-long-reent"
112 #define OPTION_FLOAT_RENT "-float-reent"
113 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
114 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
115 #define OPTION_CYCLOMATIC "-cyclomatic"
116 #define OPTION_NOOVERLAY "-nooverlay"
117 #define OPTION_MAINRETURN "-main-return"
118 #define OPTION_NOPEEP "-no-peep"
119 #define OPTION_ASMPEEP "-peep-asm"
120 #define OPTION_DEBUG "-debug"
121 #define OPTION_NODEBUG "-nodebug"
122 #define OPTION_VERSION "-version"
123 #define OPTION_STKAFTRDATA "-stack-after-data"
124 #define OPTION_PREPROC_ONLY "-preprocessonly"
125 #define OPTION_C1_MODE "-c1mode"
126 #define OPTION_HELP "-help"
127 #define OPTION_CALLEE_SAVES "-callee-saves"
128 #define OPTION_NOREGPARMS "-noregparms"
130 static const char *_preCmd[] = {
131 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
132 "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
135 #if !OPT_DISABLE_MCS51
136 extern PORT mcs51_port;
138 #if !OPT_DISABLE_GBZ80
139 extern PORT gbz80_port;
142 extern PORT z80_port;
145 extern PORT avr_port;
147 #if !OPT_DISABLE_DS390
148 extern PORT ds390_port;
154 static PORT *_ports[] = {
155 #if !OPT_DISABLE_MCS51
158 #if !OPT_DISABLE_GBZ80
167 #if !OPT_DISABLE_DS390
172 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
174 /** Sets the port to the one given by the command line option.
175 @param The name minus the option (eg 'mcs51')
176 @return 0 on success.
178 static int _setPort(const char *name)
181 for (i=0; i<NUM_PORTS; i++) {
182 if (!strcmp(_ports[i]->target, name)) {
187 /* Error - didnt find */
188 werror(E_UNKNOWN_TARGET,name);
192 void buildCmdLine(char *into, char **args, const char **cmds,
193 const char *p1, const char *p2,
194 const char *p3, const char **list)
196 const char *p, *from;
206 /* See if it has a '$' anywhere - if not, just copy */
207 if ((p = strchr(from, '$'))) {
208 strncpy(into, from, p - from);
209 /* NULL terminate it */
227 const char **tmp = list;
231 into += strlen(into)+1;
244 if (strlen(into) == 0)
246 into += strlen(into)+1;
251 /*-----------------------------------------------------------------*/
252 /* printVersionInfo - prints the version info */
253 /*-----------------------------------------------------------------*/
254 void printVersionInfo ()
260 for (i=0; i<NUM_PORTS; i++)
261 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
262 fprintf(stderr, " %s"
263 #ifdef SDCC_SUB_VERSION_STR
264 "/" SDCC_SUB_VERSION_STR
281 /*-----------------------------------------------------------------*/
282 /* printUsage - prints command line syntax */
283 /*-----------------------------------------------------------------*/
288 "Usage : [options] filename\n"
290 "\t-m<proc> - Target processor <proc>. Default %s\n"
291 "\t Try --version for supported values of <proc>\n"
292 "\t--model-large - Large Model\n"
293 "\t--model-small - Small Model (default)\n"
294 "\t--stack-auto - Stack automatic variables\n"
295 "\t--xstack - Use external stack\n"
296 "\t--xram-loc <nnnn> - External Ram start location\n"
297 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
298 "\t--code-loc <nnnn> - Code Segment Location\n"
299 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
300 "\t--data-loc <nnnn> - Direct data start location\n"
301 "\t--idata-loc <nnnn> - Indirect data start location\n"
302 "\t--iram-size <nnnn> - Internal Ram size\n"
303 "\t--nojtbound - Don't generate boundary check for jump tables\n"
304 "\t--generic - All unqualified ptrs converted to '_generic'\n"
305 "PreProcessor Options :-\n"
306 "\t-Dmacro - Define Macro\n"
307 "\t-Ipath - Include \"*.h\" path\n"
308 "Note: this is NOT a complete list of options see docs for details\n",
314 /*-----------------------------------------------------------------*/
315 /* parseWithComma - separates string with comma */
316 /*-----------------------------------------------------------------*/
317 void parseWithComma (char **dest,char *src)
322 /* skip the initial white spaces */
323 while (isspace(*src)) src++;
337 /*-----------------------------------------------------------------*/
338 /* setDefaultOptions - sets the default options */
339 /*-----------------------------------------------------------------*/
340 static void setDefaultOptions()
344 for ( i = 0 ; i < 128 ; i++)
345 preArgv[i] = asmOptions [i] =
346 linkOptions[i] = relFiles[i] = libFiles[i] =
349 /* first the options part */
350 options.stack_loc = 0; /* stack pointer initialised to 0 */
351 options.xstack_loc= 0; /* xternal stack starts at 0 */
352 options.code_loc = 0; /* code starts at 0 */
353 options.data_loc = 0x0030; /* data starts at 0x0030 */
354 options.xdata_loc = 0;
355 options.idata_loc = 0x80;
356 options.genericPtr = 1; /* default on */
358 options.model = port->general.default_model;
360 /* now for the optimizations */
361 /* turn on the everything */
362 optimize.global_cse = 1;
367 optimize.loopInvariant = 1;
368 optimize.loopInduction = 1;
370 port->setDefaultOptions();
373 /*-----------------------------------------------------------------*/
374 /* processFile - determines the type of file from the extension */
375 /*-----------------------------------------------------------------*/
376 static void processFile (char *s)
380 /* get the file extension */
381 fext = s + strlen(s);
382 while ((fext != s) && *fext != '.') fext--;
384 /* now if no '.' then we don't know what the file type is
385 so give a warning and return */
387 werror(W_UNKNOWN_FEXT,s);
391 /* otherwise depending on the file type */
392 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
393 /* source file name : not if we already have a
396 werror(W_TOO_MANY_SRC,s);
400 /* the only source file */
401 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
402 werror(E_FILE_OPEN_ERR,s);
406 /* copy the file name into the buffer */
409 /* get rid of the "." */
411 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
412 strcpy(srcFileName,buffer);
414 /* get rid of any path information
415 for the module name; do this by going
416 backwards till we get to either '/' or '\' or ':'
417 or start of buffer */
418 fext = buffer + strlen(buffer);
419 while (fext != buffer &&
420 *(fext -1) != '\\' &&
424 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
425 strcpy(moduleName,fext);
430 /* if the extention is type .rel or .r or .REL or .R
431 addtional object file will be passed to the linker */
432 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
433 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
434 strcmp(fext, port->linker.rel_ext) == 0)
436 relFiles[nrelFiles++] = s;
440 /* if .lib or .LIB */
441 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
442 libFiles[nlibFiles++] = s;
446 werror(W_UNKNOWN_FEXT,s);
450 static void _processC1Arg(char *s)
453 if (options.out_name) {
454 werror(W_TOO_MANY_SRC,s);
457 options.out_name = strdup(s);
464 static void _addToList(const char **list, const char *str)
466 /* This is the bad way to do things :) */
471 werror(E_OUT_OF_MEM,__FILE__, 0);
477 static void _setModel(int model, const char *sz)
479 if (port->general.supported_models & model)
480 options.model = model;
482 werror(W_UNSUPPORTED_MODEL, sz, port->target);
485 /*-----------------------------------------------------------------*/
486 /* parseCmdLine - parses the command line and sets the options */
487 /*-----------------------------------------------------------------*/
488 int parseCmdLine ( int argc, char **argv )
493 /* go thru all whole command line */
494 for ( i = 1; i < argc; i++ ) {
499 if (argv[i][0] == '-' && argv[i][1] == '-') {
501 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
506 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
507 options.regExtend = 1;
511 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
512 _setModel(MODEL_LARGE, argv[i]);
516 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
517 _setModel(MODEL_MEDIUM, argv[i]);
521 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
522 _setModel(MODEL_SMALL, argv[i]);
526 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
527 _setModel(MODEL_FLAT24, argv[i]);
531 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
532 options.stack10bit = 1;
536 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
537 options.stackAuto = 1;
541 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
542 options.dump_raw = 1;
546 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
547 options.cyclomatic = 1;
551 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
552 options.dump_gcse = 1;
556 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
557 options.dump_loop = 1;
561 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
562 options.dump_kill = 1;
566 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
567 options.intlong_rent = 1;
571 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
572 options.float_rent = 1;
576 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
577 options.dump_range = 1;
581 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
582 options.dump_pack = 1;
586 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
587 options.dump_rassgn = 1;
591 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
596 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
601 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
602 options.noOverlay = 1;
606 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
607 options.stackOnData = 1;
611 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
616 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
622 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
623 options.dump_rassgn =
629 options.dump_raw = 1;
633 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
638 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
639 options.genericPtr = 1;
643 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
648 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
653 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
658 if (strcmp(&argv[i][1],OPTION_NODEBUG) == 0) {
663 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
664 options.noregparms = 1;
668 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
669 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
671 &argv[i][1+strlen(OPTION_PEEP_FILE)];
673 options.peep_file = argv[++i];
677 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
678 if (argv[i][1+strlen(OPTION_LIB_PATH)])
679 libPaths[nlibPaths++] =
680 &argv[i][1+strlen(OPTION_PEEP_FILE)];
682 libPaths[nlibPaths++] = argv[++i];
686 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
688 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
690 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
693 (int) floatFromVal(constVal(argv[++i]));
697 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
698 options.useXstack = 1;
702 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
703 options.mainreturn = 1;
707 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
708 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
709 parseWithComma(options.calleeSaves
710 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
712 parseWithComma(options.calleeSaves,argv[++i]);
716 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
718 if (argv[i][1+strlen(OPTION_STACK_LOC)])
720 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
723 (int) floatFromVal(constVal(argv[++i]));
727 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
729 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
731 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
734 (unsigned int) floatFromVal(constVal(argv[++i]));
738 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
740 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
742 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
745 (int) floatFromVal(constVal(argv[++i]));
749 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
755 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
757 if (argv[i][1+strlen(OPTION_DATA_LOC)])
759 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
762 (int) floatFromVal(constVal(argv[++i]));
766 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
768 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
770 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
773 (int) floatFromVal(constVal(argv[++i]));
777 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
779 if (argv[i][1+strlen(OPTION_CODE_LOC)])
781 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
784 (int) floatFromVal(constVal(argv[++i]));
789 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
790 optimize.noJTabBoundary = 1;
794 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
795 optimize.global_cse = 0;
799 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
800 optimize.loopInvariant = 0;
804 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
805 optimize.loopInduction = 0;
809 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
810 optimize.noLoopReverse = 1;
814 if (!port->parseOption(&argc, argv, &i))
816 werror(W_UNKNOWN_OPTION,argv[i]);
824 /* these are undocumented options */
825 /* if preceded by '/' then turn off certain optmizations, used
826 for debugging only these are also the legacy options from
827 version 1.xx will be removed gradually.
828 It may be an absolute filename.
830 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
831 switch (argv[i][1]) {
834 optimize.ptrArithmetic=0;
838 switch (argv[i][2]) {
843 optimize.label4 = 0 ;
861 switch (argv[i][2]) {
863 optimize.loopInvariant = 0;
866 optimize.loopInduction = 0;
873 optimize.global_cse = 0;
880 /* if preceded by '-' then option */
881 if ( *argv[i] == '-' ) {
882 switch (argv[i][1]) {
893 /* Used to select the port */
894 if (_setPort(argv[i] + 2)) {
895 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
900 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
904 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
907 case 'X' : /* use external stack */
908 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
912 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
915 case 'p' : /* stack pointer intial value */
917 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
921 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
925 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
929 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
937 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
942 libPaths[nlibPaths++] = &argv[i][2];
944 libPaths[nlibPaths++] = argv[++i];
949 if (argv[i][2] == 'l') {
951 parseWithComma(linkOptions,&argv[i][3]);
953 parseWithComma(linkOptions,argv[++i]);
955 /* assembler options */
956 if (argv[i][2] == 'a') {
958 parseWithComma((char **)asmOptions,&argv[i][3]);
960 parseWithComma((char **)asmOptions,argv[++i]);
963 werror(W_UNKNOWN_OPTION,argv[i]);
972 #if FEATURE_VERBOSE_EXEC
980 /* preprocessor options */
984 _addToList(preArgv, "-M");
989 _addToList(preArgv, "-C");
998 char sOpt = argv[i][1] ;
1001 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1006 rest = &argv[i][2] ;
1008 if ( argv[i][1] == 'Y' )
1011 sprintf(buffer, "-%c%s", sOpt, rest);
1012 _addToList(preArgv, buffer);
1017 if (!port->parseOption(&argc, argv, &i))
1018 werror(W_UNKNOWN_OPTION,argv[i]);
1023 if (!port->parseOption(&argc, argv, &i)) {
1024 /* no option must be a filename */
1026 _processC1Arg(argv[i]);
1028 processFile(argv[i]);
1032 /* set up external stack location if not explicitly specified */
1033 if ( !options.xstack_loc )
1034 options.xstack_loc = options.xdata_loc ;
1036 /* if debug option is set the open the cdbFile */
1037 if (!options.nodebug && srcFileName) {
1038 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1039 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1040 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1042 /* add a module record */
1043 fprintf(cdbFile,"M:%s\n",moduleName);
1049 /*-----------------------------------------------------------------*/
1050 /* my_system - will call a program with arguments */
1051 /*-----------------------------------------------------------------*/
1052 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1053 int my_system (const char *cmd, char **cmd_argv)
1055 char *dir, *got= NULL; int i= 0;
1057 while (!got && try_dir[i])
1059 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1060 strcpy(dir, try_dir[i]);
1065 strcat(dir, ".exe");
1067 /* Mung slashes into backslashes to keep WIndoze happy. */
1083 if (access(dir, X_OK) == 0)
1090 #if FEATURE_VERBOSE_EXEC
1092 char **pCmd = cmd_argv;
1094 printf("%s ", *pCmd);
1101 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1103 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1105 perror("Cannot exec process ");
1112 /*-----------------------------------------------------------------*/
1113 /* linkEdit : - calls the linkage editor with options */
1114 /*-----------------------------------------------------------------*/
1115 static void linkEdit (char **envp)
1123 srcFileName = "temp";
1125 /* first we need to create the <filename>.lnk file */
1126 sprintf(buffer,"%s.lnk",srcFileName);
1127 if (!(lnkfile = fopen(buffer,"w"))) {
1128 werror(E_FILE_OPEN_ERR,buffer);
1132 /* now write the options */
1133 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1135 /* if iram size specified */
1136 if (options.iram_size)
1137 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1139 /*if (options.debug) */
1140 fprintf(lnkfile,"-z\n");
1142 #define WRITE_SEG_LOC(N, L) \
1143 segName = strdup(N); \
1144 c = strtok(segName, " \t"); \
1145 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1146 if (segName) { free(segName); }
1148 /* code segment start */
1149 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1151 /* data segment start */
1152 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1155 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1158 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1160 /* bit segment start */
1161 WRITE_SEG_LOC(BIT_NAME, 0);
1163 /* add the extra linker options */
1164 for (i=0; linkOptions[i] ; i++)
1165 fprintf(lnkfile,"%s\n",linkOptions[i]);
1167 /* standard library path */
1168 if (strcmp(port->target,"ds390")==0) {
1171 switch(options.model)
1183 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1188 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1190 /* other library paths if specified */
1191 for (i = 0 ; i < nlibPaths ; i++ )
1192 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1194 /* standard library files */
1195 if (strcmp(port->target, "ds390")==0) {
1196 fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
1198 fprintf (lnkfile,"-l %s\n",STD_LIB);
1199 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1200 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1201 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1203 /* additional libraries if any */
1204 for (i = 0 ; i < nlibFiles; i++)
1205 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1207 /* put in the object files */
1208 if (strcmp(srcFileName,"temp"))
1209 fprintf (lnkfile,"%s ",srcFileName);
1211 for (i = 0 ; i < nrelFiles ; i++ )
1212 fprintf (lnkfile,"%s\n",relFiles[i]);
1214 fprintf (lnkfile,"\n-e\n");
1217 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1219 /* call the linker */
1220 if (my_system(argv[0], argv)) {
1221 perror("Cannot exec linker");
1225 if (strcmp(srcFileName,"temp") == 0) {
1226 /* rename "temp.cdb" to "firstRelFile.cdb" */
1227 char *f = strtok(strdup(relFiles[0]),".");
1228 f = strcat(f,".cdb");
1229 rename("temp.cdb",f);
1234 /*-----------------------------------------------------------------*/
1235 /* assemble - spawns the assembler with arguments */
1236 /*-----------------------------------------------------------------*/
1237 static void assemble (char **envp)
1239 char *argv[128]; /* assembler arguments */
1241 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1243 if (my_system(argv[0], argv)) {
1244 perror("Cannot exec assember");
1251 /*-----------------------------------------------------------------*/
1252 /* preProcess - spawns the preprocessor with arguments */
1253 /*-----------------------------------------------------------------*/
1254 static int preProcess (char **envp)
1261 if (!options.c1mode) {
1262 /* if using external stack define the macro */
1263 if ( options.useXstack )
1264 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1266 /* set the macro for stack autos */
1267 if ( options.stackAuto )
1268 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1270 /* set the macro for stack autos */
1271 if ( options.stack10bit )
1272 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1274 /* set the macro for large model */
1275 switch(options.model)
1278 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1281 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1284 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1287 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1290 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1293 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1298 /* add port (processor information to processor */
1299 sprintf(procDef,"-DSDCC_%s",port->target);
1300 _addToList(preArgv,procDef);
1303 preOutName = strdup(tmpnam(NULL));
1305 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1306 preOutName, srcFileName, preArgv);
1308 if (my_system(argv[0], argv)) {
1309 unlink (preOutName);
1310 perror("Cannot exec Preprocessor");
1318 preOutName = fullSrcFileName;
1321 yyin = fopen(preOutName, "r");
1323 perror("Preproc file not found\n");
1330 static void _findPort(int argc, char **argv)
1334 if (!strncmp(*argv, "-m", 2)) {
1335 _setPort(*argv + 2);
1341 /* Use the first in the list */
1347 * initialises and calls the parser
1350 int main ( int argc, char **argv , char **envp)
1352 /* turn all optimizations off by default */
1353 memset(&optimize,0,sizeof(struct optimize));
1355 /*printVersionInfo ();*/
1357 _findPort(argc, argv);
1358 /* Initalise the port. */
1362 setDefaultOptions();
1363 parseCmdLine(argc,argv);
1367 port->finaliseOptions();
1369 /* if no input then printUsage & exit */
1370 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1388 if (!options.c1mode)
1399 if (!options.cc_only &&
1403 (srcFileName || nrelFiles)) {
1404 if (port->linker.do_link)
1405 port->linker.do_link();
1410 if (yyin && yyin != stdin)
1413 if (preOutName && !options.c1mode) {