forked from Mirrors/wine-wine
cmd.exe: Expand for variables at last with tilda modifications.
parent
dc372175d4
commit
b69241124e
|
@ -19,6 +19,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "wcmd.h"
|
#include "wcmd.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(cmd);
|
||||||
|
|
||||||
extern int echo_mode;
|
extern int echo_mode;
|
||||||
extern WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
|
extern WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
|
||||||
|
@ -301,7 +304,7 @@ void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHA
|
||||||
* Hence search forwards until find an invalid modifier, and then
|
* Hence search forwards until find an invalid modifier, and then
|
||||||
* backwards until find for variable or 0-9
|
* backwards until find for variable or 0-9
|
||||||
*/
|
*/
|
||||||
void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable) {
|
void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValue, BOOL justFors) {
|
||||||
|
|
||||||
#define NUMMODIFIERS 11
|
#define NUMMODIFIERS 11
|
||||||
static const WCHAR validmodifiers[NUMMODIFIERS] = {
|
static const WCHAR validmodifiers[NUMMODIFIERS] = {
|
||||||
|
@ -324,10 +327,10 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable) {
|
||||||
BOOL skipFileParsing = FALSE;
|
BOOL skipFileParsing = FALSE;
|
||||||
BOOL doneModifier = FALSE;
|
BOOL doneModifier = FALSE;
|
||||||
|
|
||||||
/* Search forwards until find invalid WCHARacter modifier */
|
/* Search forwards until find invalid character modifier */
|
||||||
while (!finished) {
|
while (!finished) {
|
||||||
|
|
||||||
/* Work on the previous WCHARacter */
|
/* Work on the previous character */
|
||||||
if (lastModifier != NULL) {
|
if (lastModifier != NULL) {
|
||||||
|
|
||||||
for (i=0; i<NUMMODIFIERS; i++) {
|
for (i=0; i<NUMMODIFIERS; i++) {
|
||||||
|
@ -355,27 +358,30 @@ void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now make sure the position we stopped at is a valid parameter */
|
while (lastModifier > firstModifier) {
|
||||||
if (!(*lastModifier >= '0' || *lastModifier <= '9') &&
|
WINE_TRACE("Looking backwards for parameter id: %s / %s\n",
|
||||||
(forVariable != NULL) &&
|
wine_dbgstr_w(lastModifier), wine_dbgstr_w(forVariable));
|
||||||
(toupperW(*lastModifier) != toupperW(*forVariable))) {
|
|
||||||
|
|
||||||
/* Its not... Step backwards until it matches or we get to the start */
|
if (!justFors && context && (*lastModifier >= '0' || *lastModifier <= '9')) {
|
||||||
while (toupperW(*lastModifier) != toupperW(*forVariable) &&
|
/* Its a valid parameter identifier - OK */
|
||||||
lastModifier > firstModifier) {
|
break;
|
||||||
|
|
||||||
|
} else if (forVariable && *lastModifier == *(forVariable+1)) {
|
||||||
|
/* Its a valid parameter identifier - OK */
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else {
|
||||||
lastModifier--;
|
lastModifier--;
|
||||||
}
|
}
|
||||||
if (lastModifier == firstModifier) return; /* Invalid syntax */
|
|
||||||
}
|
}
|
||||||
|
if (lastModifier == firstModifier) return; /* Invalid syntax */
|
||||||
|
|
||||||
/* Extract the parameter to play with */
|
/* Extract the parameter to play with */
|
||||||
if ((*lastModifier >= '0' && *lastModifier <= '9')) {
|
if ((*lastModifier >= '0' && *lastModifier <= '9')) {
|
||||||
strcpyW(outputparam, WCMD_parameter (context -> command,
|
strcpyW(outputparam, WCMD_parameter (context -> command,
|
||||||
*lastModifier-'0' + context -> shift_count[*lastModifier-'0'], NULL));
|
*lastModifier-'0' + context -> shift_count[*lastModifier-'0'], NULL));
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: Retrieve 'for' variable %c\n", *lastModifier); */
|
strcpyW(outputparam, forValue);
|
||||||
/* Need to get 'for' loop variable into outputparam */
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* So now, firstModifier points to beginning of modifiers, lastModifier
|
/* So now, firstModifier points to beginning of modifiers, lastModifier
|
||||||
|
|
|
@ -992,40 +992,6 @@ void WCMD_part_execute(CMD_LIST **cmdList, WCHAR *firstcmd, WCHAR *variable,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* WCMD_Execute
|
|
||||||
*
|
|
||||||
* Execute a command after substituting variable text for the supplied parameter
|
|
||||||
*/
|
|
||||||
|
|
||||||
void WCMD_execute (WCHAR *orig_cmd, WCHAR *param, WCHAR *subst, CMD_LIST **cmdList) {
|
|
||||||
|
|
||||||
WCHAR *new_cmd, *p, *s, *dup;
|
|
||||||
int size;
|
|
||||||
|
|
||||||
if (param) {
|
|
||||||
size = (strlenW (orig_cmd) + 1) * sizeof(WCHAR);
|
|
||||||
new_cmd = (WCHAR *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, size);
|
|
||||||
dup = s = WCMD_strdupW(orig_cmd);
|
|
||||||
|
|
||||||
while ((p = strstrW (s, param))) {
|
|
||||||
*p = '\0';
|
|
||||||
size += strlenW (subst) * sizeof(WCHAR);
|
|
||||||
new_cmd = (WCHAR *) LocalReAlloc ((HANDLE)new_cmd, size, 0);
|
|
||||||
strcatW (new_cmd, s);
|
|
||||||
strcatW (new_cmd, subst);
|
|
||||||
s = p + strlenW (param);
|
|
||||||
}
|
|
||||||
strcatW (new_cmd, s);
|
|
||||||
WCMD_process_command (new_cmd, cmdList);
|
|
||||||
free (dup);
|
|
||||||
LocalFree ((HANDLE)new_cmd);
|
|
||||||
} else {
|
|
||||||
WCMD_process_command (orig_cmd, cmdList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* WCMD_give_help
|
* WCMD_give_help
|
||||||
*
|
*
|
||||||
|
@ -1067,7 +1033,7 @@ void WCMD_goto (CMD_LIST **cmdList) {
|
||||||
WCHAR string[MAX_PATH];
|
WCHAR string[MAX_PATH];
|
||||||
|
|
||||||
/* Do not process any more parts of a processed multipart or multilines command */
|
/* Do not process any more parts of a processed multipart or multilines command */
|
||||||
*cmdList = NULL;
|
if (cmdList) *cmdList = NULL;
|
||||||
|
|
||||||
if (param1[0] == 0x00) {
|
if (param1[0] == 0x00) {
|
||||||
WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
|
WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
|
||||||
|
|
|
@ -65,7 +65,6 @@ void WCMD_pause (void);
|
||||||
void WCMD_pipe (CMD_LIST **command, WCHAR *var, WCHAR *val);
|
void WCMD_pipe (CMD_LIST **command, WCHAR *var, WCHAR *val);
|
||||||
void WCMD_popd (void);
|
void WCMD_popd (void);
|
||||||
void WCMD_print_error (void);
|
void WCMD_print_error (void);
|
||||||
void WCMD_process_command (WCHAR *command, CMD_LIST **cmdList);
|
|
||||||
void WCMD_pushd (WCHAR *);
|
void WCMD_pushd (WCHAR *);
|
||||||
int WCMD_read_console (WCHAR *string, int str_len);
|
int WCMD_read_console (WCHAR *string, int str_len);
|
||||||
void WCMD_remove_dir (WCHAR *command);
|
void WCMD_remove_dir (WCHAR *command);
|
||||||
|
@ -92,7 +91,7 @@ WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where);
|
||||||
WCHAR *WCMD_strtrim_leading_spaces (WCHAR *string);
|
WCHAR *WCMD_strtrim_leading_spaces (WCHAR *string);
|
||||||
void WCMD_strtrim_trailing_spaces (WCHAR *string);
|
void WCMD_strtrim_trailing_spaces (WCHAR *string);
|
||||||
void WCMD_opt_s_strip_quotes(WCHAR *cmd);
|
void WCMD_opt_s_strip_quotes(WCHAR *cmd);
|
||||||
void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable);
|
void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValue, BOOL justFors);
|
||||||
BOOL WCMD_ask_confirm (WCHAR *message, BOOL showSureText, BOOL *optionAll);
|
BOOL WCMD_ask_confirm (WCHAR *message, BOOL showSureText, BOOL *optionAll);
|
||||||
|
|
||||||
void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
|
void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
|
||||||
|
|
|
@ -95,7 +95,7 @@ static char *output_bufA = NULL;
|
||||||
#define MAX_WRITECONSOLE_SIZE 65535
|
#define MAX_WRITECONSOLE_SIZE 65535
|
||||||
BOOL unicodePipes = FALSE;
|
BOOL unicodePipes = FALSE;
|
||||||
|
|
||||||
static WCHAR *WCMD_expand_envvar(WCHAR *start);
|
static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forvar, WCHAR *forVal);
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Main entry point. This is a console application so we have a main() not a
|
* Main entry point. This is a console application so we have a main() not a
|
||||||
|
@ -456,6 +456,87 @@ int wmain (int argc, WCHAR *argvW[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Expand the command. Native expands lines from batch programs as they are
|
||||||
|
* read in and not again, except for 'for' variable substitution.
|
||||||
|
* eg. As evidence, "echo %1 && shift && echo %1" or "echo %%path%%"
|
||||||
|
*/
|
||||||
|
void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR *forValue) {
|
||||||
|
|
||||||
|
/* For commands in a context (batch program): */
|
||||||
|
/* Expand environment variables in a batch file %{0-9} first */
|
||||||
|
/* including support for any ~ modifiers */
|
||||||
|
/* Additionally: */
|
||||||
|
/* Expand the DATE, TIME, CD, RANDOM and ERRORLEVEL special */
|
||||||
|
/* names allowing environment variable overrides */
|
||||||
|
/* NOTE: To support the %PATH:xxx% syntax, also perform */
|
||||||
|
/* manual expansion of environment variables here */
|
||||||
|
|
||||||
|
WCHAR *p = cmd;
|
||||||
|
WCHAR *s, *t;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while ((p = strchrW(p, '%'))) {
|
||||||
|
|
||||||
|
WINE_TRACE("Translate command:%s %d (at: %s)\n",
|
||||||
|
wine_dbgstr_w(cmd), justFors, wine_dbgstr_w(p));
|
||||||
|
i = *(p+1) - '0';
|
||||||
|
|
||||||
|
/* Don't touch %% unless its in Batch */
|
||||||
|
if (!justFors && *(p+1) == '%') {
|
||||||
|
if (context) {
|
||||||
|
s = WCMD_strdupW(p+1);
|
||||||
|
strcpyW (p, s);
|
||||||
|
free (s);
|
||||||
|
}
|
||||||
|
p+=1;
|
||||||
|
|
||||||
|
/* Replace %~ modifications if in batch program */
|
||||||
|
} else if (*(p+1) == '~') {
|
||||||
|
WCMD_HandleTildaModifiers(&p, forVariable, forValue, justFors);
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* Replace use of %0...%9 if in batch program*/
|
||||||
|
} else if (!justFors && context && (i >= 0) && (i <= 9)) {
|
||||||
|
s = WCMD_strdupW(p+2);
|
||||||
|
t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
|
||||||
|
strcpyW (p, t);
|
||||||
|
strcatW (p, s);
|
||||||
|
free (s);
|
||||||
|
|
||||||
|
/* Replace use of %* if in batch program*/
|
||||||
|
} else if (!justFors && context && *(p+1)=='*') {
|
||||||
|
WCHAR *startOfParms = NULL;
|
||||||
|
s = WCMD_strdupW(p+2);
|
||||||
|
t = WCMD_parameter (context -> command, 1, &startOfParms);
|
||||||
|
if (startOfParms != NULL) strcpyW (p, startOfParms);
|
||||||
|
else *p = 0x00;
|
||||||
|
strcatW (p, s);
|
||||||
|
free (s);
|
||||||
|
|
||||||
|
} else if (forVariable &&
|
||||||
|
(CompareString (LOCALE_USER_DEFAULT,
|
||||||
|
SORT_STRINGSORT,
|
||||||
|
p,
|
||||||
|
strlenW(forVariable),
|
||||||
|
forVariable, -1) == 2)) {
|
||||||
|
s = WCMD_strdupW(p + strlenW(forVariable));
|
||||||
|
strcpyW(p, forValue);
|
||||||
|
strcatW(p, s);
|
||||||
|
free(s);
|
||||||
|
|
||||||
|
} else if (!justFors) {
|
||||||
|
p = WCMD_expand_envvar(p, forVariable, forValue);
|
||||||
|
|
||||||
|
/* In a FOR loop, see if this is the variable to replace */
|
||||||
|
} else { /* Ignore %'s on second pass of batch program */
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Process one command. If the command is EXIT this routine does not return.
|
* Process one command. If the command is EXIT this routine does not return.
|
||||||
|
@ -463,9 +544,11 @@ int wmain (int argc, WCHAR *argvW[])
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void WCMD_process_command (WCHAR *command, CMD_LIST **cmdList)
|
void WCMD_execute (WCHAR *command,
|
||||||
|
WCHAR *forVariable, WCHAR *forValue,
|
||||||
|
CMD_LIST **cmdList)
|
||||||
{
|
{
|
||||||
WCHAR *cmd, *p, *s, *t, *redir;
|
WCHAR *cmd, *p, *redir;
|
||||||
int status, i;
|
int status, i;
|
||||||
DWORD count, creationDisposition;
|
DWORD count, creationDisposition;
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
|
@ -480,81 +563,24 @@ void WCMD_process_command (WCHAR *command, CMD_LIST **cmdList)
|
||||||
STD_OUTPUT_HANDLE,
|
STD_OUTPUT_HANDLE,
|
||||||
STD_ERROR_HANDLE};
|
STD_ERROR_HANDLE};
|
||||||
|
|
||||||
|
WINE_TRACE("command on entry:%s (%p), with '%s'='%s'\n",
|
||||||
|
wine_dbgstr_w(command), cmdList,
|
||||||
|
wine_dbgstr_w(forVariable), wine_dbgstr_w(forValue));
|
||||||
|
|
||||||
/* Move copy of the command onto the heap so it can be expanded */
|
/* Move copy of the command onto the heap so it can be expanded */
|
||||||
new_cmd = HeapAlloc( GetProcessHeap(), 0, MAXSTRING * sizeof(WCHAR));
|
new_cmd = HeapAlloc( GetProcessHeap(), 0, MAXSTRING * sizeof(WCHAR));
|
||||||
strcpyW(new_cmd, command);
|
strcpyW(new_cmd, command);
|
||||||
|
|
||||||
/* For commands in a context (batch program): */
|
/* Expand variables in command line mode only (batch mode will
|
||||||
/* Expand environment variables in a batch file %{0-9} first */
|
be expanded as the line is read in, except for for loops) */
|
||||||
/* including support for any ~ modifiers */
|
handleExpansion(new_cmd, (context != NULL), forVariable, forValue);
|
||||||
/* Additionally: */
|
|
||||||
/* Expand the DATE, TIME, CD, RANDOM and ERRORLEVEL special */
|
|
||||||
/* names allowing environment variable overrides */
|
|
||||||
/* NOTE: To support the %PATH:xxx% syntax, also perform */
|
|
||||||
/* manual expansion of environment variables here */
|
|
||||||
|
|
||||||
p = new_cmd;
|
|
||||||
while ((p = strchrW(p, '%'))) {
|
|
||||||
i = *(p+1) - '0';
|
|
||||||
|
|
||||||
/* Don't touch %% */
|
|
||||||
if (*(p+1) == '%') {
|
|
||||||
p+=2;
|
|
||||||
|
|
||||||
/* Replace %~ modifications if in batch program */
|
|
||||||
} else if (context && *(p+1) == '~') {
|
|
||||||
WCMD_HandleTildaModifiers(&p, NULL);
|
|
||||||
p++;
|
|
||||||
|
|
||||||
/* Replace use of %0...%9 if in batch program*/
|
|
||||||
} else if (context && (i >= 0) && (i <= 9)) {
|
|
||||||
s = WCMD_strdupW(p+2);
|
|
||||||
t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
|
|
||||||
strcpyW (p, t);
|
|
||||||
strcatW (p, s);
|
|
||||||
free (s);
|
|
||||||
|
|
||||||
/* Replace use of %* if in batch program*/
|
|
||||||
} else if (context && *(p+1)=='*') {
|
|
||||||
WCHAR *startOfParms = NULL;
|
|
||||||
s = WCMD_strdupW(p+2);
|
|
||||||
t = WCMD_parameter (context -> command, 1, &startOfParms);
|
|
||||||
if (startOfParms != NULL) strcpyW (p, startOfParms);
|
|
||||||
else *p = 0x00;
|
|
||||||
strcatW (p, s);
|
|
||||||
free (s);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
p = WCMD_expand_envvar(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmd = new_cmd;
|
cmd = new_cmd;
|
||||||
|
|
||||||
/* In a batch program, unknown variables are replace by nothing */
|
/* Show prompt before batch line IF echo is on and in batch program */
|
||||||
/* so remove any remaining %var% */
|
if (context && echo_mode && (cmd[0] != '@')) {
|
||||||
if (context) {
|
WCMD_show_prompt();
|
||||||
p = cmd;
|
WCMD_output_asis ( cmd);
|
||||||
while ((p = strchrW(p, '%'))) {
|
WCMD_output_asis ( newline);
|
||||||
if (*(p+1) == '%') {
|
|
||||||
p+=2;
|
|
||||||
} else {
|
|
||||||
s = strchrW(p+1, '%');
|
|
||||||
if (!s) {
|
|
||||||
*p=0x00;
|
|
||||||
} else {
|
|
||||||
t = WCMD_strdupW(s+1);
|
|
||||||
strcpyW(p, t);
|
|
||||||
free(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show prompt before batch line IF echo is on and in batch program */
|
|
||||||
if (echo_mode && (cmd[0] != '@')) {
|
|
||||||
WCMD_show_prompt();
|
|
||||||
WCMD_output_asis ( cmd);
|
|
||||||
WCMD_output_asis ( newline);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1533,7 +1559,7 @@ void WCMD_pipe (CMD_LIST **cmdEntry, WCHAR *var, WCHAR *val) {
|
||||||
*
|
*
|
||||||
* Expands environment variables, allowing for WCHARacter substitution
|
* Expands environment variables, allowing for WCHARacter substitution
|
||||||
*/
|
*/
|
||||||
static WCHAR *WCMD_expand_envvar(WCHAR *start) {
|
static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
|
||||||
WCHAR *endOfVar = NULL, *s;
|
WCHAR *endOfVar = NULL, *s;
|
||||||
WCHAR *colonpos = NULL;
|
WCHAR *colonpos = NULL;
|
||||||
WCHAR thisVar[MAXSTRING];
|
WCHAR thisVar[MAXSTRING];
|
||||||
|
@ -1551,20 +1577,38 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start) {
|
||||||
static const WCHAR CdP[] = {'%','C','D','%','\0'};
|
static const WCHAR CdP[] = {'%','C','D','%','\0'};
|
||||||
static const WCHAR Random[] = {'R','A','N','D','O','M','\0'};
|
static const WCHAR Random[] = {'R','A','N','D','O','M','\0'};
|
||||||
static const WCHAR RandomP[] = {'%','R','A','N','D','O','M','%','\0'};
|
static const WCHAR RandomP[] = {'%','R','A','N','D','O','M','%','\0'};
|
||||||
|
static const WCHAR Delims[] = {'%',' ',':','\0'};
|
||||||
|
|
||||||
|
WINE_TRACE("Expanding: %s (%s,%s)\n", wine_dbgstr_w(start),
|
||||||
|
wine_dbgstr_w(forVal), wine_dbgstr_w(forVar));
|
||||||
|
|
||||||
/* Find the end of the environment variable, and extract name */
|
/* Find the end of the environment variable, and extract name */
|
||||||
endOfVar = strchrW(start+1, '%');
|
endOfVar = strpbrkW(start+1, Delims);
|
||||||
if (endOfVar == NULL) {
|
|
||||||
|
if (endOfVar == NULL || *endOfVar==' ') {
|
||||||
|
|
||||||
/* In batch program, missing terminator for % and no following
|
/* In batch program, missing terminator for % and no following
|
||||||
':' just removes the '%' */
|
':' just removes the '%' */
|
||||||
s = WCMD_strdupW(start + 1);
|
if (context) {
|
||||||
strcpyW (start, s);
|
s = WCMD_strdupW(start + 1);
|
||||||
free(s);
|
strcpyW (start, s);
|
||||||
|
free(s);
|
||||||
|
return start;
|
||||||
|
} else {
|
||||||
|
|
||||||
/* FIXME: Some other special conditions here depending on whether
|
/* In command processing, just ignore it - allows command line
|
||||||
in batch, complex or not, and whether env var exists or not! */
|
syntax like: for %i in (a.a) do echo %i */
|
||||||
return start;
|
return start+1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If ':' found, process remaining up until '%' (or stop at ':' if
|
||||||
|
a missing '%' */
|
||||||
|
if (*endOfVar==':') {
|
||||||
|
WCHAR *endOfVar2 = strchrW(endOfVar+1, '%');
|
||||||
|
if (endOfVar2 != NULL) endOfVar = endOfVar2;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(thisVar, start, ((endOfVar - start) + 1) * sizeof(WCHAR));
|
memcpy(thisVar, start, ((endOfVar - start) + 1) * sizeof(WCHAR));
|
||||||
thisVar[(endOfVar - start)+1] = 0x00;
|
thisVar[(endOfVar - start)+1] = 0x00;
|
||||||
colonpos = strchrW(thisVar+1, ':');
|
colonpos = strchrW(thisVar+1, ':');
|
||||||
|
@ -1627,6 +1671,16 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start) {
|
||||||
wsprintf(thisVarContents, fmt, rand() % 32768);
|
wsprintf(thisVarContents, fmt, rand() % 32768);
|
||||||
len = strlenW(thisVarContents);
|
len = strlenW(thisVarContents);
|
||||||
|
|
||||||
|
/* Look for a matching 'for' variable */
|
||||||
|
} else if (forVar &&
|
||||||
|
(CompareString (LOCALE_USER_DEFAULT,
|
||||||
|
SORT_STRINGSORT,
|
||||||
|
thisVar,
|
||||||
|
(colonpos - thisVar) - 1,
|
||||||
|
forVar, -1) == 2)) {
|
||||||
|
strcpyW(thisVarContents, forVal);
|
||||||
|
len = strlenW(thisVarContents);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
len = ExpandEnvironmentStrings(thisVar, thisVarContents,
|
len = ExpandEnvironmentStrings(thisVar, thisVarContents,
|
||||||
|
@ -1952,6 +2006,9 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
|
||||||
WCMD_output_asis(newline);
|
WCMD_output_asis(newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Replace env vars if in a batch context */
|
||||||
|
if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);
|
||||||
|
|
||||||
/* Start with an empty string */
|
/* Start with an empty string */
|
||||||
curLen = 0;
|
curLen = 0;
|
||||||
|
|
||||||
|
@ -2234,6 +2291,7 @@ WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readF
|
||||||
if (WCMD_fgets(extraSpace, MAXSTRING, readFrom) == NULL) break;
|
if (WCMD_fgets(extraSpace, MAXSTRING, readFrom) == NULL) break;
|
||||||
}
|
}
|
||||||
curPos = extraSpace;
|
curPos = extraSpace;
|
||||||
|
if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue