expressions: Implement the STRUNC function.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2016 18:39:29 +0000 (11:39 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2016 18:39:29 +0000 (11:39 -0700)
NEWS
doc/expressions.texi
src/language/expressions/operations.def
tests/language/expressions/evaluate.at

diff --git a/NEWS b/NEWS
index 309cf9e2a5a1a4915d0e1fc13c504023ab0a9c64..bb69e0549017ef9844d62da151216bdcda5bde4c 100644 (file)
--- 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:
index e468b8750ac457361b878a7788ac24e6d0e8a544..5898d53d77cd0c604666de83b5d171e6c5c8be2a 100644 (file)
@@ -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})
index 18ab4447c824032a7f896161c9fc760fa31a2d62..eb05661678277fb8cc25233d91beda496bd063bf 100644 (file)
@@ -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;
 {
index 703758b3b598d9602ecf0f35ec2bfaa1515dbcd3..ae7c89a5bb5335a1b519748ce8547ea71345dde8 100644 (file)
@@ -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"]],