cmd: Fix some issues with ~ modifier expansion.

This commit is contained in:
Jason Edmeades 2012-10-11 22:53:38 +01:00 committed by Alexandre Julliard
parent 7b9971abf9
commit 8f019b1111
3 changed files with 74 additions and 53 deletions

View file

@ -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;

View file

@ -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...

View file

@ -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@