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; modifierLen = lastModifier - firstModifier;
finaloutput[0] = 0x00; 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 */ /* 1. Handle '~' : Strip surrounding quotes */
if (outputparam[0]=='"' && if (outputparam[0]=='"' &&
memchrW(firstModifier, '~', modifierLen) != NULL) { memchrW(firstModifier, '~', modifierLen) != NULL) {
@ -477,64 +472,69 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
exists = GetFileAttributesExW(fullfilename, GetFileExInfoStandard, exists = GetFileAttributesExW(fullfilename, GetFileExInfoStandard,
&fileInfo); &fileInfo);
/* 2. Handle 'a' : Output attributes */ /* 2. Handle 'a' : Output attributes (File doesn't have to exist) */
if (exists && if (memchrW(firstModifier, 'a', modifierLen) != NULL) {
memchrW(firstModifier, 'a', modifierLen) != NULL) {
WCHAR defaults[] = {'-','-','-','-','-','-','-','-','-','\0'}; WCHAR defaults[] = {'-','-','-','-','-','-','-','-','-','\0'};
doneModifier = TRUE; doneModifier = TRUE;
strcpyW(thisoutput, defaults);
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) if (exists) {
thisoutput[0]='d'; strcpyW(thisoutput, defaults);
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
thisoutput[1]='r'; thisoutput[0]='d';
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
thisoutput[2]='a'; thisoutput[1]='r';
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
thisoutput[3]='h'; thisoutput[2]='a';
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
thisoutput[4]='s'; thisoutput[3]='h';
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
thisoutput[5]='c'; thisoutput[4]='s';
/* FIXME: What are 6 and 7? */ if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) thisoutput[5]='c';
thisoutput[8]='l'; /* FIXME: What are 6 and 7? */
strcatW(finaloutput, thisoutput); if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
thisoutput[8]='l';
strcatW(finaloutput, thisoutput);
}
} }
/* 3. Handle 't' : Date+time */ /* 3. Handle 't' : Date+time (File doesn't have to exist) */
if (exists && if (memchrW(firstModifier, 't', modifierLen) != NULL) {
memchrW(firstModifier, 't', modifierLen) != NULL) {
SYSTEMTIME systime; SYSTEMTIME systime;
int datelen; int datelen;
doneModifier = TRUE; doneModifier = TRUE;
if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
/* Format the time */ if (exists) {
FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systime); if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
NULL, thisoutput, MAX_PATH); /* Format the time */
strcatW(thisoutput, spaceW); FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systime);
datelen = strlenW(thisoutput); GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &systime, NULL, thisoutput, MAX_PATH);
NULL, (thisoutput+datelen), MAX_PATH-datelen); strcatW(thisoutput, spaceW);
strcatW(finaloutput, thisoutput); datelen = strlenW(thisoutput);
GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &systime,
NULL, (thisoutput+datelen), MAX_PATH-datelen);
strcatW(finaloutput, thisoutput);
}
} }
/* 4. Handle 'z' : File length */ /* 4. Handle 'z' : File length (File doesn't have to exist) */
if (exists && if (memchrW(firstModifier, 'z', modifierLen) != NULL) {
memchrW(firstModifier, 'z', modifierLen) != NULL) {
/* FIXME: Output full 64 bit size (sprintf does not support I64 here) */ /* FIXME: Output full 64 bit size (sprintf does not support I64 here) */
ULONG/*64*/ fullsize = /*(fileInfo.nFileSizeHigh << 32) +*/ ULONG/*64*/ fullsize = /*(fileInfo.nFileSizeHigh << 32) +*/
fileInfo.nFileSizeLow; fileInfo.nFileSizeLow;
static const WCHAR fmt[] = {'%','u','\0'}; static const WCHAR fmt[] = {'%','u','\0'};
doneModifier = TRUE; doneModifier = TRUE;
if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW); if (exists) {
wsprintfW(thisoutput, fmt, fullsize); if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
strcatW(finaloutput, thisoutput); wsprintfW(thisoutput, fmt, fullsize);
strcatW(finaloutput, thisoutput);
}
} }
/* 4. Handle 's' : Use short paths (File doesn't have to exist) */ /* 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 fname[MAX_PATH];
WCHAR ext[MAX_PATH]; WCHAR ext[MAX_PATH];
BOOL doneFileModifier = FALSE; BOOL doneFileModifier = FALSE;
BOOL addSpace = (finaloutput[0] != 0x00);
if (finaloutput[0] != 0x00) strcatW(finaloutput, spaceW);
/* Split into components */ /* Split into components */
WCMD_splitpath(fullfilename, drive, dir, fname, ext); WCMD_splitpath(fullfilename, drive, dir, fname, ext);
/* 5. Handle 'd' : Drive Letter */ /* 5. Handle 'd' : Drive Letter */
if (memchrW(firstModifier, 'd', modifierLen) != NULL) { if (memchrW(firstModifier, 'd', modifierLen) != NULL) {
if (addSpace) {
strcatW(finaloutput, spaceW);
addSpace = FALSE;
}
strcatW(finaloutput, drive); strcatW(finaloutput, drive);
doneModifier = TRUE; doneModifier = TRUE;
doneFileModifier = TRUE; doneFileModifier = TRUE;
@ -572,6 +576,11 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
/* 6. Handle 'p' : Path */ /* 6. Handle 'p' : Path */
if (memchrW(firstModifier, 'p', modifierLen) != NULL) { if (memchrW(firstModifier, 'p', modifierLen) != NULL) {
if (addSpace) {
strcatW(finaloutput, spaceW);
addSpace = FALSE;
}
strcatW(finaloutput, dir); strcatW(finaloutput, dir);
doneModifier = TRUE; doneModifier = TRUE;
doneFileModifier = TRUE; doneFileModifier = TRUE;
@ -579,6 +588,11 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
/* 7. Handle 'n' : Name */ /* 7. Handle 'n' : Name */
if (memchrW(firstModifier, 'n', modifierLen) != NULL) { if (memchrW(firstModifier, 'n', modifierLen) != NULL) {
if (addSpace) {
strcatW(finaloutput, spaceW);
addSpace = FALSE;
}
strcatW(finaloutput, fname); strcatW(finaloutput, fname);
doneModifier = TRUE; doneModifier = TRUE;
doneFileModifier = TRUE; doneFileModifier = TRUE;
@ -586,6 +600,11 @@ void WCMD_HandleTildaModifiers(WCHAR **start, const WCHAR *forVariable,
/* 8. Handle 'x' : Ext */ /* 8. Handle 'x' : Ext */
if (memchrW(firstModifier, 'x', modifierLen) != NULL) { if (memchrW(firstModifier, 'x', modifierLen) != NULL) {
if (addSpace) {
strcatW(finaloutput, spaceW);
addSpace = FALSE;
}
strcatW(finaloutput, ext); strcatW(finaloutput, ext);
doneModifier = TRUE; doneModifier = TRUE;
doneFileModifier = TRUE; doneFileModifier = TRUE;

View File

@ -347,6 +347,7 @@ rem file attribute
for %%i in ("U V" W) do echo '%%~ai' for %%i in ("U V" W) do echo '%%~ai'
echo foo> foo echo foo> foo
for %%i in (foo) do echo '%%~ai' for %%i in (foo) do echo '%%~ai'
for %%i in (foo) do echo '%%~zi'
del foo del foo
rem file date/time rem file date/time
rem Not fully testable, until we can grep dir's output to get foo's creation time in an envvar... 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@R S'@or_broken@''
@todo_wine@'@drive@@shortpath@T'@or_broken@'' @todo_wine@'@drive@@shortpath@T'@or_broken@''
@todo_wine@'@drive@@shortpath@ABCDEFGHIJK.LMNOP'@or_broken@'' @todo_wine@'@drive@@shortpath@ABCDEFGHIJK.LMNOP'@or_broken@''
@todo_wine@''@or_broken@'%~ai' ''@or_broken@'%~ai'
@todo_wine@''@or_broken@'%~ai' ''@or_broken@'%~ai'
@todo_wine@'--a------'@or_broken@'%~ai' '--a------'@or_broken@'%~ai'
@todo_wine@''@or_broken@'%~ti' '5'@or_broken@'%~zi'
@todo_wine@''@or_broken@'%~ti' ''@or_broken@'%~ti'
@todo_wine@''@or_broken@'%~zi' ''@or_broken@'%~ti'
@todo_wine@''@or_broken@'%~zi' ''@or_broken@'%~zi'
''@or_broken@'%~zi'
@drive@@path@ @drive@@path@
@drive@@path@ @drive@@path@
@drive@ @drive@