Moved the File selection dialog
[grace.git] / src / iofilters.c
blob46f02a651f9f002c35be73fb8144b05c61388c81
1 /*
2 * Grace - Graphics for Exploratory Data Analysis
3 *
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
5 *
6 * Copyright (c) 1991-95 Paul J Turner, Portland, OR
7 * Copyright (c) 1996-99 Grace Development Team
8 *
9 * Maintained by Evgeny Stambulchik
12 * All Rights Reserved
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
34 #include <config.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdlib.h>
40 #if defined(HAVE_FNMATCH)
41 # include <fnmatch.h>
42 #endif
44 #include "defines.h"
45 #include "utils.h"
46 #include "files.h"
48 typedef struct filter {
49 char *command;
50 int method;
51 char *id;
52 int idlen;
53 } Filter;
55 Filter *ifilt, *ofilt;
56 int numIfilt=0;
57 int numOfilt=0;
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 );
71 else
72 return 1;
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 );
89 } else {
90 ifilt[numIfilt-1].id = xmalloc(strlen(id)/2+1);
91 hex2char( &ifilt[numIfilt-1], id );
93 if( ifilt[numIfilt-1].idlen == 0 ) {
94 numIfilt--;
95 return 1;
96 } else
97 return 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;
109 return 0;
114 * eliminate filters:
115 * f = 0->output filters, f=1->input filters
117 void clear_io_filters( int f )
119 Filter *filt;
120 int *i;
122 if( f==FILTER_OUTPUT ){
123 i = &numOfilt;
124 filt = ofilt;
125 } else {
126 i = &numIfilt;
127 filt = ifilt;
130 for( ; *i>0; (*i)-- ) {
131 xfree( filt[*i-1].command );
132 xfree( filt[*i-1].id );
134 xfree(filt);
139 * filter input file and return pointer to a pipe
141 FILE *filter_read(GraceApp *gapp, const char *fn)
143 char buf[1024];
144 int i;
145 FILE *in;
147 /* check if file name o.k. */
148 if( (in=fopen( fn, "rb")) == NULL )
149 return NULL;
151 for( i=0; i<numIfilt; i++ )
152 if( ifilt[i].method==FILTER_PATTERN && test_pattern(ifilt[i].id, fn ))
153 break;
154 else if( ifilt[i].method==FILTER_MAGIC &&
155 test_magic(ifilt[i].idlen, ifilt[i].id, in ) )
156 break;
158 if( i != numIfilt ){
159 fclose( in );
160 sprintf( buf, ifilt[i].command, fn );
161 fflush( stdout );
162 return popen(gapp_exe_path(gapp, buf), "r");
163 } else {
164 return in;
170 * filter output file and return pointer to a pipe or file
172 FILE *filter_write(GraceApp *gapp, const char *fn)
174 char buf[1024];
175 int i;
176 FILE *out;
178 /* check if file name o.k. */
179 if( (out=fopen( fn, "wb")) == NULL )
180 return 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 ) )
185 break;
186 else if( ofilt[i].method==FILTER_MAGIC &&
187 test_magic( ofilt[i].method, ofilt[i].id, out ) )
188 break;
190 if( i != numOfilt ){
191 fclose( out );
192 sprintf( buf, ofilt[i].command, fn );
193 fflush( stdin );
194 return popen(gapp_exe_path(gapp, buf), "w");
195 } else {
196 return out;
202 * test for a magic number
203 * if found at the beginning of the file, return 1
204 * else 0
206 static int test_magic( int len, const char *magic, FILE *in )
208 char buf[512], rstr[50];
210 if( in == NULL )
211 return 0;
213 sprintf( rstr, "%%%dc", len );
214 fscanf( in, rstr, buf );
215 rewind( in );
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 );
228 #else
229 /* you are out of luck */
230 return 0;
231 #endif
236 * convert hex string to character string interpreting 2 hex digits as 1
237 * byte
239 static void hex2char( Filter *f, const char *hex )
241 unsigned int i;
242 char tmp[3], *ptr;
244 tmp[2] = '\0';
245 f->idlen = 0;
246 for( i=0; i<strlen(hex)/2; i++ ) {
247 tmp[0] = hex[2*i];
248 tmp[1] = hex[2*i+1];
249 f->id[i] = strtol( tmp, &ptr, 16 );
250 if( f->id[i]==0 && ptr==NULL ){
251 f->id[0] = '\0';
252 f->idlen = 0;
253 break;
254 } else
255 f->idlen++;
257 f->id[i] = '\0';