2 * FML interpreter. Europagate, 1995
5 * Revision 1.5 1995/03/02 08:06:07 adam
6 * Fml function strsub implemented. New test files marc[45].fml.
7 * New test options in fmltest.
9 * Revision 1.4 1995/02/27 09:01:21 adam
10 * Regular expression support. Argument passing by name option. New FML
13 * Revision 1.3 1995/02/23 08:32:06 adam
16 * Revision 1.1 1995/02/10 18:15:53 adam
17 * FML function 'strcmp' implemented. This function can be used to
18 * test for existence of MARC fields.
34 struct re_pattern_buffer buf;
36 struct reg_cache *next;
39 static int no_in_use = 0;
40 static struct reg_cache *reg_cache_list = NULL;
42 struct reg_cache *fml_reg_compile (const char *pattern)
44 struct reg_cache *list, *last = NULL;
45 for (list = reg_cache_list; list; list = list->next)
47 if (!strcmp (pattern, list->pattern))
53 for (list = reg_cache_list; list->next->next; list = list->next)
55 free (list->next->pattern);
56 regfree (&list->next->buf);
62 list = malloc (sizeof (*list));
64 list->next = reg_cache_list;
65 reg_cache_list = list;
66 list->pattern = malloc (strlen(pattern)+1);
67 assert (list->pattern);
68 strcpy (list->pattern, pattern);
70 re_syntax_options = RE_SYNTAX_GREP;
71 list->buf.translate = NULL;
72 list->buf.fastmap = NULL;
73 list->buf.buffer = NULL;
74 list->buf.allocated = 0;
75 re_compile_pattern (pattern, strlen(pattern), &list->buf);
79 static int fml_reg_match (struct reg_cache *reg_pat, const char *str)
81 int ret, len = strlen (str);
83 ret = re_match (®_pat->buf, str, len, 0, NULL);
91 static struct fml_node *fml_exec_match (Fml fml, struct fml_node **lp,
94 struct reg_cache *reg;
100 fml_cmd_lex (lp, tp);
104 fml_cmd_lex (lp, tp);
108 fn = fml_expr_term (fml, lp, tp);
111 fml_node_delete (fml, fn);
114 fml_atom_str (fn->p[0], pattern);
115 fml_node_delete (fml, fn);
118 reg = fml_reg_compile (cp);
119 fn = fml_expr_term (fml, lp, tp);
122 fml_node_delete (fml, fn);
125 fml_atom_str (fn->p[0], sstring);
126 fml_node_delete (fml, fn);
127 if (fml_reg_match (reg, sstring))
128 return fml_mk_node_val (fml, 1);
132 static struct fml_node *fml_exec_strlen (Fml fml, struct fml_node **lp,
138 fml_cmd_lex (lp, tp);
139 fn = fml_expr_term (fml, lp, tp);
143 len += fml_atom_len (fn->p[0]);
148 fml_node_delete (fml, fn);
149 return fml_mk_node_val (fml, len);
152 static struct fml_node *fml_exec_strsub (Fml fml, struct fml_node **lp,
155 struct fml_node *fn_str;
156 struct fml_node *fn_offset;
157 struct fml_node *fn_length;
158 struct fml_node *fn_res;
161 fml_cmd_lex (lp, tp);
162 fn_str = fml_expr_term (fml, lp, tp);
163 fn_offset = fml_expr_term (fml, lp, tp);
164 fn_length = fml_expr_term (fml, lp, tp);
165 if (!fn_offset->is_atom || !fn_length->is_atom || !fn_str->is_atom)
167 fml_node_delete (fml, fn_str);
168 fml_node_delete (fml, fn_offset);
169 fml_node_delete (fml, fn_length);
172 offset = fml_atom_val (fn_offset->p[0]);
173 fml_node_delete (fml, fn_offset);
174 length = fml_atom_val (fn_length->p[0]);
175 fml_node_delete (fml, fn_length);
176 if (offset == 0 && fml_atom_len (fn_str->p[0]) < length)
178 fn_res = fml_node_alloc (fml);
180 fn_res->p[0]= fml_atom_strsub (fml, fn_str->p[0], offset, length);
181 fml_node_delete (fml, fn_str);
185 static struct fml_node *fml_exec_strcmp (Fml fml, struct fml_node **lp,
189 struct fml_node *fn = NULL, *fn1, *fn2;
192 fml_cmd_lex (lp, tp);
194 fn1 = fml_expr_term (fml, lp, tp);
195 fn2 = fml_expr_term (fml, lp, tp);
196 if (!fn1->is_atom && !fn2->is_atom)
198 n = fml_atom_cmp (fml, fn1->p[0], fn2->p[0]);
205 fml_node_delete (fml, fn1);
206 fml_node_delete (fml, fn2);
207 fn = fml_node_alloc (fml);
209 fn->p[0] = fml_atom_alloc (fml, arg);
213 void fml_str_init (Fml fml)
215 struct fml_sym_info *sym_info;
217 sym_info = fml_sym_add (fml->sym_tab, "strcmp");
218 sym_info->kind = FML_CPREFIX;
219 sym_info->prefix = fml_exec_strcmp;
220 sym_info = fml_sym_add (fml->sym_tab, "strlen");
221 sym_info->kind = FML_CPREFIX;
222 sym_info->prefix = fml_exec_strlen;
223 sym_info = fml_sym_add (fml->sym_tab, "strsub");
224 sym_info->kind = FML_CPREFIX;
225 sym_info->prefix = fml_exec_strsub;
227 sym_info = fml_sym_add (fml->sym_tab, "match");
228 sym_info->kind = FML_CPREFIX;
229 sym_info->prefix = fml_exec_match;