Jason Edmeades : cmd: Fix some issues with ~ modifier expansion.

Alexandre Julliard julliard at winehq.org
Mon Oct 15 14:29:06 CDT 2012


Module: wine
Branch: master
Commit: 8f019b1111a0ad4523eed2ba93f16ef09ba350e9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8f019b1111a0ad4523eed2ba93f16ef09ba350e9

Author: Jason Edmeades <jason at edmeades.me.uk>
Date:   Thu Oct 11 22:53:38 2012 +0100

cmd: Fix some issues with ~ modifier expansion.

---

 programs/cmd/batch.c                     |  111 +++++++++++++++++------------
 programs/cmd/tests/test_builtins.cmd     |    1 +
 programs/cmd/tests/test_builtins.cmd.exp |   15 ++--
 3 files changed, 74 insertions(+), 53 deletions(-)

diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index b77931d..6fc9970 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -430,11 +430,6 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
   modifierLen = lastModifier - firstModifier;
   finaloutput[0] = 0x00;
 
-  /* Useful for debugging purposes: */
-  /*printf("Modifier string '%*.*s' and variable is %c\n Param starts as '%s'\n",
-             (modifierLen), (modifierLen), firstModifier, *lastModifier,
-             outputparam);*/
-
   /* 1. Handle '~' : Strip surrounding quotes */
   if (outputparam[0]=='"' &&
       memchrW(firstModifier, '~', modifierLen) != NULL) {
@@ -477,64 +472,69 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
     exists = GetFileAttributesExW(fullfilename, GetFileExInfoStandard,
                                   &fileInfo);
 
-    /* 2. Handle 'a' : Output attributes */
-    if (exists &&
-        memchrW(firstModifier, 'a', modifierLen) != NULL) {
+    /* 2. Handle 'a' : Output attributes (File doesn't have to exist) */
+    if (memchrW(firstModifier, 'a', modifierLen) != NULL) {
 
       WCHAR defaults[] = {'-','-','-','-','-','-','-','-','-','\0'};
       doneModifier = TRUE;
-      strcpyW(thisoutput, defaults);
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-        thisoutput[0]='d';
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
-        thisoutput[1]='r';
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
-        thisoutput[2]='a';
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-        thisoutput[3]='h';
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
-        thisoutput[4]='s';
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
-        thisoutput[5]='c';
-      /* FIXME: What are 6 and 7? */
-      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
-        thisoutput[8]='l';
-      strcatW(finaloutput, thisoutput);
+
+      if (exists) {
+        strcpyW(thisoutput, defaults);
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+          thisoutput[0]='d';
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+          thisoutput[1]='r';
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
+          thisoutput[2]='a';
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+          thisoutput[3]='h';
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
+          thisoutput[4]='s';
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
+          thisoutput[5]='c';
+        /* FIXME: What are 6 and 7? */
+        if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+          thisoutput[8]='l';
+        strcatW(finaloutput, thisoutput);
+      }
     }
 
-    /* 3. Handle 't' : Date+time */
-    if (exists &&
-        memchrW(firstModifier, 't', modifierLen) != NULL) {
+    /* 3. Handle 't' : Date+time (File doesn't have to exist) */
+    if (memchrW(firstModifier, 't', modifierLen) != NULL) {
 
       SYSTEMTIME systime;
       int datelen;
 
       doneModifier = TRUE;
-      if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
 
-      /* Format the time */
-      FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systime);
-      GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
-                        NULL, thisoutput, MAX_PATH);
-      strcatW(thisoutput, spaceW);
-      datelen = strlenW(thisoutput);
-      GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &systime,
-                        NULL, (thisoutput+datelen), MAX_PATH-datelen);
-      strcatW(finaloutput, thisoutput);
+      if (exists) {
+        if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
+
+        /* Format the time */
+        FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systime);
+        GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
+                          NULL, thisoutput, MAX_PATH);
+        strcatW(thisoutput, spaceW);
+        datelen = strlenW(thisoutput);
+        GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &systime,
+                          NULL, (thisoutput+datelen), MAX_PATH-datelen);
+        strcatW(finaloutput, thisoutput);
+      }
     }
 
