Add pool_asprintf(), pool_vasprintf().
authorBen Pfaff <blp@gnu.org>
Mon, 8 May 2006 01:18:10 +0000 (01:18 +0000)
committerBen Pfaff <blp@gnu.org>
Mon, 8 May 2006 01:18:10 +0000 (01:18 +0000)
src/libpspp/ChangeLog
src/libpspp/pool.c
src/libpspp/pool.h

index 31097a107da4eb8277a94be94437b8feb8ad6771..386d317c77a4f6b5d11ce27da55f8965baece708 100644 (file)
@@ -1,3 +1,8 @@
+Sun May  7 18:17:32 2006  Ben Pfaff  <blp@gnu.org>
+
+       * pool.c (pool_vasprintf): New function.
+       (pool_asprintf) New function.
+
 Sun May  7 17:09:54 2006  Ben Pfaff  <blp@gnu.org>
 
        * compiler.h: (macro WARN_UNUSED_RESULT) New macro.
index a0dc99e32d79467e0955a0c0dcddc7258f93e4d0..0e6c9358fc828cd10f027c32d9f5750c7ffd5c23 100644 (file)
@@ -364,6 +364,72 @@ pool_strdup (struct pool *pool, const char *string)
 {
   return pool_clone_unaligned (pool, string, strlen (string) + 1);
 }
+
+/* Formats FORMAT with the given ARGS in memory allocated from
+   POOL and returns the formatted string. */
+char *
+pool_vasprintf (struct pool *pool, const char *format, va_list args_)
+{
+  struct pool_block *b;
+  va_list args;
+  int needed, avail;
+  char *s;
+
+  va_copy (args, args_);
+  b = pool->blocks;
+  avail = BLOCK_SIZE - b->ofs;
+  s = ((char *) b) + b->ofs;
+  needed = vsnprintf (s, avail, format, args);
+  va_end (args);
+
+  if (needed >= 0) 
+    {
+      if (needed < avail) 
+        {
+          /* Success.  Reserve the space that was actually used. */
+          b->ofs += needed + 1;
+        }
+      else
+        {
+          /* Failure, but now we know how much space is needed.
+             Allocate that much and reformat. */
+          s = pool_alloc (pool, needed + 1);
+
+          va_copy (args, args_);
+          vsprintf (s, format, args);
+          va_end (args);
+        }
+    }
+  else 
+    {
+      /* Some old libc's returned -1 when the destination string
+         was too short.  This should be uncommon these days and
+         it's a rare case anyhow.  Use the easiest solution: punt
+         to dynamic allocation. */
+      va_copy (args, args_);
+      s = xvasprintf (format, args);
+      va_end (args);
+
+      pool_register (pool, free, s);
+    }
+
+  return s;
+}
+
+/* Formats FORMAT in memory allocated from POOL
+   and returns the formatted string. */
+char *
+pool_asprintf (struct pool *pool, const char *format, ...)
+{
+  va_list args;
+  char *string;
+  
+  va_start (args, format);
+  string = pool_vasprintf (pool, format, args);
+  va_end (args);
+
+  return string;
+}
 \f
 /* Standard allocation routines. */
 
index f2b01fe195522cdf0467ae65f1d2e515c8371b16..b735d912e09577826522a4d9fa2ab5747540a8e8 100644 (file)
@@ -63,7 +63,10 @@ void *pool_clone (struct pool *, const void *, size_t) MALLOC_LIKE;
 void *pool_alloc_unaligned (struct pool *, size_t) MALLOC_LIKE;
 void *pool_clone_unaligned (struct pool *, const void *, size_t) MALLOC_LIKE;
 char *pool_strdup (struct pool *, const char *) MALLOC_LIKE;
-char *pool_strcat (struct pool *, const char *, ...) MALLOC_LIKE;
+char *pool_vasprintf (struct pool *, const char *, va_list) 
+     MALLOC_LIKE PRINTF_FORMAT (2, 0);
+char *pool_asprintf (struct pool *, const char *, ...)
+     MALLOC_LIKE PRINTF_FORMAT (2, 3);
 
 /* Standard allocation routines. */
 void *pool_malloc (struct pool *, size_t) MALLOC_LIKE;
@@ -79,7 +82,7 @@ void pool_add_subpool (struct pool *, struct pool *subpool);
 
 /* Files. */
 FILE *pool_fopen (struct pool *, const char *, const char *);
-int pool_fclose (struct pool *, FILE *);
+int pool_fclose (struct pool *, FILE *) WARN_UNUSED_RESULT;
 FILE *pool_tmpfile (struct pool *);
 void pool_attach_file (struct pool *, FILE *);
 void pool_detach_file (struct pool *, FILE *);