On 09/05/2013 01:49 AM, Michal Privoznik wrote:
> In glibc, regcomp assigns into preg, but is careful to undo any
> allocation on failure; it is also careful to make regfree() a no-op on
> an already-freed buffer (whether by calling regfree() twice in a row, or
> using it on preg after a failed regcomp). Gnulib copies this behavior.
> But it is not universally standard:
Question then is: if regcomp(®, ...) fails, reg == NULL, right?
No. You, the caller, supplied reg (typically stack allocated). As in:
regex_t reg;
int ret;
if ((ret = regcomp(®, str, flags))) {
regerror(ret, ®, buf, len);
} else {
regexec(...)
...
regfree(®);
}
The only thing that regfree() does is free any pointers _within_ the
regex_t struct. Remember, regex_t is a semi-opaque struct - POSIX only
documents that it contains a re_nsub member (and portable code therefore
cannot use any of its other members directly), but you ARE promised that
it is not an incomplete type, and that it is larger than a simple
pointer. It is _because_ regex_t is a struct with non-pointer members,
and where _you_ allocate the storage for the struct, that the struct can
contain useful information even after a failed regcomp() so that
regerror(®) can give a nicer message than regerror(NULL). But
ultimately, as long as regcomp() leaves no allocated data in the
remaining unnamed members, then there is nothing for regfree() to clean
up after failure.
You know, maybe I should ask the Austin Group (the people in charge of
POSIX) to clarify whether regfree() can/must be used after regcomp
failure, since the current wording isn't very clear.
But
passing the @reg to regerror: regerror(errcode, ®, ...) doesn't make
much sense then. It can make, if regcomp would free all mem allocated,
but set @reg to different values (each of them representing different
cause of error). If that is the case, <irony>this is what I call the
design!</irony>
Michal
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org