1 /* Public domain */
2
3 #include <agar/core/begin.h>
4
5 typedef enum ag_variable_type {
6 AG_VARIABLE_NULL, /* No data */
7 AG_VARIABLE_UINT, /* Unsigned int */
8 AG_VARIABLE_P_UINT, /* Pointer to Uint */
9 AG_VARIABLE_INT, /* Natural int */
10 AG_VARIABLE_P_INT, /* Pointer to int */
11 AG_VARIABLE_UINT8, /* Unsigned 8-bit */
12 AG_VARIABLE_P_UINT8, /* Pointer to Uint8 */
13 AG_VARIABLE_SINT8, /* Signed 8-bit */
14 AG_VARIABLE_P_SINT8, /* Pointer to Sint8 */
15 AG_VARIABLE_UINT16, /* Unsigned 16-bit */
16 AG_VARIABLE_P_UINT16, /* Pointer to Uint16 */
17 AG_VARIABLE_SINT16, /* Signed 16-bit */
18 AG_VARIABLE_P_SINT16, /* Pointer to Sint16 */
19 AG_VARIABLE_UINT32, /* Unsigned 32-bit */
20 AG_VARIABLE_P_UINT32, /* Pointer to Uint32 */
21 AG_VARIABLE_SINT32, /* Signed 32-bit */
22 AG_VARIABLE_P_SINT32, /* Pointer to Sint32 */
23 AG_VARIABLE_UINT64, /* Unsigned 64-bit (optional) */
24 AG_VARIABLE_P_UINT64, /* Pointer to Uint64 (optional) */
25 AG_VARIABLE_SINT64, /* Signed 64-bit (optional) */
26 AG_VARIABLE_P_SINT64, /* Pointer to Sint64 (optional) */
27 AG_VARIABLE_FLOAT, /* Single-precision float */
28 AG_VARIABLE_P_FLOAT, /* Pointer to float */
29 AG_VARIABLE_DOUBLE, /* Double-precision float */
30 AG_VARIABLE_P_DOUBLE, /* Pointer to double */
31 AG_VARIABLE_LONG_DOUBLE, /* Quad-precision float (optional) */
32 AG_VARIABLE_P_LONG_DOUBLE, /* Pointer to long double (optional) */
33 AG_VARIABLE_STRING, /* C string */
34 AG_VARIABLE_P_STRING, /* Pointer to C string */
35 AG_VARIABLE_CONST_STRING, /* C string (const) */
36 AG_VARIABLE_P_CONST_STRING, /* Pointer to C string (const) */
37 AG_VARIABLE_POINTER, /* C pointer */
38 AG_VARIABLE_P_POINTER, /* Pointer to C pointer */
39 AG_VARIABLE_CONST_POINTER, /* C pointer (const) */
40 AG_VARIABLE_P_CONST_POINTER, /* Pointer to C pointer (const) */
41 AG_VARIABLE_P_FLAG, /* Bit in int (uses info.mask) */
42 AG_VARIABLE_P_FLAG8, /* Bit in int8 (uses info.mask) */
43 AG_VARIABLE_P_FLAG16, /* Bit in int16 (uses info.mask) */
44 AG_VARIABLE_P_FLAG32, /* Bit in int32 (uses info.mask) */
45 AG_VARIABLE_P_OBJECT, /* Pointer to AG_Object(3) */
46 AG_VARIABLE_P_TEXT, /* Pointer to AG_Text(3) */
47 AG_VARIABLE_P_VARIABLE, /* Reference to an AG_Variable(3) */
48 AG_VARIABLE_TYPE_LAST
49 } AG_VariableType;
50
51 typedef struct ag_variable_type_info {
52 enum ag_variable_type type; /* Variable type */
53 int indirLvl; /* Indirection level */
54 const char *name; /* Name string */
55 enum ag_variable_type typeTgt; /* Pointer target type (or AG_VARIABLE_NULL) */
56 Sint32 code; /* Numerical code (-1 = non persistent) */
57 size_t size; /* Size in bytes (or 0) */
58 } AG_VariableTypeInfo;
59
60 #define AG_VARIABLE_NAME_MAX 40
61 #define AG_VARIABLE_BOOL AG_VARIABLE_INT
62
63 struct ag_event;
64
65 typedef void (*AG_VoidFn)(struct ag_event *);
66 typedef Uint (*AG_UintFn)(struct ag_event *);
67 typedef int (*AG_IntFn)(struct ag_event *);
68 typedef Uint8 (*AG_Uint8Fn)(struct ag_event *);
69 typedef Sint8 (*AG_Sint8Fn)(struct ag_event *);
70 typedef Uint16 (*AG_Uint16Fn)(struct ag_event *);
71 typedef Sint16 (*AG_Sint16Fn)(struct ag_event *);
72 typedef Uint32 (*AG_Uint32Fn)(struct ag_event *);
73 typedef Sint32 (*AG_Sint32Fn)(struct ag_event *);
74 #ifdef AG_HAVE_64BIT
75 typedef Uint64 (*AG_Uint64Fn)(struct ag_event *);
76 typedef Sint64 (*AG_Sint64Fn)(struct ag_event *);
77 #endif
78 typedef float (*AG_FloatFn)(struct ag_event *);
79 typedef double (*AG_DoubleFn)(struct ag_event *);
80 #ifdef AG_HAVE_LONG_DOUBLE
81 typedef long double (*AG_LongDoubleFn)(struct ag_event *);
82 #endif
83 typedef size_t (*AG_StringFn)(struct ag_event *, char *, size_t);
84 typedef void *(*AG_PointerFn)(struct ag_event *);
85 typedef const void *(*AG_ConstPointerFn)(struct ag_event *);
86 typedef AG_Text *(*AG_TextFn)(struct ag_event *);
87
88 union ag_function {
89 AG_VoidFn fnVoid;
90 AG_UintFn fnUint;
91 AG_IntFn fnInt;
92 AG_Uint8Fn fnUint8;
93 AG_Sint8Fn fnSint8;
94 AG_Uint16Fn fnUint16;
95 AG_Sint16Fn fnSint16;
96 AG_Uint32Fn fnUint32;
97 AG_Sint32Fn fnSint32;
98 #ifdef AG_HAVE_64BIT
99 AG_Uint64Fn fnUint64;
100 AG_Sint64Fn fnSint64;
101 #endif
102 AG_FloatFn fnFloat;
103 AG_DoubleFn fnDouble;
104 #ifdef AG_HAVE_LONG_DOUBLE
105 AG_LongDoubleFn fnLongDouble;
106 #endif
107 AG_StringFn fnString;
108 AG_PointerFn fnPointer;
109 AG_ConstPointerFn fnConstPointer;
110 AG_TextFn fnText;
111 };
112
113 union ag_variable_data {
114 void *p;
115 const void *Cp;
116 char *s;
117 const char *Cs;
118 int i;
119 Uint u;
120 float flt;
121 double dbl;
122 #ifdef AG_HAVE_LONG_DOUBLE
123 long double ldbl;
124 #endif
125 Uint8 u8;
126 Sint8 s8;
127 Uint16 u16;
128 Sint16 s16;
129 Uint32 u32;
130 Sint32 s32;
131 #ifdef AG_HAVE_64BIT
132 Uint64 u64;
133 Sint64 s64;
134 #endif
135 };
136
137 typedef struct ag_variable {
138 char name[AG_VARIABLE_NAME_MAX]; /* Variable name */
139 AG_VariableType type; /* Variable type */
140 AG_Mutex *mutex; /* Lock protecting data (or NULL) */
141 union {
142 Uint32 bitmask; /* Bitmask (P_FLAG_*) */
143 size_t size; /* Length / Buffer size (STRING_*) */
144 struct { /* For P_VARIABLE type */
145 char *key;
146 struct ag_variable *var;
147 } ref;
148 } info;
149 union ag_function fn; /* Eval function */
150 union ag_variable_data data; /* Variable-stored data */
151 AG_TAILQ_ENTRY(ag_variable) vars;
152 } AG_Variable;
153
154 __BEGIN_DECLS
155 struct ag_list;
156 extern const AG_VariableTypeInfo agVariableTypes[];
157
158 int AG_EvalVariable(void *, AG_Variable *);
159 void AG_PrintVariable(char *, size_t, AG_Variable *);
160 AG_Variable *AG_GetVariableVFS(void *, const char *)
161 WARN_UNUSED_RESULT_ATTRIBUTE;
162 AG_Variable *AG_GetVariable(void *, const char *, ...)
163 WARN_UNUSED_RESULT_ATTRIBUTE;
164 int AG_CopyVariable(AG_Variable *, const AG_Variable *);
165 int AG_DerefVariable(AG_Variable *, const AG_Variable *);
166 int AG_CompareVariables(const AG_Variable *, const AG_Variable *);
167 void AG_Unset(void *, const char *);
168 void AG_VariableSubst(void *, const char *, char *, size_t)
169 BOUNDED_ATTRIBUTE(__string__, 3, 4);
170
171 struct ag_list *AG_ListSet(const char *, ...);
172
173 Uint AG_GetUint(void *, const char *);
174 void AG_InitUint(AG_Variable *, Uint);
175 AG_Variable *AG_SetUint(void *, const char *, Uint);
176 AG_Variable *AG_BindUint(void *, const char *, Uint *);
177 AG_Variable *AG_BindUintFn(void *, const char *, AG_UintFn, const char *, ...);
178 AG_Variable *AG_BindUintMp(void *, const char *, Uint *, AG_Mutex *);
179
180 int AG_GetInt(void *, const char *);
181 AG_Variable *AG_SetInt(void *, const char *, int);
182 void AG_InitInt(AG_Variable *, int);
183 AG_Variable *AG_BindInt(void *, const char *, int *);
184 AG_Variable *AG_BindIntFn(void *, const char *, AG_IntFn, const char *, ...);
185 AG_Variable *AG_BindIntMp(void *, const char *, int *, AG_Mutex *);
186
187 #define AG_GetBool AG_GetInt
188 #define AG_SetBool AG_SetInt
189 #define AG_BindBool AG_BindInt
190 #define AG_BindBoolFn AG_BindIntFn
191 #define AG_BindBoolMp AG_BindIntMp
192
193 Uint8 AG_GetUint8(void *, const char *);
194 AG_Variable *AG_SetUint8(void *, const char *, Uint8);
195 void AG_InitUint8(AG_Variable *, Uint8);
196 AG_Variable *AG_BindUint8(void *, const char *, Uint8 *);
197 AG_Variable *AG_BindUint8Fn(void *, const char *, AG_Uint8Fn, const char *, ...);
198 AG_Variable *AG_BindUint8Mp(void *, const char *, Uint8 *, AG_Mutex *);
199
200 Sint8 AG_GetSint8(void *, const char *);
201 AG_Variable *AG_SetSint8(void *, const char *, Sint8);
202 void AG_InitSint8(AG_Variable *, Sint8);
203 AG_Variable *AG_BindSint8(void *, const char *, Sint8 *);
204 AG_Variable *AG_BindSint8Fn(void *, const char *, AG_Sint8Fn, const char *, ...);
205 AG_Variable *AG_BindSint8Mp(void *, const char *, Sint8 *, AG_Mutex *);
206
207 Uint16 AG_GetUint16(void *, const char *);
208 AG_Variable *AG_SetUint16(void *, const char *, Uint16);
209 void AG_InitUint16(AG_Variable *, Uint16);
210 AG_Variable *AG_BindUint16(void *, const char *, Uint16 *);
211 AG_Variable *AG_BindUint16Fn(void *, const char *, AG_Uint16Fn, const char *, ...);
212 AG_Variable *AG_BindUint16Mp(void *, const char *, Uint16 *, AG_Mutex *);
213
214 Sint16 AG_GetSint16(void *, const char *);
215 AG_Variable *AG_SetSint16(void *, const char *, Sint16);
216 void AG_InitSint16(AG_Variable *, Sint16);
217 AG_Variable *AG_BindSint16Fn(void *, const char *, AG_Sint16Fn, const char *, ...);
218 AG_Variable *AG_BindSint16(void *, const char *, Sint16 *);
219 AG_Variable *AG_BindSint16Mp(void *, const char *, Sint16 *, AG_Mutex *);
220
221 Uint32 AG_GetUint32(void *, const char *);
222 AG_Variable *AG_SetUint32(void *, const char *, Uint32);
223 void AG_InitUint32(AG_Variable *, Uint32);
224 AG_Variable *AG_BindUint32Fn(void *, const char *, AG_Uint32Fn, const char *, ...);
225 AG_Variable *AG_BindUint32(void *, const char *, Uint32 *);
226 AG_Variable *AG_BindUint32Mp(void *, const char *, Uint32 *, AG_Mutex *);
227
228 Sint32 AG_GetSint32(void *, const char *);
229 AG_Variable *AG_SetSint32(void *, const char *, Sint32);
230 void AG_InitSint32(AG_Variable *, Sint32);
231 AG_Variable *AG_BindSint32Fn(void *, const char *, AG_Sint32Fn, const char *, ...);
232 AG_Variable *AG_BindSint32(void *, const char *, Sint32 *);
233 AG_Variable *AG_BindSint32Mp(void *, const char *, Sint32 *, AG_Mutex *);
234
235 #ifdef AG_HAVE_64BIT
236 Uint64 AG_GetUint64(void *, const char *);
237 AG_Variable *AG_SetUint64(void *, const char *, Uint64);
238 void AG_InitUint64(AG_Variable *, Uint64);
239 AG_Variable *AG_BindUint64Fn(void *, const char *, AG_Uint64Fn, const char *, ...);
240 AG_Variable *AG_BindUint64(void *, const char *, Uint64 *);
241 AG_Variable *AG_BindUint64Mp(void *, const char *, Uint64 *, AG_Mutex *);
242 Sint64 AG_GetSint64(void *, const char *);
243 AG_Variable *AG_SetSint64(void *, const char *, Sint64);
244 void AG_InitSint64(AG_Variable *, Sint64);
245 AG_Variable *AG_BindSint64Fn(void *, const char *, AG_Sint64Fn, const char *, ...);
246 AG_Variable *AG_BindSint64(void *, const char *, Sint64 *);
247 AG_Variable *AG_BindSint64Mp(void *, const char *, Sint64 *, AG_Mutex *);
248 #endif /* AG_HAVE_64BIT */
249
250 float AG_GetFloat(void *, const char *);
251 AG_Variable *AG_SetFloat(void *, const char *, float);
252 void AG_InitFloat(AG_Variable *, float);
253 AG_Variable *AG_BindFloatFn(void *, const char *, AG_FloatFn, const char *, ...);
254 AG_Variable *AG_BindFloat(void *, const char *, float *);
255 AG_Variable *AG_BindFloatMp(void *, const char *, float *, AG_Mutex *);
256
257 double AG_GetDouble(void *, const char *);
258 AG_Variable *AG_SetDouble(void *, const char *, double);
259 void AG_InitDouble(AG_Variable *, double);
260 AG_Variable *AG_BindDoubleFn(void *, const char *, AG_DoubleFn, const char *, ...);
261 AG_Variable *AG_BindDouble(void *, const char *, double *);
262 AG_Variable *AG_BindDoubleMp(void *, const char *, double *, AG_Mutex *);
263 #ifdef AG_HAVE_LONG_DOUBLE
264 long double AG_GetLongDouble(void *, const char *);
265 AG_Variable *AG_SetLongDouble(void *, const char *, long double);
266 void AG_InitLongDouble(AG_Variable *, long double);
267 AG_Variable *AG_BindLongDoubleFn(void *, const char *, AG_LongDoubleFn, const char *, ...);
268 AG_Variable *AG_BindLongDouble(void *, const char *, long double *);
269 AG_Variable *AG_BindLongDoubleMp(void *, const char *, long double *, AG_Mutex *);
270 #endif
271
272 size_t AG_GetString(void *, const char *, char *, size_t)
273 BOUNDED_ATTRIBUTE(__string__, 3, 4);
274 char *AG_GetStringDup(void *, const char *);
275 char *AG_GetStringP(void *, const char *);
276 AG_Variable *AG_SetString(void *, const char *, const char *);
277 AG_Variable *AG_SetStringNODUP(void *, const char *, char *);
278 void AG_InitString(AG_Variable *, const char *);
279 void AG_InitStringNODUP(AG_Variable *, char *);
280 AG_Variable *AG_PrtString(void *, const char *, const char *, ...);
281 AG_Variable *AG_BindString(void *, const char *, char *, size_t);
282 AG_Variable *AG_BindStringFn(void *, const char *, AG_StringFn, const char *, ...);
283 AG_Variable *AG_BindStringMp(void *, const char *, char *, size_t, AG_Mutex *);
284 AG_Variable *AG_SetConstString(void *, const char *, const char *);
285 AG_Variable *AG_BindConstString(void *, const char *, const char **);
286 AG_Variable *AG_BindConstStringMp(void *, const char *, const char **, AG_Mutex *);
287
288 void *AG_GetPointer(void *, const char *);
289 AG_Variable *AG_SetPointer(void *, const char *, void *);
290 void AG_InitPointer(AG_Variable *, void *);
291 AG_Variable *AG_BindPointer(void *, const char *, void **);
292 AG_Variable *AG_BindPointerFn(void *, const char *, AG_PointerFn, const char *, ...);
293 AG_Variable *AG_BindPointerMp(void *, const char *, void **, AG_Mutex *);
294
295 const void *AG_GetConstPointer(void *, const char *);
296 AG_Variable *AG_SetConstPointer(void *, const char *, const void *);
297 void AG_InitConstPointer(AG_Variable *, const void *);
298 AG_Variable *AG_BindConstPointer(void *, const char *, const void **);
299 AG_Variable *AG_BindConstPointerFn(void *, const char *, AG_ConstPointerFn, const char *, ...);
300 AG_Variable *AG_BindConstPointerMp(void *, const char *, const void **, AG_Mutex *);
301
302 AG_Text *AG_GetText(void *, const char *);
303 AG_Variable *AG_SetText(void *, const char *, AG_Text *);
304 void AG_InitText(AG_Variable *, AG_Text *);
305 AG_Variable *AG_BindText(void *, const char *, AG_Text *);
306 AG_Variable *AG_BindTextFn(void *, const char *, AG_TextFn, const char *, ...);
307 AG_Variable *AG_BindTextMp(void *, const char *, AG_Text *, AG_Mutex *);
308
309 AG_Variable *AG_BindFlag(void *, const char *, Uint *, Uint);
310 AG_Variable *AG_BindFlagMp(void *, const char *, Uint *, Uint, AG_Mutex *);
311 AG_Variable *AG_BindFlag8(void *, const char *, Uint8 *, Uint8);
312 AG_Variable *AG_BindFlag8Mp(void *, const char *, Uint8 *, Uint8, AG_Mutex *);
313 AG_Variable *AG_BindFlag16(void *, const char *, Uint16 *, Uint16);
314 AG_Variable *AG_BindFlag16Mp(void *, const char *, Uint16 *, Uint16, AG_Mutex *);
315 AG_Variable *AG_BindFlag32(void *, const char *, Uint32 *, Uint32);
316 AG_Variable *AG_BindFlag32Mp(void *, const char *, Uint32 *, Uint32, AG_Mutex *);
317
318 AG_Variable *AG_BindVariable(void *, const char *, void *, const char *);
319
320 /* Initialize an AG_Variable structure. */
321 static __inline__ void
AG_InitVariable(AG_Variable * V,enum ag_variable_type type)322 AG_InitVariable(AG_Variable *V, enum ag_variable_type type)
323 {
324 V->type = type;
325 V->mutex = NULL;
326 V->fn.fnVoid = NULL;
327 V->info.size = 0;
328 V->info.ref.key = NULL;
329 V->info.ref.var = NULL;
330 V->data.s = NULL;
331 }
332
333 /* Acquire any locking device associated with a variable. */
334 static __inline__ void
AG_LockVariable(AG_Variable * V)335 AG_LockVariable(AG_Variable *V)
336 {
337 if (V->mutex != NULL) { AG_MutexLock(V->mutex); }
338 }
339
340 /* Release any locking device associated with a variable. */
341 static __inline__ void
AG_UnlockVariable(AG_Variable * V)342 AG_UnlockVariable(AG_Variable *V)
343 {
344 if (V->mutex != NULL) { AG_MutexUnlock(V->mutex); }
345 }
346
347 /* Release all resources associated with a variable. */
348 static __inline__ void
AG_FreeVariable(AG_Variable * V)349 AG_FreeVariable(AG_Variable *V)
350 {
351 switch (V->type) {
352 case AG_VARIABLE_STRING:
353 if (V->info.size == 0) {
354 AG_Free(V->data.s);
355 }
356 break;
357 case AG_VARIABLE_P_VARIABLE:
358 AG_Free(V->info.ref.key);
359 break;
360 default:
361 break;
362 }
363 }
364
365 #define AG_VARIABLE_TYPE(V) (agVariableTypes[(V)->type].typeTgt)
366 #define AG_VARIABLE_TYPE_NAME(V) (agVariableTypes[(V)->type].name)
367 __END_DECLS
368
369 #include <agar/core/close.h>
370