2 * IF.C - if internal batch command.
7 * 16 Jul 1998 (Hans B Pufal)
10 * 16 Jul 1998 (John P Price)
11 * Seperated commands into individual files.
13 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
14 * added config.h include
16 * 07-Jan-1999 (Eric Kohl)
17 * Added help text ("if /?") and cleaned up.
19 * 21-Jan-1999 (Eric Kohl)
20 * Unicode and redirection ready!
22 * 01-Sep-1999 (Eric Kohl)
26 * IF DEFINED variable command
28 * 28-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
29 * Remove all hardcode string to En.rc
35 static INT
GenericCmp(INT (*StringCmp
)(LPCTSTR
, LPCTSTR
),
36 LPCTSTR Left
, LPCTSTR Right
)
39 INT nLeft
= _tcstol(Left
, &end
, 0);
42 INT nRight
= _tcstol(Right
, &end
, 0);
45 /* both arguments are numeric */
46 return (nLeft
< nRight
) ? -1 : (nLeft
> nRight
);
49 return StringCmp(Left
, Right
);
52 INT
cmd_if (LPTSTR param
)
54 TRACE ("cmd_if: (\'%s\')\n", debugstr_aw(param
));
56 if (!_tcsncmp (param
, _T("/?"), 2))
58 ConOutResPaging(TRUE
,STRING_IF_HELP1
);
66 INT
ExecuteIf(PARSED_COMMAND
*Cmd
)
68 INT result
= FALSE
; /* when set cause 'then' clause to be executed */
70 LPTSTR Left
= NULL
, Right
;
74 Left
= DoDelayedExpansion(Cmd
->If
.LeftArg
);
78 Right
= DoDelayedExpansion(Cmd
->If
.RightArg
);
85 if (Cmd
->If
.Operator
== IF_CMDEXTVERSION
)
87 /* IF CMDEXTVERSION n: check if Command Extensions version
88 * is greater or equal to n */
89 DWORD n
= _tcstoul(Right
, ¶m
, 10);
90 if (*param
!= _T('\0'))
98 else if (Cmd
->If
.Operator
== IF_DEFINED
)
100 /* IF DEFINED var: check if environment variable exists */
101 result
= (GetEnvVarOrSpecial(Right
) != NULL
);
103 else if (Cmd
->If
.Operator
== IF_ERRORLEVEL
)
105 /* IF ERRORLEVEL n: check if last exit code is greater or equal to n */
106 INT n
= _tcstol(Right
, ¶m
, 10);
107 if (*param
!= _T('\0'))
113 result
= (nErrorLevel
>= n
);
115 else if (Cmd
->If
.Operator
== IF_EXIST
)
117 /* IF EXIST filename: check if file exists (wildcards allowed) */
123 hFind
= FindFirstFile(Right
, &f
);
124 if (hFind
!= INVALID_HANDLE_VALUE
)
132 /* Do case-insensitive string comparisons if /I specified */
133 INT (*StringCmp
)(LPCTSTR
, LPCTSTR
) =
134 (Cmd
->If
.Flags
& IFFLAG_IGNORECASE
) ? _tcsicmp
: _tcscmp
;
136 if (Cmd
->If
.Operator
== IF_STRINGEQ
)
138 /* IF str1 == str2 */
139 result
= StringCmp(Left
, Right
) == 0;
143 result
= GenericCmp(StringCmp
, Left
, Right
);
144 switch (Cmd
->If
.Operator
)
146 case IF_EQU
: result
= (result
== 0); break;
147 case IF_NEQ
: result
= (result
!= 0); break;
148 case IF_LSS
: result
= (result
< 0); break;
149 case IF_LEQ
: result
= (result
<= 0); break;
150 case IF_GTR
: result
= (result
> 0); break;
151 case IF_GEQ
: result
= (result
>= 0); break;
159 if (result
^ ((Cmd
->If
.Flags
& IFFLAG_NEGATE
) != 0))
161 /* full condition was true, do the command */
162 return ExecuteCommand(Cmd
->Subcommands
);
166 /* full condition was false, do the "else" command if there is one */
167 if (Cmd
->Subcommands
->Next
)
168 return ExecuteCommand(Cmd
->Subcommands
->Next
);