143 lines
3.3 KiB
C
143 lines
3.3 KiB
C
/****************************************************************************
|
|
* This file is part of the project Gwenhywfar.
|
|
* 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 "./path.h"
|
|
|
|
#include <gwenhywfar/stringlist.h>
|
|
#include <gwenhywfar/text.h>
|
|
#include <gwenhywfar/debug.h>
|
|
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* forward declarations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
static void *_handleElement(const char *element, void *data, uint32_t flags, AQH_PATH_HANDLERFN fn);
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------
|
|
* implementations
|
|
* ------------------------------------------------------------------------------------------------
|
|
*/
|
|
|
|
void *AQH_Path_Handle(const char *path, void *data, uint32_t flags, const char *delimiters, AQH_PATH_HANDLERFN fn)
|
|
{
|
|
if (path && *path) {
|
|
GWEN_STRINGLIST *elementList;
|
|
|
|
/* clear internal flags */
|
|
flags&=~(AQH_PATH_FLAGS_ROOT | AQH_PATH_FLAGS_LAST);
|
|
|
|
if (*path=='/') {
|
|
flags|=AQH_PATH_FLAGS_ROOT;
|
|
path++;
|
|
}
|
|
elementList=GWEN_StringList_fromString2(path, delimiters, 0, GWEN_TEXT_FLAGS_CHECK_BACKSLASH | GWEN_TEXT_FLAGS_DEL_QUOTES);
|
|
if (elementList) {
|
|
GWEN_STRINGLISTENTRY *se;
|
|
|
|
se=GWEN_StringList_FirstEntry(elementList);
|
|
while(se) {
|
|
const char *s;
|
|
GWEN_STRINGLISTENTRY *seNext;
|
|
|
|
seNext=GWEN_StringListEntry_Next(se);
|
|
if (seNext)
|
|
flags&=~AQH_PATH_FLAGS_LAST;
|
|
else
|
|
flags|=AQH_PATH_FLAGS_LAST;
|
|
s=GWEN_StringListEntry_Data(se);
|
|
if (s && *s) {
|
|
void *result;
|
|
|
|
result=_handleElement(s, data, flags, fn);
|
|
if (result==NULL) {
|
|
DBG_INFO(NULL, "Error handling element \"%s\" (%08x)", s, flags);
|
|
GWEN_StringList_free(elementList);
|
|
return NULL;
|
|
}
|
|
data=result;
|
|
}
|
|
flags&=~AQH_PATH_FLAGS_ROOT;
|
|
se=GWEN_StringListEntry_Next(se);
|
|
}
|
|
GWEN_StringList_free(elementList);
|
|
return data;
|
|
}
|
|
else {
|
|
DBG_INFO(NULL, "Error reading path \"%s\" into stringlist", path);
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "Empty path given");
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
void *_handleElement(const char *element, void *data, uint32_t flags, AQH_PATH_HANDLERFN fn)
|
|
{
|
|
if (flags & AQH_PATH_FLAGS_PARSEIDX) {
|
|
const char *ptrOpenBracket;
|
|
|
|
ptrOpenBracket=strchr(element, '[');
|
|
if (ptrOpenBracket) {
|
|
if (ptrOpenBracket!=element) {
|
|
const char *s;
|
|
int idx=0;
|
|
|
|
s=ptrOpenBracket+1;
|
|
while(*s && isdigit(*s)) {
|
|
idx*=10;
|
|
idx+=*s-'0';
|
|
s++;
|
|
}
|
|
if (*s!=']') {
|
|
DBG_ERROR(NULL, "Closed bracket expected (got \"%c\")", *s);
|
|
return NULL;
|
|
}
|
|
else {
|
|
char *rawElement;
|
|
void *result;
|
|
|
|
s++;
|
|
rawElement=GWEN_Text_strndup(element, ptrOpenBracket-element);
|
|
result=fn?fn(rawElement, data, idx, flags):data;
|
|
free(rawElement);
|
|
return result;
|
|
}
|
|
}
|
|
else {
|
|
DBG_ERROR(NULL, "Empty element with index");
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
return fn(element, data, 0, flags);
|
|
}
|
|
|
|
|
|
|
|
#include "./path-t.c"
|
|
|
|
|
|
|
|
|