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