/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkfilefilter.c
ViewVC logotype

Contents of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkfilefilter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 69 - (show annotations) (download)
Sat Nov 5 10:54:17 2016 UTC (6 years, 3 months ago) by dashley
File MIME type: text/plain
File size: 13108 byte(s)
License and property (keyword) changes.
1 /* $Header$ */
2
3 /*
4 * tkFileFilter.c --
5 *
6 * Process the -filetypes option for the file dialogs on Windows and the
7 * Mac.
8 *
9 * Copyright (c) 1996 Sun Microsystems, Inc.
10 *
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 *
14 * RCS: @(#) $Id: tkfilefilter.c,v 1.1.1.1 2001/06/13 05:00:16 dtashley Exp $
15 */
16
17 #include "tkInt.h"
18 #include "tkFileFilter.h"
19
20 static int AddClause _ANSI_ARGS_((
21 Tcl_Interp * interp, FileFilter * filterPtr,
22 char * patternsStr, char * ostypesStr,
23 int isWindows));
24 static void FreeClauses _ANSI_ARGS_((FileFilter * filterPtr));
25 static void FreeGlobPatterns _ANSI_ARGS_((
26 FileFilterClause * clausePtr));
27 static void FreeMacFileTypes _ANSI_ARGS_((
28 FileFilterClause * clausePtr));
29 static FileFilter * GetFilter _ANSI_ARGS_((FileFilterList * flistPtr,
30 char * name));
31
32 /*
33 *----------------------------------------------------------------------
34 *
35 * TkInitFileFilters --
36 *
37 * Initializes a FileFilterList data structure. A FileFilterList
38 * must be initialized EXACTLY ONCE before any calls to
39 * TkGetFileFilters() is made. The usual flow of control is:
40 * TkInitFileFilters(&flist);
41 * TkGetFileFilters(&flist, ...);
42 * TkGetFileFilters(&flist, ...);
43 * ...
44 * TkFreeFileFilters(&flist);
45 *
46 * Results:
47 * None.
48 *
49 * Side effects:
50 * The fields in flistPtr are initialized.
51 *----------------------------------------------------------------------
52 */
53
54 void
55 TkInitFileFilters(flistPtr)
56 FileFilterList * flistPtr; /* The structure to be initialized. */
57 {
58 flistPtr->filters = NULL;
59 flistPtr->filtersTail = NULL;
60 flistPtr->numFilters = 0;
61 }
62
63 /*
64 *----------------------------------------------------------------------
65 *
66 * TkGetFileFilters --
67 *
68 * This function is called by the Mac and Windows implementation
69 * of tk_getOpenFile and tk_getSaveFile to translate the string
70 * value of the -filetypes option of into an easy-to-parse C
71 * structure (flistPtr). The caller of this function will then use
72 * flistPtr to perform filetype matching in a platform specific way.
73 *
74 * flistPtr must be initialized (See comments in TkInitFileFilters).
75 *
76 * Results:
77 * A standard TCL return value.
78 *
79 * Side effects:
80 * The fields in flistPtr are changed according to string.
81 *----------------------------------------------------------------------
82 */
83 int
84 TkGetFileFilters(interp, flistPtr, string, isWindows)
85 Tcl_Interp *interp; /* Interpreter to use for error reporting. */
86 FileFilterList * flistPtr; /* Stores the list of file filters. */
87 char * string; /* Value of the -filetypes option. */
88 int isWindows; /* True if we are running on Windows. */
89 {
90 int listArgc;
91 char ** listArgv = NULL;
92 char ** typeInfo = NULL;
93 int code = TCL_OK;
94 int i;
95
96 if (Tcl_SplitList(interp, string, &listArgc, &listArgv) != TCL_OK) {
97 return TCL_ERROR;
98 }
99 if (listArgc == 0) {
100 goto done;
101 }
102
103 /*
104 * Free the filter information that have been allocated the previous
105 * time -- the -filefilters option may have been used more than once in
106 * the command line.
107 */
108 TkFreeFileFilters(flistPtr);
109
110 for (i = 0; i<listArgc; i++) {
111 /*
112 * Each file type should have two or three elements: the first one
113 * is the name of the type and the second is the filter of the type.
114 * The third is the Mac OSType ID, but we don't care about them here.
115 */
116 int count;
117 FileFilter * filterPtr;
118
119 if (Tcl_SplitList(interp, listArgv[i], &count, &typeInfo) != TCL_OK) {
120 code = TCL_ERROR;
121 goto done;
122 }
123
124 if (count != 2 && count != 3) {
125 Tcl_AppendResult(interp, "bad file type \"", listArgv[i], "\", ",
126 "should be \"typeName {extension ?extensions ...?} ",
127 "?{macType ?macTypes ...?}?\"", NULL);
128 code = TCL_ERROR;
129 goto done;
130 }
131
132 filterPtr = GetFilter(flistPtr, typeInfo[0]);
133
134 if (count == 2) {
135 code = AddClause(interp, filterPtr, typeInfo[1], NULL,
136 isWindows);
137 } else {
138 code = AddClause(interp, filterPtr, typeInfo[1], typeInfo[2],
139 isWindows);
140 }
141 if (code != TCL_OK) {
142 goto done;
143 }
144
145 if (typeInfo) {
146 ckfree((char*)typeInfo);
147 }
148 typeInfo = NULL;
149 }
150
151 done:
152 if (typeInfo) {
153 ckfree((char*)typeInfo);
154 }
155 if (listArgv) {
156 ckfree((char*)listArgv);
157 }
158 return code;
159 }
160
161 /*
162 *----------------------------------------------------------------------
163 *
164 * TkFreeFileFilters --
165 *
166 * Frees the malloc'ed file filter information.
167 *
168 * Results:
169 * None.
170 *
171 * Side effects:
172 * The fields allocated by TkGetFileFilters() are freed.
173 *----------------------------------------------------------------------
174 */
175
176 void
177 TkFreeFileFilters(flistPtr)
178 FileFilterList * flistPtr; /* List of file filters to free */
179 {
180 FileFilter * filterPtr, *toFree;
181
182 filterPtr=flistPtr->filters;
183 while (filterPtr) {
184 toFree = filterPtr;
185 filterPtr=filterPtr->next;
186 FreeClauses(toFree);
187 ckfree((char*)toFree->name);
188 ckfree((char*)toFree);
189 }
190 flistPtr->filters = NULL;
191 }
192
193 /*
194 *----------------------------------------------------------------------
195 *
196 * AddClause --
197 *
198 * Add one FileFilterClause to filterPtr.
199 *
200 * Results:
201 * A standard TCL result.
202 *
203 * Side effects:
204 * The list of filter clauses are updated in filterPtr.
205 *----------------------------------------------------------------------
206 */
207
208 static int AddClause(interp, filterPtr, patternsStr, ostypesStr, isWindows)
209 Tcl_Interp * interp; /* Interpreter to use for error reporting. */
210 FileFilter * filterPtr; /* Stores the new filter clause */
211 char * patternsStr; /* A TCL list of glob patterns. */
212 char * ostypesStr; /* A TCL list of Mac OSType strings. */
213 int isWindows; /* True if we are running on Windows; False
214 * if we are running on the Mac; Glob
215 * patterns need to be processed differently
216 * on these two platforms */
217 {
218 char ** globList = NULL;
219 int globCount;
220 char ** ostypeList = NULL;
221 int ostypeCount;
222 FileFilterClause * clausePtr;
223 int i;
224 int code = TCL_OK;
225
226 if (Tcl_SplitList(interp, patternsStr, &globCount, &globList)!= TCL_OK) {
227 code = TCL_ERROR;
228 goto done;
229 }
230 if (ostypesStr != NULL) {
231 if (Tcl_SplitList(interp, ostypesStr, &ostypeCount, &ostypeList)
232 != TCL_OK) {
233 code = TCL_ERROR;
234 goto done;
235 }
236 for (i=0; i<ostypeCount; i++) {
237 if (strlen(ostypeList[i]) != 4) {
238 Tcl_AppendResult(interp, "bad Macintosh file type \"",
239 ostypeList[i], "\"", NULL);
240 code = TCL_ERROR;
241 goto done;
242 }
243 }
244 }
245
246 /*
247 * Add the clause into the list of clauses
248 */
249
250 clausePtr = (FileFilterClause*)ckalloc(sizeof(FileFilterClause));
251 clausePtr->patterns = NULL;
252 clausePtr->patternsTail = NULL;
253 clausePtr->macTypes = NULL;
254 clausePtr->macTypesTail = NULL;
255
256 if (filterPtr->clauses == NULL) {
257 filterPtr->clauses = filterPtr->clausesTail = clausePtr;
258 } else {
259 filterPtr->clausesTail->next = clausePtr;
260 filterPtr->clausesTail = clausePtr;
261 }
262 clausePtr->next = NULL;
263
264 if (globCount > 0 && globList != NULL) {
265 for (i=0; i<globCount; i++) {
266 GlobPattern * globPtr = (GlobPattern*)ckalloc(sizeof(GlobPattern));
267 int len;
268
269 len = (strlen(globList[i]) + 1) * sizeof(char);
270
271 if (globList[i][0] && globList[i][0] != '*') {
272 /*
273 * Prepend a "*" to patterns that do not have a leading "*"
274 */
275 globPtr->pattern = (char*)ckalloc(len+1);
276 globPtr->pattern[0] = '*';
277 strcpy(globPtr->pattern+1, globList[i]);
278 }
279 else if (isWindows) {
280 if (strcmp(globList[i], "*") == 0) {
281 globPtr->pattern = (char*)ckalloc(4*sizeof(char));
282 strcpy(globPtr->pattern, "*.*");
283 }
284 else if (strcmp(globList[i], "") == 0) {
285 /*
286 * An empty string means "match all files with no
287 * extensions"
288 * BUG: "*." actually matches with all files on Win95
289 */
290 globPtr->pattern = (char*)ckalloc(3*sizeof(char));
291 strcpy(globPtr->pattern, "*.");
292 }
293 else {
294 globPtr->pattern = (char*)ckalloc(len);
295 strcpy(globPtr->pattern, globList[i]);
296 }
297 } else {
298 globPtr->pattern = (char*)ckalloc(len);
299 strcpy(globPtr->pattern, globList[i]);
300 }
301
302 /*
303 * Add the glob pattern into the list of patterns.
304 */
305
306 if (clausePtr->patterns == NULL) {
307 clausePtr->patterns = clausePtr->patternsTail = globPtr;
308 } else {
309 clausePtr->patternsTail->next = globPtr;
310 clausePtr->patternsTail = globPtr;
311 }
312 globPtr->next = NULL;
313 }
314 }
315 if (ostypeCount > 0 && ostypeList != NULL) {
316 for (i=0; i<ostypeCount; i++) {
317 MacFileType * mfPtr = (MacFileType*)ckalloc(sizeof(MacFileType));
318
319 memcpy(&mfPtr->type, ostypeList[i], sizeof(OSType));
320
321 /*
322 * Add the Mac type pattern into the list of Mac types
323 */
324 if (clausePtr->macTypes == NULL) {
325 clausePtr->macTypes = clausePtr->macTypesTail = mfPtr;
326 } else {
327 clausePtr->macTypesTail->next = mfPtr;
328 clausePtr->macTypesTail = mfPtr;
329 }
330 mfPtr->next = NULL;
331 }
332 }
333
334 done:
335 if (globList) {
336 ckfree((char*)globList);
337 }
338 if (ostypeList) {
339 ckfree((char*)ostypeList);
340 }
341
342 return code;
343 }
344
345 /*
346 *----------------------------------------------------------------------
347 *
348 * GetFilter --
349 *
350 * Add one FileFilter to flistPtr.
351 *
352 * Results:
353 * A standard TCL result.
354 *
355 * Side effects:
356 * The list of filters are updated in flistPtr.
357 *----------------------------------------------------------------------
358 */
359
360 static FileFilter * GetFilter(flistPtr, name)
361 FileFilterList * flistPtr; /* The FileFilterList that contains the
362 * newly created filter */
363 char * name; /* Name of the filter. It is usually displayed
364 * in the "File Types" listbox in the file
365 * dialogs. */
366 {
367 FileFilter * filterPtr;
368
369 for (filterPtr=flistPtr->filters; filterPtr; filterPtr=filterPtr->next) {
370 if (strcmp(filterPtr->name, name)==0) {
371 return filterPtr;
372 }
373 }
374
375 filterPtr = (FileFilter*)ckalloc(sizeof(FileFilter));
376 filterPtr->clauses = NULL;
377 filterPtr->clausesTail = NULL;
378 filterPtr->name = (char*)ckalloc((strlen(name)+1) * sizeof(char));
379 strcpy(filterPtr->name, name);
380
381 if (flistPtr->filters == NULL) {
382 flistPtr->filters = flistPtr->filtersTail = filterPtr;
383 } else {
384 flistPtr->filtersTail->next = filterPtr;
385 flistPtr->filtersTail = filterPtr;
386 }
387 filterPtr->next = NULL;
388
389 ++flistPtr->numFilters;
390 return filterPtr;
391 }
392
393 /*
394 *----------------------------------------------------------------------
395 *
396 * FreeClauses --
397 *
398 * Frees the malloc'ed file type clause
399 *
400 * Results:
401 * None.
402 *
403 * Side effects:
404 * The list of clauses in filterPtr->clauses are freed.
405 *----------------------------------------------------------------------
406 */
407
408 static void
409 FreeClauses(filterPtr)
410 FileFilter * filterPtr; /* FileFilter whose clauses are to be freed */
411 {
412 FileFilterClause * clausePtr, * toFree;
413
414 clausePtr = filterPtr->clauses;
415 while (clausePtr) {
416 toFree = clausePtr;
417 clausePtr=clausePtr->next;
418 FreeGlobPatterns(toFree);
419 FreeMacFileTypes(toFree);
420 ckfree((char*)toFree);
421 }
422 filterPtr->clauses = NULL;
423 filterPtr->clausesTail = NULL;
424 }
425
426 /*
427 *----------------------------------------------------------------------
428 *
429 * FreeGlobPatterns --
430 *
431 * Frees the malloc'ed glob patterns in a clause
432 *
433 * Results:
434 * None.
435 *
436 * Side effects:
437 * The list of glob patterns in clausePtr->patterns are freed.
438 *----------------------------------------------------------------------
439 */
440
441 static void
442 FreeGlobPatterns(clausePtr)
443 FileFilterClause * clausePtr;/* The clause whose patterns are to be freed*/
444 {
445 GlobPattern * globPtr, * toFree;
446
447 globPtr = clausePtr->patterns;
448 while (globPtr) {
449 toFree = globPtr;
450 globPtr=globPtr->next;
451
452 ckfree((char*)toFree->pattern);
453 ckfree((char*)toFree);
454 }
455 clausePtr->patterns = NULL;
456 }
457
458 /*
459 *----------------------------------------------------------------------
460 *
461 * FreeMacFileTypes --
462 *
463 * Frees the malloc'ed Mac file types in a clause
464 *
465 * Results:
466 * None.
467 *
468 * Side effects:
469 * The list of Mac file types in clausePtr->macTypes are freed.
470 *----------------------------------------------------------------------
471 */
472
473 static void
474 FreeMacFileTypes(clausePtr)
475 FileFilterClause * clausePtr; /* The clause whose mac types are to be
476 * freed */
477 {
478 MacFileType * mfPtr, * toFree;
479
480 mfPtr = clausePtr->macTypes;
481 while (mfPtr) {
482 toFree = mfPtr;
483 mfPtr=mfPtr->next;
484 ckfree((char*)toFree);
485 }
486 clausePtr->macTypes = NULL;
487 }
488
489 /* End of tkfilefilter.c */

Properties

Name Value
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25