Title   : Wild Card String Compares, Token String Operations.
Keywords: WILD CARDS TOKENS STRING SUBSTRING FUNCTIONS UDF SOURCE CODE

This package contains five functions used to extract delimited fields or
"Tokens" from strings.  The Token-Delimiting character sequence is passed as
one of the parameters to these functions.  Also included is a sixth function
written in C which allows comparing a string containing Wild Card characters
against a literal string.  Returns True/False.  Includes OBJ's and SOURCE
CODE for all functions.

I have been using these string functions for nearly a year in most of my
applications, and have found no bugs in them.  I have included the source
code so that you may see how they work, and possibly modify them to suite
your personal needs.  But please DO NOT distribute them in a modified state.
If you have any questions, please leave me mail (address 72037,3222 -
Patrick Weisser).

The six functions I have included in this package were taken from my
personal library of over 100 functions.  I have found it convenient to
maintain the object code for all my Clipper and C functions in a single
Microsoft .LIB file which I reference during LINK time.  This is because:

  1) I have many different applications which use some but not all the
     functions of my library.
  
  2) Single functions often reference other functions within my library.

  3) Since all my applications look to the same library, I need only update
     a single "master" copy of each library function for all applications
     to have an updated version next time they are linked.

  4) During LINK time, the linker will only include in the final EXE file
     the code for functions which I have explicitly referenced in the
     application being linked.

In my master library, each function lives in a separate .PRG or .C file. 
This enables my MAKE command file to maintain a single .OBJ file for each
library function.  The Microsoft Library Manager then takes these discreet
OBJ's and combines them together in a single library ".LIB" file.

Included in this .ARC file should be the following four files:

  1) Str_Fun.Txt:  This file -- contains informational text.

  2) Str_Fun.Prg:  The source code for the select Clipper functions from my
                   library.  For ease of viewing, I have combined the
                   separate .PRG files that I have chosen from my library
                   into this single file.

  3) Str_Fun.C  :  The source code for the single Wild Card String Compare C
                   function from my library.  

  3) Str_Fun.Lib:  The Library which you must reference in your Link auto-
                   response file to allow your linker access to the Object
                   Code of the functions I have included.  For example, your
                   Freeformat .LNK file might contains the following
                   instructions:

                   LIBRARY C:\Clipper\Clipper\Extend
                   LIBRARY C:\Clipper\Clipper\Clipper
                   LIBRARY C:\Clipper\Str_Fun\Str_Fun
                   MAP = Your_App.Map
                   FILE MainProg, App_Mod1, App_Mod2, App_Util
                   OUTPUT = Your_App.Exe

                   The third LIBRARY command references the "Str_Fun.Lib"
                   file, and tells the linker to include the code for any
                   of the six functions from "Str_Fun.Lib" you may have used
                   in your application.


Following are some examples on how to use the functions in this package. 
Before reading them, you should look at the source code for each function,
since the Heading of each function contains a discussion on function usage
and PARAMETERS.


THE "_wc_cmp()" FUNCTION:
------------------------
Of the six functions included, this is the only one written in C.  It is
used to compare a string containing DOS Wild Card characters ("?" and "*")
against another string of characters.  This is a very powerful function
since you may use it in your applications to allow users to embed Wild Cards
in database search keys.  For example, if searching for the name
"Fitswatterman", the user might simply enter "Fit*man".  Remember that this
is a C function, and you must precede it with an underscore "_" character.

Since this function returns a logical value, it can easily be used with the
LOCATE command like this:

LOCATE FOR _wc_cmp( "Fit*man", Name_Field )

...where "Name_Field" is the field in the currently selected database
containing individual's last names.  With a some additional logic, it is
also possible to use this function with the SEEK command.  Here's how you
would do it:

  1) Prompt the user for a name to search for, insisting that he enter at
     least one literal character before the first Wild Card character. 
     Store the name the user entered in a variable called "Search_Key".
  
  2) Using the other string analysis functions I have included in this
     package, extract from the user-entered search key all the literal
     characters which occur before the first Wild Card character, and store
     them in a variable (we'll call it "Chars_Before_WC").  If the user
     entered "Fit*man" for the search key, then "Chars_Before_WC" would
     equal "Fit".
  
  3) Do an Indexed SEEK (with EXACT off) on the contents of the
     "Chars_Before_WC" variable like this:
     
     SEEK( Chars_Before_WC )
  

  3) If the SEEK was successful, begin the following loop:
  
     Name_Found = .F.

     SET EXACT OFF

     WHILE( ( Field_Name == Chars_Before_WC ) .AND. !EOF() )

       IF( _wc_cmp( Search_Key, Name_Field ) )
         Name_Found = .T.
         EXIT
       ENDIF

       SKIP

     ENDDO

If the variable "Name_Found" is true at when the loop in step three
terminates, then you will have found a name in the database complying with
the user's Wild Card-Laden search key.



THE "TOKEN" FUNCTIONS:
---------------------
The rest of the string functions I have included deal with the concept of a
"Token".  A Token is a sequence of one or more characters within a character
string.  Within strings, Tokens are usually separated by a single character
called a Delimiter.  You are probably familiar with comma-delimited database
files.  These files simply contain lines of character strings.  Fields or
"Tokens" within these strings are Delimited by commas.

Quite simply, the Token functions deal with "getting at" and extracting
tokens (or fields) from strings.  Also, these functions will accept a
Delimiter that is more than one character in length.  They also have the
ability to ignore null (empty) tokens.

Following are descriptions and examples for each of the Token functions. 
Please refer to the SOURCE CODE HEADER for each function for a detailed
discussion of the parameters each function expects.


