source: trunk/dll/makelist.c

Last change on this file was 1916, checked in by Gregg Young, 3 days ago

Fix easize so that EAs larger than 32767 show their actual size instead of 32767

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: makelist.c 1916 2025-11-01 18:30:47Z gyoung $
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 29 Feb 08 GKY Use xfree where appropriate
17 17 Jul 08 SHL Add SetListOwner for Fortify support
18 12 Jun 11 GKY Added IdleIfNeeded to the freelist loop to improve system
19 responsiveness when freeing lists with large numbers of items
20
21***********************************************************************/
22
23#include <stdlib.h>
24#include <string.h>
25
26#define INCL_DOS
27#define INCL_WIN
28#define INCL_LONGLONG
29
30#include "fm3dll.h" // 05 Jan 08 SHL fixme to be gone
31#include "fm3str.h"
32#include "makelist.h"
33#include "errutil.h" // Dos_Error...
34#include "strutil.h" // GetPString
35#include "dircnrs.h"
36#include "misc.h" // CurrentRecord
37#include "newview.h" // Data declarations
38#include "wrappers.h" // xfree
39#include "fortify.h" // 06 May 08 SHL
40#include "tmrsvcs.h" // ITIMER_DESC
41#include "eas.h" // GetLargeEASize
42
43static PSZ pszSrcFile = __FILE__;
44
45VOID SortList(LISTINFO *li)
46{
47 // bubble-sort entries by size, descending
48
49 UINT x;
50 CHAR *s;
51 ULONG l;
52 BOOL swapped;
53
54 if (li && li->list && li->list[0] && li->cbFile) {
55 do {
56 swapped = FALSE;
57 for (x = 0; li->list[x] && li->list[x + 1]; x++) {
58 if (li->cbFile[x] < li->cbFile[x + 1]) {
59 s = li->list[x];
60 li->list[x] = li->list[x + 1];
61 li->list[x + 1] = s;
62 l = li->cbFile[x];
63 li->cbFile[x] = li->cbFile[x + 1];
64 li->cbFile[x + 1] = l;
65 if (li->ulitemID) {
66 l = li->ulitemID[x];
67 li->ulitemID[x] = li->ulitemID[x + 1];
68 li->ulitemID[x + 1] = l;
69 }
70 swapped = TRUE;
71 }
72 }
73 } while (swapped);
74 }
75}
76
77VOID FreeListInfo(LISTINFO *li)
78{
79 if (li) {
80 xfree(li->ulitemID, pszSrcFile, __LINE__);
81 xfree(li->cbFile, pszSrcFile, __LINE__);
82 if (li->list)
83 FreeList(li->list);
84 free(li);
85 }
86}
87
88VOID FreeList(CHAR **list)
89{
90 UINT x;
91 ITIMER_DESC itdSleep = { 0 };
92
93 if (list) {
94 InitITimer(&itdSleep, 500);
95 for (x = 0; list[x]; x++) {
96#ifdef __DEBUG_ALLOC__
97 _heap_check();
98#endif
99 free(list[x]);
100 if (!IdleIfNeeded(&itdSleep, 30)) {
101 for (x = x + 1; list[x]; x++) {
102 free(list[x]);
103 }
104 break;
105 }
106 }
107#ifdef __DEBUG_ALLOC__
108 _heap_check();
109#endif
110 free(list);
111 priority_normal();
112 DosPostEventSem(CompactSem);
113 }
114}
115
116INT AddToFileList(CHAR *string, FILEFINDBUF4L *ffb4, FILELIST ***list,
117 UINT *pnumfiles, UINT *pnumalloced)
118{
119 FILELIST *pfl;
120
121 if (string && ffb4) {
122 // Ensure room for NULL entry
123 if (((*pnumfiles) + 3) > *pnumalloced) {
124 FILELIST **pflArray;
125
126 // Use plain realloc for speed
127 // 06 Aug 07 SHL fixme to know why + 6
128# ifdef FORTIFY
129 Fortify_EnterScope();
130# endif
131 pflArray = realloc(*list, (*pnumalloced + 6) * sizeof(FILELIST *));
132 if (!pflArray) {
133 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
134 return 1;
135 }
136 (*pnumalloced) += 6;
137 *list = pflArray;
138 }
139 // Use plain malloc for speed
140 pfl = malloc(sizeof(FILELIST) + strlen(string));
141 if (!pfl) {
142 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
143 return 2;
144 }
145 pfl->attrFile = ffb4->attrFile;
146 pfl->date = ffb4->fdateLastWrite;
147 pfl->time = ffb4->ftimeLastWrite;
148 pfl->ladate = ffb4->fdateLastAccess;
149 pfl->latime = ffb4->ftimeLastAccess;
150 pfl->crdate = ffb4->fdateCreation;
151 pfl->crtime = ffb4->ftimeCreation;
152 pfl->cbFile = ffb4->cbFile;
153 //Need to account for snapshot file but since cbList is a ulong and will always be even the fact they can exceed
154 //65535 doesn't matter. 31 Oct 25 GKY
155 pfl->easize = ffb4->cbList == 65535 ? GetLargeEASize(ffb4->achName) : CBLIST_TO_EASIZE(ffb4->cbList);
156 strcpy(pfl->fname, string);
157 (*list)[*pnumfiles] = pfl;
158 (*pnumfiles)++;
159 // Ensure list always ends with two NULL entries
160 // 06 Aug 07 SHL fixme to know why
161 (*list)[*pnumfiles] = NULL;
162 (*list)[(*pnumfiles) + 1] = NULL;
163#ifdef __DEBUG_ALLOC__
164 _heap_check();
165#endif
166 }
167 return 0;
168}
169
170/**
171 * Add string to string list
172 * Enlarges as needed
173 * Ensures 2 NULL end markers exist
174 */
175
176INT AddToList(CHAR *string, CHAR ***list, UINT *pnumfiles, UINT *pnumalloced)
177{
178 CHAR **ppsz;
179 PSZ psz;
180
181 if (string) {
182 if (((*pnumfiles) + 3) > *pnumalloced) {
183 // Use plain realloc for speed
184# ifdef FORTIFY
185 Fortify_EnterScope();
186# endif
187 ppsz = realloc(*list, (*pnumalloced + 6) * sizeof(CHAR *));
188 if (!ppsz) {
189 Runtime_Error(pszSrcFile, __LINE__, "realloc");
190 return 1;
191 }
192 (*pnumalloced) += 6;
193 *list = ppsz;
194 }
195 // Use plain malloc for speed
196 psz = malloc(strlen(string) + 1);
197 if (!psz) {
198 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
199 return 2;
200 }
201 (*list)[*pnumfiles] = psz;
202 strcpy((*list)[*pnumfiles], string); // Add entry
203 (*pnumfiles)++;
204 (*list)[*pnumfiles] = NULL; // Add end marker
205 (*list)[(*pnumfiles) + 1] = NULL; // Add 2nd end marker - fixme to know why?
206#ifdef __DEBUG_ALLOC__
207 _heap_check();
208#endif
209 }
210 return 0;
211}
212
213CHAR **BuildList(HWND hwndCnr)
214{
215 PCNRITEM pci;
216 CHAR **list = NULL, **test;
217 UINT numfiles = 0, numalloc = 0;
218 INT error = 0, attribute = CRA_CURSORED;
219
220 pci = (PCNRITEM) CurrentRecord(hwndCnr);
221 if (pci && (INT) pci != -1 && !(pci->flags & RECFLAGS_ENV)) {
222 if (pci->rc.flRecordAttr & CRA_SELECTED) {
223 attribute = CRA_SELECTED;
224 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
225 MPFROMSHORT(attribute));
226 }
227 }
228 while (pci && (INT) pci != -1 && !error) {
229 if (!(pci->rc.flRecordAttr & CRA_FILTERED))
230 error = AddToList(pci->pszFileName, &list, &numfiles, &numalloc);
231 pci = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pci),
232 MPFROMSHORT(attribute));
233 }
234 if (numalloc > numfiles + 1) {
235 // Use plain realloc for speed
236
237# ifdef FORTIFY
238 Fortify_EnterScope();
239# endif
240 test = realloc(list, sizeof(CHAR *) * (numfiles + 1));
241 if (!test)
242 Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_OUTOFMEMORY));
243 else
244 list = test;
245 } // while
246 return list;
247}
248
249CHAR **BuildArcList(HWND hwndCnr)
250{
251 PARCITEM pai;
252 CHAR **list = NULL;
253 UINT numfiles = 0, numalloc = 0;
254 INT error = 0, attribute = CRA_CURSORED;
255
256 pai = (PARCITEM) CurrentRecord(hwndCnr);
257 if (pai && (INT) pai != -1) {
258 if (pai->rc.flRecordAttr & CRA_SELECTED) {
259 attribute = CRA_SELECTED;
260 pai = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST),
261 MPFROMSHORT(attribute));
262 }
263 }
264 while (pai && (INT) pai != -1 && !error) {
265 if (!(pai->rc.flRecordAttr & CRA_FILTERED))
266 error = AddToList(pai->pszFileName, &list, &numfiles, &numalloc);
267 pai = WinSendMsg(hwndCnr, CM_QUERYRECORDEMPHASIS, MPFROMP(pai),
268 MPFROMSHORT(attribute));
269 }
270 return list;
271}
272
273CHAR **RemoveFromList(CHAR **list, CHAR *item)
274{
275 UINT x, y;
276
277 if (list && list[0] && item) {
278 for (x = 0; list[x]; x++) {
279 if (item == list[x]) {
280 free(list[x]);
281 list[x] = NULL;
282 for (y = x;; y++) {
283 if (y != x && !list[y])
284 break;
285 list[y] = list[y + 1];
286 }
287 if (!list[0]) {
288 FreeList(list);
289 list = NULL;
290 }
291# ifdef FORTIFY
292 Fortify_LeaveScope();
293# endif
294 break;
295 }
296 }
297 }
298 return list;
299}
300
301CHAR **CombineLists(CHAR **prime, CHAR **add)
302{
303 UINT x;
304 UINT numalloc, numfiles = 0;
305
306 if (add && add[0]) {
307 if (prime) {
308 for (x = 0; prime[x]; x++)
309 numfiles++;
310 }
311 numalloc = numfiles;
312 for (x = 0; add[x]; x++) {
313 if (*add[x])
314 AddToList(add[x], &prime, &numfiles, &numalloc);
315 }
316 FreeList(add);
317 }
318 return prime;
319}
320
321#ifdef FORTIFY
322
323VOID SetListOwner(LISTINFO *li)
324{
325 if (li) {
326 CHAR **list = li->list;
327 if (list) {
328 UINT x;
329 for (x = 0; list[x]; x++)
330 Fortify_BecomeOwner(list[x]);
331 }
332 Fortify_BecomeOwner(li);
333 }
334}
335
336#endif // FORTIFY
337
338#pragma alloc_text(MAKELIST,AddToList,AddToFileList,BuildList,FreeListInfo,FreeList)
339#pragma alloc_text(MAKELIST,SortList,BuildArcList,RemoveFromList,CombineLists)
340#ifdef FORTIFY
341#pragma alloc_text(MAKELIST,SetListOwner)
342#endif // FORTIFY
Note: See TracBrowser for help on using the repository browser.