Conditional Expressions

The commands DO (when used with the UNTIL or WHILE keyword), IF, IFF/ELSEIFF, and the variable function @IF evaluate a conditional expression, and perform a different action based on whether or not the expression is TRUE. The SWITCH command tests pairs of values for equality. Most of the examples below use the IF command, but conditional expressions could be used in the other cases above as well.

 

A conditional expression can be one of the following, as described below:

 

Onesteprelational expression
Onestepstatus test
Onesteplogical expression

 

Relational Expression

 

A relational expression compares two character strings, using one of the relational operators in the table below. Each of these two character strings can contain literal text, environment and internal variables, and variable functions, including user defined ones, in any combination. Note that double quotes are significant.

 

Numeric and String Comparison

 

When comparing the two character strings, either a numeric or a string comparison will be used. A numeric comparison treats the strings as numeric values and tests them arithmetically. A string comparison treats the strings as text. The parser uses the rules described for the @NUMERIC function to determine whether or not the strings are numeric, and only if both are numeric is a numeric comparison performed. If either value is non-numeric, a string comparison is used. To force a string comparison when both values may be numeric, use double quotes around the values you are testing, as shown below. Because the quote mark is not a numeric character, string comparison is performed. Numeric comparison cannot be forced. To compare hexadecimal numbers numerically, you must convert them to decimal numbers using @CONVERT. This is not necessary if both are the same length - string comparison and numeric comparison yield the same result.

 

The example below demonstrates the difference between numeric and string comparisons, as shown in the table below. Numerically, 2 is smaller, but as a string it is "larger" because its first digit is larger than the first digit of 19. So the first of these conditions will be true, and the second will be false:

 

expression

value

comparison type

2  lt  19

true

numeric

"2" lt "19"

false

string

 

Relational Expression Formats

 

The format of a relational expression is one of

 

num1 relational operator num2

string1 relational operator string2

 

Note: The correct syntax requires a space both before and after operator to separate it from its operands. Commonly seen constructs such as %a==b may or may not work depending on the specific parameters, but they are never recommended.

 

Relational Operators

 

operator

numeric comparison: expression is true if

string comparison: expression is true if, when ignoring character case:

EQ or ==

num1 equals num2

string1 equals string2

NE or !=

num1 does not equal num2

string1 does not equal string2

LT

num1 is less than num2

string1 alphabetically precedes string2

LE

num1 is less than or is equal to num2

string1 alphabetically precedes or is equal to string2

GE

num1 is greater than or is equal to num2

string1 alphabetically succeeds or is equal to string2

GT

num1 is greater than num2

string1 alphabetically succeeds string2

EQC

tested as strings è

string1 is identical to string2, including character case

=~

regular expression test

string1 matches the regular expression in string2

!~

regular expression test

string1 doesn't match the regular expression in string2

 

Case differences are ignored in string comparisons (except by EQC). If two strings begin with the same text but one is shorter, the shorter string is considered to precede (be less than) the longer one. For example, "a" is less than "abc", and "hello_there" is greater than "hello".

 

When you compare text strings, you may need to enclose the parameters in double quotes in order to avoid syntax errors which can occur if one of the parameter values is empty (e.g., due to an environment variable which has never been assigned a value). This technique will not work for numeric comparisons, as the quotes will force a string comparison, so with numeric tests you must be sure that all variables are assigned values before the test is done.

 

In order to maintain compatibility with CMD, TCC recognizes the following additional names for conditions:

 

CMD

TCC

EQL or EQU

EQ

NEQ

NE

LSS

LT

LEQ

LE

GTR

GT

GEQ

GE

 

Internal variables and variable functions are very powerful when combined with string and numeric comparisons. They allow you to test the state of your system, the characteristics of a file, date and time information, or the result of a calculation. You may want to review the variables and variable functions when determining the best way to set up a condition test.

 

Status Test

 

These conditions test operating system, file system or TCC status. In addition to the tests below, there are many internal variables and variable functions which allow you to test the status of many other parts of the system.

 

In the descriptions below of the various status tests, the status tests are true if and only if the specified condition is true.

 

DEFINED variable

If variable exists in the environment, the expression is true. This is equivalent to testing whether or not variable is nonempty.




Note: GOSUB variables, array variables, and internal variables do not exist in the environment, so they always fail the DEFINED test.



ERRORLEVEL [relational operator] n

This test retrieves the exit code of the preceding external program. By convention, programs return an exit code of 0 when they are successful and a non-zero number to indicate an error. The relational operator may be any of those listed above (e.g., EQ, GT). If no operator is specified, the default is GE. The comparison is done numerically.




