684 lines
16 KiB
C
684 lines
16 KiB
C
/****************************************************************************
|
|
* This file is part of the project AqHome.
|
|
* AqHome (c) by 2024 Martin Preuss, all rights reserved.
|
|
*
|
|
* The license for this file can be found in the file COPYING which you
|
|
* should have received along with this file.
|
|
****************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
|
|
|
|
#include "./vars_p.h"
|
|
#include "aqhome/data/path.h"
|
|
|
|
#include <gwenhywfar/misc.h>
|
|
#include <gwenhywfar/debug.h>
|
|
#include <gwenhywfar/buffer.h>
|
|
#include <gwenhywfar/text.h>
|
|
|
|
|
|
|
|
GWEN_TREE2_FUNCTIONS(AQH_VARS, AQH_Vars);
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static AQH_VARS *_newData(void);
|
|
static void _releaseData(AQH_VARS *vt);
|
|
static AQH_VARS *_newStringElement(char *s, AQH_VARS_DATATYPE dt);
|
|
static AQH_VARS *_getValueNodeByIdx(const AQH_VARS *vt, int idx);
|
|
static AQH_VARS *_getPath(AQH_VARS *vt, const char *s, uint32_t flags);
|
|
static void *_pathHandlerFn(const char *entry, void *data, int idx, uint32_t flags);
|
|
static AQH_VARS *_getNodeByTypeAndName(const AQH_VARS *vt, AQH_VARS_DATATYPE dt, const char *name, int idx);
|
|
static void _dumpElement(const AQH_VARS *vt, int indent, GWEN_BUFFER *dbuf);
|
|
static int GWENHYWFAR_CB _replaceVarsCb(void *cbPtr, const char *name, int index, int maxLen, GWEN_BUFFER *dstBuf);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* implementations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
AQH_VARS *_newData(void)
|
|
{
|
|
AQH_VARS *vt;
|
|
|
|
GWEN_NEW_OBJECT(AQH_VARS, vt);
|
|
GWEN_TREE2_INIT(AQH_VARS, vt, AQH_Vars);
|
|
return vt;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *_newStringElement(char *s, AQH_VARS_DATATYPE dt)
|
|
{
|
|
AQH_VARS *vt;
|
|
|
|
vt=_newData();
|
|
vt->data.dataString=s;
|
|
vt->dataType=dt;
|
|
|
|
return vt;
|
|
}
|
|
|
|
|
|
|
|
|
|
void _releaseData(AQH_VARS *vt)
|
|
{
|
|
if (vt) {
|
|
switch(vt->dataType) {
|
|
case AQH_Vars_DataType_Group:
|
|
case AQH_Vars_DataType_Variable:
|
|
case AQH_Vars_DataType_ValueString:
|
|
free(vt->data.dataString);
|
|
vt->data.dataString=NULL;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
vt->dataType=AQH_Vars_DataType_Unknown;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *_dupData(const AQH_VARS *vt)
|
|
{
|
|
if (vt) {
|
|
AQH_VARS *vtCopy;
|
|
|
|
vtCopy=_newData();
|
|
vtCopy->dataType=vt->dataType;
|
|
switch(vt->dataType) {
|
|
case AQH_Vars_DataType_Unknown:
|
|
break;
|
|
case AQH_Vars_DataType_Group:
|
|
case AQH_Vars_DataType_Variable:
|
|
case AQH_Vars_DataType_ValueString:
|
|
vtCopy->data.dataString=(vt->data.dataString)?strdup(vt->data.dataString):NULL;
|
|
break;
|
|
case AQH_Vars_DataType_ValueInt:
|
|
vtCopy->data.dataInt=vt->data.dataInt;
|
|
break;
|
|
case AQH_Vars_DataType_ValueDouble:
|
|
vtCopy->data.dataDouble=vt->data.dataDouble;
|
|
break;
|
|
}
|
|
|
|
return vtCopy;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
void AQH_Vars_free(AQH_VARS *vt)
|
|
{
|
|
if (vt) {
|
|
GWEN_TREE2_FINI(AQH_VARS, vt, AQH_Vars);
|
|
_releaseData(vt);
|
|
GWEN_FREE_OBJECT(vt);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS_DATATYPE AQH_Vars_DataTypeFromString(const char *s)
|
|
{
|
|
if (s && *s) {
|
|
if (strcasecmp(s, "group")==0)
|
|
return AQH_Vars_DataType_Group;
|
|
else if (strcasecmp(s, "variable")==0)
|
|
return AQH_Vars_DataType_Variable;
|
|
else if (strcasecmp(s, "char")==0)
|
|
return AQH_Vars_DataType_ValueString;
|
|
else if (strcasecmp(s, "int")==0)
|
|
return AQH_Vars_DataType_ValueInt;
|
|
else if (strcasecmp(s, "double")==0)
|
|
return AQH_Vars_DataType_ValueDouble;
|
|
}
|
|
return AQH_Vars_DataType_Unknown;
|
|
}
|
|
|
|
|
|
|
|
const char *AQH_Vars_DataTypeToString(AQH_VARS_DATATYPE dt)
|
|
{
|
|
switch(dt) {
|
|
case AQH_Vars_DataType_Unknown: break;
|
|
case AQH_Vars_DataType_Group: return "group";
|
|
case AQH_Vars_DataType_Variable: return "variable";
|
|
case AQH_Vars_DataType_ValueString: return "char";
|
|
case AQH_Vars_DataType_ValueInt: return "int";
|
|
case AQH_Vars_DataType_ValueDouble: return "double";
|
|
}
|
|
|
|
return "unknown";
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_dup(const AQH_VARS *vt)
|
|
{
|
|
AQH_VARS *vtCopy;
|
|
AQH_VARS *vtChild;
|
|
|
|
vtCopy=_dupData(vt);
|
|
vtChild=AQH_Vars_Tree2_GetFirstChild(vt);
|
|
while(vtChild) {
|
|
AQH_Vars_Tree2_AddChild(vtCopy, _dupData(vtChild));
|
|
vtChild=AQH_Vars_Tree2_GetNext(vtChild);
|
|
}
|
|
|
|
return vtCopy;
|
|
}
|
|
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_CreateGroup(const char *s)
|
|
{
|
|
return _newStringElement(s?strdup(s):NULL, AQH_Vars_DataType_Group);
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_CreateVariable(const char *s)
|
|
{
|
|
return _newStringElement(s?strdup(s):NULL, AQH_Vars_DataType_Variable);
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_CreateStringValue(char *s)
|
|
{
|
|
return _newStringElement(s, AQH_Vars_DataType_ValueString);
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_CreateIntValue(int d)
|
|
{
|
|
AQH_VARS *vt;
|
|
|
|
vt=_newData();
|
|
vt->data.dataInt=d;
|
|
vt->dataType=AQH_Vars_DataType_ValueInt;
|
|
|
|
return vt;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_CreateDoubleValue(double d)
|
|
{
|
|
AQH_VARS *vt;
|
|
|
|
vt=_newData();
|
|
vt->data.dataDouble=d;
|
|
vt->dataType=AQH_Vars_DataType_ValueDouble;
|
|
|
|
return vt;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS_DATATYPE AQH_Vars_GetDataType(const AQH_VARS *vt)
|
|
{
|
|
return vt?vt->dataType:AQH_Vars_DataType_Unknown;
|
|
}
|
|
|
|
|
|
|
|
uint32_t AQH_Vars_GetFlags(const AQH_VARS *vt)
|
|
{
|
|
return vt?vt->flags:0;
|
|
}
|
|
|
|
|
|
|
|
const char *AQH_Vars_GetStringData(const AQH_VARS *vt, const char *defValue)
|
|
{
|
|
if (vt) {
|
|
switch(vt->dataType) {
|
|
case AQH_Vars_DataType_Group:
|
|
case AQH_Vars_DataType_Variable:
|
|
case AQH_Vars_DataType_ValueString:
|
|
return vt->data.dataString;
|
|
case AQH_Vars_DataType_ValueInt:
|
|
DBG_INFO(AQH_LOGDOMAIN, "Unexpected type INT: %d", vt->data.dataInt);
|
|
break;
|
|
case AQH_Vars_DataType_ValueDouble:
|
|
DBG_INFO(AQH_LOGDOMAIN, "Unexpected type DOUBLE: %f", vt->data.dataDouble);
|
|
break;
|
|
default:
|
|
DBG_INFO(AQH_LOGDOMAIN, "Unexpected type %d", vt->dataType);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return defValue;
|
|
}
|
|
|
|
|
|
|
|
void AQH_Vars_SetStringData(AQH_VARS *vt, char *s)
|
|
{
|
|
if (vt) {
|
|
_releaseData(vt);
|
|
vt->data.dataString=s;
|
|
vt->dataType=AQH_Vars_DataType_ValueString;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int AQH_Vars_GetIntData(const AQH_VARS *vt, int defValue)
|
|
{
|
|
if (vt && vt->dataType==AQH_Vars_DataType_ValueInt)
|
|
return vt->data.dataInt;
|
|
|
|
return defValue;
|
|
}
|
|
|
|
|
|
|
|
void AQH_Vars_SetIntData(AQH_VARS *vt, int d)
|
|
{
|
|
if (vt) {
|
|
_releaseData(vt);
|
|
vt->data.dataInt=d;
|
|
vt->dataType=AQH_Vars_DataType_ValueInt;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
double AQH_Vars_GetDoubleData(const AQH_VARS *vt, double defValue)
|
|
{
|
|
if (vt && vt->dataType==AQH_Vars_DataType_ValueDouble)
|
|
return vt->data.dataDouble;
|
|
|
|
return defValue;
|
|
}
|
|
|
|
|
|
|
|
void AQH_Vars_SetDoubleData(AQH_VARS *vt, double d)
|
|
{
|
|
if (vt) {
|
|
_releaseData(vt);
|
|
vt->data.dataDouble=d;
|
|
vt->dataType=AQH_Vars_DataType_ValueDouble;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_GetFirstChildByType(const AQH_VARS *vt, AQH_VARS_DATATYPE dt)
|
|
{
|
|
if (vt) {
|
|
AQH_VARS *vtChild;
|
|
|
|
vtChild=AQH_Vars_Tree2_GetFirstChild(vt);
|
|
while(vtChild) {
|
|
if (vtChild->dataType==dt)
|
|
return vtChild;
|
|
vtChild=AQH_Vars_Tree2_GetNext(vtChild);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_GetNextByType(const AQH_VARS *vt, AQH_VARS_DATATYPE dt)
|
|
{
|
|
if (vt) {
|
|
AQH_VARS *vtNext;
|
|
|
|
vtNext=AQH_Vars_Tree2_GetNext(vt);
|
|
while(vtNext) {
|
|
if (vtNext->dataType==dt)
|
|
return vtNext;
|
|
vtNext=AQH_Vars_Tree2_GetNext(vtNext);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *AQH_Vars_GetGroup(AQH_VARS *vt, const char *path, uint32_t flags)
|
|
{
|
|
return vt?_getPath(vt, path, (flags & ~AQH_PATH_FLAGS_VARIABLE)):NULL;
|
|
}
|
|
|
|
|
|
|
|
int AQH_Vars_SetCharValue(AQH_VARS *vt, uint32_t flags, const char *path, const char *value)
|
|
{
|
|
if (vt) {
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS *vtValue;
|
|
|
|
vtChild=_getPath(vt, path, flags | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtChild==NULL) {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Error getting path for var \"%s\"", path);
|
|
return GWEN_ERROR_GENERIC;
|
|
}
|
|
vtValue=AQH_Vars_CreateStringValue(value?strdup(value):NULL);
|
|
AQH_Vars_Tree2_AddChild(vtChild, vtValue);
|
|
return 0;
|
|
}
|
|
return GWEN_ERROR_INVALID;
|
|
}
|
|
|
|
|
|
|
|
const char *AQH_Vars_GetCharValue(AQH_VARS *vt, const char *path, int idx, const char *defaultValue)
|
|
{
|
|
if (vt && idx>=0) {
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS *vtValue;
|
|
|
|
vtChild=_getPath(vt, path, AQH_PATH_FLAGS_PATHMUSTEXIST | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtChild==NULL)
|
|
return defaultValue;
|
|
vtValue=_getValueNodeByIdx(vtChild, idx);
|
|
if (vtValue)
|
|
return AQH_Vars_GetStringData(vtValue, defaultValue);
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
|
|
|
|
int AQH_Vars_SetIntValue(AQH_VARS *vt, uint32_t flags, const char *path, int value)
|
|
{
|
|
if (vt) {
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS *vtValue;
|
|
|
|
vtChild=_getPath(vt, path, flags | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtChild==NULL) {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Error getting path for var \"%s\"", path);
|
|
return GWEN_ERROR_GENERIC;
|
|
}
|
|
vtValue=AQH_Vars_CreateIntValue(value);
|
|
AQH_Vars_Tree2_AddChild(vtChild, vtValue);
|
|
return 0;
|
|
}
|
|
return GWEN_ERROR_INVALID;
|
|
}
|
|
|
|
|
|
|
|
int AQH_Vars_GetIntValue(AQH_VARS *vt, const char *path, int idx, int defaultValue)
|
|
{
|
|
if (vt && idx>=0) {
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS *vtValue;
|
|
|
|
vtChild=_getPath(vt, path, AQH_PATH_FLAGS_PATHMUSTEXIST | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtChild==NULL)
|
|
return defaultValue;
|
|
|
|
vtValue=_getValueNodeByIdx(vtChild, idx);
|
|
if (vtValue)
|
|
return AQH_Vars_GetIntData(vtValue, defaultValue);
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
|
|
|
|
int AQH_Vars_SetDoubleValue(AQH_VARS *vt, uint32_t flags, const char *path, double value)
|
|
{
|
|
if (vt) {
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS *vtValue;
|
|
|
|
vtChild=_getPath(vt, path, flags | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtChild==NULL) {
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Error getting path for var \"%s\"", path);
|
|
return GWEN_ERROR_GENERIC;
|
|
}
|
|
vtValue=AQH_Vars_CreateDoubleValue(value);
|
|
AQH_Vars_Tree2_AddChild(vtChild, vtValue);
|
|
return 0;
|
|
}
|
|
return GWEN_ERROR_INVALID;
|
|
}
|
|
|
|
|
|
|
|
double AQH_Vars_GetDoubleValue(AQH_VARS *vt, const char *path, int idx, double defaultValue)
|
|
{
|
|
if (vt && idx>=0) {
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS *vtValue;
|
|
|
|
vtChild=_getPath(vt, path, AQH_PATH_FLAGS_PATHMUSTEXIST | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtChild==NULL)
|
|
return defaultValue;
|
|
vtValue=_getValueNodeByIdx(vtChild, idx);
|
|
if (vtValue)
|
|
return AQH_Vars_GetDoubleData(vtValue, defaultValue);
|
|
}
|
|
return defaultValue;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *_getValueNodeByIdx(const AQH_VARS *vt, int idx)
|
|
{
|
|
if (vt && idx>=0) {
|
|
AQH_VARS *vtValue;
|
|
|
|
vtValue=AQH_Vars_Tree2_GetFirstChild(vt);
|
|
while(vtValue && idx) {
|
|
idx--;
|
|
vtValue=AQH_Vars_Tree2_GetNext(vtValue);
|
|
}
|
|
return vtValue;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *_getPath(AQH_VARS *vt, const char *s, uint32_t flags)
|
|
{
|
|
return (AQH_VARS *)AQH_Path_Handle(s, (void*) vt, flags, "/", _pathHandlerFn);
|
|
}
|
|
|
|
|
|
|
|
void *_pathHandlerFn(const char *entry, void *data, int idx, uint32_t flags)
|
|
{
|
|
AQH_VARS *vt;
|
|
AQH_VARS *vtChild;
|
|
AQH_VARS_DATATYPE dt;
|
|
|
|
vt=(AQH_VARS*) data;
|
|
dt=((flags & AQH_PATH_FLAGS_LAST) && (flags & AQH_PATH_FLAGS_VARIABLE))?AQH_Vars_DataType_Variable:AQH_Vars_DataType_Group;
|
|
|
|
if (
|
|
!(
|
|
(flags & AQH_PATH_FLAGS_PATHCREATE) ||
|
|
((flags & AQH_PATH_FLAGS_LAST) && (flags & AQH_PATH_FLAGS_LASTCREATE))
|
|
)
|
|
) {
|
|
/* look it up */
|
|
vtChild=_getNodeByTypeAndName(vt, dt, entry, idx);
|
|
if (vtChild) {
|
|
/* already exists, should it? */
|
|
if (
|
|
(flags & AQH_PATH_FLAGS_PATHMUSTNOTEXIST) ||
|
|
((flags & AQH_PATH_FLAGS_LAST) && (flags & AQH_PATH_FLAGS_LASTMUSTNOTEXIST))
|
|
) {
|
|
DBG_INFO(AQH_LOGDOMAIN, "Element \"%s[%d]\" exists when it should not", entry, idx);
|
|
return NULL;
|
|
}
|
|
/* already exists, should we overwrite it (i.e. remove children)? */
|
|
if (
|
|
(flags & AQH_PATH_FLAGS_LAST) &&
|
|
(
|
|
((dt==AQH_Vars_DataType_Group) && (flags & AQH_VARS_PATHFLAGS_OVERWRITE_GROUPS)) ||
|
|
((dt==AQH_Vars_DataType_Variable) && (flags & AQH_VARS_PATHFLAGS_OVERWRITE_VARS))
|
|
)
|
|
)
|
|
AQH_Vars_Tree2_ClearChildren(vtChild);
|
|
return vtChild;
|
|
}
|
|
else {
|
|
/* does not exist, should it? */
|
|
if (flags & AQH_PATH_FLAGS_PATHMUSTEXIST) {
|
|
DBG_INFO(AQH_LOGDOMAIN, "Element \"%s[%d]\" does not exist when it should", entry, idx);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* create new string element (either group or var) */
|
|
vtChild=_newStringElement(strdup(entry), dt);
|
|
AQH_Vars_Tree2_AddChild(vt, vtChild);
|
|
return vtChild;
|
|
}
|
|
|
|
|
|
|
|
AQH_VARS *_getNodeByTypeAndName(const AQH_VARS *vt, AQH_VARS_DATATYPE dt, const char *name, int idx)
|
|
{
|
|
AQH_VARS *vtChild=NULL;
|
|
|
|
if (idx>=0) {
|
|
/* look it up */
|
|
vtChild=AQH_Vars_GetFirstChildByType(vt, dt);
|
|
while(vtChild) {
|
|
if (vtChild->data.dataString && strcasecmp(vtChild->data.dataString, name)==0) {
|
|
if (idx==0)
|
|
break;
|
|
else
|
|
idx--;
|
|
}
|
|
vtChild=AQH_Vars_GetNextByType(vtChild, dt);
|
|
}
|
|
}
|
|
|
|
return vtChild;
|
|
}
|
|
|
|
|
|
|
|
void AQH_Vars_Dump(const AQH_VARS *vt, int indent)
|
|
{
|
|
GWEN_BUFFER *dbuf;
|
|
|
|
dbuf=GWEN_Buffer_new(0, 256, 0, 1);
|
|
_dumpElement(vt, indent, dbuf);
|
|
fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(dbuf));
|
|
GWEN_Buffer_free(dbuf);
|
|
}
|
|
|
|
|
|
|
|
void _dumpElement(const AQH_VARS *vt, int indent, GWEN_BUFFER *dbuf)
|
|
{
|
|
const AQH_VARS *vtChild;
|
|
|
|
if (indent)
|
|
GWEN_Buffer_FillWithBytes(dbuf, ' ', indent);
|
|
|
|
switch(vt->dataType) {
|
|
case AQH_Vars_DataType_Unknown:
|
|
GWEN_Buffer_AppendString(dbuf, "unknown\n");
|
|
break;
|
|
case AQH_Vars_DataType_Group:
|
|
GWEN_Buffer_AppendArgs(dbuf, "group..\"%s\"\n", (vt->data.dataString)?vt->data.dataString:"<no name>");
|
|
break;
|
|
case AQH_Vars_DataType_Variable:
|
|
GWEN_Buffer_AppendArgs(dbuf, "var....\"%s\"\n", (vt->data.dataString)?vt->data.dataString:"<no name>");
|
|
break;
|
|
case AQH_Vars_DataType_ValueString:
|
|
GWEN_Buffer_AppendArgs(dbuf, "char...\"%s\"\n", (vt->data.dataString)?vt->data.dataString:"<no data>");
|
|
break;
|
|
case AQH_Vars_DataType_ValueInt:
|
|
GWEN_Buffer_AppendArgs(dbuf, "int....\"%d\"\n", vt->data.dataInt);
|
|
break;
|
|
case AQH_Vars_DataType_ValueDouble:
|
|
GWEN_Buffer_AppendArgs(dbuf, "double.\"%f\"\n", vt->data.dataDouble);
|
|
break;
|
|
}
|
|
|
|
vtChild=AQH_Vars_Tree2_GetFirstChild(vt);
|
|
while(vtChild) {
|
|
_dumpElement(vtChild, indent+2, dbuf);
|
|
vtChild=AQH_Vars_Tree2_GetNext(vtChild);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int AQH_Vars_ReplaceVars(AQH_VARS *vars, const char *s, GWEN_BUFFER *dbuf)
|
|
{
|
|
int rv;
|
|
|
|
rv=GWEN_Text_ReplaceVars(s, dbuf, _replaceVarsCb, vars);
|
|
if (rv<0) {
|
|
DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv);
|
|
return rv;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int GWENHYWFAR_CB _replaceVarsCb(void *cbPtr, const char *name, int index, GWEN_UNUSED int maxLen, GWEN_BUFFER *dstBuf)
|
|
{
|
|
AQH_VARS *vars;
|
|
AQH_VARS *vtVariable;
|
|
|
|
vars=(AQH_VARS*) cbPtr;
|
|
vtVariable=_getPath(vars, name, AQH_PATH_FLAGS_PATHMUSTEXIST | AQH_PATH_FLAGS_VARIABLE);
|
|
if (vtVariable) {
|
|
AQH_VARS *vtValue;
|
|
|
|
vtValue=_getValueNodeByIdx(vtVariable, index);
|
|
if (vtValue) {
|
|
switch(vtValue->dataType) {
|
|
case AQH_Vars_DataType_ValueString: GWEN_Buffer_AppendArgs(dstBuf, "%s", vtValue->data.dataString); return 0;
|
|
case AQH_Vars_DataType_ValueInt: GWEN_Buffer_AppendArgs(dstBuf, "%d", vtValue->data.dataInt); return 0;
|
|
case AQH_Vars_DataType_ValueDouble: GWEN_Buffer_AppendArgs(dstBuf, "%f", vtValue->data.dataDouble); return 0;
|
|
case AQH_Vars_DataType_Unknown:
|
|
case AQH_Vars_DataType_Group:
|
|
case AQH_Vars_DataType_Variable:
|
|
break;
|
|
}
|
|
DBG_ERROR(AQH_LOGDOMAIN, "Unexpected data type \"%d\" (%s)", vtValue->dataType, AQH_Vars_DataTypeToString(vtValue->dataType));
|
|
return GWEN_ERROR_INVALID;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
#include "./vars-t.c"
|
|
|