1 /* $Id: concat.c 4234 2000-12-21 03:43:02Z rra $
3 ** Concatenate strings with dynamic memory allocation.
5 ** Written by Russ Allbery <rra@stanford.edu>
6 ** This work is hereby placed in the public domain by its author.
10 ** string = concat(string1, string2, ..., (char *) 0);
11 ** path = concatpath(base, name);
13 ** Dynamically allocates (using xmalloc) sufficient memory to hold all of
14 ** the strings given and then concatenates them together into that
15 ** allocated memory, returning a pointer to it. Caller is responsible for
16 ** freeing. Assumes xmalloc is available. The last argument must be a
17 ** null pointer (to a char *, if you actually find a platform where it
20 ** concatpath is similar, except that it only takes two arguments. If the
21 ** second argument begins with / or ./, a copy of it is returned;
22 ** otherwise, the first argument, a slash, and the second argument are
23 ** concatenated together and returned. This is useful for building file
24 ** names where names that aren't fully qualified are qualified with some
25 ** particular directory.
36 /* Abbreviation for cleaner code. */
37 #define VA_NEXT(var, type) ((var) = (type) va_arg(args, type))
39 /* ANSI C requires at least one named parameter. */
41 concat(const char *first, ...)
48 /* Find the total memory required. */
49 va_start(args, first);
50 for (string = first; string != NULL; VA_NEXT(string, const char *))
51 length += strlen(string);
55 /* Create the string. Doing the copy ourselves avoids useless string
56 traversals of result, if using strcat, or string, if using strlen to
57 increment a pointer into result, at the cost of losing the native
58 optimization of strcat if any. */
59 result = xmalloc(length);
61 va_start(args, first);
62 for (string = first; string != NULL; VA_NEXT(string, const char *))
63 while (*string != '\0')
73 concatpath(const char *base, const char *name)
75 if (name[0] == '/' || (name[0] == '.' && name[1] == '/'))
78 return concat(base, "/", name, (char *) 0);