OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [generic/] [tkFileFilter.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.