2 * FML interpreter. Europagate, 1995
5 * Revision 1.6 1995/03/27 12:49:51 adam
6 * Removed CFLAGS def. Bug fix (compile error when USE_GNU_REGEX=0).
8 * Revision 1.5 1995/03/02 08:06:07 adam
9 * Fml function strsub implemented. New test files marc[45].fml.
10 * New test options in fmltest.
12 * Revision 1.4 1995/02/27 09:01:21 adam
13 * Regular expression support. Argument passing by name option. New FML
16 * Revision 1.3 1995/02/23 08:32:06 adam
19 * Revision 1.1 1995/02/10 18:15:53 adam
20 * FML function 'strcmp' implemented. This function can be used to
21 * test for existence of MARC fields.
37 struct re_pattern_buffer buf;
39 struct reg_cache *next;
42 static int no_in_use = 0;
43 static struct reg_cache *reg_cache_list = NULL;
45 struct reg_cache *fml_reg_compile (const char *pattern)
47 struct reg_cache *list, *last = NULL;
48 for (list = reg_cache_list; list; list = list->next)
50 if (!strcmp (pattern, list->pattern))
56 for (list = reg_cache_list; list->next->next; list = list->next)
58 free (list->next->pattern);
59 regfree (&list->next->buf);
65 list = malloc (sizeof (*list));
67 list->next = reg_cache_list;
68 reg_cache_list = list;
69 list->pattern = malloc (strlen(pattern)+1);
70 assert (list->pattern);
71 strcpy (list->pattern, pattern);
73 re_syntax_options = RE_SYNTAX_GREP;
74 list->buf.translate = NULL;
75 list->buf.fastmap = NULL;
76 list->buf.buffer = NULL;
77 list->buf.allocated = 0;
78 re_compile_pattern (pattern, strlen(pattern), &list->buf);
82 static int fml_reg_match (struct reg_cache *reg_pat, const char *str)
84 int ret, len = strlen (str);
86 ret = re_match (®_pat->buf, str, len, 0, NULL);
92 static struct fml_node *fml_exec_match (Fml fml, struct fml_node **lp,
95 struct reg_cache *reg;
101 fml_cmd_lex (lp, tp);
105 fml_cmd_lex (lp, tp);
109 fn = fml_expr_term (fml, lp, tp);
112 fml_node_delete (fml, fn);
115 fml_atom_str (fn->p[0], pattern);
116 fml_node_delete (fml, fn);
119 reg = fml_reg_compile (cp);
120 fn = fml_expr_term (fml, lp, tp);
123 fml_node_delete (fml, fn);
126 fml_atom_str (fn->p[0], sstring);
127 fml_node_delete (fml, fn);
128 if (fml_reg_match (reg, sstring))
129 return fml_mk_node_val (fml, 1);
135 static struct fml_node *fml_exec_strlen (Fml fml, struct fml_node **lp,
141 fml_cmd_lex (lp, tp);
142 fn = fml_expr_term (fml, lp, tp);
146 len += fml_atom_len (fn->p[0]);
151 fml_node_delete (fml, fn);
152 return fml_mk_node_val (fml, len);
155 static struct fml_node *fml_exec_strsub (Fml fml, struct fml_node **lp,
158 struct fml_node *fn_str;
159 struct fml_node *fn_offset;
160 struct fml_node *fn_length;
161 struct fml_node *fn_res;
164 fml_cmd_lex (lp, tp);
165 fn_str = fml_expr_term (fml, lp, tp);
166 fn_offset = fml_expr_term (fml, lp, tp);
167 fn_length = fml_expr_term (fml, lp, tp);
168 if (!fn_offset->is_atom || !fn_length->is_atom || !fn_str->is_atom)
170 fml_node_delete (fml, fn_str);
171 fml_node_delete (fml, fn_offset);
172 fml_node_delete (fml, fn_length);
175 offset = fml_atom_val (fn_offset->p[0]);
176 fml_node_delete (fml, fn_offset);
177 length = fml_atom_val (fn_length->p[0]);
178 fml_node_delete (fml, fn_length);
179 if (offset == 0 && fml_atom_len (fn_str->p[0]) < length)
181 fn_res = fml_node_alloc (fml);
183 fn_res->p[0]= fml_atom_strsub (fml, fn_str->p[0], offset, length);
184 fml_node_delete (fml, fn_str);
188 static struct fml_node *fml_exec_strcmp (Fml fml, struct fml_node **lp,
192 struct fml_node *fn = NULL, *fn1, *fn2;
195 fml_cmd_lex (lp, tp);
197 fn1 = fml_expr_term (fml, lp, tp);
198 fn2 = fml_expr_term (fml, lp, tp);
199 if (!fn1->is_atom && !fn2->is_atom)
201 n = fml_atom_cmp (fml, fn1->p[0], fn2->p[0]);
208 fml_node_delete (fml, fn1);
209 fml_node_delete (fml, fn2);
210 fn = fml_node_alloc (fml);
212 fn->p[0] = fml_atom_alloc (fml, arg);
216 void fml_str_init (Fml fml)
218 struct fml_sym_info *sym_info;
220 sym_info = fml_sym_add (fml->sym_tab, "strcmp");
221 sym_info->kind = FML_CPREFIX;
222 sym_info->prefix = fml_exec_strcmp;
223 sym_info = fml_sym_add (fml->sym_tab, "strlen");
224 sym_info->kind = FML_CPREFIX;
225 sym_info->prefix = fml_exec_strlen;
226 sym_info = fml_sym_add (fml->sym_tab, "strsub");
227 sym_info->kind = FML_CPREFIX;
228 sym_info->prefix = fml_exec_strsub;
230 sym_info = fml_sym_add (fml->sym_tab, "match");
231 sym_info->kind = FML_CPREFIX;
232 sym_info->prefix = fml_exec_match;