move explorer and cmd. Add a few .rbuild files
[reactos.git] / reactos / base / shell / cmd / for.c
1 /*
2 * FOR.C - for 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 * 19-Jul-1998 (Hans B Pufal)
14 * Implementation of FOR.
15 *
16 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
17 * Added config.h include.
18 *
19 * 20-Jan-1999 (Eric Kohl)
20 * Unicode and redirection safe!
21 *
22 * 01-Sep-1999 (Eric Kohl)
23 * Added help text.
24 *
25 * 23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
26 * Implemented preservation of echo flag. Some other for related
27 * code in other files fixed, too.
28 *
29 * 28-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
30 * Remove all hardcode string to En.rc
31 */
32
33 #include <precomp.h>
34 #include "resource.h"
35
36
37 /*
38 * Perform FOR command.
39 *
40 * First check syntax is correct : FOR %v IN ( <list> ) DO <command>
41 * v must be alphabetic, <command> must not be empty.
42 *
43 * If all is correct build a new bcontext structure which preserves
44 * the necessary information so that readbatchline can expand
45 * each the command prototype for each list element.
46 *
47 * You might look on a FOR as being a called batch file with one line
48 * per list element.
49 */
50
51 INT cmd_for (LPTSTR cmd, LPTSTR param)
52 {
53 LPBATCH_CONTEXT lpNew;
54 LPTSTR pp;
55 TCHAR var;
56 TCHAR szMsg[RC_STRING_MAX_SIZE];
57
58 #ifdef _DEBUG
59 DebugPrintf (_T("cmd_for (\'%s\', \'%s\'\n"), cmd, param);
60 #endif
61
62 if (!_tcsncmp (param, _T("/?"), 2))
63 {
64 ConOutResPaging(TRUE,STRING_FOR_HELP1);
65 return 0;
66 }
67
68 /* Check that first element is % then an alpha char followed by space */
69 if ((*param != _T('%')) || !_istalpha (*(param + 1)) || !_istspace (*(param + 2)))
70 {
71 LoadString( CMD_ModuleHandle, STRING_FOR_ERROR, szMsg, RC_STRING_MAX_SIZE);
72 error_syntax (szMsg);
73 return 1;
74 }
75
76 param++;
77 var = *param++; /* Save FOR var name */
78
79 while (_istspace (*param))
80 param++;
81
82 /* Check next element is 'IN' */
83 if ((_tcsnicmp (param, _T("in"), 2) != 0) || !_istspace (*(param + 2)))
84 {
85 LoadString(CMD_ModuleHandle, STRING_FOR_ERROR1, szMsg, RC_STRING_MAX_SIZE);
86 error_syntax(szMsg);
87 return 1;
88 }
89
90 param += 2;
91 while (_istspace (*param))
92 param++;
93
94 /* Folowed by a '(', find also matching ')' */
95 if ((*param != _T('(')) || (NULL == (pp = _tcsrchr (param, _T(')')))))
96 {
97 LoadString(CMD_ModuleHandle, STRING_FOR_ERROR2, szMsg, RC_STRING_MAX_SIZE);
98 error_syntax(szMsg);
99 return 1;
100 }
101
102 *pp++ = _T('\0');
103 param++; /* param now points at null terminated list */
104
105 while (_istspace (*pp))
106 pp++;
107
108 /* Check DO follows */
109 if ((_tcsnicmp (pp, _T("do"), 2) != 0) || !_istspace (*(pp + 2)))
110 {
111 LoadString(CMD_ModuleHandle, STRING_FOR_ERROR3, szMsg, RC_STRING_MAX_SIZE);
112 error_syntax(szMsg);
113 return 1;
114 }
115
116 pp += 2;
117 while (_istspace (*pp))
118 pp++;
119
120 /* Check that command tail is not empty */
121 if (*pp == _T('\0'))
122 {
123 LoadString(CMD_ModuleHandle, STRING_FOR_ERROR4, szMsg, RC_STRING_MAX_SIZE);
124 error_syntax(szMsg);
125 return 1;
126 }
127
128 /* OK all is correct, build a bcontext.... */
129 lpNew = (LPBATCH_CONTEXT)malloc (sizeof (BATCH_CONTEXT));
130
131 lpNew->prev = bc;
132 bc = lpNew;
133
134 bc->hBatchFile = INVALID_HANDLE_VALUE;
135 bc->ffind = NULL;
136 bc->params = BatchParams (_T(""), param); /* Split out list */
137 bc->shiftlevel = 0;
138 bc->forvar = var;
139 bc->forproto = _tcsdup (pp);
140 if (bc->prev)
141 bc->bEcho = bc->prev->bEcho;
142 else
143 bc->bEcho = bEcho;
144 bc->In[0] = _T('\0');
145 bc->Out[0] = _T('\0');
146 bc->Err[0] = _T('\0');
147
148
149 return 0;
150 }
151
152 /* EOF */