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_VERSION "-version"
122 #define OPTION_STKAFTRDATA "-stack-after-data"
123 #define OPTION_PREPROC_ONLY "-preprocessonly"
124 #define OPTION_C1_MODE "-c1mode"
125 #define OPTION_HELP "-help"
126 #define OPTION_CALLEE_SAVES "-callee-saves"
127 #define OPTION_NOREGPARMS "-noregparms"
129 static const char *_preCmd[] = {
130 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
131 "-I" SDCC_INCLUDE_DIR, "$l", "$1", "$2", NULL
134 #if !OPT_DISABLE_MCS51
135 extern PORT mcs51_port;
137 #if !OPT_DISABLE_GBZ80
138 extern PORT gbz80_port;
141 extern PORT z80_port;
144 extern PORT avr_port;
146 #if !OPT_DISABLE_DS390
147 extern PORT ds390_port;
153 static PORT *_ports[] = {
154 #if !OPT_DISABLE_MCS51
157 #if !OPT_DISABLE_GBZ80
166 #if !OPT_DISABLE_DS390
171 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
173 /** Sets the port to the one given by the command line option.
174 @param The name minus the option (eg 'mcs51')
175 @return 0 on success.
177 static int _setPort(const char *name)
180 for (i=0; i<NUM_PORTS; i++) {
181 if (!strcmp(_ports[i]->target, name)) {
186 /* Error - didnt find */
187 werror(E_UNKNOWN_TARGET,name);
191 void buildCmdLine(char *into, char **args, const char **cmds,
192 const char *p1, const char *p2,
193 const char *p3, const char **list)
195 const char *p, *from;
205 /* See if it has a '$' anywhere - if not, just copy */
206 if ((p = strchr(from, '$'))) {
207 strncpy(into, from, p - from);
208 /* NULL terminate it */
226 const char **tmp = list;
230 into += strlen(into)+1;
243 if (strlen(into) == 0)
245 into += strlen(into)+1;
250 /*-----------------------------------------------------------------*/
251 /* printVersionInfo - prints the version info */
252 /*-----------------------------------------------------------------*/
253 void printVersionInfo ()
259 for (i=0; i<NUM_PORTS; i++)
260 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
261 fprintf(stderr, " %s"
262 #ifdef SDCC_SUB_VERSION_STR
263 "/" SDCC_SUB_VERSION_STR
280 /*-----------------------------------------------------------------*/
281 /* printUsage - prints command line syntax */
282 /*-----------------------------------------------------------------*/
287 "Usage : [options] filename\n"
289 "\t-m<proc> - Target processor <proc>. Default %s\n"
290 "\t Try --version for supported values of <proc>\n"
291 "\t--model-large - Large Model\n"
292 "\t--model-small - Small Model (default)\n"
293 "\t--stack-auto - Stack automatic variables\n"
294 "\t--xstack - Use external stack\n"
295 "\t--xram-loc <nnnn> - External Ram start location\n"
296 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
297 "\t--code-loc <nnnn> - Code Segment Location\n"
298 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
299 "\t--data-loc <nnnn> - Direct data start location\n"
300 "\t--idata-loc <nnnn> - Indirect data start location\n"
301 "\t--iram-size <nnnn> - Internal Ram size\n"
302 "\t--nojtbound - Don't generate boundary check for jump tables\n"
303 "\t--generic - All unqualified ptrs converted to '_generic'\n"
304 "PreProcessor Options :-\n"
305 "\t-Dmacro - Define Macro\n"
306 "\t-Ipath - Include \"*.h\" path\n"
307 "Note: this is NOT a complete list of options see docs for details\n",
313 /*-----------------------------------------------------------------*/
314 /* parseWithComma - separates string with comma */
315 /*-----------------------------------------------------------------*/
316 void parseWithComma (char **dest,char *src)
321 /* skip the initial white spaces */
322 while (isspace(*src)) src++;
336 /*-----------------------------------------------------------------*/
337 /* setDefaultOptions - sets the default options */
338 /*-----------------------------------------------------------------*/
339 static void setDefaultOptions()
343 for ( i = 0 ; i < 128 ; i++)
344 preArgv[i] = asmOptions [i] =
345 linkOptions[i] = relFiles[i] = libFiles[i] =
348 /* first the options part */
349 options.stack_loc = 0; /* stack pointer initialised to 0 */
350 options.xstack_loc= 0; /* xternal stack starts at 0 */
351 options.code_loc = 0; /* code starts at 0 */
352 options.data_loc = 0x0030; /* data starts at 0x0030 */
353 options.xdata_loc = 0;
354 options.idata_loc = 0x80;
355 options.genericPtr = 1; /* default on */
357 options.model = port->general.default_model;
359 /* now for the optimizations */
360 /* turn on the everything */
361 optimize.global_cse = 1;
366 optimize.loopInvariant = 1;
367 optimize.loopInduction = 1;
369 port->setDefaultOptions();
372 /*-----------------------------------------------------------------*/
373 /* processFile - determines the type of file from the extension */
374 /*-----------------------------------------------------------------*/
375 static void processFile (char *s)
379 /* get the file extension */
380 fext = s + strlen(s);
381 while ((fext != s) && *fext != '.') fext--;
383 /* now if no '.' then we don't know what the file type is
384 so give a warning and return */
386 werror(W_UNKNOWN_FEXT,s);
390 /* otherwise depending on the file type */
391 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
392 /* source file name : not if we already have a
395 werror(W_TOO_MANY_SRC,s);
399 /* the only source file */
400 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
401 werror(E_FILE_OPEN_ERR,s);
405 /* copy the file name into the buffer */
408 /* get rid of the "." */
410 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
411 strcpy(srcFileName,buffer);
413 /* get rid of any path information
414 for the module name; do this by going
415 backwards till we get to either '/' or '\' or ':'
416 or start of buffer */
417 fext = buffer + strlen(buffer);
418 while (fext != buffer &&
419 *(fext -1) != '\\' &&
423 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
424 strcpy(moduleName,fext);
429 /* if the extention is type .rel or .r or .REL or .R
430 addtional object file will be passed to the linker */
431 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
432 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
433 strcmp(fext, port->linker.rel_ext) == 0)
435 relFiles[nrelFiles++] = s;
439 /* if .lib or .LIB */
440 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
441 libFiles[nlibFiles++] = s;
445 werror(W_UNKNOWN_FEXT,s);
449 static void _processC1Arg(char *s)
452 if (options.out_name) {
453 werror(W_TOO_MANY_SRC,s);
456 options.out_name = strdup(s);
463 static void _addToList(const char **list, const char *str)
465 /* This is the bad way to do things :) */
470 werror(E_OUT_OF_MEM,__FILE__, 0);
476 static void _setModel(int model, const char *sz)
478 if (port->general.supported_models & model)
479 options.model = model;
481 werror(W_UNSUPPORTED_MODEL, sz, port->target);
484 /*-----------------------------------------------------------------*/
485 /* parseCmdLine - parses the command line and sets the options */
486 /*-----------------------------------------------------------------*/
487 int parseCmdLine ( int argc, char **argv )
492 /* go thru all whole command line */
493 for ( i = 1; i < argc; i++ ) {
498 if (argv[i][0] == '-' && argv[i][1] == '-') {
500 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
505 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
506 options.regExtend = 1;
510 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
511 _setModel(MODEL_LARGE, argv[i]);
515 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
516 _setModel(MODEL_MEDIUM, argv[i]);
520 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
521 _setModel(MODEL_SMALL, argv[i]);
525 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
526 _setModel(MODEL_FLAT24, argv[i]);
530 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
531 options.stack10bit = 1;
535 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
536 options.stackAuto = 1;
540 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
541 options.dump_raw = 1;
545 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
546 options.cyclomatic = 1;
550 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
551 options.dump_gcse = 1;
555 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
556 options.dump_loop = 1;
560 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
561 options.dump_kill = 1;
565 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
566 options.intlong_rent = 1;
570 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
571 options.float_rent = 1;
575 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
576 options.dump_range = 1;
580 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
581 options.dump_pack = 1;
585 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
586 options.dump_rassgn = 1;
590 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
595 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
600 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
601 options.noOverlay = 1;
605 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
606 options.stackOnData = 1;
610 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
615 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
621 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
622 options.dump_rassgn =
628 options.dump_raw = 1;
632 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
637 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
638 options.genericPtr = 1;
642 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
647 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
652 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
657 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
658 options.noregparms = 1;
662 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
663 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
665 &argv[i][1+strlen(OPTION_PEEP_FILE)];
667 options.peep_file = argv[++i];
671 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
672 if (argv[i][1+strlen(OPTION_LIB_PATH)])
673 libPaths[nlibPaths++] =
674 &argv[i][1+strlen(OPTION_PEEP_FILE)];
676 libPaths[nlibPaths++] = argv[++i];
680 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
682 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
684 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
687 (int) floatFromVal(constVal(argv[++i]));
691 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
692 options.useXstack = 1;
696 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
697 options.mainreturn = 1;
701 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
702 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
703 parseWithComma(options.calleeSaves
704 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
706 parseWithComma(options.calleeSaves,argv[++i]);
710 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
712 if (argv[i][1+strlen(OPTION_STACK_LOC)])
714 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
717 (int) floatFromVal(constVal(argv[++i]));
721 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
723 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
725 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
728 (unsigned int) floatFromVal(constVal(argv[++i]));
732 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
734 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
736 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
739 (int) floatFromVal(constVal(argv[++i]));
743 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
749 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
751 if (argv[i][1+strlen(OPTION_DATA_LOC)])
753 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
756 (int) floatFromVal(constVal(argv[++i]));
760 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
762 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
764 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
767 (int) floatFromVal(constVal(argv[++i]));
771 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
773 if (argv[i][1+strlen(OPTION_CODE_LOC)])
775 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
778 (int) floatFromVal(constVal(argv[++i]));
783 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
784 optimize.noJTabBoundary = 1;
788 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
789 optimize.global_cse = 0;
793 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
794 optimize.loopInvariant = 0;
798 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
799 optimize.loopInduction = 0;
803 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
804 optimize.noLoopReverse = 1;
808 if (!port->parseOption(&argc, argv, &i))
810 werror(W_UNKNOWN_OPTION,argv[i]);
818 /* these are undocumented options */
819 /* if preceded by '/' then turn off certain optmizations, used
820 for debugging only these are also the legacy options from
821 version 1.xx will be removed gradually.
822 It may be an absolute filename.
824 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
825 switch (argv[i][1]) {
828 optimize.ptrArithmetic=0;
832 switch (argv[i][2]) {
837 optimize.label4 = 0 ;
855 switch (argv[i][2]) {
857 optimize.loopInvariant = 0;
860 optimize.loopInduction = 0;
867 optimize.global_cse = 0;
874 /* if preceded by '-' then option */
875 if ( *argv[i] == '-' ) {
876 switch (argv[i][1]) {
887 /* Used to select the port */
888 if (_setPort(argv[i] + 2)) {
889 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
894 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
898 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
901 case 'X' : /* use external stack */
902 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
906 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
909 case 'p' : /* stack pointer intial value */
911 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
915 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
919 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
923 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
931 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
936 libPaths[nlibPaths++] = &argv[i][2];
938 libPaths[nlibPaths++] = argv[++i];
943 if (argv[i][2] == 'l') {
945 parseWithComma(linkOptions,&argv[i][3]);
947 parseWithComma(linkOptions,argv[++i]);
949 /* assembler options */
950 if (argv[i][2] == 'a') {
952 parseWithComma((char **)asmOptions,&argv[i][3]);
954 parseWithComma((char **)asmOptions,argv[++i]);
957 werror(W_UNKNOWN_OPTION,argv[i]);
966 #if FEATURE_VERBOSE_EXEC
974 /* preprocessor options */
978 _addToList(preArgv, "-M");
983 _addToList(preArgv, "-C");
992 char sOpt = argv[i][1] ;
995 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
1000 rest = &argv[i][2] ;
1002 if ( argv[i][1] == 'Y' )
1005 sprintf(buffer, "-%c%s", sOpt, rest);
1006 _addToList(preArgv, buffer);
1011 if (!port->parseOption(&argc, argv, &i))
1012 werror(W_UNKNOWN_OPTION,argv[i]);
1017 if (!port->parseOption(&argc, argv, &i)) {
1018 /* no option must be a filename */
1020 _processC1Arg(argv[i]);
1022 processFile(argv[i]);
1026 /* set up external stack location if not explicitly specified */
1027 if ( !options.xstack_loc )
1028 options.xstack_loc = options.xdata_loc ;
1030 /* if debug option is set the open the cdbFile */
1031 if (/* options.debug && */ srcFileName) {
1032 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1033 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1034 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1036 /* add a module record */
1037 fprintf(cdbFile,"M:%s\n",moduleName);
1043 /*-----------------------------------------------------------------*/
1044 /* my_system - will call a program with arguments */
1045 /*-----------------------------------------------------------------*/
1046 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1047 int my_system (const char *cmd, char **cmd_argv)
1049 char *dir, *got= NULL; int i= 0;
1051 while (!got && try_dir[i])
1053 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1054 strcpy(dir, try_dir[i]);
1059 strcat(dir, ".exe");
1061 /* Mung slashes into backslashes to keep WIndoze happy. */
1077 if (access(dir, X_OK) == 0)
1084 #if FEATURE_VERBOSE_EXEC
1086 char **pCmd = cmd_argv;
1088 printf("%s ", *pCmd);
1095 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1097 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1099 perror("Cannot exec process ");
1106 /*-----------------------------------------------------------------*/
1107 /* linkEdit : - calls the linkage editor with options */
1108 /*-----------------------------------------------------------------*/
1109 static void linkEdit (char **envp)
1117 srcFileName = "temp";
1119 /* first we need to create the <filename>.lnk file */
1120 sprintf(buffer,"%s.lnk",srcFileName);
1121 if (!(lnkfile = fopen(buffer,"w"))) {
1122 werror(E_FILE_OPEN_ERR,buffer);
1126 /* now write the options */
1127 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1129 /* if iram size specified */
1130 if (options.iram_size)
1131 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1133 /*if (options.debug) */
1134 fprintf(lnkfile,"-z\n");
1136 #define WRITE_SEG_LOC(N, L) \
1137 segName = strdup(N); \
1138 c = strtok(segName, " \t"); \
1139 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1140 if (segName) { free(segName); }
1142 /* code segment start */
1143 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1145 /* data segment start */
1146 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1149 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1152 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1154 /* bit segment start */
1155 WRITE_SEG_LOC(BIT_NAME, 0);
1157 /* add the extra linker options */
1158 for (i=0; linkOptions[i] ; i++)
1159 fprintf(lnkfile,"%s\n",linkOptions[i]);
1161 /* standard library path */
1162 switch(options.model)
1174 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1178 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1180 /* other library paths if specified */
1181 for (i = 0 ; i < nlibPaths ; i++ )
1182 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1184 /* standard library files */
1185 fprintf (lnkfile,"-l %s\n",STD_LIB);
1186 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1187 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1188 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1190 /* additional libraries if any */
1191 for (i = 0 ; i < nlibFiles; i++)
1192 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1194 /* put in the object files */
1195 if (strcmp(srcFileName,"temp"))
1196 fprintf (lnkfile,"%s ",srcFileName);
1198 for (i = 0 ; i < nrelFiles ; i++ )
1199 fprintf (lnkfile,"%s\n",relFiles[i]);
1201 fprintf (lnkfile,"\n-e\n");
1204 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1206 /* call the linker */
1207 if (my_system(argv[0], argv)) {
1208 perror("Cannot exec linker");
1212 if (strcmp(srcFileName,"temp") == 0) {
1213 /* rename "temp.cdb" to "firstRelFile.cdb" */
1214 char *f = strtok(strdup(relFiles[0]),".");
1215 f = strcat(f,".cdb");
1216 rename("temp.cdb",f);
1221 /*-----------------------------------------------------------------*/
1222 /* assemble - spawns the assembler with arguments */
1223 /*-----------------------------------------------------------------*/
1224 static void assemble (char **envp)
1226 char *argv[128]; /* assembler arguments */
1228 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1230 if (my_system(argv[0], argv)) {
1231 perror("Cannot exec assember");
1238 /*-----------------------------------------------------------------*/
1239 /* preProcess - spawns the preprocessor with arguments */
1240 /*-----------------------------------------------------------------*/
1241 static int preProcess (char **envp)
1248 if (!options.c1mode) {
1249 /* if using external stack define the macro */
1250 if ( options.useXstack )
1251 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1253 /* set the macro for stack autos */
1254 if ( options.stackAuto )
1255 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1257 /* set the macro for stack autos */
1258 if ( options.stack10bit )
1259 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1261 /* set the macro for large model */
1262 switch(options.model)
1265 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1268 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1271 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1274 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1277 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1280 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1285 /* add port (processor information to processor */
1286 sprintf(procDef,"-DSDCC_%s",port->target);
1287 _addToList(preArgv,procDef);
1290 preOutName = strdup(tmpnam(NULL));
1292 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1293 preOutName, srcFileName, preArgv);
1295 if (my_system(argv[0], argv)) {
1296 unlink (preOutName);
1297 perror("Cannot exec Preprocessor");
1305 preOutName = fullSrcFileName;
1308 yyin = fopen(preOutName, "r");
1310 perror("Preproc file not found\n");
1317 static void _findPort(int argc, char **argv)
1321 if (!strncmp(*argv, "-m", 2)) {
1322 _setPort(*argv + 2);
1328 /* Use the first in the list */
1334 * initialises and calls the parser
1337 int main ( int argc, char **argv , char **envp)
1339 /* turn all optimizations off by default */
1340 memset(&optimize,0,sizeof(struct optimize));
1342 /*printVersionInfo ();*/
1344 _findPort(argc, argv);
1345 /* Initalise the port. */
1349 setDefaultOptions();
1350 parseCmdLine(argc,argv);
1354 port->finaliseOptions();
1356 /* if no input then printUsage & exit */
1357 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1375 if (!options.c1mode)
1386 if (!options.cc_only &&
1390 (srcFileName || nrelFiles)) {
1391 if (port->linker.do_link)
1392 port->linker.do_link();
1397 if (yyin && yyin != stdin)
1400 if (preOutName && !options.c1mode) {