remove empty dir
[reactos.git] / rosapps / winfile / sort.c
1 /*
2 * ReactOS winfile
3 *
4 * sort.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
24 #include <windows.h>
25 #include <commctrl.h>
26 #include <stdlib.h>
27 #include <malloc.h>
28 #include <memory.h>
29 #include <tchar.h>
30 #include <process.h>
31 #include <stdio.h>
32
33 #include <windowsx.h>
34 #include <shellapi.h>
35 #include <ctype.h>
36 #include <assert.h>
37 #define ASSERT assert
38
39 #include "main.h"
40 #include "sort.h"
41
42
43
44 // directories first...
45 static int compareType(const WIN32_FIND_DATA* fd1, const WIN32_FIND_DATA* fd2)
46 {
47 int dir1 = fd1->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
48 int dir2 = fd2->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
49
50 return dir2==dir1? 0: dir2<dir1? -1: 1;
51 }
52
53
54 static int compareName(const void* arg1, const void* arg2)
55 {
56 const WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->data;
57 const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
58
59 int cmp = compareType(fd1, fd2);
60 if (cmp)
61 return cmp;
62
63 return lstrcmpi(fd1->cFileName, fd2->cFileName);
64 }
65
66 static int compareExt(const void* arg1, const void* arg2)
67 {
68 const WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->data;
69 const WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
70 const TCHAR *name1, *name2, *ext1, *ext2;
71
72 int cmp = compareType(fd1, fd2);
73 if (cmp)
74 return cmp;
75
76 name1 = fd1->cFileName;
77 name2 = fd2->cFileName;
78
79 ext1 = _tcsrchr(name1, _T('.'));
80 ext2 = _tcsrchr(name2, _T('.'));
81
82 if (ext1)
83 ext1++;
84 else
85 ext1 = _T("");
86
87 if (ext2)
88 ext2++;
89 else
90 ext2 = _T("");
91
92 cmp = lstrcmpi(ext1, ext2);
93 if (cmp)
94 return cmp;
95
96 return lstrcmpi(name1, name2);
97 }
98
99 static int compareSize(const void* arg1, const void* arg2)
100 {
101 WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->data;
102 WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
103
104 int cmp = compareType(fd1, fd2);
105 if (cmp)
106 return cmp;
107
108 cmp = fd2->nFileSizeHigh - fd1->nFileSizeHigh;
109
110 if (cmp < 0)
111 return -1;
112 else if (cmp > 0)
113 return 1;
114
115 cmp = fd2->nFileSizeLow - fd1->nFileSizeLow;
116
117 return cmp<0? -1: cmp>0? 1: 0;
118 }
119
120 static int compareDate(const void* arg1, const void* arg2)
121 {
122 WIN32_FIND_DATA* fd1 = &(*(Entry**)arg1)->data;
123 WIN32_FIND_DATA* fd2 = &(*(Entry**)arg2)->data;
124
125 int cmp = compareType(fd1, fd2);
126 if (cmp)
127 return cmp;
128
129 return CompareFileTime(&fd2->ftLastWriteTime, &fd1->ftLastWriteTime);
130 }
131
132
133 static int (*sortFunctions[])(const void* arg1, const void* arg2) = {
134 compareName, // SORT_NAME
135 compareExt, // SORT_EXT
136 compareSize, // SORT_SIZE
137 compareDate // SORT_DATE
138 };
139
140
141 void SortDirectory(Entry* parent, SORT_ORDER sortOrder)
142 {
143 Entry* entry = parent->down;
144 Entry** array, **p;
145 int len;
146
147 len = 0;
148 for(entry=parent->down; entry; entry=entry->next)
149 len++;
150
151 if (len) {
152 #ifdef _MSC_VER
153 array = (Entry**) alloca(len*sizeof(Entry*));
154 #else
155 array = (Entry**) malloc(len*sizeof(Entry*));
156 #endif
157 memset(array, 0, len*sizeof(Entry*));
158 p = array;
159 for(entry=parent->down; entry; entry=entry->next)
160 *p++ = entry;
161
162 // call qsort with the appropriate compare function
163 qsort(array, len, sizeof(array[0]), sortFunctions[sortOrder]);
164
165 parent->down = array[0];
166
167 for(p=array; --len; p++)
168 p[0]->next = p[1];
169
170 (*p)->next = 0;
171 }
172 }
173
174