packetie
packetie

Reputation: 5059

perl match function for C program

Trying to use perl API functions in C program. Couldn't find the function to do regular expression match. Wish there is a function like regexmatch in the following program.

#include <EXTERN.h>               /* from the Perl distribution     */
#include <perl.h>                 /* from the Perl distribution     */
#include <sys/time.h>

typedef unsigned long ulong;

static PerlInterpreter *my_perl;  /***    The Perl interpreter    ***/


int main(int argc, char **argv, char **env) {
    int numOfArgs = 0;
    PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
    my_perl = perl_alloc();
    perl_construct(my_perl);
    SV* str = newSVpv(argv[1], strlen(argv[1]));
    if (regexmatch(str, "/hi (\S+)/")) {
        printf("found a match\n");
    }   
    return 0;
}

I know it's possible to use pcre library, just wonder if it's possible to get it from perl library here (libperl.so.5.14.2 on ubuntu 12.04)

Thanks!

UPDATE 1: Did some google search and got the following simple program compiling. But when I ran the program as ./a.out ping pin, it gave "Segmentation fault" in the "pregcomp" function. Not sure why.

#include <EXTERN.h>               /* from the Perl distribution     */
#include <perl.h>                 /* from the Perl distribution     */
#include <sys/time.h>
#include <embed.h>

typedef unsigned long ulong;

static PerlInterpreter *my_perl;  /***    The Perl interpreter    ***/

struct REGEXP * const engine;

int main(int argc, char **argv, char **env) {
    int numOfArgs = 0;
    PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
    my_perl = perl_alloc();
    perl_construct(my_perl);

    SV* reStr = newSVpv(argv[2], strlen(argv[2]));
    printf("compiling regexp\n");
    REGEXP * const compiled_regex = pregcomp(reStr, 0);
    printf("execing regexp\n");
    int len = strlen(argv[1]);
    pregexec(compiled_regex, argv[1], argv[1] + len, argv[1], 5, NULL, 0);
    return 0;
}

Upvotes: 3

Views: 191

Answers (1)

ikegami
ikegami

Reputation: 385496

Don't mess with Perl's private internals. Call a Perl sub that uses the match operator.

Say you previously compiled the following in your interpreter (using eval_pv),

sub regex_match { $_[0] =~ $_[1] }

Then you can call

static bool regex_match_sv(SV* str, SV* re) {
    dSP;
    bool matched;
    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    XPUSHs(str);
    XPUSHs(re);
    PUTBACK;
    call_pv("regex_match", G_SCALAR);
    SPAGAIN;
    matched = SvTRUE(POPs);
    PUTBACK;
    FREETMPS;
    LEAVE;
    return matched;
}

Upvotes: 4

Related Questions