How do I call a regex from C?

Hi:

I need to call a regex from C, but haven’t quite figured
it out. Does someone have some sample code they can share?

If I use rb_funcall, Do I have to make two calls? One
to create the regex and one to apply it?
Is there a faster way?

Thanks

···


Jim Freeze

If you live in a country run by committee, be on the committee.
– Graham Summer

If I use rb_funcall, Do I have to make two calls? One
to create the regex and one to apply it?
Is there a faster way?

It really depend what call you want to do.

For example, String#sub can take a String or a Regexp as the first
argument. You can call Regexp::new (via rb_funcall)

To create a regexp you have also rb_reg_regcomp(VALUE). You can use
perhaps also rb_reg_match()

Guy Decoux

Ok, this is what I have done so far:

static VALUE re_equal;

in_some_init_func() {
re_equal = rb_reg_regcomp(“\s*=\s”);
re_space = rb_reg_regcomp(“\s+”);
}

in_main_loop() {
VALUE sp = rb_str_new2(" ");

// I don’t think this is allowed -------v
rb_funcall(line, “gsub!”, 2, re_equal, “=”)

// should probably be this.
rb_funcall(line, “gsub!”, 2, re_equal, sp)
}

If I just want to replace with a character, is there
a faster way than to create a string object?

What if I want to replace with an empty string “”?

Thanks

···

On Monday, 14 April 2003 at 23:25:03 +0900, ts wrote:

If I use rb_funcall, Do I have to make two calls? One
to create the regex and one to apply it?
Is there a faster way?

It really depend what call you want to do.

For example, String#sub can take a String or a Regexp as the first
argument. You can call Regexp::new (via rb_funcall)

To create a regexp you have also rb_reg_regcomp(VALUE). You can use
perhaps also rb_reg_match()

Guy Decoux


Jim Freeze

HOW YOU CAN TELL THAT IT’S GOING TO BE A ROTTEN DAY:

#32: You call your answering service and they've never heard of
     you.

To create a regexp you have also rb_reg_regcomp(VALUE). You can use
perhaps also rb_reg_match()

Guy Decoux

Ok, this is what I have done so far:

static VALUE re_equal;

in_some_init_func() {
re_equal = rb_reg_regcomp(“\s*=\s”);
re_space = rb_reg_regcomp(“\s+”);
}

The argument to rb_reg_regcomp is a VALUE, not a C null-terminated string.

If I just want to replace with a character, is there
a faster way than to create a string object?

If you create string objects at initialisation time then you don’t have to
worry about the overhead, just use them when required.

B.

···

On Mon, Apr 14, 2003 at 11:56:45PM +0900, Jim Freeze wrote:

// I don't think this is allowed -------v
rb_funcall(line, "gsub!", 2, re_equal, "=")

not allowed : you must give only VALUE

// should probably be this.
rb_funcall(line, "gsub!", 2, re_equal, sp)

yes, this must work if you replace "gsub!" with rb_intern("gsub!")

What if I want to replace with an empty string ""?

   rb_str_new2("")

Guy Decoux

Cool. Ok, I can do all that. However, the following aborts:

re_equal = rb_reg_regcomp(“\s*=\s”);
re_space = rb_reg_regcomp(“\s+”);

···

On Tuesday, 15 April 2003 at 0:06:08 +0900, ts wrote:

// I don’t think this is allowed -------v
rb_funcall(line, “gsub!”, 2, re_equal, “=”)

not allowed : you must give only VALUE

// should probably be this.
rb_funcall(line, “gsub!”, 2, re_equal, sp)

yes, this must work if you replace “gsub!” with rb_intern(“gsub!”)

What if I want to replace with an empty string “”?

rb_str_new2(“”)


Jim Freeze

Fourth Law of Revision:
It is usually impractical to worry beforehand about
interferences – if you have none, someone will make one for you.

  re_equal = rb_reg_regcomp("\\s*=\\s");
  re_space = rb_reg_regcomp("\\s+");

See [ruby-talk:69375], you must give a VALUE (rb_str_new2()), not a string

p.s. : I hope that re_equal and re_space are protected against the GC

Guy Decoux

re_equal = rb_reg_regcomp(“\s*=\s”);
re_space = rb_reg_regcomp(“\s+”);

See [ruby-talk:69375], you must give a VALUE (rb_str_new2()), not a string

Thanks

p.s. : I hope that re_equal and re_space are protected against the GC

I don’t know how to do that yet.
I have just declared them as static in my .c file. But, maybe that
doesn’t matter.

···

On Tuesday, 15 April 2003 at 0:15:57 +0900, ts wrote:


Jim Freeze

There are two types of people in this world, good and bad. The good
sleep better, but the bad seem to enjoy the waking hours much more.
– Woody Allen

I don't know how to do that yet.
I have just declared them as static in my .c file. But, maybe that
doesn't matter.

Something like this

#include <ruby.h>

static VALUE re_equal, re_space;

static VALUE
tt_sub_bang(VALUE line)
{
VALUE sp = rb_str_new2(" ");

rb_funcall(line, rb_intern("gsub!"), 2, re_equal, sp)
/* ... */
return line;
}

void Init_tt()
{
    re_equal = rb_reg_regcomp(rb_str_new2("\\s*=\\s"));
    re_space = rb_reg_regcomp(rb_str_new2("\\s+"));
    /* register the variable */
    rb_global_variable(&re_equal);
    rb_global_variable(&re_space);
    /* ... */
}

Guy Decoux

Cool, how did you know my code without me sending it to you? :slight_smile:

Here is my init function. I assume that I don’t have to protect
id’s.

void Init_netlistparser()
{
VALUE cNetlistParsr = rb_define_class(“NetlistParser”, rb_cObject);
rb_define_method(cNetlistParsr, “initialize”, np_initialize, 1);
rb_define_method(cNetlistParsr, “each_statement”, np_each_statement,1);

id_strip_bang = rb_intern("strip!");
id_gsub_bang  = rb_intern("gsub!");

re_equal      = rb_reg_regcomp(rb_str_new2("\\s*=\\s*"));
re_space      = rb_reg_regcomp(rb_str_new2("\\s+"));
str_space     = rb_str_new2(" ");
str_equal     = rb_str_new2("=");

rb_global_variable(&re_equal);
rb_global_variable(&re_space);
rb_global_variable(&str_space);
rb_global_variable(&str_equal);

}

···

On Tuesday, 15 April 2003 at 0:27:10 +0900, ts wrote:

I don’t know how to do that yet.
I have just declared them as static in my .c file. But, maybe that
doesn’t matter.

Something like this

#include <ruby.h>

static VALUE re_equal, re_space;

static VALUE
tt_sub_bang(VALUE line)
{
VALUE sp = rb_str_new2(" ");

rb_funcall(line, rb_intern(“gsub!”), 2, re_equal, sp)
/* … */
return line;
}

void Init_tt()
{
re_equal = rb_reg_regcomp(rb_str_new2(“\s*=\s”));
re_space = rb_reg_regcomp(rb_str_new2(“\s+”));
/* register the variable /
rb_global_variable(&re_equal);
rb_global_variable(&re_space);
/
… */
}


Jim Freeze

Don’t worry about the world coming to an end today. It’s already
tomorrow in Australia.
– Charles Schultz

Here is my init function. I assume that I don't have to protect
id's.

No, you don't need to protect id's

Guy Decoux