-    /* 4. Handle 'z' : File length */
-    if (exists &&
-        memchrW(firstModifier, 'z', modifierLen) != NULL) {
+    /* 4. Handle 'z' : File length (File doesn't have to exist) */
+    if (memchrW(firstModifier, 'z', modifierLen) != NULL) {
       /* FIXME: Output full 64 bit size (sprintf does not support I64 here) */
       ULONG/*64*/ fullsize = /*(fileInfo.nFileSizeHigh << 32) +*/
                                   fileInfo.nFileSizeLow;
       static const WCHAR fmt[] = {'%','u','\0'};
 
       doneModifier = TRUE;
-      if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
-      wsprintfW(thisoutput, fmt, fullsize);
-      strcatW(finaloutput, thisoutput);
+      if (exists) {
+        if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
+        wsprintfW(thisoutput, fmt, fullsize);
+        strcatW(finaloutput, thisoutput);
+      }
     }
 
     /* 4. Handle 's' : Use short paths (File doesn't have to exist) */
@@ -557,14 +557,18 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
       WCHAR fname[MAX_PATH];
       WCHAR ext[MAX_PATH];
       BOOL doneFileModifier = FALSE;
-
-      if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
+      BOOL addSpace = (finaloutput[0] != 0x00);
 
       /* Split into components */
       WCMD_splitpath(fullfilename, drive, dir, fname, ext);
 
       /* 5. Handle 'd' : Drive Letter */
       if (memchrW(firstModifier, 'd', modifierLen) != NULL) {
+        if (addSpace) {
+          strcatW(finaloutput, spaceW);
+          addSpace = FALSE;
+        }
+
         strcatW(finaloutput, drive);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
@@ -572,6 +576,11 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
 
       /* 6. Handle 'p' : Path */
       if (memchrW(firstModifier, 'p', modifierLen) != NULL) {
+        if (addSpace) {
+          strcatW(finaloutput, spaceW);
+          addSpace = FALSE;
+        }
+
         strcatW(finaloutput, dir);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
@@ -579,6 +588,11 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
 
       /* 7. Handle 'n' : Name */
       if (memchrW(firstModifier, 'n', modifierLen) != NULL) {
+        if (addSpace) {
+          strcatW(finaloutput, spaceW);
+          addSpace = FALSE;
+        }
+
         strcatW(finaloutput, fname);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
@@ -586,6 +600,11 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
 
       /* 8. Handle 'x' : Ext */
       if (memchrW(firstModifier, 'x', modifierLen) != NULL) {
+        if (addSpace) {
+          strcatW(finaloutput, spaceW);
+          addSpace = FALSE;
+        }
+
         strcatW(finaloutput, ext);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 8a47238..44d7f2f 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -347,6 +347,7 @@ rem file attribute
 for %%i in ("U V" W) do echo '%%~ai'
 echo foo> foo
 for %%i in (foo) do echo '%%~ai'
+for %%i in (foo) do echo '%%~zi'
 del foo
 rem file date/time
 rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar...
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 4bab1ef..ec11324 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -303,13 +303,14 @@ N
 @todo_wine@'@drive@@shortpath at R S'@or_broken@''
 @todo_wine@'@drive@@shortpath at T'@or_broken@''
 @todo_wine@'@drive@@shortpath at ABCDEFGHIJK.LMNOP'@or_broken@''
- at todo_wine@''@or_broken@'%~ai'
- at todo_wine@''@or_broken@'%~ai'
- at todo_wine@'--a------'@or_broken@'%~ai'
- at todo_wine@''@or_broken@'%~ti'
- at todo_wine@''@or_broken@'%~ti'
- at todo_wine@''@or_broken@'%~zi'
- at todo_wine@''@or_broken@'%~zi'
+''@or_broken@'%~ai'
+''@or_broken@'%~ai'
+'--a------'@or_broken@'%~ai'
+'5'@or_broken@'%~zi'
+''@or_broken@'%~ti'
+''@or_broken@'%~ti'
+''@or_broken@'%~zi'
+''@or_broken@'%~zi'
 @drive@@path@
 @drive@@path@
 @drive@




More information about the wine-cvs mailing list