summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2017-05-29 15:54:30 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2017-05-29 15:54:30 +0200
commitdb01090e1f869965c07b12d9480fa6f3d2e7b1b0 (patch)
tree523e4b00bf591c56f671b5b610f6284b8ce64fbd
parent6f1126ae2c585afc34d0bb06f3763e3a82ee3d37 (diff)
Add vfail and vsuccess interfaces
This now factorizes code needed to asprintf the arguments in an allocated string. But the most interesting effect is the ability to handle va_list of arguments. It can be used for library of tools. Change-Id: I4ba74c9984786f07abe0c7e53d7ef79dca863735 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--include/afb/afb-daemon-common.h2
-rw-r--r--include/afb/afb-req-itf.h54
-rw-r--r--include/afb/afb-service-v2.h1
-rw-r--r--src/afb-api-dbus.c1
-rw-r--r--src/afb-api-so-v1.c1
-rw-r--r--src/afb-api-so-v2.c1
-rw-r--r--src/afb-ditf.c1
-rw-r--r--src/afb-xreq.c36
8 files changed, 70 insertions, 27 deletions
diff --git a/include/afb/afb-daemon-common.h b/include/afb/afb-daemon-common.h
index 7b241492..e8e1817e 100644
--- a/include/afb/afb-daemon-common.h
+++ b/include/afb/afb-daemon-common.h
@@ -17,6 +17,8 @@
#pragma once
+#include <stdarg.h>
+
/* declaration of features of libsystemd */
struct sd_event;
struct sd_bus;
diff --git a/include/afb/afb-req-itf.h b/include/afb/afb-req-itf.h
index 34d73dd2..65f2bfe6 100644
--- a/include/afb/afb-req-itf.h
+++ b/include/afb/afb-req-itf.h
@@ -17,13 +17,7 @@
#pragma once
-#if !defined(_GNU_SOURCE)
-# error "_GNU_SOURCE must be defined for using vasprintf"
-#endif
-
-#include <stdlib.h>
#include <stdarg.h>
-#include <stdio.h>
#include "afb-event-itf.h"
@@ -56,8 +50,8 @@ struct afb_req_itf {
void (*success)(void *closure, struct json_object *obj, const char *info);
void (*fail)(void *closure, const char *status, const char *info);
- /*legacy raw */void (*spare1)(void *closure);
- /*legacy send*/void (*spare2)(void *closure);
+ void (*vsuccess)(void *closure, struct json_object *obj, const char *fmt, va_list args);
+ void (*vfail)(void *closure, const char *status, const char *fmt, va_list args);
void *(*context_get)(void *closure);
void (*context_set)(void *closure, void *value, void (*free_value)(void*));
@@ -166,16 +160,26 @@ static inline void afb_req_success(struct afb_req req, struct json_object *obj,
* Thus, in the case where 'obj' should remain available after
* the function returns, the function 'json_object_get' shall be used.
*/
+static inline void afb_req_success_f(struct afb_req req, struct json_object *obj, const char *info, ...) __attribute__((format(printf, 3, 4)));
static inline void afb_req_success_f(struct afb_req req, struct json_object *obj, const char *info, ...)
{
- char *message;
va_list args;
va_start(args, info);
- if (info == NULL || vasprintf(&message, info, args) < 0)
- message = NULL;
+ req.itf->vsuccess(req.closure, obj, info, args);
va_end(args);
- afb_req_success(req, obj, message);
- free(message);
+}
+
+/*
+ * Same as 'afb_req_success_f' but the arguments to the format 'info'
+ * are given as a variable argument list instance.
+ *
+ * For convenience, the function calls 'json_object_put' for 'obj'.
+ * Thus, in the case where 'obj' should remain available after
+ * the function returns, the function 'json_object_get' shall be used.
+ */
+static inline void afb_req_success_v(struct afb_req req, struct json_object *obj, const char *info, va_list args)
+{
+ req.itf->vsuccess(req.closure, obj, info, args);
}
/*
@@ -186,10 +190,6 @@ static inline void afb_req_success_f(struct afb_req req, struct json_object *obj
* Note that calling afb_req_fail("success", info) is equivalent
* to call afb_req_success(NULL, info). Thus even if possible it
* is strongly recommanded to NEVER use "success" for status.
- *
- * For convenience, the function calls 'json_object_put' for 'obj'.
- * Thus, in the case where 'obj' should remain available after
- * the function returns, the function 'json_object_get' shall be used.
*/
static inline void afb_req_fail(struct afb_req req, const char *status, const char *info)
{
@@ -199,21 +199,23 @@ static inline void afb_req_fail(struct afb_req req, const char *status, const ch
/*
* Same as 'afb_req_fail' but the 'info' is a formatting
* string followed by arguments.
- *
- * For convenience, the function calls 'json_object_put' for 'obj'.
- * Thus, in the case where 'obj' should remain available after
- * the function returns, the function 'json_object_get' shall be used.
*/
+static inline void afb_req_fail_f(struct afb_req req, const char *status, const char *info, ...) __attribute__((format(printf, 3, 4)));
static inline void afb_req_fail_f(struct afb_req req, const char *status, const char *info, ...)
{
- char *message;
va_list args;
va_start(args, info);
- if (info == NULL || vasprintf(&message, info, args) < 0)
- message = NULL;
+ req.itf->vfail(req.closure, status, info, args);
va_end(args);
- afb_req_fail(req, status, message);
- free(message);
+}
+
+/*
+ * Same as 'afb_req_fail_f' but the arguments to the format 'info'
+ * are given as a variable argument list instance.
+ */
+static inline void afb_req_fail_v(struct afb_req req, const char *status, const char *info, va_list args)
+{
+ req.itf->vfail(req.closure, status, info, args);
}
/*
diff --git a/include/afb/afb-service-v2.h b/include/afb/afb-service-v2.h
index 2d138350..5c0d3bd8 100644
--- a/include/afb/afb-service-v2.h
+++ b/include/afb/afb-service-v2.h
@@ -56,7 +56,6 @@ static inline void afb_service_call_v2(
* Thus, in the case where 'args' should remain available after
* the function returns, the function 'json_object_get' shall be used.
*
- * @param service The service as received during initialisation
* @param api The api name of the method to call
* @param verb The verb name of the method to call
* @param args The arguments to pass to the method
diff --git a/src/afb-api-dbus.c b/src/afb-api-dbus.c
index 2f4c4ca9..4689ad1f 100644
--- a/src/afb-api-dbus.c
+++ b/src/afb-api-dbus.c
@@ -19,6 +19,7 @@
#define NO_PLUGIN_VERBOSE_MACRO
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c
index c1f27093..f4562ec5 100644
--- a/src/afb-api-so-v1.c
+++ b/src/afb-api-so-v1.c
@@ -18,6 +18,7 @@
#define _GNU_SOURCE
#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO
+#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <assert.h>
diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c
index 8dadada5..1c5fe520 100644
--- a/src/afb-api-so-v2.c
+++ b/src/afb-api-so-v2.c
@@ -18,6 +18,7 @@
#define _GNU_SOURCE
#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO
+#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <assert.h>
diff --git a/src/afb-ditf.c b/src/afb-ditf.c
index 474c58cf..9160a9d4 100644
--- a/src/afb-ditf.c
+++ b/src/afb-ditf.c
@@ -17,6 +17,7 @@
#define _GNU_SOURCE
+#include <stdio.h>
#include <string.h>
#include <errno.h>
diff --git a/src/afb-xreq.c b/src/afb-xreq.c
index 527692c6..0b828277 100644
--- a/src/afb-xreq.c
+++ b/src/afb-xreq.c
@@ -19,6 +19,7 @@
#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <errno.h>
@@ -39,6 +40,17 @@
/******************************************************************************/
+static void vinfo(void *first, void *second, const char *fmt, va_list args, void (*fun)(void*,void*,const char*))
+{
+ char *info;
+ if (fmt == NULL || vasprintf(&info, fmt, args) < 0)
+ info = NULL;
+ fun(first, second, info);
+ free(info);
+}
+
+/******************************************************************************/
+
static struct json_object *xreq_json_cb(void *closure)
{
struct afb_xreq *xreq = closure;
@@ -85,6 +97,16 @@ static void xreq_fail_cb(void *closure, const char *status, const char *info)
}
}
+static void xreq_vsuccess_cb(void *closure, struct json_object *obj, const char *fmt, va_list args)
+{
+ vinfo(closure, obj, fmt, args, (void*)xreq_success_cb);
+}
+
+static void xreq_vfail_cb(void *closure, const char *status, const char *fmt, va_list args)
+{
+ vinfo(closure, (void*)status, fmt, args, (void*)xreq_fail_cb);
+}
+
static void *xreq_context_get_cb(void *closure)
{
struct afb_xreq *xreq = closure;
@@ -265,6 +287,16 @@ static void xreq_hooked_fail_cb(void *closure, const char *status, const char *i
xreq_fail_cb(closure, status, info);
}
+static void xreq_hooked_vsuccess_cb(void *closure, struct json_object *obj, const char *fmt, va_list args)
+{
+ vinfo(closure, obj, fmt, args, (void*)xreq_hooked_success_cb);
+}
+
+static void xreq_hooked_vfail_cb(void *closure, const char *status, const char *fmt, va_list args)
+{
+ vinfo(closure, (void*)status, fmt, args, (void*)xreq_hooked_fail_cb);
+}
+
static void *xreq_hooked_context_get_cb(void *closure)
{
void *r = xreq_context_get_cb(closure);
@@ -372,6 +404,8 @@ const struct afb_req_itf xreq_itf = {
.get = xreq_get_cb,
.success = xreq_success_cb,
.fail = xreq_fail_cb,
+ .vsuccess = xreq_vsuccess_cb,
+ .vfail = xreq_vfail_cb,
.context_get = xreq_context_get_cb,
.context_set = xreq_context_set_cb,
.addref = xreq_addref_cb,
@@ -389,6 +423,8 @@ const struct afb_req_itf xreq_hooked_itf = {
.get = xreq_hooked_get_cb,
.success = xreq_hooked_success_cb,
.fail = xreq_hooked_fail_cb,
+ .vsuccess = xreq_hooked_vsuccess_cb,
+ .vfail = xreq_hooked_vfail_cb,
.context_get = xreq_hooked_context_get_cb,
.context_set = xreq_hooked_context_set_cb,
.addref = xreq_hooked_addref_cb,