source: trunk/dll/makelist.c@ 985

Last change on this file since 985 was 985, checked in by Gregg Young, 18 years ago

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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