/* namespace.c -- Copyright 1994 Liam R. Quin.  All Rights Reserved.
 * This code is NOT in the public domain.
 * See the file COPYRIGHT for full details.
 */

/* $Id$ */

#include "globals.h"
#include "error.h"

#include <stdio.h>
#include <ctype.h>

#include <sys/types.h>
#include <sys/stat.h>

#include "lqutil.h"

typedef unsigned short t_VariableFlag : 1;

typedef struct s_VariableType {
} t_VariableType;

typedef struct s_MetaVariable {
    char *Name;
    t_VariableType *Type;
    char *Description;
    t_Options *Options;
    t_VariableFlag IsReadOnly; /* sets the default at creation time */
    t_VariableFlag UseOnceOnly; /* only for creation */
} t_MetaVariable;

typedef enum {
    LQT_BVT_ILLEGAL_TYPE,
    LQT_BVT_INT,
    LQT_BVT_U_INT,
    LQT_BVT_LONG,
    LQT_BVT_U_LONG,
    LQT_BVT_STRING,
    LQT_BVT_NAMESPACE
} t_VariableBaseValueType;

typedef union {
    int Int;
    int UInt;
    long Long;
    unsigned long ULong;
    char *String;
    struct s_NameSpace *NameSpace;
} t_VariableValue;

typedef struct s_InstanceVariable {
    t_MetaVariable *MetaVariable;
    struct s_InstanceVariable *SetBy;
    t_VariableFlag IsReadOnly; /* if set, overrides base type */
    t_VariableFlag UseOnceOnly;
    t_VariableFlag IsValid;
    t_VariableFlag FreeWhenInvalidated; /* for string and namespace */
} t_InstanceVariable;

/* A container for lots of variables */
typedef struct s_NameSpace {
} t_NameSpace;

/* operations on name spaces and variables */

LQU_ForEachVariable(NameSpace)
LQU_GetVariableByName(NameSpace, Name)

LQU_InvalidateAllVariables(NameSpace)
LQU_DeleteVariable(NameSpace, Variable)

LQU_GetVariableValue(Variable)
/*VARARGS*/ LQU_SetVariableValue(Variable, NewValue) /* also validates it */

LQU_InvalidateVariable(Variable)

LQU_VariableHasType(Variable, Type)

/* some macros */

LQU_SET_VARIABLE_INT(Variable, Int) Variable->Value.Int
LQU_SET_VARIABLE_U_INT(Variable, UInt) Variable->Value.UInt
LQU_SET_VARIABLE_LONG(Variable, Long) Variable->Value.Long
LQU_SET_VARIABLE_U_LONG(Variable, ULong) Variable->Value.ULong

#define LQUpBVT_CK(V,T) ((V)->Type->BaseType == T)
#define LQUpBVT_TE(V,T) \
    Error(E_FATAL|E_BUG,
	"%s: %d: Attempted to retrieve type %s from variable %s (type %s)",
	__FILE__, __LINE__
	TypeDescriptions[T], /* NOTDONE */
	TypeDescriptions[(V)->Type->BaseType]
    );

#define LQU_GET_VARIABLINT(Variable) \
	LQUpBVT_CK(V,LQU_BVT_INT) ? Variable->Value.Int : E(V,T)
#define LQU_GET_VARIABLU_INT(Variable) \
	LQUpBVT_CK(V,LQU_BVT_U_INT) ? Variable->Value.UInt : E(V,T)
#define LQU_GET_VARIABLLONG(Variable) \
	LQUpBVT_CK(V,LQU_BVT_LONG) ? Variable->Value.Long : E(V,T)
#define LQU_GET_VARIABLU_LONG(Variable) \
	LQUpBVT_CK(V,LQU_BVT_U_LONG) ? Variable->Value.ULong : E(V,T)
#define LQU_GET_VARIABLSTRING(Variable) \
	LQUpBVT_CK(V,LQU_BVT_STRING) ? Variable->Value.String : E(V,T)

