ReactOS  0.4.10-dev-244-gb941574
parser.c File Reference
#include "precomp.h"
Include dependency graph for parser.c:

Go to the source code of this file.

Macros

#define C_OP_LOWEST   C_MULTI
 
#define C_OP_HIGHEST   C_PIPE
 
#define IF_MAX_UNARY   IF_EXIST
 
#define IF_MAX_COMPARISON   IF_NEQ
 
#define STANDARD_SEPS   _T(",;=")
 
#define CHAR(Char)
 
#define STRING(String)
 
#define PRINTF(Format,...)
 
#define RECURSE(Subcommand)
 

Enumerations

enum  {
  TOK_END, TOK_NORMAL, TOK_OPERATOR, TOK_REDIRECTION,
  TOK_BEGIN_BLOCK, TOK_END_BLOCK
}
 

Functions

static BOOL IsSeparator (TCHAR Char)
 
static TCHAR ParseChar (void)
 
static void ParseError (void)
 
static int ParseToken (TCHAR ExtraEnd, TCHAR *Separators)
 
static BOOL ParseRedirection (REDIRECTION **List)
 
static PARSED_COMMANDParseCommandOp (int OpType)
 
static PARSED_COMMANDParseBlock (REDIRECTION *RedirList)
 
static PARSED_COMMANDParseIf (void)
 
static PARSED_COMMANDParseFor (void)
 
static PARSED_COMMANDParseRem (void)
 
static DECLSPEC_NOINLINE
PARSED_COMMAND
ParseCommandPart (REDIRECTION *RedirList)
 
static PARSED_COMMANDParsePrimary (void)
 
PARSED_COMMANDParseCommand (LPTSTR Line)
 
VOID EchoCommand (PARSED_COMMAND *Cmd)
 
TCHARUnparse (PARSED_COMMAND *Cmd, TCHAR *Out, TCHAR *OutEnd)
 
VOID FreeCommand (PARSED_COMMAND *Cmd)
 

Variables

static const TCHAR OpString [][3] = { _T("&"), _T("||"), _T("&&"), _T("|") }
 
static const TCHAR RedirString [][3] = { _T("<"), _T(">"), _T(">>") }
 
static const TCHAR *const IfOperatorString []
 
static BOOL bParseError
 
static BOOL bLineContinuations
 
static TCHAR ParseLine [CMDLINE_LENGTH]
 
static TCHARParsePos
 
static TCHAR CurChar
 
static TCHAR CurrentToken [CMDLINE_LENGTH]
 
static int CurrentTokenType
 
static int InsideBlock
 

Macro Definition Documentation

#define C_OP_HIGHEST   C_PIPE

Definition at line 8 of file parser.c.

Referenced by ParseCommandOp().

#define C_OP_LOWEST   C_MULTI
#define CHAR (   Char)
Value:
{ \
if (Out == OutEnd) return NULL; \
*Out++ = Char; }
return
Definition: dirsup.c:529
char Char
Definition: bzip2.c:161
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:717

Referenced by AddConsoleAliasA(), ArcGetNextTokenA(), AtapiDmaReinit(), AtapiHwInitialize__(), AtapiStartIo__(), AtaSetTransferMode(), BytesInHostent(), BytesInProtoent(), BytesInServent(), calc_arg_size(), CmpCopyName(), CmpGetNameControlBlock(), co_UserCreateWindowEx(), ComputeStringSize(), ConDrvReadConsoleOutputString(), ConDrvWriteConsoleOutputString(), ConMgrSerialPortConsumer(), CopyCompStringIMEtoClient(), CopyHostentToBuffer(), CopyProtoentToBuffer(), CopyServentToBuffer(), CPin::CPin(), CSR_API(), DuplicateStringAEx(), CPin::EnumMediaTypes(), ExpLoadBootSymbols(), FAST486_OPCODE_HANDLER(), FlatBuf_Arg_WriteString(), FONT_TextMetricWToA(), FsRtlIsDbcsInExpression(), FsRtlNotifyFilterChangeDirectory(), FsRtlNotifyFilterReportChange(), gdb_receive_packet(), get_type_size(), GetServiceDisplayNameA(), GetServiceKeyNameA(), GspGetPacket(), HCR_GetClassNameA(), HEXEDIT_WM_CHAR(), IntWideCharToMultiByteCP(), IntWideCharToMultiByteSYMBOL(), IntWideCharToMultiByteUTF8(), IPADDRESS_SubclassProc(), KbdHid_InsertScanCodes(), KdbpSymUnicodeToAnsi(), KdInitSystem(), KeBugCheckUnicodeToAnsi(), KeInitializeProcess(), LdrpGetProcedureAddress(), Link(), ListBoxWndProc_common(), main(), MountMgrNextDriveLetterWorker(), NLS_EnumCalendarInfo(), Open(), PciGetDescriptionMessage(), QueryCygwinEA(), RawUszAsz(), RtlInitAnsiString(), RtlIntegerToChar(), RtlLargeIntegerToChar(), RWComputeCHS(), ScBuildAnsiArgsVector(), START_TEST(), test_GetPrinterData(), test_GetPrinterDataEx(), test_GetPrivateProfileString(), test_profile_sections_names(), UniataFindBusMasterController(), Unparse(), UrlUnescapeA(), UTF8fromUNICODE(), VfdGetLocalLink(), VfdLoadLink(), VfdSetGlobalLink(), VfdSetLocalLink(), write_unicode2cp_table(), wvnsprintfA(), and wvnsprintfW().

#define IF_MAX_COMPARISON   IF_NEQ

Referenced by ParseIf().

#define IF_MAX_UNARY   IF_EXIST

Referenced by ParseIf().

#define PRINTF (   Format,
  ... 
)
Value:
{ \
UINT Len = _sntprintf(Out, OutEnd - Out, Format, __VA_ARGS__); \
if (Len > (UINT)(OutEnd - Out)) return NULL; \
Out += Len; }
return
Definition: dirsup.c:529
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define Len
Definition: deflate.h:82
#define _sntprintf
Definition: xmlstorage.h:201
unsigned int UINT
Definition: ndis.h:50
#define UINT
Definition: msvc.h:27

Referenced by Unparse().

