2 * Copyright (C) 2015-2020 "IoT.bzh"
3 * Author José Bollo <jose.bollo@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #if WITH_AFB_HOOK /***********************************************************/
27 #include "afb-hook-flags.h"
29 /* structure for searching flags by names */
32 const char *name; /** the name */
33 int value; /** the value */
42 #define FLAGS(x) ((struct flags){ .flags = x, .count = (int)(sizeof x / sizeof * x) })
44 static struct flag xreq_flags[] = { /* must be sorted by names */
45 { "addref", afb_hook_flag_req_addref },
46 { "all", afb_hook_flags_req_all },
47 { "args", afb_hook_flags_req_args },
48 { "begin", afb_hook_flag_req_begin },
49 { "common", afb_hook_flags_req_common },
50 { "context", afb_hook_flags_req_context },
51 { "context_get", afb_hook_flag_req_legacy_context_get },
52 { "context_make", afb_hook_flag_req_context_make },
53 { "context_set", afb_hook_flag_req_legacy_context_set },
54 { "end", afb_hook_flag_req_end },
55 { "event", afb_hook_flags_req_event },
56 { "extra", afb_hook_flags_req_extra },
57 { "get", afb_hook_flag_req_get },
58 { "get_application_id", afb_hook_flag_req_get_application_id },
59 { "get_client_info", afb_hook_flag_req_get_client_info },
60 { "get_uid", afb_hook_flag_req_get_uid },
61 { "has_permission", afb_hook_flag_req_has_permission },
62 { "json", afb_hook_flag_req_json },
63 { "life", afb_hook_flags_req_life },
64 { "ref", afb_hook_flags_req_ref },
65 { "reply", afb_hook_flag_req_reply },
66 { "security", afb_hook_flags_req_security },
67 { "session", afb_hook_flags_req_session },
68 { "session_close", afb_hook_flag_req_session_close },
69 { "session_set_LOA", afb_hook_flag_req_session_set_LOA },
70 { "store", afb_hook_flag_req_legacy_store },
71 { "stores", afb_hook_flags_req_stores },
72 { "subcall", afb_hook_flag_req_subcall },
73 { "subcall_result", afb_hook_flag_req_subcall_result },
74 { "subcalls", afb_hook_flags_req_subcalls },
75 { "subcallsync", afb_hook_flag_req_subcallsync },
76 { "subcallsync_result", afb_hook_flag_req_subcallsync_result },
77 { "subscribe", afb_hook_flag_req_subscribe },
78 { "unref", afb_hook_flag_req_unref },
79 { "unstore", afb_hook_flag_req_legacy_unstore },
80 { "unsubscribe", afb_hook_flag_req_unsubscribe },
81 { "vverbose", afb_hook_flag_req_vverbose },
84 static struct flag api_flags[] = { /* must be sorted by names */
85 { "add_alias", afb_hook_flag_api_add_alias },
86 { "all", afb_hook_flags_api_all },
87 { "api_add_verb", afb_hook_flag_api_api_add_verb },
88 { "api", afb_hook_flags_api_api },
89 { "api_del_verb", afb_hook_flag_api_api_del_verb },
90 { "api_seal", afb_hook_flag_api_api_seal },
91 { "api_set_on_event", afb_hook_flag_api_api_set_on_event },
92 { "api_set_on_init", afb_hook_flag_api_api_set_on_init },
93 { "api_set_verbs", afb_hook_flag_api_api_set_verbs },
94 { "call", afb_hook_flag_api_call },
95 { "callsync", afb_hook_flag_api_callsync },
96 { "class_provide", afb_hook_flag_api_class_provide },
97 { "class_require", afb_hook_flag_api_class_require },
98 { "common", afb_hook_flags_api_common },
99 { "delete_api", afb_hook_flag_api_delete_api },
100 { "event", afb_hook_flags_api_event },
101 { "event_broadcast", afb_hook_flag_api_event_broadcast },
102 { "event_handler_add", afb_hook_flag_api_event_handler_add },
103 { "event_handler_del", afb_hook_flag_api_event_handler_del },
104 { "event_make", afb_hook_flag_api_event_make },
105 { "extra", afb_hook_flags_api_extra },
106 { "get_event_loop", afb_hook_flag_api_get_event_loop },
107 { "get_system_bus", afb_hook_flag_api_get_system_bus },
108 { "get_user_bus", afb_hook_flag_api_get_user_bus },
109 { "legacy_unstore_req", afb_hook_flag_api_legacy_unstore_req },
110 { "new_api", afb_hook_flag_api_new_api },
111 { "on_event", afb_hook_flag_api_on_event },
112 { "on_event_handler", afb_hook_flag_api_on_event_handler },
113 { "queue_job", afb_hook_flag_api_queue_job },
114 { "require_api", afb_hook_flag_api_require_api },
115 { "rootdir_get_fd", afb_hook_flag_api_rootdir_get_fd },
116 { "rootdir_open_locale",afb_hook_flag_api_rootdir_open_locale },
117 { "settings", afb_hook_flag_api_settings },
118 { "start", afb_hook_flag_api_start },
119 { "vverbose", afb_hook_flag_api_vverbose },
122 static struct flag evt_flags[] = { /* must be sorted by names */
123 { "addref", afb_hook_flag_evt_addref },
124 { "all", afb_hook_flags_evt_all },
125 { "broadcast_after", afb_hook_flag_evt_broadcast_after },
126 { "broadcast_before", afb_hook_flag_evt_broadcast_before },
127 { "common", afb_hook_flags_evt_common },
128 { "create", afb_hook_flag_evt_create },
129 { "extra", afb_hook_flags_evt_extra },
130 { "name", afb_hook_flag_evt_name },
131 { "push_after", afb_hook_flag_evt_push_after },
132 { "push_before", afb_hook_flag_evt_push_before },
133 { "unref", afb_hook_flag_evt_unref },
136 static struct flag session_flags[] = { /* must be sorted by names */
137 { "addref", afb_hook_flag_session_addref },
138 { "all", afb_hook_flags_session_all },
139 { "close", afb_hook_flag_session_close },
140 { "common", afb_hook_flags_session_common },
141 { "create", afb_hook_flag_session_create },
142 { "destroy", afb_hook_flag_session_destroy },
143 { "unref", afb_hook_flag_session_unref },
146 static struct flag global_flags[] = { /* must be sorted by names */
147 { "all", afb_hook_flags_global_all },
148 { "vverbose", afb_hook_flag_global_vverbose },
151 static int compare(const char *query, const char *value, size_t query_length)
156 for (i = 0 ; i < query_length ; i++) {
161 v = v == '_' ? '-' : (char)toupper(v);
162 q = q == '_' ? '-' : (char)toupper(q);
164 return (int)((unsigned)q - (unsigned)v);
169 /* get the value of the flag of 'name' in the array 'flags' of 'count elements */
170 static int get_flag(const char *name, struct flags flags, size_t length)
172 /* replace "*" by "all" */
173 if (length == 1 && *name == '*') {
178 /* dichotomic search */
179 int lower = 0, upper = flags.count;
180 while (lower < upper) {
181 int mid = (lower + upper) >> 1;
182 int cmp = compare(name, flags.flags[mid].name, length);
184 return flags.flags[mid].value;
191 return -(compare(name, "no", length) && compare(name, "none", length));
194 static int from_text(const char *text, struct flags flags)
196 static const char sep[] = " \t,";
202 text += strspn(text, sep);
205 s = strcspn(text, sep);
206 val = get_flag(text, flags, s);
216 static char *to_text(int value, struct flags flags)
218 int borrow = 0, mask = 0, i, v, imask;
223 return strdup("none");
227 result = malloc(s + 1);
232 while (borrow != value) {
236 v = flags.flags[--i].value;
237 if ((mask & v) == mask && (borrow & v) == 0 && (value & v) == v) {
246 s += strlen(flags.flags[imask].name) + !!s;
250 strcpy(&result[s], flags.flags[imask].name);
251 s += strlen(flags.flags[imask].name);
259 int afb_hook_flags_xreq_from_text(const char *text)
261 return from_text(text, FLAGS(xreq_flags));
264 int afb_hook_flags_api_from_text(const char *text)
266 return from_text(text, FLAGS(api_flags));
269 int afb_hook_flags_evt_from_text(const char *text)
271 return from_text(text, FLAGS(evt_flags));
274 int afb_hook_flags_session_from_text(const char *text)
276 return from_text(text, FLAGS(session_flags));
279 int afb_hook_flags_global_from_text(const char *text)
281 return from_text(text, FLAGS(global_flags));
284 char *afb_hook_flags_xreq_to_text(int value)
286 return to_text(value, FLAGS(xreq_flags));
289 char *afb_hook_flags_api_to_text(int value)
291 return to_text(value, FLAGS(api_flags));
294 char *afb_hook_flags_evt_to_text(int value)
296 return to_text(value, FLAGS(evt_flags));
299 char *afb_hook_flags_session_to_text(int value)
301 return to_text(value, FLAGS(session_flags));
304 char *afb_hook_flags_global_to_text(int value)
306 return to_text(value, FLAGS(global_flags));
309 #if !defined(REMOVE_LEGACY_TRACE)
310 static struct flag legacy_ditf_flags[] = { /* must be sorted by names */
311 { "all", afb_hook_flags_api_ditf_all },
312 { "common", afb_hook_flags_api_ditf_common },
313 { "event_broadcast_after", afb_hook_flag_api_event_broadcast },
314 { "event_broadcast_before", afb_hook_flag_api_event_broadcast },
315 { "event_make", afb_hook_flag_api_event_make },
316 { "extra", afb_hook_flags_api_ditf_extra },
317 { "get_event_loop", afb_hook_flag_api_get_event_loop },
318 { "get_system_bus", afb_hook_flag_api_get_system_bus },
319 { "get_user_bus", afb_hook_flag_api_get_user_bus },
320 { "queue_job", afb_hook_flag_api_queue_job },
321 { "require_api", afb_hook_flag_api_require_api },
322 { "require_api_result", afb_hook_flag_api_require_api },
323 { "rootdir_get_fd", afb_hook_flag_api_rootdir_get_fd },
324 { "rootdir_open_locale", afb_hook_flag_api_rootdir_open_locale },
325 { "unstore_req", afb_hook_flag_api_legacy_unstore_req },
326 { "vverbose", afb_hook_flag_api_vverbose },
329 static struct flag legacy_svc_flags[] = { /* must be sorted by names */
330 { "all", afb_hook_flags_api_svc_all },
331 { "call", afb_hook_flag_api_call },
332 { "call_result", afb_hook_flag_api_call },
333 { "callsync", afb_hook_flag_api_callsync },
334 { "callsync_result", afb_hook_flag_api_callsync },
335 { "on_event_after", afb_hook_flag_api_on_event },
336 { "on_event_before", afb_hook_flag_api_on_event },
337 { "start_after", afb_hook_flag_api_start },
338 { "start_before", afb_hook_flag_api_start },
341 int afb_hook_flags_legacy_ditf_from_text(const char *text)
343 return from_text(text, FLAGS(legacy_ditf_flags));
346 int afb_hook_flags_legacy_svc_from_text(const char *text)
348 return from_text(text, FLAGS(legacy_svc_flags));
351 char *afb_hook_flags_legacy_ditf_to_text(int value)
353 return to_text(value, FLAGS(legacy_ditf_flags));
356 char *afb_hook_flags_legacy_svc_to_text(int value)
358 return to_text(value, FLAGS(legacy_svc_flags));
362 #endif /* WITH_AFB_HOOK *******************************************************/