name change
[metze/wireshark/wip.git] / epan / ftypes / ftype-pcre.c
1 /*
2  * $Id$
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 2001 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  */
22
23 /* Perl-Compatible Regular Expression (PCRE) internal field type.
24  * Used with the "matches" dfilter operator, allowing efficient
25  * compilation and studying of a PCRE pattern in dfilters.
26  *
27  * PCRE is provided with libpcre (http://www.pcre.org/).
28  */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <ftypes-int.h>
35
36 #ifdef HAVE_LIBPCRE
37
38 #include <string.h>
39
40 #include <pcre.h>
41
42 /* Create a pcre_tuple_t object based on the given string pattern */ 
43 static pcre_tuple_t *
44 pcre_tuple_new(const char *value)
45 {
46         pcre_tuple_t *tuple;
47         const char *pcre_error_text;
48         int pcre_error_offset;
49
50         tuple = g_malloc(sizeof(pcre_tuple_t));
51         tuple->string = g_strdup(value); /* The RE as string */
52         tuple->ex = NULL;
53         /* Compile the RE */
54         tuple->re = pcre_compile(
55                         value,                          /* pattern */
56                         0,                                      /* PCRE options */
57                         &pcre_error_text,       /* PCRE constant error string */
58                         &pcre_error_offset,     /* Start offset of error in pattern */
59                         NULL                            /* Default char tables (C locale) */
60                         );
61         if (pcre_error_text) {
62                 tuple->error = g_strdup_printf("In regular expression \"%s\":\n"
63                                 "%s (character position %d)",
64                                 value, pcre_error_text, pcre_error_offset);
65                 return tuple;
66         } else {
67                 tuple->error = NULL;
68         }
69         /* Study the RE */
70         tuple->ex = pcre_study(tuple->re, 0, &pcre_error_text);
71         if (pcre_error_text) {
72                 if (tuple->error) {
73                         tuple->error = g_strdup_printf("In regular expression \"%s\":\n"
74                                         "%s. %s",
75                                         value, tuple->error, pcre_error_text);
76                 } else {
77                         tuple->error = g_strdup_printf("In regular expression \"%s\":\n"
78                                         "%s",
79                                         value, pcre_error_text);
80                 }
81         }
82         return tuple;
83 }
84
85 static void
86 pcre_tuple_free(pcre_tuple_t *tuple)
87 {
88         if (tuple) {
89                 if (tuple->string) g_free(tuple->string);
90                 if (tuple->re) g_free(tuple->re);
91                 if (tuple->ex) g_free(tuple->ex);
92                 if (tuple->error) g_free(tuple->error);
93                 g_free(tuple);
94         }
95 }
96
97 static void
98 pcre_fvalue_new(fvalue_t *fv)
99 {
100         fv->value.re = NULL;
101 }
102
103 static void
104 pcre_fvalue_free(fvalue_t *fv)
105 {
106         if (fv->value.re) {
107                 pcre_tuple_free(fv->value.re);
108         }
109 }
110
111 /* Generate a FT_PCRE from a parsed string pattern.
112  * Uses the specified logfunc() to report errors. */
113 static gboolean
114 val_from_string(fvalue_t *fv, char *pattern, LogFunc logfunc)
115 {
116         /* Free up the old value, if we have one */
117         pcre_fvalue_free(fv);
118
119         fv->value.re = pcre_tuple_new(pattern);
120         if (fv->value.re->error) {
121                 logfunc(fv->value.re->error);
122                 return FALSE;
123         }
124         return TRUE;
125 }
126
127 /* Generate a FT_PCRE from an unparsed string pattern.
128  * Uses the specified logfunc() to report errors. */
129 static gboolean
130 val_from_unparsed(fvalue_t *fv, char *pattern, gboolean allow_partial_value _U_, LogFunc logfunc)
131 {
132         /* Free up the old value, if we have one */
133         pcre_fvalue_free(fv);
134         g_assert(! allow_partial_value);
135
136         fv->value.re = pcre_tuple_new(pattern);
137         if (fv->value.re->error) {
138                 logfunc(fv->value.re->error);
139                 return FALSE;
140         }
141         return TRUE;
142 }
143
144 static int
145 pcre_repr_len(fvalue_t *fv, ftrepr_t rtype)
146 {
147         g_assert(rtype == FTREPR_DFILTER);
148         return strlen(fv->value.re->string);
149 }
150
151 static void
152 pcre_to_repr(fvalue_t *fv, ftrepr_t rtype, char *buf)
153 {
154         g_assert(rtype == FTREPR_DFILTER);
155         strcpy(buf, fv->value.re->string);
156 }
157
158 /* BEHOLD - value contains the string representation of the regular expression,
159  * and we want to store the compiled PCRE RE object into the value. */
160 static void
161 pcre_fvalue_set(fvalue_t *fv, gpointer value, gboolean already_copied)
162 {
163         g_assert(value != NULL);
164         /* Free up the old value, if we have one */
165         pcre_fvalue_free(fv);
166         g_assert(! already_copied);
167         fv->value.re = pcre_tuple_new(value);
168 }
169
170 static gpointer
171 pcre_fvalue_get(fvalue_t *fv)
172 {
173         return fv->value.re;
174 }
175
176 void
177 ftype_register_pcre(void)
178 {
179         static ftype_t pcre_type = {
180                 FT_PCRE,                /* ftype */
181                 "FT_PCRE",              /* name */
182                 "Compiled Perl-Compatible Regular Expression object", /* pretty_name */
183                 0,                      /* wire_size */
184                 pcre_fvalue_new,        /* new_value */
185                 pcre_fvalue_free,       /* free_value */
186                 val_from_unparsed,      /* val_from_unparsed */
187                 val_from_string,        /* val_from_string */
188                 pcre_to_repr,           /* val_to_string_repr */
189                 pcre_repr_len,          /* len_string_repr */
190
191                 pcre_fvalue_set,        /* set_value */
192                 NULL,                   /* set_value_integer */
193                 NULL,                   /* set_value_integer64 */
194                 NULL,                   /* set_value_floating */
195
196                 pcre_fvalue_get,        /* get_value */
197                 NULL,                   /* get_value_integer */
198                 NULL,                   /* get_value_integer64 */
199                 NULL,                   /* get_value_floating */
200
201                 NULL,                   /* cmp_eq */
202                 NULL,                   /* cmp_ne */
203                 NULL,                   /* cmp_gt */
204                 NULL,                   /* cmp_ge */
205                 NULL,                   /* cmp_lt */
206                 NULL,                   /* cmp_le */
207                 NULL,                   /* cmp_bitwise_and */
208                 NULL,                   /* cmp_contains */
209                 NULL,                   /* cmp_matches */
210
211                 NULL,                   /* len */
212                 NULL,                   /* slice */
213         };
214         ftype_register(FT_PCRE, &pcre_type);
215 }
216
217 #else /* HAVE_LIBPCRE */
218
219 void
220 ftype_register_pcre(void)
221 {
222         static ftype_t pcre_type = {
223                 FT_PCRE,                /* ftype */
224                 "FT_PCRE",                      /* name */
225                 "Compiled Perl-Compatible Regular Expression object", /* pretty_name */
226                 0,                              /* wire_size */
227                 NULL,                           /* new_value */
228                 NULL,                           /* free_value */
229                 NULL,                           /* val_from_unparsed */
230                 NULL,                           /* val_from_string */
231                 NULL,                           /* val_to_string_repr */
232                 NULL,                           /* len_string_repr */
233
234                 NULL,                           /* set_value */
235                 NULL,                           /* set_value_integer */
236                 NULL,                           /* set_value_integer64 */
237                 NULL,                           /* set_value_floating */
238
239                 NULL,                           /* get_value */
240                 NULL,                           /* get_value_integer */
241                 NULL,                           /* get_value_integer64 */
242                 NULL,                           /* get_value_floating */ 
243
244                 NULL,                           /* cmp_eq */
245                 NULL,                           /* cmp_ne */
246                 NULL,                           /* cmp_gt */
247                 NULL,                           /* cmp_ge */
248                 NULL,                           /* cmp_lt */
249                 NULL,                           /* cmp_le */
250                 NULL,                           /* cmp_bitwise_and */
251                 NULL,                           /* cmp_contains */
252                 NULL,                           /* cmp_matches */
253
254                 NULL,                           /* len */
255                 NULL,                           /* slice */
256         };
257         ftype_register(FT_PCRE, &pcre_type);
258 }
259
260 #endif /* HAVE_LIBPCRE */