source: trunk/dll/makelist.c@ 907

Last change on this file since 907 was 907, checked in by Steven Levine, 18 years ago

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1
2/***********************************************************************
3
4 $Id: makelist.c 907 2008-01-06 07:26:17Z stevenhl $
5
6 Make file lists
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2003, 2008 Steven H.Levine
10
11 12 Feb 03 SHL AddToFileList: standardize EA math
12 22 Jul 06 SHL Use Runtime_Error
13 22 Jul 06 SHL AddToList optimize
14 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limits
15 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
16
17***********************************************************************/
18
19#include <stdlib.h>
20#include <string.h>
21
22#define INCL_DOS
23#define INCL_WIN
24#define INCL_LONGLONG
25
26#include "fm3str.h"
27#include "makelist.h"
28#include "errutil.h" // Dos_Error...
29#include "strutil.h" // GetPString
30#include "dircnrs.h"
31#include "fm3dll.h" // 05 Jan 08 SHL fixme to be gone
32
33static PSZ pszSrcFile = __FILE__;
34
35VOID SortList(LISTINFO *li)
36{
37 /* bubble-sort entries by size, descending */
38
39 UINT x;
40 CHAR *s;
41 ULONG l;
42 BOOL swapped;
43
44 if (li && li->list && li->list[0] && li->cbFile) {
45 do {
46 swapped = FALSE;
47 for (x = 0; li->list[x] && li->list[x + 1]; x++) {
48 if (li->cbFile[x] < li->cbFile[x + 1]) {
49 s = li->list[x];
50 li->list[x] = li->list[x + 1];
51 li->list[x + 1] = s;
52 l = li->cbFile[x];
53 li->cbFile[x] = li->cbFile[x + 1];
54 li->cbFile[x + 1] = l;
55 if (li->ulitemID) {
56 l = li->ulitemID[x];
57 li->ulitemID[x] = li->ulitemID[x + 1];
58 li->ulitemID[x + 1] = l;
59 }
60 swapped = TRUE;
61 }
62 }
63 } while (swapped);
64 }
65}
66
67VOID FreeListInfo(LISTINFO *li)
68{
69 if (li) {
70 if (li->ulitemID)
71 free(li->ulitemID);
72 if (li->cbFile)
73 free(li->cbFile);
74 if (li->list)
75 FreeList(li->list);
76 free(li);
77 }
78}
79
80VOID FreeList(CHAR **list)
81{
82 UINT x;
83
84 if (list) {
85 for (x = 0; list[x]; x++) {
86#ifdef __DEBUG_ALLOC__
87 _heap_check();
88#endif
89 free(list[x]);
90 }
91#ifdef __DEBUG_ALLOC__
92 _heap_check();
93#endif
94 free(list);
95 }
96 DosPostEventSem(CompactSem);
97}
98
99INT AddToFileList(CHAR *string, FILEFINDBUF4L *ffb4, FILELIST ***list,
100 UINT *pnumfiles, UINT *pnumalloced)
101{
102 FILELIST *pfl;
103
104 if (string && ffb4) {
105 // Ensure room for NULL entry
106 if (((*pnumfiles) + 3) > *pnumalloced) {
107 FILELIST **pflArray;
108
109 // Use plain realloc for speed
110 // 06 Aug 07 SHL fixme to know why + 6
111 pflArray = realloc(*list, (*pnumalloced + 6) * sizeof(FILELIST *));
112 if (!pflArray) {
113 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
114 return 1;
115 }
116 (*pnumalloced) += 6;
117 *list = pflArray;
118 }
119 // Use plain malloc for speed
120 pfl = malloc(sizeof(FILELIST) + strlen(string));
121 if (!pfl) {
122 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
123 return 2;
124 }
125 pfl->attrFile = ffb4->attrFile;
126 pfl->date = ffb4->fdateLastWrite;
127 pfl->time = ffb4->ftimeLastWrite;
128 pfl->ladate = ffb4->fdateLastAccess;
129 pfl->latime = ffb4->ftimeLastAccess;
130 pfl->crdate = ffb4->fdateCreation;
131 pfl->crtime = ffb4->ftimeCreation;
132 pfl->cbFile = ffb4->cbFile;
133 pfl->easize = CBLIST_TO_EASIZE(ffb4->cbList);
134 strcpy(pfl->fname, string);
135 (*list)[*pnumfiles] = pfl;
136 (*pnumfiles)++;
137 // Ensure list always ends with two NULL entries
138 // 06 Aug 07 SHL fixme to know why
139 (*list)[*pnumfiles] = NULL;
140 (*list)[(*pnumfiles) + 1] = NULL;
141#ifdef __DEBUG_ALLOC__
142 _heap_check();
143#endif
144 }
145 return 0;
146}
147
148/**
149 * Add string to string list
150 * Enlarges as needed
151 * Ensures 2 NULL end markers exist
152 */
153
154INT AddToList(CHAR *string, CHAR ***list, UINT *pnumfiles, UINT *pnumalloced)
155{
156 CHAR **ppsz;
157 PSZ psz;
158
159 if (string) {
160 if (((*pnumfiles) + 3) > *pnumalloced) {
161 // Use plain realloc for speed
162 ppsz = realloc(*list, (*pnumalloced + 6) * sizeof(CHAR *));
163 if (!ppsz) {
164 Runtime_Error(pszSrcFile, __LINE__, "realloc");
165 return 1;
166 }
167 (*pnumalloced) += 6;
168 *list = ppsz;
169 }
170 // Use plain malloc for speed
171 psz = malloc(strlen(string) + 1);
172 if (!psz) {
173 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
174 return 2;
175 }
176 (*list)[*pnumfiles] = psz;
177 strcpy((*list)[*pnumfiles], string); // Add entry
178 (*pnumfiles)++;
179 (*list)[*pnumfiles] = NULL; // Add end marker
180 (*list)[(*pnumfiles) + 1] = NULL; // Add 2nd end marker - fixme to know why?
181#ifdef __DEBUG_ALLOC__
182 _heap_check();
183#endif
184 }
185 return 0;
186}
187
188CHAR **BuildList(HWND hwndCnr)
189{
190 PCNRITEM pci;
191 CHAR **list = NULL, **test;
192 UINT numfiles = 0, numalloc = 0;
193 INT error = 0, attribute = CRA_CURSORED;
194
195 pci = (PCNRITEM) CurrentRecord(hwndCnr);
196 if (pci && (INT) pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
197 if (pci->rc.flRecordAttr & CRA_SELECTED) {
198 attribute = CRA_SELECTED;
199 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
200 MPFROMSHORT(attribute));
201 }
202 }
203 while (pci && (INT) pci != -1 && !error) {
204 if (!(pci->rc.flRecordAttr & CRA_FILTERED))
205 error = AddToList(pci->pszFileName, &list, &numfiles, &numalloc);
206 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
207 MPFROMSHORT(attribute));
208 }
209 if (numalloc > numfiles + 1) {
210 // Use plain realloc for speed
211 test = realloc(list, sizeof(CHAR *) * (numfiles + 1));
212 if (!test)
213 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
214 else
215 list = test;
216 } // while
217 return list;
218}
219
220CHAR **BuildArcList(HWND hwndCnr)
221{
222 PARCITEM pai;
223 CHAR **list = NULL;
224 UINT numfiles = 0, numalloc = 0;
225 INT error = 0, attribute = CRA_CURSORED;
226
227 pai = (PARCITEM) CurrentRecord(hwndCnr);
228 if (pai && (INT) pai != -1) {
229 if (pai->rc.flRecordAttr & CRA_SELECTED) {
230 attribute = CRA_SELECTED;
231 pai = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
232 MPFROMSHORT(attribute));
233 }
234 }
235 while (pai && (INT) pai != -1 && !error) {
236 if (!(pai->rc.flRecordAttr & CRA_FILTERED))
237 error = AddToList(pai->pszFileName, &list, &numfiles, &numalloc);
238 pai = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pai),
239 MPFROMSHORT(attribute));
240 }
241 return list;
242}
243
244CHAR **RemoveFromList(CHAR **list, CHAR *item)
245{
246 UINT x, y;
247
248 if (list && list[0] && item) {
249 for (x = 0; list[x]; x++) {
250 if (item == list[x]) {
251 free(list[x]);
252 list[x] = NULL;
253 for (y = x;; y++) {
254 if (y != x && !list[y])
255 break;
256 list[y] = list[y + 1];
257 }
258 if (!list[0]) {
259 FreeList(list);
260 list = NULL;
261 }
262 break;
263 }
264 }
265 }
266 return list;
267}
268
269CHAR **CombineLists(CHAR **prime, CHAR **add)
270{
271 UINT x;
272 UINT numalloc, numfiles = 0;
273
274 if (add && add[0]) {
275 if (prime) {
276 for (x = 0; prime[x]; x++)
277 numfiles++;
278 }
279 numalloc = numfiles;
280 for (x = 0; add[x]; x++) {
281 if (*add[x])
282 AddToList(add[x], &prime, &numfiles, &numalloc);
283 }
284 FreeList(add);
285 }
286 return prime;
287}
288
289#pragma alloc_text(MAKELIST,AddToList,AddToFileList,BuildList,FreeListInfo,FreeList)
290#pragma alloc_text(MAKELIST,SortList,BuildArcList,RemoveFromList,CombineLists)
Note: See TracBrowser for help on using the repository browser.