diff options
author | Steve Bennett <steveb@workware.net.au> | 2019-11-27 23:09:34 +1100 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2019-11-30 08:14:35 +1000 |
commit | 5802d3f5e49737b761c93fceba1d169e0a26b763 (patch) | |
tree | 977d6f6cd757108a71a67a3f887831f01fd15811 /jim-tclprefix.c | |
parent | 0aa0fb4e3a38d38a49de9eb585d93d63a370dcf6 (diff) | |
download | jimtcl-5802d3f5e49737b761c93fceba1d169e0a26b763.zip jimtcl-5802d3f5e49737b761c93fceba1d169e0a26b763.tar.gz jimtcl-5802d3f5e49737b761c93fceba1d169e0a26b763.tar.bz2 |
string map and string compare now support embedded nulls
Reported-by: dbohdan <dbohdan@dbohdan.com>
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim-tclprefix.c')
-rw-r--r-- | jim-tclprefix.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/jim-tclprefix.c b/jim-tclprefix.c index dcffd4d..c492234 100644 --- a/jim-tclprefix.c +++ b/jim-tclprefix.c @@ -28,6 +28,32 @@ static int JimStringCommonLength(const char *str1, int charlen1, const char *str return maxlen; } +/* + * Like Jim_StringCompareObj() except only matches as much as the length of firstObjPtr. + * So "abc" matches "abcdef" but "abcdef" does not match "abc". + */ +int JimStringComparePrefix(Jim_Interp *interp, Jim_Obj *firstObjPtr, Jim_Obj *secondObjPtr) +{ + /* We do this the easy way by creating a (possibly) shorter version of secondObjPtr */ + int l1 = Jim_Utf8Length(interp, firstObjPtr); + const char *s2 = Jim_String(secondObjPtr); + int l2 = Jim_Utf8Length(interp, secondObjPtr); + Jim_Obj *objPtr; + int ret; + + if (l2 > l1) { + objPtr = Jim_NewStringObjUtf8(interp, s2, l1); + } + else { + objPtr = secondObjPtr; + } + Jim_IncrRefCount(objPtr); + + ret = Jim_StringCompareObj(interp, firstObjPtr, objPtr, 0); + Jim_DecrRefCount(interp, objPtr); + return ret; +} + /* [tcl::prefix] */ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) @@ -140,7 +166,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const objPtr = Jim_NewListObj(interp, NULL, 0); for (i = 0; i < listlen; i++) { Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i); - if (Jim_StringCompareLenObj(interp, argv[3], valObj, 0) == 0) { + if (JimStringComparePrefix(interp, argv[3], valObj) == 0) { Jim_ListAppendElement(interp, objPtr, valObj); } } @@ -164,7 +190,7 @@ static int Jim_TclPrefixCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const for (i = 0; i < listlen; i++) { Jim_Obj *valObj = Jim_ListGetIndex(interp, argv[2], i); - if (Jim_StringCompareLenObj(interp, stringObj, valObj, 0)) { + if (JimStringComparePrefix(interp, stringObj, valObj)) { /* Does not begin with 'string' */ continue; } |