Commit 51b0d941 authored by Jason Edmeades's avatar Jason Edmeades Committed by Alexandre Julliard

cmd: Add for /f delims= support.

parent a45301cb
...@@ -121,9 +121,10 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA ...@@ -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 * PARAMS
* s [I] input string, non NULL * s [I] input string, non NULL
...@@ -135,6 +136,7 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA ...@@ -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 * wholecmdline [I] True to indicate this routine is being used to parse the
* command line, and special logic for arg0->1 transition * command line, and special logic for arg0->1 transition
* needs to be applied. * needs to be applied.
* delims[I] The delimiter characters to use
* *
* RETURNS * RETURNS
* Success: The nth delimited parameter found in s * Success: The nth delimited parameter found in s
...@@ -150,10 +152,9 @@ void WCMD_batch (WCHAR *file, WCHAR *command, BOOL called, WCHAR *startLabel, HA ...@@ -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 * 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. * 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, WCHAR *WCMD_parameter_with_delims (WCHAR *s, int n, WCHAR **start, WCHAR **end,
BOOL wholecmdline) BOOL raw, BOOL wholecmdline, const WCHAR *delims)
{ {
static const WCHAR defaultDelims[] = { ' ', '\t', ',', '=', ';', '\0' };
int curParamNb = 0; int curParamNb = 0;
static WCHAR param[MAX_PATH]; static WCHAR param[MAX_PATH];
WCHAR *p = s, *begin; WCHAR *p = s, *begin;
...@@ -165,7 +166,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw, ...@@ -165,7 +166,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw,
while (TRUE) { while (TRUE) {
/* Absorb repeated word delimiters until we get to the next token (or the end!) */ /* 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++; p++;
if (*p == '\0') return param; if (*p == '\0') return param;
...@@ -179,7 +180,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **start, WCHAR **end, BOOL raw, ...@@ -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 */ /* Loop character by character, but just need to special case quotes */
while (*p) { while (*p) {
/* Once we have found a delimiter, break */ /* 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 /* 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 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, ...@@ -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 * WCMD_fgets
* *
......
...@@ -1600,7 +1600,7 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip, ...@@ -1600,7 +1600,7 @@ static BOOL WCMD_parse_forf_options(WCHAR *options, WCHAR *eol, int *skip,
} }
if (*pos==' ' && *(pos+1)==0) delims[i++] = *pos; if (*pos==' ' && *(pos+1)==0) delims[i++] = *pos;
delims[i++] = 0; /* Null terminate the delims */ 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 */ /* Save the tokens being requested */
} else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, } else if (CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
...@@ -1694,6 +1694,7 @@ static void WCMD_add_dirstowalk(DIRECTORY_STACK *dirsToWalk) { ...@@ -1694,6 +1694,7 @@ static void WCMD_add_dirstowalk(DIRECTORY_STACK *dirsToWalk) {
* doExecuted [O] - Set to TRUE if the DO is ever executed once * doExecuted [O] - Set to TRUE if the DO is ever executed once
* forf_skip [I/O] - How many lines to skip first * forf_skip [I/O] - How many lines to skip first
* forf_eol [I] - The 'end of line' (comment) character * 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, static void WCMD_parse_line(CMD_LIST *cmdStart,
const WCHAR *firstCmd, const WCHAR *firstCmd,
...@@ -1702,7 +1703,8 @@ static void WCMD_parse_line(CMD_LIST *cmdStart, ...@@ -1702,7 +1703,8 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
WCHAR *buffer, WCHAR *buffer,
BOOL *doExecuted, BOOL *doExecuted,
int *forf_skip, int *forf_skip,
WCHAR forf_eol) { WCHAR forf_eol,
WCHAR *forf_delims) {
WCHAR *parm, *where; WCHAR *parm, *where;
...@@ -1713,7 +1715,7 @@ static void WCMD_parse_line(CMD_LIST *cmdStart, ...@@ -1713,7 +1715,7 @@ static void WCMD_parse_line(CMD_LIST *cmdStart,
} }
/* Extract the parameter */ /* 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_TRACE("Parsed parameter: %s from %s\n", wine_dbgstr_w(parm),
wine_dbgstr_w(buffer)); wine_dbgstr_w(buffer));
...@@ -2070,7 +2072,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { ...@@ -2070,7 +2072,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Read line by line until end of file */ /* Read line by line until end of file */
while (WCMD_fgets(buffer, sizeof(buffer)/sizeof(WCHAR), input)) { while (WCMD_fgets(buffer, sizeof(buffer)/sizeof(WCHAR), input)) {
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted, WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted,
&forf_skip, forf_eol); &forf_skip, forf_eol, forf_delims);
buffer[0] = 0; buffer[0] = 0;
} }
CloseHandle (input); CloseHandle (input);
...@@ -2090,7 +2092,6 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { ...@@ -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 Note that the last quote is removed from the set and the string terminates
there to mimic windows */ there to mimic windows */
WCHAR *strend = strrchrW(itemStart, forf_usebackq?'\'':'"'); WCHAR *strend = strrchrW(itemStart, forf_usebackq?'\'':'"');
if (strend) { if (strend) {
*strend = 0x00; *strend = 0x00;
itemStart++; itemStart++;
...@@ -2099,7 +2100,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) { ...@@ -2099,7 +2100,7 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
/* Copy the item away from the global buffer used by WCMD_parameter */ /* Copy the item away from the global buffer used by WCMD_parameter */
strcpyW(buffer, itemStart); strcpyW(buffer, itemStart);
WCMD_parse_line(cmdStart, firstCmd, &cmdEnd, variable, buffer, &doExecuted, 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 */ /* Only one string can be supplied in the whole set, abort future set processing */
thisSet = NULL; thisSet = NULL;
......
...@@ -826,14 +826,14 @@ ad ...@@ -826,14 +826,14 @@ ad
z@y z@y
a|d a|d
no output no output
@todo_wine@no output no output
------ delims option ------ delims option
@todo_wine@a
@todo_wine@a@space@
@todo_wine@a d
a a
@todo_wine@C r a@space@
@todo_wine@foo bar baz a d
a
C r
foo bar baz
@todo_wine@c:\ @todo_wine@c:\
------ skip option ------ skip option
c c
......
...@@ -108,6 +108,8 @@ static inline BOOL WCMD_is_console_handle(HANDLE h) ...@@ -108,6 +108,8 @@ static inline BOOL WCMD_is_console_handle(HANDLE h)
} }
WCHAR *WCMD_fgets (WCHAR *buf, DWORD n, HANDLE stream); 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 (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); WCHAR *WCMD_skip_leading_spaces (WCHAR *string);
BOOL WCMD_keyword_ws_found(const WCHAR *keyword, int len, const WCHAR *ptr); 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); void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable, const WCHAR *forValue, BOOL justFors);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment