1996-09-27 06:29:02 -04:00
|
|
|
/*
|
|
|
|
* sregexp.c -- Regular expressions for STk.
|
|
|
|
* tromey Fri Jul 22 1994
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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 STk_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 */
|
|
|
|
NULL /* compare_fct */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define REGEXP(x) ((struct regexp *) (x)->storage_as.extension.data)
|
|
|
|
#define REGEXPP(x) (TYPEP((x), tc_regexp))
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GC interface.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void free_regexp (SCM reg)
|
|
|
|
{
|
|
|
|
free (REGEXP (reg));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
|
|
|
struct regexp *r;
|
|
|
|
SCM z;
|
|
|
|
|
1998-06-09 07:07:40 -04:00
|
|
|
ENTER_PRIMITIVE("string->regexp");
|
1996-09-27 06:29:02 -04:00
|
|
|
|
1998-06-09 07:07:40 -04:00
|
|
|
if (NSTRINGP (obj)) Serror("not a string", obj);
|
|
|
|
if ((r=TclRegComp(CHARS (obj))) == NULL) Serror("error compiling regexp", obj);
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
|
|
/* Regexp is Ok. Make a new cell and return it */
|
|
|
|
NEWCELL(z, tc_regexp);
|
|
|
|
z->storage_as.extension.data = (void *) r;
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to match string against regular expression. Returns sub-match
|
|
|
|
* object, or #f if no match.
|
|
|
|
*/
|
1998-06-09 07:07:40 -04:00
|
|
|
static SCM apply_regexp(SCM regexp, SCM l, SCM env)
|
1996-09-27 06:29:02 -04:00
|
|
|
{
|
|
|
|
SCM string;
|
|
|
|
char *the_chars;
|
|
|
|
|
1998-06-09 07:07:40 -04:00
|
|
|
ENTER_SCM("apply-regexp");
|
|
|
|
|
|
|
|
if (STk_llength (l) != 1) Serror("bad number of args", l);
|
1996-09-27 06:29:02 -04:00
|
|
|
string = CAR (l);
|
|
|
|
|
1998-06-09 07:07:40 -04:00
|
|
|
if (NSTRINGP (string)) Serror("bad string", string);
|
1996-09-27 06:29:02 -04:00
|
|
|
the_chars = CHARS (string);
|
|
|
|
|
|
|
|
if (TclRegExec(REGEXP(regexp), the_chars, the_chars)) {
|
|
|
|
struct regexp *r = REGEXP(regexp);
|
|
|
|
SCM z = NIL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* Find the length of the result */
|
|
|
|
for (i=0; r->startp[i]; i++) {/*Nothing*/}
|
|
|
|
|
|
|
|
/* Build result */
|
|
|
|
for (--i; i >= 0; i--) {
|
|
|
|
z = Cons(LIST2(STk_makeinteger(r->startp[i]-the_chars),
|
|
|
|
STk_makeinteger(r->endp[i]-the_chars)),
|
|
|
|
z);
|
|
|
|
}
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
return Ntruth;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialization.
|
|
|
|
*/
|
|
|
|
|
|
|
|
PRIMITIVE STk_init_sregexp(void)
|
|
|
|
{
|
|
|
|
tc_regexp = STk_add_new_type (®exp_type);
|
|
|
|
|
|
|
|
STk_add_new_primitive ("string->regexp", tc_subr_1, string_to_regexp);
|
|
|
|
STk_add_new_primitive ("regexp?", tc_subr_1, regexp_p);
|
|
|
|
return UNDEFINED;
|
|
|
|
}
|