/**************************************************************************** * 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 #endif #include "./path.h" #include #include #include #include #include #include /* ------------------------------------------------------------------------------------------------ * forward declarations * ------------------------------------------------------------------------------------------------ */ static void *_handleElement(const char *element, void *data, uint32_t flags, AQH_PATH_HANDLERFN fn); static void _getPathBetween(const char *path1, const char *path2, GWEN_BUFFER *diffBuf); /* ------------------------------------------------------------------------------------------------ * 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_LAST; 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; } 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); } int AQH_Path_GetPathBetween(const char *path1, const char *path2, GWEN_BUFFER *diffBuf) { if (!(path1 && *path1)) { if (path2 && *path2) { GWEN_Buffer_AppendString(diffBuf, path2); return 0; } else { DBG_INFO(AQH_LOGDOMAIN, "Both paths are NULL."); return 0; } } if (!(path2 && *path2)) { GWEN_STRINGLIST *sl1; sl1=GWEN_StringList_fromString2(path1, "/", 0, GWEN_TEXT_FLAGS_DEL_QUOTES | GWEN_TEXT_FLAGS_CHECK_BACKSLASH); if (sl1) { int cnt; int i; cnt=GWEN_StringList_Count(sl1); for (i=0; i0) GWEN_Buffer_AppendString(diffBuf, "/"); GWEN_Buffer_AppendString(diffBuf, ".."); } GWEN_StringList_free(sl1); return 0; } } _getPathBetween(path1, path2, diffBuf); return 0; } void _getPathBetween(const char *path1, const char *path2, GWEN_BUFFER *diffBuf) { GWEN_STRINGLIST *sl1; GWEN_STRINGLIST *sl2; GWEN_STRINGLISTENTRY *se; int count; int i; sl2=GWEN_StringList_fromString2(path2, "/", 0, GWEN_TEXT_FLAGS_DEL_QUOTES | GWEN_TEXT_FLAGS_CHECK_BACKSLASH); sl1=GWEN_StringList_fromString2(path1, "/", 0, GWEN_TEXT_FLAGS_DEL_QUOTES | GWEN_TEXT_FLAGS_CHECK_BACKSLASH); GWEN_StringList_RemoveCommonFirstEntries(sl1, sl2); count=GWEN_StringList_Count(sl1); for (i=0; i