Listing 2 Weitzel's string handling functions

/*
 * Module: pstring.c (string handling support)
 *   by Martin.Weitzel@rent-a-guru. DE
 */
#include "pstring.h"
#include <stdarg.h>
#include <stlib.h>
#include <string.h>
/*
 * The macros ALLOC and FREE hide away some casts
 * (necessary to suppress compiler-warnings) and
 * care for pre-ANSI/ISO-C free() which is not
 * guaranteed to be safe for (void *)0-pointers.
 */
#define ALLOC(n, t) ((t *)malloc((n)*(sizeof(t))))
#if __STDC__ == 1
#define FREE(p) free((void *)p)
#else
#define FREE(p) if (p) free((void *)p)
#endif

/*
 * Concatenate variable number of strings in space
 * allocated from the heap. If no more space is
 * available, the program is aborted.
 */
char *pstr_x(const char *str, ...) {
    const char *cp; /* tmpry to step over args */
    char *result; /* tmpry for return value */
    va_list ap;    /* arglist iterator */
    size_t len = 1; /* total length of strs + 1 */
    /*
     * loop over args, sum length of all strs
     */
    va_start(ap, str);
    for (cp = str; cp; cp = va_arg(ap, const char *))
        len += strlen(cp);
    va_end(ap);
    /* 
     * allocate space for all strs
     */
    if ((result = ALLOC(len, char)) == (char *)0)
        abort();
    result[0] = '\0';
    /*
     * loop over args, concatenate all strs
     */
    va_start(ap, str);
    for (cp = str; cp; cp = va_arg(ap, const char *))
        (void) strcat(result, cp);
    va_end(ap);
    return result;
}

/*
 * Helper function for building temporary strings
 * (see "TMPSTR"-macros in "pstring.h" for details).
 * It effectively "schedules a free" delayed by one
 * call to this function, so the caller does not have
 * to care for saving the result of "strmake" in a
 * variable and hand this to free later on.
 * Note: With "(void) tmpstr((char *)0)" you may
 * force to de-allocate the last temporary string
 * build with one of the "TMPSTR"-macros.
 */
char *tmpstr(char *str) {
    static char *laststr;
    FREE(laststr);
    return laststr = str;

}

/*
 * Helper function for copying to pointers initialized
 * by calls to the "pstr_"-function and macros.
 * Note: "pstrcpy" takes the ADDRESS of a char pointer
 * as its first argument and automatic char pointer
 * variables MUST be initialized with (char *)0 prior
 * handing their address to this function the first
 * time.
 */
void pstrcpy(char **destp, const char *src) {
    FREE(*destp);
    *destp = pstr_1(src);

}

/* End of File */