summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ivy.c290
-rw-r--r--src/ivy.h2
-rw-r--r--src/ivybind.c194
-rw-r--r--src/ivybind.h12
4 files changed, 79 insertions, 419 deletions
diff --git a/src/ivy.c b/src/ivy.c
index dd8aa04..6502ea8 100644
--- a/src/ivy.c
+++ b/src/ivy.c
@@ -26,13 +26,6 @@
#include <stdarg.h>
#include <ctype.h>
-#ifndef USE_PCRE_REGEX
-#include <regex.h>
-#else
-#define OVECSIZE 60 /* must be multiple of 3, for regexp return */
-#include <pcre.h>
-#endif
-
#include <fcntl.h>
#include "ivychannel.h"
@@ -40,6 +33,7 @@
#include "list.h"
#include "ivybuffer.h"
#include "ivydebug.h"
+#include "ivybind.h"
#include "ivy.h"
#define VERSION 3
@@ -86,12 +80,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 binding; /* la regexp sous forme machine */
};
struct _clnt_lst {
@@ -116,16 +105,6 @@ static Client broadcast;
static const char *ApplicationName = 0;
-/* classes de messages emis par l'application utilise pour le filtrage */
-static int messages_classes_count = 0;
-static const char **messages_classes = 0;
-/* regexp d'extraction du mot clef des regexp client pour le filtrage des regexp , ca va c'est clair ??? */
-#ifndef USE_PCRE_REGEX
- regex_t token_extract;
-#else
- pcre *token_extract;
- pcre_extra *token_inspect;
-#endif
/* callback appele sur reception d'un message direct */
static MsgDirectCallback direct_callback = 0;
@@ -194,24 +173,17 @@ static void IvyCleanup()
SocketClose( broadcast );
}
-#ifdef USE_PCRE_REGEX
-static int
-MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
+static int MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
{
int waiting = 0;
static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
int err;
- int ovector[OVECSIZE];
int index;
- int rc=pcre_exec(
- msg->regexp,
- msg->inspect,
- message,
- strlen(message),
- 0, /* debut */
- 0, /* no other regexp option */
- ovector,
- OVECSIZE);
+ int arglen;
+ const char *arg;
+
+ int rc= IvyBindingExec( msg->binding, message );
+
if (rc<1) return 0; /* no match */
TRACE( "Sending message id=%d '%s'\n",msg->id,message);
@@ -226,8 +198,8 @@ MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
index=1;
while ( index<rc ) {
- err = make_message_var( &buffer, "%.*s" ARG_END , ovector[2*index+1]- ovector[2*index],
- message + ovector[2*index]);
+ IvyBindingMatch( msg->binding, message, index, &arglen, & arg );
+ err = make_message_var( &buffer, "%.*s" ARG_END , arglen, arg );
++index;
}
err = make_message_var( &buffer, "\n");
@@ -237,65 +209,7 @@ MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
return 1;
}
-#else /* we don't USE_PCRE_REGEX */
-static int
-MsgCall (const char *message, MsgSndPtr msg, IvyClientPtr client)
-{
- int waiting = 0;
- static IvyBuffer buffer = { NULL, 0, 0 }; /* Use satic mem to eliminate multiple call to malloc /free */
- int err;
-
- regmatch_t match[MAX_MATCHING_ARGS+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_MATCHING_ARGS, match, 0) != 0)
- return 0;
-
- TRACE( "Sending message id=%d '%s'\n",msg->id,message);
-
- // 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 )
- buffer.offset = 0;
- err = make_message_var( &buffer, "%d %d" ARG_START ,Msg, msg->id);
-
- TRACE( "Send matching args count %ld\n",msg->regexp.re_nsub);
-
-#ifdef GNU_REGEXP
- p = &match[1];
- while ( p->rm_so != -1 ) {
- err = make_message_var( &buffer, "%.*s" ARG_END , 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 ) {
-
- TRACE("Send matching arg%d %d %d\n",i,match[i].rm_so , match[i].rm_eo);
- TRACE ("Send matching arg%d %.*s\n",i,(int)(match[i].rm_eo - match[i].rm_so),
- message + match[i].rm_so);
-
- buffer.offset += make_message_var( &buffer, "%.*s" ARG_END ,(int)(match[i].rm_eo - match[i].rm_so),
- message + match[i].rm_so);
- } else {
- buffer.offset += make_message_var( &buffer, ARG_END );
-
- TRACE( "Send matching arg%d VIDE\n",i);
- }
- }
-#endif
- err = make_message_var( &buffer,"\n");
- SocketSendRaw(client->client, buffer.data , buffer.offset);
- return 1;
-}
-#endif /* USE_PCRE_REGEX */
-
static int
ClientCall (IvyClientPtr clnt, const char *message)
{
@@ -307,91 +221,6 @@ ClientCall (IvyClientPtr clnt, const char *message)
}
return match_count;
}
-#ifdef USE_PCRE_REGEX
-static int ExtractTokenRegexp (const char *exp, char *buffer, int buffersize)
-{
-#define TOKEN_OVECSIZE 3*2 /* must be multiple of 3, for regexp return */
- int ovector[TOKEN_OVECSIZE];
- int rc=pcre_exec(
- token_extract,
- token_inspect,
- exp,
- strlen(exp),
- 0, /* debut */
- 0, /* no other regexp option */
- ovector,
- TOKEN_OVECSIZE);
- /*if (rc<1) return rc; *//* no match */
-
- return pcre_copy_substring(exp, ovector, rc, 1, buffer, buffersize);
-
-
-}
-
-#else /* we don't USE_PCRE_REGEX */
-static int ExtractTokenRegexp (const char *exp, char *buffer, int buffersize)
-{
- int err;
-
- regmatch_t match[MAX_MATCHING_ARGS+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_MATCHING_ARGS, match, 0) != 0)
- return 0;
-
-#ifdef GNU_REGEXP
- p = &match[1];
- while ( p->rm_so != -1 ) {
- err = make_message_var( &buffer, "%.*s" ARG_END , 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 ) {
-
- TRACE ("Send matching arg%d %d %d\n",i,match[i].rm_so , match[i].rm_eo);
- TRACE ("Send matching arg%d %.*s\n",i,(int)(match[i].rm_eo - match[i].rm_so),
- message + match[i].rm_so);
-
- buffer.offset += make_message_var( &buffer, "%.*s" ARG_END ,(int)(match[i].rm_eo - match[i].rm_so),
- message + match[i].rm_so);
- } else {
- buffer.offset += make_message_var( &buffer, ARG_END );
- }
- }
-#endif
-
- return 1;
-}
-#endif /* USE_PCRE_REGEX */
-
-static int CheckRegexp(char *exp)
-{
- int i;
- int err;
- int regexp_ok = 1; /* accepte tout par default */
- char token[200];
-
- if ( *exp =='^' && messages_classes_count !=0 )
- {
- regexp_ok = 0;
-
- /* extract token */
- err = ExtractTokenRegexp ( exp, token, sizeof(token));
- if ( err < 1 ) return 1;
- for ( i = 0 ; i < messages_classes_count; i++ )
- {
- if (strncmp( messages_classes[i], token, strlen( token )) == 0)
- return 1;
- }
- }
- return regexp_ok;
-}
static int CheckConnected( IvyClientPtr clnt )
{
@@ -428,14 +257,10 @@ static void Receive( Client client, void *data, char *line )
char *argv[MAX_MATCHING_ARGS];
char *arg;
int kind_of_msg = Bye;
-#ifndef USE_PCRE_REGEX
- regex_t regexp;
- int reg;
-#else
- pcre *regexp;
+ IvyBinding bind;
+
const char *errbuf;
int erroffset;
-#endif
err = sscanf( line ,"%d %d", &kind_of_msg, &id );
arg = strstr( line , ARG_START );
@@ -465,7 +290,7 @@ static void Receive( Client client, void *data, char *line )
TRACE("Regexp id=%d exp='%s'\n", id, arg);
- if ( !CheckRegexp( arg ) )
+ if ( !IvyBindingFilter( arg ) )
{
TRACE("Warning: regexp '%s' illegal, removing from %s\n",arg,ApplicationName);
@@ -476,41 +301,14 @@ static void Receive( Client client, void *data, char *line )
}
return;
}
-#ifndef USE_PCRE_REGEX
- reg = regcomp(&regexp, arg, REGCOMP_OPT|REG_EXTENDED);
- if ( reg == 0 )
- {
- IVY_LIST_ADD_START( clnt->msg_send, snd )
- snd->id = id;
- snd->str_regexp = strdup( arg );
- snd->regexp = regexp;
- if ( application_bind_callback )
- {
- (*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyAddBind );
- }
- IVY_LIST_ADD_END( clnt->msg_send, snd )
- }
- else
- {
- char errbuf[4096];
- regerror (reg, &regexp, errbuf, 4096);
- printf("Error compiling '%s', %s\n", arg, errbuf);
- MsgSendTo( client, Error, reg, errbuf );
- }
-#else
- regexp = pcre_compile(arg, PCRE_OPT,&errbuf,&erroffset,NULL);
- if ( regexp != NULL )
+
+ bind = IvyBindingCompile( arg );
+ if ( bind != NULL )
{
IVY_LIST_ADD_START( clnt->msg_send, snd )
snd->id = id;
snd->str_regexp = strdup( arg );
- snd->regexp = regexp;
- snd->inspect = pcre_study(regexp,0,&errbuf);
- if (errbuf!=NULL)
- {
- printf("Error studying %s, message: %s\n",arg,errbuf);
- }
-
+ snd->binding = bind;
if ( application_bind_callback )
{
(*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyAddBind );
@@ -520,10 +318,11 @@ static void Receive( Client client, void *data, char *line )
}
else
{
+ IvyBindingGetCompileError( & erroffset, & errbuf );
printf("Error compiling '%s', %s\n", arg, errbuf);
MsgSendTo( client, Error, erroffset, errbuf );
}
-#endif
+
break;
case DelRegexp:
@@ -536,13 +335,7 @@ static void Receive( Client client, void *data, char *line )
{
(*application_bind_callback)( clnt, application_bind_data, id, snd->str_regexp, IvyRemoveBind );
}
-#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->binding );
IVY_LIST_REMOVE( clnt->msg_send, snd );
}
break;
@@ -749,52 +542,15 @@ void IvyInit (const char *appname, const char *ready,
ready_message = ready;
}
-void IvySetBindCallback(IvyBindCallback bind_callback, void *bind_data
- )
+void IvySetBindCallback( IvyBindCallback bind_callback, void *bind_data )
{
application_bind_callback=bind_callback;
application_bind_data=bind_data;
}
-void IvyClasses( int argc, const char **argv)
+void IvySetFilter( int argc, const char **argv)
{
-
-#ifndef USE_PCRE_REGEX
- int reg;
-#else
- const char *errbuf;
- int erroffset;
-#endif
- messages_classes_count = argc;
- messages_classes = argv;
-
- /* compile the token extraction regexp */
-#ifndef USE_PCRE_REGEX
- reg = regcomp(&token_extract, "^\\^([a-zA-Z_0-9-]+).*", REGCOMP_OPT|REG_EXTENDED);
- if ( reg == 0 )
- {
- }
- else
- {
- char errbuf[4096];
- regerror (reg, &regexp, errbuf, 4096);
- printf("Error compiling Token Extract regexp: %s\n", errbuf);
- }
-#else
- token_extract = pcre_compile("^\\^([a-zA-Z_0-9-]+).*", PCRE_OPT,&errbuf,&erroffset,NULL);
- if ( token_extract != NULL )
- {
- token_inspect = pcre_study(token_extract,0,&errbuf);
- if (errbuf!=NULL)
- {
- printf("Error studying Token Extract regexp: %s\n",errbuf);
- }
- }
- else
- {
- printf("Error compiling Token Extract regexp: %s\n", errbuf);
- }
-#endif
+ IvyBindingSetFilter( argc, argv );
}
void IvyStart (const char* bus)
diff --git a/src/ivy.h b/src/ivy.h
index 1056cd1..e892070 100644
--- a/src/ivy.h
+++ b/src/ivy.h
@@ -54,7 +54,7 @@ typedef void (*MsgDirectCallback)( IvyClientPtr app, void *user_data, int id, ch
typedef struct _msg_rcv *MsgRcvPtr;
/* filtrage des regexps */
-void IvyClasses( int argc, const char **argv);
+void IvySetFilter( int argc, const char **argv);
void IvyInit(
const char *AppName, /* nom de l'application */
diff --git a/src/ivybind.c b/src/ivybind.c
index 237ee78..5e0ffe0 100644
--- a/src/ivybind.c
+++ b/src/ivybind.c
@@ -37,7 +37,6 @@
#endif
#include "list.h"
-#include "hash.h"
#include "ivybind.h"
static int err_offset;
@@ -49,10 +48,7 @@ static int err_offset;
#endif
struct _binding {
- IvyBindingType type;
- const char *msgname; /* msg tag name first word of message */
- char **msgargs; /* list of msg argument name */
- IvyArgument args; /* result */
+ const char *expression; /* regexp*/
#ifdef USE_PCRE_REGEX
pcre *regexp;
pcre_extra *inspect;
@@ -64,45 +60,13 @@ struct _binding {
#endif
};
-
/* classes de messages emis par l'application utilise pour le filtrage */
static int messages_classes_count = 0;
static const char **messages_classes = 0;
+/* regexp d'extraction du mot clef des regexp client pour le filtrage des regexp , ca va c'est clair ??? */
+static IvyBinding token_extract;
-
-/* stokage du message parse avant l'execution des regles de binding simple */
-static char *current_msg = NULL;
-static char *msgtag;
-static HASHTABLE msg_args_values = NULL;
-
-static IvyBinding IvyBindingCompileSimple( IvyBindingType typ, const char * expression )
-{
- int nb_arg= 0;
- char *argname;
- char **argv;
- char *expr;
- IvyBinding bind=0;
-
- expr = strdup( expression ); //Allocate a new buffer of separated token
- /* count nb args */
- argname = expr;
- while ( *argname )
- {
- if ( *argname++ == ' ' ) nb_arg++;
- }
-
- bind = (IvyBinding)malloc( sizeof( struct _binding ));
- memset( bind, 0, sizeof(*bind ) );
- bind->type = IvyBindSimple;
- bind->msgname = strtok( expr, " ");
- bind->msgargs = malloc ( sizeof( char* ) * ( nb_arg + 1) );
- argv = bind->msgargs;
- while ( (argname = strtok( NULL, " ")) )
- *argv++ = argname;
- *argv++ = argname; /* end with NULL */
- return bind;
-}
-static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expression )
+IvyBinding IvyBindingCompile( const char * expression )
{
IvyBinding bind=0;
#ifdef USE_PCRE_REGEX
@@ -111,9 +75,13 @@ static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expr
if ( regexp != NULL )
{
bind = (IvyBinding)malloc( sizeof( struct _binding ));
+ if ( ! bind )
+ {
+ perror( "IvyBindingCompile malloc error: ");
+ exit(-1);
+ }
memset( bind, 0, sizeof(*bind ) );
bind->regexp = regexp;
- bind->type = IvyBindRegexp;
bind->inspect = pcre_study(regexp,0,&err_buf);
if (err_buf!=NULL)
{
@@ -144,13 +112,7 @@ static IvyBinding IvyBindingCompileRegexp( IvyBindingType typ, const char * expr
#endif
return bind;
}
-IvyBinding IvyBindingCompile( IvyBindingType typ, const char * expression )
-{
- if ( typ == IvyBindRegexp )
- return IvyBindingCompileRegexp( typ, expression);
- else
- return IvyBindingCompileSimple( typ, expression);
-}
+
void IvyBindingGetCompileError( int *offset, const char **errmessage )
{
*offset = err_offset;
@@ -159,17 +121,15 @@ void IvyBindingGetCompileError( int *offset, const char **errmessage )
void IvyBindingFree( IvyBinding bind )
{
#ifdef USE_PCRE_REGEX
- if (bind->inspect!=NULL) pcre_free(bind->inspect);
+ if (bind->inspect!=NULL)
+ pcre_free(bind->inspect);
pcre_free(bind->regexp);
#else
+ free( bind->regexp );
#endif
- if (bind->msgname)
- free ( bind->msgname );
- if (bind->msgargs)
- free ( bind->msgargs );
free ( bind );
}
-int IvyBindingExecRegexp( IvyBinding bind, const char * message )
+int IvyBindingExec( IvyBinding bind, const char * message )
{
int nb_match = 0;
#ifdef USE_PCRE_REGEX
@@ -200,123 +160,69 @@ int IvyBindingExecRegexp( IvyBinding bind, const char * message )
#endif
return nb_match;
}
-int IvyBindingExecSimple( IvyBinding bind, const char * message )
-{
- char **msg_args;
- if ( strcmp( bind->msgname, msgtag ) != 0 )
- return 0;
- msg_args = bind->msgargs;
- bind->args = IvyArgumentNew( 0,NULL );
- while( *msg_args )
- {
- char *value;
- value = hash_lookup(msg_args_values, (HASHKEYTYPE)*msg_args++);
- if ( !value ) value = ""; /* TODO should we report matching ??? */
- IvyAddChildValue( bind->args, strlen( value ), value);
- }
- return 1;
-}
-int IvyBindingExec( IvyBinding bind, const char * message )
-{
- if ( bind->type == IvyBindRegexp )
- return IvyBindingExecRegexp( bind, message);
- else
- return IvyBindingExecSimple( bind, message);
-}
-static IvyArgument IvyBindingMatchSimple( IvyBinding bind, const char *message)
-{
- return bind->args;
-}
-static IvyArgument IvyBindingMatchRegexp( IvyBinding bind, const char *message)
+
+void IvyBindingMatch( IvyBinding bind, const char *message, int argnum, int *arglen, const char **arg)
{
- int index=1;// firts arg wall string ???
- int arglen;
- const void* arg;
- IvyArgument args;
- args = IvyArgumentNew( 0,NULL );
#ifdef USE_PCRE_REGEX
- while ( index<bind->nb_match ) {
- arglen = bind->ovector[2*index+1]- bind->ovector[2*index];
- arg = message + bind->ovector[2*index];
- index++;
+
+ *arglen = bind->ovector[2*argnum+1]- bind->ovector[2*argnum];
+ *arg = message + bind->ovector[2*argnum];
#else /* we don't USE_PCRE_REGEX */
- for ( index = 1; index < MAX_MSG_FIELDS; index++ )
- {
+
regmatch_t* p;
- p = &bind->match[index];
+ p = &bind->match[argnum+1];
if ( p->rm_so != -1 ) {
- arglen = p->rm_eo - p->rm_so;
- arg = message + p->rm_so;
+ *arglen = p->rm_eo - p->rm_so;
+ *arg = message + p->rm_so;
} else { // ARG VIDE
- arglen = 0;
- arg = NULL;
+ *arglen = 0;
+ *arg = NULL;
}
#endif // USE_PCRE_REGEX
- IvyAddChildValue( args, arglen, arg );
- }
- return args;
-}
-IvyArgument IvyBindingMatch( IvyBinding bind, const char *message)
-{
- if ( bind->type == IvyBindRegexp )
- return IvyBindingMatchRegexp( bind, message);
- else
- return IvyBindingMatchSimple( bind, message);
+
}
//filter Expression Bind
void IvyBindingSetFilter( int argc, const char **argv)
{
+ const char *errbuf;
+ int erroffset;
+
messages_classes_count = argc;
messages_classes = argv;
-}
-void IvyBindingParseMessage( const char *msg )
-{
- char *arg;
- if ( current_msg ) free( current_msg );
- if ( msg_args_values ) hash_destroy( msg_args_values );
- current_msg = strdup( msg );
- msg_args_values = hash_create( 256, TRUE );
- msgtag = strtok( current_msg, " " );
- while( (arg = strtok( NULL, " =" )) )
+ /* compile the token extraction regexp */
+
+ token_extract = IvyBindingCompile("^\\^([a-zA-Z_0-9-]+).*");
+ if ( !token_extract )
{
- char *val = strtok( NULL, " =");
- if ( arg && val )
- hash_addstring( msg_args_values, arg, val );
+ IvyBindingGetCompileError( & erroffset, & errbuf );
+ printf("Error compiling Token Extract regexp: %s\n", errbuf);
}
}
-int IvyBindingFilter(IvyBindingType typ, int len, const char *exp)
+
+int IvyBindingFilter(const char *expression)
{
- /* TODO check args limits !!!*/
int i;
- /* accepte tout par default */
- int regexp_ok = 1;
- // TODO simplify test 3 conditions
- if ( typ == IvyBindRegexp )
- {
- if ( *exp =='^' && messages_classes_count !=0 )
- {
- regexp_ok = 0;
- for ( i = 0 ; i < messages_classes_count; i++ )
- {
- if (strncmp( messages_classes[i], exp+1, strlen( messages_classes[i] )) == 0)
- return 1;
- }
- }
- }
- else
- {
- if ( messages_classes_count !=0 )
+ int err;
+ int regexp_ok = 1; /* accepte tout par default */
+ int tokenlen;
+ const char *token;
+
+ if ( *expression =='^' && messages_classes_count !=0 )
{
regexp_ok = 0;
+
+ /* extract token */
+ err = IvyBindingExec( token_extract, expression );
+ if ( err < 1 ) return 1;
+ IvyBindingMatch( token_extract, expression , 0, &tokenlen, &token );
for ( i = 0 ; i < messages_classes_count; i++ )
{
- if (strncmp( messages_classes[i], exp, strlen( messages_classes[i] )) == 0)
+ if (strncmp( messages_classes[i], token, tokenlen ) == 0)
return 1;
}
}
- }
return regexp_ok;
-} \ No newline at end of file
+}
diff --git a/src/ivybind.h b/src/ivybind.h
index 9846d3f..40f6932 100644
--- a/src/ivybind.h
+++ b/src/ivybind.h
@@ -14,18 +14,16 @@
* Please refer to file version.h for the
* copyright notice regarding this software
*/
-#include "ivyargument.h"
-
/* Module de gestion de la syntaxe des messages Ivy */
typedef struct _binding *IvyBinding;
-typedef enum { IvyBindRegexp, IvyBindSimple } IvyBindingType;
-void IvyBindingParseMessage( const char *msg );
void IvyBindingSetFilter( int argc, const char ** argv );
-int IvyBindingFilter( IvyBindingType typ, int len, const char *exp );
-IvyBinding IvyBindingCompile( IvyBindingType typ, const char * expression );
+int IvyBindingFilter( const char *expression );
+
+IvyBinding IvyBindingCompile( const char *expression );
void IvyBindingGetCompileError( int *erroffset, const char **errmessage );
void IvyBindingFree( IvyBinding bind );
+
int IvyBindingExec( IvyBinding bind, const char * message );
-IvyArgument IvyBindingMatch( IvyBinding bind, const char *message );
+void IvyBindingMatch( IvyBinding bind, const char *message, int argnum, int *arglen, const char **arg );