#define RECURSE (   Subcommand)
Value:
{ \
Out = Unparse(Subcommand, Out, OutEnd); \
return
Definition: dirsup.c:529
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:717
TCHAR * Unparse(PARSED_COMMAND *Cmd, TCHAR *Out, TCHAR *OutEnd)
Definition: parser.c:854

Referenced by Unparse().

#define STANDARD_SEPS   _T(",;=")
Value:
{ \
if (Out + _tcslen(String) > OutEnd) return NULL; \
return
Definition: dirsup.c:529
CHAR16 * String
Definition: acefiex.h:201
LPTSTR _stpcpy(LPTSTR, LPCTSTR)
Definition: misc.c:449
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:717

Referenced by Unparse(), and while().

Enumeration Type Documentation

anonymous enum
Enumerator
TOK_END 
TOK_NORMAL 
TOK_OPERATOR 
TOK_REDIRECTION 
TOK_BEGIN_BLOCK 
TOK_END_BLOCK 

Definition at line 38 of file parser.c.

Function Documentation

VOID EchoCommand ( PARSED_COMMAND Cmd)

Definition at line 762 of file parser.c.

Referenced by Batch(), and RunInstance().

763 {
764  TCHAR Buf[CMDLINE_LENGTH];
765  PARSED_COMMAND *Sub;
766  REDIRECTION *Redir;
767 
768  switch (Cmd->Type)
769  {
770  case C_COMMAND:
771  if (SubstituteForVars(Cmd->Command.First, Buf))
772  ConOutPrintf(_T("%s"), Buf);
773  if (SubstituteForVars(Cmd->Command.Rest, Buf))
774  ConOutPrintf(_T("%s"), Buf);
775  break;
776  case C_QUIET:
777  return;
778  case C_BLOCK:
779  ConOutChar(_T('('));
780  Sub = Cmd->Subcommands;
781  if (Sub && !Sub->Next)
782  {
783  /* Single-command block: display all on one line */
784  EchoCommand(Sub);
785  }
786  else if (Sub)
787  {
788  /* Multi-command block: display parenthesis on separate lines */
789  ConOutChar(_T('\n'));
790  do
791  {
792  EchoCommand(Sub);
793  ConOutChar(_T('\n'));
794  Sub = Sub->Next;
795  } while (Sub);
796  }
797  ConOutChar(_T(')'));
798  break;
799  case C_MULTI:
800  case C_IFFAILURE:
801  case C_IFSUCCESS:
802  case C_PIPE:
803  Sub = Cmd->Subcommands;
804  EchoCommand(Sub);
805  ConOutPrintf(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST]);
806  EchoCommand(Sub->Next);
807  break;
808  case C_IF:
809  ConOutPrintf(_T("if"));
810  if (Cmd->If.Flags & IFFLAG_IGNORECASE)
811  ConOutPrintf(_T(" /I"));
812  if (Cmd->If.Flags & IFFLAG_NEGATE)
813  ConOutPrintf(_T(" not"));
814  if (Cmd->If.LeftArg && SubstituteForVars(Cmd->If.LeftArg, Buf))
815  ConOutPrintf(_T(" %s"), Buf);
816  ConOutPrintf(_T(" %s"), IfOperatorString[Cmd->If.Operator]);
817  if (SubstituteForVars(Cmd->If.RightArg, Buf))
818  ConOutPrintf(_T(" %s "), Buf);
819  Sub = Cmd->Subcommands;
820  EchoCommand(Sub);
821  if (Sub->Next)
822  {
823  ConOutPrintf(_T(" else "));
824  EchoCommand(Sub->Next);
825  }
826  break;
827  case C_FOR:
828  ConOutPrintf(_T("for"));
829  if (Cmd->For.Switches & FOR_DIRS) ConOutPrintf(_T(" /D"));
830  if (Cmd->For.Switches & FOR_F) ConOutPrintf(_T(" /F"));
831  if (Cmd->For.Switches & FOR_LOOP) ConOutPrintf(_T(" /L"));
832  if (Cmd->For.Switches & FOR_RECURSIVE) ConOutPrintf(_T(" /R"));
833  if (Cmd->For.Params)
834  ConOutPrintf(_T(" %s"), Cmd->For.Params);
835  ConOutPrintf(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List);
836  EchoCommand(Cmd->Subcommands);
837  break;
838  }
839 
840  for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next)
841  {
842  if (SubstituteForVars(Redir->Filename, Buf))
843  ConOutPrintf(_T(" %c%s%s"), _T('0') + Redir->Number,
844  RedirString[Redir->Mode], Buf);
845  }
846 }
#define FOR_DIRS
Definition: cmd.h:200
Definition: cmd.h:298
Definition: cmd.h:298
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
Definition: cmd.h:298
#define IFFLAG_IGNORECASE
Definition: cmd.h:227
VOID ConOutChar(TCHAR c)
Definition: console.c:123
BYTE Type
Definition: cmd.h:304
#define CMDLINE_LENGTH
Definition: help.h:12
Definition: cmd.h:298
#define ConOutPrintf(szStr,...)
Definition: console.h:42
#define FOR_F
Definition: cmd.h:201
struct _PARSED_COMMAND * Next
Definition: cmd.h:302
#define C_OP_LOWEST
Definition: parser.c:7
REDIR_MODE Mode
Definition: cmd.h:357
struct _PARSED_COMMAND::@54::@58 For
#define FOR_LOOP
Definition: cmd.h:202
BYTE Number
Definition: cmd.h:356
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
Definition: cmd.h:298
#define IFFLAG_NEGATE
Definition: cmd.h:226
TCHAR Filename[]
Definition: cmd.h:358
static const TCHAR *const IfOperatorString[]
Definition: parser.c:13
#define FOR_RECURSIVE
Definition: cmd.h:203
static const TCHAR RedirString[][3]
Definition: parser.c:11
struct _PARSED_COMMAND::@54::@57 If
Definition: cmd.h:298
struct _REDIRECTION * Redirections
Definition: cmd.h:303
BOOL SubstituteForVars(TCHAR *Src, TCHAR *Dest)
Definition: cmd.c:1372
static const TCHAR OpString[][3]
Definition: parser.c:9
struct _REDIRECTION * Next
Definition: cmd.h:354
Definition: cmd.h:298
VOID EchoCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:762
struct _PARSED_COMMAND::@54::@56 Command
VOID FreeCommand ( PARSED_COMMAND Cmd)

Definition at line 955 of file parser.c.

Referenced by Batch(), ParseBlock(), ParseCommand(), ParseCommandLine(), ParseCommandOp(), ParseFor(), ParseIf(), and ProcessInput().

956 {
957  if (Cmd->Subcommands)
958  FreeCommand(Cmd->Subcommands);
959  if (Cmd->Next)
960  FreeCommand(Cmd->Next);
962  if (Cmd->Type == C_IF)
963  {
964  cmd_free(Cmd->If.LeftArg);
965  cmd_free(Cmd->If.RightArg);
966  }
967  else if (Cmd->Type == C_FOR)
968  {
969  cmd_free(Cmd->For.Params);
970  cmd_free(Cmd->For.List);
971  }
972  cmd_free(Cmd);
973 }
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
Definition: cmd.h:298
BYTE Type
Definition: cmd.h:304
VOID FreeCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:955
struct _PARSED_COMMAND * Next
Definition: cmd.h:302
struct _PARSED_COMMAND::@54::@58 For
Definition: cmd.h:298
struct _PARSED_COMMAND::@54::@57 If
struct _REDIRECTION * Redirections
Definition: cmd.h:303
#define cmd_free(ptr)
Definition: cmddbg.h:31
VOID FreeRedirection(REDIRECTION *)
Definition: redir.c:153
static BOOL IsSeparator ( TCHAR  Char)
static

