                               Managing Strings

                                         "When gold argues the cause,
                                          eloquence is impotent."
                                                   Pubilius Syrus
                                                  "Moral Sayings"
                                                   1st Century BC

Introduction

          The GOLDSTR unit contains all the string management routines
     needed to support any sophisticated DOS application. The unit
     includes the following:

          Functions which make predefined adjustments to strings
          Support for character testing and conversion
          Functions which convert numbers to and from strings
          String encryption to protect your data
          String Adjustment

          Gold defines a user input with three basic variables: the
     keystroke or mouse action, the mouse X coordinate and the mouse Y
     coordinate. These three variables are defined in the KeyVars record
     as LastKey, LastX and LastY.

     Replicate(N : byte; Character:char): string;

          Constructs a string of repeated characters. This routine uses
     memory moves which are much faster than a for loop.

     PicFormat(Input,Picture:string;Pad:char;RightJustify:boolean):
                                                              string;

          Returns a formatted string using the format characters '!@*#'.
     See chapter 16 for a complete discussion on formatting characters.

     TruncFormat(Input:string;Start,Len:byte; Pad:char):string;

          Truncates (or expands) a string beginning at a specified
     character position. If Start is greater than 1, character positions
     less than Start are truncated. If Len is greater than the remaining
     string, then the remaining string is padded to a length of Len
     using the Pad character.

     Squeeze(L:char;Str:string;Width:byte): string;

          Squeezes a string to the length defined by width, removing
     characters from the beginning or the end of the string if
     necessary. If  'L' is passed then the left portion of the string is
     retained, otherwise the right portion is retained.

          The returned string appears as if the string doesn't fit in
     the space allocated. This is accomplished by adding the squeeze
     character string. GoldStr defines a variable, StrVars.SqzChars
     which by default is a double dot string (..).

     FirstCapitalPos(Str:string): byte;

          Returns the position of the first capital letter contained in
     the passed string. A zero is returned if no capital letters are
     encountered.

     FirstCapital(Str:string): char;

          Returns the first capital letter encountered in the passed
     string. If no capital letters are encountered then a null character
     is returned.

     PadLeft(Str:string;Size:byte;ChPad:char):string;

          Left justifies the passed string, padding with ChPad, if
     necessary, to a length indicated by size.

     PadCenter(Str:string;Size:byte;ChPad:char):string;

          Centers the passed string within a string, padding with ChPad,
     if necessary, to a length indicated by size.

     PadRight(Str:string;Size:byte;ChPad:char):string;

          Right justifies the passed string, padding with ChPad, if
     necessary, to a length indicated by size.

     Pad(PadJust:gJust;Str:string;Size:byte;ChPad:char):string;

          If your application requires that the justification be
     determined at runtime then this is the routine for you. Pad
     incorporates all three by allowing you to specify the proper
     justification, Left, Right, or Center.

     TabSubStr(Source:string; TabCount:byte):string;

          This routine permits simple parsing of a delimited string
     using a single delimiter. It is used extensively within the toolkit
     itself. TabSubStr extracts the string immediately before the
     delimiter defined by TabCount.

          The GoldStr unit defines a global variable called
     StrVars.TabBreak which by default is the vertical split bar.

     An example of using TabSubStr follows:

          const UserStr = 'Silver|Bronze|Gold|Brass';

          var SubStr: String;
          begin
             SubStr := TabSubStr(UserStr,3);
             { SubStr will now be 'Gold' }
          end;

     Last(N:byte;Str:string):string;

          Extracts the last part of a string beginning at a specified
     position. If N is greater than the length of the passed string,
     only the string is returned.

     First(N:byte;Str:string):string;

          Extracts the first part of a string. Beginning at position 1,
     First returns N number of characters. If N is greater than the
     length of the passed string, the entire string is returned.

     SetUpper(Str:string):string;

          Converts all alpha characters of the passed string to upper
     case.

     SetLower(Str:string):string;

          Converts all alpha characters of the passed string to lower
     case.

     SetProper(Str:string):string;

          Converts the first character of each word in the passed string
     to upper case while the remaining characters are converted to lower
     case.

     AdjCase(NewCase:gCase;Str:string):string;

          Returns an appropriately adjusted string. If your application
     requires that the case of words be modified during execution,
     AdjCase incorporates all three by allowing you to specify the
     proper case; Upper, Lower or Proper. The type gCase defines one
     other enumeration called Leave, which does nothing to the passed
     string. Just leaves it unaltered.

     OverType(N:byte;StrS,StrT:string):string;

          Places one string "on top of" another string and overlays the
     underlying characters. The function is passed three parameters; the
     character position in the target string to start the overtyping,
     the source string, and the target string.

     Strip(L,C:char;Str:string):string;

          Returns the string with a specific character C removed. The
     function is passed three parameters; a character to indicate which
     part of the string to strip, the character to strip, and the source
     string. The strip can be performed on the left of the string by
     specifying the L parameter with one of the following characters:

          'L' - Removes the leftmost specified characters.
          'R' - Removes the rightmost specified characters.
          'B' - Removes the leftmost and rightmost characters.
          'A' - Removes all specified characters.

     LastPos(C:char;Str:string):byte;

          Returns a byte indicating the position of the last occurrence
     of a character in a string. If the character is not found, a zero
     is returned. The function is passed two parameters; a character to
     search for, and the source string.

     PosAfter(C:char;Str:string;Start:byte):byte;

          Returns a byte indicating the position of the first occurrence
     of a character, starting from a specified position in the string.
     If the character is not found, or if Start is greater than the
     length of the passed string, a zero is returned.

     LastPosBefore(C:char;Str:string;Last:byte):byte;

          Returns a byte indicating the position of the last occurrence
     of a character, up to a specified part fo the string. The search
     begins at character 1 and continues through the character specified
     by Last. A zero is returned if the character is not found.

     NthPos(Nth:byte;St,Src:string): byte;

          Returns a byte indicating the position of the Nth occurrence
     of a substring in a string. A zero is returned if the substring is
     not found.

     PosWord(Wordno:byte;Str:string):byte;

          Returns the character position of a specified word in a
     string.

     WordCnt(Str:string):byte;

          Counts and returns the number of words contained in a string.

     ExtractWords(StartWord,NoWords:byte;Str:string):string;

          Beginning at a specified word, extracts a specific number of
     words from a string.

