cmd: Add for /f delims= support.
This commit is contained in:
parent
a45301cb93
commit
51b0d941d0
|
@ -121,9 +121,10 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
|
|||
}
|
||||
|
||||
/*******************************************************************
|
||||
* WCMD_parameter
|
||||
* WCMD_parameter_with_delims
|
||||
*
|
||||
* Extracts a delimited parameter from an input string
|
||||
* Extracts a delimited parameter from an input string, providing
|
||||
* the delimiters characters to use
|
||||
*
|
||||
* PARAMS
|
||||
* s [I] input string, non NULL
|
||||
|
@ -135,6 +136,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
|
|||
* wholecmdline [I] True to indicate this routine is being used to parse the
|
||||
* command line, and special logic for arg0->1 transition
|
||||
* needs to be applied.
|
||||
* delims[I] The delimiter characters to use
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The nth delimited parameter found in s
|
||||
|
@ -150,10 +152,9 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA
|
|||
* other API calls, e.g. c:\"a b"\c is returned as c:\a b\c. However, some commands
|
||||
* need to preserve the exact syntax (echo, for, etc) hence the raw option.
|
||||
*/
|
||||
WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
|
||||
BOOL wholecmdline)
|
||||
WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, WCHAR **end,
|
||||
BOOL raw, BOOL wholecmdline, const WCHAR *delims)
|
||||
{
|
||||
static const WCHAR defaultDelims[] = { ' ', '\t', ',', '=', ';', '\0' };
|
||||
int curParamNb = 0;
|
||||
static WCHAR param[MAX_PATH];
|
||||
WCHAR *p = s, *begin;
|
||||
|
@ -165,7 +166,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
|
|||
while (TRUE) {
|
||||
|
||||
/* Absorb repeated word delimiters until we get to the next token (or the end!) */
|
||||
while (*p && (strchrW(defaultDelims, *p) != NULL))
|
||||
while (*p && (strchrW(delims, *p) != NULL))
|
||||
p++;
|
||||
if (*p == '\0') return param;
|
||||
|
||||
|
@ -179,7 +180,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
|
|||
/* Loop character by character, but just need to special case quotes */
|
||||
while (*p) {
|
||||
/* Once we have found a delimiter, break */
|
||||
if (strchrW(defaultDelims, *p) != NULL) break;
|
||||
if (strchrW(delims, *p) != NULL) break;
|
||||
|
||||
/* Very odd special case - Seems as if a ( acts as a delimiter which is
|
||||
not swallowed but is effective only when it comes between the program
|
||||
|
@ -218,6 +219,20 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
|
|||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* WCMD_parameter
|
||||
*
|
||||
* Extracts a delimited parameter from an input string, using a
|
||||
* default set of delimiter characters. For parameters, see the main
|
||||
* function above.
|
||||
*/
|
||||
WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
|
||||
BOOL wholecmdline)
|
||||
{
|
||||
static const WCHAR defaultDelims[] = { ' ', '\t', ',', '=', ';', '\0' };
|
||||
return WCMD_parameter_with_delims (s, n, start, end, raw, wholecmdline, defaultDelims);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* WCMD_fgets
|
||||
*
|
||||
|
|
|
@ -1600,7 +1600,7 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
|
|||
}
|
||||
if (*pos==' ' && *(pos+1)==0) delims[i++] = *pos;
|
||||
delims[i++] = 0; /* Null terminate the delims */
|
||||
WINE_FIXME("Found delims as '%s'\n", wine_dbgstr_w(delims));
|
||||
WINE_TRACE("Found delims as '%s'\n", wine_dbgstr_w(delims));
|
||||
|
||||
/* Save the tokens being requested */
|
||||
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
|
||||
|
@ -1694,6 +1694,7 @@ static void WCMD_add_dirstowalk(DIRECTORY_STACK *dirsToWalk) {
|
|||
* doExecuted [O] - Set to TRUE if the DO is ever executed once
|
||||
* forf_skip [I/O] - How many lines to skip first
|
||||
* forf_eol [I] - The 'end of line' (comment) character
|
||||
* forf_delims [I] - The delimiters to use when breaking the string apart
|
||||
*/
|
||||
static void WCMD_parse_line(CMD_LIST *cmdStart,
|
||||
const WCHAR *firstCmd,
|
||||
|
@ -1702,7 +1703,8 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
|
|||
WCHAR *buffer,
|
||||
BOOL *doExecuted,
|
||||
int *forf_skip,
|
||||
WCHAR forf_eol) {
|
||||
WCHAR forf_eol,
|
||||
WCHAR *forf_delims) {
|
||||
|
||||
WCHAR *parm, *where;
|
||||
|
||||
|
@ -1713,7 +1715,7 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
|
|||
}
|
||||
|
||||
/* Extract the parameter */
|
||||
parm = WCMD_parameter (buffer, 0, &where, NULL, FALSE, FALSE);
|
||||
parm = WCMD_parameter_with_delims(buffer, 0, &where, NULL, FALSE, FALSE, forf_delims);
|
||||
WINE_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
|
||||
wine_dbgstr_w(buffer));
|
||||
|
||||
|
@ -2070,7 +2072,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
|||
/* Read line by line until end of file */
|
||||
while (WCMD_fgets(buffer, sizeof(buffer)/sizeof(WCHAR), input)) {
|
||||
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
|
||||
&forf_skip, forf_eol);
|
||||
&forf_skip, forf_eol, forf_delims);
|
||||
buffer[0] = 0;
|
||||
}
|
||||
CloseHandle (input);
|
||||
|
@ -2090,7 +2092,6 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
|||
Note that the last quote is removed from the set and the string terminates
|
||||
there to mimic windows */
|
||||
WCHAR *strend = strrchrW(itemStart, forf_usebackq?'\'':'"');
|
||||
|
||||
if (strend) {
|
||||
*strend = 0x00;
|
||||
itemStart++;
|
||||
|
@ -2099,7 +2100,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
|
|||
/* Copy the item away from the global buffer used by WCMD_parameter */
|
||||
strcpyW(buffer, itemStart);
|
||||
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
|
||||
&forf_skip, forf_eol);
|
||||
&forf_skip, forf_eol, forf_delims);
|
||||
|
||||
/* Only one string can be supplied in the whole set, abort future set processing */
|
||||
thisSet = NULL;
|
||||
|
|
|
@ -826,14 +826,14 @@ ad
|
|||
z@y
|
||||
a|d
|
||||
no output
|
||||
@todo_wine@no output
|
||||
no output
|
||||
------ delims option
|
||||
@todo_wine@a
|
||||
@todo_wine@a@space@
|
||||
@todo_wine@a d
|
||||
a
|
||||
@todo_wine@C r
|
||||
@todo_wine@foo bar baz
|
||||
a@space@
|
||||
a d
|
||||
a
|
||||
C r
|
||||
foo bar baz
|
||||
@todo_wine@c:\
|
||||
------ skip option
|
||||
c
|
||||
|
|
|
@ -108,6 +108,8 @@ static inline BOOL WCMD_is_console_handle(HANDLE h)
|
|||
}
|
||||
WCHAR *WCMD_fgets (WCHAR *buf, DWORD n, HANDLE stream);
|
||||
WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw, BOOL wholecmdline);
|
||||
WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
|
||||
BOOL wholecmdline, const WCHAR *delims);
|
||||
WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
|
||||
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr);
|
||||
void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable, const WCHAR *forValue, BOOL justFors);
|
||||
|
|
Loading…
Reference in New Issue