Module: wine Branch: master Commit: 8f019b1111a0ad4523eed2ba93f16ef09ba350e9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8f019b1111a0ad4523eed2ba93...
Author: Jason Edmeades jason@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@R S'@or_broken@'' @todo_wine@'@drive@@shortpath@T'@or_broken@'' @todo_wine@'@drive@@shortpath@ABCDEFGHIJK.LMNOP'@or_broken@'' -@todo_wine@''@or_broken@'%~ai' -@todo_wine@''@or_broken@'%~ai' -@todo_wine@'--a------'@or_broken@'%~ai' -@todo_wine@''@or_broken@'%~ti' -@todo_wine@''@or_broken@'%~ti' -@todo_wine@''@or_broken@'%~zi' -@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@