From 66c583f866ff230c5111898b03137db3cd56cbf7 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Fri, 17 May 2024 17:16:20 +0200 Subject: [PATCH] aqhome: use our own implementation of GWEN_Text_GetWordToBuffer(). use the same flags like the original function (maybe replace the original function in gwen later). --- aqhome/data/vars_dbread-t.c | 2 +- aqhome/data/vars_dbread.c | 146 ++++++++++++++++++++++++++++++++---- 2 files changed, 134 insertions(+), 14 deletions(-) diff --git a/aqhome/data/vars_dbread-t.c b/aqhome/data/vars_dbread-t.c index 9042bb5..4778f4e 100644 --- a/aqhome/data/vars_dbread-t.c +++ b/aqhome/data/vars_dbread-t.c @@ -143,7 +143,7 @@ int GWENHYWFAR_CB test4(GWEN_UNUSED GWEN_TEST_MODULE *mod) " secondGroup { # here starts the 2nd group\n" "# this is the second comment\n" " int firstVarOfSecondGroup=\"1234\";\n" - " secondVarOfSecondGroup=\"secondValue\"\n" + " secondVarOfSecondGroup=\"s%65condValue\"\n" " }\n" "}"; const char *s; diff --git a/aqhome/data/vars_dbread.c b/aqhome/data/vars_dbread.c index e21ba87..6871a39 100644 --- a/aqhome/data/vars_dbread.c +++ b/aqhome/data/vars_dbread.c @@ -49,7 +49,9 @@ static const char *_readValue(AQH_VARS *vtVar, AQH_VARS_DATATYPE dataType, const static AQH_VARS *_mkStringValue(const char *s); static AQH_VARS *_mkIntValue(const char *s); static AQH_VARS *_mkDoubleValue(const char *s); - +static const char *_getWordToBuffer(const char *src, const char *delims, GWEN_BUFFER *buf, uint32_t flags); +static const char *_skipBlanks(const char *src, const char *delims); +static const char *_readEscapeSequence(const char *src, GWEN_BUFFER *wbuf); @@ -143,9 +145,10 @@ const char *_readGroupOrVar(AQH_VARS **pVars, const char *src, GWEN_BUFFER *wbuf const char *s; int rv; - rv=GWEN_Text_GetWordToBuffer(src, " ={#\t\r\n", wbuf, _textFlags, &s); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); + GWEN_Buffer_Reset(wbuf); + s=_getWordToBuffer(src, " ={#\t\r\n", wbuf, _textFlags); + if (s==NULL) { + DBG_INFO(AQH_LOGDOMAIN, "here"); return NULL; } @@ -190,7 +193,6 @@ const char *_contAsTypedVar(AQH_VARS **pVars, const char *src, const char *tname { AQH_VARS_DATATYPE dataType; const char *s; - int rv; /* got type, convert to type */ dataType=AQH_Vars_DataTypeFromString(tname); @@ -201,9 +203,9 @@ const char *_contAsTypedVar(AQH_VARS **pVars, const char *src, const char *tname /* read name */ GWEN_Buffer_Reset(wbuf); - rv=GWEN_Text_GetWordToBuffer(src, " \t={#\r\n", wbuf, _textFlags, &s); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); + s=_getWordToBuffer(src, " \t={#\r\n", wbuf, _textFlags); + if (s==NULL) { + DBG_INFO(AQH_LOGDOMAIN, "here"); return NULL; } @@ -260,14 +262,14 @@ const char *_contAsVar(AQH_VARS **pVars, AQH_VARS_DATATYPE dataType, const char const char *_readValue(AQH_VARS *vtVar, AQH_VARS_DATATYPE dataType, const char *s, GWEN_BUFFER *wbuf) { - int rv; AQH_VARS *vtValue; - rv=GWEN_Text_GetWordToBuffer(s, " \t,;#\r\n", wbuf, _textFlags, &s); - if (rv<0) { - DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); + s=_getWordToBuffer(s, " \t,;#\r\n", wbuf, _textFlags); + if (s==NULL) { + DBG_INFO(AQH_LOGDOMAIN, "here"); return NULL; } + switch(dataType) { case AQH_Vars_DataType_ValueString: vtValue=_mkStringValue(GWEN_Buffer_GetStart(wbuf)); break; case AQH_Vars_DataType_ValueInt: vtValue=_mkIntValue(GWEN_Buffer_GetStart(wbuf)); break; @@ -283,7 +285,7 @@ const char *_readValue(AQH_VARS *vtVar, AQH_VARS_DATATYPE dataType, const char * } - +// @TODO: unescape (write own GWEN_Text_GetWordToBuffer here) AQH_VARS *_mkStringValue(const char *s) { return AQH_Vars_CreateStringValue(strdup(s)); @@ -320,5 +322,123 @@ AQH_VARS *_mkDoubleValue(const char *s) +const char *_getWordToBuffer(const char *src, const char *delims, GWEN_BUFFER *buf, uint32_t flags) +{ + + /* skip leading blanks, if wanted */ + if (flags & GWEN_TEXT_FLAGS_DEL_LEADING_BLANKS) + src=_skipBlanks(src, delims); + + if (*src=='"') { + /* inside brackets */ + if (flags & GWEN_TEXT_FLAGS_DEL_QUOTES) + src++; + while(*src && strchr(delims, *src)==NULL) { + unsigned char x; + + x=(unsigned char)*src; + if (x=='"') { + if (flags & GWEN_TEXT_FLAGS_DEL_QUOTES) + src++; + return src; + } + else { + if (x=='%') { + src=_readEscapeSequence(src, buf); + if (src==NULL) { + DBG_INFO(AQH_LOGDOMAIN, "here"); + return NULL; + } + } + else { + GWEN_Buffer_AppendByte(buf, x); + src++; + } + } + } + } + else { + while(*src && strchr(delims, *src)==NULL) { + unsigned char x; + + x=*src; + if (x=='%') { + src=_readEscapeSequence(src, buf); + if (src==NULL) { + DBG_INFO(AQH_LOGDOMAIN, "here"); + return NULL; + } + } + else { + GWEN_Buffer_AppendByte(buf, x); + src++; + } + if ((flags & GWEN_TEXT_FLAGS_DEL_MULTIPLE_BLANKS) && isblank(x)) + src=_skipBlanks(src, delims); + } + } + + return src; +} + + + +const char *_skipBlanks(const char *src, const char *delims) +{ + while (*src && isblank(*src)) { + if (strchr(delims, *src)) { + return src; /* empty buffer */ + } + src++; + } + return src; +} + + + +const char *_readEscapeSequence(const char *src, GWEN_BUFFER *wbuf) +{ + if (src[1] && src[2]) { + unsigned char d1, d2; + unsigned char c; + + src++; /* skip "%" */ + + if (!(*src) || !isxdigit((int)*src)) { + DBG_ERROR(GWEN_LOGDOMAIN, "Incomplete escape sequence (no digits)"); + return NULL; + } + d1=(unsigned char)(toupper(*src)); + src++; + + if (!(*src) || !isxdigit((int)*src)) { + DBG_ERROR(GWEN_LOGDOMAIN, "Incomplete escape sequence (only 1 digit)"); + return NULL; + } + d2=(unsigned char)(toupper(*src)); + src++; + + d1-='0'; + if (d1>9) + d1-=7; + + d2-='0'; + if (d2>9) + d2-=7; + c=((d1<<4) & 0xf0) | (d2 & 0x0f); + GWEN_Buffer_AppendByte(wbuf, c); + return src; + } + else { + DBG_ERROR(AQH_LOGDOMAIN, "Incomplete escape sequence"); + return NULL; + } +} + + +//if ((x>='A' && x<='Z') || (x>='a' && x<='z') || (x>='0' && x<='9') || strchr(_acceptableChars, x)) + + + #include "./vars_dbread-t.c"