From: Ben Pfaff Date: Mon, 8 May 2006 01:18:10 +0000 (+0000) Subject: Add pool_asprintf(), pool_vasprintf(). X-Git-Tag: v0.6.0~868 X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7bafb24d29d2370665c02e070f90fa180ad8056;p=pspp-builds.git Add pool_asprintf(), pool_vasprintf(). --- diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog index 31097a10..386d317c 100644 --- a/src/libpspp/ChangeLog +++ b/src/libpspp/ChangeLog @@ -1,3 +1,8 @@ +Sun May 7 18:17:32 2006 Ben Pfaff + + * pool.c (pool_vasprintf): New function. + (pool_asprintf) New function. + Sun May 7 17:09:54 2006 Ben Pfaff * compiler.h: (macro WARN_UNUSED_RESULT) New macro. diff --git a/src/libpspp/pool.c b/src/libpspp/pool.c index a0dc99e3..0e6c9358 100644 --- a/src/libpspp/pool.c +++ b/src/libpspp/pool.c @@ -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; +} /* Standard allocation routines. */ diff --git a/src/libpspp/pool.h b/src/libpspp/pool.h index f2b01fe1..b735d912 100644 --- a/src/libpspp/pool.h +++ b/src/libpspp/pool.h @@ -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 *);