GETOPTS.BTM version 1.0 - DOCUMENTATION

SUMMARY 

   The purpose of GETOPTS.BTM is to allow 4DOS batch files to support 
   Unix-style option switches on the command line. The idea is that a 
   4DOS batch file can "call" GETOPTS, which locates and parses each 
   option and sets environment variables, while the parent batch file 
   determines which switches are allowed and handles other details. I 
   wrote GETOPTS to mimic, within reason, the operation of "getopts" 
   in the Unix/GNU/Linux environment.

   GETOPTS.BTM was written by Eric Pement (pemente@northpark.edu) in 
   December 2001. Your feedback and suggestions for improvement are 
   welcome. It is freely offered to the 4DOS user community under the 
   terms of the GNU General Public License ("copyleft").

SYNTAX:
   
   When GETOPTS is active, the following command lines are equivalent:

      cmd -a -b -C -w foo -W "one two" word1 word2
      cmd -ba -wfoo -C -W"one two" -- word1 word2
      cmd word1 word2 -abCwfoo -W"one two"
      cmd -W "one two" word1 -bw foo word2 -aC

   Given the example above, GETOPTS will create and return the 
   following environment variables to the parent batch file:
    
      OPTIONS=a b C!     - a list of character switches used
      STRINGS=LC_w UC_W  - a list of string switches used
      LC_W=foo           - each string switch has a separate variable
      UC_W="one two"     - case-sensitivity is kept by LC_ or UC_

   Moreover, the command tail &% will be reset to "word1 word2" since 
   all the options and option-arguments have been stripped out.

FEATURES SUPPORTED:

   * Position-independent switch clustering
        "-a -b -c" equals "-ac -b" equals "-c -ba" equals "-bac".

   * 3 types of switches:
        character switches, string switches, and numeric switches.

   * Case-sensitive character switches
        "-d" and "-D" are recognized as different options. Character 
        switches are alphabetic only (a-z or A-Z), and cannot take an 
        argument or parameter.

   * Case-sensitive string switches
       String switches are one character (a-z or A-Z) which must take 
       an argument or parameter. Thus, -f and -F may accept different 
       arguments which may be passed as '-fhello' or '-F goodbye'. 
       Multi-word arguments are permitted if they are enclosed in 
       double quotes, such as '-g "one or more words"'.       

   * Numeric options
       Numeric options may be permitted or forbidden. If permitted, 
       -123 will set N=123, and --456 will set N=-456.

   * Switches and argument removed from the command tail
       Under GETOPTS, all switches and switch parameters on the 
       command line are placed into appropriate environment variables 
       (see SYNTAX: for examples, above). The switches are then 
       removed from the command tail (&%). If the batch file executes 
       external utilities, the utility's own option syntax can be used 
       (e.g., /opt1, opt2:opt3, word=opt4, etc.).

   * Halt on invalid options
       The parent batch file contains a list of permissible letters for 
       character and string options, and tells whether numeric options 
       are allowed. The GETOPTS batch file first checks the list itself 
       and then checks each option on the command-tail for validity. 
       GETOPTS will halt if it detects invalid options, but it can be 
       set to "pass" invalid options through instead.

   * Switch termination
       To permit processing filenames which begin with leading 
       hyphens, the switch "--" terminates switch processing, and the 
       rest of the command tail is returned untouched to the parent 
       batch file. Further, a single hyphen "-" by itself is passed 
       without modification to the command tail.

