[PATCH 4/7] [cmd] Fix some issues with ~ modifier expansion
Ann and Jason Edmeades
jason at edmeades.me.uk
Fri Oct 12 04:52:49 CDT 2012
When requesting file information for non-existant files, empty strings
should be returned, with no whitespace.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20121012/121e526d/attachment.html>
-------------- next part --------------
From d00024e82d7fb1b194a8050ec1dcd231d25dd625 Mon Sep 17 00:00:00 2001
From: Jason Edmeades <jason at edmeades.me.uk>
Date: Thu, 11 Oct 2012 22:53:38 +0100
Subject: [PATCH 4/7] [cmd] Fix some issues with ~ modifier expansion
When requesting file information for non-existant files, empty strings
should be returned, with no whitespace.
---
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@
--
1.7.9.5
More information about the wine-patches
mailing list