ReactOS  0.4.15-dev-1152-g6c94e4f
for.c File Reference
#include "precomp.h"
Include dependency graph for for.c:

Go to the source code of this file.

Macros

#define MSCMD_FOR_QUIRKS
 
#define RunInstance(Cmd)   ExecuteCommandWithEcho((Cmd)->Subcommands)
 
#define Exiting(Cmd)
 
#define ExitingOrGoto(Cmd)   (Exiting(Cmd) || (bc && bc->current == NULL))
 

Functions

INT cmd_for (LPTSTR param)
 
static BOOL GetNextElement (TCHAR **pStart, TCHAR **pEnd)
 
static LPTSTR ReadFileContents (FILE *InputFile, TCHAR *Buffer)
 
static INT ForF (PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
 
static INT ForLoop (PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
 
static INT ForDir (PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
 
static INT ForRecursive (PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
 
INT ExecuteFor (PARSED_COMMAND *Cmd)
 

Variables

PFOR_CONTEXT fc = NULL
 

Macro Definition Documentation

◆ Exiting

#define Exiting (   Cmd)
Value:
/* Someone might have removed our context */ \
(bCtrlBreak || (fc != (Cmd)->For.Context))
PFOR_CONTEXT fc
Definition: for.c:57
Definition: sacdrv.h:277
BOOL bCtrlBreak
Definition: cmd.c:154

Definition at line 81 of file for.c.

◆ ExitingOrGoto

#define ExitingOrGoto (   Cmd)    (Exiting(Cmd) || (bc && bc->current == NULL))

Definition at line 85 of file for.c.

◆ MSCMD_FOR_QUIRKS

#define MSCMD_FOR_QUIRKS

Definition at line 37 of file for.c.

◆ RunInstance

#define RunInstance (   Cmd)    ExecuteCommandWithEcho((Cmd)->Subcommands)

Definition at line 77 of file for.c.

Function Documentation

◆ cmd_for()

INT cmd_for ( LPTSTR  param)

Definition at line 41 of file for.c.

42 {
43  TRACE("cmd_for(\'%s\')\n", debugstr_aw(param));
44 
45  if (!_tcsncmp(param, _T("/?"), 2))
46  {
48  return 0;
49  }
50 
52  return 1;
53 }
#define TRUE
Definition: types.h:120
#define debugstr_aw
Definition: precomp.h:43
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define STRING_FOR_HELP1
Definition: resource.h:128
#define _T(x)
Definition: vfdio.h:22
#define TRACE(s)
Definition: solgame.cpp:4
GLfloat param
Definition: glext.h:5796
VOID ParseErrorEx(IN PCTSTR s)
Definition: parser.c:227
int _tcsncmp(const _TCHAR *s1, const _TCHAR *s2, size_t n)
Definition: tcsncmp.h:9

◆ ExecuteFor()

INT ExecuteFor ( PARSED_COMMAND Cmd)

Definition at line 604 of file for.c.

605 {
606  INT Ret;
607  LPTSTR List;
608  PFOR_CONTEXT lpNew;
609  TCHAR Buffer[CMDLINE_LENGTH]; /* Buffer to hold the variable value */
610  LPTSTR BufferPtr = Buffer;
611 
612  List = DoDelayedExpansion(Cmd->For.List);
613  if (!List)
614  return 1;
615 
616  /* Create our FOR context */
617  lpNew = cmd_alloc(sizeof(FOR_CONTEXT));
618  if (!lpNew)
619  {
620  WARN("Cannot allocate memory for lpNew!\n");
621  cmd_free(List);
622  return 1;
623  }
624  lpNew->prev = fc;
625  lpNew->firstvar = Cmd->For.Variable;
626  lpNew->varcount = 1;
627  lpNew->values = &BufferPtr;
628 
629  Cmd->For.Context = lpNew;
630  fc = lpNew;
631 
632  /* Run the extended FOR syntax only if extensions are enabled */
633  if (bEnableExtensions)
634  {
635  if (Cmd->For.Switches & FOR_F)
636  {
637  Ret = ForF(Cmd, List, Buffer);
638  }
639  else if (Cmd->For.Switches & FOR_LOOP)
640  {
641  Ret = ForLoop(Cmd, List, Buffer);
642  }
643  else if (Cmd->For.Switches & FOR_RECURSIVE)
644  {
645  DWORD Len = GetFullPathName(Cmd->For.Params ? Cmd->For.Params : _T("."),
646  MAX_PATH, Buffer, NULL);
647  Ret = ForRecursive(Cmd, List, Buffer, &Buffer[Len]);
648  }
649  else
650  {
651  Ret = ForDir(Cmd, List, Buffer, Buffer);
652  }
653  }
654  else
655  {
656  Ret = ForDir(Cmd, List, Buffer, Buffer);
657  }
658 
659  /* Remove our context, unless someone already did that */
660  if (fc == lpNew)
661  fc = lpNew->prev;
662 
663  cmd_free(lpNew);
664  cmd_free(List);
665  return Ret;
666 }
PFOR_CONTEXT fc
Definition: for.c:57
PTSTR DoDelayedExpansion(IN PCTSTR Line)
Definition: cmd.c:1638
#define WARN(fmt,...)
Definition: debug.h:112
#define CMDLINE_LENGTH
Definition: help.h:12
static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
Definition: for.c:125
int32_t INT
Definition: typedefs.h:58
#define FOR_F
Definition: cmd.h:235
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define FOR_LOOP
Definition: cmd.h:236
smooth NULL
Definition: ftsmooth.c:416
LPTSTR * values
Definition: batch.h:50
Definition: bufpool.h:45
char TCHAR
Definition: xmlstorage.h:189
static INT ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
Definition: for.c:561
#define _T(x)
Definition: vfdio.h:22
static INT ForLoop(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
Definition: for.c:482
LIST_ENTRY List
Definition: psmgr.c:57
#define MAX_PATH
Definition: compat.h:34
static INT ForDir(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
Definition: for.c:513
unsigned long DWORD
Definition: ntddk_ex.h:95
#define Len
Definition: deflate.h:82
#define FOR_RECURSIVE
Definition: cmd.h:237
BOOL bEnableExtensions
Definition: cmd.c:161
TCHAR firstvar
Definition: batch.h:48
struct _FOR_CONTEXT * prev
Definition: batch.h:47
Definition: sacdrv.h:277
#define GetFullPathName
Definition: winbase.h:3661
UINT varcount
Definition: batch.h:49
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34

Referenced by ExecuteCommand().

◆ ForDir()

static INT ForDir ( PARSED_COMMAND Cmd,
LPTSTR  List,
TCHAR Buffer,
TCHAR BufPos 
)
static

Definition at line 513 of file for.c.

514 {
515  INT Ret = 0;
516  TCHAR *Start, *End = List;
517 
518  while (!ExitingOrGoto(Cmd) && GetNextElement(&Start, &End))
519  {
520  if (BufPos + (End - Start) > &Buffer[CMDLINE_LENGTH])
521  continue;
522  memcpy(BufPos, Start, (End - Start) * sizeof(TCHAR));
523  BufPos[End - Start] = _T('\0');
524 
525  if (_tcschr(BufPos, _T('?')) || _tcschr(BufPos, _T('*')))
526  {
527  WIN32_FIND_DATA w32fd;
528  HANDLE hFind;
529  TCHAR *FilePart;
530 
531  StripQuotes(BufPos);
532  hFind = FindFirstFile(Buffer, &w32fd);
533  if (hFind == INVALID_HANDLE_VALUE)
534  continue;
535  FilePart = _tcsrchr(BufPos, _T('\\'));
536  FilePart = FilePart ? FilePart + 1 : BufPos;
537  do
538  {
539  if (w32fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
540  continue;
541  if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
542  != !(Cmd->For.Switches & FOR_DIRS))
543  continue;
544  if (_tcscmp(w32fd.cFileName, _T(".")) == 0 ||
545  _tcscmp(w32fd.cFileName, _T("..")) == 0)
546  continue;
547  _tcscpy(FilePart, w32fd.cFileName);
548  Ret = RunInstance(Cmd);
549  } while (!ExitingOrGoto(Cmd) && FindNextFile(hFind, &w32fd));
550  FindClose(hFind);
551  }
552  else
553  {
554  Ret = RunInstance(Cmd);
555  }
556  }
557  return Ret;
558 }
#define FOR_DIRS
Definition: cmd.h:234
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
#define CMDLINE_LENGTH
Definition: help.h:12
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
int32_t INT
Definition: typedefs.h:58
Definition: bufpool.h:45
#define FindFirstFile
Definition: winbase.h:3622
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
static BOOL GetNextElement(TCHAR **pStart, TCHAR **pEnd)
Definition: for.c:60
LIST_ENTRY List
Definition: psmgr.c:57
#define FindNextFile
Definition: winbase.h:3628
#define ExitingOrGoto(Cmd)
Definition: for.c:85
#define RunInstance(Cmd)
Definition: for.c:77
Definition: partlist.h:33
Definition: sacdrv.h:277
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
_TCHAR * _tcsrchr(const _TCHAR *s, _XINT c)
Definition: tcsrchr.h:4
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Referenced by ExecuteFor(), and ForRecursive().

◆ ForF()

static INT ForF ( PARSED_COMMAND Cmd,
LPTSTR  List,
TCHAR Buffer 
)
static

Definition at line 125 of file for.c.

126 {
127  LPTSTR Delims = _T(" \t");
128  PTCHAR DelimsEndPtr = NULL;
129  TCHAR DelimsEndChr = _T('\0');
130  TCHAR Eol = _T(';');
131  INT SkipLines = 0;
132  DWORD TokensMask = (1 << 1);
133 #ifdef MSCMD_FOR_QUIRKS
134  DWORD NumTokens = 1;
135  DWORD RemainderVar = 0;
136 #else
137  DWORD NumTokens = 0;
138 #endif
139  TCHAR StringQuote = _T('"');
140  TCHAR CommandQuote = _T('\'');
141  LPTSTR Variables[32];
142  PTCHAR Start, End;
143  INT Ret = 0;
144 
145  if (Cmd->For.Params)
146  {
147  TCHAR Quote = 0;
148  PTCHAR Param = Cmd->For.Params;
149  if (*Param == _T('"') || *Param == _T('\''))
150  Quote = *Param++;
151 
152  while (*Param && *Param != Quote)
153  {
154  if (*Param <= _T(' '))
155  {
156  Param++;
157  }
158  else if (_tcsnicmp(Param, _T("delims="), 7) == 0)
159  {
160  Param += 7;
161  /*
162  * delims=xxx: Specifies the list of characters that separate tokens.
163  * This option does not cumulate: only the latest 'delims=' specification
164  * is taken into account.
165  */
166  Delims = Param;
167  DelimsEndPtr = NULL;
168  while (*Param && *Param != Quote)
169  {
170  if (*Param == _T(' '))
171  {
172  PTCHAR FirstSpace = Param;
173  Param += _tcsspn(Param, _T(" "));
174  /* Exclude trailing spaces if this is not the last parameter */
175  if (*Param && *Param != Quote)
176  {
177  /* Save where the delimiters specification string ends */
178  DelimsEndPtr = FirstSpace;
179  }
180  break;
181  }
182  Param++;
183  }
184  if (*Param == Quote)
185  {
186  /* Save where the delimiters specification string ends */
187  DelimsEndPtr = Param++;
188  }
189  }
190  else if (_tcsnicmp(Param, _T("eol="), 4) == 0)
191  {
192  Param += 4;
193  /* eol=c: Lines starting with this character (may be
194  * preceded by delimiters) are skipped. */
195  Eol = *Param;
196  if (Eol != _T('\0'))
197  Param++;
198  }
199  else if (_tcsnicmp(Param, _T("skip="), 5) == 0)
200  {
201  /* skip=n: Number of lines to skip at the beginning of each file */
202  SkipLines = _tcstol(Param + 5, &Param, 0);
203  if (SkipLines <= 0)
204  goto error;
205  }
206  else if (_tcsnicmp(Param, _T("tokens="), 7) == 0)
207  {
208 #ifdef MSCMD_FOR_QUIRKS
209  DWORD NumToksInSpec = 0; // Number of tokens in this specification.
210 #endif
211  Param += 7;
212  /*
213  * tokens=x,y,m-n: List of token numbers (must be between 1 and 31)
214  * that will be assigned into variables. This option does not cumulate:
215  * only the latest 'tokens=' specification is taken into account.
216  *
217  * NOTE: In MSCMD_FOR_QUIRKS mode, for Windows' CMD compatibility,
218  * not all the tokens-state is reset. This leads to subtle bugs.
219  */
220  TokensMask = 0;
221 #ifdef MSCMD_FOR_QUIRKS
222  NumToksInSpec = 0;
223  // Windows' CMD compatibility: bug: the asterisk-token's position is not reset!
224  // RemainderVar = 0;
225 #else
226  NumTokens = 0;
227 #endif
228 
229  while (*Param && *Param != Quote && *Param != _T('*'))
230  {
231  INT First = _tcstol(Param, &Param, 0);
232  INT Last = First;
233 #ifdef MSCMD_FOR_QUIRKS
234  if (First < 1)
235 #else
236  if ((First < 1) || (First > 31))
237 #endif
238  goto error;
239  if (*Param == _T('-'))
240  {
241  /* It's a range of tokens */
242  Last = _tcstol(Param + 1, &Param, 0);
243 #ifdef MSCMD_FOR_QUIRKS
244  /* Ignore the range if the endpoints are not in correct order */
245  if (Last < 1)
246 #else
247  if ((Last < First) || (Last > 31))
248 #endif
249  goto error;
250  }
251 #ifdef MSCMD_FOR_QUIRKS
252  /* Ignore the range if the endpoints are not in correct order */
253  if ((First <= Last) && (Last <= 31))
254  {
255 #endif
256  TokensMask |= (2 << Last) - (1 << First);
257 #ifdef MSCMD_FOR_QUIRKS
258  NumToksInSpec += (Last - First + 1);
259  }
260 #endif
261 
262  if (*Param != _T(','))
263  break;
264  Param++;
265  }
266  /* With an asterisk at the end, an additional variable
267  * will be created to hold the remainder of the line
268  * (after the last specified token). */
269  if (*Param == _T('*'))
270  {
271 #ifdef MSCMD_FOR_QUIRKS
272  RemainderVar = ++NumToksInSpec;
273 #else
274  ++NumTokens;
275 #endif
276  Param++;
277  }
278 #ifdef MSCMD_FOR_QUIRKS
279  NumTokens = max(NumTokens, NumToksInSpec);
280 #endif
281  }
282  else if (_tcsnicmp(Param, _T("useback"), 7) == 0)
283  {
284  Param += 7;
285  /* usebackq: Use alternate quote characters */
286  StringQuote = _T('\'');
287  CommandQuote = _T('`');
288  /* Can be written as either "useback" or "usebackq" */
289  if (_totlower(*Param) == _T('q'))
290  Param++;
291  }
292  else
293  {
294  error:
295  error_syntax(Param);
296  return 1;
297  }
298  }
299  }
300 
301 #ifdef MSCMD_FOR_QUIRKS
302  /* Windows' CMD compatibility: use the wrongly evaluated number of tokens */
303  fc->varcount = NumTokens;
304  /* Allocate a large enough variables array if needed */
305  if (NumTokens <= ARRAYSIZE(Variables))
306  {
307  fc->values = Variables;
308  }
309  else
310  {
311  fc->values = cmd_alloc(fc->varcount * sizeof(*fc->values));
312  if (!fc->values)
313  {
315  return 1;
316  }
317  }
318 #else
319  /* Count how many variables will be set: one for each token,
320  * plus maybe one for the remainder. */
321  fc->varcount = NumTokens;
322  for (NumTokens = 1; NumTokens < 32; ++NumTokens)
323  fc->varcount += (TokensMask >> NumTokens) & 1;
324  fc->values = Variables;
325 #endif
326 
327  if (*List == StringQuote || *List == CommandQuote)
328  {
329  /* Treat the entire "list" as one single element */
330  Start = List;
331  End = &List[_tcslen(List)];
332  goto single_element;
333  }
334 
335  /* Loop over each file */
336  End = List;
337  while (!ExitingOrGoto(Cmd) && GetNextElement(&Start, &End))
338  {
339  FILE* InputFile;
340  LPTSTR FullInput, In, NextLine;
341  INT Skip;
342  single_element:
343 
344  if (*Start == StringQuote && End[-1] == StringQuote)
345  {
346  /* Input given directly as a string */
347  End[-1] = _T('\0');
348  FullInput = cmd_dup(Start + 1);
349  }
350  else if (*Start == CommandQuote && End[-1] == CommandQuote)
351  {
352  /*
353  * Read input from a command. We let the CRT do the ANSI/UNICODE conversion.
354  * NOTE: Should we do that, or instead read in binary mode and
355  * do the conversion by ourselves, using *OUR* current codepage??
356  */
357  End[-1] = _T('\0');
358  InputFile = _tpopen(Start + 1, _T("r"));
359  if (!InputFile)
360  {
362  Ret = 1;
363  goto Quit;
364  }
365  FullInput = ReadFileContents(InputFile, Buffer);
366  _pclose(InputFile);
367  }
368  else
369  {
370  /* Read input from a file */
371  TCHAR Temp = *End;
372  *End = _T('\0');
374  InputFile = _tfopen(Start, _T("r"));
375  *End = Temp;
376  if (!InputFile)
377  {
379  Ret = 1;
380  goto Quit;
381  }
382  FullInput = ReadFileContents(InputFile, Buffer);
383  fclose(InputFile);
384  }
385 
386  if (!FullInput)
387  {
389  Ret = 1;
390  goto Quit;
391  }
392 
393  /* Patch the delimiters string */
394  if (DelimsEndPtr)
395  {
396  DelimsEndChr = *DelimsEndPtr;
397  *DelimsEndPtr = _T('\0');
398  }
399 
400  /* Loop over the input line by line */
401  for (In = FullInput, Skip = SkipLines;
402  !ExitingOrGoto(Cmd) && (In != NULL);
403  In = NextLine)
404  {
405  DWORD RemainingTokens = TokensMask;
406  LPTSTR* CurVar = fc->values;
407 
408  ZeroMemory(fc->values, fc->varcount * sizeof(*fc->values));
409 #ifdef MSCMD_FOR_QUIRKS
410  NumTokens = fc->varcount;
411 #endif
412 
413  NextLine = _tcschr(In, _T('\n'));
414  if (NextLine)
415  *NextLine++ = _T('\0');
416 
417  if (--Skip >= 0)
418  continue;
419 
420  /* Ignore lines where the first token starts with the eol character */
421  In += _tcsspn(In, Delims);
422  if (*In == Eol)
423  continue;
424 
425  /* Loop as long as we have not reached the end of
426  * the line, and that we have tokens available.
427  * A maximum of 31 tokens will be enumerated. */
428  while (*In && ((RemainingTokens >>= 1) != 0))
429  {
430  /* Save pointer to this token in a variable if requested */
431  if (RemainingTokens & 1)
432  {
433 #ifdef MSCMD_FOR_QUIRKS
434  --NumTokens;
435 #endif
436  *CurVar++ = In;
437  }
438  /* Find end of token */
439  In += _tcscspn(In, Delims);
440  /* NULL-terminate it and advance to next token */
441  if (*In)
442  {
443  *In++ = _T('\0');
444  In += _tcsspn(In, Delims);
445  }
446  }
447 
448  /* Save pointer to remainder of the line if we need to do so */
449  if (*In)
450 #ifdef MSCMD_FOR_QUIRKS
451  if (RemainderVar && (fc->varcount - NumTokens + 1 == RemainderVar))
452 #endif
453  {
454  /* NOTE: This sets fc->values[0] at least, if no tokens
455  * were initialized so far, since CurVar is initialized
456  * originally to point to fc->values. */
457  *CurVar = In;
458  }
459 
460  /* Don't run unless we have at least one variable filled */
461  if (fc->values[0])
462  Ret = RunInstance(Cmd);
463  }
464 
465  /* Restore the delimiters string */
466  if (DelimsEndPtr)
467  *DelimsEndPtr = DelimsEndChr;
468 
469  cmd_free(FullInput);
470  }
471 
472 Quit:
473 #ifdef MSCMD_FOR_QUIRKS
474  if (fc->values && (fc->values != Variables))
475  cmd_free(fc->values);
476 #endif
477 
478  return Ret;
479 }
#define max(a, b)
Definition: svc.c:63
PFOR_CONTEXT fc
Definition: for.c:57
#define error(str)
Definition: mkdosfs.c:1605
ULONG SkipLines(VOID)
Definition: parser.c:275
#define _tcstol
Definition: tchar.h:594
_Check_return_opt_ _CRTIMP int __cdecl _pclose(_Inout_ FILE *_File)
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ZeroMemory
Definition: winbase.h:1648
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
int32_t INT
Definition: typedefs.h:58
CHAR * LPTSTR
Definition: xmlstorage.h:192
BOOLEAN NextLine(PCHAR LineBuffer, ULONG BufferSize, FILE *File)
Definition: parser.c:230
WCHAR First[]
Definition: FormatMessage.c:11
#define _tcsnicmp
Definition: xmlstorage.h:207
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
VOID error_out_of_memory(VOID)
Definition: error.c:138
LPTSTR * values
Definition: batch.h:50
Definition: bufpool.h:45
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
char TCHAR
Definition: xmlstorage.h:189
#define _tfopen
Definition: xmlstorage.h:196
#define _T(x)
Definition: vfdio.h:22
static BOOL GetNextElement(TCHAR **pStart, TCHAR **pEnd)
Definition: for.c:60
LIST_ENTRY List
Definition: psmgr.c:57
#define ExitingOrGoto(Cmd)
Definition: for.c:85
#define RunInstance(Cmd)
Definition: for.c:77
unsigned long DWORD
Definition: ntddk_ex.h:95
Definition: partlist.h:33
#define _totlower
Definition: tchar.h:1511
VOID error_sfile_not_found(PCTSTR s)
Definition: error.c:100
Definition: sacdrv.h:277
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
UINT varcount
Definition: batch.h:49
#define _tcsspn
Definition: tchar.h:1414
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31
VOID error_bad_command(PCTSTR s)
Definition: error.c:124
FILE * _tpopen(const _TCHAR *cm, const _TCHAR *md)
Definition: popen.c:38
#define cmd_dup(str)
Definition: cmddbg.h:32
static LPTSTR ReadFileContents(FILE *InputFile, TCHAR *Buffer)
Definition: for.c:90
VOID error_syntax(PCTSTR s)
Definition: error.c:152
#define _tcscspn
Definition: tchar.h:1407
char * PTCHAR
Definition: ntbasedef.h:477

Referenced by ExecuteFor().

◆ ForLoop()

static INT ForLoop ( PARSED_COMMAND Cmd,
LPTSTR  List,
TCHAR Buffer 
)
static

Definition at line 482 of file for.c.

483 {
484  enum { START, STEP, END };
485  INT params[3] = { 0, 0, 0 };
486  INT i;
487  INT Ret = 0;
488  TCHAR *Start, *End = List;
489 
490  for (i = 0; i < 3 && GetNextElement(&Start, &End); ++i)
491  params[i] = _tcstol(Start, NULL, 0);
492 
493  i = params[START];
494  /*
495  * Windows' CMD compatibility:
496  * Contrary to the other FOR-loops, FOR /L does not check
497  * whether a GOTO has been done, and will continue to loop.
498  */
499  while (!Exiting(Cmd) &&
500  (params[STEP] >= 0 ? (i <= params[END]) : (i >= params[END])))
501  {
502  _itot(i, Buffer, 10);
503  Ret = RunInstance(Cmd);
504  i += params[STEP];
505  }
506 
507  return Ret;
508 }
#define _tcstol
Definition: tchar.h:594
int32_t INT
Definition: typedefs.h:58
#define _itot
Definition: tchar.h:608
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLenum const GLfloat * params
Definition: glext.h:5645
#define STEP
Definition: input.c:1260
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
Definition: infcodes.c:25
char TCHAR
Definition: xmlstorage.h:189
static BOOL GetNextElement(TCHAR **pStart, TCHAR **pEnd)
Definition: for.c:60
LIST_ENTRY List
Definition: psmgr.c:57
#define RunInstance(Cmd)
Definition: for.c:77
Definition: partlist.h:33
Definition: sacdrv.h:277
Definition: infcodes.c:17
#define Exiting(Cmd)
Definition: for.c:81

Referenced by ExecuteFor().

◆ ForRecursive()

static INT ForRecursive ( PARSED_COMMAND Cmd,
LPTSTR  List,
TCHAR Buffer,
TCHAR BufPos 
)
static

Definition at line 561 of file for.c.

562 {
563  INT Ret = 0;
564  HANDLE hFind;
565  WIN32_FIND_DATA w32fd;
566 
567  if (BufPos[-1] != _T('\\'))
568  {
569  *BufPos++ = _T('\\');
570  *BufPos = _T('\0');
571  }
572 
573  Ret = ForDir(Cmd, List, Buffer, BufPos);
574 
575  /* NOTE (We don't apply Windows' CMD compatibility here):
576  * Windows' CMD does not check whether a GOTO has been done,
577  * and will continue to loop. */
578  if (ExitingOrGoto(Cmd))
579  return Ret;
580 
581  _tcscpy(BufPos, _T("*"));
582  hFind = FindFirstFile(Buffer, &w32fd);
583  if (hFind == INVALID_HANDLE_VALUE)
584  return Ret;
585  do
586  {
587  if (!(w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
588  continue;
589  if (_tcscmp(w32fd.cFileName, _T(".")) == 0 ||
590  _tcscmp(w32fd.cFileName, _T("..")) == 0)
591  continue;
592  Ret = ForRecursive(Cmd, List, Buffer, _stpcpy(BufPos, w32fd.cFileName));
593 
594  /* NOTE (We don't apply Windows' CMD compatibility here):
595  * Windows' CMD does not check whether a GOTO has been done,
596  * and will continue to loop. */
597  } while (!ExitingOrGoto(Cmd) && FindNextFile(hFind, &w32fd));
598  FindClose(hFind);
599 
600  return Ret;
601 }
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
int32_t INT
Definition: typedefs.h:58
LPTSTR _stpcpy(LPTSTR, LPCTSTR)
Definition: misc.c:460
Definition: bufpool.h:45
#define FindFirstFile
Definition: winbase.h:3622
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
static INT ForRecursive(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
Definition: for.c:561
#define _T(x)
Definition: vfdio.h:22
LIST_ENTRY List
Definition: psmgr.c:57
#define FindNextFile
Definition: winbase.h:3628
#define ExitingOrGoto(Cmd)
Definition: for.c:85
static INT ForDir(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer, TCHAR *BufPos)
Definition: for.c:513
Definition: sacdrv.h:277
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Referenced by ExecuteFor().

◆ GetNextElement()

static BOOL GetNextElement ( TCHAR **  pStart,
TCHAR **  pEnd 
)
static

Definition at line 60 of file for.c.

61 {
62  TCHAR *p = *pEnd;
63  BOOL InQuotes = FALSE;
64  while (_istspace(*p))
65  p++;
66  if (!*p)
67  return FALSE;
68  *pStart = p;
69  while (*p && (InQuotes || !_istspace(*p)))
70  InQuotes ^= (*p++ == _T('"'));
71  *pEnd = p;
72  return TRUE;
73 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define _istspace
Definition: tchar.h:1504
GLfloat GLfloat p
Definition: glext.h:8902

Referenced by ForDir(), ForF(), and ForLoop().

◆ ReadFileContents()

static LPTSTR ReadFileContents ( FILE InputFile,
TCHAR Buffer 
)
static

Definition at line 90 of file for.c.

91 {
92  SIZE_T Len = 0;
93  SIZE_T AllocLen = 1000;
94 
95  LPTSTR Contents = cmd_alloc(AllocLen * sizeof(TCHAR));
96  if (!Contents)
97  {
98  WARN("Cannot allocate memory for Contents!\n");
99  return NULL;
100  }
101 
102  while (_fgetts(Buffer, CMDLINE_LENGTH, InputFile))
103  {
104  ULONG_PTR CharsRead = _tcslen(Buffer);
105  while (Len + CharsRead >= AllocLen)
106  {
107  LPTSTR OldContents = Contents;
108  Contents = cmd_realloc(Contents, (AllocLen *= 2) * sizeof(TCHAR));
109  if (!Contents)
110  {
111  WARN("Cannot reallocate memory for Contents!\n");
112  cmd_free(OldContents);
113  return NULL;
114  }
115  }
116  _tcscpy(&Contents[Len], Buffer);
117  Len += CharsRead;
118  }
119 
120  Contents[Len] = _T('\0');
121  return Contents;
122 }
#define WARN(fmt,...)
Definition: debug.h:112
#define _fgetts
Definition: tchar.h:565
#define CMDLINE_LENGTH
Definition: help.h:12
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
CHAR * LPTSTR
Definition: xmlstorage.h:192
uint32_t ULONG_PTR
Definition: typedefs.h:65
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define Len
Definition: deflate.h:82
#define cmd_realloc(ptr, size)
Definition: cmddbg.h:30
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31

Referenced by ForF().

Variable Documentation

◆ fc