USING GETOPTS:

   The "parent" batch file should contain (at least) a single block of 
   6 to 12 lines of code, which sets up necessary variables and calls 
   the GETOPTS.BTM parser. Here is a sample batch file using GETOPTS, 
   with each line numbered for reference below. I have listed more 
   lines than I normally would use.

           @echo off
        1: setlocal
        2: if "%1" EQ "" .or. "%1" EQ "-?" .or. "%1" EQ "/?" goto syntax
        3: set F0=%@truename[%0]
        4: set chr_opts=a b C D
        5: set str_opts=y Y z Z
        6: set num_opts=Y
        7: set pass_inv=Y
        8: call getopts.btm %&
        9: if %? == 1 ( pause %+ goto syntax )
       10: for %a in ( %rev_args ) do shift /%a
       11: for %b in ( %options ) do gosub parse1
       12: for %c in ( %strings ) do gosub parse2
       13: cmd %param1 %param2 %&
       14: goto end
           :syntax
           TEXT
                Issue a custom help message here, and 
                   -l   List all valid
                   -o   option
                   -s   switches also!
           ENDTEXT
           :end
           unset /q chr_opts str_opts num_opts pass_inv [etc.]
           endlocal

   At the very end of the batch file, I normally put the syntax or 
   "help" messages to dispaly what options are available. After the 
   syntax messages, "cleanup" commands help to unset any environment 
   variables, remove temporary files (if any), and ENDLOCAL if needed.  
   GETOPTS does not create any temporary files during its execution.

   1: setlocal

      Setlocal saves (among other things) the current environment and 
      alias list, so you can remove and manipulate environ. variables 
      and aliases without affecting the master environment. Setlocal 
      is recommended but not required for GETOPTS. If you use it, 
      don't forget to add ENDLOCAL to the end of the batch file.


   2: if "%1" EQ "" .or. "%1" EQ "-?" .or. "%1" EQ "/?" goto syntax

      This command is recommended but not required for GETOPTS. The 
      switch "-?" should be placed here, because the GETOPTS parser 
      will see "-?" as a symbol and issue an error message since 
      switches must be alphabetics only. You probably want "-?" to 
      generate a help message, not an error message.


   3: set F0=%@truename[%0]

      Required for GETOPTS, which uses the name of the parent batch 
      file in various syntax or option errors. %F0 also prevents 
      unwitting users from trying to run GETOPTS.BTM by itself.


   4: set chr_opts=a b C D
   5: set str_opts=y Y z Z
   6: set num_opts=Y

      Any or all of these may be used. None is required for GETOPTS, 
      but GETOPTS does nothing if no options are defined at all! In 
      both CHR_OPTS and STR_OPTS, the only valid characters are A-Z or 
      a-z. The list is case-sensitive, so both "b" and "B" may occur 
      in the list. Separate letters by one space each; don't do 
      anything like "set chr_opts=efgh".

      CHR_OPTS is a list of all permissible character options.

      STR_OPTS is a list of all permissible string options. They MUST 
      be followed by an argument on the command line, or an error 
      message will be issued (see SYNTAX: and FEATURES, above). In the 
      example above, 'y' is a string option and 'a' is a character 
      option. Thus, in the following commands:
                      
         cmd -ya
         cmd -y -a

      "a" and "-a" (respectively) will be interpreted as arguments to 
      -y. A new variable, LC_Y, will contain either "a" or "-a".

      If NUM_OPTS is set to 'y' or 'Y', then the command line may 
      accept numeric options of the form "-234" or "-0" or "--56", and 
      GETOPTS will set the variable N to 234, 0, or -56 in each case. 
      Numeric variables must be whole numbers only. Decimal values 
      like -2.71828 are truncated to integers (N=2). Remember that 
      numeric options can be forbidden, while string options may 
      nonetheless contain numeric values (e.g., -z123 or -Z 2.537).


   7: set pass_inv=Y

      Not required for GETOPTS, but if used, it will pass invalid 
      switches as part of the command tail without causing an error. 
      For example, if you want to "add" a switch to a utility that 
      already uses hyphen-prefixed switches, setting this variable 
      will let you use %CHR_OPTS to add your new option while not 
      halting when it encounters other options.

      If this value is set to Y, the token is not parsed beyond the 
      first letter. For example, if "%CHR_OPTS=x b" and the command 
      line looks like this:

         cmd -b -rx foo

      then %OPTIONS will contain "b" only and the command tail (%&) 
      will be set to "-rx foo".
 

   8: call getopts.btm %&
   9: if %? == 1 ( pause %+ goto syntax )
   10: for %a in ( %rev_args ) do shift /%a

      The 3 lines above are absolutely required for GETOPTS. In line 
      #9, "if %? == 1" means a syntax error was found. PAUSE is 
      helpful, but may be omitted. The "%+" is a 4DOS variable for the 
      command separator, in case it has been changed from its default 
      setting of "^". GOTO SYNTAX may be changed to another label 
      name, such as "goto help", but it's a good idea to have a text 
      area which provides a list of valid option switches. Line #10 
      removes the option switches from the command tail. 
      

   11: for %b in ( %options ) do gosub parse1
   12: for %c in ( %strings ) do gosub parse2

      If CHR_OPTS was set, GETOPTS creates the variable %OPTIONS, a 
      list of each character option used on the command line, 
      separated by one space. A '!' is placed after each capital 
      letter to enable easier parsing in the parent batch file. Thus, 
      if %OPTIONS == "k l M!", the "M!" indicates a capital M was used 
      as an option switch.

      If STR_OPTS was set, GETOPTS creates %STRINGS, a list of each 
      string option used on the command line. The list in %STRINGS 
      looks something like "UC_P LC_a LC_n". The UC means upper-case, 
      and the LC means lower-case. Each token in %STRINGS also exists 
      as a separate environment variable, with the value assigned to 
      it on the command line. In the example used just now, three 
      additional variables would be set like so:

         UC_P=one
         LC_A=word
         LC_N="two or more words"

      The GOSUB command sends control to a label, parse1 or parse2. 
      These labels should be placed somewhere below line #14, and they 
      generally work best with the 4DOS SWITCH command (not to be 
      confused with option switches). Here is a sample routine for 
      line #11, above:

         :parse1
         SWITCH %b
         CASE a
            echo We have lower-case "a".
            set anyvar1=abc
         CASE a!
            echo We have capital "A".
            set anyvar1=def
         CASE b
            echo We have lower-case "b".
            set anyvar2=efg
         ENDSWITCH
         RETURN

      Note that there is never any DEFAULT case, since the only 
      possible options are those permitted by the %CHR_STR list.
      

   13: cmd %anyvar1 %anyvar2 %&                   
   14: goto end

       These are "required", but are not part of the GETOPTS 
       routine. After the option switches have been processed by the 
       GOSUB routine (above), control should pass to the main command 
       ("cmd"), with variables setting acceptable command parameters. 
       If desired, the command itself could be chosen by the CASE 
       statements.

       After the command executes, go to the :end label to do final 
       clean-up. Unset surplus variables, and end with ENDLOCAL if a 
       SETLOCAL command was used at the top of the parent file.