Definition at line 33 of file parser.c.

Referenced by ParsePrimary(), and ParseToken().

34 {
35  return _istspace(Char) || (Char && _tcschr(STANDARD_SEPS, Char));
36 }
char Char
Definition: bzip2.c:161
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
#define STANDARD_SEPS
Definition: parser.c:31
#define _istspace
Definition: tchar.h:1504
static PARSED_COMMAND* ParseBlock ( REDIRECTION RedirList)
static

Definition at line 293 of file parser.c.

Referenced by ParsePrimary().

294 {
295  PARSED_COMMAND *Cmd, *Sub, **NextPtr;
296  Cmd = cmd_alloc(sizeof(PARSED_COMMAND));
297  Cmd->Type = C_BLOCK;
298  Cmd->Next = NULL;
299  Cmd->Subcommands = NULL;
300  Cmd->Redirections = RedirList;
301 
302  /* Read the block contents */
303  NextPtr = &Cmd->Subcommands;
304  InsideBlock++;
305  while (1)
306  {
308  if (Sub)
309  {
310  *NextPtr = Sub;
311  NextPtr = &Sub->Next;
312  }
313  else if (bParseError)
314  {
315  InsideBlock--;
316  FreeCommand(Cmd);
317  return NULL;
318  }
319 
321  break;
322 
323  /* Skip past the \n */
324  ParseChar();
325  }
326  InsideBlock--;
327 
328  /* Process any trailing redirections */
330  {
331  if (!ParseRedirection(&Cmd->Redirections))
332  {
333  FreeCommand(Cmd);
334  return NULL;
335  }
336  }
337  return Cmd;
338 }
static int CurrentTokenType
Definition: parser.c:55
Definition: cmd.h:298
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
BYTE Type
Definition: cmd.h:304
VOID FreeCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:955
struct _PARSED_COMMAND * Next
Definition: cmd.h:302
static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators)
Definition: parser.c:106
#define C_OP_LOWEST
Definition: parser.c:7
static BOOL ParseRedirection(REDIRECTION **List)
Definition: parser.c:226
static BOOL bParseError
Definition: parser.c:48
smooth NULL
Definition: ftsmooth.c:416
static TCHAR ParseChar(void)
Definition: parser.c:58
Definition: sacdrv.h:278
static PARSED_COMMAND * ParseCommandOp(int OpType)
Definition: parser.c:678
struct _REDIRECTION * Redirections
Definition: cmd.h:303
#define STANDARD_SEPS
Definition: parser.c:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
static int InsideBlock
Definition: parser.c:56
static TCHAR ParseChar ( void  )
static

Definition at line 58 of file parser.c.

Referenced by ParseBlock(), ParseFor(), ParsePrimary(), ParseRem(), and ParseToken().

59 {
60  TCHAR Char;
61 
62  if (bParseError)
63  return CurChar = 0;
64 
65 restart:
66  /*
67  * Although CRs can be injected into a line via an environment
68  * variable substitution, the parser ignores them - they won't
69  * even separate tokens.
70  */
71  do
72  {
73  Char = *ParsePos++;
74  }
75  while (Char == _T('\r'));
76 
77  if (!Char)
78  {
79  ParsePos--;
81  {
82  if (!ReadLine(ParseLine, TRUE))
83  {
84  /* ^C pressed, or line was too long */
85  bParseError = TRUE;
86  }
87  else if (*(ParsePos = ParseLine))
88  {
89  goto restart;
90  }
91  }
92  }
93  return CurChar = Char;
94 }
#define TRUE
Definition: types.h:120
static BOOL bLineContinuations
Definition: parser.c:49
static BOOL bParseError
Definition: parser.c:48
char Char
Definition: bzip2.c:161
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
static TCHAR ParseLine[CMDLINE_LENGTH]
Definition: parser.c:50
static TCHAR * ParsePos
Definition: parser.c:51
BOOL ReadLine(TCHAR *commandline, BOOL bMore)
Definition: cmd.c:1435
static TCHAR CurChar
Definition: parser.c:52
PARSED_COMMAND* ParseCommand ( LPTSTR  Line)

Definition at line 717 of file parser.c.

Referenced by Batch(), ParseCommandLine(), and ProcessInput().

718 {
720 
721  if (Line)
722  {
723  if (!SubstituteVars(Line, ParseLine, _T('%')))
724  return NULL;
726  }
727  else
728  {
729  if (!ReadLine(ParseLine, FALSE))
730  return NULL;
732  }
733  bParseError = FALSE;
735  CurChar = _T(' ');
736 
738  if (Cmd)
739  {
740  if (CurrentTokenType != TOK_END)
741  ParseError();
742  if (bParseError)
743  {
744  FreeCommand(Cmd);
745  Cmd = NULL;
746  }
747  bIgnoreEcho = FALSE;
748  }
749  else
750  {
751  bIgnoreEcho = TRUE;
752  }
753  return Cmd;
754 }
static int CurrentTokenType
Definition: parser.c:55
#define TRUE
Definition: types.h:120
BOOL bIgnoreEcho
Definition: cmd.c:155
Definition: parser.c:40
BOOL SubstituteVars(TCHAR *Src, TCHAR *Dest, TCHAR Delim)
Definition: cmd.c:1206
VOID FreeCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:955
#define C_OP_LOWEST
Definition: parser.c:7
static BOOL bLineContinuations
Definition: parser.c:49
static BOOL bParseError
Definition: parser.c:48
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define _T(x)
Definition: vfdio.h:22
static TCHAR ParseLine[CMDLINE_LENGTH]
Definition: parser.c:50
static TCHAR * ParsePos
Definition: parser.c:51
BOOL ReadLine(TCHAR *commandline, BOOL bMore)
Definition: cmd.c:1435
Definition: ncftp.h:79
Definition: sacdrv.h:278
static PARSED_COMMAND * ParseCommandOp(int OpType)
Definition: parser.c:678
static TCHAR CurChar
Definition: parser.c:52
static void ParseError(void)
Definition: parser.c:96
static PARSED_COMMAND * ParseCommandOp ( int  OpType)
static

Definition at line 678 of file parser.c.

Referenced by ParseBlock(), ParseCommand(), ParseFor(), ParseIf(), and ParsePrimary().