String and Number Conversions

          The following three functions should be used to test whether a
     string can be successfully converted to its numerical equivalent:

     ValidInt(Str:string):boolean;

          Returns TRUE if the string can be converted to an integer.

     ValidHEXInt(Str:string):boolean;

          Returns TRUE if the source string represents a valid
     hexadecimal number.

     ValidReal(Str:string):boolean;

          Returns TRUE if the string can be converted to a real.

     The following functions enable string and number conversion:

     StrToInt(Str:string):integer;

          Converts a valid numeric string to an integer value. If the
     string does not represent an integer value, a zero is returned, and
     an error code of 1004 is assigned to LastStrError.

     StrToLong(Str:string):Longint;

          Converts a valid numeric string to a longint value. If the
     string does not represent a longint value, a zero is returned, and
     an error code of 1002 is assigned to LastStrError.

     IntToStr(Number:longint):string;

          Converts a whole number to its string equivalent.

     StrToReal(Str:string):extended;

          Converts a valid real string to a real. If the string does not
     represent a real value, a zero is returned, and an error code of
     1003 is assigned to LastStrError.

     RealToStr(Number:extended;Decimals:byte):string;

          Converts a real to its string equivalent. If the number of
     decimal places is passed as FLOATING (a constant), the function
     will return only the significant digits.

     IntToHEXStr(Number:longint;Width:integer):string;

          Returns a string representing the value of a hexadecimal
     number.

     HEXStrToLong(Str:string):longint;

          Converts a hexadecimal string and returns a longint. If the
     string is not a valid hex number, a zero is returned, and an error
     code of 1002 is assigned to LastStrError.

     RealToSciStr(Number:extended; D:byte):string;

          Returns a real number converted to a scientific notation
     string. The second parameter identifies the number of decimal
     places.

     NthNumber(InStr:string;Nth:byte) : char;

          This function returns a number in character form. Gold
     searches InStr, counting each occurrence of a number character.
     When N number characters have been counted, the value of the Nth
     character is returned. For example, if the string '02/20/48' is
     passed, and the N parameter is passed as 5, the character '4' would
     be returned, i.e. the fifth number in the string has a value of 4.

Character Evaluation and Case Conversion

     IsUpper(K:word): boolean;

          Returns TRUE if the value represented by K is an upper case
     character.

     IsLower(K:word): boolean;

          Returns TRUE if the value represented by K is a lower case
     character.

     IsDigit(K:word): boolean;

          Returns TRUE if the value represented by K is a digit ranging
     from 0 to 9.

     IsLetter(K:word): boolean;

          Returns TRUE if the value represented by K is an alpha
     character.

     IsPunctuation(K:word): boolean;

          Returns TRUE if the value represented by K is a punctuation
     character.

     GetUpCase(Ch:char):char;

          Converts the character represented by Ch to its upper case
     equivalent.

     GetLoCase(Ch:char):char;

          Converts the character represented by Ch to its lower case
     equivalent.

     CapitalWord(W:word):word;

          Converts the character represented by W to uppercase and
     returns the word value of the capital letter.

String Encryption

          Data encryption has been the study of mathematicians and R & D
     teams since man determined that it was necessary to protect certain
     information. We would never attempt to compete with any of the
     highly complex methods of data encryption that are employed today.
     However, we have implemented an extremely simple but useful form of
     encryption. Each character of the passed string is encrypted using
     the XOR operator in conjunction with an encryption code. The
     variable StrVars.EncryptionCode, which is of type word, affects the
     content of the encrypted string. By default the encryption code is
     134, but may be changed.

          If you are going to store the final encrypted strings in text
     files, it is important to keep the value of StrVars.EncryptionCode
     between 128 and 255. Values between 0 and 127 occasionally produce
     a Ctrl-Z or EOF character. This produces a premature end-of-file
     when the text file is being retrieved from disk.

     EnCode(Str: string): string;

          Converts the passed, readable string, to an unreadable string.

     DeCode(Str: string): string;

          Converts the passed, unreadable string, to a readable string.

          One valuable use of string encryption is to store encoded
     constants in a program, such as passwords. You can compare the
     user's input to the function call, DeCode(<constant>). The
     probability of someone locating and decoding your embedded password
     in the final, compiled program is, at best, slim to none. The
     encoded constants would be generated by another small utility
     program that you would write.

Miscellaneous

          Listed below are some other string management functions that
     couldn't find a home anywhere else:

     CharCount(Ch:Char;Str:string):byte;

          Returns the total number of times Ch occurs in Str.

     WidestLine(Str:string):byte;

          Searches for the embedded line break character and returns the
     length of the longest line-element. The line break character is
     defined as a global  variable, StrVars.LineBreak. Its default is
     the vertical split bar.

     LineCount(Str:string):byte;

          A bit different from the obvious appearance, LineCount returns
     the number of elements contained in a <LineBreak> delimited string.

     LastStrError: integer;

          Returns the code of the last error generated by a GoldStr
     routine.
