From 2a38273b4212c38e66af99c8c3b6e9335dc64cb2 Mon Sep 17 00:00:00 2001 From: fcolin Date: Fri, 3 Jun 2005 16:43:22 +0000 Subject: separation du code regexp dans un module a part en vue de l'implementation des bindings simple! --- src/Makefile | 21 ++++---- src/ivy.c | 166 ++++++++-------------------------------------------------- src/ivybind.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ivybind.h | 26 +++++++++ 4 files changed, 218 insertions(+), 152 deletions(-) create mode 100644 src/ivybind.c create mode 100644 src/ivybind.h diff --git a/src/Makefile b/src/Makefile index d9907ce..c094e7d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -43,7 +43,7 @@ TCLLIB = -ltcl$(TCLVERS) PCREINC = `pcre-config --cflags` PCRELIB = `pcre-config --libs` CASESENSITIVE = "yes" -ifeq ($(CASESENSITIVE), "no") +ifeq ($(CASESENSITIVE), "yes") PCRE_OPT=PCRE_CASELESS REGCOMP_OPT=REG_ICASE else @@ -68,12 +68,12 @@ REGEXP= -DUSE_PCRE_REGEX -DPCRE_OPT=$(PCRE_OPT) CHANNEL = -DTCL_CHANNEL_INTEGRATION CFLAGS = -g -Wall #-DDEBUG -OBJ = ivyloop.o timer.o ivysocket.o ivy.o -GOBJ = ivyloop.o timer.o ivysocket.o givy.o -XTOBJ = ivyxtloop.o ivysocket.o ivy.o -GLIBOBJ = ivyglibloop.o ivysocket.o ivy.o -GLUTOBJ = ivyglutloop.o ivysocket.o ivy.o -TCLOBJ = ivytcl.o timer.o ivysocket.o givy.o +OBJ = ivyloop.o timer.o ivysocket.o ivybind.o ivy.o +GOBJ = ivyloop.o timer.o ivysocket.o ivybind.o givy.o +XTOBJ = ivyxtloop.o ivysocket.o ivybind.o ivy.o +GLIBOBJ = ivyglibloop.o ivysocket.o ivybind.o ivy.o +GLUTOBJ = ivyglutloop.o ivysocket.o ivybind.o ivy.o +TCLOBJ = ivytcl.o timer.o ivysocket.o ivybind.o givy.o # WINDOWS add ivyloop.o if TCL_CHANNEL_INTEGRATION is not set TARGETS = ivyprobe ivyperf ivyglibprobe ivyxtprobe TARGETLIBS=libivy.so.$(MAJOR).$(MINOR) libgivy.so.$(MAJOR).$(MINOR) libxtivy.so.$(MAJOR).$(MINOR) libglibivy.so.$(MAJOR).$(MINOR) libtclivy.so.$(MAJOR).$(MINOR) @@ -96,10 +96,13 @@ ivytcl.o: ivytcl.c $(CC) -c $(CFLAGS) $(TCLINCL) $(CHANNEL) ivytcl.c ivy.o: ivy.c - $(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivy.c + $(CC) -c $(CFLAGS) ivy.c + +ivybind.o: ivybind.c + $(CC) -c $(CFLAGS) $(REGEXP) $(PCREINC) ivybind.c givy.o: ivy.c - $(CC) -c $(CFLAGS) -DGNU_REGEXP -DREGCOMP_OPT=$(REGCOMP_OPT) -o givy.o ivy.c + $(CC) -c $(CFLAGS) $(REGEXP) -o givy.o ivy.c ivyglutloop.o: ivyglutloop.c ivyglutloop.h $(CC) -c $(CFLAGS) $(GLUTINC) ivyglutloop.c diff --git a/src/ivy.c b/src/ivy.c index 8288558..303c737 100644 --- a/src/ivy.c +++ b/src/ivy.c @@ -28,16 +28,11 @@ #include #include -#ifndef USE_PCRE_REGEX -#include -#else -#define OVECSIZE 60 /* must be multiple of 3, for regexp return */ -#include -#endif #include #include "ivychannel.h" +#include "ivybind.h" #include "ivysocket.h" #include "list.h" #include "ivy.h" @@ -96,12 +91,7 @@ struct _msg_snd { /* requete de reception d'un client */ MsgSndPtr next; int id; char *str_regexp; /* la regexp sous forme inhumaine */ -#ifndef USE_PCRE_REGEX - regex_t regexp; /* la regexp sous forme machine */ -#else - pcre *regexp; - pcre_extra *inspect; -#endif + IvyBinding bind; }; struct _clnt_lst { @@ -276,24 +266,17 @@ static void IvyCleanup() SocketClose( broadcast ); } -#ifdef USE_PCRE_REGEX -static int -MsgCall (const char *message, MsgSndPtr msg, Client client) +static int MsgCall (const char *message, MsgSndPtr msg, Client client) { static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */ static int size = 0; /* donc non reentrant !!!! */ int offset = 0; - int ovector[OVECSIZE]; + int arglen; + const char *arg; int index; - int rc=pcre_exec( - msg->regexp, - msg->inspect, - message, - strlen(message), - 0, /* debut */ - 0, /* no other regexp option */ - ovector, - OVECSIZE); + + int rc = IvyBindExec( msg->bind, message ); + if (rc<1) return 0; /* no match */ #ifdef DEBUG printf( "Sending message id=%d '%s'\n",msg->id,message); @@ -307,17 +290,16 @@ MsgCall (const char *message, MsgSndPtr msg, Client client) #ifdef DEBUG printf( "Send matching args count %d\n",rc-1); #endif - index=1; + index=0; while ( indexbind, message, index, &arg, &arglen ); #ifdef DEBUG - printf ("Send matching arg%d '%.*s'\n",index,ovector[2*index+1]- ovector[2*index], - message + ovector[2*index]); + printf ("Send matching arg%d '%.*s'\n",arglen, arg); #endif offset += make_message_var( &buffer, &size, offset, "%c%.*s", MESSAGE_SEPARATOR, - ovector[2*index+1]- ovector[2*index], - message + ovector[2*index] + arglen, arg ); ++index; } @@ -326,70 +308,7 @@ MsgCall (const char *message, MsgSndPtr msg, Client client) return 1; } -#else /* we don't USE_PCRE_REGEX */ -static int -MsgCall (const char *message, MsgSndPtr msg, Client client) -{ - static char *buffer = NULL; /* Use satic mem to eliminate multiple call to malloc /free */ - static int size = 0; /* donc non reentrant !!!! */ - int offset = 0; - regmatch_t match[MAX_MSG_FIELDS+1]; -#ifdef GNU_REGEXP - regmatch_t* p; -#else - unsigned int i; -#endif - memset( match, -1, sizeof(match )); /* work around bug !!!*/ - if (regexec (&msg->regexp, message, MAX_MSG_FIELDS, match, 0) != 0) - return 0; -#ifdef DEBUG - printf( "Sending message id=%d '%s'\n",msg->id,message); -#endif - // il faut essayer d'envoyer le message en une seule fois sur la socket - // pour eviter au maximun de passer dans le select plusieur fois par message du protocole Ivy - // pour eviter la latence ( PB detecte par ivyperf ping roudtrip ) - offset += make_message_var( &buffer, &size, offset, "%d%c%d",Msg, MESSAGE_SEPARATOR, msg->id); - -#ifdef DEBUG - printf( "Send matching args count %d\n",msg->regexp.re_nsub); -#endif //DEBUG - -#ifdef GNU_REGEXP - p = &match[1]; - while ( p->rm_so != -1 ) { - offset += make_message_var( &buffer, &size, offset, "%c%.*s", - MESSAGE_SEPARATOR, - p->rm_eo - p->rm_so, - message + p->rm_so); - ++p; - } -#else - for ( i = 1; i < msg->regexp.re_nsub+1; i ++ ) { - if ( match[i].rm_so != -1 ) { -#ifdef DEBUG - printf ("Send matching arg%d %d %d\n",i,match[i].rm_so , match[i].rm_eo); - printf ("Send matching arg%d %.*s\n",i,(int)(match[i].rm_eo - match[i].rm_so), - message + match[i].rm_so); -#endif - offset += make_message_var( &buffer, &size, offset, "%c%.*s", - MESSAGE_SEPARATOR , - (int)(match[i].rm_eo - match[i].rm_so), - message + match[i].rm_so); - } else { -#ifdef DEBUG - printf( "Send matching arg%d VIDE\n",i); -#endif //DEBUG - } - } -#endif - - offset += make_message_var( &buffer, &size, offset, "%c", MESSAGE_TERMINATOR); - SocketSendRaw(client, buffer , offset); - return 1; -} -#endif /* USE_PCRE_REGEX */ - static int ClientCall (IvyClientPtr clnt, const char *message) { @@ -453,14 +372,7 @@ static void Receive( Client client, void *data, char *line ) int argc = 0; char *argv[MAX_MSG_FIELDS]; int kind_of_msg = Bye; -#ifndef USE_PCRE_REGEX - regex_t regexp; - int reg; -#else - pcre *regexp; - const char *errbuf; - int erroffset; -#endif + IvyBinding bind; argc = SplitArg( line, MESSAGE_SEPARATOR, argv); @@ -501,45 +413,15 @@ static void Receive( Client client, void *data, char *line ) #endif //DEBUG return; } -#ifndef USE_PCRE_REGEX - reg = regcomp(®exp, argv[ARG_0], REGCOMP_OPT|REG_EXTENDED); - if ( reg == 0 ) - { - IVY_LIST_ADD( clnt->msg_send, snd ) - if ( snd ) - { - snd->id = id; - snd->str_regexp = strdup( argv[ARG_0] ); - snd->regexp = regexp; - if ( application_bind_callback ) - { - (*application_bind_callback)( clnt, application_bind_data, snd->str_regexp, IvyAddBind ); - } - } - } - else - { - char errbuf[4096]; - regerror (reg, ®exp, errbuf, 4096); - printf("Error compiling '%s', %s\n", argv[ARG_0], errbuf); - MsgSendTo( client, Error, reg, errbuf ); - } -#else - regexp = pcre_compile(argv[ARG_0], PCRE_OPT,&errbuf,&erroffset,NULL); - if ( regexp != NULL ) + bind = IvyBindingCompile( argv[ARG_0] ); + if ( bind != NULL ) { IVY_LIST_ADD( clnt->msg_send, snd ) if ( snd ) { snd->id = id; snd->str_regexp = strdup( argv[ARG_0] ); - snd->regexp = regexp; - snd->inspect = pcre_study(regexp,0,&errbuf); - if (errbuf!=NULL) - { - printf("Error studying %s, message: %s\n",argv[ARG_0],errbuf); - } - + snd->bind = bind; if ( application_bind_callback ) { (*application_bind_callback)( clnt, application_bind_data, IvyAddBind, snd->str_regexp ); @@ -548,10 +430,12 @@ static void Receive( Client client, void *data, char *line ) } else { - printf("Error compiling '%s', %s\n", argv[ARG_0], errbuf); - MsgSendTo( client, Error, erroffset, errbuf ); + int offset; + const char *errbuf; + IvyBindingGetCompileError( &offset, &errbuf ); + MsgSendTo( client, Error, offset, errbuf ); } -#endif + break; case DelRegexp: #ifdef DEBUG @@ -565,13 +449,9 @@ static void Receive( Client client, void *data, char *line ) { (*application_bind_callback)( clnt, application_bind_data, IvyRemoveBind, snd->str_regexp ); } -#ifndef USE_PCRE_REGEX free( snd->str_regexp ); -#else - free( snd->str_regexp ); - if (snd->inspect!=NULL) pcre_free(snd->inspect); - pcre_free(snd->regexp); -#endif + IvyBindingFree( snd->bind ); + IVY_LIST_REMOVE( clnt->msg_send, snd ); } break; diff --git a/src/ivybind.c b/src/ivybind.c new file mode 100644 index 0000000..1a9d49a --- /dev/null +++ b/src/ivybind.c @@ -0,0 +1,157 @@ +/* + * Ivy, C interface + * + * Copyright (C) 1997-2000 + * Centre d'Études de la Navigation Aérienne + * + * Bind syntax for extracting message comtent + * using regexp or other + * + * Authors: François-Régis Colin + * + * $Id$ + * + * Please refer to file version.h for the + * copyright notice regarding this software + */ +/* Module de gestion de la syntaxe des messages Ivy */ + +#include +#include +#include +#include +#include + +#ifndef USE_PCRE_REGEX +#include +#else +#define OVECSIZE 60 /* must be multiple of 3, for regexp return */ +#include +#endif + +#include "list.h" +#include "ivybind.h" + +#ifndef USE_PCRE_REGEX + static int erroroffset; + static char errbuf[4096]; +#else + static const char *errbuf; + static int erroffset; +#endif + +struct _binding { + struct _timer *next; +#ifndef USE_PCRE_REGEX + regex_t regexp; /* la regexp sous forme machine */ + regmatch_t match[MAX_MSG_FIELDS+1]; /* resultat du match */ +#else + pcre *regexp; + pcre_extra *inspect; + int ovector[OVECSIZE]; +#endif + }; + +IvyBinding IvyBindingCompile( const char * expression ) +{ + IvyBinding bind=0; +#ifdef USE_PCRE_REGEX + pcre *regexp; + regexp = pcre_compile(expression, PCRE_OPT,&errbuf,&erroffset,NULL); + if ( regexp != NULL ) + { + bind = (IvyBinding)malloc( sizeof( struct _binding )); + bind->regexp = regexp; + bind->inspect = pcre_study(regexp,0,&errbuf); + if (errbuf!=NULL) + { + printf("Error studying %s, message: %s\n",expression,errbuf); + } + } + else + { + printf("Error compiling '%s', %s\n", expression, errbuf); + } +#else + regex_t regexp; + int reg; + reg = regcomp(®exp, expression, REGCOMP_OPT|REG_EXTENDED); + if ( reg == 0 ) + { + bind = (IvyBinding)malloc( sizeof( struct _binding )); + bind->regexp = regexp; + } + else + { + regerror (reg, ®exp, errbuf, sizeof(errbuf) ); + erroroffset = 0; // TODO unkown offset error + printf("Error compiling '%s', %s\n", expression, errbuf); + } +#endif + return bind; +} +void IvyBindingGetCompileError( int *offset, const char **errmessage ) +{ +#ifndef USE_PCRE_REGEX + *offset = erroroffset; + *errmessage = errbuf; +#else + *offset = erroffset; + *errmessage = errbuf; +#endif +} +void IvyBindingFree( IvyBinding bind ) +{ +#ifdef USE_PCRE_REGEX + if (bind->inspect!=NULL) pcre_free(bind->inspect); + pcre_free(bind->regexp); +#else +#endif + free ( bind ); +} +int IvyBindExec( IvyBinding bind, const char * message ) +{ + int nb_match = 0; +#ifdef USE_PCRE_REGEX + + nb_match = pcre_exec( + bind->regexp, + bind->inspect, + message, + strlen(message), + 0, /* debut */ + 0, /* no other regexp option */ + bind->ovector, + OVECSIZE); + if (nb_match<1) return 0; /* no match */ + nb_match--; // firts arg wall string ??? + +#else + memset( bind->match, -1, sizeof(bind->match )); /* work around bug !!!*/ + nb_match = regexec (&bind->regexp, message, MAX_MSG_FIELDS, bind->match, 0) + if (nb_match != 0) + return 0; +#endif + return nb_match; +} +void IvyBindingGetMatch( IvyBinding bind, const char *message, int index, const char **arg, int *arglen ) +{ + index++; // firts arg wall string ??? +#ifdef USE_PCRE_REGEX + *arglen = bind->ovector[2*index+1]- bind->ovector[2*index]; + *arg = message + bind->ovector[2*index]; +#else /* we don't USE_PCRE_REGEX */ + + regmatch_t* p; + + p = &bind->match[index]; + if ( p->rm_so != -1 ) { + *arglen = p->rm_eo - p->rm_so; + *arg = message + p->rm_so; + } else { // ARG VIDE + *arglen = 0; + *arg = message; + } + +#endif +} \ No newline at end of file diff --git a/src/ivybind.h b/src/ivybind.h new file mode 100644 index 0000000..84468b8 --- /dev/null +++ b/src/ivybind.h @@ -0,0 +1,26 @@ +/* + * Ivy, C interface + * + * Copyright (C) 1997-2000 + * Centre d'Études de la Navigation Aérienne + * + * Bind syntax for extracting message comtent + * using regexp or other + * + * Authors: François-Régis Colin + * + * $Id$ + * + * Please refer to file version.h for the + * copyright notice regarding this software + */ + +/* Module de gestion de la syntaxe des messages Ivy */ + +typedef struct _binding *IvyBinding; + +IvyBinding IvyBindingCompile( const char * expression ); +void IvyBindingGetCompileError( int *erroffset, const char **errmessage ); +void IvyBindingFree( IvyBinding bind ); +int IvyBindExec( IvyBinding bind, const char * message ); +void IvyBindingGetMatch( IvyBinding bind, const char *message, int index, const char **arg, int *arglen ); \ No newline at end of file -- cgit v1.1