679 {
680  PARSED_COMMAND *Cmd, *Left, *Right;
681 
682  if (OpType == C_OP_HIGHEST)
683  Cmd = ParsePrimary();
684  else
685  Cmd = ParseCommandOp(OpType + 1);
686 
687  if (Cmd && !_tcscmp(CurrentToken, OpString[OpType - C_OP_LOWEST]))
688  {
689  Left = Cmd;
690  Right = ParseCommandOp(OpType);
691  if (!Right)
692  {
693  if (!bParseError)
694  {
695  /* & is allowed to have an empty RHS */
696  if (OpType == C_MULTI)
697  return Left;
698  ParseError();
699  }
700  FreeCommand(Left);
701  return NULL;
702  }
703 
704  Cmd = cmd_alloc(sizeof(PARSED_COMMAND));
705  Cmd->Type = OpType;
706  Cmd->Next = NULL;
707  Cmd->Redirections = NULL;
708  Cmd->Subcommands = Left;
709  Left->Next = Right;
710  Right->Next = NULL;
711  }
712 
713  return Cmd;
714 }
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
BYTE Type
Definition: cmd.h:304
Definition: cmd.h:298
VOID FreeCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:955
struct _PARSED_COMMAND * Next
Definition: cmd.h:302
#define C_OP_LOWEST
Definition: parser.c:7
static BOOL bParseError
Definition: parser.c:48
smooth NULL
Definition: ftsmooth.c:416
Definition: sacdrv.h:278
static PARSED_COMMAND * ParseCommandOp(int OpType)
Definition: parser.c:678
struct _REDIRECTION * Redirections
Definition: cmd.h:303
#define cmd_alloc(size)
Definition: cmddbg.h:29
static void ParseError(void)
Definition: parser.c:96
static const TCHAR OpString[][3]
Definition: parser.c:9
#define C_OP_HIGHEST
Definition: parser.c:8
static PARSED_COMMAND * ParsePrimary(void)
Definition: parser.c:621
static DECLSPEC_NOINLINE PARSED_COMMAND* ParseCommandPart ( REDIRECTION RedirList)
static

Definition at line 556 of file parser.c.

Referenced by ParsePrimary().

557 {
558  TCHAR ParsedLine[CMDLINE_LENGTH];
560  PARSED_COMMAND *(*Func)(void);
561 
562  TCHAR *Pos = _stpcpy(ParsedLine, CurrentToken) + 1;
563  DWORD_PTR TailOffset = Pos - ParsedLine;
564 
565  /* Check for special forms */
566  if ((Func = ParseFor, _tcsicmp(ParsedLine, _T("for")) == 0) ||
567  (Func = ParseIf, _tcsicmp(ParsedLine, _T("if")) == 0) ||
568  (Func = ParseRem, _tcsicmp(ParsedLine, _T("rem")) == 0))
569  {
571  /* Do special parsing only if it's not followed by /? */
572  if (_tcscmp(CurrentToken, _T("/?")) != 0)
573  {
574  if (RedirList)
575  {
576  ParseError();
577  FreeRedirection(RedirList);
578  return NULL;
579  }
580  return Func();
581  }
582  Pos = _stpcpy(Pos, _T(" /?"));
583  }
584 
585  /* Now get the tail */
586  while (1)
587  {
588  int Type = ParseToken(0, NULL);
589  if (Type == TOK_NORMAL)
590  {
591  if (Pos + _tcslen(CurrentToken) >= &ParsedLine[CMDLINE_LENGTH])
592  {
593  ParseError();
594  FreeRedirection(RedirList);
595  return NULL;
596  }
597  Pos = _stpcpy(Pos, CurrentToken);
598  }
599  else if (Type == TOK_REDIRECTION)
600  {
601  if (!ParseRedirection(&RedirList))
602  return NULL;
603  }
604  else
605  {
606  break;
607  }
608  }
609  *Pos++ = _T('\0');
610 
611  Cmd = cmd_alloc(FIELD_OFFSET(PARSED_COMMAND, Command.First[Pos - ParsedLine]));
612  Cmd->Type = C_COMMAND;
613  Cmd->Next = NULL;
614  Cmd->Subcommands = NULL;
615  Cmd->Redirections = RedirList;
616  memcpy(Cmd->Command.First, ParsedLine, (Pos - ParsedLine) * sizeof(TCHAR));
617  Cmd->Command.Rest = Cmd->Command.First + TailOffset;
618  return Cmd;
619 }
Definition: cmd.h:298
Type
Definition: Type.h:6
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
#define _tcsicmp
Definition: xmlstorage.h:205
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
BYTE Type
Definition: cmd.h:304
ush Pos
Definition: deflate.h:92
#define CMDLINE_LENGTH
Definition: help.h:12
Definition: shell.h:41
struct _PARSED_COMMAND * Next
Definition: cmd.h:302
static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators)
Definition: parser.c:106
static PARSED_COMMAND * ParseFor(void)
Definition: parser.c:433
static BOOL ParseRedirection(REDIRECTION **List)
Definition: parser.c:226
LPTSTR _stpcpy(LPTSTR, LPCTSTR)
Definition: misc.c:449
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
static PARSED_COMMAND * ParseIf(void)
Definition: parser.c:341
char TCHAR
Definition: xmlstorage.h:189
static PARSED_COMMAND * ParseRem(void)
Definition: parser.c:548
#define _T(x)
Definition: vfdio.h:22
void(* Func)(int)
Definition: sacdrv.h:278
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
uint32_t DWORD_PTR
Definition: typedefs.h:63
struct _REDIRECTION * Redirections
Definition: cmd.h:303
#define STANDARD_SEPS
Definition: parser.c:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
static void ParseError(void)
Definition: parser.c:96
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID FreeRedirection(REDIRECTION *)
Definition: redir.c:153
struct _PARSED_COMMAND::@54::@56 Command
static void ParseError ( void  )
static

Definition at line 96 of file parser.c.

Referenced by ParseCommand(), ParseCommandOp(), ParseCommandPart(), ParseFor(), ParseIf(), ParsePrimary(), and ParseRedirection().

97 {
99  bParseError = TRUE;
100 }
static int CurrentTokenType
Definition: parser.c:55
#define TRUE
Definition: types.h:120
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
Definition: parser.c:40
static BOOL bParseError
Definition: parser.c:48
smooth NULL
Definition: ftsmooth.c:416
VOID error_syntax(LPTSTR)
Definition: error.c:150
static PARSED_COMMAND* ParseFor ( void  )
static

Definition at line 433 of file parser.c.

Referenced by ParseCommandPart().