THE "But_Last()" FUNCTION:
-------------------------
Given a string of delimited Tokens, the delimiting character sequence, and
whether or not to ignore null tokens, this function will remove the Last
Token from the string, returning the Rest of the Tokens of the string.  The
delimiting character sequence separating the Last Token from the rest of the
string is also removed.  

EXAMPLE USE                                           RESULT
-----------                                           ------
But_Last( "A Day In The Life", " ", .F. )             "A Day In The"

But_Last( "A|Day|In|The|Life", "|", .F. )             "A|Day|In|The"

But_Last( "A|Beatles|Classic|", "|", .F. )            "A|Beatles|Classic"

But_Last( "A|Beatles|Classic|||||", "|", .F. )        "A|Beatles||||"

But_Last( "A|Beatles|Classic|", "|", .T. )            "A|Beatles"

But_Last( "A|Beatles|Classic|||||", "|", .T. )        "A|Beatles"



THE "Last_Token()" FUNCTION:
---------------------------
Given a string of delimited Tokens, the delimiting character sequence, and
whether or not to ignore null tokens, this function will find and return
the last Token in the string.  If the list is empty, a null string will be
returned.

EXAMPLE USE                                           RESULT
-----------                                           ------
Last_Token( "Dr. Tom Baker", " ", .F. )               "Baker"

Last_Token( "Dr.|Tom|Baker", "|", .F. )               "Baker"

Last_Token( "The|Fourth|Doctor|", "|", .F. )          null string ("")

Last_Token( "The|Fourth|Doctor|", "|", .T. )          "Doctor"

Last_Token( "The|Fourth|Doctor|||||", "|", .T. )      "Doctor"



THE "But_First()" FUNCTION:
--------------------------
Given a string of delimited Tokens, the delimiting character sequence, and
whether or not to ignore null tokens, this function will remove the first
Token from the string, returning the Rest of the Tokens of the string.  The
delimiting character sequence separating the first Token from the rest of
the string is NOT returned.

EXAMPLE USE                                           RESULT
-----------                                           ------
But_First( "Dr. Peter Davidson", " ", .F. )           "Peter Davidson"

But_First( "Dr.|Peter|Davidson", "|", .F. )           "Peter|Davidson"

But_First( "|The|Fifth|Doctor", "|", .F. )            "The|Fifth|Doctor"

But_First( "|||||The|Fifth|Doctor", "|", .F. )        "||||The|Fifth|Doctor"

But_First( "|The|Fifth|Doctor", "|", .T. )            "Fifth|Doctor"

But_First( "|||||The|Fifth|Doctor", "|", .T. )        "Fifth|Doctor"




THE "Get_Token()" FUNCTION:
--------------------------
Given a character string of delimited Tokens, the number of the desired
Token, the delimiting character sequence, and whether or not to ignore null
tokens, this function will extract the Nth Token from the string and return
it.  A null string will be returned if the end of the token string is
encountered before the desired token is encountered.

EXAMPLE USE                                                     RESULT
-----------                                                     ------
Get_Token( "Time And Relative Dimensions", 3, " ", .F. )        "Relative"

Get_Token( "Time|And|Relative|Dimensions", 3, "|", .F. )        "Relative"

Get_Token( "Time||And|Relative|Dimensions", 3, "|", .F. )       "And"

Get_Token( "Time|||And|Relative|Dimensions", 3, "|", .F. )      Null Token ("")

Get_Token( "Time||And|Relative|Dimensions", 3, "|", .T. )       "Relative"

Get_Token( "Time|||And|Relative|Dimensions", 3, "|", .T. )      "Relative"

Get_Token( "Time|And|Relative|Dimensions", 4, "|", .F. )        "Dimensions"

Get_Token( "Time||And|Relative|Dimensions", 4, "|", .F. )       "Relative"

Get_Token( "Time|||And|Relative|Dimensions", 4, "|", .F. )      "And"

Get_Token( "Time||And|Relative|Dimensions", 4, "|", .T. )       "Dimensions"

Get_Token( "Time|||And|Relative|Dimensions", 4, "|", .T. )      "Dimensions"



THE "Token_Count()" FUNCTION:
----------------------------
Given a string of delimited Tokens, the delimiting character sequence, and
whether or not to ignore null tokens, this function will return the number
of delimited Tokens in the character string.

EXAMPLE USE                                                     RESULT
-----------                                                     ------
Token_Count( "Time And Relative Dimensions", " ", .F. )         4

Token_Count( "Time|And|Relative|Dimensions", "|", .F. )         4

Token_Count( "Time||And|Relative|Dimensions", "|", .F. )        5

Token_Count( "Time|||And|Relative|Dimensions", "|", .F. )       6

Token_Count( "|Time|||And|Relative|Dimensions", "|", .F. )      7

Token_Count( "Time|||And|Relative|Dimensions|", "|", .F. )      7

Token_Count( "Time||And|Relative|Dimensions", "|", .T. )        4

Token_Count( "Time|||And|Relative|Dimensions", "|", .T. )       4

Token_Count( "|Time|||And|Relative|Dimensions", "|", .T. )      4

Token_Count( "Time|||And|Relative|Dimensions|", "|", .T. )      4


I have been using Clipper professionally for over four years now, and I have
come to really love the language and the power it offers.  We also use C a
great deal where I work, and the two languages compliment each other 
perfectly -- especially since they now share the same Microsoft Library.

Again, if you have any questions or comments, please leave me mail.

Patrick Weisser
72037,3222

<End Of Document>.
