/* PSPP - computes sample statistics.
Copyright (C) 2000 Free Software Foundation, Inc.
- Written by Ben Pfaff <blp@gnu.org>.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "pool.h"
#include <stdlib.h>
#include "alloc.h"
+#include <libpspp/assertion.h>
#include "message.h"
#include "size_max.h"
#include "str.h"
/* DISCRETE_BLOCKS may be declared as nonzero to prevent
suballocation of blocks. This is useful under memory
- debuggers like Checker or valgrind because it allows the
- source location of bugs to be more accurately pinpointed.
+ debuggers like valgrind because it allows the source location
+ of bugs to be more accurately pinpointed.
On the other hand, if we're testing the library, then we want to
test the library's real functionality, not its crippled, slow,
{
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. */
subpool->parent = pool;
}
-/* Opens file FILENAME with mode MODE and returns a handle to it
+/* Opens file FILE_NAME with mode MODE 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(), or
detached from the pool with pool_detach_file(). */
FILE *
-pool_fopen (struct pool *pool, const char *filename, const char *mode)
+pool_fopen (struct pool *pool, const char *file_name, const char *mode)
{
FILE *f;
- assert (pool && filename && mode);
- f = fopen (filename, mode);
- if (f == NULL)
- return NULL;
+ assert (pool && file_name && mode);
+ f = fopen (file_name, mode);
+ if (f != NULL)
+ pool_attach_file (pool, f);
return f;
}
}
/* Unregisters previously registered P from POOL.
- Returns nonzero only if P was found to be registered in POOL. */
-int
+ Returns true only if P was found to be registered in POOL. */
+bool
pool_unregister (struct pool *pool, void *p)
{
assert (pool && p);
if (g->type == POOL_GIZMO_REGISTERED && g->p.registered.p == p)
{
delete_gizmo (pool, g);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
\f
/* Partial freeing. */
gizmo->p.registered.free (gizmo->p.registered.p);
break;
default:
- assert (0);
+ NOT_REACHED ();
}
}