diff options
author | (no author) | 2006-01-10 13:51:39 +0000 |
---|---|---|
committer | (no author) | 2006-01-10 13:51:39 +0000 |
commit | d7960adb0c52a7abb2af932d1e7af98b980c8642 (patch) | |
tree | 7b995c5f5d12d102735a562364ca1a6ca50a29bc /src/ivybind.c | |
parent | deaa6a5ec82c1d158caf360fd12672f72d7dae5b (diff) | |
download | ivy-c-d7960adb0c52a7abb2af932d1e7af98b980c8642.zip ivy-c-d7960adb0c52a7abb2af932d1e7af98b980c8642.tar.gz ivy-c-d7960adb0c52a7abb2af932d1e7af98b980c8642.tar.bz2 ivy-c-d7960adb0c52a7abb2af932d1e7af98b980c8642.tar.xz |
This commit was manufactured by cvs2svn to create branch 'protocol_v3'.
Diffstat (limited to 'src/ivybind.c')
-rw-r--r-- | src/ivybind.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/src/ivybind.c b/src/ivybind.c new file mode 100644 index 0000000..237ee78 --- /dev/null +++ b/src/ivybind.c @@ -0,0 +1,322 @@ +/* + * 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 <fcolin@cena.fr> + * + * $Id$ + * + * Please refer to file version.h for the + * copyright notice regarding this software + */ +/* Module de gestion de la syntaxe des messages Ivy */ +#include <stdio.h> +#include <sys/types.h> +#include <time.h> +#include <stdlib.h> +#include <memory.h> +#include <string.h> +#include <stdarg.h> + +#ifdef WIN32 +#include <crtdbg.h> +#endif + + +#ifdef USE_PCRE_REGEX +#define OVECSIZE 60 /* must be multiple of 3, for regexp return */ +#include <pcre.h> +#else +#define MAX_MSG_FIELDS 200 +#include <regex.h> +#endif + +#include "list.h" +#include "hash.h" +#include "ivybind.h" + +static int err_offset; + +#ifdef USE_PCRE_REGEX + static const char *err_buf; +#else + static char err_buf[4096]; +#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 */ +#ifdef USE_PCRE_REGEX + pcre *regexp; + pcre_extra *inspect; + int nb_match; + int ovector[OVECSIZE]; +#else + regex_t regexp; /* la regexp sous forme machine */ + regmatch_t match[MAX_MSG_FIELDS+1]; /* resultat du match */ +#endif + }; + + +/* classes de messages emis par l'application utilise pour le filtrage */ +static int messages_classes_count = 0; +static const char **messages_classes = 0; + + +/* 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 bind=0; +#ifdef USE_PCRE_REGEX + pcre *regexp; + regexp = pcre_compile(expression, PCRE_OPT,&err_buf,&err_offset,NULL); + if ( regexp != NULL ) + { + bind = (IvyBinding)malloc( sizeof( struct _binding )); + memset( bind, 0, sizeof(*bind ) ); + bind->regexp = regexp; + bind->type = IvyBindRegexp; + bind->inspect = pcre_study(regexp,0,&err_buf); + if (err_buf!=NULL) + { + printf("Error studying %s, message: %s\n",expression,err_buf); + } + } + else + { + printf("Error compiling '%s', %s\n", expression, err_buf); + } +#else + regex_t regexp; + int reg; + reg = regcomp(®exp, expression, REGCOMP_OPT|REG_EXTENDED); + if ( reg == 0 ) + { + bind = (IvyBinding)malloc( sizeof( struct _binding )); + memset( bind, 0, sizeof(*bind ) ); + bind->regexp = regexp; + bind->next = NULL; + } + else + { + regerror (reg, ®exp, err_buf, sizeof(err_buf) ); + err_offset = 0; // TODO unkown offset error + printf("Error compiling '%s', %s\n", expression, err_buf); + } +#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; + *errmessage = err_buf; +} +void IvyBindingFree( IvyBinding bind ) +{ +#ifdef USE_PCRE_REGEX + if (bind->inspect!=NULL) pcre_free(bind->inspect); + pcre_free(bind->regexp); +#else +#endif + if (bind->msgname) + free ( bind->msgname ); + if (bind->msgargs) + free ( bind->msgargs ); + free ( bind ); +} +int IvyBindingExecRegexp( 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 */ + bind->nb_match = nb_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 == REG_NOMATCH) + return 0; + for ( index = 1; index < MAX_MSG_FIELDS; index++ ) + { + if ( bind->match[i].rm_so != -1 ) + nb_match++; + } +#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) +{ + 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++; +#else /* we don't USE_PCRE_REGEX */ + for ( index = 1; index < MAX_MSG_FIELDS; index++ ) + { + 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 = 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) +{ + 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, " =" )) ) + { + char *val = strtok( NULL, " ="); + if ( arg && val ) + hash_addstring( msg_args_values, arg, val ); + } +} +int IvyBindingFilter(IvyBindingType typ, int len, const char *exp) +{ + /* 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 ) + { + regexp_ok = 0; + for ( i = 0 ; i < messages_classes_count; i++ ) + { + if (strncmp( messages_classes[i], exp, strlen( messages_classes[i] )) == 0) + return 1; + } + } + } + return regexp_ok; +}
\ No newline at end of file |