From 7f12f9a3f6aeb2452acedced5a54c66c4a19382b Mon Sep 17 00:00:00 2001 From: Przemyslaw Pawelczyk Date: Thu, 18 Jun 2009 01:50:31 +0200 Subject: Fix tokenize function and test. Previous implementation was error-prone, because allowed returning empty tokens (mimiced strsep()), which is fine if there is a NULL semantic. Unfortunately SystemTap doesn't provide it in scripts and has only blank string (""), therefore testing against it was misleading. The solution is to return only non-empty tokens (mimic strtok()). * tapset/string.stp: Fix tokenize. * testsuite/systemtap.string/tokenize.stp: Improve and add case with more than one delimiter in the delim string. * testsuite/systemtap.string/tokenize.exp: Ditto. * stapfuncs.3stap.in: Update tokenize description. * doc/langref.tex: Ditto. Signed-off-by: Josh Stone --- doc/langref.tex | 4 +- stapfuncs.3stap.in | 6 +-- tapset/string.stp | 23 ++++++---- testsuite/systemtap.string/tokenize.exp | 16 ++++++- testsuite/systemtap.string/tokenize.stp | 75 +++++++++++++++++++++------------ 5 files changed, 82 insertions(+), 42 deletions(-) diff --git a/doc/langref.tex b/doc/langref.tex index 5aefa278..5a149d19 100644 --- a/doc/langref.tex +++ b/doc/langref.tex @@ -3160,8 +3160,8 @@ General syntax: tokenize:string (input:string, delim:string) \end{verbatim} \end{vindent} -This function returns the next token in the given input string, where -the tokens are delimited by one of the characters in the delim string. +This function returns the next non-empty token in the given input string, +where the tokens are delimited by characters in the delim string. If the input string is non-NULL, it returns the first token. If the input string is NULL, it returns the next token in the string passed in the previous call to tokenize. If no delimiter is found, the entire remaining input string diff --git a/stapfuncs.3stap.in b/stapfuncs.3stap.in index 518ff2bb..3d88b2ea 100644 --- a/stapfuncs.3stap.in +++ b/stapfuncs.3stap.in @@ -166,11 +166,11 @@ specified by base. For example, strtol("1000", 16) returns 4096. Returns 0 if string cannot be converted. .TP tokenize:string (str:string, delim:string) -Return the next token in the given str string, where the tokens are delimited -by one of the characters in the delim string. If the str string is not blank, +Return the next non-empty token in the given str string, where the tokens are +delimited by characters in the delim string. If the str string is not blank, it returns the first token. If the str string is blank, it returns the next token in the string passed in the previous call to tokenize. If no delimiter -is found, the entire remaining str string is returned. Returns blank when +is found, the entire remaining str string is returned. Returns blank when no more tokens are left. .SS TIMESTAMP diff --git a/tapset/string.stp b/tapset/string.stp index 35ee9fa2..cc842929 100644 --- a/tapset/string.stp +++ b/tapset/string.stp @@ -70,25 +70,32 @@ function text_strn:string(input:string, len:long, quoted:long) /* * tokenize - Given a string and a token delimiter, - * return the next token in the string - * input String to tokenize. If NULL, returns the next token in the - * string passed in the previous call to tokenize(). - * delim Token delimiter. Note this is a string, but only the first - * character is used as the delimiter. + * return the next non-empty token in the string + * or blank when no more non-empty tokens are left + * input String to tokenize. If NULL, returns the next non-empty token + * in the string passed in the previous call to tokenize(). + * delim Token delimiter. Set of characters that delimit the tokens. */ function tokenize:string(input:string, delim:string) %{ /* pure */ static char str[MAXSTRINGLEN]; static char *str_start; + static char *str_end; char *token = NULL; + char *token_end = NULL; if (THIS->input[0]) { strncpy(str, THIS->input, MAXSTRINGLEN); str_start = &str[0]; + str_end = &str[0] + strlen(str); + } + do { + token = strsep(&str_start, THIS->delim); + } while (token && !token[0]); + if (token) { + token_end = (str_start ? str_start - 1 : str_end); + memcpy(THIS->__retvalue, token, token_end - token + 1); } - token = strsep(&str_start, THIS->delim); - if (token) - strncpy (THIS->__retvalue, token, MAXSTRINGLEN); %} /* diff --git a/testsuite/systemtap.string/tokenize.exp b/testsuite/systemtap.string/tokenize.exp index 697b7c7e..aa28f855 100644 --- a/testsuite/systemtap.string/tokenize.exp +++ b/testsuite/systemtap.string/tokenize.exp @@ -9,7 +9,9 @@ seven eight nine ten +- one|two|three|four|five|six|seven|eight|nine|ten +- a b c @@ -17,10 +19,22 @@ d e f g +- 1 2 3 4 -this is a string with no delimiters} +- +- +this is a string with no delimiters +- +this +is +a +string +which +has +two +delimiters} stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.string/tokenize.stp b/testsuite/systemtap.string/tokenize.stp index 10703d90..1b253c8d 100644 --- a/testsuite/systemtap.string/tokenize.stp +++ b/testsuite/systemtap.string/tokenize.stp @@ -5,42 +5,61 @@ probe begin teststr3 = "1,,2,3, ,4" teststr4 = "" teststr5 = "this is a string with no delimiters" + teststr6 = "this is a string, which has two delimiters" tok = tokenize(teststr1, "|") while (tok != "") { - printf("%s\n", tok) + println(tok) tok = tokenize("", "|") } - tok = tokenize(teststr1, ",") - while (tok != "") { - printf("%s\n", tok) - tok = tokenize("", "|") - } + println("-") + + tok = tokenize(teststr1, ",") + while (tok != "") { + println(tok) + tok = tokenize("", "|") + } + println("-") + tok = tokenize(teststr2, ",") - while (tok != "") { - printf("%s\n", tok) - tok = tokenize("", ",") - } - - tok = tokenize(teststr3, ",") - while (tok != "") { - printf("%s\n", tok) - tok = tokenize("", ",") - } - - tok = tokenize(teststr4, ",") - while (tok != "") { - printf("%s\n", tok) - tok = tokenize("", ",") - } - - tok = tokenize(teststr5, ",") - while (tok != "") { - printf("%s\n", tok) - tok = tokenize("", ",") - } + while (tok != "") { + println(tok) + tok = tokenize("", ",") + } + + println("-") + + tok = tokenize(teststr3, ",") + while (tok != "") { + println(tok) + tok = tokenize("", ",") + } + + println("-") + + tok = tokenize(teststr4, ",") + while (tok != "") { + println(tok) + tok = tokenize("", ",") + } + + println("-") + + tok = tokenize(teststr5, ",") + while (tok != "") { + println(tok) + tok = tokenize("", ",") + } + + println("-") + + tok = tokenize(teststr6, ", ") + while (tok != "") { + println(tok) + tok = tokenize("", ", ") + } exit() } -- cgit From d917e520b1bd36e2230312ab25c61e6161cdc372 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 17 Jun 2009 18:23:39 -0700 Subject: Refactor common code in the tokenize test --- testsuite/systemtap.string/tokenize.exp | 3 +- testsuite/systemtap.string/tokenize.stp | 71 +++++++++------------------------ 2 files changed, 20 insertions(+), 54 deletions(-) diff --git a/testsuite/systemtap.string/tokenize.exp b/testsuite/systemtap.string/tokenize.exp index aa28f855..d32868cf 100644 --- a/testsuite/systemtap.string/tokenize.exp +++ b/testsuite/systemtap.string/tokenize.exp @@ -1,5 +1,6 @@ set test "tokenize" -set ::result_string {one +set ::result_string {- +one two three four diff --git a/testsuite/systemtap.string/tokenize.stp b/testsuite/systemtap.string/tokenize.stp index 1b253c8d..ba95f63f 100644 --- a/testsuite/systemtap.string/tokenize.stp +++ b/testsuite/systemtap.string/tokenize.stp @@ -1,3 +1,14 @@ +function tokprint(str, delim) +{ + println("-") + + tok = tokenize(str, delim) + while (tok != "") { + println(tok) + tok = tokenize("", delim) + } +} + probe begin { teststr1 = "one|two|three|four|five|six|seven|eight|nine|ten" @@ -7,59 +18,13 @@ probe begin teststr5 = "this is a string with no delimiters" teststr6 = "this is a string, which has two delimiters" - tok = tokenize(teststr1, "|") - while (tok != "") { - println(tok) - tok = tokenize("", "|") - } - - println("-") - - tok = tokenize(teststr1, ",") - while (tok != "") { - println(tok) - tok = tokenize("", "|") - } - - println("-") - - tok = tokenize(teststr2, ",") - while (tok != "") { - println(tok) - tok = tokenize("", ",") - } - - println("-") - - tok = tokenize(teststr3, ",") - while (tok != "") { - println(tok) - tok = tokenize("", ",") - } - - println("-") - - tok = tokenize(teststr4, ",") - while (tok != "") { - println(tok) - tok = tokenize("", ",") - } - - println("-") - - tok = tokenize(teststr5, ",") - while (tok != "") { - println(tok) - tok = tokenize("", ",") - } - - println("-") - - tok = tokenize(teststr6, ", ") - while (tok != "") { - println(tok) - tok = tokenize("", ", ") - } + tokprint(teststr1, "|") + tokprint(teststr1, ",") + tokprint(teststr2, ",") + tokprint(teststr3, ",") + tokprint(teststr4, ",") + tokprint(teststr5, ",") + tokprint(teststr6, ", ") exit() } -- cgit From 0e5cd254d3ef39cef5fa6ba56231604274fd85cd Mon Sep 17 00:00:00 2001 From: David Smith Date: Thu, 18 Jun 2009 10:10:51 -0500 Subject: Made testcase handle slower systems. * testsuite/systemtap.base/flightrec3.exp: Fixed for slower systems. --- testsuite/systemtap.base/flightrec3.exp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testsuite/systemtap.base/flightrec3.exp b/testsuite/systemtap.base/flightrec3.exp index 20a65c50..3799c6a6 100644 --- a/testsuite/systemtap.base/flightrec3.exp +++ b/testsuite/systemtap.base/flightrec3.exp @@ -61,7 +61,9 @@ catch {exec kill -CONT $pid} # check logfile number set cnt 0 foreach e [array names cpus] { - if {$cpus($e) != 6} { + # If we have more than 6 files per cpu, something is wrong. We + # might have less than 6 files per cpu if the machine is slow. + if {$cpus($e) > 6} { fail "$test (log file numbers cpu:$e, cnt:$cpus($e)))" } set cnt [expr $cnt + $cpus($e)] -- cgit