home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / games / patterns.zip / TST.DOC < prev    next >
Text File  |  1988-03-15  |  15KB  |  367 lines

  1.  
  2.                              TST.EXE
  3.         A Batch File Tool for Testing Strings or Integers
  4.                Optionally with Unix-Style Patterns
  5.  
  6.                                by
  7.                        Robert A. Magnuson
  8.                          DMB, DCRT, NIH
  9.                        Bethesda, MD 20892
  10.                             Feb 1988
  11.  
  12.  
  13.  
  14. TST is used in DOS batch files to control branching by string or
  15. integer comparisons, or by pattern matching.
  16.  
  17.     [This document is intended to be read from the screen.
  18.     It contains some characters which will probably not print
  19.     correctly on a printer.]
  20.  
  21. A DOS command line that invokes TST contains a number of
  22. arguments.  The syntax is expressed by the following diagram:
  23.  
  24.         ┌───────────────────────────────────────┐
  25.         │       ┌─ d ─┐ compare as decimal       │
  26.         │       │     │  signed integers         │
  27.         │       ├─ e ─┤ <str> follows even       │         ┌────────────┐
  28.         │       │     │  if it starts with /     │         │             │
  29.    TST ─┴─ / ─┬─┤     ├─────────────────────┬──┴─ <str> ─┴─┬ <cmp> ┬──┴─
  30.               │ ├─ x ─┤ compare case exact   │               │       │
  31.               │ ├─ i ─┤ prompt for new <str> │ Null input    └──────┘
  32.               │ │     │  from stdin          │ for /i gets "(null)",
  33.               │ └─ p ─┘ pattern match        │ for /id gets -10001
  34.               └─────────────────────────────┘
  35.  
  36. First there may be an optional argument specifying various TST
  37. options.  Then there is the required string which is compared,
  38. one by one, with each of the following comparands until a
  39. successful comparison is achieved.
  40.  
  41.     The arguments can optionally be enclosed in double
  42.     quotes.  The enclosing quotes are stripped off and not
  43.     seen by TST.  Should you need to have a double quote
  44.     within an argument, the argument must be double quoted
  45.     and the internal double quote must be escaped by
  46.     preceding it with a backslash.  This treatment of the
  47.     double quotes is done by the argc/argv mechanism of the C
  48.     compiler. [TST is implemented in Borland TurboC.]
  49.  
  50. TST exits with ERRORLEVEL set to the ordinal number of the first
  51. comparand that compares (zero if none).  TST is normally followed
  52. by IF ERRORLEVEL statements which selectively invoke various
  53. batch file elements.
  54.  
  55. There are three main kinds of comparisons:
  56.  
  57.         ■  string
  58.  
  59.         ■  decimal integer
  60.  
  61.         ■  Unix-style, anchored pattern match
  62.  
  63. chosen via the presence (or absence) of various letters in an
  64. option arg.  String comparisons--as well as pattern matching--can
  65. ignore (upper or lower) case, or insist on exact case.
  66.  
  67. When interactive programming is required, TST can prompt for,
  68. then obtain, the <str> used in the comparisons.  TST prompts with
  69. the original <str>, then obtains a new one from stdin (normally
  70. the keyboard unless the input is being redirected).
  71.  
  72. OPTION ARGUMENTS:
  73.  
  74. TST options are specified by the presence or absence of various
  75. option letters in option arguments.  Any option argument must
  76. begin with a slash and must appear in front of the other kinds of
  77. arguments.  Any number of legal option letters can appear in an
  78. option argument.  Thus, you can have multiple option arguments,
  79. perhaps each with a single option letter (and each beginning with
  80. a slash), or just one option argument containing all of the
  81. option letters desired.  CURRENTLY, ALL LEGAL TST OPTION LETTERS
  82. ARE lower case.
  83.  
  84.     For the sake of readability, the above shown syntax
  85.     diagram shows only the case where all option letters
  86.     appear in the (at most one) option argument.
  87.  
  88. A TST syntax error occurs when illegal option letters appear,
  89. when inconsistent combinations of option letters appear, and when
  90. required arguments are missing.  'd' may not appear together with
  91. either 'x' or 'p'.  The <str> argument is required.  And when
  92. both 'p' and 'i' options are taken, at least one <cmp> is
  93. required.
  94.  
  95. When a syntax error occurs TST prints a boxed syntax diagram
  96. containing terse instructions on how to use TST.  This mechanism
  97. can be deliberately tripped in order to get on-screen help.  The
  98. suggested way is to invoke TST with no arguments--thus causing
  99. the no-<str) syntax error.  A second help screen giving pattern
  100. matching help is printed when the 'p' option is taken and no
  101. <str> appears.
  102.  
  103. STRING COMPARISON:
  104.  
  105. TST does string comparison when neither the /d option nor the /p
  106. option is in effect.  Case (upper or lower) is ignored unless the
  107. /x option has been taken.
  108.  
  109. DECIMAL INTEGER COMPARISON:
  110.  
  111. TST does integer comparison when the /d option is in effect.  The
  112. <str> and the <cmp>'s are interpreted as signed decimal integers.
  113. This means that as soon as an illegal integer byte is seen, the
  114. remaining bytes are ignored.  E.g., '23SKIDOO' is 23, and 'Hello'
  115. is 0.  A decimal <cmp> can contain two integers separated by ".."
  116. in which case the comparison succeeds if the <str> lies between.
  117.  
  118. PATTERN-MATCHING:
  119.  
  120. TST does pattern matching when the /p option is in effect.  Each
  121. <cmp> is a pattern that is matched in turn against the same
  122. <str>.  Case (upper or lower) is ignored unless the /x option has
  123. been taken.
  124.  
  125. A pattern is a string of characters.  We distinguish two kinds of
  126. characters:  normal and meta.  There are exactly nine
  127. metacharacters:
  128.  
  129.         . * + ? ^ $ [ ] \
  130.  
  131. The remaining characters are normal.  Metacharacters sometimes
  132. combine with normal characters as we will see.  Otherwise, a
  133. normal character simply matches itself.  The metacharacters
  134. behave as follows:
  135.  
  136.         A       matches
  137.         ─────   ────────────────────────────
  138.         .       any single byte
  139.         *       0 or more of the preceding
  140.         +       1 or more of the preceding
  141.         ?       0 or 1 of the preceding
  142.         [...]   any 1 of the enclosed bytes
  143.         [^...]  any byte not enclosed
  144.         ^       the beginning of the <cmp>
  145.         $       the end of the <cmp>
  146.         \α      α, where α is a metabyte
  147.         α\!ß    α or ß
  148.         \(α\)   α (grouped for precedence)
  149.         \δ      the δth group where δ is 1-9
  150.         \b      beginning/end of a word
  151.         \<      beginning of a word
  152.         \>      end of a word
  153.         \w      a word byte: [a-zA-Z0-9]
  154.         \W      a nonword byte: [^a-zA-Z0-9]
  155.  
  156. Note that the '\' metacharacter is used as an escape, i.e., to
  157. quote a metacharacter.  Thus to match, e.g., a period (as a
  158. normal character) you must use '\.'  If you leave out the
  159. backslash, the period alone will have its metacharacter meaning.
  160.  
  161. In the above explanation of the '*', '+' and '?' metacharacters,
  162. 'preceding' means 'the shortest possible preceding'.  Thus, 'ab+'
  163. matches 'ab', 'abb', etc., but not 'abab'
  164.  
  165. The square bracket metacharacters specify any one of the enclosed
  166. characters--known as a character class.  The minus sign has a
  167. special meaning as a range in a character class.  '[a-g]' can be
  168. used in place of '[abcdefg]'.  When appearing first in a
  169. character class, a circumflex indicates that the match is with
  170. any character not in the character class.  Thus, '[^0-9]' matches
  171. any non decimal-digit.  Most metacharacters lose their special
  172. status in a character class, and should not be escaped.  If a
  173. right square bracket is to be in a character class, it must
  174. follow immediately the beginning left square bracket.  If a minus
  175. sign is to be in a character class, it must appear as '---',
  176. i.e., a range containing only itself.  Since the square brackets
  177. do not nest, a left square bracket can easily be included in a
  178. character class.  E.g., '[][]' matches a right or a left square
  179. bracket.
  180.  
  181. TST's pattern match is anchored, i.e., the pattern must match the
  182. entire <cmp>.  This can be circumvented, e.g., the pattern
  183. '.*zyx.*' will find 'zyx' anywhere in a <cmp>.
  184.  
  185. Some pattern match examples follow:
  186.  
  187.         A                   matches
  188.         ────────────────── ───────────────────────
  189.         zyx                 zyx
  190.         f.x                 fax, fix and fxx
  191.         f\.x                f.x
  192.         f[aix]x             only fax, fix and fxx
  193.         \[[a-z]+\]          [hello] and [world]
  194.         \(suf\!pre\)fix     suffix or prefix
  195.         ba\(na\)*           banananana
  196.         [A-P]:              A:, C:, H:, etc
  197.         \([cd]:\)?\w        abc, c:zyx, d:cat, etc
  198.         \(abra\)\(cad\1\)*  abracadabracadabra
  199.  
  200.  
  201.     Due to a bug in PC DOS I have changed the alternative
  202.     (i.e., the "or") from '\|' to '\!'.  The vertical, '|',
  203.     is DOS's piping symbol.  Although doublequoting is
  204.     supposed to protect any redirection symbols in the
  205.     interior from being acted upon, under certain
  206.     circumstances DOS performs the redirection even though
  207.     doublequoted.
  208.  
  209. Please note that TST's pattern matching is done via REGEX.C from
  210. Free Software Foundation, Inc.
  211.  
  212. EXAMPLES:
  213.  
  214. Here is an example of (a portion of) a batch file that uses TST.
  215.  
  216.            .
  217.            .
  218.            .
  219.         :tryagain
  220.         stdo
  221.         stdo
  222.         echo I need to know how you want the generated files
  223.         echo to specify your home drive.  The choices are:
  224.         stdo
  225.         echo         1)     C:
  226.         echo         2)     D:
  227.         echo         3)     %%home%%
  228.         echo         4)     [I'll enter it myself]
  229.         stdo
  230.         tst/id "Enter choice (from 1 to 4) [1] :" 1 2 3 4 -10001
  231.         if errorlevel 5 goto cdrive
  232.         if errorlevel 4 goto mydrive
  233.         if errorlevel 3 goto homedrive
  234.         if errorlevel 2 goto ddrive
  235.         if errorlevel 1 goto cdrive
  236.         goto tryagain
  237.         :cdrive
  238.            .
  239.            .
  240.            .
  241.  
  242. The material preceding the TST invocation sets the stage for its
  243. use--by explaining what is to follow.  The TST invocation's first
  244. arg is '/id'--specifying a decimal comparison wherein the <str>
  245. is to be the prompt to be replaced by whatever is gotten from
  246. stdin.  The prompt, i.e., the <str>,
  247.  
  248.         Enter choice (from 1 to 4) [1] :
  249.  
  250. is doublequoted because it contains spaces which would make it
  251. eight arguments if unquoted.  Note that the prompt contains '[1]'
  252. meaning that the user can make this choice merely by hitting the
  253. ENTER key.  Then there are five comparands, the first four being
  254. the 1 through 4 choices, and the fifth being -10001 which is what
  255. TST gets for a null reply to a decimal prompt.  Since there are
  256. five comparands TST will set the ERRORLEVEL to 1 through 5 or 0
  257. (the last for a failure to match).  The TST invocation is
  258. followed by a sequence of IF ERRORLEVEL statements, the first
  259. being:
  260.  
  261.         if errorlevel 5 goto cdrive
  262.  
  263. Note that the meaning of this is to go to cdrive if the
  264. errorlevel is at least 5.  That is why the ERRORLEVEL tests are
  265. in reverse numerical order, i.e., an IF ERRORLEVEL 1 would
  266. succeed if the ERRORLEVEL was anything greater--say 5.  Each of
  267. the ERRORLEVEL statements send control to the appropriate part of
  268. the batch file.  Following the IF ERRORLEVEL's is a GOTO which is
  269. done only if the ERRORLEVEL is zero--meaning that the user
  270. entered a number out of the allowed range.  In this case, control
  271. is sent to :TRYAGAIN which reprompts the user.
  272.  
  273. Of course, if you don't want to check the ERRORLEVEL in
  274. descending order you can use double IF ERRORLEVEL's as in:
  275.  
  276.         if errorlevel 3 if not errorlevel 4 goto three
  277.  
  278. which checks for errorlevel 3 exactly.
  279.  
  280. The next example is the batch file I use to test TST.  It is a
  281. rich set of TST examples including, e.g., /i cases where the
  282. stdin does not come from the keyboard.  [See lines 18-23.]
  283.  
  284.  
  285.         ---------- tst-test.bat
  286.         [1]REM testing string compares against 3 cmp's
  287.         [2]tst abc abc de f
  288.         [3]if not errorlevel 1 goto error
  289.         [4]if errorlevel 2 goto error
  290.         [5]tst de  abc de f
  291.         [6]if not errorlevel 2 goto error
  292.         [7]if errorlevel 3 goto error
  293.         [8]tst f   abc de f
  294.         [9]if not errorlevel 3 goto error
  295.         [10]if errorlevel 4 goto error
  296.         [11]tst no  abc de f
  297.         [12]if errorlevel 1 goto error
  298.         [13]REM testing string compares for case sensitivity
  299.         [14]tst/x AbC abc
  300.         [15]if errorlevel 1 goto error
  301.         [16]tst/x AbC AbC
  302.         [17]if not errorlevel 1 goto error
  303.         [18]REM testing /i string compares
  304.         [19]echo abc>d:\tmp\junk1
  305.         [20]tst/i Prompt abc <d:\tmp\junk1 >d:\tmp\junk2
  306.         [21]if not errorlevel 1 goto error
  307.         [22]tst/i "<str>" Prompt <d:\tmp\junk2 >nul
  308.         [23]if not errorlevel 1 goto error
  309.         [24]REM testing /i string compare for null response
  310.         [25]stdo >d:\tmp\junk1
  311.         [26]tst/i "<str>" (null) <d:\tmp\junk1 >nul
  312.         [27]REM testing integer compares against 3 cmp's
  313.         [28]tst/d 123 123 4..6 -12
  314.         [29]if not errorlevel 1 goto error
  315.         [30]if errorlevel 2 goto error
  316.         [31]tst/d 4   123 4..6 -12
  317.         [32]if not errorlevel 2 goto error
  318.         [33]if errorlevel 3 goto error
  319.         [34]tst/d 05  123 4..6 -12
  320.         [35]if not errorlevel 2 goto error
  321.         [36]if errorlevel 3 goto error
  322.         [37]tst/d +6  123 4..6 -12
  323.         [38]if not errorlevel 2 goto error
  324.         [39]if errorlevel 3 goto error
  325.         [40]tst/d -12 123 4..6 -12
  326.         [41]if not errorlevel 3 goto error
  327.         [42]if errorlevel 4 goto error
  328.         [43]tst/d 3   123 4..6 -12
  329.         [44]if errorlevel 1 goto error
  330.         [45]tst/d 7   123 4..6 -12
  331.         [46]if errorlevel 1 goto error
  332.         [47]REM testing pattern matches against 3 cmp's
  333.         [48]tst/p A:    [ab]: [cd]: [h-p]:
  334.         [49]if not errorlevel 1 goto error
  335.         [50]if errorlevel 2 goto error
  336.         [51]tst/p D:    [ab]: [cd]: [h-p]:
  337.         [52]if not errorlevel 2 goto error
  338.         [53]if errorlevel 3 goto error
  339.         [54]tst/p o:    [ab]: [cd]: [h-p]:
  340.         [55]if not errorlevel 3 goto error
  341.         [56]if errorlevel 4 goto error
  342.         [57]tst/p e:    [ab]: [cd]: [h-p]:
  343.         [58]if errorlevel 1 goto error
  344.         [59]REM testing /pi pattern matches
  345.         [60]echo c:>d:\tmp\junk1
  346.         [61]tst/pi Prompter [a-z]: <d:\tmp\junk1 >d:\tmp\junk2
  347.         [62]if not errorlevel 1 goto error
  348.         [63]tst/pix "<str>" Prompter <d:\tmp\junk2 >nul
  349.         [64]if not errorlevel 1 goto error
  350.         [65]REM testing /pi pattern match for null response
  351.         [66]stdo >d:\tmp\junk1
  352.         [67]tst/pi "<str>" (n?ul?l) <d:\tmp\junk1 >nul
  353.         [68]:
  354.         [69]@echo off
  355.         [70]echo /
  356.         [71]echo  TST.EXE passed all tests
  357.         [72]echo \
  358.         [73]quitbat
  359.         [74]:
  360.         [75]:error
  361.         [76]@echo off
  362.         [77]echo /
  363.         [78]echo  TST.EXE failed!
  364.         [79]echo \
  365.         [80]:TST-TEST.BAT for testing TST.EXE, by Bob Magnuson
  366.  
  367.