Agar


Note: The Agar manual pages follow certain conventions, notably concerning function return values. Please read AG_Intro(3) first.


SYNOPSIS

#include <agar/core.h>

DESCRIPTION

The AG_Variable structure holds primitive data such as integer, floats, strings or typed pointers. It is possible to tie variables to functions, or protect access to data referenced by typed pointers using a mutex device.

AG_Variable is used extensively throughout the Agar library, notably by AG_Object(3) (for property tables), by AG_Event(3) (for argument passing to event handlers), and AG_Widget(3) (where typed pointers are the basis of widget bindings).


INTERFACE


int AG_Defined (AG_Object *obj, const char *name)

AG_Variable * AG_GetVariable (AG_Object *obj, const char *name, void **data)

AG_Variable * AG_GetVariableLocked (AG_Object *obj, const char *name)

void AG_LockVariable (AG_Variable *var)

void AG_UnlockVariable (AG_Variable *var)

AG_Variable * AG_GetVariableVFS (AG_Object *obj, const char *name)

int AG_EvalVariable (AG_Object *obj, AG_Variable *var)

void AG_PrintVariable (char *dst, size_t len, AG_Variable *var)

void AG_CopyVariable (AG_Variable *Vdst, const AG_Variable *Vsrc)

AG_Variable * AG_Set (AG_Object *obj, const char *name, const char *fmt, ...)

void AG_Unset (AG_Object *obj, const char *name)

void AG_VariableSubst (AG_Object *obj, const char *s, char *dst, size_t dst_len)


The AG_Defined() routine returns 1 if the specified variable name is defined under the object obj, otherwise it returns 0.

AG_GetVariable() searches for a named variable under object obj and returns a pointer to the corresponding AG_Variable structure if found, otherwise NULL is returned. If the variable is tied to a function, the function is evaluated first. If data is non-NULL, the primitive data or pointer is copied (not valid for strings).

AG_GetVariableLocked() looks up the named variable under obj and returns a pointer to the corresponding AG_Variable structure if found, otherwise NULL is returned. If the variable is tied to a function, the function is not evaluated internally. Before returning, AG_GetVariableLocked() acquires any locking devices associated with the variable. The caller is expected to invoke AG_UnlockVariable() when done accessing the data.

AG_LockVariable() and AG_UnlockVariable() acquire and release any locking device associated with the specified variable.

AG_GetVariableVFS() searches an AG_Object(3) VFS for a variable from a string of the form object:variable.

The AG_EvalVariable() function evaluates the value of a variable tied to a function. The corresponding function is invoked and the value is returned into the data union. Note that internally, AG_GetVariable() calls AG_EvalVariable(), but AG_GetVariableLocked() does not.

AG_PrintVariable() returns a string representation of the value of variable var into a fixed-size buffer dst, of len bytes.

AG_CopyVariable() copies the contents of a variable from Vsrc to Vdst.

The AG_Set() sets an object-bound variable value using a format-string interface (see AG_PARSE_VARIABLE_ARGS()).

AG_Unset() deletes the named object-bound variable.

AG_VariableSubst() parses the string s for references of the form "$(foo)", and substitutes those references for the value of variable foo (under object obj). The substituted string is returned into fixed-size buffer dst, of size dst_size.

TYPE-SPECIFIC INTERFACES

The following functions are used to retrieve or set variables of specific types.

The AG_GetFoo() functions return the value of variable name (under object obj). If the variable is a pointer type, it is dereferenced. If it is tied to a function, the function is evaluated first.

The AG_InitFoo() functions initialize an AG_Variable structure var with the specified value val.

The AG_SetFoo() functions set the value of variable name to the specified value val. If the variable does not exist, it is created.

The AG_BindFoo() functions create or modify a typed pointer variable. The argument pVal is a pointer to the actual value.

The AG_BindFooMp() variant accepts an extra lock argument, which is a mutex device (i.e., an AG_Mutex or pthread_mutex_t) to be acquired whenever the data referenced by pVal will be accessed.

The AG_BindFooFn() variants create or modify a variable, tying the variable to a function fn, which will be evaluated whenever the variable is read. A list of optional AG_Event(3) style arguments follow the fn argument.

INTEGERS


