2 * Copyright (c) 1995, the EUROPAGATE consortium (see below).
4 * The EUROPAGATE consortium members are:
6 * University College Dublin
7 * Danmarks Teknologiske Videnscenter
8 * An Chomhairle Leabharlanna
9 * Consejo Superior de Investigaciones Cientificas
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation, in whole or in part, for any purpose, is hereby granted,
15 * 1. This copyright and permission notice appear in all copies of the
16 * software and its documentation. Notices of copyright or attribution
17 * which appear at the beginning of any file must remain unchanged.
19 * 2. The names of EUROPAGATE or the project partners may not be used to
20 * endorse or promote products derived from this software without specific
21 * prior written permission.
23 * 3. Users of this software (implementors and gateway operators) agree to
24 * inform the EUROPAGATE consortium of their use of the software. This
25 * information will be used to evaluate the EUROPAGATE project and the
26 * software, and to plan further developments. The consortium may use
27 * the information in later publications.
29 * 4. Users of this software agree to make their best efforts, when
30 * documenting their use of the software, to acknowledge the EUROPAGATE
31 * consortium, and the role played by the software in their work.
33 * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
35 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
36 * IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
37 * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
38 * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
39 * OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
40 * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
41 * USE OR PERFORMANCE OF THIS SOFTWARE.
45 * FML interpreter. Europagate, 1995
48 * Revision 1.7 1995/05/16 09:39:34 adam
51 * Revision 1.6 1995/03/27 12:49:51 adam
52 * Removed CFLAGS def. Bug fix (compile error when USE_GNU_REGEX=0).
54 * Revision 1.5 1995/03/02 08:06:07 adam
55 * Fml function strsub implemented. New test files marc[45].fml.
56 * New test options in fmltest.
58 * Revision 1.4 1995/02/27 09:01:21 adam
59 * Regular expression support. Argument passing by name option. New FML
62 * Revision 1.3 1995/02/23 08:32:06 adam
65 * Revision 1.1 1995/02/10 18:15:53 adam
66 * FML function 'strcmp' implemented. This function can be used to
67 * test for existence of MARC fields.
83 struct re_pattern_buffer buf;
85 struct reg_cache *next;
88 static int no_in_use = 0;
89 static struct reg_cache *reg_cache_list = NULL;
91 struct reg_cache *fml_reg_compile (const char *pattern)
93 struct reg_cache *list, *last = NULL;
94 for (list = reg_cache_list; list; list = list->next)
96 if (!strcmp (pattern, list->pattern))
102 for (list = reg_cache_list; list->next->next; list = list->next)
104 free (list->next->pattern);
105 regfree (&list->next->buf);
111 list = malloc (sizeof (*list));
113 list->next = reg_cache_list;
114 reg_cache_list = list;
115 list->pattern = malloc (strlen(pattern)+1);
116 assert (list->pattern);
117 strcpy (list->pattern, pattern);
119 re_syntax_options = RE_SYNTAX_GREP;
120 list->buf.translate = NULL;
121 list->buf.fastmap = NULL;
122 list->buf.buffer = NULL;
123 list->buf.allocated = 0;
124 re_compile_pattern (pattern, strlen(pattern), &list->buf);
128 static int fml_reg_match (struct reg_cache *reg_pat, const char *str)
130 int ret, len = strlen (str);
132 ret = re_match (®_pat->buf, str, len, 0, NULL);
138 static struct fml_node *fml_exec_match (Fml fml, struct fml_node **lp,
141 struct reg_cache *reg;
147 fml_cmd_lex (lp, tp);
151 fml_cmd_lex (lp, tp);
155 fn = fml_expr_term (fml, lp, tp);
158 fml_node_delete (fml, fn);
161 fml_atom_str (fn->p[0], pattern);
162 fml_node_delete (fml, fn);
165 reg = fml_reg_compile (cp);
166 fn = fml_expr_term (fml, lp, tp);
169 fml_node_delete (fml, fn);
172 fml_atom_str (fn->p[0], sstring);
173 fml_node_delete (fml, fn);
174 if (fml_reg_match (reg, sstring))
175 return fml_mk_node_val (fml, 1);
181 static struct fml_node *fml_exec_strlen (Fml fml, struct fml_node **lp,
187 fml_cmd_lex (lp, tp);
188 fn = fml_expr_term (fml, lp, tp);
192 len += fml_atom_len (fn->p[0]);
197 fml_node_delete (fml, fn);
198 return fml_mk_node_val (fml, len);
201 static struct fml_node *fml_exec_strsub (Fml fml, struct fml_node **lp,
204 struct fml_node *fn_str;
205 struct fml_node *fn_offset;
206 struct fml_node *fn_length;
207 struct fml_node *fn_res;
210 fml_cmd_lex (lp, tp);
211 fn_str = fml_expr_term (fml, lp, tp);
212 fn_offset = fml_expr_term (fml, lp, tp);
213 fn_length = fml_expr_term (fml, lp, tp);
214 if (!fn_offset->is_atom || !fn_length->is_atom || !fn_str->is_atom)
216 fml_node_delete (fml, fn_str);
217 fml_node_delete (fml, fn_offset);
218 fml_node_delete (fml, fn_length);
221 offset = fml_atom_val (fn_offset->p[0]);
222 fml_node_delete (fml, fn_offset);
223 length = fml_atom_val (fn_length->p[0]);
224 fml_node_delete (fml, fn_length);
225 if (offset == 0 && fml_atom_len (fn_str->p[0]) < length)
227 fn_res = fml_node_alloc (fml);
229 fn_res->p[0]= fml_atom_strsub (fml, fn_str->p[0], offset, length);
230 fml_node_delete (fml, fn_str);
234 static struct fml_node *fml_exec_strcmp (Fml fml, struct fml_node **lp,
238 struct fml_node *fn = NULL, *fn1, *fn2;
241 fml_cmd_lex (lp, tp);
243 fn1 = fml_expr_term (fml, lp, tp);
244 fn2 = fml_expr_term (fml, lp, tp);
245 if (!fn1->is_atom && !fn2->is_atom)
247 n = fml_atom_cmp (fml, fn1->p[0], fn2->p[0]);
254 fml_node_delete (fml, fn1);
255 fml_node_delete (fml, fn2);
256 fn = fml_node_alloc (fml);
258 fn->p[0] = fml_atom_alloc (fml, arg);
262 void fml_str_init (Fml fml)
264 struct fml_sym_info *sym_info;
266 sym_info = fml_sym_add (fml->sym_tab, "strcmp");
267 sym_info->kind = FML_CPREFIX;
268 sym_info->prefix = fml_exec_strcmp;
269 sym_info = fml_sym_add (fml->sym_tab, "strlen");
270 sym_info->kind = FML_CPREFIX;
271 sym_info->prefix = fml_exec_strlen;
272 sym_info = fml_sym_add (fml->sym_tab, "strsub");
273 sym_info->kind = FML_CPREFIX;
274 sym_info->prefix = fml_exec_strsub;
276 sym_info = fml_sym_add (fml->sym_tab, "match");
277 sym_info->kind = FML_CPREFIX;
278 sym_info->prefix = fml_exec_match;