Not all programs return an explicit exit code. For programs which do not, the behavior of ERRORLEVEL is undefined.



EXIST filename

If filename matches a file which exists, the expression is true. You can use wildcards in filename, in which case the expression is true if any file matching the wildcard name exists. filename may include an absolute or relative path.




WARNING: In Windows the expression will be true if there is either a file or a directory named filename. Use ISFILE or ISDIR instead.




The special filename NUL is commonly used in CMD batch files to test the existence of a directory. The expression exist xxx\NUL is true only if xxx is a directory.



ISALIAS aliasname

If aliasname is defined as an alias, the expression is true.



ISAPP appname

If appname matches the name of an application which is currently running, the expression is true. To match a specific application, you must enter the full pathname of the application. Partial names and wildcards will yield undependable results. Both the short and long filename forms of the name will be checked (see LFN File Searches for details on the correspondence between short and long filenames).


This test may require DEBUG privilege.



ISDIR path

DIREXIST path

 

If the directory specified by path exists, the expression is true. Path may be either absolute or relative. DIREXIST may be used as a synonym for ISDIR.



ISFILE filename

If filename matches a file which exists, the expression is true. You can use wildcards in the filename, in which case the expression is true if any file matching the wildcard name exists. ISFILE matches only files, not directories.



ISFUNCTION name

If the user-defined function name is loaded, the expression is true.



ISINTERNAL command

If command is an active internal command, the expression is true. Commands can be activated and deactivated with the SETDOS /I command.



ISLABEL label

If label exists in the current batch file, the expression is true. Labels may be one or more words long. Note that this test has nothing to do with disk partition labels.



ISPLUGIN name

If name is a plugin variable, function, or command, the expression is true.



ISWINDOW "title"

If a window which matches the title exists, the expression is true. double quotes must be used around the title, which may contain wildcards and extended wildcards.

 

ISHUNG "title"

If the specified window is not responding, the expression is true.

 

PLUGIN module

If the plugin module is loaded, the expression is true. Do not include an extension (i.e., ".dll"), for the module name.

 

Logical Expressions

 

A logical expression is one of the following:

 

 Onestep        a relational expression

 Onestep        a status test

 Onestep        the unary logical operator NOT (or !) followed by a logical expression

 Onestep        two logical expressions connected by a binary logical operator

 

Logical operators

 

operator

type

usage

value is TRUE if

NOT

unary

NOT cond

cond is FALSE.

.AND.

binary

cond1 .AND. cond2

both cond1 and cond2 are TRUE.

.OR.

binary

cond1 .OR. cond2

at least one of cond1 and cond2 is TRUE.

.XOR.

binary

cond1 .XOR. cond2

one of cond1 and cond2 is TRUE, and the other one is FALSE.

 

This example runs a program called DATALOAD if today is Monday or Tuesday (enter this on one line):

 

if "%_dow" == "Mon" .or. "%_dow" == "Tue" dataload

 

Test conditions are always scanned from left to right -- there is no implied order of precedence, as there is in some programming languages. You can, however, force a specific order of testing by grouping conditions with parentheses, for example (enter this on one line):

 

if (%a == 1 .or. (%b == 2 .and. %c == 3)) echo something

 

Combining logical expressions

 

Parentheses can be used only when the portion of the expression inside the parentheses contains at least one of the binary logical operators .and., .or., or .xor.. Parentheses on a simple expression which does not combine two or more tests will be taken as part of the string to be tested, and will probably make the test fail. For example, the first of these tests is FALSE, the second is TRUE:

 

(a == a)

(a == a .and. b == b)

 

Parentheses may be nested.

 

Examples

 

This batch file fragment runs a program called WEEKLY if today is Monday:

 

if "%_dow" == "mon" weekly

 

This batch file fragment tests for a string value:

 

input "Enter your selection : " %%cmd

if "%cmd" == "WP" goto wordproc

if "%cmd" NE "GRAPHICS" goto badentry

 

This example calls GO.BTM if the first two characters in the file MYFILE are GO:

 

if "%@left[2,%@line[myfile,0]]" == "GO" call go.btm

 

The first batch file fragment below tests for the existence of A:\JAN.DOC before copying it to drive C (this avoids an error message if the file does not exist):

 

if isfile a:\jan.doc copy a:\jan.doc c:\

 

This example tests the exit code of the previous program and stops all batch file processing if an error occurred:

 

if errorlevel == 0 goto success

echo "External Error; Batch File Ends!"

cancel