Uint AG_GetUint (AG_Object *obj, const char *name)

void AG_InitUint (AG_Variable *var, Uint val)

AG_Variable * AG_SetUint (AG_Object *obj, const char *name, Uint val)

AG_Variable * AG_BindUint (AG_Object *obj, const char *name, Uint *pVal)

AG_Variable * AG_BindUintMp (AG_Object *obj, const char *name, Uint *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUintFn (AG_Object *obj, const char *name, Uint (*fn)(AG_Event *), ...)

int AG_GetInt (AG_Object *obj, const char *name)

void AG_InitInt (AG_Variable *var, int val)

AG_Variable * AG_SetInt (AG_Object *obj, const char *name, int val)

AG_Variable * AG_BindInt (AG_Object *obj, const char *name, int *pVal)

AG_Variable * AG_BindIntMp (AG_Object *obj, const char *name, int *pVal, AG_Mutex *lock)

AG_Variable * AG_BindIntFn (AG_Object *obj, const char *name, int (*fn)(AG_Event *))

Uint8 AG_GetUint8 (AG_Object *obj, const char *name)

void AG_InitUint8 (AG_Variable *var, Uint8 val)

AG_Variable * AG_SetUint8 (AG_Object *obj, const char *name, Uint8 val)

AG_Variable * AG_BindUint8 (AG_Object *obj, const char *name, Uint8 *pVal)

AG_Variable * AG_BindUint8Mp (AG_Object *obj, const char *name, Uint8 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint8Fn (AG_Object *obj, const char *name, Uint8 (*fn)(AG_Event *))

Sint8 AG_GetSint8 (AG_Object *obj, const char *name)

void AG_InitSint8 (AG_Variable *var, Sint8 val)

AG_Variable * AG_SetSint8 (AG_Object *obj, const char *name, Sint8 val)

AG_Variable * AG_BindSint8 (AG_Object *obj, const char *name, Sint8 *pVal)

AG_Variable * AG_BindSint8Mp (AG_Object *obj, const char *name, Sint8 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint8Fn (AG_Object *obj, const char *name, Sint8 (*fn)(AG_Event *))

Uint16 AG_GetUint16 (AG_Object *obj, const char *name)

void AG_InitUint16 (AG_Variable *var, Uint16 val)

AG_Variable * AG_SetUint16 (AG_Object *obj, const char *name, Uint16 val)

AG_Variable * AG_BindUint16 (AG_Object *obj, const char *name, Uint16 *pVal)

AG_Variable * AG_BindUint16Mp (AG_Object *obj, const char *name, Uint16 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint16Fn (AG_Object *obj, const char *name, Uint16 (*fn)(AG_Event *))

Sint16 AG_GetSint16 (AG_Object *obj, const char *name)

void AG_InitSint16 (AG_Variable *var, Sint16 val)

AG_Variable * AG_SetSint16 (AG_Object *obj, const char *name, Sint16 val)

AG_Variable * AG_BindSint16 (AG_Object *obj, const char *name, Sint16 *pVal)

AG_Variable * AG_BindSint16Mp (AG_Object *obj, const char *name, Sint16 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint16Fn (AG_Object *obj, const char *name, Sint16 (*fn)(AG_Event *))

Uint32 AG_GetUint32 (AG_Object *obj, const char *name)

void AG_InitUint32 (AG_Variable *var, Uint32 val)

AG_Variable * AG_SetUint32 (AG_Object *obj, const char *name, Uint32 val)

AG_Variable * AG_BindUint32 (AG_Object *obj, const char *name, Uint32 *pVal)

AG_Variable * AG_BindUint32Mp (AG_Object *obj, const char *name, Uint32 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindUint32Fn (AG_Object *obj, const char *name, Uint32 (*fn)(AG_Event *))

Sint32 AG_GetSint32 (AG_Object *obj, const char *name)

void AG_InitSint32 (AG_Variable *var, Sint32 val)

AG_Variable * AG_SetSint32 (AG_Object *obj, const char *name, Sint32 val)

AG_Variable * AG_BindSint32 (AG_Object *obj, const char *name, Sint32 *pVal)

AG_Variable * AG_BindSint32Mp (AG_Object *obj, const char *name, Sint32 *pVal, AG_Mutex *lock)

AG_Variable * AG_BindSint32Fn (AG_Object *obj, const char *name, Sint32 (*fn)(AG_Event *))


These functions provide an interface to primitive integer types.

REAL NUMBERS


float AG_GetFloat (AG_Object *obj, const char *name)

void AG_InitFloat (AG_Variable *var, float val)

AG_Variable * AG_SetFloat (AG_Object *obj, const char *name, float val)

AG_Variable * AG_BindFloat (AG_Object *obj, const char *name, float *pVal)

AG_Variable * AG_BindFloatMp (AG_Object *obj, const char *name, float *pVal, AG_Mutex *lock)

AG_Variable * AG_BindFloatFn (AG_Object *obj, const char *name, float (*fn)(AG_Event *))

double AG_GetDouble (AG_Object *obj, const char *name)

void AG_InitDouble (AG_Variable *var, double val)

AG_Variable * AG_SetDouble (AG_Object *obj, const char *name, double val)

AG_Variable * AG_BindDouble (AG_Object *obj, const char *name, double *pVal)

AG_Variable * AG_BindDoubleMp (AG_Object *obj, const char *name, double *pVal, AG_Mutex *lock)

AG_Variable * AG_BindDoubleFn (AG_Object *obj, const char *name, double (*fn)(AG_Event *))


These functions provide an interface to primitive floating-point types.

C STRINGS


size_t AG_GetString (AG_Object *obj, const char *name, char *dst, size_t dst_size)

char * AG_GetStringDup (AG_Object *obj, const char *name)

char * AG_GetStringP (AG_Object *obj, const char *name)

void AG_InitString (AG_Variable *var, const char *s)

void AG_InitStringNODUP (AG_Variable *var, const char *s)

void AG_InitStringFixed (AG_Variable *var, char *s, size_t len)

AG_Variable * AG_SetString (AG_Object *obj, const char *name, const char *s)

AG_Variable * AG_SetStringNODUP (AG_Object *obj, const char *name, const char *s)

AG_Variable * AG_PrtString (AG_Object *obj, const char *name, const char *fmt, ...)

AG_Variable * AG_SetStringFixed (AG_Object *obj, const char *name, char *s, size_t len)

AG_Variable * AG_BindString (AG_Object *obj, const char *name, char *s, size_t len)

AG_Variable * AG_BindStringMp (AG_Object *obj, const char *name, char *s, size_t len, AG_Mutex *lock)

AG_Variable * AG_BindStringFn (AG_Object *obj, const char *name, size_t (*fn)(AG_Event *, char *, size_t))

AG_Variable * AG_SetConstString (AG_Object *obj, const char *name, const char *s)

AG_Variable * AG_BindConstString (AG_Object *obj, const char *name, const char **s)

AG_Variable * AG_BindConstStringMp (AG_Object *obj, const char *name, const char **s, AG_Mutex *lock)


These functions provide an interface to variable-length and fixed-length C strings. A string variable can reference an internal, statically-defined string (see AG_SetString()), or an external fixed-size buffer containing a valid C string (see AG_BindString()). It is also possible to have a string variable defined by a function (see AG_BindStringFn()).

AG_GetString() returns the contents of a string variable. The string is safely copied to fixed-size buffer dst, of size dst_size. The return value is the number of bytes that would have been copied, were dst_size unlimited.

AG_GetStringDup() returns a newly-allocated copy of the string variable. If the string cannot be allocated, NULL is returned.

The AG_GetStringP() function returns a direct pointer to the buffer containing the string. If the given variable is function-defined (i.e., it was set by AG_BindStringFn()), the value generated by the last AG_EvalVariable() operation is returned. Note that AG_GetStringP() is NOT free-threaded: safely accessing the string requires that the application calls AG_LockVariable(). As an exception to this rule, static strings (i.e., strings set by AG_SetString()) may be considered safe to access without locking, as long as the string variable's parent object is locked.

AG_InitString() initializes a AG_Variable structure with the given string, which is copied from s. The AG_InitStringNODUP() variant sets the s pointer without copying the string. The AG_InitStringFixed() variant initializes a string variable to use a fixed-size buffer s, of size len.

AG_SetString() sets the named string variable to the given string s. The argument may be set to NULL (in which case further AG_GetString() calls will return NULL).

The AG_SetStringNODUP() variant is NOT free-threaded: it uses the s pointer directly without copying the string, assuming the pointer will remain valid for as long as the variable exists.

The AG_PrtString() variant sets a string variable from a format string argument.

The AG_SetStringFixed() function creates or modifies a string variable, tied to a fixed-size string buffer s, of size len.

AG_BindString() creates or modifies a variable referencing a fixed-size string buffer s, of size len. The AG_BindStringFn() variant ties the variable to a function fn.

GENERIC POINTERS


void * AG_GetPointer (AG_Object *obj, const char *name)

void AG_InitPointer (AG_Variable *var, void *val)

AG_Variable * AG_SetPointer (AG_Object *obj, const char *name, void *val)

AG_Variable * AG_BindPointer (AG_Object *obj, const char *name, void **pVal)

AG_Variable * AG_BindPointerMp (AG_Object *obj, const char *name, void **pVal, AG_Mutex *lock)

AG_Variable * AG_BindPointerFn (AG_Object *obj, const char *name, void *(*fn)(AG_Event *))

const void * AG_GetConstPointer (AG_Object *obj, const char *name)

void AG_InitConstPointer (AG_Variable *var, const void *val)

AG_Variable * AG_SetConstPointer (AG_Object *obj, const char *name, const void *val)

AG_Variable * AG_BindConstPointer (AG_Object *obj, const char *name, const void **pVal)

AG_Variable * AG_BindConstPointerMp (AG_Object *obj, const char *name, const void **pVal, AG_Mutex *lock)

AG_Variable * AG_BindConstPointerFn (AG_Object *obj, const char *name, const void *(*fn)(AG_Event *))


These functions provide an interface to generic pointer types.

BITS


AG_Variable * AG_BindFlag (AG_Object *obj, const char *name, Uint *pVal, Uint bitmask)

AG_Variable * AG_BindFlagMp (AG_Object *obj, const char *name, Uint *pVal, Uint bitmask, AG_Mutex *lock)

AG_Variable * AG_BindFlag8 (AG_Object *obj, const char *name, Uint8 *pVal, Uint8 bitmask)

AG_Variable * AG_BindFlag8Mp (AG_Object *obj, const char *name, Uint8 *pVal, Uint8 bitmask, AG_Mutex *lock)

AG_Variable * AG_BindFlag16 (AG_Object *obj, const char *name, Uint16 *pVal, Uint16 bitmask)

AG_Variable * AG_BindFlag16Mp (AG_Object *obj, const char *name, Uint16 *pVal, Uint16 bitmask, AG_Mutex *lock)

AG_Variable * AG_BindFlag32 (AG_Object *obj, const char *name, Uint32 *pVal, Uint32 bitmask)

AG_Variable * AG_BindFlag32Mp (AG_Object *obj, const char *name, Uint32 *pVal, Uint32 bitmask, AG_Mutex *lock)


These functions provide an interface for binding to specific bits in integers. They follow the standard form, with an extra bitmask argument.

STRUCTURE DATA

The AG_Variable structure is defined as follows:
typedef struct ag_variable {
	char name[AG_VARIABLE_NAME_MAX]; /* Variable name */
	AG_VariableType type;            /* Variable type */
	AG_Mutex *mutex;                 /* Lock on data (or NULL) */
	union {
		Uint32 bitmask;          /* Bitmask (for P_FLAG_*) */
		size_t size;             /* Size (for STRING_*) */
	} info;
	union ag_variable_fn fn;
	union ag_variable_data data;
} AG_Variable;
typedef enum ag_variable_type {
	AG_VARIABLE_NULL,		/* No data */
	/* Primitive */
	AG_VARIABLE_UINT,		/* Unsigned int */
	AG_VARIABLE_P_UINT,		/* Pointer to Uint */
	AG_VARIABLE_INT,		/* Natural int */
	AG_VARIABLE_P_INT,		/* Pointer to int */
	AG_VARIABLE_UINT8,		/* Unsigned 8-bit */
	AG_VARIABLE_P_UINT8,		/* Pointer to Uint8 */
	AG_VARIABLE_SINT8,		/* Signed 8-bit */
	AG_VARIABLE_P_SINT8,		/* Pointer to Sint8 */
	AG_VARIABLE_UINT16,		/* Unsigned 16-bit */
	AG_VARIABLE_P_UINT16,		/* Pointer to Uint16 */
	AG_VARIABLE_SINT16,		/* Signed 16-bit */
	AG_VARIABLE_P_SINT16,		/* Pointer to Sint16 */
	AG_VARIABLE_UINT32,		/* Unsigned 32-bit */
	AG_VARIABLE_P_UINT32,		/* Pointer to Uint32 */
	AG_VARIABLE_SINT32,		/* Signed 32-bit */
	AG_VARIABLE_P_SINT32,		/* Pointer to Sint32 */
	AG_VARIABLE_UINT64,		/* Unsigned 64-bit (opt.) */
	AG_VARIABLE_P_UINT64,		/* Pointer to Uint64 (opt.) */
	AG_VARIABLE_SINT64,		/* Signed 64-bit (opt.) */
	AG_VARIABLE_P_SINT64,		/* Pointer to Sint64 (opt.) */
	AG_VARIABLE_FLOAT,		/* Single-precision float */
	AG_VARIABLE_P_FLOAT,		/* Pointer to float */
	AG_VARIABLE_DOUBLE,		/* Double-precision float */
	AG_VARIABLE_P_DOUBLE,		/* Pointer to double */
	AG_VARIABLE_LONG_DOUBLE,	/* Quad-precision float (opt.) */
	AG_VARIABLE_P_LONG_DOUBLE,	/* Pointer to long double (opt.) */
	AG_VARIABLE_STRING,		/* C string */
	AG_VARIABLE_P_STRING,		/* Pointer to C string */
	AG_VARIABLE_CONST_STRING,	/* C string (const) */
	AG_VARIABLE_P_CONST_STRING,	/* Pointer to C string (const) */
	AG_VARIABLE_POINTER,		/* C pointer */
	AG_VARIABLE_P_POINTER,		/* Pointer to C pointer */
	AG_VARIABLE_CONST_POINTER,	/* C pointer (const) */
	AG_VARIABLE_P_CONST_POINTER, 	/* Pointer to C pointer (const) */
	/* Bitmask */
	AG_VARIABLE_P_FLAG,		/* Bit in int (uses info.mask) */
	AG_VARIABLE_P_FLAG8,		/* Bit in int8 (uses info.mask) */
	AG_VARIABLE_P_FLAG16,		/* Bit in int16 (uses info.mask) */
	AG_VARIABLE_P_FLAG32,		/* Bit in int32 (uses info.mask) */
	/* ... */
	AG_VARIABLE_TYPE_LAST
};
union ag_variable_data {
	void *p;
	const void *Cp;
	char *s;
	const char *Cs;
	int i;
	Uint u;
	float flt;
	double dbl;
	Uint8 u8;
	Sint8 s8;
	Uint16 u16;
	Sint16 s16;
	Uint32 u32;
	Sint32 s32;
};

The name string identifies the variable when it is part of a set, such as the AG_Object(3) property table or a list of named AG_Event(3) arguments. The type field indicates the type of variable.

The optional mutex specifies a mutex device that any user of the variable should acquire prior to accessing data (only applies to pointer-type variables).

bitmask and size are extra arguments needed by BITMASK_* and STRING_* type variables, respectively.

fn, if not NULL, ties the variable to a function. Whenever the variable is accessed, this function will be invoked by AG_EvalVariable() to return the data in the AG_Variable structure itself. fn is an union of function pointers such as fnVoid(), fnUint(), fnInt(), etc. The functions are defined as:


TYPE fnTYPE (AG_Event *event)



with the exception of fnString(), which expects the string to be copied to a fixed-size buffer, and is defined as:


size_t fnString (AG_Event *event, char *buffer, size_t length)



The data union contains the primitive data itself.

SEE ALSO

AG_Intro(3), AG_Object(3), AG_List(3), AG_Tree(3), AG_Tbl(3)

HISTORY

The AG_Variable interface first appeared in Agar 1.3.4. It replaced, notably, the AG_Prop(3) interface and widget bindings at the AG_Widget(3) level which had both been using different structures.