virstring: Introduce VIR_STRDUP and VIR_STRNDUP

The code adaptation is not done right now, but in subsequent patches.
Hence I am not implementing syntax-check rule as it would break
compilation. Developers are strongly advised to use these new macros.
They are similar to VIR_ALLOC() logic: VIR_STRDUP(dst, src) returns zero
on success, -1 otherwise. In case you don't want to report OOM error,
use the _QUIET variant of a macro.
This commit is contained in:
Michal Privoznik 2013-04-03 14:51:20 +02:00
parent b1434b36b1
commit c3abb5c459
5 changed files with 163 additions and 0 deletions

11
HACKING
View File

@ -719,6 +719,17 @@ sizeof(dest) returns something meaningful). Note that this is a macro, so
arguments could be evaluated more than once. This is equivalent to arguments could be evaluated more than once. This is equivalent to
virStrncpy(dest, src, strlen(src), sizeof(dest)). virStrncpy(dest, src, strlen(src), sizeof(dest)).
VIR_STRDUP(char *dst, const char *src);
VIR_STRNDUP(char *dst, const char *src, size_t n);
You should avoid using strdup or strndup directly as they do not report
out-of-memory error. Use VIR_STRDUP or VIR_STRNDUP macros instead. Note, that
these two behave similar to VIR_ALLOC: on success zero is returned, otherwise
the result is -1 and dst is guaranteed to be NULL. In very specific cases,
when you don't want to report the out-of-memory error, you can use
VIR_STRDUP_QUIET or VIR_STRNDUP_QUIET, but such usage is very rare and usually
considered a flaw.
Variable length string buffer Variable length string buffer
============================= =============================

View File

@ -855,6 +855,20 @@
virStrncpy(dest, src, strlen(src), sizeof(dest)). virStrncpy(dest, src, strlen(src), sizeof(dest)).
</p> </p>
<pre>
VIR_STRDUP(char *dst, const char *src);
VIR_STRNDUP(char *dst, const char *src, size_t n);
</pre>
<p>
You should avoid using strdup or strndup directly as they do not report
out-of-memory error. Use VIR_STRDUP or VIR_STRNDUP macros instead. Note,
that these two behave similar to VIR_ALLOC: on success zero is returned,
otherwise the result is -1 and dst is guaranteed to be NULL. In very
specific cases, when you don't want to report the out-of-memory error, you
can use VIR_STRDUP_QUIET or VIR_STRNDUP_QUIET, but such usage is very rare
and usually considered a flaw.
</p>
<h2><a name="strbuf">Variable length string buffer</a></h2> <h2><a name="strbuf">Variable length string buffer</a></h2>
<p> <p>

View File

@ -1751,11 +1751,13 @@ virSkipSpaces;
virSkipSpacesAndBackslash; virSkipSpacesAndBackslash;
virSkipSpacesBackwards; virSkipSpacesBackwards;
virStrcpy; virStrcpy;
virStrdup;
virStringArrayHasString; virStringArrayHasString;
virStringFreeList; virStringFreeList;
virStringJoin; virStringJoin;
virStringSplit; virStringSplit;
virStrncpy; virStrncpy;
virStrndup;
virStrToDouble; virStrToDouble;
virStrToLong_i; virStrToLong_i;
virStrToLong_l; virStrToLong_l;

View File

