X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCglue.c;h=5e1d084d98ccddca5d4fd5a8514aa787eaa36977;hb=bc04edccb1ca8d1dafb8ae5c96b047005029b866;hp=6b100947609d50c93f57cd255e586c900ac944ab;hpb=9df3b7ca4140682c53e39d63e8b91fe52609dca7;p=fw%2Fsdcc diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 6b100947..5e1d084d 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -26,8 +26,12 @@ #include "asm.h" #include #include "newalloc.h" +#include +#include -#if !defined(__BORLANDC__) && !defined(_MSC_VER) +#ifdef _WIN32 +#include +#else #include #endif @@ -42,9 +46,26 @@ unsigned maxInterrupts = 6; int allocInfo = 1; symbol *mainf; extern char *VersionString; +set *pipeSet = NULL; /* set of pipes */ set *tmpfileSet = NULL; /* set of tmp file created by the compiler */ set *tmpfileNameSet = NULL; /* All are unlinked at close. */ +/*-----------------------------------------------------------------*/ +/* closePipes - closes all pipes created by the compiler */ +/*-----------------------------------------------------------------*/ +DEFSETFUNC (closePipes) +{ + FILE *pfile = item; + int ret; + + if (pfile) { + ret = pclose (pfile); + assert(ret != -1); + } + + return 0; +} + /*-----------------------------------------------------------------*/ /* closeTmpFiles - closes all tmp files created by the compiler */ /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */ @@ -52,9 +73,12 @@ set *tmpfileNameSet = NULL; /* All are unlinked at close. */ DEFSETFUNC (closeTmpFiles) { FILE *tfile = item; + int ret; - if (tfile) - fclose (tfile); + if (tfile) { + ret = fclose (tfile); + assert(ret == 0); + } return 0; } @@ -66,12 +90,14 @@ DEFSETFUNC (closeTmpFiles) DEFSETFUNC (rmTmpFiles) { char *name = item; + int ret; - if (name) - { - unlink (name); + if (name) { + ret = unlink (name); + assert(ret == 0); Safe_free (name); - } + } + return 0; } @@ -82,6 +108,10 @@ void rm_tmpfiles (void) { /* close temporary files */ + applyToSet (pipeSet, closePipes); + /* close temporary files */ + deleteSet (&pipeSet); + applyToSet (tmpfileSet, closeTmpFiles); /* remove temporary files */ applyToSet (tmpfileNameSet, rmTmpFiles); @@ -107,7 +137,6 @@ copyFile (FILE * dest, FILE * src) char * aopLiteralLong (value * val, int offset, int size) { - char *rs; union { float f; unsigned char c[4]; @@ -127,17 +156,18 @@ aopLiteralLong (value * val, int offset, int size) v >>= (offset * 8); switch (size) { case 1: - tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff); + tsprintf (buffer, sizeof(buffer), + "!immedbyte", (unsigned int) v & 0xff); break; case 2: - tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff); + tsprintf (buffer, sizeof(buffer), + "!immedword", (unsigned int) v & 0xffff); break; default: /* Hmm. Too big for now. */ assert (0); } - rs = Safe_calloc (1, strlen (buffer) + 1); - return strcpy (rs, buffer); + return Safe_strdup (buffer); } /* PENDING: For now size must be 1 */ @@ -145,13 +175,14 @@ aopLiteralLong (value * val, int offset, int size) /* it is type float */ fl.f = (float) floatFromVal (val); -#ifdef _BIG_ENDIAN - tsprintf (buffer, "!immedbyte", fl.c[3 - offset]); +#ifdef WORDS_BIGENDIAN + tsprintf (buffer, sizeof(buffer), + "!immedbyte", fl.c[3 - offset]); #else - tsprintf (buffer, "!immedbyte", fl.c[offset]); + tsprintf (buffer, sizeof(buffer), + "!immedbyte", fl.c[offset]); #endif - rs = Safe_calloc (1, strlen (buffer) + 1); - return strcpy (rs, buffer); + return Safe_strdup (buffer); } /*-----------------------------------------------------------------*/ @@ -232,18 +263,22 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) continue; /* print extra debug info if required */ - if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); - if (!sym->level) /* global */ - if (IS_STATIC (sym->etype)) - fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ + if (options.debug) + { + if (!sym->level) /* global */ + { + if (IS_STATIC (sym->etype)) + fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ + else + fprintf (map->oFile, "G$"); /* scope is global */ + } else - fprintf (map->oFile, "G$"); /* scope is global */ - else - /* symbol is local */ - fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); - fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); - } + { + /* symbol is local */ + fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + } + fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); + } /* if it has an initial value then do it only if it is a global variable */ @@ -252,10 +287,11 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag) // create a new "XINIT (CODE)" symbol, that will be emitted later newSym=copySymbol (sym); SPEC_OCLS(newSym->etype)=xinit; - sprintf (newSym->name, "__xinit_%s", sym->name); - sprintf (newSym->rname,"__xinit_%s", sym->rname); + SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name); + SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname); SPEC_CONST(newSym->etype)=1; SPEC_STAT(newSym->etype)=1; + resolveIvalSym(newSym->ival); // add it to the "XINIT (CODE)" segment addSet(&xinit->syms, newSym); @@ -373,7 +409,7 @@ initPointer (initList * ilist, sym_link *toType) /* address of symbol */ if (IS_AST_SYM_VALUE (expr->left)) { val = copyValue (AST_VALUE (expr->left)); - val->type = newLink (); + val->type = newLink (DECLARATOR); if (SPEC_SCLS (expr->left->etype) == S_CODE) { DCL_TYPE (val->type) = CPOINTER; DCL_PTR_CONST (val->type) = port->mem.code_ro; @@ -432,7 +468,7 @@ initPointer (initList * ilist, sym_link *toType) IS_ARRAY(expr->right->ftype)) { val = copyValue (AST_VALUE (expr->right)); - val->type = newLink (); + val->type = newLink (DECLARATOR); if (SPEC_SCLS (expr->right->etype) == S_CODE) { DCL_TYPE (val->type) = CPOINTER; DCL_PTR_CONST (val->type) = port->mem.code_ro; @@ -778,8 +814,11 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, iloop = ilist->init.deep; lcnt = DCL_ELEM (type); - for (last_type = type->next; last_type && DCL_ELEM (last_type); last_type = last_type->next) + for (last_type = type->next; + last_type && IS_DECL(last_type) && DCL_ELEM (last_type); + last_type = last_type->next) { lcnt *= DCL_ELEM (last_type); + } for (;;) { @@ -1115,7 +1154,7 @@ emitStaticSeg (memmap * map, FILE * out) /* print extra debug info if required */ if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); + if (!sym->level) { /* global */ if (IS_STATIC (sym->etype)) @@ -1153,6 +1192,13 @@ emitStaticSeg (memmap * map, FILE * out) resolveIvalSym (sym->ival); printIval (sym, sym->type, sym->ival, out); noAlloc--; + /* if sym is a simple string and sym->ival is a string, + WE don't need it anymore */ + if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) && + IS_AST_SYM_VALUE(list2expr(sym->ival)) && + list2val(sym->ival)->sym->isstrlit) { + freeStringSymbol(list2val(sym->ival)->sym); + } } else { /* allocate space */ @@ -1378,8 +1424,6 @@ emitOverlay (FILE * afile) /* print extra debug info if required */ if (options.debug) { - cdbSymbol (sym, cdbFile, FALSE, FALSE); - if (!sym->level) { /* global */ if (IS_STATIC (sym->etype)) @@ -1437,7 +1481,7 @@ glue (void) addSetHead (&tmpfileSet, ovrFile); /* print the global struct definitions */ if (options.debug) - cdbStructBlock (0, cdbFile); + cdbStructBlock (0); vFile = tempfile (); /* PENDING: this isnt the best place but it will do */ @@ -1454,18 +1498,20 @@ glue (void) /* do the overlay segments */ emitOverlay (ovrFile); + outputDebugSymbols(); + /* now put it all together into the assembler file */ /* create the assembler file name */ /* -o option overrides default name? */ if ((noAssemble || options.c1mode) && fullDstFileName) { - strcpy (scratchFileName, fullDstFileName); + strncpyz (scratchFileName, fullDstFileName, PATH_MAX); } else { - strcpy (scratchFileName, dstFileName); - strcat (scratchFileName, port->assembler.file_ext); + strncpyz (scratchFileName, dstFileName, PATH_MAX); + strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX); } if (!(asmFile = fopen (scratchFileName, "w"))) @@ -1696,58 +1742,148 @@ glue (void) rm_tmpfiles (); } -/** Creates a temporary file name a'la tmpnam which avoids the bugs - in cygwin wrt c:\tmp. - Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). + +/** Creates a temporary file with unoque file name + Scans, in order: + - TMP, TEMP, TMPDIR env. varibles + - if Un*x system: /usr/tmp and /tmp + - root directory using mkstemp() if avaliable + - default location using tempnam() */ -char * -tempfilename (void) +static int +tempfileandname(char *fname, size_t len) { +#define TEMPLATE "sdccXXXXXX" +#define TEMPLATE_LEN ((sizeof TEMPLATE) - 1) + const char *tmpdir = NULL; - if (getenv ("TMP")) - tmpdir = getenv ("TMP"); - else if (getenv ("TEMP")) - tmpdir = getenv ("TEMP"); - else if (getenv ("TMPDIR")) - tmpdir = getenv ("TMPDIR"); - if (tmpdir) - { - char *name = tempnam (tmpdir, "sdcc"); - if (name) - { - return name; - } + int fd; + + if ((tmpdir = getenv ("TMP")) == NULL) + if ((tmpdir = getenv ("TEMP")) == NULL) + tmpdir = getenv ("TMPDIR"); + +#ifndef _WIN32 + { + /* try with /usr/tmp and /tmp on Un*x systems */ + struct stat statbuf; + + if (tmpdir == NULL) { + if (stat("/usr/tmp", &statbuf) != -1) + tmpdir = "/usr/tmp"; + else if (stat("/tmp", &statbuf) != -1) + tmpdir = "/tmp"; } - return tmpnam (NULL); + } +#endif + +#ifdef HAVE_MKSTEMP + { + char fnamebuf[PATH_MAX]; + size_t name_len; + + if (fname == NULL || len == 0) { + fname = fnamebuf; + len = sizeof fnamebuf; + } + + if (tmpdir) { + name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN; + + assert(name_len < len); + if (!(name_len < len)) /* in NDEBUG is defined */ + return -1; /* buffer too small, temporary file can not be created */ + + sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir); + } + else { + name_len = TEMPLATE_LEN; + + assert(name_len < len); + if (!(name_len < len)) /* in NDEBUG is defined */ + return -1; /* buffer too small, temporary file can not be created */ + + strcpy(fname, TEMPLATE); + } + + fd = mkstemp(fname); + } +#else + { + char *name = tempnam(tmpdir, "sdcc"); + + if (name == NULL) { + perror("Can't create temporary file name"); + exit(1); + } + + assert(strlen(name) < len); + if (!(strlen(name) < len)) /* in NDEBUG is defined */ + return -1; /* buffer too small, temporary file can not be created */ + + strcpy(fname, name); +#ifdef _WIN32 + fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE); +#else + fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); +#endif + } +#endif + + if (fd == -1) { + perror("Can't create temporary file"); + exit(1); + } + + return fd; } -/** Creates a temporary file a'la tmpfile which avoids the bugs - in cygwin wrt c:\tmp. - Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). + +/** Create a temporary file name +*/ +char * +tempfilename(void) +{ + int fd; + static char fnamebuf[PATH_MAX]; + + if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) { + fprintf(stderr, "Can't create temporary file name!"); + exit(1); + } + + fd = close(fd); + assert(fd != -1); + + return fnamebuf; +} + + +/** Create a temporary file and add it to tmpfileNameSet, + so that it is removed explicitly by rm_tmpfiles() + or implicitly at program extit. */ FILE * -tempfile (void) +tempfile(void) { - const char *tmpdir = NULL; - if (getenv ("TMP")) - tmpdir = getenv ("TMP"); - else if (getenv ("TEMP")) - tmpdir = getenv ("TEMP"); - else if (getenv ("TMPDIR")) - tmpdir = getenv ("TMPDIR"); - if (tmpdir) - { - char *name = Safe_strdup( tempnam (tmpdir, "sdcc")); - if (name) - { - FILE *fp = fopen (name, "w+b"); - if (fp) - { - addSetHead (&tmpfileNameSet, name); - } - return fp; - } - return NULL; - } - return tmpfile (); + int fd; + char *tmp; + FILE *fp; + char fnamebuf[PATH_MAX]; + + if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) { + fprintf(stderr, "Can't create temporary file!"); + exit(1); + } + + tmp = Safe_strdup(fnamebuf); + if (tmp) + addSetHead(&tmpfileNameSet, tmp); + + if ((fp = fdopen(fd, "w+b")) == NULL) { + perror("Can't create temporary file!"); + exit(1); + } + + return fp; }