Jason Edmeades : cmd.exe:
setlocal and endlocal should preserve drive and directory.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Mar 8 07:17:10 CST 2007
Module: wine
Branch: master
Commit: 86140e3fbb0ac108314f4db6d504c62a4a7cf3bb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=86140e3fbb0ac108314f4db6d504c62a4a7cf3bb
Author: Jason Edmeades <us at edmeades.me.uk>
Date: Thu Mar 8 00:48:49 2007 +0000
cmd.exe: setlocal and endlocal should preserve drive and directory.
---
programs/cmd/builtins.c | 24 ++++++++++++++++++++++--
programs/cmd/wcmd.h | 5 ++++-
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 5149159..6a1a3a6 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -893,6 +893,7 @@ static WCHAR *WCMD_dupenv( const WCHAR *env )
void WCMD_setlocal (const char *s) {
WCHAR *env;
struct env_stack *env_copy;
+ char cwd[MAX_PATH];
/* DISABLEEXTENSIONS ignored */
@@ -910,11 +911,16 @@ void WCMD_setlocal (const char *s) {
{
env_copy->next = saved_environment;
saved_environment = env_copy;
+
+ /* Save the current drive letter */
+ GetCurrentDirectory (MAX_PATH, cwd);
+ env_copy->cwd = cwd[0];
}
else
LocalFree (env_copy);
FreeEnvironmentStringsW (env);
+
}
/*****************************************************************************
@@ -935,6 +941,8 @@ static inline WCHAR *WCMD_strchrW(WCHAR *str, WCHAR ch)
* WCMD_endlocal
*
* endlocal pops the environment off a stack
+ * Note: When searching for '=', search from char position 1, to handle
+ * special internal environment variables =C:, =D: etc
*/
void WCMD_endlocal (void) {
WCHAR *env, *old, *p;
@@ -954,7 +962,7 @@ void WCMD_endlocal (void) {
len = 0;
while (old[len]) {
n = lstrlenW(&old[len]) + 1;
- p = WCMD_strchrW(&old[len], '=');
+ p = WCMD_strchrW(&old[len] + 1, '=');
if (p)
{
*p++ = 0;
@@ -970,7 +978,7 @@ void WCMD_endlocal (void) {
len = 0;
while (env[len]) {
n = lstrlenW(&env[len]) + 1;
- p = WCMD_strchrW(&env[len], '=');
+ p = WCMD_strchrW(&env[len] + 1, '=');
if (p)
{
*p++ = 0;
@@ -978,6 +986,18 @@ void WCMD_endlocal (void) {
}
len += n;
}
+
+ /* Restore current drive letter */
+ if (IsCharAlpha(temp->cwd)) {
+ char envvar[4];
+ char cwd[MAX_PATH];
+ sprintf(envvar, "=%c:", temp->cwd);
+ if (GetEnvironmentVariable(envvar, cwd, MAX_PATH)) {
+ WINE_TRACE("Resetting cwd to %s\n", cwd);
+ SetCurrentDirectory(cwd);
+ }
+ }
+
LocalFree (env);
LocalFree (temp);
}
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index 53f163c..e7ffa94 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -101,7 +101,10 @@ typedef struct {
struct env_stack
{
struct env_stack *next;
- int stackdepth; /* Only used for pushd and popd */
+ union {
+ int stackdepth; /* Only used for pushd and popd */
+ char cwd; /* Only used for set/endlocal */
+ };
WCHAR *strings;
};
More information about the wine-cvs
mailing list