Suprtool Does Strings!

By Neil Armstrong, Suprtool Architect

Originally published in the 3000 NewsWire

Neil Armstrong

Sometimes at Robelle we tend to forget how quickly we implement new features and move on to the next enhancement in our products. For example, in year 2000, with Suprtool's high speed extract and new and more powerful machines, our focus was to eliminate the number of passes that you need to do in order to get your data in the format you want. One result of that effort was expanded string handling to Suprtool, but some of you may have only just heard about this feature now. With the prospect of migrating data off of the 3000 we see these features as being very helpful for some migrations.

String Expressions

Both the Extract and If commands have been enhanced to allow string expressions, which can be used to:
  1. Combine two fields together (using the + operator).
  2. Remove spaces (using the built-in trim functions).
  3. Upshift or downshift characters.
String expressions reduce the number of tasks required for many common operations involving byte-type fields. Fewer tasks means that Suprtool delivers data to your applications faster than ever before.

These changes are so extensive that string expressions are described separately for the Extract and If Commands. See the sections below for specific details and examples of string expressions.

Extract Command

You can now use string expressions in the Extract command. They allow you to combine byte-type fields together (using the + operator) or operate on byte-type fields with special functions. In many cases, you can now reduce the number of tasks required to format your data the way you want. Fewer tasks means that Suprtool delivers the data where you need it faster than ever before. To extract a string expression, use this syntax:

EXTRACT target-field = expression

Target-Field

The target-field determines the byte-length of the expression. The data-type must be Byte or Char. The expression is extracted during the output phase and cannot be used by other Suprtool commands that accept fields (e.g., Sort).

Examples

>extract id-no = warehouse-no + bin-no

>extract full-name = first-name + last-name

Constants vs. Expressions

If you have a string expression that starts with a string, Suprtool assumes that you are attempting to extract a single string value and not a string expression. To specify a string expression that starts with a constant, surround the expression with parentheses. For example,

Incorrect

>extract name = " " + product-desc

Error: Missing comma or invalid arithmetic expression

Correct

>extract name = (" " + product-desc)

Variable Length Strings

String expressions use variable-length strings. Suprtool keeps track of the length of every string, and all operations are done using the actual string length. For fields, the length of the string is the length of the field. If you do not want to retain all the spaces in a field, use one of the built-in trimming functions.

String constants are created with the exact length of the constant. For example, the string "abc" is three characters long and the string "a" is one.

When assigning the string expression to the target field, Suprtool pads the final string value with spaces to fill out the target field. String expressions longer than the target field generate an error.

>in testfile
>def a,1,10,byte
>ext a="I'm too long for this container"

Error: String is too long for the specified item

String Truncation

Suprtool produces an error if the string expression is longer than the target field. You cannot override this error with Set Ignore On. To help avoid the error, you may want to trim trailing spaces from the expression before assigning it to the target field. For example,
>extract new-field = $trim(a + b + c)

Upshifting Strings ($Upper)

Use the built-in function $upper to upshift all the characters of a string expression into uppercase characters. This function can be used to upshift a single field, a complicated string expression, or any subpart of an expression. Both ASCII and Roman-8 characters are upshifted by $upper. For example,
>extract city-up = $upper(city)

>extract full-name = $upper(first + last)

Downshifting Strings ($Lower)

If you want to downshift all characters of a string expression to lowercase, use the built-in function $lower. This function can be used to downshift a single field, a complicated string expression, or any subpart of an expression. Both ASCII and Roman-8 characters are downshifted by $lower. For example,
>extract city-lower-case = $lower(city)

>extract city-state = $lower(city + state)

Trimming Spaces ($Trim, $Ltrim, $Rtrim)

Use one of three built-in string functions to remove leading or trailing spaces from a string expression. The three functions are:

$Trim: Remove leading and trailing spaces from the string expression.

$Ltrim: Remove leading spaces.

$Rtrim: Remove trailing spaces.

Strings in the If Command

You can do comparisons with byte-type fields in numerous ways using Suprtool. These powerful features minimize the number of tasks you must execute in order to select the data you need. The fewer the number of tasks, the faster your data is delivered to the users and applications that need it.

You can combine byte-type fields together and use the built-in string functions to create string expressions. String expressions involve the + operator and any of the built-in string functions, which are $lower, $upper, $trim, $ltrim and $rtrim.

Fixed vs. Variable Length Strings

