diff options
-rw-r--r-- | jim.c | 81 | ||||
-rw-r--r-- | test.tcl | 68 |
2 files changed, 129 insertions, 20 deletions
@@ -309,26 +309,6 @@ int JimStringCompare(const char *s1, int l1, const char *s2, int l2, } } -int testGlobMatching(void) -{ - char buf[1024]; - char *str = "hello worldo"; - - printf("string: %s\n", str); - while(1) { - int len; - - printf("pattern> "); - if (fgets(buf, 1024, stdin) == NULL) return 0; - len = strlen(buf); - if (len && buf[len-1] == '\n') { - buf[len-1] = '\0'; - } - printf("%d\n", JimStringMatch(buf, strlen(buf), str, strlen(str), 0)); - } - return 0; -} - int Jim_WideToString(char *buf, jim_wide wideValue) { const char *fmt = "%" JIM_WIDE_MODIFIER; @@ -8540,6 +8520,66 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, } } +/* [split] */ +static int Jim_SplitCoreCommand(Jim_Interp *interp, int argc, + Jim_Obj *const *argv) +{ + const char *str, *splitChars, *noMatchStart; + int splitLen, strLen, i; + Jim_Obj *resObjPtr; + + if (argc != 2 && argc != 3) { + Jim_WrongNumArgs(interp, 1, argv, "string ?splitChars?"); + return JIM_ERR; + } + /* Init */ + if (argc == 2) { + splitChars = " \n\t\r"; + splitLen = 4; + } else { + splitChars = Jim_GetString(argv[2], &splitLen); + } + str = Jim_GetString(argv[1], &strLen); + if (!strLen) return JIM_OK; + noMatchStart = str; + resObjPtr = Jim_NewListObj(interp, NULL, 0); + /* Split */ + if (splitLen) { + while (strLen) { + for (i = 0; i < splitLen; i++) { + if (*str == splitChars[i]) { + Jim_Obj *objPtr; + + objPtr = Jim_NewStringObj(interp, noMatchStart, + (str-noMatchStart)); + Jim_ListAppendElement(interp, resObjPtr, objPtr); + noMatchStart = str+1; + break; + } + } + str ++; + strLen --; + } + Jim_ListAppendElement(interp, resObjPtr, + Jim_NewStringObj(interp, noMatchStart, (str-noMatchStart))); + } else { + /* This handles the special case of splitchars eq {}. This + * is trivial but we want to perform object sharing as Tcl does. */ + Jim_Obj *objCache[256]; + const unsigned char *u = (unsigned char*) str; + memset(objCache, 0, sizeof(objCache)); + for (i = 0; i < strLen; i++) { + int c = u[i]; + + if (objCache[c] == NULL) + objCache[c] = Jim_NewStringObj(interp, u+i, 1); + Jim_ListAppendElement(interp, resObjPtr, objCache[c]); + } + } + Jim_SetResult(interp, resObjPtr); + return JIM_OK; +} + static struct { char *name; Jim_CmdProc cmdProc; @@ -8586,6 +8626,7 @@ static struct { {"load", Jim_LoadCoreCommand}, {"subst", Jim_SubstCoreCommand}, {"info", Jim_InfoCoreCommand}, + {"split", Jim_SplitCoreCommand}, {NULL, NULL}, }; @@ -2285,6 +2285,74 @@ test string-10.19 {string map, empty arguments} { string map -nocase {{} abc f bar {} def} foo } baroo +################################################################################ +# SPLIT +################################################################################ + +test split-1.1 {basic split commands} { + split "a\n b\t\r c\n " +} {a {} b {} {} c {} {}} +test split-1.2 {basic split commands} { + split "word 1xyzword 2zword 3" xyz +} {{word 1} {} {} {word 2} {word 3}} +test split-1.3 {basic split commands} { + split "12345" {} +} {1 2 3 4 5} +test split-1.4 {basic split commands} { + split "a\}b\[c\{\]\$" +} "a\\}b\\\[c\\{\\\]\\\$" +test split-1.5 {basic split commands} { + split {} {} +} {} +test split-1.6 {basic split commands} { + split {} +} {} +test split-1.7 {basic split commands} { + split { } +} {{} {} {} {}} +test split-1.8 {basic split commands} { + proc foo {} { + set x {} + foreach f [split {]\n} {}] { + append x $f + } + return $x + } + foo +} {]\n} +test split-1.9 {basic split commands} { + proc foo {} { + set x ab\000c + set y [split $x {}] + return $y + } + foo +} "a b \000 c" +test split-1.10 {basic split commands} { + split "a0ab1b2bbb3\000c4" ab\000c +} {{} 0 {} 1 2 {} {} 3 {} 4} +test split-1.11 {basic split commands} { + split "12,3,45" {,} +} {12 3 45} +#test split-1.12 {basic split commands} { +# split "\u0001ab\u0001cd\u0001\u0001ef\u0001" \1 +#} {{} ab cd {} ef {}} +test split-1.13 {basic split commands} { + split "12,34,56," {,} +} {12 34 56 {}} +test split-1.14 {basic split commands} { + split ",12,,,34,56," {,} +} {{} 12 {} {} 34 56 {}} + +test split-2.1 {split errors} { + list [catch split msg] $msg +} {1 {wrong # args: should be "split string ?splitChars?"}} +test split-2.2 {split errors} { + list [catch {split a b c} msg] $msg +} {1 {wrong # args: should be "split string ?splitChars?"}} + +# cleanup +catch {rename foo {}} ################################################################################ # FINAL REPORT |