434 {
437  TCHAR *Pos = List;
438 
439  memset(Cmd, 0, sizeof(PARSED_COMMAND));
440  Cmd->Type = C_FOR;
441 
442  while (1)
443  {
444  if (_tcsicmp(CurrentToken, _T("/D")) == 0)
445  Cmd->For.Switches |= FOR_DIRS;
446  else if (_tcsicmp(CurrentToken, _T("/F")) == 0)
447  {
448  Cmd->For.Switches |= FOR_F;
449  if (!Cmd->For.Params)
450  {
452  if (CurrentToken[0] == _T('/') || CurrentToken[0] == _T('%'))
453  break;
454  Cmd->For.Params = cmd_dup(CurrentToken);
455  }
456  }
457  else if (_tcsicmp(CurrentToken, _T("/L")) == 0)
458  Cmd->For.Switches |= FOR_LOOP;
459  else if (_tcsicmp(CurrentToken, _T("/R")) == 0)
460  {
461  Cmd->For.Switches |= FOR_RECURSIVE;
462  if (!Cmd->For.Params)
463  {
465  if (CurrentToken[0] == _T('/') || CurrentToken[0] == _T('%'))
466  break;
468  Cmd->For.Params = cmd_dup(CurrentToken);
469  }
470  }
471  else
472  break;
474  }
475 
476  /* Make sure there aren't two different switches specified
477  * at the same time, unless they're /D and /R */
478  if ((Cmd->For.Switches & (Cmd->For.Switches - 1)) != 0
479  && Cmd->For.Switches != (FOR_DIRS | FOR_RECURSIVE))
480  {
481  goto error;
482  }
483 
484  /* Variable name should be % and just one other character */
485  if (CurrentToken[0] != _T('%') || _tcslen(CurrentToken) != 2)
486  goto error;
487  Cmd->For.Variable = CurrentToken[1];
488 
490  if (_tcsicmp(CurrentToken, _T("in")) != 0)
491  goto error;
492 
494  goto error;
495 
496  while (1)
497  {
498  int Type;
499 
500  /* Pretend we're inside a block so the tokenizer will stop on ')' */
501  InsideBlock++;
502  Type = ParseToken(0, STANDARD_SEPS);
503  InsideBlock--;
504 
505  if (Type == TOK_END_BLOCK)
506  break;
507 
508  if (Type == TOK_END)
509  {
510  /* Skip past the \n */
511  ParseChar();
512  continue;
513  }
514 
515  if (Type != TOK_NORMAL)
516  goto error;
517 
518  if (Pos != List)
519  *Pos++ = _T(' ');
520 
521  if (Pos + _tcslen(CurrentToken) >= &List[CMDLINE_LENGTH])
522  goto error;
523  Pos = _stpcpy(Pos, CurrentToken);
524  }
525  *Pos = _T('\0');
526  Cmd->For.List = cmd_dup(List);
527 
529  if (_tcsicmp(CurrentToken, _T("do")) != 0)
530  goto error;
531 
533  if (Cmd->Subcommands == NULL)
534  {
535  FreeCommand(Cmd);
536  return NULL;
537  }
538 
539  return Cmd;
540 
541 error:
542  FreeCommand(Cmd);
543  ParseError();
544  return NULL;
545 }
#define FOR_DIRS
Definition: cmd.h:200
Type
Definition: Type.h:6
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
#define _tcsicmp
Definition: xmlstorage.h:205
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
BYTE Type
Definition: cmd.h:304
ush Pos
Definition: deflate.h:92
#define CMDLINE_LENGTH
Definition: help.h:12
Definition: parser.c:40
VOID FreeCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:955
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
#define FOR_F
Definition: cmd.h:201
static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators)
Definition: parser.c:106
#define C_OP_LOWEST
Definition: parser.c:7
LPTSTR _stpcpy(LPTSTR, LPCTSTR)
Definition: misc.c:449
struct _PARSED_COMMAND::@54::@58 For
#define FOR_LOOP
Definition: cmd.h:202
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
Definition: cmd.h:298
LIST_ENTRY List
Definition: psmgr.c:57
DWORD error
Definition: parser.c:104
static TCHAR ParseChar(void)
Definition: parser.c:58
#define FOR_RECURSIVE
Definition: cmd.h:203
Definition: sacdrv.h:278
static PARSED_COMMAND * ParseCommandOp(int OpType)
Definition: parser.c:678
#define STANDARD_SEPS
Definition: parser.c:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
static void ParseError(void)
Definition: parser.c:96
#define cmd_dup(str)
Definition: cmddbg.h:32
static int InsideBlock
Definition: parser.c:56
#define memset(x, y, z)
Definition: compat.h:39
static PARSED_COMMAND* ParseIf ( void  )
static

Definition at line 341 of file parser.c.

Referenced by ParseCommandPart().

342 {
344  int Type;
345  memset(Cmd, 0, sizeof(PARSED_COMMAND));
346  Cmd->Type = C_IF;
347 
348  Type = CurrentTokenType;
349  if (_tcsicmp(CurrentToken, _T("/I")) == 0)
350  {
351  Cmd->If.Flags |= IFFLAG_IGNORECASE;
352  Type = ParseToken(0, STANDARD_SEPS);
353  }
354  if (_tcsicmp(CurrentToken, _T("not")) == 0)
355  {
356  Cmd->If.Flags |= IFFLAG_NEGATE;
357  Type = ParseToken(0, STANDARD_SEPS);
358  }
359 
360  if (Type != TOK_NORMAL)
361  {
362  FreeCommand(Cmd);
363  ParseError();
364  return NULL;
365  }
366 
367  /* Check for unary operators */
368  for (; Cmd->If.Operator <= IF_MAX_UNARY; Cmd->If.Operator++)
369  {
370  if (_tcsicmp(CurrentToken, IfOperatorString[Cmd->If.Operator]) == 0)
371  {
373  {
374  FreeCommand(Cmd);
375  ParseError();
376  return NULL;
377  }
378  Cmd->If.RightArg = cmd_dup(CurrentToken);
379  goto condition_done;
380  }
381  }
382 
383  /* It must be a two-argument (comparison) operator. It could be ==, so
384  * the equals sign can't be treated as whitespace here. */
385  Cmd->If.LeftArg = cmd_dup(CurrentToken);
386  ParseToken(0, _T(",;"));
387 
388  /* The right argument can come immediately after == */
389  if (_tcsnicmp(CurrentToken, _T("=="), 2) == 0 && CurrentToken[2])
390  {
391  Cmd->If.RightArg = cmd_dup(&CurrentToken[2]);
392  goto condition_done;
393  }
394 
395  for (; Cmd->If.Operator <= IF_MAX_COMPARISON; Cmd->If.Operator++)
396  {
397  if (_tcsicmp(CurrentToken, IfOperatorString[Cmd->If.Operator]) == 0)
398  {
400  break;
401  Cmd->If.RightArg = cmd_dup(CurrentToken);
402  goto condition_done;
403  }
404  }
405  FreeCommand(Cmd);
406  ParseError();
407  return NULL;
408 
409 condition_done:
411  if (Cmd->Subcommands == NULL)
412  {
413  FreeCommand(Cmd);
414  return NULL;
415  }
416  if (_tcsicmp(CurrentToken, _T("else")) == 0)
417  {
419  if (Cmd->Subcommands->Next == NULL)
420  {
421  FreeCommand(Cmd);
422  return NULL;
423  }
424  }
425 
426  return Cmd;
427 }
static int CurrentTokenType
Definition: parser.c:55
Type
Definition: Type.h:6
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
Definition: cmd.h:298
#define _tcsicmp
Definition: xmlstorage.h:205
#define IFFLAG_IGNORECASE
Definition: cmd.h:227
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
BYTE Type
Definition: cmd.h:304
#define IF_MAX_UNARY
VOID FreeCommand(PARSED_COMMAND *Cmd)
Definition: parser.c:955
static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators)
Definition: parser.c:106
#define C_OP_LOWEST
Definition: parser.c:7
#define _tcsnicmp
Definition: xmlstorage.h:207
smooth NULL
Definition: ftsmooth.c:416
#define _T(x)
Definition: vfdio.h:22
#define IFFLAG_NEGATE
Definition: cmd.h:226
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
static const TCHAR *const IfOperatorString[]
Definition: parser.c:13
Definition: sacdrv.h:278
static PARSED_COMMAND * ParseCommandOp(int OpType)
Definition: parser.c:678
struct _PARSED_COMMAND::@54::@57 If
#define STANDARD_SEPS
Definition: parser.c:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
static void ParseError(void)
Definition: parser.c:96
#define cmd_dup(str)
Definition: cmddbg.h:32
#define IF_MAX_COMPARISON
#define memset(x, y, z)
Definition: compat.h:39
static PARSED_COMMAND* ParsePrimary ( void  )
static

