Re: [Libclc-developers] string function clc_stralloc()
Status: Planning
Brought to you by:
augestad
|
From: Hallvard B F. <h.b...@us...> - 2003-03-19 11:10:35
|
[Bj=F8rn, you forgot cc: libclc-developers]
Bj=F8rn Augestad writes:
>Hallvard B Furuseth wrote:
>> Here is a function I've seen with several names: stralloc(), concat(=
),
>> pstrcat(). I prefer clc_str<someting>.
>> (...)
>=20
> We need an example here. The required NULL sentinel can easily be=20
> forgotten, which creates funny bugs. A simple example will do IMO.
I modified your example a bit:
EXAMPLE
char *s =3D clc_stralloc("foo", "bar", (char *)0);
if(s !=3D NULL) {
puts(s);
free(s);
}
I prefer (char *)0 over NULL. It's good to teach users to be careful
about the types given to variadic functions. In this case NULL works
too, since (char*)0 has the same representation, but then users may
think this applies to other pointer types as well.
> (...)
> #include <string.h> /* for strlen() */
> (...)
> <paranoid>
> =09len may wrap around if the sum of all strlen's > SIZE_MAX.
> </paranoid>
With that test it needs to set errno, since there are two different
error conditions (too long string and malloc failed). I've called them=
CLC_ETOOBIG and CLC_ENOMEM. Though I'm not sure I like the CLC_ETOOBIG=
name. Should we just use ERANGE instead of CLC_ETOOBIG?
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include "clc_errno.h"
#include "clc_string.h"
char *
clc_stralloc(const char *arg1, ...)
{
size_t len;
const char *arg;
char *ret, *end;
va_list ap;
len =3D 1;
va_start(ap, arg1);
for (arg =3D arg1; arg !=3D NULL; arg =3D va_arg(ap, const char *))=
{
=09size_t arglen =3D strlen(arg);
=09len +=3D arglen;
=09if (len < arglen) {
=09 /* string length too large for size_t */
=09 errno =3D CLC_ETOOBIG;
=09 return NULL;
=09}
}
va_end(ap);
ret =3D malloc(len);
if (ret =3D=3D NULL) {
=09errno =3D CLC_ENOMEM;
} else {
=09end =3D ret;
=09*end =3D '\0';
=09va_start(ap, arg1);
=09for (arg =3D arg1; arg !=3D NULL; arg =3D va_arg(ap, const char *))
=09 end =3D clc_stpcpy(end, arg);
=09va_end(ap);
}
return ret;
}
--=20
Hallvard
|