@ -515,3 +515,77 @@ virArgvToString(const char *const *argv)
return ret; return ret;
} }
/**
* virStrdup:
* @dest: where to store duplicated string
* @src: the source string to duplicate
* @report: whether to report OOM error, if there is one
* @domcode: error domain code
* @filename: caller's filename
* @funcname: caller's funcname
* @linenr: caller's line number
*
* Wrapper over strdup, which reports OOM error if told so,
* in which case callers wants to pass @domcode, @filename,
* @funcname and @linenr which should represent location in
* caller's body where virStrdup is called from. Consider
* using VIR_STRDUP which sets these automatically.
*
* Returns: 0 on success, -1 otherwise.
*/
int
virStrdup(char **dest,
const char *src,
bool report,
int domcode,
const char *filename,
const char *funcname,
size_t linenr)
{
if (!(*dest = strdup(src))) {
if (report)
virReportOOMErrorFull(domcode, filename, funcname, linenr);
return -1;
}
return 0;
}
/**
* virStrndup:
* @dest: where to store duplicated string
* @src: the source string to duplicate
* @n: how many bytes to copy
* @report: whether to report OOM error, if there is one
* @domcode: error domain code
* @filename: caller's filename
* @funcname: caller's funcname
* @linenr: caller's line number
*
* Wrapper over strndup, which reports OOM error if told so,
* in which case callers wants to pass @domcode, @filename,
* @funcname and @linenr which should represent location in
* caller's body where virStrndup is called from. Consider
* using VIR_STRNDUP which sets these automatically.
*
* Returns: 0 on success, -1 otherwise.
*/
int
virStrndup(char **dest,
const char *src,
size_t n,
bool report,
int domcode,
const char *filename,
const char *funcname,
size_t linenr)
{
if (!(*dest = strndup(src, n))) {
if (report)
virReportOOMErrorFull(domcode, filename, funcname, linenr);
return -1;
}
return 0;
}

View File

@ -87,4 +87,66 @@ char *virStrncpy(char *dest, const char *src, size_t n, size_t destbytes)
char *virStrcpy(char *dest, const char *src, size_t destbytes) char *virStrcpy(char *dest, const char *src, size_t destbytes)
ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_RETURN_CHECK;
# define virStrcpyStatic(dest, src) virStrcpy((dest), (src), sizeof(dest)) # define virStrcpyStatic(dest, src) virStrcpy((dest), (src), sizeof(dest))
/* Don't call these directly - use the macros below */
int virStrdup(char **dest, const char *src, bool report, int domcode,
const char *filename, const char *funcname, size_t linenr)
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
int virStrndup(char **dest, const char *src, size_t n, bool report, int domcode,
const char *filename, const char *funcname, size_t linenr)
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
/**
* VIR_STRDUP:
* @dst: variable to hold result (char*, not char**)
* @src: string to duplicate
*
* Duplicate @src string and store it into @dst.
*
* Returns -1 on failure (with OOM error reported), 0 on success
*/
# define VIR_STRDUP(dst, src) virStrdup(&(dst), src, true, VIR_FROM_THIS, \
__FILE__, __FUNCTION__, __LINE__)
/**
* VIR_STRDUP_QUIET:
* @dst: variable to hold result (char*, not char**)
* @src: string to duplicate
*
* Duplicate @src string and store it into @dst.
*
* Returns -1 on failure, 0 on success
*/
# define VIR_STRDUP_QUIET(dst, src) virStrdup(&(dst), src, false, 0, NULL, NULL, 0)
/**
* VIR_STRNDUP:
* @dst: variable to hold result (char*, not char**)
* @src: string to duplicate
* @n: the maximum number of bytes to copy
*
* Duplicate @src string and store it into @dst. If @src is longer than @n,
* only @n bytes are copied and terminating null byte '\0' is added.
*
* Returns -1 on failure (with OOM error reported), 0 on success
*/
# define VIR_STRNDUP(dst, src, n) virStrndup(&(dst), src, n, true, \
VIR_FROM_THIS, __FILE__, \
__FUNCTION__, __LINE__)
/**
* VIR_STRNDUP_QUIET:
* @dst: variable to hold result (char*, not char**)
* @src: string to duplicate
* @n: the maximum number of bytes to copy
*
* Duplicate @src string and store it into @dst. If @src is longer than @n,
* only @n bytes are copied and terminating null byte '\0' is added.
*
* Returns -1 on failure, 0 on success
*/
# define VIR_STRNDUP_QUIET(dst, src, n) virStrndup(&(dst), src, n, false, \
0, NULL, NULL, 0)
#endif /* __VIR_STRING_H__ */ #endif /* __VIR_STRING_H__ */