Definition at line 621 of file parser.c.

Referenced by ParseCommandOp().

622 {
623  REDIRECTION *RedirList = NULL;
624  int Type;
625 
626  while (IsSeparator(CurChar))
627  {
628  if (CurChar == _T('\n'))
629  return NULL;
630  ParseChar();
631  }
632 
633  if (!CurChar)
634  return NULL;
635 
636  if (CurChar == _T(':'))
637  {
638  /* "Ignore" the rest of the line.
639  * (Line continuations will still be parsed, though.) */
640  while (ParseToken(0, NULL) != TOK_END)
641  ;
642  return NULL;
643  }
644 
645  if (CurChar == _T('@'))
646  {
648  ParseChar();
649  Cmd = cmd_alloc(sizeof(PARSED_COMMAND));
650  Cmd->Type = C_QUIET;
651  Cmd->Next = NULL;
652  /* @ acts like a unary operator with low precedence,
653  * so call the top-level parser */
655  Cmd->Redirections = NULL;
656  return Cmd;
657  }
658 
659  /* Process leading redirections and get the head of the command */
660  while ((Type = ParseToken(_T('('), STANDARD_SEPS)) == TOK_REDIRECTION)
661  {
662  if (!ParseRedirection(&RedirList))
663  return NULL;
664  }
665 
666  if (Type == TOK_NORMAL)
667  return ParseCommandPart(RedirList);
668  else if (Type == TOK_BEGIN_BLOCK)
669  return ParseBlock(RedirList);
670  else if (Type == TOK_END_BLOCK && !RedirList)
671  return NULL;
672 
673  ParseError();
674  FreeRedirection(RedirList);
675  return NULL;
676 }
static DECLSPEC_NOINLINE PARSED_COMMAND * ParseCommandPart(REDIRECTION *RedirList)
Definition: parser.c:556
Type
Definition: Type.h:6
struct _PARSED_COMMAND * Subcommands
Definition: cmd.h:301
BYTE Type
Definition: cmd.h:304
static PARSED_COMMAND * ParseBlock(REDIRECTION *RedirList)
Definition: parser.c:293
Definition: parser.c:40
static BOOL IsSeparator(TCHAR Char)
Definition: parser.c:33
struct _PARSED_COMMAND * Next
Definition: cmd.h:302
static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators)
Definition: parser.c:106
#define C_OP_LOWEST
Definition: parser.c:7
static BOOL ParseRedirection(REDIRECTION **List)
Definition: parser.c:226
smooth NULL
Definition: ftsmooth.c:416
#define _T(x)
Definition: vfdio.h:22
static TCHAR ParseChar(void)
Definition: parser.c:58
Definition: sacdrv.h:278
static PARSED_COMMAND * ParseCommandOp(int OpType)
Definition: parser.c:678
struct _REDIRECTION * Redirections
Definition: cmd.h:303
#define STANDARD_SEPS
Definition: parser.c:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
static TCHAR CurChar
Definition: parser.c:52
static void ParseError(void)
Definition: parser.c:96
VOID FreeRedirection(REDIRECTION *)
Definition: redir.c:153
Definition: cmd.h:298
static BOOL ParseRedirection ( REDIRECTION **  List)
static

Definition at line 226 of file parser.c.

Referenced by ParseBlock(), ParseCommandPart(), and ParsePrimary().

227 {
228  TCHAR *Tok = CurrentToken;
229  BYTE Number;
230  REDIR_MODE RedirMode;
231  REDIRECTION *Redir;
232 
233  if (*Tok >= _T('0') && *Tok <= _T('9'))
234  Number = *Tok++ - _T('0');
235  else
236  Number = *Tok == _T('<') ? 0 : 1;
237 
238  if (*Tok++ == _T('<'))
239  {
240  RedirMode = REDIR_READ;
241  if (*Tok == _T('<'))
242  goto fail;
243  }
244  else
245  {
246  RedirMode = REDIR_WRITE;
247  if (*Tok == _T('>'))
248  {
249  RedirMode = REDIR_APPEND;
250  Tok++;
251  }
252  }
253 
254  if (!*Tok)
255  {
256  /* The file name was not part of this token, so it'll be the next one */
258  goto fail;
259  Tok = CurrentToken;
260  }
261 
262  /* If a redirection for this handle number already exists, delete it */
263  while ((Redir = *List))
264  {
265  if (Redir->Number == Number)
266  {
267  *List = Redir->Next;
268  cmd_free(Redir);
269  continue;
270  }
271  List = &Redir->Next;
272  }
273 
274  Redir = cmd_alloc(FIELD_OFFSET(REDIRECTION, Filename[_tcslen(Tok) + 1]));
275  Redir->Next = NULL;
277  Redir->Number = Number;
278  Redir->Mode = RedirMode;
279  _tcscpy(Redir->Filename, Tok);
280  *List = Redir;
281  return TRUE;
282 
283 fail:
284  ParseError();
285  FreeRedirection(*List);
286  *List = NULL;
287  return FALSE;
288 }
#define TRUE
Definition: types.h:120
enum _REDIR_MODE REDIR_MODE
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
static int ParseToken(TCHAR ExtraEnd, TCHAR *Separators)
Definition: parser.c:106
IN PVCB IN PBCB OUT PDIRENT IN USHORT IN POEM_STRING Filename
Definition: fatprocs.h:925
REDIR_MODE Mode
Definition: cmd.h:357
HANDLE OldHandle
Definition: cmd.h:355
#define FALSE
Definition: types.h:117
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
BYTE Number
Definition: cmd.h:356
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
TCHAR Filename[]
Definition: cmd.h:358
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
unsigned char BYTE
Definition: ntddk_ex.h:96
#define STANDARD_SEPS
Definition: parser.c:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31
static void ParseError(void)
Definition: parser.c:96
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
VOID FreeRedirection(REDIRECTION *)
Definition: redir.c:153
struct _REDIRECTION * Next
Definition: cmd.h:354
static PARSED_COMMAND* ParseRem ( void  )
static

