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

Reply via email to