libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
cmd.c
1/*
2 * CDDL HEADER START
3 *
4 * This file and its contents are supplied under the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may only use this file in accordance with the terms of version
7 * 1.0 of the CDDL.
8 *
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.illumos.org/license/CDDL.
12 *
13 * CDDL HEADER END
14*/
15/*
16 * Copyright 2018 Saso Kiselkov. All rights reserved.
17 */
18
19#include <stdio.h>
20
21#include <acfutils/assert.h>
22#include <acfutils/cmd.h>
23#include <acfutils/safe_alloc.h>
24
25static XPLMCommandRef
26cmd_find_v_impl(const char *fmt, va_list ap, bool_t force)
27{
28 va_list ap2;
29 int l;
30 char *name;
31 XPLMCommandRef ref;
32
33 va_copy(ap2, ap);
34 l = vsnprintf(NULL, 0, fmt, ap2);
35 va_end(ap2);
36
37 name = malloc(l + 1);
38 vsnprintf(name, l + 1, fmt, ap);
39 ref = XPLMFindCommand(name);
40 if (ref == NULL && force)
41 VERIFY_MSG(0, "Command \"%s\" not found", name);
42 free(name);
43
44 return (ref);
45}
46
47API_EXPORT XPLMCommandRef
48cmd_find(const char *fmt, ...)
49{
50 va_list ap;
51 XPLMCommandRef ref;
52
53 va_start(ap, fmt);
54 ref = cmd_find_v_impl(fmt, ap, B_FALSE);
55 va_end(ap);
56
57 return (ref);
58}
59
60API_EXPORT XPLMCommandRef
61fcmd_find(const char *fmt, ...)
62{
63 va_list ap;
64 XPLMCommandRef ref;
65
66 va_start(ap, fmt);
67 ref = cmd_find_v_impl(fmt, ap, B_TRUE);
68 va_end(ap);
69
70 return (ref);
71}
72
73API_EXPORT XPLMCommandRef
74cmd_find_v(const char *fmt, va_list ap)
75{
76 return (cmd_find_v_impl(fmt, ap, B_FALSE));
77}
78
79API_EXPORT XPLMCommandRef
80fcmd_find_v(const char *fmt, va_list ap)
81{
82 return (cmd_find_v_impl(fmt, ap, B_TRUE));
83}
84
85API_EXPORT XPLMCommandRef
86cmd_bind_v(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon,
87 va_list ap)
88{
89 XPLMCommandRef ref;
90 va_list ap2;
91 char *name;
92 int len;
93
94 va_copy(ap2, ap);
95 len = vsnprintf(NULL, 0, fmt, ap2);
96 va_end(ap2);
97 name = safe_malloc(len + 1);
98 VERIFY3S(vsnprintf(name, len + 1, fmt, ap), ==, len);
99
100 ref = XPLMFindCommand(name);
101 if (ref != NULL)
102 XPLMRegisterCommandHandler(ref, cb, before, refcon);
103
104 free(name);
105
106 return (ref);
107}
108
109API_EXPORT XPLMCommandRef
110cmd_bind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon, ...)
111{
112 va_list ap;
113 XPLMCommandRef ref;
114
115 va_start(ap, refcon);
116 ref = cmd_bind_v(fmt, cb, before, refcon, ap);
117 va_end(ap);
118
119 return (ref);
120}
121
122API_EXPORT XPLMCommandRef
123fcmd_bind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon, ...)
124{
125 va_list ap;
126 XPLMCommandRef ref;
127
128 va_start(ap, refcon);
129 ref = cmd_bind_v(fmt, cb, before, refcon, ap);
130 va_end(ap);
131
132 if (ref == NULL) {
133 char name[256];
134 va_start(ap, refcon);
135 vsnprintf(name, sizeof (name), fmt, ap);
136 va_end(ap);
137 VERIFY_MSG(0, "Command %s not found", name);
138 }
139
140 return (ref);
141}
142
143API_EXPORT bool_t
144cmd_unbind_v(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon,
145 va_list ap)
146{
147 XPLMCommandRef ref;
148 va_list ap2;
149 char *name;
150 int len;
151
152 va_copy(ap2, ap);
153 len = vsnprintf(NULL, 0, fmt, ap2);
154 va_end(ap2);
155 name = safe_malloc(len + 1);
156 VERIFY3S(vsnprintf(name, len + 1, fmt, ap), ==, len);
157
158 ref = XPLMFindCommand(name);
159
160 free(name);
161
162 if (ref != NULL) {
163 XPLMUnregisterCommandHandler(ref, cb, before, refcon);
164 return (B_TRUE);
165 }
166
167 return (B_FALSE);
168}
169
170API_EXPORT bool_t
171cmd_unbind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon, ...)
172{
173 va_list ap;
174 bool_t res;
175
176 va_start(ap, refcon);
177 res = cmd_unbind_v(fmt, cb, before, refcon, ap);
178 va_end(ap);
179
180 return (res);
181}
182
183API_EXPORT void
184fcmd_unbind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon, ...)
185{
186 va_list ap;
187 bool_t res;
188
189 va_start(ap, refcon);
190 res = cmd_unbind_v(fmt, cb, before, refcon, ap);
191 va_end(ap);
192
193 if (!res) {
194 char name[256];
195 va_start(ap, refcon);
196 vsnprintf(name, sizeof (name), fmt, ap);
197 va_end(ap);
198 VERIFY_MSG(0, "Command %s not found", name);
199 }
200}
#define VERIFY3S(x, op, y)
Definition assert.h:125
#define VERIFY_MSG(x, fmt,...)
Definition assert.h:91
XPLMCommandRef cmd_bind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon,...)
Definition cmd.c:110
XPLMCommandRef fcmd_find(const char *fmt,...)
Definition cmd.c:61
XPLMCommandRef fcmd_find_v(const char *fmt, va_list ap)
Definition cmd.c:80
void fcmd_unbind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon,...)
Definition cmd.c:184
XPLMCommandRef cmd_find(const char *fmt,...)
Definition cmd.c:48
XPLMCommandRef cmd_bind_v(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon, va_list ap)
Definition cmd.c:86
bool_t cmd_unbind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon,...)
Definition cmd.c:171
XPLMCommandRef fcmd_bind(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon,...)
Definition cmd.c:123
bool_t cmd_unbind_v(const char *fmt, cmd_cb_t cb, bool_t before, void *refcon, va_list ap)
Definition cmd.c:144
XPLMCommandRef cmd_find_v(const char *fmt, va_list ap)
Definition cmd.c:74
static void * safe_malloc(size_t size)
Definition safe_alloc.h:56