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
|
* 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
|
||||||
* 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
|
||||||
* 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,
|
||||||
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,
|
||||||
/* 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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* 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,
|
||||||
}
|
}
|
||||||
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) {
|
||||||
* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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) {
|
||||||
/* 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) {
|
||||||
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) {
|
||||||
/* 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
|
||||||
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)
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue