summaryrefslogtreecommitdiffstats
path: root/Makefile
blob: 02cb6ec97e7e227d92c817b43955f2386c7769ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# Makefile used to build xds-cli commands

# Application Name
TARGET=xds-cli


# Retrieve git tag/commit to set version & sub-version strings
GIT_DESC := $(shell git describe --always --tags)
VERSION := $(firstword $(subst -, ,$(GIT_DESC)))
ifeq (-,$(findstring -,$(GIT_DESC)))
SUB_VERSION := $(subst $(VERSION)-,,$(GIT_DESC))
endif
ifeq ($(VERSION), )
	VERSION := unknown-dev
endif
ifeq ($(SUB_VERSION), )
	SUB_VERSION := $(shell date +'%Y-%m-%d_%H%M%S')
endif

# Configurable variables for installation (default /opt/AGL/...)
ifeq ($(origin DESTDIR), undefined)
	DESTDIR := /opt/AGL/xds/cli
endif

HOST_GOOS=$(shell go env GOOS)
HOST_GOARCH=$(shell go env GOARCH)
ARCH=$(HOST_GOOS)-$(HOST_GOARCH)
REPOPATH=github.com/iotbzh/$(TARGET)

EXT=
ifeq ($(HOST_GOOS), windows)
	EXT=.exe
endif

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
ROOT_SRCDIR := $(patsubst %/,%,$(dir $(mkfile_path)))
ROOT_GOPRJ := $(abspath $(ROOT_SRCDIR)/../../../..)
LOCAL_BINDIR := $(ROOT_SRCDIR)/bin
LOCAL_TOOLSDIR := $(ROOT_SRCDIR)/tools/${HOST_GOOS}
PACKAGE_DIR := $(ROOT_SRCDIR)/package

export GOPATH := $(shell go env GOPATH):$(ROOT_GOPRJ)
export PATH := $(PATH):$(LOCAL_TOOLSDIR)

# Check Go version
GOVERSION := $(shell go version |grep -o '[0-9\.]*'|head -n 1)
GOVERMAJ := $(shell echo $(GOVERSION) |cut -f1 -d.)
GOVERMIN := $(shell echo $(GOVERSION) |cut -f2 -d.)
CHECKGOVER := $(shell [ $(GOVERMAJ) -gt 1 -o \( $(GOVERMAJ) -eq 1 -a $(GOVERMIN) -ge 8 \) ] && echo true)
CHECKERRMSG := "ERROR: Go version 1.8.1 or higher is requested (current detected version: $(GOVERSION))."


VERBOSE_1 := -v
VERBOSE_2 := -v -x

# Release or Debug mode
ifeq ($(filter 1,$(RELEASE) $(REL)),)
	GO_LDFLAGS=
	# disable compiler optimizations and inlining
	GO_GCFLAGS=-N -l
	BUILD_MODE="Debug mode"
else
	# optimized code without debug info
	GO_LDFLAGS=-s -w
	GO_GCFLAGS=
	BUILD_MODE="Release mode"
endif


ifeq ($(SUB_VERSION), )
	PACKAGE_ZIPFILE := $(TARGET)_$(ARCH)-$(VERSION).zip
else
	PACKAGE_ZIPFILE := $(TARGET)_$(ARCH)-$(VERSION)_$(SUB_VERSION).zip
endif

.PHONY: all
all: vendor build

.PHONY: build
build: checkgover
	@echo "### Build $(TARGET) (version $(VERSION), subversion $(SUB_VERSION) - $(BUILD_MODE))";
	@cd $(ROOT_SRCDIR); $(BUILD_ENV_FLAGS) go build $(VERBOSE_$(V)) -i -o $(LOCAL_BINDIR)/$(TARGET)$(EXT) -ldflags "$(GO_LDFLAGS) -X main.AppVersion=$(VERSION) -X main.AppSubVersion=$(SUB_VERSION)" -gcflags "$(GO_GCFLAGS)" .

test: tools/glide
	go test --race $(shell $(LOCAL_TOOLSDIR)/glide novendor)

