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;
149 static PORT *_ports[] = {
150 #if !OPT_DISABLE_MCS51
153 #if !OPT_DISABLE_GBZ80
164 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
166 /** Sets the port to the one given by the command line option.
167 @param The name minus the option (eg 'mcs51')
168 @return 0 on success.
170 static int _setPort(const char *name)
173 for (i=0; i<NUM_PORTS; i++) {
174 if (!strcmp(_ports[i]->target, name)) {
179 /* Error - didnt find */
180 werror(E_UNKNOWN_TARGET,name);
184 void buildCmdLine(char *into, char **args, const char **cmds,
185 const char *p1, const char *p2,
186 const char *p3, const char **list)
188 const char *p, *from;
198 /* See if it has a '$' anywhere - if not, just copy */
199 if ((p = strchr(from, '$'))) {
200 strncpy(into, from, p - from);
201 /* NULL terminate it */
219 const char **tmp = list;
223 into += strlen(into)+1;
236 if (strlen(into) == 0)
238 into += strlen(into)+1;
243 /*-----------------------------------------------------------------*/
244 /* printVersionInfo - prints the version info */
245 /*-----------------------------------------------------------------*/
246 void printVersionInfo ()
252 for (i=0; i<NUM_PORTS; i++)
253 fprintf(stderr, "%s%s", i==0 ? "" : "/", _ports[i]->target);
254 fprintf(stderr, " %s"
255 #ifdef SDCC_SUB_VERSION_STR
256 "/" SDCC_SUB_VERSION_STR
273 /*-----------------------------------------------------------------*/
274 /* printUsage - prints command line syntax */
275 /*-----------------------------------------------------------------*/
280 "Usage : [options] filename\n"
282 "\t-m<proc> - Target processor <proc>. Default %s\n"
283 "\t Try --version for supported values of <proc>\n"
284 "\t--model-large - Large Model\n"
285 "\t--model-small - Small Model (default)\n"
286 "\t--stack-auto - Stack automatic variables\n"
287 "\t--xstack - Use external stack\n"
288 "\t--xram-loc <nnnn> - External Ram start location\n"
289 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
290 "\t--code-loc <nnnn> - Code Segment Location\n"
291 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
292 "\t--data-loc <nnnn> - Direct data start location\n"
293 "\t--idata-loc <nnnn> - Indirect data start location\n"
294 "\t--iram-size <nnnn> - Internal Ram size\n"
295 "\t--nojtbound - Don't generate boundary check for jump tables\n"
296 "\t--generic - All unqualified ptrs converted to '_generic'\n"
297 "PreProcessor Options :-\n"
298 "\t-Dmacro - Define Macro\n"
299 "\t-Ipath - Include \"*.h\" path\n"
300 "Note: this is NOT a complete list of options see docs for details\n",
306 /*-----------------------------------------------------------------*/
307 /* parseWithComma - separates string with comma */
308 /*-----------------------------------------------------------------*/
309 void parseWithComma (char **dest,char *src)
314 /* skip the initial white spaces */
315 while (isspace(*src)) src++;
329 /*-----------------------------------------------------------------*/
330 /* setDefaultOptions - sets the default options */
331 /*-----------------------------------------------------------------*/
332 static void setDefaultOptions()
336 for ( i = 0 ; i < 128 ; i++)
337 preArgv[i] = asmOptions [i] =
338 linkOptions[i] = relFiles[i] = libFiles[i] =
341 /* first the options part */
342 options.stack_loc = 0; /* stack pointer initialised to 0 */
343 options.xstack_loc= 0; /* xternal stack starts at 0 */
344 options.code_loc = 0; /* code starts at 0 */
345 options.data_loc = 0x0030; /* data starts at 0x0030 */
346 options.xdata_loc = 0;
347 options.idata_loc = 0x80;
348 options.genericPtr = 1; /* default on */
350 options.model = port->general.default_model;
352 /* now for the optimizations */
353 /* turn on the everything */
354 optimize.global_cse = 1;
359 optimize.loopInvariant = 1;
360 optimize.loopInduction = 1;
362 port->setDefaultOptions();
365 /*-----------------------------------------------------------------*/
366 /* processFile - determines the type of file from the extension */
367 /*-----------------------------------------------------------------*/
368 static void processFile (char *s)
372 /* get the file extension */
373 fext = s + strlen(s);
374 while ((fext != s) && *fext != '.') fext--;
376 /* now if no '.' then we don't know what the file type is
377 so give a warning and return */
379 werror(W_UNKNOWN_FEXT,s);
383 /* otherwise depending on the file type */
384 if (strcmp(fext,".c") == 0 || strcmp(fext,".C") == 0 || options.c1mode) {
385 /* source file name : not if we already have a
388 werror(W_TOO_MANY_SRC,s);
392 /* the only source file */
393 if (!(srcFile = fopen((fullSrcFileName = s),"r"))) {
394 werror(E_FILE_OPEN_ERR,s);
398 /* copy the file name into the buffer */
401 /* get rid of the "." */
403 ALLOC_ATOMIC(srcFileName,strlen(buffer)+1);
404 strcpy(srcFileName,buffer);
406 /* get rid of any path information
407 for the module name; do this by going
408 backwards till we get to either '/' or '\' or ':'
409 or start of buffer */
410 fext = buffer + strlen(buffer);
411 while (fext != buffer &&
412 *(fext -1) != '\\' &&
416 ALLOC_ATOMIC(moduleName,strlen(fext)+1);
417 strcpy(moduleName,fext);
422 /* if the extention is type .rel or .r or .REL or .R
423 addtional object file will be passed to the linker */
424 if (strcmp(fext,".r") == 0 || strcmp(fext,".rel") == 0 ||
425 strcmp(fext,".R") == 0 || strcmp(fext,".REL") == 0 ||
426 strcmp(fext, port->linker.rel_ext) == 0)
428 relFiles[nrelFiles++] = s;
432 /* if .lib or .LIB */
433 if (strcmp(fext,".lib") == 0 || strcmp(fext,".LIB") == 0) {
434 libFiles[nlibFiles++] = s;
438 werror(W_UNKNOWN_FEXT,s);
442 static void _processC1Arg(char *s)
445 if (options.out_name) {
446 werror(W_TOO_MANY_SRC,s);
449 options.out_name = strdup(s);
456 static void _addToList(const char **list, const char *str)
458 /* This is the bad way to do things :) */
463 werror(E_OUT_OF_MEM,__FILE__, 0);
469 static void _setModel(int model, const char *sz)
471 if (port->general.supported_models & model)
472 options.model = model;
474 werror(W_UNSUPPORTED_MODEL, sz, port->target);
477 /*-----------------------------------------------------------------*/
478 /* parseCmdLine - parses the command line and sets the options */
479 /*-----------------------------------------------------------------*/
480 int parseCmdLine ( int argc, char **argv )
485 /* go thru all whole command line */
486 for ( i = 1; i < argc; i++ ) {
491 if (argv[i][0] == '-' && argv[i][1] == '-') {
493 if (strcmp(&argv[i][1],OPTION_HELP) == 0) {
498 if (strcmp(&argv[i][1],OPTION_XREGS) == 0) {
499 options.regExtend = 1;
503 if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
504 _setModel(MODEL_LARGE, argv[i]);
508 if (strcmp(&argv[i][1],OPTION_MEDIUM_MODEL) == 0) {
509 _setModel(MODEL_MEDIUM, argv[i]);
513 if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
514 _setModel(MODEL_SMALL, argv[i]);
518 if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
519 _setModel(MODEL_FLAT24, argv[i]);
523 if (strcmp(&argv[i][1],OPTION_STACK_10BIT) == 0) {
524 options.stack10bit = 1;
528 if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
529 options.stackAuto = 1;
533 if (strcmp(&argv[i][1],OPTION_DUMP_RAW) == 0) {
534 options.dump_raw = 1;
538 if (strcmp(&argv[i][1],OPTION_CYCLOMATIC) == 0) {
539 options.cyclomatic = 1;
543 if (strcmp(&argv[i][1],OPTION_DUMP_GCSE) == 0) {
544 options.dump_gcse = 1;
548 if (strcmp(&argv[i][1],OPTION_DUMP_LOOP) == 0) {
549 options.dump_loop = 1;
553 if (strcmp(&argv[i][1],OPTION_DUMP_KILL) == 0) {
554 options.dump_kill = 1;
558 if (strcmp(&argv[i][1],OPTION_INTLONG_RENT) == 0) {
559 options.intlong_rent = 1;
563 if (strcmp(&argv[i][1],OPTION_FLOAT_RENT) == 0) {
564 options.float_rent = 1;
568 if (strcmp(&argv[i][1],OPTION_DUMP_RANGE) == 0) {
569 options.dump_range = 1;
573 if (strcmp(&argv[i][1],OPTION_DUMP_PACK) == 0) {
574 options.dump_pack = 1;
578 if (strcmp(&argv[i][1],OPTION_DUMP_RASSGN) == 0) {
579 options.dump_rassgn = 1;
583 if (strcmp(&argv[i][1],OPTION_OUT_FMT_IHX) == 0) {
588 if (strcmp(&argv[i][1],OPTION_OUT_FMT_S19) == 0) {
593 if (strcmp(&argv[i][1],OPTION_NOOVERLAY) == 0) {
594 options.noOverlay = 1;
598 if (strcmp(&argv[i][1],OPTION_STKAFTRDATA) == 0) {
599 options.stackOnData = 1;
603 if (strcmp(&argv[i][1],OPTION_PREPROC_ONLY) == 0) {
608 if (strcmp(&argv[i][1],OPTION_C1_MODE) == 0) {
614 if (strcmp(&argv[i][1],OPTION_DUMP_ALL) == 0) {
615 options.dump_rassgn =
621 options.dump_raw = 1;
625 if (strcmp(&argv[i][1],OPTION_COMP_ONLY) == 0) {
630 if (strcmp(&argv[i][1],OPTION_GENERIC) == 0) {
631 options.genericPtr = 1;
635 if (strcmp(&argv[i][1],OPTION_NOPEEP) == 0) {
640 if (strcmp(&argv[i][1],OPTION_ASMPEEP) == 0) {
645 if (strcmp(&argv[i][1],OPTION_DEBUG) == 0) {
650 if (strcmp(&argv[i][1],OPTION_NOREGPARMS) == 0) {
651 options.noregparms = 1;
655 if (strcmp(&argv[i][1],OPTION_PEEP_FILE) == 0) {
656 if (argv[i][1+strlen(OPTION_PEEP_FILE)])
658 &argv[i][1+strlen(OPTION_PEEP_FILE)];
660 options.peep_file = argv[++i];
664 if (strcmp(&argv[i][1],OPTION_LIB_PATH) == 0) {
665 if (argv[i][1+strlen(OPTION_LIB_PATH)])
666 libPaths[nlibPaths++] =
667 &argv[i][1+strlen(OPTION_PEEP_FILE)];
669 libPaths[nlibPaths++] = argv[++i];
673 if (strcmp(&argv[i][1],OPTION_XSTACK_LOC) == 0) {
675 if (argv[i][1+strlen(OPTION_XSTACK_LOC)])
677 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XSTACK_LOC)]));
680 (int) floatFromVal(constVal(argv[++i]));
684 if (strcmp(&argv[i][1],OPTION_XSTACK) == 0) {
685 options.useXstack = 1;
689 if (strcmp(&argv[i][1],OPTION_MAINRETURN) == 0) {
690 options.mainreturn = 1;
694 if (strcmp(&argv[i][1],OPTION_CALLEE_SAVES) == 0) {
695 if (argv[i][1+strlen(OPTION_CALLEE_SAVES)])
696 parseWithComma(options.calleeSaves
697 ,&argv[i][1+strlen(OPTION_CALLEE_SAVES)]);
699 parseWithComma(options.calleeSaves,argv[++i]);
703 if (strcmp(&argv[i][1],OPTION_STACK_LOC) == 0) {
705 if (argv[i][1+strlen(OPTION_STACK_LOC)])
707 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_STACK_LOC)]));
710 (int) floatFromVal(constVal(argv[++i]));
714 if (strcmp(&argv[i][1],OPTION_XRAM_LOC) == 0) {
716 if (argv[i][1+strlen(OPTION_XRAM_LOC)])
718 (unsigned int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_XRAM_LOC)]));
721 (unsigned int) floatFromVal(constVal(argv[++i]));
725 if (strcmp(&argv[i][1],OPTION_IRAM_SIZE) == 0) {
727 if (argv[i][1+strlen(OPTION_IRAM_SIZE)])
729 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IRAM_SIZE)]));
732 (int) floatFromVal(constVal(argv[++i]));
736 if (strcmp(&argv[i][1],OPTION_VERSION) == 0) {
742 if (strcmp(&argv[i][1],OPTION_DATA_LOC) == 0) {
744 if (argv[i][1+strlen(OPTION_DATA_LOC)])
746 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_DATA_LOC)]));
749 (int) floatFromVal(constVal(argv[++i]));
753 if (strcmp(&argv[i][1],OPTION_IDATA_LOC) == 0) {
755 if (argv[i][1+strlen(OPTION_IDATA_LOC)])
757 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_IDATA_LOC)]));
760 (int) floatFromVal(constVal(argv[++i]));
764 if (strcmp(&argv[i][1],OPTION_CODE_LOC) == 0) {
766 if (argv[i][1+strlen(OPTION_CODE_LOC)])
768 (int) floatFromVal(constVal(&argv[i][1+strlen(OPTION_CODE_LOC)]));
771 (int) floatFromVal(constVal(argv[++i]));
776 if (strcmp(&argv[i][1],OPTION_NO_JTBOUND) == 0) {
777 optimize.noJTabBoundary = 1;
781 if (strcmp(&argv[i][1],OPTION_NO_GCSE) == 0) {
782 optimize.global_cse = 0;
786 if (strcmp(&argv[i][1],OPTION_NO_LOOP_INV) == 0) {
787 optimize.loopInvariant = 0;
791 if (strcmp(&argv[i][1],OPTION_NO_LOOP_IND) == 0) {
792 optimize.loopInduction = 0;
796 if (strcmp(&argv[i][1],OPTION_NO_LOOPREV) == 0) {
797 optimize.noLoopReverse = 1;
801 if (!port->parseOption(&argc, argv, &i))
803 werror(W_UNKNOWN_OPTION,argv[i]);
811 /* these are undocumented options */
812 /* if preceded by '/' then turn off certain optmizations, used
813 for debugging only these are also the legacy options from
814 version 1.xx will be removed gradually.
815 It may be an absolute filename.
817 if ( *argv[i] == '/' && strlen(argv[i]) < 3) {
818 switch (argv[i][1]) {
821 optimize.ptrArithmetic=0;
825 switch (argv[i][2]) {
830 optimize.label4 = 0 ;
848 switch (argv[i][2]) {
850 optimize.loopInvariant = 0;
853 optimize.loopInduction = 0;
860 optimize.global_cse = 0;
867 /* if preceded by '-' then option */
868 if ( *argv[i] == '-' ) {
869 switch (argv[i][1]) {
880 /* Used to select the port */
881 if (_setPort(argv[i] + 2)) {
882 werror(W_UNSUPP_OPTION,"-m","Unrecognised processor");
887 werror(W_UNSUPP_OPTION,"-a","use --stack-auto instead");
891 werror(W_UNSUPP_OPTION,"-g","use --generic instead");
894 case 'X' : /* use external stack */
895 werror(W_UNSUPP_OPTION,"-X","use --xstack-loc instead");
899 werror(W_UNSUPP_OPTION,"-x","use --xstack instead");
902 case 'p' : /* stack pointer intial value */
904 werror(W_UNSUPP_OPTION,"-p","use --stack-loc instead");
908 werror(W_UNSUPP_OPTION,"-i","use --idata-loc instead");
912 werror(W_UNSUPP_OPTION,"-r","use --xdata-loc instead");
916 werror(W_UNSUPP_OPTION,"-s","use --code-loc instead");
924 werror(W_UNSUPP_OPTION,"-Y","use -I instead");
929 libPaths[nlibPaths++] = &argv[i][2];
931 libPaths[nlibPaths++] = argv[++i];
936 if (argv[i][2] == 'l') {
938 parseWithComma(linkOptions,&argv[i][3]);
940 parseWithComma(linkOptions,argv[++i]);
942 /* assembler options */
943 if (argv[i][2] == 'a') {
945 parseWithComma((char **)asmOptions,&argv[i][3]);
947 parseWithComma((char **)asmOptions,argv[++i]);
950 werror(W_UNKNOWN_OPTION,argv[i]);
959 #if FEATURE_VERBOSE_EXEC
967 /* preprocessor options */
976 char sOpt = argv[i][1] ;
979 if ( argv[i][2] == ' ' || argv[i][2] == '\0') {
986 if ( argv[i][1] == 'Y' )
988 if (argv[i][1] == 'M')
991 sprintf(buffer, "-%c%s", sOpt, rest);
992 _addToList(preArgv, buffer);
997 if (!port->parseOption(&argc, argv, &i))
998 werror(W_UNKNOWN_OPTION,argv[i]);
1003 if (!port->parseOption(&argc, argv, &i)) {
1004 /* no option must be a filename */
1006 _processC1Arg(argv[i]);
1008 processFile(argv[i]);
1012 /* set up external stack location if not explicitly specified */
1013 if ( !options.xstack_loc )
1014 options.xstack_loc = options.xdata_loc ;
1016 /* if debug option is set the open the cdbFile */
1017 if (/* options.debug && */ srcFileName) {
1018 sprintf(cdbfnbuf,"%s.cdb",srcFileName);
1019 if ((cdbFile = fopen(cdbfnbuf,"w")) == NULL)
1020 werror(E_FILE_OPEN_ERR,cdbfnbuf);
1022 /* add a module record */
1023 fprintf(cdbFile,"M:%s\n",moduleName);
1029 /*-----------------------------------------------------------------*/
1030 /* my_system - will call a program with arguments */
1031 /*-----------------------------------------------------------------*/
1032 char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1033 int my_system (const char *cmd, char **cmd_argv)
1035 char *dir, *got= NULL; int i= 0;
1037 while (!got && try_dir[i])
1039 dir= (char*)malloc(strlen(try_dir[i])+strlen(cmd)+10);
1040 strcpy(dir, try_dir[i]);
1045 strcat(dir, ".exe");
1047 /* Mung slashes into backslashes to keep WIndoze happy. */
1063 if (access(dir, X_OK) == 0)
1070 #if FEATURE_VERBOSE_EXEC
1072 char **pCmd = cmd_argv;
1074 printf("%s ", *pCmd);
1081 i= spawnv(P_WAIT,got,cmd_argv) == -1;
1083 i= spawnvp(P_WAIT,cmd,cmd_argv) == -1;
1085 perror("Cannot exec process ");
1092 /*-----------------------------------------------------------------*/
1093 /* linkEdit : - calls the linkage editor with options */
1094 /*-----------------------------------------------------------------*/
1095 static void linkEdit (char **envp)
1103 srcFileName = "temp";
1105 /* first we need to create the <filename>.lnk file */
1106 sprintf(buffer,"%s.lnk",srcFileName);
1107 if (!(lnkfile = fopen(buffer,"w"))) {
1108 werror(E_FILE_OPEN_ERR,buffer);
1112 /* now write the options */
1113 fprintf(lnkfile,"-mux%c\n", (options.out_fmt ? 's' : 'i'));
1115 /* if iram size specified */
1116 if (options.iram_size)
1117 fprintf(lnkfile,"-a 0x%04x\n",options.iram_size);
1119 /*if (options.debug) */
1120 fprintf(lnkfile,"-z\n");
1122 #define WRITE_SEG_LOC(N, L) \
1123 segName = strdup(N); \
1124 c = strtok(segName, " \t"); \
1125 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1126 if (segName) { free(segName); }
1128 /* code segment start */
1129 WRITE_SEG_LOC(CODE_NAME, options.code_loc);
1131 /* data segment start */
1132 WRITE_SEG_LOC(DATA_NAME, options.data_loc);
1135 WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
1138 WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
1140 /* bit segment start */
1141 WRITE_SEG_LOC(BIT_NAME, 0);
1143 /* add the extra linker options */
1144 for (i=0; linkOptions[i] ; i++)
1145 fprintf(lnkfile,"%s\n",linkOptions[i]);
1147 /* standard library path */
1148 switch(options.model)
1160 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1164 fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
1166 /* other library paths if specified */
1167 for (i = 0 ; i < nlibPaths ; i++ )
1168 fprintf (lnkfile,"-k %s\n",libPaths[i]);
1170 /* standard library files */
1171 fprintf (lnkfile,"-l %s\n",STD_LIB);
1172 fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
1173 fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);
1174 fprintf (lnkfile,"-l %s\n",STD_FP_LIB);
1176 /* additional libraries if any */
1177 for (i = 0 ; i < nlibFiles; i++)
1178 fprintf (lnkfile,"-l %s\n",libFiles[i]);
1180 /* put in the object files */
1181 if (strcmp(srcFileName,"temp"))
1182 fprintf (lnkfile,"%s ",srcFileName);
1184 for (i = 0 ; i < nrelFiles ; i++ )
1185 fprintf (lnkfile,"%s\n",relFiles[i]);
1187 fprintf (lnkfile,"\n-e\n");
1190 buildCmdLine(buffer, argv, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1192 /* call the linker */
1193 if (my_system(argv[0], argv)) {
1194 perror("Cannot exec linker");
1198 if (strcmp(srcFileName,"temp") == 0) {
1199 /* rename "temp.cdb" to "firstRelFile.cdb" */
1200 char *f = strtok(strdup(relFiles[0]),".");
1201 f = strcat(f,".cdb");
1202 rename("temp.cdb",f);
1207 /*-----------------------------------------------------------------*/
1208 /* assemble - spawns the assembler with arguments */
1209 /*-----------------------------------------------------------------*/
1210 static void assemble (char **envp)
1212 char *argv[128]; /* assembler arguments */
1214 buildCmdLine(buffer, argv, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1216 if (my_system(argv[0], argv)) {
1217 perror("Cannot exec assember");
1224 /*-----------------------------------------------------------------*/
1225 /* preProcess - spawns the preprocessor with arguments */
1226 /*-----------------------------------------------------------------*/
1227 static int preProcess (char **envp)
1234 if (!options.c1mode) {
1235 /* if using external stack define the macro */
1236 if ( options.useXstack )
1237 _addToList(preArgv, "-DSDCC_USE_XSTACK");
1239 /* set the macro for stack autos */
1240 if ( options.stackAuto )
1241 _addToList(preArgv, "-DSDCC_STACK_AUTO");
1243 /* set the macro for stack autos */
1244 if ( options.stack10bit )
1245 _addToList(preArgv, "-DSDCC_STACK_TENBIT");
1247 /* set the macro for large model */
1248 switch(options.model)
1251 _addToList(preArgv, "-DSDCC_MODEL_LARGE");
1254 _addToList(preArgv, "-DSDCC_MODEL_SMALL");
1257 _addToList(preArgv, "-DSDCC_MODEL_COMPACT");
1260 _addToList(preArgv, "-DSDCC_MODEL_MEDIUM");
1263 _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
1266 werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
1271 /* add port (processor information to processor */
1272 sprintf(procDef,"-DSDCC_%s",port->target);
1273 _addToList(preArgv,procDef);
1276 preOutName = strdup(tmpnam(NULL));
1278 buildCmdLine(buffer, argv, _preCmd, fullSrcFileName,
1279 preOutName, srcFileName, preArgv);
1281 if (my_system(argv[0], argv)) {
1282 unlink (preOutName);
1283 perror("Cannot exec Preprocessor");
1291 preOutName = fullSrcFileName;
1294 yyin = fopen(preOutName, "r");
1296 perror("Preproc file not found\n");
1303 static void _findPort(int argc, char **argv)
1307 if (!strncmp(*argv, "-m", 2)) {
1308 _setPort(*argv + 2);
1314 /* Use the first in the list */
1320 * initialises and calls the parser
1323 int main ( int argc, char **argv , char **envp)
1325 /* turn all optimizations off by default */
1326 memset(&optimize,0,sizeof(struct optimize));
1328 /*printVersionInfo ();*/
1330 _findPort(argc, argv);
1331 /* Initalise the port. */
1335 setDefaultOptions();
1336 parseCmdLine(argc,argv);
1340 port->finaliseOptions();
1342 /* if no input then printUsage & exit */
1343 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name)) {
1361 if (!options.c1mode)
1372 if (!options.cc_only &&
1376 (srcFileName || nrelFiles)) {
1377 if (port->linker.do_link)
1378 port->linker.do_link();
1383 if (yyin && yyin != stdin)
1386 if (preOutName && !options.c1mode) {