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.8 2001/02/26 14:32:36 adam
49 * Updated for YAZ 1.7. HTML output tidy up. Added LOC target.
51 * Revision 1.7 1995/05/16 09:39:34 adam
54 * Revision 1.6 1995/03/27 12:49:51 adam
55 * Removed CFLAGS def. Bug fix (compile error when USE_GNU_REGEX=0).
57 * Revision 1.5 1995/03/02 08:06:07 adam
58 * Fml function strsub implemented. New test files marc[45].fml.
59 * New test options in fmltest.
61 * Revision 1.4 1995/02/27 09:01:21 adam
62 * Regular expression support. Argument passing by name option. New FML
65 * Revision 1.3 1995/02/23 08:32:06 adam
68 * Revision 1.1 1995/02/10 18:15:53 adam
69 * FML function 'strcmp' implemented. This function can be used to
70 * test for existence of MARC fields.
87 struct re_pattern_buffer buf;
89 struct reg_cache *next;
92 static int no_in_use = 0;
93 static struct reg_cache *reg_cache_list = NULL;
95 struct reg_cache *fml_reg_compile (const char *pattern)
97 struct reg_cache *list, *last = NULL;
98 for (list = reg_cache_list; list; list = list->next)
100 if (!strcmp (pattern, list->pattern))
106 for (list = reg_cache_list; list->next->next; list = list->next)
108 free (list->next->pattern);
109 regfree (&list->next->buf);
115 list = malloc (sizeof (*list));
117 list->next = reg_cache_list;
118 reg_cache_list = list;
119 list->pattern = malloc (strlen(pattern)+1);
120 assert (list->pattern);
121 strcpy (list->pattern, pattern);
123 re_syntax_options = RE_SYNTAX_GREP;
124 list->buf.translate = NULL;
125 list->buf.fastmap = NULL;
126 list->buf.buffer = NULL;
127 list->buf.allocated = 0;
128 re_compile_pattern (pattern, strlen(pattern), &list->buf);
132 static int fml_reg_match (struct reg_cache *reg_pat, const char *str)
134 int ret, len = strlen (str);
136 ret = re_match (®_pat->buf, str, len, 0, NULL);
142 static struct fml_node *fml_exec_match (Fml fml, struct fml_node **lp,
145 struct reg_cache *reg;
151 fml_cmd_lex (lp, tp);
155 fml_cmd_lex (lp, tp);
159 fn = fml_expr_term (fml, lp, tp);
162 fml_node_delete (fml, fn);
165 fml_atom_str (fn->p[0], pattern);
166 fml_node_delete (fml, fn);
169 reg = fml_reg_compile (cp);
170 fn = fml_expr_term (fml, lp, tp);
173 fml_node_delete (fml, fn);
176 fml_atom_str (fn->p[0], sstring);
177 fml_node_delete (fml, fn);
178 if (fml_reg_match (reg, sstring))
179 return fml_mk_node_val (fml, 1);
185 static struct fml_node *fml_exec_strlen (Fml fml, struct fml_node **lp,
191 fml_cmd_lex (lp, tp);
192 fn = fml_expr_term (fml, lp, tp);
196 len += fml_atom_len (fn->p[0]);
201 fml_node_delete (fml, fn);
202 return fml_mk_node_val (fml, len);
205 static struct fml_node *fml_exec_strsub (Fml fml, struct fml_node **lp,
208 struct fml_node *fn_str;
209 struct fml_node *fn_offset;
210 struct fml_node *fn_length;
211 struct fml_node *fn_res;
214 fml_cmd_lex (lp, tp);
215 fn_str = fml_expr_term (fml, lp, tp);
216 fn_offset = fml_expr_term (fml, lp, tp);
217 fn_length = fml_expr_term (fml, lp, tp);
218 if (!fn_offset->is_atom || !fn_length->is_atom || !fn_str->is_atom)
220 fml_node_delete (fml, fn_str);
221 fml_node_delete (fml, fn_offset);
222 fml_node_delete (fml, fn_length);
225 offset = fml_atom_val (fn_offset->p[0]);
226 fml_node_delete (fml, fn_offset);
227 length = fml_atom_val (fn_length->p[0]);
228 fml_node_delete (fml, fn_length);
229 if (offset == 0 && fml_atom_len (fn_str->p[0]) < length)
231 fn_res = fml_node_alloc (fml);
233 fn_res->p[0]= fml_atom_strsub (fml, fn_str->p[0], offset, length);
234 fml_node_delete (fml, fn_str);
238 static struct fml_node *fml_exec_strcmp (Fml fml, struct fml_node **lp,
242 struct fml_node *fn = NULL, *fn1, *fn2;
245 fml_cmd_lex (lp, tp);
247 fn1 = fml_expr_term (fml, lp, tp);
248 fn2 = fml_expr_term (fml, lp, tp);
249 if (!fn1->is_atom && !fn2->is_atom)
251 n = fml_atom_cmp (fml, fn1->p[0], fn2->p[0]);
258 fml_node_delete (fml, fn1);
259 fml_node_delete (fml, fn2);
260 fn = fml_node_alloc (fml);
262 fn->p[0] = fml_atom_alloc (fml, arg);
266 void fml_str_init (Fml fml)
268 struct fml_sym_info *sym_info;
270 sym_info = fml_sym_add (fml->sym_tab, "strcmp");
271 sym_info->kind = FML_CPREFIX;
272 sym_info->prefix = fml_exec_strcmp;
273 sym_info = fml_sym_add (fml->sym_tab, "strlen");
274 sym_info->kind = FML_CPREFIX;
275 sym_info->prefix = fml_exec_strlen;
276 sym_info = fml_sym_add (fml->sym_tab, "strsub");
277 sym_info->kind = FML_CPREFIX;
278 sym_info->prefix = fml_exec_strsub;
280 sym_info = fml_sym_add (fml->sym_tab, "match");
281 sym_info->kind = FML_CPREFIX;
282 sym_info->prefix = fml_exec_match;