Add some missing #include directives
[pspp] / src / libpspp / pool.c
index ecf263abcda8ec26324b25bb46b0045cf161e336..5309c729efa77c2f5ce66cf1e9521a64fc16489d 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2000 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2010, 2011, 2012 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
-#include "pool.h"
+
+#include "libpspp/pool.h"
+
+#include <stdint.h>
 #include <stdlib.h>
-#include <libpspp/assertion.h>
-#include "message.h"
-#include "str.h"
 
-#include "size_max.h"
-#include "xalloc.h"
+#include "libpspp/assertion.h"
+#include "libpspp/message.h"
+#include "libpspp/temp-file.h"
+#include "libpspp/str.h"
+
+#include "gl/xalloc-oversized.h"
+#include "gl/xalloc.h"
 
 /* Fast, low-overhead memory block suballocator. */
 struct pool
@@ -45,6 +50,7 @@ enum
   {
     POOL_GIZMO_MALLOC,
     POOL_GIZMO_FILE,
+    POOL_GIZMO_TEMP_FILE,
     POOL_GIZMO_SUBPOOL,
     POOL_GIZMO_REGISTERED,
   };
@@ -64,7 +70,7 @@ struct pool_gizmo
     /* Type-dependent info. */
     union
       {
-       FILE *file;             /* POOL_GIZMO_FILE. */
+       FILE *file;             /* POOL_GIZMO_FILE, POOL_GIZMO_TEMP_FILE. */
        struct pool *subpool;   /* POOL_GIZMO_SUBPOOL. */
 
        /* POOL_GIZMO_REGISTERED. */
@@ -91,10 +97,16 @@ union align
     void (*fp) (void);
     long l;
     double d;
+
+    /* glibc jmp_buf on ia64 requires 16-byte alignment.  This ensures it. */
+    size_t s[2];
   };
 
 /* This should be the alignment size used by malloc().  The size of
-   the union above is correct, if not optimal, in all known cases. */
+   the union above is correct, if not optimal, in all known cases.
+
+   This is normally 8 bytes for 32-bit architectures and 16 bytes for 64-bit
+   architectures. */
 #define ALIGN_SIZE sizeof (union align)
 
 /* DISCRETE_BLOCKS may be declared as nonzero to prevent
@@ -294,7 +306,8 @@ pool_alloc (struct pool *pool, size_t amt)
 void *
 pool_alloc_unaligned (struct pool *pool, size_t amt)
 {
-  assert (pool != NULL);
+  if (pool == NULL)
+    return xmalloc (amt);
 
 #ifndef DISCRETE_BLOCKS
   /* Strings need not be aligned on any boundary, but some
@@ -364,6 +377,19 @@ pool_strdup (struct pool *pool, const char *string)
   return pool_clone_unaligned (pool, string, strlen (string) + 1);
 }
 
+/* Duplicates the SIZE bytes of STRING, plus a trailing 0 byte,
+   and returns a pointer to the duplicate.  For use only with
+   strings, because the returned pointere may not be aligned
+   properly for other types. */
+char *
+pool_strdup0 (struct pool *pool, const char *string, size_t size)
+{
+  char *new_string = pool_alloc_unaligned (pool, size + 1);
+  memcpy (new_string, string, size);
+  new_string[size] = '\0';
+  return new_string;
+}
+
 /* Formats FORMAT with the given ARGS in memory allocated from
    POOL and returns the formatted string. */
 char *
@@ -742,41 +768,78 @@ pool_fclose (struct pool *pool, FILE *file)
   return fclose (file);
 }
 
-/* Creates a temporary file with tmpfile() and returns a handle to it
-   if successful or a null pointer if not.
+/* Attaches FILE to POOL.
    The file will be closed automatically when POOL is destroyed, or it
    may be closed explicitly in advance using pool_fclose(), or
    detached from the pool with pool_detach_file(). */
+void
+pool_attach_file (struct pool *pool, FILE *file)
+{
+  struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
+  g->type = POOL_GIZMO_FILE;
+  g->p.file = file;
+  add_gizmo (pool, g);
+}
+
+/* Detaches FILE from POOL. */
+void
+pool_detach_file (struct pool *pool, FILE *file)
+{
+  struct pool_gizmo *g;
+
+  for (g = pool->gizmos; g; g = g->next)
+    if (g->type == POOL_GIZMO_FILE && g->p.file == file)
+      {
+        delete_gizmo (pool, g);
+        return;
+      }
+}
+
+/* Creates a temporary file with create_temp_file() and returns a handle to it
+   if successful or a null pointer if not.
+   The file will be closed automatically when POOL is destroyed, or it
+   may be closed explicitly in advance using pool_fclose_temp_file(), or
+   detached from the pool with pool_detach_temp_file(). */
 FILE *
-pool_tmpfile (struct pool *pool)
+pool_create_temp_file (struct pool *pool)
 {
-  FILE *file = tmpfile ();
+  FILE *file = create_temp_file ();
   if (file != NULL)
-    pool_attach_file (pool, file);
+    pool_attach_temp_file (pool, file);
   return file;
 }
 
-/* Attaches FILE to POOL.
+/* Closes file FILE managed by POOL.
+   FILE must have been opened with create_temp_file(). */
+void
+pool_fclose_temp_file (struct pool *pool, FILE *file)
+{
+  assert (pool && file);
+  pool_detach_temp_file (pool, file);
+  close_temp_file (file);
+}
+
+/* Attaches FILE, which must have been opened with create_temp_file(), to POOL.
    The file will be closed automatically when POOL is destroyed, or it
-   may be closed explicitly in advance using pool_fclose(), or
-   detached from the pool with pool_detach_file(). */
+   may be closed explicitly in advance using pool_fclose_temp_file(), or
+   detached from the pool with pool_detach_temp_file(). */
 void
-pool_attach_file (struct pool *pool, FILE *file)
+pool_attach_temp_file (struct pool *pool, FILE *file)
 {
   struct pool_gizmo *g = pool_alloc (pool, sizeof *g);
-  g->type = POOL_GIZMO_FILE;
+  g->type = POOL_GIZMO_TEMP_FILE;
   g->p.file = file;
   add_gizmo (pool, g);
 }
 
-/* Detaches FILE from POOL. */
+/* Detaches FILE that was opened with create_temp_file() from POOL. */
 void
-pool_detach_file (struct pool *pool, FILE *file)
+pool_detach_temp_file (struct pool *pool, FILE *file)
 {
   struct pool_gizmo *g;
 
   for (g = pool->gizmos; g; g = g->next)
-    if (g->type == POOL_GIZMO_FILE && g->p.file == file)
+    if (g->type == POOL_GIZMO_TEMP_FILE && g->p.file == file)
       {
         delete_gizmo (pool, g);
         return;
@@ -934,6 +997,9 @@ free_gizmo (struct pool_gizmo *gizmo)
     case POOL_GIZMO_FILE:
       fclose (gizmo->p.file);  /* Ignore errors. */
       break;
+    case POOL_GIZMO_TEMP_FILE:
+      close_temp_file (gizmo->p.file); /* Ignore errors. */
+      break;
     case POOL_GIZMO_SUBPOOL:
       gizmo->p.subpool->parent = NULL;
       pool_destroy (gizmo->p.subpool);