vet: tools/glide
	go vet $(shell $(LOCAL_TOOLSDIR)/glide novendor)

fmt: tools/glide
	go fmt $(shell $(LOCAL_TOOLSDIR)/glide novendor)

.PHONY: clean
clean:
	rm -rf $(LOCAL_BINDIR)/* debug $(ROOT_GOPRJ)/pkg/*/$(REPOPATH) $(PACKAGE_DIR)

.PHONY: distclean
distclean: clean
	rm -rf $(LOCAL_BINDIR) $(ROOT_SRCDIR)/tools glide.lock vendor


.PHONY: scripts
scripts:
	@mkdir -p $(LOCAL_BINDIR) && cp -rf scripts/*.sh scripts/xds-utils $(LOCAL_BINDIR)

.PHONY: release
release:
	RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile clean build

package: clean vendor build
	@mkdir -p $(PACKAGE_DIR)/$(TARGET)
	@cp -a $(LOCAL_BINDIR)/*cli$(EXT) $(PACKAGE_DIR)/$(TARGET)
	@cp -r $(ROOT_SRCDIR)/conf.d $(ROOT_SRCDIR)/scripts $(PACKAGE_DIR)/$(TARGET)
	cd $(PACKAGE_DIR) && zip -r $(ROOT_SRCDIR)/$(PACKAGE_ZIPFILE) ./$(TARGET)

.PHONY: package-all
package-all:
	@echo "# Build linux amd64..."
	GOOS=linux GOARCH=amd64 RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile package
	@echo "# Build windows amd64..."
	GOOS=windows GOARCH=amd64 RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile package
	@echo "# Build darwin amd64..."
	GOOS=darwin GOARCH=amd64 RELEASE=1 make -f $(ROOT_SRCDIR)/Makefile package
	make -f $(ROOT_SRCDIR)/Makefile clean

.PHONY: install
install:
	@test -e $(LOCAL_BINDIR)/$(TARGET)$(EXT) || { echo "Please execute first: make all\n"; exit 1; }
	export DESTDIR=$(DESTDIR) && $(ROOT_SRCDIR)/scripts/install.sh

.PHONY: uninstall
uninstall:
	export DESTDIR=$(DESTDIR) && $(ROOT_SRCDIR)/scripts/install.sh uninstall

vendor: tools/glide glide.yaml
	$(LOCAL_TOOLSDIR)/glide install --strip-vendor

vendor/debug: vendor
	(cd vendor/github.com/iotbzh && \
		rm -rf xds-common && ln -s ../../../../xds-common && \
		rm -rf xds-agent && ln -s ../../../../xds-agent )

.PHONY: tools/glide
tools/glide:
	@test -f $(LOCAL_TOOLSDIR)/glide || { \
		echo "Downloading glide"; \
		mkdir -p $(LOCAL_TOOLSDIR); \
		curl --silent -L https://glide.sh/get | GOBIN=$(LOCAL_TOOLSDIR)  sh; \
	}

.PHONY:
checkgover:
	@test "$(CHECKGOVER)" = "true" || { echo $(CHECKERRMSG); exit 1; }


.PHONY: help
help:
	@echo "Main supported rules:"
	@echo "  all               (default)"
	@echo "  build"
	@echo "  release"
	@echo "  clean"
	@echo "  package"
	@echo "  install / uninstall"
	@echo "  distclean"
	@echo ""
	@echo "Influential make variables:"
	@echo "  V                 - Build verbosity {0,1,2}."
	@echo "  BUILD_ENV_FLAGS   - Environment added to 'go build'."
sure version */ #ifndef AFB_BINDING_VERSION # define AFB_BINDING_VERSION 3 #endif /* check the version */ #if AFB_BINDING_VERSION < 3 # error "AFB_BINDING_VERSION must be at least 3" #endif /* get C definitions of bindings */ extern "C" { #include <afb/afb-binding.h> } namespace afb { /*************************************************************************/ /* pre-declaration of classes */ /*************************************************************************/ class arg; class event; class req; /*************************************************************************/ /* declaration of functions */ /*************************************************************************/ int broadcast_event(const char *name, json_object *object = nullptr); event make_event(const char *name); void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args); void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...); int rootdir_get_fd(); int rootdir_open_locale_fd(const char *filename, int flags, const char *locale = nullptr); int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout); int require_api(const char *apiname, bool initialized = true); int add_alias(const char *apiname, const char *aliasname); int verbosity(); bool wants_errors(); bool wants_warnings(); bool wants_notices(); bool wants_infos(); bool wants_debugs(); void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result, afb_api_t api), void *closure); template <class T> void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result, afb_api_t api), T *closure); bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result); /*************************************************************************/ /* effective declaration of classes */ /*************************************************************************/ /* events */ class event { afb_event_t event_; public: event() { invalidate(); } event(afb_event_t e); event(const event &other); event &operator=(const event &other); operator afb_event_t() const; afb_event_t operator->() const; operator bool() const; bool is_valid() const; void invalidate(); int broadcast(json_object *object) const; int push(json_object *object) const; void unref(); void addref(); const char *name() const; }; /* args */ class arg { struct afb_arg arg_; public: arg() = delete; arg(const struct afb_arg &a); arg(const arg &other); arg &operator=(const arg &other); operator const struct afb_arg&() const; bool has_name() const; bool has_value() const; bool has_path() const; const char *name() const; const char *value() const; const char *path() const; }; /* req(uest) */ class req { afb_req_t req_; public: req() = delete; req(afb_req_t r); req(const req &other); req &operator=(const req &other); operator afb_req_t() const; afb_req_t operator->() const; operator bool() const; bool is_valid() const; arg get(const char *name) const; const char *value(const char *name) const; const char *path(const char *name) const; json_object *json() const; void reply(json_object *obj = nullptr, const char *error = nullptr, const char *info = nullptr) const; void replyf(json_object *obj, const char *error, const char *info, ...) const; void replyv(json_object *obj, const char *error, const char *info, va_list args) const; void success(json_object *obj = nullptr, const char *info = nullptr) const; void successf(json_object *obj, const char *info, ...) const; void successv(json_object *obj, const char *info, va_list args) const; void fail(const char *error = "failed", const char *info = nullptr) const; void failf(const char *error, const char *info, ...) const; void failv(const char *error, const char *info, va_list args) const; template < class T > T *context() const; void addref() const; void unref() const; void session_close() const; bool session_set_LOA(unsigned level) const; bool subscribe(const event &event) const; bool unsubscribe(const event &event) const; void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const; template <class T> void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const; bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const; void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *object, const char *error, const char *info, afb_req_t req), void *closure) const; template <class T> void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *object, const char *error, const char *info, afb_req_t req), T *closure) const; bool subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const; void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const; void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const; bool has_permission(const char *permission) const; char *get_application_id() const; int get_uid() const; json_object *get_client_info() const; }; /*************************************************************************/ /* effective declaration of classes */ /*************************************************************************/ ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// /*************************************************************************/ /* effective declaration of classes */ /*************************************************************************/ /* events */ inline event::event(afb_event_t e) : event_(e) { } inline event::event(const event &other) : event_(other.event_) { } inline event &event::operator=(const event &other) { event_ = other.event_; return *this; } inline event::operator afb_event_t() const { return event_; } inline afb_event_t event::operator->() const { return event_; } inline event::operator bool() const { return is_valid(); } inline bool event::is_valid() const { return afb_event_is_valid(event_); } inline void event::invalidate() { event_ = nullptr; } inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); } inline int event::push(json_object *object) const { return afb_event_push(event_, object); } inline void event::unref() { afb_event_unref(event_); invalidate(); } inline void event::addref() { afb_event_addref(event_); } inline const char *event::name() const { return afb_event_name(event_); } /* args */ inline arg::arg(const struct afb_arg &a) : arg_(a) {} inline arg::arg(const arg &other) : arg_(other.arg_) {} inline arg &arg::operator=(const arg &other) { arg_ = other.arg_; return *this; } inline arg::operator const struct afb_arg&() const { return arg_; } inline bool arg::has_name() const { return !!arg_.name; } inline bool arg::has_value() const { return !!arg_.value; } inline bool arg::has_path() const { return !!arg_.path; } inline const char *arg::name() const { return arg_.name; } inline const char *arg::value() const { return arg_.value; } inline const char *arg::path() const { return arg_.path; } /* req(uests)s */ inline req::req(afb_req_t r) : req_(r) {} inline req::req(const req &other) : req_(other.req_) {} inline req &req::operator=(const req &other) { req_ = other.req_; return *this; } inline req::operator afb_req_t() const { return req_; } inline afb_req_t req::operator->() const { return req_; } inline req::operator bool() const { return is_valid(); } inline bool req::is_valid() const { return afb_req_is_valid(req_); } inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); } inline const char *req::value(const char *name) const { return afb_req_value(req_, name); } inline const char *req::path(const char *name) const { return afb_req_path(req_, name); } inline json_object *req::json() const { return afb_req_json(req_); } inline void req::reply(json_object *obj, const char *error, const char *info) const { afb_req_reply(req_, obj, error, info); } inline void req::replyv(json_object *obj, const char *error, const char *info, va_list args) const { afb_req_reply_v(req_, obj, error, info, args); } inline void req::replyf(json_object *obj, const char *error, const char *info, ...) const { va_list args; va_start(args, info); replyv(obj, error, info, args); va_end(args); } inline void req::success(json_object *obj, const char *info) const { reply(obj, nullptr, info); } inline void req::successv(json_object *obj, const char *info, va_list args) const { replyv(obj, nullptr, info, args); } inline void req::successf(json_object *obj, const char *info, ...) const { va_list args; va_start(args, info); successv(obj, info, args); va_end(args); } inline void req::fail(const char *error, const char *info) const { reply(nullptr, error, info); } inline void req::failv(const char *error, const char *info, va_list args) const { replyv(nullptr, error, info, args); } inline void req::failf(const char *error, const char *info, ...) const { va_list args; va_start(args, info); failv(error, info, args); va_end(args); } template < class T > inline T *req::context() const { T* (*creater)(void*) = [](){return new T();}; void (*freer)(T*) = [](T*t){delete t;}; return reinterpret_cast<T*>(afb_req_context(req_, 0, reinterpret_cast<void *(*)(void*)>(creater), reinterpret_cast<void (*)(void*)>(freer), nullptr)); } inline void req::addref() const { afb_req_addref(req_); } inline void req::unref() const { afb_req_unref(req_); } inline void req::session_close() const { afb_req_session_close(req_); } inline bool req::session_set_LOA(unsigned level) const { return !afb_req_session_set_LOA(req_, level); } inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); } inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); } inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *result, const char *error, const char *info, afb_req_t req), void *closure) const { afb_req_subcall(req_, api, verb, args, flags, callback, closure); } template <class T> inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *result, const char *error, const char *info, afb_req_t req), T *closure) const { subcall(api, verb, args, flags, reinterpret_cast<void(*)(void*,json_object*,const char*,const char*,afb_req_t)>(callback), reinterpret_cast<void*>(closure)); } inline bool req::subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const { return !afb_req_subcall_sync(req_, api, verb, args, flags, &object, &error, &info); } inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const { afb_req_subcall_legacy(req_, api, verb, args, callback, closure); } template <class T> inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const { subcall(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_req_t)>(callback), reinterpret_cast<void*>(closure)); } inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const { return !afb_req_subcall_sync_legacy(req_, api, verb, args, &result); } inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const { afb_req_verbose(req_, level, file, line, func, fmt, args); } inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const { va_list args; va_start(args, fmt); afb_req_verbose(req_, level, file, line, func, fmt, args); va_end(args); } inline bool req::has_permission(const char *permission) const { return bool(afb_req_has_permission(req_, permission)); } inline char *req::get_application_id() const { return afb_req_get_application_id(req_); } inline int req::get_uid() const { return afb_req_get_uid(req_); } inline json_object *req::get_client_info() const { return afb_req_get_client_info(req_); } /* commons */ inline int broadcast_event(const char *name, json_object *object) { return afb_daemon_broadcast_event(name, object); } inline event make_event(const char *name) { return afb_daemon_make_event(name); } inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) { afb_daemon_verbose(level, file, line, func, fmt, args); } inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); } inline int rootdir_get_fd() { return afb_daemon_rootdir_get_fd(); } inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale) { return afb_daemon_rootdir_open_locale(filename, flags, locale); } inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) { return afb_daemon_queue_job(callback, argument, group, timeout); } inline int require_api(const char *apiname, bool initialized) { return afb_daemon_require_api(apiname, int(initialized)); } inline int add_alias(const char *apiname, const char *aliasname) { return afb_daemon_add_alias(apiname, aliasname); } inline int logmask() { return afb_get_logmask(); } inline bool wants_errors() { return AFB_SYSLOG_MASK_WANT_ERROR(logmask()); } inline bool wants_warnings() { return AFB_SYSLOG_MASK_WANT_WARNING(logmask()); } inline bool wants_notices() { return AFB_SYSLOG_MASK_WANT_NOTICE(logmask()); } inline bool wants_infos() { return AFB_SYSLOG_MASK_WANT_INFO(logmask()); } inline bool wants_debugs() { return AFB_SYSLOG_MASK_WANT_DEBUG(logmask()); } inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, struct json_object *result, const char *error, const char *info, afb_api_t api), void *closure) { afb_service_call(api, verb, args, callback, closure); } template <class T> inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, struct json_object *result, const char *error, const char *info, afb_api_t api), T *closure) { afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_api_t)>(callback), reinterpret_cast<void*>(closure)); } inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result, char *&error, char *&info) { return !!afb_service_call_sync(api, verb, args, &result, &error, &info); } /*************************************************************************/ /* declaration of the binding's authorization s */ /*************************************************************************/ constexpr afb_auth auth_no() { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_No; return r; } constexpr afb_auth auth_yes() { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Yes; return r; } constexpr afb_auth auth_token() { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Token; return r; } constexpr afb_auth auth_LOA(unsigned loa) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_LOA; r.loa = loa; return r; } constexpr afb_auth auth_permission(const char *permission) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Permission; r.text = permission; return r; } constexpr afb_auth auth_not(const afb_auth *other) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Not; r.first = other; return r; } constexpr afb_auth auth_not(const afb_auth &other) { return auth_not(&other); } constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Or; r.first = first; r.next = next; return r; } constexpr afb_auth auth_or(const afb_auth &first, const afb_auth &next) { return auth_or(&first, &next); } constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_And; r.first = first; r.next = next; return r; } constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next) { return auth_and(&first, &next); } constexpr afb_verb_t verb( const char *name, void (*callback)(afb_req_t), const char *info = nullptr, uint16_t session = 0, const afb_auth *auth = nullptr, bool glob = false, void *vcbdata = nullptr ) { afb_verb_t r = { 0, 0, 0, 0, 0, 0, 0 }; r.verb = name; r.callback = callback; r.info = info; r.session = session; r.auth = auth; r.glob = (unsigned)glob; r.vcbdata = vcbdata; return r; } constexpr afb_verb_t verbend() { afb_verb_t r = verb(nullptr, nullptr); return r; } constexpr afb_binding_t binding( const char *name, const afb_verb_t *verbs, const char *info = nullptr, int (*init)(afb_api_t) = nullptr, const char *specification = nullptr, void (*onevent)(afb_api_t, const char*, struct json_object*) = nullptr, bool noconcurrency = false, int (*preinit)(afb_api_t) = nullptr, void *userdata = nullptr ) { afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; r.api = name; r.specification = specification; r.info = info; r.verbs = verbs; r.preinit = preinit; r.init = init; r.onevent = onevent; r.noconcurrency = noconcurrency ? 1 : 0; r.userdata = userdata; return r; }; /*************************************************************************/ /*** E N D ***/ /*************************************************************************/ }