/*
* 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 */