2 * Grace - Graphics for Exploratory Data Analysis
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 * Copyright (c) 1991-95 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-99 Grace Development Team
9 * Maintained by Evgeny Stambulchik
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 * filter files before they are input and output
40 #if defined(HAVE_FNMATCH)
48 typedef struct filter
{
55 Filter
*ifilt
, *ofilt
;
59 int add_input_filter( int method
, const char *id
, const char *comm
);
60 int add_output_filter( int method
, const char *id
, const char *comm
);
61 static void hex2char( Filter
*, const char * );
62 static int test_magic( int len
, const char *magic
, FILE *in
);
63 static int test_pattern( char *ext
, const char *fn
);
65 int add_io_filter( int type
, int method
, const char *id
, const char *comm
)
67 if( type
== FILTER_INPUT
)
68 return add_input_filter( method
, id
, comm
);
69 else if( type
== FILTER_OUTPUT
)
70 return add_output_filter( method
, id
, comm
);
76 * if method == 0 -> PATTERN MATCHING else method = the number of bytes to
77 * match in MAGIC NUMBER
79 int add_input_filter( int method
, const char *id
, const char *comm
)
81 ifilt
= xrealloc( ifilt
, ++numIfilt
*sizeof(Filter
) );
82 ifilt
[numIfilt
-1].command
= copy_string(NULL
, comm
);
83 strcpy( ifilt
[numIfilt
-1].command
, comm
);
84 ifilt
[numIfilt
-1].method
= method
;
85 if( method
== FILTER_PATTERN
) {
86 ifilt
[numIfilt
-1].id
= xmalloc( strlen(id
)+1 );
87 strcpy( ifilt
[numIfilt
-1].id
, id
);
88 ifilt
[numIfilt
-1].idlen
= strlen( ifilt
[numIfilt
-1].id
);
90 ifilt
[numIfilt
-1].id
= xmalloc(strlen(id
)/2+1);
91 hex2char( &ifilt
[numIfilt
-1], id
);
93 if( ifilt
[numIfilt
-1].idlen
== 0 ) {
101 int add_output_filter( int method
, const char *id
, const char *comm
)
103 ofilt
= xrealloc( ofilt
, ++numOfilt
*sizeof(Filter
) );
104 ofilt
[numOfilt
-1].command
= copy_string(NULL
, comm
);
105 strcpy( ofilt
[numOfilt
-1].command
, comm
);
106 ofilt
[numOfilt
-1].id
= xmalloc( strlen(id
)+1 );
107 strcpy( ofilt
[numOfilt
-1].id
, id
);
108 ofilt
[numOfilt
-1].method
= FILTER_PATTERN
;
115 * f = 0->output filters, f=1->input filters
117 void clear_io_filters( int f
)
122 if( f
==FILTER_OUTPUT
){
130 for( ; *i
>0; (*i
)-- ) {
131 xfree( filt
[*i
-1].command
);
132 xfree( filt
[*i
-1].id
);
139 * filter input file and return pointer to a pipe
141 FILE *filter_read(GraceApp
*gapp
, const char *fn
)
147 /* check if file name o.k. */
148 if( (in
=fopen( fn
, "rb")) == NULL
)
151 for( i
=0; i
<numIfilt
; i
++ )
152 if( ifilt
[i
].method
==FILTER_PATTERN
&& test_pattern(ifilt
[i
].id
, fn
))
154 else if( ifilt
[i
].method
==FILTER_MAGIC
&&
155 test_magic(ifilt
[i
].idlen
, ifilt
[i
].id
, in
) )
160 sprintf( buf
, ifilt
[i
].command
, fn
);
162 return popen(gapp_exe_path(gapp
, buf
), "r");
170 * filter output file and return pointer to a pipe or file
172 FILE *filter_write(GraceApp
*gapp
, const char *fn
)
178 /* check if file name o.k. */
179 if( (out
=fopen( fn
, "wb")) == NULL
)
182 /* see if we get a match */
183 for( i
=0; i
<numOfilt
; i
++ )
184 if( ofilt
[i
].method
==FILTER_PATTERN
&& test_pattern( ofilt
[i
].id
, fn
) )
186 else if( ofilt
[i
].method
==FILTER_MAGIC
&&
187 test_magic( ofilt
[i
].method
, ofilt
[i
].id
, out
) )
192 sprintf( buf
, ofilt
[i
].command
, fn
);
194 return popen(gapp_exe_path(gapp
, buf
), "w");
202 * test for a magic number
203 * if found at the beginning of the file, return 1
206 static int test_magic( int len
, const char *magic
, FILE *in
)
208 char buf
[512], rstr
[50];
213 sprintf( rstr
, "%%%dc", len
);
214 fscanf( in
, rstr
, buf
);
217 return !memcmp( buf
, magic
, len
);
221 * test for a pattern match
222 * if found return 1, else 0
224 static int test_pattern( char *ext
, const char *fn
)
226 #if defined(HAVE_FNMATCH)
227 return !fnmatch( ext
, fn
, 0 );
229 /* you are out of luck */
236 * convert hex string to character string interpreting 2 hex digits as 1
239 static void hex2char( Filter
*f
, const char *hex
)
246 for( i
=0; i
<strlen(hex
)/2; i
++ ) {
249 f
->id
[i
] = strtol( tmp
, &ptr
, 16 );
250 if( f
->id
[i
]==0 && ptr
==NULL
){