e921c03193cee70eff402555e0fd81d852e8f7ec
[reactos.git] / rosapps / cmd / if.c
1 /*
2 * IF.C - if internal batch command.
3 *
4 *
5 * History:
6 *
7 * 16 Jul 1998 (Hans B Pufal)
8 * started.
9 *
10 * 16 Jul 1998 (John P Price)
11 * Seperated commands into individual files.
12 *
13 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
14 * added config.h include
15 *
16 * 07-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
17 * Added help text ("if /?") and cleaned up.
18 *
19 * 21-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
20 * Unicode and redirection ready!
21 *
22 * 01-Sep-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
23 * Fixed help text.
24 */
25
26 #include "config.h"
27
28 #include <windows.h>
29 #include <tchar.h>
30 #include <string.h>
31 #include <ctype.h>
32
33 #include "cmd.h"
34 #include "batch.h"
35
36
37 #define X_EXEC 1
38 #define X_EMPTY 0x80
39
40
41 INT cmd_if (LPTSTR cmd, LPTSTR param)
42 {
43 INT x_flag = 0; /* when set cause 'then' clause to be executed */
44 LPTSTR pp;
45
46 #ifdef _DEBUG
47 DebugPrintf ("cmd_if: (\'%s\', \'%s\'\n", cmd, param);
48 #endif
49
50 if (!_tcsncmp (param, _T("/?"), 2))
51 {
52 ConOutPuts (_T("Performs conditional processing in batch programs.\n"
53 "\n"
54 " IF [NOT] ERRORLEVEL number command\n"
55 " IF [NOT] string1==string2 command\n"
56 " IF [NOT] EXIST filename command\n"
57 "\n"
58 "NOT Specifies that CMD should carry out the command only if\n"
59 " the condition is false\n"
60 "ERRORLEVEL number Specifies a true condition if the last program run returned\n"
61 " an exit code equal or greater than the number specified.\n"
62 "command Specifies the command to carry out if the condition is met.\n"
63 "string1==string2 Specifies a true condition if the specified text strings\n"
64 " match.\n"
65 "EXIST filename Specifies a true condition if the specified filename exists."));
66 return 0;
67 }
68
69 /* First check if param string begins with word 'not' */
70 if (!_tcsnicmp (param, _T("not"), 3) && _istspace (*(param + 3)))
71 {
72 x_flag = X_EXEC; /* Remember 'NOT' */
73 param += 3; /* Step over 'NOT' */
74 while (_istspace (*param)) /* And subsequent spaces */
75 param++;
76 }
77
78 /* Check for 'exist' form */
79 if (!_tcsnicmp (param, _T("exist"), 5) && _istspace (*(param + 5)))
80 {
81 param += 5;
82 while (_istspace (*param))
83 param++;
84
85 pp = param;
86 while (*pp && !_istspace (*pp))
87 pp++;
88
89 if (*pp)
90 {
91 WIN32_FIND_DATA f;
92 HANDLE hFind;
93
94 *pp++ = _T('\0');
95 hFind = FindFirstFile (param, &f);
96 x_flag ^= (hFind != INVALID_HANDLE_VALUE) ? 0 : X_EXEC;
97 if (hFind != INVALID_HANDLE_VALUE)
98 FindClose (hFind);
99 }
100 else
101 return 0;
102 }
103
104 /* Check for 'errorlevel' form */
105 else if (!_tcsnicmp (param, _T("errorlevel"), 10) && _istspace (*(param + 10)))
106 {
107 INT n = 0;
108
109 pp = param + 10;
110 while (_istspace (*pp))
111 pp++;
112
113 while (_istdigit (*pp))
114 n = n * 10 + (*pp++ - _T('0'));
115
116 x_flag ^= (nErrorLevel < n) ? 0 : X_EXEC;
117
118 x_flag |= X_EMPTY; /* Syntax error if comd empty */
119 }
120
121 /* Check that '==' is present, syntax error if not */
122 else if (NULL == (pp = _tcsstr (param, _T("=="))))
123 {
124 error_syntax (NULL);
125 return 1;
126 }
127
128 else
129 {
130 /* Change first '='to space to terminate comparison loop */
131
132 *pp = _T(' '); /* Need a space to terminate comparison loop */
133 pp += 2; /* over '==' */
134 while (_istspace (*pp)) /* Skip subsequent spaces */
135 pp++;
136
137 _tcscat (pp, _T(" ")); /* Add one space to ensure comparison ends */
138
139 while (*param == *pp) /* Comparison loop */
140 {
141 if (_istspace (*param)) /* Terminates on space */
142 break;
143
144 param++, pp++;
145 }
146
147 if (x_flag ^= (*param != *pp) ? 0 : X_EXEC)
148 {
149 while (*pp && !_istspace (*pp)) /* Find first space, */
150 pp++;
151
152 x_flag |= X_EMPTY;
153 }
154 }
155
156 if (x_flag & X_EMPTY)
157 {
158 while (_istspace (*pp)) /* Then skip spaces */
159 pp++;
160
161 if (*pp == _T('\0')) /* If nothing left then syntax err */
162 {
163 error_syntax (NULL);
164 return 1;
165 }
166 }
167
168 if (x_flag & X_EXEC)
169 ParseCommandLine (pp);
170
171 return 0;
172 }