--- tromey_at_busco.lanl.gov Member, League for Programming Freedom /* * sregexp.c -- Regular expressions for STk. * tromey Fri Jul 22 1994 * */ /* TO DO: * Write regexp-quote. */ #include <stk.h> #include "tclRegexp.h" /* * Regular expression type. A regular expression is a function that * takes one argument. It returns #f if no match, or a regular * expression match object on match. */ static void free_regexp (SCM ht); static SCM apply_regexp (SCM x, SCM args, SCM env); static int tc_regexp; static extended_scheme_type regexp_type = { "regexp", /* name */ EXT_ISPROC | EXT_EVALPARAM, /* flags */ NULL, /* gc_mark_fct */ free_regexp, /* gc_sweep_fct */ apply_regexp, /* apply_fct */ NULL /* display_fct */ }; #define REGEXP(x) ((struct regexp *) ((x)->storage_as.extension.data)) #define REGEXPP(x) (TYPEP ((x), tc_regexp)) /* * Regular expression match object. It can be queried to get * sub-match information. */ static void free_regmatch (SCM ht); static int tc_regmatch; static extended_scheme_type regmatch_type = { "regmatch", /* name */ 0, /* flags */ NULL, /* gc_mark_fct */ free_regmatch, /* gc_sweep_fct */ NULL, /* apply_fct */ NULL /* display_fct */ }; struct re_registers { int number; /* Number of matches. */ int startp[NSUBEXP]; /* Start indices. */ int endp[NSUBEXP]; /* End indices. */ }; #define REGMATCH(x) ((struct re_registers *) ((x)->storage_as.extension.data)) #define REGMATCHP(x) (TYPEP ((x), tc_regmatch)) /* * Return #t if object is a regexp, #f otherwise. */ static PRIMITIVE regexp_p (SCM obj) { return (REGEXPP (obj) ? truth : ntruth); } /* * Return compiled form of regexp represented by string. Error if not * a string, or if regexp has a syntax error. */ static PRIMITIVE string_to_regexp (SCM obj) { SCM result; if (NSTRINGP (obj)) err ("not a string", obj); NEWCELL (result, tc_regexp); REGEXP (result) = TclRegComp (CHARS (obj)); if (REGEXP (result) == NULL) { /* FIXME use Tcl error message. */ err ("error compiling regexp", obj); } return (result); } /* * Try to match string against regular expression. Returns sub-match * object, or #f if no match. */ static PRIMITIVE apply_regexp (SCM regexp, SCM l, SCM env) { int match, number, length; struct re_registers *matches; SCM result, string; char *the_chars; length = llength (l); if (length != 1) err ("bad number of args", l); string = CAR (l); if (!REGEXPP (regexp)) err ("not a regular expression", regexp); if (NSTRINGP (string)) err ("not a string", string); the_chars = CHARS (string); match = TclRegExec (REGEXP (regexp), the_chars, CHARS (string)); if (match) { matches = must_malloc (sizeof (struct re_registers)); for (number = 0; REGEXP (regexp)->startp[number] != NULL; ++number) { matches->startp[number] = (REGEXP (regexp)->startp[number] - the_chars); matches->endp[number] = (REGEXP (regexp)->endp[number] - the_chars); } matches->number = number; NEWCELL (result, tc_regmatch); REGMATCH (result) = matches; } else result = ntruth; return (result); } /* * Is object a regmatch? */ static PRIMITIVE regmatch_p (SCM obj) { return (REGMATCHP (obj) ? truth : ntruth); } /* * Return number of submatches. */ static PRIMITIVE regmatch_size (SCM rm) { if (!REGMATCHP (rm)) err ("not a regular expression match", rm); return (makeinteger (REGMATCH (rm)->number)); } /* * Return nth start index of regmatch. */ static PRIMITIVE regmatch_start (SCM rm, SCM n) { int val; if (!REGMATCHP (rm)) err ("not a regular expression match", rm); if (NINTEGERP (n)) err ("not an integer", n); val = INTEGER (n); if (val >= REGMATCH (rm)->number) err ("match index out of bounds", n); return (makeinteger (REGMATCH (rm)->startp[val])); } /* * Return nth end index of regmatch. */ static PRIMITIVE regmatch_end (SCM rm, SCM n) { int val; if (!REGMATCHP (rm)) err ("not a regular expression match", rm); if (NINTEGERP (n)) err ("not an integer", n); val = INTEGER (n); if (val >= REGMATCH (rm)->number) err ("match index out of bounds", n); return (makeinteger (REGMATCH (rm)->endp[val])); } /* * GC interface. */ static void free_regexp (SCM reg) { free (REGEXP (reg)); } static void free_regmatch (SCM reg) { free (REGMATCH (reg)); } /* * Initialization. */ PRIMITIVE init_sregexp (void) { tc_regexp = add_new_type (®exp_type); tc_regmatch = add_new_type (®match_type); add_new_primitive ("regexp?", tc_subr_1, regexp_p); add_new_primitive ("string->regexp", tc_subr_1, string_to_regexp); add_new_primitive ("regmatch?", tc_subr_1, regmatch_p); /* These are named oddly for similarity with Emacs. FIXME? */ add_new_primitive ("match-length", tc_subr_1, regmatch_size); add_new_primitive ("match-beginning", tc_subr_2, regmatch_start); add_new_primitive ("match-end", tc_subr_2, regmatch_end); return (UNDEFINED); }Received on Sat Sep 24 1994 - 23:13:34 CEST
This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST