[PATCH 2/9] Add DIR /O ordering support
Jason Edmeades
us at edmeades.me.uk
Tue Mar 13 15:27:46 CDT 2007
---
programs/cmd/directory.c | 113 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 111 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
index 31ac6d0..2abdc34 100644
--- a/programs/cmd/directory.c
+++ b/programs/cmd/directory.c
@@ -46,10 +46,20 @@ typedef enum _DISPLAYTIME
Written
} DISPLAYTIME;
+typedef enum _DISPLAYORDER
+{
+ Name = 0,
+ Extension,
+ Size,
+ Date
+} DISPLAYORDER;
+
static int file_total, dir_total, recurse, wide, bare, max_width, lower;
static int shortname, usernames;
static ULONGLONG byte_total;
static DISPLAYTIME dirTime;
+static DISPLAYORDER dirOrder;
+static BOOL orderReverse, orderGroupDirs, orderGroupDirsReverse;
/*****************************************************************************
* WCMD_directory
@@ -69,6 +79,10 @@ void WCMD_directory (void) {
byte_total = 0;
file_total = dir_total = 0;
dirTime = Written;
+ dirOrder = Name;
+ orderReverse = FALSE;
+ orderGroupDirs = FALSE;
+ orderGroupDirsReverse = FALSE;
/* Handle args */
paged_mode = (strstr(quals, "/P") != NULL);
@@ -96,6 +110,28 @@ void WCMD_directory (void) {
}
}
+ if ((p = strstr(quals, "/O")) != NULL) {
+ p = p + 2;
+ if (*p==':') p++; /* Skip optional : */
+ while (*p && *p != '/') {
+ switch (*p) {
+ case 'N': dirOrder = Name; break;
+ case 'E': dirOrder = Extension; break;
+ case 'S': dirOrder = Size; break;
+ case 'D': dirOrder = Date; break;
+ case '-': if (*(p+1)=='G') orderGroupDirsReverse=TRUE;
+ else orderReverse = TRUE;
+ break;
+ case 'G': orderGroupDirs = TRUE; break;
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ WCMD_print_error();
+ return;
+ }
+ p++;
+ }
+ }
+
/* Handle conflicting args and initialization */
if (bare || shortname) wide = FALSE;
if (bare) shortname = FALSE;
@@ -410,10 +446,83 @@ char * WCMD_strrev (char *buff) {
}
+/*****************************************************************************
+ * WCMD_dir_sort
+ *
+ * Sort based on the /O options supplied on the command line
+ */
int WCMD_dir_sort (const void *a, const void *b)
{
- return (lstrcmpi(((const WIN32_FIND_DATA *)a)->cFileName,
- ((const WIN32_FIND_DATA *)b)->cFileName));
+ WIN32_FIND_DATA *filea = (WIN32_FIND_DATA *)a;
+ WIN32_FIND_DATA *fileb = (WIN32_FIND_DATA *)b;
+ int result = 0;
+
+ /* If /OG or /O-G supplied, dirs go at the top or bottom, ignoring the
+ requested sort order for the directory components */
+ if (orderGroupDirs &&
+ ((filea->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
+ (fileb->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)))
+ {
+ BOOL aDir = filea->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+ if (aDir) result = -1;
+ else result = 1;
+ if (orderGroupDirsReverse) result = -result;
+ return result;
+
+ /* Order by Name: */
+ } else if (dirOrder == Name) {
+ result = lstrcmpi(filea->cFileName, fileb->cFileName);
+
+ /* Order by Size: */
+ } else if (dirOrder == Size) {
+ ULONG64 sizea = (((ULONG64)filea->nFileSizeHigh) << 32) + filea->nFileSizeLow;
+ ULONG64 sizeb = (((ULONG64)fileb->nFileSizeHigh) << 32) + fileb->nFileSizeLow;
+ if( sizea < sizeb ) result = -1;
+ else if( sizea == sizeb ) result = 0;
+ else result = 1;
+
+ /* Order by Date: (Takes into account which date (/T option) */
+ } else if (dirOrder == Date) {
+
+ FILETIME *ft;
+ ULONG64 timea, timeb;
+
+ if (dirTime == Written) {
+ ft = &filea->ftLastWriteTime;
+ timea = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ ft = &fileb->ftLastWriteTime;
+ timeb = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ } else if (dirTime == Access) {
+ ft = &filea->ftLastAccessTime;
+ timea = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ ft = &fileb->ftLastAccessTime;
+ timeb = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ } else {
+ ft = &filea->ftCreationTime;
+ timea = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ ft = &fileb->ftCreationTime;
+ timeb = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
+ }
+ if( timea < timeb ) result = -1;
+ else if( timea == timeb ) result = 0;
+ else result = 1;
+
+ /* Order by Extension: (Takes into account which date (/T option) */
+ } else if (dirOrder == Extension) {
+ char drive[10];
+ char dir[MAX_PATH];
+ char fname[MAX_PATH];
+ char extA[MAX_PATH];
+ char extB[MAX_PATH];
+
+ /* Split into components */
+ WCMD_splitpath(filea->cFileName, drive, dir, fname, extA);
+ WCMD_splitpath(fileb->cFileName, drive, dir, fname, extB);
+ result = lstrcmpi(extA, extB);
+ }
+
+ if (orderReverse) result = -result;
+ return result;
}
/*****************************************************************************
--
1.5.0
More information about the wine-patches
mailing list