[libvirt] [PATCH] add sentinel attribute

This patch adds a (macro-wrapped) sentinel attribute to functions that take a NULL-terminated variable argument list. This is a nice debugging aid. * src/internal.h (ATTRIBUTE_SENTINEL): New. * src/util/buf.c (virBufferStrcat): Use it. * src/util/ebtables.c (ebtablesAddRemoveRule): Use it. * src/util/iptables.c (iptableAddRemoveRule: Use it. * src/util/qparams.h (new_qparam_set, append_qparams): Use it. --- src/internal.h | 11 +++++++++++ src/util/buf.h | 3 ++- src/util/ebtables.c | 2 +- src/util/iptables.c | 2 +- src/util/qparams.h | 6 ++++-- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/internal.h b/src/internal.h index bd1cfe6..09c19ea 100644 --- a/src/internal.h +++ b/src/internal.h @@ -93,6 +93,17 @@ #endif /** + * ATTRIBUTE_SENTINEL: + * + * Macro to check for NULL-terminated varargs lists + */ +#ifndef ATTRIBUTE_SENTINEL +#if __GNUC_PREREQ (4, 0) +#define ATTRIBUTE_SENTINEL __attribute__((__sentinel__)) +#endif +#endif + +/** * ATTRIBUTE_FMT_PRINTF * * Macro used to check printf like functions, if compiling diff --git a/src/util/buf.h b/src/util/buf.h index 7d31cb2..94ee8a3 100644 --- a/src/util/buf.h +++ b/src/util/buf.h @@ -41,7 +41,8 @@ void virBufferAdd(const virBufferPtr buf, const char *str, int len); void virBufferAddChar(const virBufferPtr buf, char c); void virBufferVSprintf(const virBufferPtr buf, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); -void virBufferStrcat(const virBufferPtr buf, ...); +void virBufferStrcat(const virBufferPtr buf, ...) + ATTRIBUTE_SENTINEL; void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str); void virBufferURIEncodeString (const virBufferPtr buf, const char *str); diff --git a/src/util/ebtables.c b/src/util/ebtables.c index 60427d7..20f3342 100644 --- a/src/util/ebtables.c +++ b/src/util/ebtables.c @@ -175,7 +175,7 @@ ebtRulesNew(const char *table, return NULL; } -static int +static int ATTRIBUTE_SENTINEL ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...) { va_list args; diff --git a/src/util/iptables.c b/src/util/iptables.c index 4562800..284f3c0 100644 --- a/src/util/iptables.c +++ b/src/util/iptables.c @@ -382,7 +382,7 @@ iptRulesNew(const char *table, return NULL; } -static int +static int ATTRIBUTE_SENTINEL iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...) { va_list args; diff --git a/src/util/qparams.h b/src/util/qparams.h index 1a92048..a2f5aa2 100644 --- a/src/util/qparams.h +++ b/src/util/qparams.h @@ -38,10 +38,12 @@ struct qparam_set { }; /* New parameter set. */ -extern struct qparam_set *new_qparam_set (int init_alloc, ...); +extern struct qparam_set *new_qparam_set (int init_alloc, ...) + ATTRIBUTE_SENTINEL; /* Appending parameters. */ -extern int append_qparams (struct qparam_set *ps, ...); +extern int append_qparams (struct qparam_set *ps, ...) + ATTRIBUTE_SENTINEL; extern int append_qparam (struct qparam_set *ps, const char *name, const char *value); -- 1.6.2.5

On Wed, Nov 04, 2009 at 06:49:47PM +0100, Paolo Bonzini wrote:
This patch adds a (macro-wrapped) sentinel attribute to functions that take a NULL-terminated variable argument list. This is a nice debugging aid.
* src/internal.h (ATTRIBUTE_SENTINEL): New. * src/util/buf.c (virBufferStrcat): Use it. * src/util/ebtables.c (ebtablesAddRemoveRule): Use it. * src/util/iptables.c (iptableAddRemoveRule: Use it. * src/util/qparams.h (new_qparam_set, append_qparams): Use it. --- src/internal.h | 11 +++++++++++ src/util/buf.h | 3 ++- src/util/ebtables.c | 2 +- src/util/iptables.c | 2 +- src/util/qparams.h | 6 ++++-- 5 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/internal.h b/src/internal.h index bd1cfe6..09c19ea 100644 --- a/src/internal.h +++ b/src/internal.h @@ -93,6 +93,17 @@ #endif
/** + * ATTRIBUTE_SENTINEL: + * + * Macro to check for NULL-terminated varargs lists + */ +#ifndef ATTRIBUTE_SENTINEL +#if __GNUC_PREREQ (4, 0) +#define ATTRIBUTE_SENTINEL __attribute__((__sentinel__)) +#endif +#endif + +/** * ATTRIBUTE_FMT_PRINTF * * Macro used to check printf like functions, if compiling diff --git a/src/util/buf.h b/src/util/buf.h index 7d31cb2..94ee8a3 100644 --- a/src/util/buf.h +++ b/src/util/buf.h @@ -41,7 +41,8 @@ void virBufferAdd(const virBufferPtr buf, const char *str, int len); void virBufferAddChar(const virBufferPtr buf, char c); void virBufferVSprintf(const virBufferPtr buf, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); -void virBufferStrcat(const virBufferPtr buf, ...); +void virBufferStrcat(const virBufferPtr buf, ...) + ATTRIBUTE_SENTINEL; void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str); void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
diff --git a/src/util/ebtables.c b/src/util/ebtables.c index 60427d7..20f3342 100644 --- a/src/util/ebtables.c +++ b/src/util/ebtables.c @@ -175,7 +175,7 @@ ebtRulesNew(const char *table, return NULL; }
-static int +static int ATTRIBUTE_SENTINEL ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...) { va_list args; diff --git a/src/util/iptables.c b/src/util/iptables.c index 4562800..284f3c0 100644 --- a/src/util/iptables.c +++ b/src/util/iptables.c @@ -382,7 +382,7 @@ iptRulesNew(const char *table, return NULL; }
-static int +static int ATTRIBUTE_SENTINEL iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...) { va_list args; diff --git a/src/util/qparams.h b/src/util/qparams.h index 1a92048..a2f5aa2 100644 --- a/src/util/qparams.h +++ b/src/util/qparams.h @@ -38,10 +38,12 @@ struct qparam_set { };
/* New parameter set. */ -extern struct qparam_set *new_qparam_set (int init_alloc, ...); +extern struct qparam_set *new_qparam_set (int init_alloc, ...) + ATTRIBUTE_SENTINEL;
/* Appending parameters. */ -extern int append_qparams (struct qparam_set *ps, ...); +extern int append_qparams (struct qparam_set *ps, ...) + ATTRIBUTE_SENTINEL; extern int append_qparam (struct qparam_set *ps, const char *name, const char *value);
--
ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Wed, Nov 04, 2009 at 06:49:47PM +0100, Paolo Bonzini wrote:
This patch adds a (macro-wrapped) sentinel attribute to functions that take a NULL-terminated variable argument list. This is a nice debugging aid.
* src/internal.h (ATTRIBUTE_SENTINEL): New. * src/util/buf.c (virBufferStrcat): Use it. * src/util/ebtables.c (ebtablesAddRemoveRule): Use it. * src/util/iptables.c (iptableAddRemoveRule: Use it. * src/util/qparams.h (new_qparam_set, append_qparams): Use it. --- src/internal.h | 11 +++++++++++ src/util/buf.h | 3 ++- src/util/ebtables.c | 2 +- src/util/iptables.c | 2 +- src/util/qparams.h | 6 ++++-- 5 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/internal.h b/src/internal.h index bd1cfe6..09c19ea 100644 --- a/src/internal.h +++ b/src/internal.h @@ -93,6 +93,17 @@ #endif
/** + * ATTRIBUTE_SENTINEL: + * + * Macro to check for NULL-terminated varargs lists + */ +#ifndef ATTRIBUTE_SENTINEL +#if __GNUC_PREREQ (4, 0) +#define ATTRIBUTE_SENTINEL __attribute__((__sentinel__)) +#endif +#endif + +/** * ATTRIBUTE_FMT_PRINTF * * Macro used to check printf like functions, if compiling diff --git a/src/util/buf.h b/src/util/buf.h index 7d31cb2..94ee8a3 100644 --- a/src/util/buf.h +++ b/src/util/buf.h @@ -41,7 +41,8 @@ void virBufferAdd(const virBufferPtr buf, const char *str, int len); void virBufferAddChar(const virBufferPtr buf, char c); void virBufferVSprintf(const virBufferPtr buf, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); -void virBufferStrcat(const virBufferPtr buf, ...); +void virBufferStrcat(const virBufferPtr buf, ...) + ATTRIBUTE_SENTINEL; void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str); void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
diff --git a/src/util/ebtables.c b/src/util/ebtables.c index 60427d7..20f3342 100644 --- a/src/util/ebtables.c +++ b/src/util/ebtables.c @@ -175,7 +175,7 @@ ebtRulesNew(const char *table, return NULL; }
-static int +static int ATTRIBUTE_SENTINEL ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...) {
I'm just surprized by having the __attribute__ being inserted before the function name, I would expect to have it between the end of the arguments ) and the curly brace { for this to work correctly.
va_list args; diff --git a/src/util/iptables.c b/src/util/iptables.c index 4562800..284f3c0 100644 --- a/src/util/iptables.c +++ b/src/util/iptables.c @@ -382,7 +382,7 @@ iptRulesNew(const char *table, return NULL; }
-static int +static int ATTRIBUTE_SENTINEL iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...) { va_list args; diff --git a/src/util/qparams.h b/src/util/qparams.h index 1a92048..a2f5aa2 100644 --- a/src/util/qparams.h +++ b/src/util/qparams.h @@ -38,10 +38,12 @@ struct qparam_set { };
/* New parameter set. */ -extern struct qparam_set *new_qparam_set (int init_alloc, ...); +extern struct qparam_set *new_qparam_set (int init_alloc, ...) + ATTRIBUTE_SENTINEL;
/* Appending parameters. */ -extern int append_qparams (struct qparam_set *ps, ...); +extern int append_qparams (struct qparam_set *ps, ...) + ATTRIBUTE_SENTINEL; extern int append_qparam (struct qparam_set *ps, const char *name, const char *value);
But that sounds like a good idea to add this check ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On 11/05/2009 06:04 PM, Daniel Veillard wrote:
+static int ATTRIBUTE_SENTINEL ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...) { I'm just surprized by having the __attribute__ being inserted before the function name, I would expect to have it between the end of the arguments ) and the curly brace { for this to work correctly.
For prototypes you can place it in either position, but in this case we have no prototype so you have to place it there. I wasn't sure either, so I did try triggering it and it works in both cases. Paolo

On Thu, Nov 05, 2009 at 06:07:54PM +0100, Paolo Bonzini wrote:
On 11/05/2009 06:04 PM, Daniel Veillard wrote:
+static int ATTRIBUTE_SENTINEL ebtablesAddRemoveRule(ebtRules *rules, int action, const char *arg, ...) { I'm just surprized by having the __attribute__ being inserted before the function name, I would expect to have it between the end of the arguments ) and the curly brace { for this to work correctly.
For prototypes you can place it in either position, but in this case we have no prototype so you have to place it there. I wasn't sure either, so I did try triggering it and it works in both cases.
Okay, I checked too, and it just doesn't compile if added the way I expected, trange it's fine for forward declaration, but breaks in implementations. No big deal :-) I just added ATTRIBUTE_SENTINEL to docs/apibuild.py list of ignored words because I'm sure it would break next time we try to generate the API. Commited and pushed :-) thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/
participants (3)
-
Daniel P. Berrange
-
Daniel Veillard
-
Paolo Bonzini