Definition at line 548 of file parser.c.

Referenced by ParseCommandPart().

549 {
550  /* Just ignore the rest of the line */
551  while (CurChar && CurChar != _T('\n'))
552  ParseChar();
553  return NULL;
554 }
smooth NULL
Definition: ftsmooth.c:416
#define _T(x)
Definition: vfdio.h:22
static TCHAR ParseChar(void)
Definition: parser.c:58
static TCHAR CurChar
Definition: parser.c:52
static int ParseToken ( TCHAR  ExtraEnd,
TCHAR Separators 
)
static

Definition at line 106 of file parser.c.

Referenced by ParseBlock(), ParseCommandPart(), ParseFor(), ParseIf(), ParsePrimary(), and ParseRedirection().

107 {
109  TCHAR Char;
110  int Type;
111  BOOL bInQuote = FALSE;
112 
113  for (Char = CurChar; Char && Char != _T('\n'); Char = ParseChar())
114  {
115  bInQuote ^= (Char == _T('"'));
116  if (!bInQuote)
117  {
118  if (Separators != NULL)
119  {
120  if (_istspace(Char) || _tcschr(Separators, Char))
121  {
122  /* Skip leading separators */
123  if (Out == CurrentToken)
124  continue;
125  break;
126  }
127  }
128 
129  /* Check for numbered redirection */
130  if ((Char >= _T('0') && Char <= _T('9') &&
131  (ParsePos == &ParseLine[1] || IsSeparator(ParsePos[-2]))
132  && (*ParsePos == _T('<') || *ParsePos == _T('>'))))
133  {
134  break;
135  }
136 
137  if (Char == ExtraEnd)
138  break;
139  if (InsideBlock && Char == _T(')'))
140  break;
141  if (_tcschr(_T("&|<>"), Char))
142  break;
143 
144  if (Char == _T('^'))
145  {
146  Char = ParseChar();
147  /* Eat up a \n, allowing line continuation */
148  if (Char == _T('\n'))
149  Char = ParseChar();
150  /* Next character is a forced literal */
151  }
152  }
153  if (Out == &CurrentToken[CMDLINE_LENGTH - 1])
154  break;
155  *Out++ = Char;
156  }
157 
158  /* Check if we got at least one character before reaching a special one.
159  * If so, return them and leave the special for the next call. */
160  if (Out != CurrentToken)
161  {
162  Type = TOK_NORMAL;
163  }
164  else if (Char == _T('('))
165  {
166  Type = TOK_BEGIN_BLOCK;
167  *Out++ = Char;
168  ParseChar();
169  }
170  else if (Char == _T(')'))
171  {
172  Type = TOK_END_BLOCK;
173  *Out++ = Char;
174  ParseChar();
175  }
176  else if (Char == _T('&') || Char == _T('|'))
177  {
178  Type = TOK_OPERATOR;
179  *Out++ = Char;
180  Char = ParseChar();
181  /* check for && or || */
182  if (Char == Out[-1])
183  {
184  *Out++ = Char;
185  ParseChar();
186  }
187  }
188  else if ((Char >= _T('0') && Char <= _T('9'))
189  || (Char == _T('<') || Char == _T('>')))
190  {
191  Type = TOK_REDIRECTION;
192  if (Char >= _T('0') && Char <= _T('9'))
193  {
194  *Out++ = Char;
195  Char = ParseChar();
196  }
197  *Out++ = Char;
198  Char = ParseChar();
199  if (Char == Out[-1])
200  {
201  /* Strangely, the tokenizer allows << as well as >>... (it
202  * will cause an error when trying to parse it though) */
203  *Out++ = Char;
204  Char = ParseChar();
205  }
206  if (Char == _T('&'))
207  {
208  *Out++ = Char;
209  while (IsSeparator(Char = ParseChar()))
210  ;
211  if (Char >= _T('0') && Char <= _T('9'))
212  {
213  *Out++ = Char;
214  ParseChar();
215  }
216  }
217  }
218  else
219  {
220  Type = TOK_END;
221  }
222  *Out = _T('\0');
223  return CurrentTokenType = Type;
224 }
static int CurrentTokenType
Definition: parser.c:55
Type
Definition: Type.h:6
static TCHAR CurrentToken[CMDLINE_LENGTH]
Definition: parser.c:54
#define CMDLINE_LENGTH
Definition: help.h:12
Definition: parser.c:40
static BOOL IsSeparator(TCHAR Char)
Definition: parser.c:33
#define FALSE
Definition: types.h:117
char Char
Definition: bzip2.c:161
smooth NULL
Definition: ftsmooth.c:416
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
unsigned int BOOL
Definition: ntddk_ex.h:94
static TCHAR ParseLine[CMDLINE_LENGTH]
Definition: parser.c:50
static TCHAR * ParsePos
Definition: parser.c:51
static TCHAR ParseChar(void)
Definition: parser.c:58
static TCHAR CurChar
Definition: parser.c:52
static int InsideBlock
Definition: parser.c:56
#define _istspace
Definition: tchar.h:1504
TCHAR* Unparse ( PARSED_COMMAND Cmd,
TCHAR Out,
TCHAR OutEnd 
)

Definition at line 854 of file parser.c.

Referenced by ExecuteAsync().

