From 63387e3d127359bab6c4f53c27a9131ab4a9c348 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 13 Mar 2016 11:39:29 -0700 Subject: [PATCH] expressions: Implement the STRUNC function. --- NEWS | 2 ++ doc/expressions.texi | 12 +++++++++++- src/language/expressions/operations.def | 12 ++++++++++++ tests/language/expressions/evaluate.at | 25 ++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 309cf9e2a5..bb69e05490 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,8 @@ Changes from 0.8.5 to 0.9.0: - REPLACE, for search-and-replace of one string with another. + - STRUNC, to truncate a string and trim trailing spaces. + - MEDIAN, to compute the median of its arguments. * Bug fixes, including the following notable ones: diff --git a/doc/expressions.texi b/doc/expressions.texi index e468b8750a..5898d53d77 100644 --- a/doc/expressions.texi +++ b/doc/expressions.texi @@ -264,7 +264,8 @@ The sections below describe each function in detail. * Set Membership:: ANY RANGE * Statistical Functions:: CFVAR MAX MEAN MEDIAN MIN SD SUM VARIANCE * String Functions:: CONCAT INDEX LENGTH LOWER LPAD LTRIM NUMBER - REPLACE RINDEX RPAD RTRIM STRING SUBSTR UPCASE + REPLACE RINDEX RPAD RTRIM STRING STRUNC SUBSTR + UPCASE * Time and Date:: CTIME.xxx DATE.xxx TIME.xxx XDATE.xxx DATEDIFF DATESUM * Miscellaneous Functions:: LAG YRMODA VALUELABEL @@ -691,6 +692,15 @@ format specifier @var{format}. For example, @code{STRING(123.56, F5.1)} has the value @code{"123.6"}. @end deftypefn +@cindex strings, trimming +@cindex strings, truncating +@cindex white space, trimming +@deftypefn {Function} {} STRUNC (@var{string}, @var{n}) +Returns @var{string}, first trimming it to at most @var{n} bytes, then +removing trailing spaces. Returns an empty string if @var{n} is +missing or negative. +@end deftypefn + @cindex substrings @cindex strings, taking substrings of @deftypefn {Function} {} SUBSTR (@var{string}, @var{start}) diff --git a/src/language/expressions/operations.def b/src/language/expressions/operations.def index 18ab4447c8..eb05661678 100644 --- a/src/language/expressions/operations.def +++ b/src/language/expressions/operations.def @@ -629,6 +629,18 @@ absorb_miss string function STRING (x, no_format f) return dst; } +absorb_miss string function STRUNC (string s, n) +{ + if (n < 1 || n == SYSMIS) + return empty_string; + + if (n < s.length) + s.length = n; + while (s.length > 0 && s.string[s.length - 1] == ' ') + s.length--; + return s; +} + absorb_miss string function SUBSTR (string s, ofs) expression e; { diff --git a/tests/language/expressions/evaluate.at b/tests/language/expressions/evaluate.at index 703758b3b5..ae7c89a5bb 100644 --- a/tests/language/expressions/evaluate.at +++ b/tests/language/expressions/evaluate.at @@ -844,7 +844,7 @@ CHECK_EXPR_EVAL([replace], [[replace('banana', 'ba', '', -1)], ["banana"]], [[replace('banana', 'ba', '', $sysmis)], ["banana"]]) -CHECK_EXPR_EVAL([lpad number ltrim lpad rtrim rpad string substr upcase], +CHECK_EXPR_EVAL([lpad number ltrim lpad rtrim rpad string strunc substr upcase], [[lpad('abc', -1)], [""]], [[lpad('abc', 0)], ["abc"]], [[lpad('abc', 2)], ["abc"]], @@ -1000,6 +1000,29 @@ dnl E has a minimum width of 6 on output: [error: DEBUG EVALUATE: Type mismatch invoking STRING(number, num_output_format) as string(number, format).]], [[string(123, e6.0)], ["1E+002"]], + [[strunc('a c ', 9)], ["a c"]], + [[strunc('a c ', 7)], ["a c"]], + [[strunc('a c ', 6)], ["a c"]], + [[strunc('a c ', 5)], ["a c"]], + [[strunc('a c ', 4)], ["a c"]], + [[strunc('a c ', 3)], ["a c"]], + [[strunc('a c ', 2)], ["a"]], + [[strunc('a c ', 1)], ["a"]], + [[strunc('a c ', 0)], [""]], + [[strunc('a c ', -1)], [""]], + [[strunc('a c ', $sysmis)], [""]], + [[strunc(' abc ', 9)], [" abc"]], + [[strunc(' abc ', 8)], [" abc"]], + [[strunc(' abc ', 7)], [" abc"]], + [[strunc(' abc ', 6)], [" abc"]], + [[strunc(' abc ', 5)], [" abc"]], + [[strunc(' abc ', 4)], [" ab"]], + [[strunc(' abc ', 3)], [" a"]], + [[strunc(' abc ', 2)], [""]], + [[strunc(' abc ', 1)], [""]], + [[strunc(' abc ', -1)], [""]], + [[strunc(' abc ', $sysmis)], [""]], + [[substr('abcdefgh', -5)], [""]], [[substr('abcdefgh', 0)], [""]], [[substr('abcdefgh', 1)], ["abcdefgh"]], -- 2.30.2