From 27eb474b8563fca091dae2a4c8dc8df84f819187 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Thu, 21 Jan 2021 23:00:51 +0100 Subject: [PATCH] + fix: Tinyexpr functions and constants parsing (fixing issue #3054) --- src/Edit.c | 14 +++++----- src/Helpers.c | 2 +- src/Helpers.h | 57 ++++++++++++++++++++++++----------------- src/Notepad3.c | 8 +++--- src/tinyexpr/tinyexpr.c | 12 ++++++--- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index e82452c1e..23eb2c6de 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -3861,7 +3861,7 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan DocPos i = end; while (--i >= 0) { const char ch = lineBuffer[i]; - if (IsBlankChar(ch)) { + if (IsBlankCharA(ch)) { lineBuffer[i] = '\0'; } else { break; @@ -3909,7 +3909,7 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan char ch; do { ch = SciCall_GetCharAt(--i); - } while ((i >= iStartPos) && IsBlankChar(ch)); + } while ((i >= iStartPos) && IsBlankCharA(ch)); if ((++i) < iEndPos) { SciCall_SetTargetRange(i, iEndPos); SciCall_ReplaceTarget(0, ""); @@ -3977,9 +3977,9 @@ void EditCompressBlanks() DocPos i = 0; while (pText < pEnd) { const char ch = *pText++; - if (IsBlankChar(ch)) { + if (IsBlankCharA(ch)) { lineBuffer[i++] = ' '; - while (IsBlankChar(*pText)) { + while (IsBlankCharA(*pText)) { ++pText; } } else { @@ -4038,11 +4038,11 @@ void EditCompressBlanks() char* co = pszOut; DocPos remWSuntilCaretPos = 0; for (int i = 0; i < cch; ++i) { - if (IsBlankChar(pszIn[i])) { + if (IsBlankCharA(pszIn[i])) { if (pszIn[i] == '\t') { bModified = true; } - while (IsBlankChar(pszIn[i + 1])) { + while (IsBlankCharA(pszIn[i + 1])) { if (bIsSelEmpty && (i < iSelStartPos)) { ++remWSuntilCaretPos; } @@ -4153,7 +4153,7 @@ void EditRemoveBlankLines(HWND hwnd, bool bMerge, bool bRemoveWhiteSpace) const char* pLine = SciCall_GetRangePointer(posLnBeg, iLnLength); DocPos i = 0; for (; i < iLnLength; ++i) { - if (!IsBlankChar(pLine[i])) { + if (!IsBlankCharA(pLine[i])) { break; } } diff --git a/src/Helpers.c b/src/Helpers.c index 6f1dec10f..4c772abf7 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -2342,7 +2342,7 @@ void UrlEscapeEx(LPCWSTR lpURL, LPWSTR lpEscaped, DWORD* pcchEscaped, bool bEscR DWORD posOut = 0; while (lpURL[posIn] && (posOut < *pcchEscaped)) { - if (IsAlphaNumeric(lpURL[posIn]) || StrChrW(lpszUnreservedChars, lpURL[posIn])) { + if (IsAlphaNumericW(lpURL[posIn]) || StrChrW(lpszUnreservedChars, lpURL[posIn])) { lpEscaped[posOut++] = lpURL[posIn++]; } else if (StrChrW(lpszReservedChars, lpURL[posIn])) { if (posOut < (*pcchEscaped - 3)) { diff --git a/src/Helpers.h b/src/Helpers.h index b2aa86830..7ef52d282 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -158,26 +158,6 @@ inline DocPosU clamppu(DocPosU x, DocPosU lower, DocPosU upper) return (x < lower) ? lower : ((x > upper) ? upper : x); } -// Is the character an octal digit? -inline bool IsDigitA(const CHAR ch) -{ - return ((ch >= '0') && (ch <= '9')); -} -inline bool IsDigitW(const WCHAR wch) -{ - return ((wch >= L'0') && (wch <= L'9')); -} - -// Is the character a white space char? -inline bool IsBlankChar(const CHAR ch) -{ - return ((ch == ' ') || (ch == '\t')); -} -inline bool IsBlankCharW(const WCHAR wch) -{ - return ((wch == L' ') || (wch == L'\t')); -} - inline int float2int(const float f) { return (int)lroundf(f); @@ -710,17 +690,46 @@ inline WCHAR* StrEndW(const WCHAR* pStart, size_t siz) // Is the character an octal digit? #define IsOctalDigit(ch) (((ch) >= '0') && ((ch) <= '7')) +// Is the character an octal digit? +inline bool IsDigitA(const char ch) { + return ((ch >= '0') && (ch <= '9')); +} +inline bool IsDigitW(const WCHAR wch) { + return ((wch >= L'0') && (wch <= L'9')); +} + +// Is the character a white space char? +inline bool IsBlankCharA(const char ch) { + return ((ch == ' ') || (ch == '\t')); +} +inline bool IsBlankCharW(const WCHAR wch) { + return ((wch == L' ') || (wch == L'\t')); +} + // no encoding for safe chars -__inline bool IsAlphaNumeric(WCHAR ch) -{ +inline bool IsAlphaNumericA(const char ch) { + return ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || + ((ch >= 'A') && (ch <= 'Z')); +} + +inline bool IsAlphaNumericW(const WCHAR ch) { return ((ch >= L'0') && (ch <= L'9')) || ((ch >= L'a') && (ch <= L'z')) || ((ch >= L'A') && (ch <= L'Z')); } +// no encoding for safe chars +inline bool IsIdentifierA(const char ch) { + return ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || + ((ch >= 'A') && (ch <= 'Z')) || + (ch >= '_'); +} + // If the character is an hexadecimal digit, get its value. -__inline int GetHexDigitA(char ch) +inline int GetHexDigitA(const char ch) { if (ch >= '0' && ch <= '9') { return ch - '0'; @@ -734,7 +743,7 @@ __inline int GetHexDigitA(char ch) return -1; } -__inline int GetHexDigitW(WCHAR ch) +inline int GetHexDigitW(const WCHAR ch) { if (ch >= L'0' && ch <= L'9') { return ch - L'0'; diff --git a/src/Notepad3.c b/src/Notepad3.c index 68bbb64c8..c80b6b64a 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -2102,7 +2102,7 @@ static bool _EvalTinyExpr(bool qmark) DocPos const posBegin = qmark ? SciCall_PositionBefore(posCur) : posCur; DocPos posBefore = SciCall_PositionBefore(posBegin); char chBefore = SciCall_GetCharAt(posBefore); - while (IsBlankChar(chBefore) && (posBefore > 0)) { + while (IsBlankCharA(chBefore) && (posBefore > 0)) { posBefore = SciCall_PositionBefore(posBefore); chBefore = SciCall_GetCharAt(posBefore); } @@ -2122,14 +2122,16 @@ static bool _EvalTinyExpr(bool qmark) FreeMem(lineBufW); const char *pBegin = lineBuf; - while (IsBlankChar(*pBegin)) { + while (IsBlankCharA(*pBegin)) { ++pBegin; } double dExprEval = 0.0; te_xint_t exprErr = 1; while (*pBegin && exprErr) { - dExprEval = te_interp(pBegin++, &exprErr); + dExprEval = te_interp(pBegin, &exprErr); + // proceed to next possible expression + while (exprErr && IsIdentifierA(*pBegin++)) {} } FreeMem(lineBuf); diff --git a/src/tinyexpr/tinyexpr.c b/src/tinyexpr/tinyexpr.c index 08fccdd7f..700632ce9 100644 --- a/src/tinyexpr/tinyexpr.c +++ b/src/tinyexpr/tinyexpr.c @@ -377,8 +377,8 @@ static const te_variable *find_builtin(const char *name, size_t len) { /*Binary search.*/ while (imax >= imin) { const int i = (imin + ((imax-imin)/2)); - int c = strncmp(name, functions[i].name, len); - if (!c) c = '\0' - functions[i].name[len]; + const int f = strncmp(name, functions[i].name, len); + const int c = f ? f : ('\0' - functions[i].name[len]); if (c == 0) { return functions + i; } else if (c > 0) { @@ -420,8 +420,12 @@ void next_token(state *s) { } else { /* Look for a variable or builtin function call. */ if (s->next[0] >= 'a' && s->next[0] <= 'z') { - const char *start = s->next; - while ((s->next[0] >= 'a' && s->next[0] <= 'z') || (s->next[0] >= '0' && s->next[0] <= '9') || (s->next[0] == '_')) s->next++; + const char * const start = s->next; + char ch = s->next[0]; + while ((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch == '_')) { + s->next++; + ch = s->next[0]; + }; const te_variable *var = find_lookup(s, start, s->next - start); if (!var) var = find_builtin(start, s->next - start);