FW: [14/16] CMD.exe: Add pushd and popd support

Ann & Jason Edmeades us at edmeades.me.uk
Tue Feb 20 12:05:32 CST 2007


That should be the whole set now - No failures on sending but they keep
going missing, so apologies if duplicates appear

Jason

-----Original Message-----
From: Ann & Jason Edmeades [mailto:us at edmeades.me.uk] 
Sent: 20 February 2007 00:45
To: 'wine-patches at winehq.org'
Subject: [14/16] CMD.exe: Add pushd and popd support


-------------- next part --------------
>From nobody Mon Sep 17 00:00:00 2001
From: Jason Edmeades <us at edmeades.me.uk>
Date: Mon Feb 19 18:40:23 2007 +0000
Subject: [PATCH] Add support for PUSHD and POPD

---

 programs/cmd/En.rc      |    8 +++++++
 programs/cmd/builtins.c |   54 +++++++++++++++++++++++++++++++++++++++++++++++
 programs/cmd/wcmd.h     |    6 ++++-
 programs/cmd/wcmdmain.c |    8 ++++++-
 4 files changed, 74 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 programs/cmd/En.rc

ac0289e0ce5e1260cef96322c5399ff196b3cb3b
diff --git a/programs/cmd/En.rc b/programs/cmd/En.rc
old mode 100644
new mode 100755
index fda556e..1a8877d
--- a/programs/cmd/En.rc
+++ b/programs/cmd/En.rc
@@ -196,6 +196,12 @@ The verify flag has no function in Wine.
 
   WCMD_VOL,    "Help about VOL\n"
 
+  WCMD_PUSHD,  "PUSHD <directoryname> saves the current directory onto a\n\
+stack, and then changes the current directory to the supplied one.\n"
+
+  WCMD_POPD,   "POPD changes current directory to the last one saved with\n\
+PUSHD.\n"
+
   WCMD_EXIT,
 "EXIT terminates the current command session and returns\n\
 to the operating system or shell from which you invoked cmd.\n"
@@ -215,7 +221,9 @@ HELP\t\tShow brief help details on a top
 MD (MKDIR)\tCreate a subdirectory\n\
 MOVE\t\tMove a file, set of files or directory tree\n\
 PATH\t\tSet or show the search path\n\
+POPD\t\tRestores the directory to the last one saved with PUSHD\n\
 PROMPT\t\tChange the command prompt\n\
+PUSHD\t\tChanges to a new directory, saving the current one\n\
 REN (RENAME)\tRename a file\n\
 RD (RMDIR)\tDelete a subdirectory\n\
 SET\t\tSet or show environment variables\n\
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 7f00068..7b853b0 100755
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -45,6 +45,7 @@ struct env_stack
 };
 
 struct env_stack *saved_environment;
+struct env_stack *pushd_directories;
 
 extern HINSTANCE hinst;
 extern char *inbuilt[];
@@ -1193,4 +1194,57 @@ void WCMD_exit (void) {
     }
 }
 
+/*****************************************************************************
+ * WCMD_pushd
+ *
+ *	Push a directory onto the stack
+ */
+
+void WCMD_pushd (void) {
+    struct env_stack *curdir;
+    BOOL   status;
+    WCHAR *thisdir;
+
+    curdir  = LocalAlloc (LMEM_FIXED, sizeof (struct env_stack));
+    thisdir = LocalAlloc (LMEM_FIXED, 1024 * sizeof(WCHAR));
+    if( !curdir || !thisdir ) {
+      LocalFree(curdir);
+      LocalFree(thisdir);
+      WCMD_output ("out of memory\n");
+      return;
+    }
+
+    GetCurrentDirectoryW (1024, thisdir);
+    status = SetCurrentDirectoryA (param1);
+    if (!status) {
+      WCMD_print_error ();
+      LocalFree(curdir);
+      LocalFree(thisdir);
+      return;
+    } else {
+      curdir -> next    = pushd_directories;
+      curdir -> strings = thisdir;
+      pushd_directories = curdir;
+    }
+}
+
+
+/*****************************************************************************
+ * WCMD_popd
+ *
+ *	Pop a directory from the stack
+ */
+
+void WCMD_popd (void) {
+    struct env_stack *temp = pushd_directories;
+
+    if (!pushd_directories)
+      return;
+
+    /* pop the old environment from the stack, and make it the current dir */
+    pushd_directories = temp->next;
+    SetCurrentDirectoryW(temp->strings);
+    LocalFree (temp->strings);
+    LocalFree (temp);
+}
 
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index a5089f2..580afe3 100755
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -50,8 +50,10 @@ void WCMD_output_asis (const char *messa
 void WCMD_parse (char *s, char *q, char *p1, char *p2);
 void WCMD_pause (void);
 void WCMD_pipe (char *command);
+void WCMD_popd (void);
 void WCMD_print_error (void);
 void WCMD_process_command (char *command);
+void WCMD_pushd (void);
 int  WCMD_read_console (char *string, int str_len);
 void WCMD_remove_dir (void);
 void WCMD_rename (void);
@@ -140,9 +142,11 @@ #define WCMD_VOL    35
 
 #define WCMD_ENDLOCAL 36
 #define WCMD_SETLOCAL 37
+#define WCMD_PUSHD  38
+#define WCMD_POPD   39
 
 /* Must be last in list */
-#define WCMD_EXIT   38
+#define WCMD_EXIT   40
 
 /* Some standard messages */
 extern const char nyi[];
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 13ceb73..8c4680c 100755
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -32,7 +32,7 @@ const char * const inbuilt[] = {"ATTRIB"
 		"HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE",
 		"PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT",
                 "TIME", "TITLE", "TYPE", "VERIFY", "VER", "VOL", 
-                "ENDLOCAL", "SETLOCAL", "EXIT" };
+                "ENDLOCAL", "SETLOCAL", "PUSHD", "POPD", "EXIT" };
 
 HINSTANCE hinst;
 DWORD errorlevel;
@@ -636,6 +636,12 @@ void WCMD_process_command (char *command
       case WCMD_VOL:
         WCMD_volume (0, p);
         break;
+      case WCMD_PUSHD:
+        WCMD_pushd();
+        break;
+      case WCMD_POPD:
+        WCMD_popd();
+        break;
       case WCMD_EXIT:
         WCMD_exit ();
         break;
-- 
1.3.0



More information about the wine-patches mailing list