#include "asm.h"
#include <time.h>
#include "newalloc.h"
+#include <fcntl.h>
+#include <sys/stat.h>
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
+#ifdef _WIN32
+#include <io.h>
+#else
#include <unistd.h>
#endif
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 */
DEFSETFUNC (closeTmpFiles)
{
FILE *tfile = item;
+ int ret;
- if (tfile)
- fclose (tfile);
+ if (tfile) {
+ ret = fclose (tfile);
+ assert(ret == 0);
+ }
return 0;
}
DEFSETFUNC (rmTmpFiles)
{
char *name = item;
+ int ret;
- if (name)
- {
- unlink (name);
+ if (name) {
+ ret = unlink (name);
+ assert(ret == 0);
Safe_free (name);
- }
+ }
+
return 0;
}
rm_tmpfiles (void)
{
/* close temporary files */
+ applyToSet (pipeSet, closePipes);
+ /* close temporary files */
+ deleteSet (&pipeSet);
+
applyToSet (tmpfileSet, closeTmpFiles);
/* remove temporary files */
applyToSet (tmpfileNameSet, rmTmpFiles);
char *
aopLiteralLong (value * val, int offset, int size)
{
- char *rs;
union {
float f;
unsigned char c[4];
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 */
/* 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);
}
/*-----------------------------------------------------------------*/
// 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);
/* 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;
+ DCL_TYPE (val->type) = port->mem.code_ro;
}
else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
DCL_TYPE (val->type) = FPOINTER;
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;
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 (;;)
{
resolveIvalSym (sym->ival);
printIval (sym, sym->type, sym->ival, out);
noAlloc--;
- // now we don't need sym->ival anymore
- deleteSetItem(&map->syms, list2val(sym->ival)->sym);
+ /* 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 */
/* -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")))
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";
+ }
+ }
+#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);
}
- return tmpnam (NULL);
+ 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;
}