30 #define DISABLE_DEBUGLOG
33 #include <gwenhywfar/misc.h>
34 #include <gwenhywfar/debug.h>
35 #include <gwenhywfar/path.h>
36 #include <gwenhywfar/text.h>
37 #include <gwenhywfar/dbio.h>
38 #include <gwenhywfar/fslock.h>
39 #include <gwenhywfar/fastbuffer.h>
40 #include <gwenhywfar/syncio_file.h>
41 #include <gwenhywfar/syncio_memory.h>
49 #include <sys/types.h>
50 #ifdef HAVE_SYS_STAT_H
51 # include <sys/stat.h>
61 #define GWEN_DB_NODE_FLAGS_MASK_INTERNAL 0xf0000000
62 #define GWEN_DB_NODE_FLAGS_GROUP 0x80000000
82 unsigned int datasize) {
90 assert(n->data.dataBin);
91 memmove(n->data.dataBin, data, datasize);
102 n->data.dataInt=data;
125 n->data.dataPtr=data;
140 n->children=GWEN_DB_Node_List_new();
155 n->children=GWEN_DB_Node_List_new();
167 assert(parent->children!=
NULL);
168 GWEN_DB_Node_List_Add(n, parent->children);
191 assert(parent->children!=
NULL);
192 GWEN_DB_Node_List_Insert(n, parent->children);
219 GWEN_DB_Node_List_Del(n);
246 GWEN_DB_Node_List_free(n->children);
253 if (n->data.dataName) {
254 int l=strlen(n->data.dataName);
256 memset(n->data.dataName, 0, l);
262 if (n->data.dataChar) {
263 int l=strlen(n->data.dataChar);
265 memset(n->data.dataChar, 0, l);
270 if (n->data.dataBin && n->dataSize) {
271 memset(n->data.dataBin, 0, n->dataSize);
276 n->data.dataPtr=
NULL;
349 cn=GWEN_DB_Node_List_First(n->children);
360 cn=GWEN_DB_Node_List_Next(cn);
395 nn=GWEN_DB_Node_List_First(n->children);
399 nn=GWEN_DB_Node_List_Next(nn);
412 n=GWEN_DB_Node_List_Next(n);
416 n=GWEN_DB_Node_List_Next(n);
432 nn=GWEN_DB_Node_List_First(n->children);
436 nn=GWEN_DB_Node_List_Next(nn);
449 n=GWEN_DB_Node_List_Next(n);
453 n=GWEN_DB_Node_List_Next(n);
469 nn=GWEN_DB_Node_List_First(n->children);
475 nn=GWEN_DB_Node_List_Next(nn);
490 n=GWEN_DB_Node_List_Next(n);
496 n=GWEN_DB_Node_List_Next(n);
523 return n->data.dataChar;
552 return n->data.dataInt;
556 if (sscanf(p,
"%d", &res)!=1) {
571 unsigned int *size) {
580 return n->data.dataBin;
600 nn=GWEN_DB_Node_List_First(n->children);
603 if (strcasecmp(nn->data.dataName, name)==0) {
610 nn=GWEN_DB_Node_List_Next(nn);
633 nn=GWEN_DB_Node_List_First(n->children);
636 if (strcasecmp(nn->data.dataName, name)==0) {
643 nn=GWEN_DB_Node_List_Next(nn);
669 (!(flags & GWEN_PATH_FLAGS_VARIABLE) &&
682 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
684 "Unconditionally creating variable \"%s\"", entry);
694 "Unconditionally creating group \"%s\"", entry);
705 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
715 (!(flags & GWEN_PATH_FLAGS_LAST) &&
719 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
721 "Variable \"%s\" does not exist", entry);
725 "Group \"%s\" does not exist", entry);
735 if (flags & GWEN_PATH_FLAGS_VARIABLE) {
737 "Variable \"%s\" not found, creating", entry);
746 "Group \"%s\" not found, creating", entry);
757 ((flags & GWEN_PATH_FLAGS_LAST) &&
759 (!(flags & GWEN_PATH_FLAGS_LAST) &&
786 GWEN_DB_Node_List_Clear(n->children);
809 assert(nn->children);
810 nn=GWEN_DB_Node_List_First(nn->children);
818 nn=GWEN_DB_Node_List_Next(nn);
900 const char *defVal) {
906 "Value for \"%s\" not found, returning default value",
913 "Bad type for path \"%s\", returning default value",
917 return nn->data.dataChar;
953 "Added char value \"%s\" to variable \"%s\"", val, path);
983 assert(nv->data.dataChar);
985 res=strcasecmp(nv->data.dataChar, val)==0;
987 res=strcmp(nv->data.dataChar, val)==0;
990 "Value \"%s\" of var \"%s\" already exists",
1000 "Added char value \"%s\" to variable \"%s\"", val, path);
1028 assert(nv->data.dataChar);
1030 res=strcasecmp(nv->data.dataChar, val)==0;
1032 res=strcmp(nv->data.dataChar, val)==0;
1035 "Value \"%s\" of var \"%s\" already exists",
1060 "Value[%d] for \"%s\" not found, returning default value",
1067 return nn->data.dataInt;
1069 p=nn->data.dataChar;
1071 if (sscanf(p,
"%d", &res)!=1) {
1073 "String [%s] in node is not an int value", p);
1124 unsigned int defValSize,
1125 unsigned int *returnValueSize) {
1128 assert(returnValueSize);
1132 "Value for \"%s\" not found, returning default value",
1134 *returnValueSize=defValSize;
1140 "Bad type for path \"%s\", returning default value",
1142 *returnValueSize=defValSize;
1145 *returnValueSize=nn->dataSize;
1146 return nn->data.dataBin;
1155 unsigned int valSize) {
1196 "Value for \"%s\" not found, returning default value",
1203 "Bad type for path \"%s\", returning default value",
1207 return nn->data.dataPtr;
1292 return n->data.dataName;
1301 for (i=0; i<insert; i++)
1302 fprintf(stderr,
" ");
1307 fprintf(stderr,
"Group : \"%s\"\n", n->data.dataName);
1310 fprintf(stderr,
"Var : \"%s\"\n", n->data.dataName);
1313 fprintf(stderr,
"Value : \"%s\" (char)\n", n->data.dataChar);
1316 fprintf(stderr,
"Value : %d (int)\n", n->data.dataInt);
1324 buffer, (n->dataSize*2)+1)==0) {
1325 fprintf(stderr,
"Value : %d bytes (bin)\n", n->dataSize);
1328 fprintf(stderr,
"Value : %s (bin)\n", buffer);
1334 fprintf(stderr,
"Value : %p (ptr)\n", n->data.dataPtr);
1337 fprintf(stderr,
"[unknown node type %d]\n", n->typ);
1344 cn=GWEN_DB_Node_List_First(n->children);
1347 cn=GWEN_DB_Node_List_Next(cn);
1352 fprintf(stderr,
"[no node]\n");
1415 nn=GWEN_DB_Node_List_First(nn->children);
1420 nn=GWEN_DB_Node_List_Next(nn);
1540 res=(*func)(iter, user_data);
1552 unsigned int *a = user_data;
1560 unsigned int res = 0;
1578 res=(*func)(iter, user_data);
1590 unsigned int res = 0;
1608 res=(*func)(iter, user_data);
1620 unsigned int res = 0;
1629 return n->nodeFlags;
1651 flags=((flags^newflags)&(mask))^flags;
1668 flags=((flags^newflags)&(mask))^flags;
1671 cn=GWEN_DB_Node_List_First(n->children);
1674 cn=GWEN_DB_Node_List_Next(cn);
1700 nn=GWEN_DB_Node_List_First(n->children);
1705 nn=GWEN_DB_Node_List_Next(nn);
1742 nn=GWEN_DB_Node_List_First(n->children);
1747 nn=GWEN_DB_Node_List_Next(nn);
1782 return n->data.dataName;
1813 while(*p && *p!=
')')
1822 const char *valueString;
1832 name=(
char*) malloc(len+1);
1834 memmove(name, pStart, len);
1879 while(*p && *p!=
'#') {
1888 else if (*p==
'\\') {
1890 if (tolower(p[1])==
'n') {
1894 else if (tolower(p[1])==
't') {
1898 else if (tolower(p[1])==
'\\') {
int GWEN_DB_ReplaceVars(GWEN_DB_NODE *db, const char *s, GWEN_BUFFER *dbuf)
GWEN_DB_NODE * GWEN_DB_GetValue(GWEN_DB_NODE *n, const char *path, int idx)
#define GWEN_DB_FLAGS_OVERWRITE_VARS
void GWEN_DB_ModifyBranchFlagsUp(GWEN_DB_NODE *n, uint32_t newflags, uint32_t mask)
void GWEN_DB_Dump(GWEN_DB_NODE *n, int insert)
void * GWEN_DB_Groups_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
struct GWEN_DB_NODE GWEN_DB_NODE
#define GWEN_DB_FLAGS_INSERT
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
#define GWEN_ERROR_INVALID
void GWEN_DB_ClearNode(GWEN_DB_NODE *n)
char * GWEN_Memory_strdup(const char *s)
GWEN_DB_NODE * GWEN_DB_ValuePtr_new(void *data)
uint32_t GWEN_DB_GetNodeFlags(const GWEN_DB_NODE *n)
#define GWEN_FREE_OBJECT(varname)
void GWEN_Memory_dealloc(void *p)
#define GWEN_PATH_FLAGS_CREATE_GROUP
void *(* GWEN_DB_NODES_CB)(GWEN_DB_NODE *node, void *user_data)
#define DBG_VERBOUS(dbg_logger, format, args...)
GWEN_DB_NODE * GWEN_DB_GetNextValue(GWEN_DB_NODE *n)
void GWEN_DB_GroupRename(GWEN_DB_NODE *n, const char *newname)
void GWEN_DB_Node_Append_UnDirty(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
unsigned int GWEN_DB_Groups_Count(const GWEN_DB_NODE *node)
#define DBG_WARN(dbg_logger, format, args...)
void GWEN_DB_ModifyBranchFlagsDown(GWEN_DB_NODE *n, uint32_t newflags, uint32_t mask)
int GWEN_DB_ValueExists(GWEN_DB_NODE *n, const char *path, unsigned int i)
int GWEN_DB_SetPtrValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, void *val)
GWEN_DB_NODE * GWEN_DB_ValueBin_new(const void *data, unsigned int datasize)
#define GWEN_PATH_FLAGS_LAST
GWEN_DB_NODE * GWEN_DB_Node_dup(const GWEN_DB_NODE *n)
int GWEN_DB_InsertGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
GWEN_DB_NODE * GWEN_DB_GetNode(GWEN_DB_NODE *n, const char *path, uint32_t flags)
#define GWEN_ERROR_BAD_DATA
int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
#define GWEN_PATH_FLAGS_NAMEMUSTNOTEXIST
GWEN_DB_NODE * GWEN_DB_GetFirstVar(GWEN_DB_NODE *n)
GWEN_DB_NODE_TYPE GWEN_DB_GetVariableType(GWEN_DB_NODE *n, const char *p)
int GWEN_DB_IsVariable(const GWEN_DB_NODE *n)
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const void *val, unsigned int valSize)
void GWEN_DB_Node_free(GWEN_DB_NODE *n)
void GWEN_DB_VariableRename(GWEN_DB_NODE *n, const char *newname)
#define GWEN_NEW_OBJECT(typ, varname)
void GWEN_DB_Node_Unlink_UnDirty(GWEN_DB_NODE *n)
#define DBG_DEBUG(dbg_logger, format, args...)
const char * GWEN_DB_GroupName(GWEN_DB_NODE *n)
void GWEN_DB_Node_Append(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
int GWEN_DB_DeleteGroup(GWEN_DB_NODE *n, const char *path)
#define GWEN_DB_FLAGS_OVERWRITE_GROUPS
#define GWEN_PATH_FLAGS_VARIABLE
#define GWEN_DB_NODE_FLAGS_SAFE
void * GWEN_Memory_malloc(size_t wsize)
const void * GWEN_DB_GetBinValue(GWEN_DB_NODE *n, const char *path, int idx, const void *defVal, unsigned int defValSize, unsigned int *returnValueSize)
void GWEN_DB_Node_InsertUnDirty(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_GetNextGroup(GWEN_DB_NODE *n)
void * GWEN_DB_GetPtrValue(GWEN_DB_NODE *n, const char *path, int idx, void *defVal)
const void * GWEN_DB_GetBinValueFromNode(const GWEN_DB_NODE *n, unsigned int *size)
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
GWEN_DB_NODE * GWEN_DB_Group_dup(const GWEN_DB_NODE *n)
const char * GWEN_DB_VariableName(GWEN_DB_NODE *n)
int GWEN_DB_IsValue(const GWEN_DB_NODE *n)
int GWEN_DB_VariableExists(GWEN_DB_NODE *n, const char *path)
GWEN_DB_NODE * GWEN_DB_FindNextVar(GWEN_DB_NODE *n, const char *name)
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
GWEN_DB_NODE * GWEN_DB_ValueChar_new(const char *data)
GWEN_DB_NODE * GWEN_DB_FindGroup(GWEN_DB_NODE *n, const char *name, int idx)
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
GWEN_DB_NODE * GWEN_DB_Node_new(GWEN_DB_NODE_TYPE t)
#define GWEN_DB_NODE_FLAGS_DIRTY
int GWEN_Text_NumToString(int num, char *buffer, unsigned int bufsize, int fillchar)
#define GWEN_PATH_FLAGS_PATHCREATE
#define GWEN_PATH_FLAGS_CREATE_VAR
#define GWEN_PATH_FLAGS_PATHMUSTNOTEXIST
#define DBG_ERROR(dbg_logger, format, args...)
void GWEN_DB_Node_Unlink(GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_FindFirstVar(GWEN_DB_NODE *n, const char *name)
char * GWEN_Text_ToHex(const char *src, unsigned l, char *buffer, unsigned int maxsize)
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
unsigned int GWEN_DB_Variables_Count(const GWEN_DB_NODE *node)
void * GWEN_DB_HandlePath(const char *entry, void *data, int idx, uint32_t flags)
GWEN_DB_NODE * GWEN_DB_GetFirstValue(GWEN_DB_NODE *n)
#define GWEN_PATH_FLAGS_PATHMUSTEXIST
GWEN_DB_NODE_TYPE GWEN_DB_GetValueTypeByPath(GWEN_DB_NODE *n, const char *path, unsigned int i)
int GWEN_DB_IsGroup(const GWEN_DB_NODE *n)
#define DBG_INFO(dbg_logger, format, args...)
int GWEN_DB_AddCharValue(GWEN_DB_NODE *n, const char *path, const char *val, int senseCase, int check)
GWEN_DB_NODE * GWEN_DB_GetNextVar(GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_FindVar(GWEN_DB_NODE *n, const char *name, int idx)
void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n)
void * GWEN_DB_count_cb(GWEN_UNUSED GWEN_DB_NODE *node, void *user_data)
#define GWEN_LIST_INIT(t, element)
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
GWEN_DB_NODE * GWEN_DB_GetParentGroup(GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_FindFirstGroup(GWEN_DB_NODE *n, const char *name)
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
GWEN_DB_NODE * GWEN_DB_GetFirstGroup(GWEN_DB_NODE *n)
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
#define GWEN_LIST_FUNCTIONS(t, pr)
void * GWEN_Path_HandleWithIdx(const char *path, void *data, uint32_t flags, GWEN_PATHIDXHANDLERPTR elementFunction)
int GWEN_DB_GetIntValueFromNode(const GWEN_DB_NODE *n)
int GWEN_DB_RemoveCharValue(GWEN_DB_NODE *n, const char *path, const char *val, int senseCase)
void * GWEN_DB_Variables_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
int GWEN_DB_ClearGroup(GWEN_DB_NODE *n, const char *path)
int GWEN_DB_AddGroupChildren(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
#define GWEN_PATH_FLAGS_NAMEMUSTEXIST
int GWEN_DB_SetCharValueInNode(GWEN_DB_NODE *n, const char *s)
GWEN_DB_NODE * GWEN_DB_FindNextGroup(GWEN_DB_NODE *n, const char *name)
#define GWEN_LIST_FINI(t, element)
void * GWEN_DB_Values_Foreach(GWEN_DB_NODE *node, GWEN_DB_NODES_CB func, void *user_data)
GWEN_DB_NODE * GWEN_DB_ValueInt_new(int data)
void GWEN_DB_SetNodeFlags(GWEN_DB_NODE *n, uint32_t flags)
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
#define GWEN_DB_FLAGS_DEFAULT
void GWEN_DB_Node_Insert(GWEN_DB_NODE *parent, GWEN_DB_NODE *n)
GWEN_DB_NODE_TYPE GWEN_DB_GetValueType(GWEN_DB_NODE *n)
GWEN_DB_NODE * GWEN_DB_Var_new(const char *name)
unsigned int GWEN_DB_Values_Count(const GWEN_DB_NODE *node)
const char * GWEN_DB_GetCharValueFromNode(const GWEN_DB_NODE *n)