aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jim.c81
-rw-r--r--test.tcl68
2 files changed, 129 insertions, 20 deletions
diff --git a/jim.c b/jim.c
index 8aa65bc..7adc06e 100644
--- a/jim.c
+++ b/jim.c
@@ -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},
};
diff --git a/test.tcl b/test.tcl
index aa2ef61..5178755 100644
--- a/test.tcl
+++ b/test.tcl
@@ -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