home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
games
/
patterns.zip
/
TST.DOC
< prev
next >
Wrap
Text File
|
1988-03-15
|
15KB
|
367 lines
TST.EXE
A Batch File Tool for Testing Strings or Integers
Optionally with Unix-Style Patterns
by
Robert A. Magnuson
DMB, DCRT, NIH
Bethesda, MD 20892
Feb 1988
TST is used in DOS batch files to control branching by string or
integer comparisons, or by pattern matching.
[This document is intended to be read from the screen.
It contains some characters which will probably not print
correctly on a printer.]
A DOS command line that invokes TST contains a number of
arguments. The syntax is expressed by the following diagram:
┌───────────────────────────────────────┐
│ ┌─ d ─┐ compare as decimal │
│ │ │ signed integers │
│ ├─ e ─┤ <str> follows even │ ┌────────────┐
│ │ │ if it starts with / │ │ │
TST ─┴─ / ─┬─┤ ├─────────────────────┬──┴─ <str> ─┴─┬ <cmp> ┬──┴─
│ ├─ x ─┤ compare case exact │ │ │
│ ├─ i ─┤ prompt for new <str> │ Null input └──────┘
│ │ │ from stdin │ for /i gets "(null)",
│ └─ p ─┘ pattern match │ for /id gets -10001
└─────────────────────────────┘
First there may be an optional argument specifying various TST
options. Then there is the required string which is compared,
one by one, with each of the following comparands until a
successful comparison is achieved.
The arguments can optionally be enclosed in double
quotes. The enclosing quotes are stripped off and not
seen by TST. Should you need to have a double quote
within an argument, the argument must be double quoted
and the internal double quote must be escaped by
preceding it with a backslash. This treatment of the
double quotes is done by the argc/argv mechanism of the C
compiler. [TST is implemented in Borland TurboC.]
TST exits with ERRORLEVEL set to the ordinal number of the first
comparand that compares (zero if none). TST is normally followed
by IF ERRORLEVEL statements which selectively invoke various
batch file elements.
There are three main kinds of comparisons:
■ string
■ decimal integer
■ Unix-style, anchored pattern match
chosen via the presence (or absence) of various letters in an
option arg. String comparisons--as well as pattern matching--can
ignore (upper or lower) case, or insist on exact case.
When interactive programming is required, TST can prompt for,
then obtain, the <str> used in the comparisons. TST prompts with
the original <str>, then obtains a new one from stdin (normally
the keyboard unless the input is being redirected).
OPTION ARGUMENTS:
TST options are specified by the presence or absence of various
option letters in option arguments. Any option argument must
begin with a slash and must appear in front of the other kinds of
arguments. Any number of legal option letters can appear in an
option argument. Thus, you can have multiple option arguments,
perhaps each with a single option letter (and each beginning with
a slash), or just one option argument containing all of the
option letters desired. CURRENTLY, ALL LEGAL TST OPTION LETTERS
ARE lower case.
For the sake of readability, the above shown syntax
diagram shows only the case where all option letters
appear in the (at most one) option argument.
A TST syntax error occurs when illegal option letters appear,
when inconsistent combinations of option letters appear, and when
required arguments are missing. 'd' may not appear together with
either 'x' or 'p'. The <str> argument is required. And when
both 'p' and 'i' options are taken, at least one <cmp> is
required.
When a syntax error occurs TST prints a boxed syntax diagram
containing terse instructions on how to use TST. This mechanism
can be deliberately tripped in order to get on-screen help. The
suggested way is to invoke TST with no arguments--thus causing
the no-<str) syntax error. A second help screen giving pattern
matching help is printed when the 'p' option is taken and no
<str> appears.
STRING COMPARISON:
TST does string comparison when neither the /d option nor the /p
option is in effect. Case (upper or lower) is ignored unless the
/x option has been taken.
DECIMAL INTEGER COMPARISON:
TST does integer comparison when the /d option is in effect. The
<str> and the <cmp>'s are interpreted as signed decimal integers.
This means that as soon as an illegal integer byte is seen, the
remaining bytes are ignored. E.g., '23SKIDOO' is 23, and 'Hello'
is 0. A decimal <cmp> can contain two integers separated by ".."
in which case the comparison succeeds if the <str> lies between.
PATTERN-MATCHING:
TST does pattern matching when the /p option is in effect. Each
<cmp> is a pattern that is matched in turn against the same
<str>. Case (upper or lower) is ignored unless the /x option has
been taken.
A pattern is a string of characters. We distinguish two kinds of
characters: normal and meta. There are exactly nine
metacharacters:
. * + ? ^ $ [ ] \
The remaining characters are normal. Metacharacters sometimes
combine with normal characters as we will see. Otherwise, a
normal character simply matches itself. The metacharacters
behave as follows:
A matches
───── ────────────────────────────
. any single byte
* 0 or more of the preceding
+ 1 or more of the preceding
? 0 or 1 of the preceding
[...] any 1 of the enclosed bytes
[^...] any byte not enclosed
^ the beginning of the <cmp>
$ the end of the <cmp>
\α α, where α is a metabyte
α\!ß α or ß
\(α\) α (grouped for precedence)
\δ the δth group where δ is 1-9
\b beginning/end of a word
\< beginning of a word
\> end of a word
\w a word byte: [a-zA-Z0-9]
\W a nonword byte: [^a-zA-Z0-9]
Note that the '\' metacharacter is used as an escape, i.e., to
quote a metacharacter. Thus to match, e.g., a period (as a
normal character) you must use '\.' If you leave out the
backslash, the period alone will have its metacharacter meaning.
In the above explanation of the '*', '+' and '?' metacharacters,
'preceding' means 'the shortest possible preceding'. Thus, 'ab+'
matches 'ab', 'abb', etc., but not 'abab'
The square bracket metacharacters specify any one of the enclosed
characters--known as a character class. The minus sign has a
special meaning as a range in a character class. '[a-g]' can be
used in place of '[abcdefg]'. When appearing first in a
character class, a circumflex indicates that the match is with
any character not in the character class. Thus, '[^0-9]' matches
any non decimal-digit. Most metacharacters lose their special
status in a character class, and should not be escaped. If a
right square bracket is to be in a character class, it must
follow immediately the beginning left square bracket. If a minus
sign is to be in a character class, it must appear as '---',
i.e., a range containing only itself. Since the square brackets
do not nest, a left square bracket can easily be included in a
character class. E.g., '[][]' matches a right or a left square
bracket.
TST's pattern match is anchored, i.e., the pattern must match the
entire <cmp>. This can be circumvented, e.g., the pattern
'.*zyx.*' will find 'zyx' anywhere in a <cmp>.
Some pattern match examples follow:
A matches
────────────────── ───────────────────────
zyx zyx
f.x fax, fix and fxx
f\.x f.x
f[aix]x only fax, fix and fxx
\[[a-z]+\] [hello] and [world]
\(suf\!pre\)fix suffix or prefix
ba\(na\)* banananana
[A-P]: A:, C:, H:, etc
\([cd]:\)?\w abc, c:zyx, d:cat, etc
\(abra\)\(cad\1\)* abracadabracadabra
Due to a bug in PC DOS I have changed the alternative
(i.e., the "or") from '\|' to '\!'. The vertical, '|',
is DOS's piping symbol. Although doublequoting is
supposed to protect any redirection symbols in the
interior from being acted upon, under certain
circumstances DOS performs the redirection even though
doublequoted.
Please note that TST's pattern matching is done via REGEX.C from
Free Software Foundation, Inc.
EXAMPLES:
Here is an example of (a portion of) a batch file that uses TST.
.
.
.
:tryagain
stdo
stdo
echo I need to know how you want the generated files
echo to specify your home drive. The choices are:
stdo
echo 1) C:
echo 2) D:
echo 3) %%home%%
echo 4) [I'll enter it myself]
stdo
tst/id "Enter choice (from 1 to 4) [1] :" 1 2 3 4 -10001
if errorlevel 5 goto cdrive
if errorlevel 4 goto mydrive
if errorlevel 3 goto homedrive
if errorlevel 2 goto ddrive
if errorlevel 1 goto cdrive
goto tryagain
:cdrive
.
.
.
The material preceding the TST invocation sets the stage for its
use--by explaining what is to follow. The TST invocation's first
arg is '/id'--specifying a decimal comparison wherein the <str>
is to be the prompt to be replaced by whatever is gotten from
stdin. The prompt, i.e., the <str>,
Enter choice (from 1 to 4) [1] :
is doublequoted because it contains spaces which would make it
eight arguments if unquoted. Note that the prompt contains '[1]'
meaning that the user can make this choice merely by hitting the
ENTER key. Then there are five comparands, the first four being
the 1 through 4 choices, and the fifth being -10001 which is what
TST gets for a null reply to a decimal prompt. Since there are
five comparands TST will set the ERRORLEVEL to 1 through 5 or 0
(the last for a failure to match). The TST invocation is
followed by a sequence of IF ERRORLEVEL statements, the first
being:
if errorlevel 5 goto cdrive
Note that the meaning of this is to go to cdrive if the
errorlevel is at least 5. That is why the ERRORLEVEL tests are
in reverse numerical order, i.e., an IF ERRORLEVEL 1 would
succeed if the ERRORLEVEL was anything greater--say 5. Each of
the ERRORLEVEL statements send control to the appropriate part of
the batch file. Following the IF ERRORLEVEL's is a GOTO which is
done only if the ERRORLEVEL is zero--meaning that the user
entered a number out of the allowed range. In this case, control
is sent to :TRYAGAIN which reprompts the user.
Of course, if you don't want to check the ERRORLEVEL in
descending order you can use double IF ERRORLEVEL's as in:
if errorlevel 3 if not errorlevel 4 goto three
which checks for errorlevel 3 exactly.
The next example is the batch file I use to test TST. It is a
rich set of TST examples including, e.g., /i cases where the
stdin does not come from the keyboard. [See lines 18-23.]
---------- tst-test.bat
[1]REM testing string compares against 3 cmp's
[2]tst abc abc de f
[3]if not errorlevel 1 goto error
[4]if errorlevel 2 goto error
[5]tst de abc de f
[6]if not errorlevel 2 goto error
[7]if errorlevel 3 goto error
[8]tst f abc de f
[9]if not errorlevel 3 goto error
[10]if errorlevel 4 goto error
[11]tst no abc de f
[12]if errorlevel 1 goto error
[13]REM testing string compares for case sensitivity
[14]tst/x AbC abc
[15]if errorlevel 1 goto error
[16]tst/x AbC AbC
[17]if not errorlevel 1 goto error
[18]REM testing /i string compares
[19]echo abc>d:\tmp\junk1
[20]tst/i Prompt abc <d:\tmp\junk1 >d:\tmp\junk2
[21]if not errorlevel 1 goto error
[22]tst/i "<str>" Prompt <d:\tmp\junk2 >nul
[23]if not errorlevel 1 goto error
[24]REM testing /i string compare for null response
[25]stdo >d:\tmp\junk1
[26]tst/i "<str>" (null) <d:\tmp\junk1 >nul
[27]REM testing integer compares against 3 cmp's
[28]tst/d 123 123 4..6 -12
[29]if not errorlevel 1 goto error
[30]if errorlevel 2 goto error
[31]tst/d 4 123 4..6 -12
[32]if not errorlevel 2 goto error
[33]if errorlevel 3 goto error
[34]tst/d 05 123 4..6 -12
[35]if not errorlevel 2 goto error
[36]if errorlevel 3 goto error
[37]tst/d +6 123 4..6 -12
[38]if not errorlevel 2 goto error
[39]if errorlevel 3 goto error
[40]tst/d -12 123 4..6 -12
[41]if not errorlevel 3 goto error
[42]if errorlevel 4 goto error
[43]tst/d 3 123 4..6 -12
[44]if errorlevel 1 goto error
[45]tst/d 7 123 4..6 -12
[46]if errorlevel 1 goto error
[47]REM testing pattern matches against 3 cmp's
[48]tst/p A: [ab]: [cd]: [h-p]:
[49]if not errorlevel 1 goto error
[50]if errorlevel 2 goto error
[51]tst/p D: [ab]: [cd]: [h-p]:
[52]if not errorlevel 2 goto error
[53]if errorlevel 3 goto error
[54]tst/p o: [ab]: [cd]: [h-p]:
[55]if not errorlevel 3 goto error
[56]if errorlevel 4 goto error
[57]tst/p e: [ab]: [cd]: [h-p]:
[58]if errorlevel 1 goto error
[59]REM testing /pi pattern matches
[60]echo c:>d:\tmp\junk1
[61]tst/pi Prompter [a-z]: <d:\tmp\junk1 >d:\tmp\junk2
[62]if not errorlevel 1 goto error
[63]tst/pix "<str>" Prompter <d:\tmp\junk2 >nul
[64]if not errorlevel 1 goto error
[65]REM testing /pi pattern match for null response
[66]stdo >d:\tmp\junk1
[67]tst/pi "<str>" (n?ul?l) <d:\tmp\junk1 >nul
[68]:
[69]@echo off
[70]echo /
[71]echo TST.EXE passed all tests
[72]echo \
[73]quitbat
[74]:
[75]:error
[76]@echo off
[77]echo /
[78]echo TST.EXE failed!
[79]echo \
[80]:TST-TEST.BAT for testing TST.EXE, by Bob Magnuson