LIMITATIONS AND EXCEPTIONS:

   There is (as yet) no facility for setting or handling mutually 
   exclusive options. E.g., if -a and -b are both valid character 
   switches, but both cannot appear on the command-line together, 
   there is no facility for indicating and detecting this condition.

   There is no check to prevent using the same letter for both 
   character and string options. If the same letter is used in both 
   sets, GETOPTS will interpret it as a character option. The fact 
   that it also occurs as a string option will not be detected.

   If the same character option is used twice ("cmd -xyx"), the second 
   occurrence is ignored. The meaning is not negated or reversed, as 
   in some programs. If the same string option is used twice, an error 
   message is generated and the batch file quits.
   
   The 4DOS `backtick` operator, which permits several words to be 
   grouped together and passed as a single argument to a batch file, 
   cannot be used here. This is because the backticks are removed when 
   the command-line is passed to GETOPTS.BTM, and so GETOPTS sees each 
   term as a separate argument. The grouping feature is lost.

AUTHOR:

   The 4DOS version of GETOPTS v1.0 was written by Eric Pement 
   (pemente@northpark.edu) in December 2001. Please notify me if you 
   have suggestions for improvements. I will try to keep the latest 
   version of GETOPTS.ZIP in the 4DOS section of my webspace at
   http://www.student.northpark.edu/pemente/. If you can't find it, 
   e-mail me directly.

Completion date: January 1, 2002.

[end-of-file]
