ReactOS 0.4.15-dev-7931-gfd331f1
call.c File Reference
#include "precomp.h"
Include dependency graph for call.c:

Go to the source code of this file.

Macros

#define MSCMD_CALL_QUIRKS
 

Functions

INT cmd_call (LPTSTR param)
 

Macro Definition Documentation

◆ MSCMD_CALL_QUIRKS

#define MSCMD_CALL_QUIRKS

Definition at line 34 of file call.c.

Function Documentation

◆ cmd_call()

INT cmd_call ( LPTSTR  param)

Definition at line 40 of file call.c.

41{
43 BOOL bOldIgnoreParserComments;
44#ifndef MSCMD_CALL_QUIRKS
45 BOOL bOldHandleContinuations;
46#else
47 SIZE_T nNumCarets;
48#endif
50
51 TRACE("cmd_call(\'%s\')\n", debugstr_aw(param));
52
53 if (!_tcsncmp(param, _T("/?"), 2))
54 {
56 return 0;
57 }
58
59 /* Fail if no command or label has been provided */
60 if (*param == _T('\0'))
61 return (nErrorLevel = 1);
62
63 /* Ignore parser comments (starting with a colon) */
64 bOldIgnoreParserComments = bIgnoreParserComments;
66
67#ifndef MSCMD_CALL_QUIRKS
68 /* Disable parsing of escape carets */
69 bOldHandleContinuations = bHandleContinuations;
71 first = param;
72#else
73 /*
74 * As the original escape carets have been dealt with during the first
75 * command parsing step, the remaining ones need to be doubled so that
76 * they can again survive the new parsing step done below.
77 * But do it the Windows' CMD "buggy" way: **all** carets are doubled,
78 * even those inside quotes. However, this causes carets inside quotes
79 * to remain doubled after the parsing step...
80 */
81
82 /* Count all the carets */
83 nNumCarets = 0;
84 first = param;
85 while (first)
86 {
87 first = _tcschr(first, _T('^'));
88 if (first)
89 {
90 ++nNumCarets;
91 ++first;
92 }
93 }
94
95 /* Re-allocate a large enough parameter string if needed */
96 if (nNumCarets > 0)
97 {
98 PTCHAR Src, Dest, End;
99
100 // TODO: Improvement: Use the scratch TempBuf if the string is not too long.
101 first = cmd_alloc((_tcslen(param) + nNumCarets + 1) * sizeof(TCHAR));
102 if (!first)
103 {
104 WARN("Cannot allocate memory for new CALL parameter string!\n");
106 return (nErrorLevel = 1);
107 }
108
109 /* Copy the parameter string and double the escape carets */
110 Src = param;
111 Dest = first;
112 while (*Src)
113 {
114 if (*Src != _T('^'))
115 {
116 /* Copy everything before the next caret (or the end of the string) */
117 End = _tcschr(Src, _T('^'));
118 if (!End)
119 End = Src + _tcslen(Src);
120 memcpy(Dest, Src, (End - Src) * sizeof(TCHAR));
121 Dest += End - Src;
122 Src = End;
123 continue;
124 }
125
126 /* Copy the original caret and double it */
127 *Dest++ = *Src;
128 *Dest++ = *Src++;
129 }
130 *Dest = _T('\0');
131 }
132 else
133 {
134 first = param;
135 }
136#endif
137
138 /*
139 * Reparse the CALL parameter string as a command.
140 * Note that this will trigger a second round of %-variable substitutions.
141 */
143
144 /* Restore the global parsing state */
145#ifndef MSCMD_CALL_QUIRKS
146 bHandleContinuations = bOldHandleContinuations;
147#endif
148 bIgnoreParserComments = bOldIgnoreParserComments;
149
150 /*
151 * If no command is there, yet no error occurred, this means that
152 * a whitespace label was given. Do not consider this as a failure.
153 */
154 if (!Cmd && !bParseError)
155 {
156#ifdef MSCMD_CALL_QUIRKS
157 if (first != param)
159#endif
160 return (nErrorLevel = 0);
161 }
162
163 /* Reset bParseError so as to continue running afterwards */
165
166 /*
167 * Otherwise, if no command is there because a parse error occurred,
168 * or if this an unsupported command: not a standard one, including
169 * FOR and IF, fail and bail out.
170 */
171 if (!Cmd || (Cmd->Type == C_FOR) || (Cmd->Type == C_IF) ||
172 ((Cmd->Type != C_COMMAND) && (Cmd->Type != C_REM)))
173 {
174 // FIXME: Localize
175 ConErrPrintf(_T("%s was unexpected.\n"), first);
176
177#ifdef MSCMD_CALL_QUIRKS
178 if (first != param)
180#endif
181 if (Cmd) FreeCommand(Cmd);
182 return (nErrorLevel = 1);
183 }
184
185#ifdef MSCMD_CALL_QUIRKS
186 if (first != param)
188#endif
189
190 first = Cmd->Command.First;
191 param = Cmd->Command.Rest;
192
193 /* "CALL :label args ..." - Call a subroutine of the current batch file, only if extensions are enabled */
194 if (bEnableExtensions && (*first == _T(':')))
195 {
196 INT ret;
197
198 /* A batch context must be present */
199 if (!bc)
200 {
201 // FIXME: Localize
202 ConErrPuts(_T("Invalid attempt to call batch label outside of batch script.\n"));
204 return (nErrorLevel = 1);
205 }
206
208 nErrorLevel = (ret != 0 ? ret : nErrorLevel);
209 }
210 else
211 {
213 }
214
216 return nErrorLevel;
217}
PBATCH_CONTEXT bc
Definition: batch.c:67
INT nErrorLevel
Definition: cmd.c:158
PARSED_COMMAND * ParseCommand(IN PCTSTR Line)
Definition: parser.c:1461
BOOL bHandleContinuations
Definition: parser.c:97
BOOL bParseError
Definition: parser.c:90
@ C_COMMAND
Definition: cmd.h:353
@ C_REM
Definition: cmd.h:361
@ C_IF
Definition: cmd.h:361
@ C_FOR
Definition: cmd.h:361
BOOL bIgnoreParserComments
Definition: parser.c:96
VOID error_out_of_memory(VOID)
Definition: error.c:138
VOID FreeCommand(IN OUT PARSED_COMMAND *Cmd)
Definition: parser.c:527
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define ConErrPrintf(szStr,...)
Definition: console.h:44
#define ConErrPuts(szStr)
Definition: console.h:32
#define debugstr_aw
Definition: precomp.h:43
#define STRING_CALL_HELP
Definition: resource.h:71
#define WARN(fmt,...)
Definition: debug.h:112
static VOID DoCommand(PCONSOLE_STATE State, LPSTR line)
Definition: cmdcons.c:1082
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
const GLint * first
Definition: glext.h:5794
GLfloat param
Definition: glext.h:5796
#define _tcsncmp
Definition: tchar.h:1428
#define _tcschr
Definition: tchar.h:1406
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOL bEnableExtensions
Definition: more.c:53
char * PTCHAR
Definition: ntbasedef.h:476
@ Batch
Definition: ntsecapi.h:291
@ Cmd
Definition: sacdrv.h:278
#define TRACE(s)
Definition: solgame.cpp:4
TCHAR BatchFilePath[MAX_PATH]
Definition: batch.h:33
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
int ret
char TCHAR
Definition: xmlstorage.h:189
CHAR * PTSTR
Definition: xmlstorage.h:191
#define _tcslen
Definition: xmlstorage.h:198