855 {
856  TCHAR Buf[CMDLINE_LENGTH];
857  PARSED_COMMAND *Sub;
858  REDIRECTION *Redir;
859 
860 /*
861  * Since this function has the annoying requirement that it must avoid
862  * overflowing the supplied buffer, define some helper macros to make
863  * this less painful.
864  */
865 #define CHAR(Char) { \
866  if (Out == OutEnd) return NULL; \
867  *Out++ = Char; }
868 #define STRING(String) { \
869  if (Out + _tcslen(String) > OutEnd) return NULL; \
870  Out = _stpcpy(Out, String); }
871 #define PRINTF(Format, ...) { \
872  UINT Len = _sntprintf(Out, OutEnd - Out, Format, __VA_ARGS__); \
873  if (Len > (UINT)(OutEnd - Out)) return NULL; \
874  Out += Len; }
875 #define RECURSE(Subcommand) { \
876  Out = Unparse(Subcommand, Out, OutEnd); \
877  if (!Out) return NULL; }
878 
879  switch (Cmd->Type)
880  {
881  case C_COMMAND:
882  /* This is fragile since there could be special characters, but
883  * Windows doesn't bother escaping them, so for compatibility
884  * we probably shouldn't do it either */
885  if (!SubstituteForVars(Cmd->Command.First, Buf)) return NULL;
886  STRING(Buf)
887  if (!SubstituteForVars(Cmd->Command.Rest, Buf)) return NULL;
888  STRING(Buf)
889  break;
890  case C_QUIET:
891  CHAR(_T('@'))
892  RECURSE(Cmd->Subcommands)
893  break;
894  case C_BLOCK:
895  CHAR(_T('('))
896  for (Sub = Cmd->Subcommands; Sub; Sub = Sub->Next)
897  {
898  RECURSE(Sub)
899  if (Sub->Next)
900  CHAR(_T('&'))
901  }
902  CHAR(_T(')'))
903  break;
904  case C_MULTI:
905  case C_IFFAILURE:
906  case C_IFSUCCESS:
907  case C_PIPE:
908  Sub = Cmd->Subcommands;
909  RECURSE(Sub)
910  PRINTF(_T(" %s "), OpString[Cmd->Type - C_OP_LOWEST])
911  RECURSE(Sub->Next)
912  break;
913  case C_IF:
914  STRING(_T("if"))
915  if (Cmd->If.Flags & IFFLAG_IGNORECASE)
916  STRING(_T(" /I"))
917  if (Cmd->If.Flags & IFFLAG_NEGATE)
918  STRING(_T(" not"))
919  if (Cmd->If.LeftArg && SubstituteForVars(Cmd->If.LeftArg, Buf))
920  PRINTF(_T(" %s"), Buf)
921  PRINTF(_T(" %s"), IfOperatorString[Cmd->If.Operator]);
922  if (!SubstituteForVars(Cmd->If.RightArg, Buf)) return NULL;
923  PRINTF(_T(" %s "), Buf)
924  Sub = Cmd->Subcommands;
925  RECURSE(Sub)
926  if (Sub->Next)
927  {
928  STRING(_T(" else "))
929  RECURSE(Sub->Next)
930  }
931  break;
932  case C_FOR:
933  STRING(_T("for"))
934  if (Cmd->For.Switches & FOR_DIRS) STRING(_T(" /D"))
935  if (Cmd->For.Switches & FOR_F) STRING(_T(" /F"))
936  if (Cmd->For.Switches & FOR_LOOP) STRING(_T(" /L"))
937  if (Cmd->For.Switches & FOR_RECURSIVE) STRING(_T(" /R"))
938  if (Cmd->For.Params)
939  PRINTF(_T(" %s"), Cmd->For.Params)
940  PRINTF(_T(" %%%c in (%s) do "), Cmd->For.Variable, Cmd->For.List)
941  RECURSE(Cmd->Subcommands)
942  break;
943  }
944 
945  for (Redir = Cmd->Redirections; Redir; Redir = Redir->Next)
946  {
947  if (!SubstituteForVars(Redir->Filename, Buf)) return NULL;
948  PRINTF(_T(" %c%s%s"), _T('0') + Redir->Number,
949  RedirString[Redir->Mode], Buf)
950  }
951  return Out;
952 }
#define FOR_DIRS
Definition: cmd.h:200
#define R(b, x)
Definition: sha2.c:134
Definition: cmd.h:298
Definition: cmd.h:298
Type
Definition: Type.h:6
#define RECURSE(Subcommand)
Definition: cmd.h:298
#define IFFLAG_IGNORECASE
Definition: cmd.h:227
BYTE Type
Definition: cmd.h:304
char CHAR
Definition: xmlstorage.h:175
#define CMDLINE_LENGTH
Definition: help.h:12
Definition: cmd.h:298
Definition: shell.h:41
#define FOR_F
Definition: cmd.h:201
#define C_OP_LOWEST
Definition: parser.c:7
REDIR_MODE Mode
Definition: cmd.h:357
return
Definition: dirsup.c:529
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define PRINTF(Format,...)
#define FOR_LOOP
Definition: cmd.h:202
smooth NULL
Definition: ftsmooth.c:416
BYTE Number
Definition: cmd.h:356
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
Definition: cmd.h:298
LIST_ENTRY List
Definition: psmgr.c:57
if(!(yy_init))
Definition: macro.lex.yy.c:717
do
Definition: dirsup.c:1173
#define D
Definition: mbstring.h:29
const GLubyte * c
Definition: glext.h:8905
#define IFFLAG_NEGATE
Definition: cmd.h:226
TCHAR Filename[]
Definition: cmd.h:358
#define for
Definition: utility.h:88
static const TCHAR *const IfOperatorString[]
Definition: parser.c:13
#define STRING(String)
std::wstring STRING
Definition: fontsub.cpp:33
#define FOR_RECURSIVE
Definition: cmd.h:203
static const TCHAR RedirString[][3]
Definition: parser.c:11
static const WCHAR L[]
Definition: oid.c:1087
#define I(s)
GLdouble s
Definition: gl.h:2039
Definition: cmd.h:298
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
BOOL SubstituteForVars(TCHAR *Src, TCHAR *Dest)
Definition: cmd.c:1372
static const TCHAR OpString[][3]
Definition: parser.c:9
Definition: cmd.h:298
#define F(x, y, z)
Definition: md5.c:51
struct _PARSED_COMMAND::@54::@56 Command

Variable Documentation

BOOL bLineContinuations
static

Definition at line 49 of file parser.c.

Referenced by ParseChar(), and ParseCommand().

BOOL bParseError
static

Definition at line 48 of file parser.c.

Referenced by ParseBlock(), ParseChar(), ParseCommand(), ParseCommandOp(), and ParseError().

TCHAR CurrentToken[CMDLINE_LENGTH]
static
int CurrentTokenType
static

Definition at line 55 of file parser.c.

Referenced by ParseBlock(), ParseCommand(), ParseError(), ParseIf(), and ParseToken().

const TCHAR* const IfOperatorString[]
static
Initial value:
=
{
_T("cmdextversion"),
_T("defined"),
_T("errorlevel"),
_T("exist"),
#define IF_MAX_UNARY
_T("=="),
_T("equ"),
_T("gtr"),
_T("geq"),
_T("lss"),
_T("leq"),
_T("neq"),
#define IF_MAX_COMPARISON
}
#define _T(x)
Definition: vfdio.h:22

Definition at line 13 of file parser.c.

Referenced by EchoCommand(), ParseIf(), and Unparse().

int InsideBlock
static

Definition at line 56 of file parser.c.

Referenced by ParseBlock(), ParseFor(), and ParseToken().

const TCHAR OpString[][3] = { _T("&"), _T("||"), _T("&&"), _T("|") }
static

Definition at line 9 of file parser.c.

Referenced by EchoCommand(), ParseCommandOp(), and Unparse().

TCHAR ParseLine[CMDLINE_LENGTH]
static

Definition at line 50 of file parser.c.

Referenced by ParseChar(), ParseCommand(), and ParseToken().

TCHAR* ParsePos
static

Definition at line 51 of file parser.c.

Referenced by ParseChar(), ParseCommand(), and ParseToken().

const TCHAR RedirString[][3] = { _T("<"), _T(">"), _T(">>") }
static

Definition at line 11 of file parser.c.

Referenced by EchoCommand(), and Unparse().