Here is the whole set of supporting routines.
-Matt
/*
* STRDUP.C
*
* $Backplane: backplane/src/libsupport/strdup.c,v 1.13 2001/04/03 00:03:18 dillon Exp
$
*/
#include "defs.h"
Export char *safe_strdup(const char *s);
Export char *safe_strdup_segment(const char *start, const char *end);
Export char *safe_replace(char **pptr, const char *s);
Export char *safe_replacef(char **pptr, const char *ctl, ...);
Export char *safe_append(char **pptr, const char *s);
Export char *safe_appendf(char **pptr, const char *ctl, ...);
/*
* safe_strdup() - Safe version of strdup(), core dump if alloc fails
*/
char *
safe_strdup(const char *s)
{
char *r;
if (s == NULL)
return(NULL);
if ((r = strdup(s)) == NULL)
fatalmem();
return(r);
}
/*
* safe_replace() - Free existing string, allocate copy
*
* Allocates a copy of 's' and stores the copy in *pptr. The
* previous contents of *ptr is freed.
*
* Typical useage is to initialize *pptr to NULL, then use
* safe_replace() as many times as necessary (or within a loop),
* then safe_free(pptr) after all operations are complete.
*
* This code optimizes the case where 's' is the same as *pptr.
*/
char *
safe_replace(char **pptr, const char *s)
{
/*
* Same data (also occurs if s == *ptr), nothing to do
*/
if (*pptr) {
if (s && strcmp(s, *pptr) == 0)
return(*pptr);
free(*pptr);
}
/*
* free old, dup new.
*/
*pptr = (s) ? strdup(s) : NULL;
return(*pptr);
}
/*
* safe_replacef() - Free existing string, allocate copy, with formatting
*
* This operates the same as safe_replace(), except a printf-style
* format string and arguments is passed rather then a simple string.
*/
char *
safe_replacef(char **pptr, const char *ctl, ...)
{
va_list va;
char *optr = *pptr;
if (ctl) {
va_start(va, ctl);
if (vasprintf(pptr, ctl, va) < 0)
fatalmem();
va_end(va);
}
safe_free(&optr);
return(*pptr);
}
/*
* safe_append() - Append to an existing string, reallocating as required
*
* *pptr represents allocated storage or NULL. *pptr is replaced
* with a new string which is the original string with the 's' argument
* appended. The original string is deallocated.
*
* *pptr is usually initialized to NULL, causing this routine to do
* the initial allocation as well as the reallocation in successive
* calls. safe_free(pptr) is typically called after all operations
* are complete and the result string is no longer needed.
*/
char *
safe_append(char **pptr, const char *s)
{
char *old;
char *new;
if ((old = *pptr) != NULL) {
int newLen = strlen(old) + strlen(s) + 1;
new = malloc(newLen);
snprintf(new, newLen, "%s%s", old, s);
free(old);
} else {
new = strdup(s);
}
*pptr = new;
return(new);
}
/*
* safe_appendf() - Var-args version of safe_append()
*
* Operates like safe_append(), but using a printf-like format string
* and additional arguments to generate the string to append.
*/
char *
safe_appendf(char **pptr, const char *ctl, ...)
{
char *old;
char *new;
va_list va;
va_start(va, ctl);
if ((old = *pptr) != NULL) {
if (vasprintf(&new, ctl, va) < 0)
DBASSERT(0);
*pptr = new;
asprintf(&new, "%s%s", old, new);
free(*pptr);
free(old);
} else {
if (vasprintf(&new, ctl, va) < 0)
DBASSERT(0);
}
va_end(va);
*pptr = new;
return(new);
}
/*
* safe_strdup_segment() - duplicate a portion of a string
*
* Returns an allocated string representing the specified segment
* between start and end (end non-inclusive). Dumps core if the
* allocation fails. The returned string will be null terminated.
*/
char *
safe_strdup_segment(const char *start, const char *end)
{
char *new;
int len;
if (start == NULL || end == NULL)
return(NULL);
if (start > end) {
const char *temp = end;
end = start;
start = temp;
}
len = end - start;
new = safe_malloc(len + 1);
memcpy(new, start, len);
new[len] = '\0';
return(new);
}
/*
* ASPRINTF.C
*
* $Backplane: backplane/src/libsupport/asprintf.c,v 1.4 2001/04/03 00:03:18 dillon
Exp $
*/
#include "defs.h"
Export void safe_asprintf(char **pptr, const char *ctl, ...);
Export void safe_vasprintf(char **pptr, const char *ctl, va_list va);
/*
* safe_asprintf() - safe version of asprintf()
*
* This routine implements a safe version of asprintf(), which allocates
* the result string and stored it in *ptr. The program will dump
* core if the allocation fails.
*
* *ptr need not be initialized to anything in particular prior to
* calling this routine.
*
* Since the return value from the stdc asprintf() is not portable, we
* simply return void in our safe version.
*/
void
safe_asprintf(char **pptr, const char *ctl, ...)
{
va_list va;
int r;
va_start(va, ctl);
r = vasprintf(pptr, ctl, va);
va_end(va);
DBASSERT(r >= 0);
}
/*
* safe_vasprintf() - safe version of var-args asprintf.
*
* This routine implements a safe version of vasprintf(), which allocates
* the result string and stored it in *ptr. The program will dump
* core if the allocation fails.
*
* *ptr need not be initialized to anything in particular prior to
* calling this routine.
*
* Since the return value from the stdc vasprintf() is not portable, we
* simply return void in our safe version.
*/
void
safe_vasprintf(char **pptr, const char *ctl, va_list va)
{
int r;
r = vasprintf(pptr, ctl, va);
DBASSERT(r >= 0);
}
/*
* MALLOC.C
*
* $Backplane: backplane/src/libsupport/malloc.c,v 1.11 2001/04/03 00:03:18 dillon Exp
$
*/
#include "defs.h"
Export void *safe_malloc(size_t bytes);
Export void *safe_realloc(void *ptr, size_t size);
Export void safe_free(char **ptr);
/*
* safe_malloc() - safe version of malloc. Dumps core if the allocation fails
*/
void *
safe_malloc(size_t bytes)
{
char *ptr = malloc(bytes);
if (ptr == NULL)
fatalmem();
return(ptr);
}
/*
* safe_realloc() - safe version of realloc. Dumps core if the
* allocation fails
*/
void *
safe_realloc(void *ptr, size_t size)
{
if (ptr == NULL)
ptr = malloc(size);
else
ptr = realloc(ptr, size);
if (ptr == NULL)
fatalmem();
return(ptr);
}
/*
* safe_free() - free a string pointer safely.
*
* Given the address of the pointer (rather then the pointer itself),
* this routine is a NOP if the pointer is NULL, and will free() and
* NULL-out the pointer if it is non-NULL.
*
* This function is typically only used on string pointers. Structural
* allocations should use zalloc() and zfree().
*/
void
safe_free(char **ptr)
{
if (*ptr) {
free(*ptr);
*ptr = NULL;
}
}
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message