undid the hackup of const and volatile, the problem is much bigger
[fw/sdcc] / src / SDCCglue.c
index c4ef6f2f5e4ef2f02c53992e1dcbb2b561904220..400f36ffd59a6c0411c69564c339158de421f4d3 100644 (file)
 #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
 
@@ -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);
@@ -145,7 +175,7 @@ aopLiteralLong (value * val, int offset, int size)
 
        /* it is type float */
        fl.f = (float) floatFromVal (val);
-#ifdef _BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
        tsprintf (buffer, sizeof(buffer), 
                  "!immedbyte", fl.c[3 - offset]);
 #else
@@ -375,10 +405,10 @@ 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;
+                               DCL_TYPE (val->type) = port->mem.code_ro;
                        }
                        else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
                                DCL_TYPE (val->type) = FPOINTER;
@@ -434,7 +464,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;
@@ -780,8 +810,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 (;;)
     {
@@ -1155,8 +1188,10 @@ emitStaticSeg (memmap * map, FILE * out)
              resolveIvalSym (sym->ival);
              printIval (sym, sym->type, sym->ival, out);
              noAlloc--;
-             // if sym->ival is a string, WE don't need it anymore
-             if (IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
+             /* 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);
              }
@@ -1703,58 +1738,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";
+    }
+  }
+#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);
     }
-  return tmpnam (NULL);
+
+    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;
 }