String comparisons are done using fixed- and variable-length strings. For most users, there should be no difference between the two types of strings. When doing string comparisons, Suprtool always pads shorter strings with spaces, with the one exception of comparing two fixed-length fields (see "Byte Fields" below).

String expressions involving the + operator or the $lower, $upper, $trim, $ltrim and $rtrim built-in functions are done using variable-length strings. Suprtool keeps track of the length of every string, and all operations are done using the actual string length. For fields, the length of the string is the length of the field. If you do not want to retain all the spaces in a field, use one of the built-in trimming functions.

When creating string expressions, string constants are created with the exact length of the constant. For example, the string "abc" is three characters long and the string "a" is one.

Byte Fields

For historical reasons, comparing two byte-type fields to each other is a special case. If the two fields are exactly the same length, Suprtool compares them completely. If one field is shorter, the comparison is done for the length of the shortest field. Suprtool does not check for spaces in the trailing characters of the longer field. For example,
>define short, 1,10  {10-character field}
>define long ,11,15  {15-character field}
>if   short = long
In this example, Suprtool compares the 10 bytes in the short field with the first 10 bytes of the long field, but ignores the last five bytes of the long field. If the expression on either side of the equal sign consisted of more than one field (using the + operator) or involved any of the built-in string functions, such as $lower, $upper, $trim, $ltrim and $rtrim, Suprtool would have compared both sides of the equal sign by padding the shorter field with spaces. It is only the case where you are directly comparing one byte-type field to another that Suprtool uses the length of the shortest field for the comparison.

Trimming Spaces ($Trim, $Ltrim, $Rtrim)

Use one of three built-in string functions to remove leading or trailing spaces from a string expression. The three functions are:

$Trim: Remove leading and trailing spaces from the string expression.

$Ltrim: Remove leading spaces.

$Rtrim: Remove trailing spaces.

Because Suprtool pads shorter strings with spaces when doing comparisons, trimming spaces is most useful when creating a combined string with several fields. For example, you might want to combine a person's first and last name (including a space between the two):

>if $trim(first) + " " + $trim(last) = "Joe Smith"

Mixed Case ($Upper and $Lower)

By default, Suprtool does an exact match when comparing two string expressions. If the expressions vary in the capitalization of characters, Suprtool finds them to be unequal. To do caseless string comparisons or pattern matches, use the $upper or $lower functions. Both ASCII and Roman-8 characters are shifted by $upper and $lower. For example,
>if $upper(city) = "VANCOUVER"

>if $lower(city) = "edmonton"
Note that if you use the $upper or $lower functions, Suprtool does not shift any constants in the comparison. You must explicitly specify the constants in the correct case or you can use $upper or $lower with the constant:
>if $upper(city) = $upper("vancouver")
Use the $upper or $lower functions for caseless pattern matching. As with other comparison operators, you must specify constants in the correct case when doing pattern matching:
>if $upper(city) == "VAN@"

>if $lower(city) == "ed@"
You can also use $upper and $lower with string expressions that combine many fields and string functions as shown in the following example:
>if $read
-  $upper($trim(first) +
-       " "       +
-       $trim(last))
-  = "JOE SMITH"
-
Say for example you wanted to find all of those customers in New York City, but your data has combinations of New York, NEW YORK and New YOrk. You can find all of these records by doing the following:
  >if $upper(city) = "NEW YORK"

Multiple Steps in One Pass

Below is an example of how you can use the string functions to format an Address line out of three separate fields, with one Suprtool command and in one pass.

The sample file with address information:

>form testaddr
    File: TESTADDR.GROUP.ACCT     (SD Version B.00.00)
       Entry:                     Offset
          NAME                 X30     1
          STREET               X20    31
          CITY                 X20    51
          PROV-STATE           X2     71
          COUNTRY              X20    73
    Limit: 10000  EOF: 15  Entry Length: 92  Blocking: 44
You can now combine fields and constants with the spaces trimmed with one single extract command, as follows:
>in testaddr
>def address3,1,40
>ext name,street
>ext address3 = $trim(city) + "," + prov-state + " " + $trim(country)
>num 1
>list
>xeq
The result is a neatly formatted address line ready for printing on labels.
>IN TESTADDR.NEIL.GREEN (0) >OUT $NULL (0)
NAME            = Neil Armstrong
STREET          = 123 54th St West
ADDRESS3        = New York,NY U.S.A
Note that if the output had been sent to a self-describing file, the field "address3" would have contained the result of the expression. This technique can be used in a range of applications, including date reformatting, firstname and lastname concatenation (with intervening blank) for generating form letters, etc, all in a single task.