2002-04-16 19:50:10 +04:00
/*
* testRegexp . c : simple module for testing regular expressions
*
* See Copyright for the status of this software .
*
* Daniel Veillard < veillard @ redhat . com >
*/
# include "libxml.h"
# ifdef LIBXML_AUTOMATA_ENABLED
2007-01-31 21:38:56 +03:00
# include <string.h>
2002-04-16 19:50:10 +04:00
2002-09-16 14:51:38 +04:00
# include <libxml/tree.h>
2002-04-16 19:50:10 +04:00
# include <libxml/xmlautomata.h>
static int scanNumber ( char * * ptr ) {
int ret = 0 ;
char * cur ;
cur = * ptr ;
while ( ( * cur > = ' 0 ' ) & & ( * cur < = ' 9 ' ) ) {
ret = ret * 10 + ( * cur - ' 0 ' ) ;
cur + + ;
}
* ptr = cur ;
return ( ret ) ;
}
static void
testRegexpFile ( const char * filename ) {
FILE * input ;
2003-11-14 19:20:34 +03:00
char expr [ 5000 ] ;
2002-04-16 19:50:10 +04:00
int len ;
int ret ;
int i ;
xmlAutomataPtr am ;
xmlAutomataStatePtr states [ 1000 ] ;
xmlRegexpPtr regexp = NULL ;
2002-09-24 18:13:13 +04:00
xmlRegExecCtxtPtr exec = NULL ;
2002-04-16 19:50:10 +04:00
for ( i = 0 ; i < 1000 ; i + + )
states [ i ] = NULL ;
input = fopen ( filename , " r " ) ;
if ( input = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Cannot open %s for reading \n " , filename ) ;
return ;
}
am = xmlNewAutomata ( ) ;
if ( am = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Cannot create automata \n " ) ;
fclose ( input ) ;
2006-03-10 03:36:23 +03:00
return ;
2002-04-16 19:50:10 +04:00
}
states [ 0 ] = xmlAutomataGetInitState ( am ) ;
if ( states [ 0 ] = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Cannot get start state \n " ) ;
xmlFreeAutomata ( am ) ;
fclose ( input ) ;
2006-03-10 03:36:23 +03:00
return ;
2002-04-16 19:50:10 +04:00
}
ret = 0 ;
2003-11-14 19:20:34 +03:00
while ( fgets ( expr , 4500 , input ) ! = NULL ) {
if ( expr [ 0 ] = = ' # ' )
2002-04-16 19:50:10 +04:00
continue ;
2003-11-14 19:20:34 +03:00
len = strlen ( expr ) ;
2002-04-16 19:50:10 +04:00
len - - ;
while ( ( len > = 0 ) & &
2003-11-14 19:20:34 +03:00
( ( expr [ len ] = = ' \n ' ) | | ( expr [ len ] = = ' \t ' ) | |
( expr [ len ] = = ' \r ' ) | | ( expr [ len ] = = ' ' ) ) ) len - - ;
expr [ len + 1 ] = 0 ;
2002-04-16 19:50:10 +04:00
if ( len > = 0 ) {
2003-11-14 19:20:34 +03:00
if ( ( am ! = NULL ) & & ( expr [ 0 ] = = ' t ' ) & & ( expr [ 1 ] = = ' ' ) ) {
char * ptr = & expr [ 2 ] ;
2002-04-16 19:50:10 +04:00
int from , to ;
from = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
if ( states [ from ] = = NULL )
states [ from ] = xmlAutomataNewState ( am ) ;
ptr + + ;
to = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
if ( states [ to ] = = NULL )
states [ to ] = xmlAutomataNewState ( am ) ;
ptr + + ;
xmlAutomataNewTransition ( am , states [ from ] , states [ to ] ,
BAD_CAST ptr , NULL ) ;
2003-11-14 19:20:34 +03:00
} else if ( ( am ! = NULL ) & & ( expr [ 0 ] = = ' e ' ) & & ( expr [ 1 ] = = ' ' ) ) {
char * ptr = & expr [ 2 ] ;
2002-04-16 19:50:10 +04:00
int from , to ;
from = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
if ( states [ from ] = = NULL )
states [ from ] = xmlAutomataNewState ( am ) ;
ptr + + ;
to = scanNumber ( & ptr ) ;
if ( states [ to ] = = NULL )
states [ to ] = xmlAutomataNewState ( am ) ;
xmlAutomataNewEpsilon ( am , states [ from ] , states [ to ] ) ;
2003-11-14 19:20:34 +03:00
} else if ( ( am ! = NULL ) & & ( expr [ 0 ] = = ' f ' ) & & ( expr [ 1 ] = = ' ' ) ) {
char * ptr = & expr [ 2 ] ;
2002-04-16 19:50:10 +04:00
int state ;
state = scanNumber ( & ptr ) ;
if ( states [ state ] = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad state %d : %s \n " , state , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
xmlAutomataSetFinalState ( am , states [ state ] ) ;
2003-11-14 19:20:34 +03:00
} else if ( ( am ! = NULL ) & & ( expr [ 0 ] = = ' c ' ) & & ( expr [ 1 ] = = ' ' ) ) {
char * ptr = & expr [ 2 ] ;
2002-04-16 19:50:10 +04:00
int from , to ;
int min , max ;
from = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
if ( states [ from ] = = NULL )
states [ from ] = xmlAutomataNewState ( am ) ;
ptr + + ;
to = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
if ( states [ to ] = = NULL )
states [ to ] = xmlAutomataNewState ( am ) ;
ptr + + ;
min = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
ptr + + ;
max = scanNumber ( & ptr ) ;
if ( * ptr ! = ' ' ) {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Bad line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
break ;
}
ptr + + ;
xmlAutomataNewCountTrans ( am , states [ from ] , states [ to ] ,
BAD_CAST ptr , min , max , NULL ) ;
2003-11-14 19:20:34 +03:00
} else if ( ( am ! = NULL ) & & ( expr [ 0 ] = = ' - ' ) & & ( expr [ 1 ] = = ' - ' ) ) {
2002-04-16 19:50:10 +04:00
/* end of the automata */
regexp = xmlAutomataCompile ( am ) ;
xmlFreeAutomata ( am ) ;
am = NULL ;
if ( regexp = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" Failed to compile the automata " ) ;
break ;
}
2003-11-14 19:20:34 +03:00
} else if ( ( expr [ 0 ] = = ' = ' ) & & ( expr [ 1 ] = = ' > ' ) ) {
2002-04-16 19:50:10 +04:00
if ( regexp = = NULL ) {
printf ( " => failed not compiled \n " ) ;
} else {
if ( exec = = NULL )
exec = xmlRegNewExecCtxt ( regexp , NULL , NULL ) ;
if ( ret = = 0 ) {
ret = xmlRegExecPushString ( exec , NULL , NULL ) ;
}
if ( ret = = 1 )
printf ( " => Passed \n " ) ;
else if ( ( ret = = 0 ) | | ( ret = = - 1 ) )
printf ( " => Failed \n " ) ;
else if ( ret < 0 )
printf ( " => Error \n " ) ;
xmlRegFreeExecCtxt ( exec ) ;
exec = NULL ;
}
ret = 0 ;
} else if ( regexp ! = NULL ) {
if ( exec = = NULL )
exec = xmlRegNewExecCtxt ( regexp , NULL , NULL ) ;
2003-11-14 19:20:34 +03:00
ret = xmlRegExecPushString ( exec , BAD_CAST expr , NULL ) ;
2002-04-16 19:50:10 +04:00
} else {
xmlGenericError ( xmlGenericErrorContext ,
2003-11-14 19:20:34 +03:00
" Unexpected line %s \n " , expr ) ;
2002-04-16 19:50:10 +04:00
}
}
}
fclose ( input ) ;
if ( regexp ! = NULL )
xmlRegFreeRegexp ( regexp ) ;
if ( exec ! = NULL )
xmlRegFreeExecCtxt ( exec ) ;
if ( am ! = NULL )
xmlFreeAutomata ( am ) ;
}
int main ( int argc , char * * argv ) {
xmlInitMemory ( ) ;
if ( argc = = 1 ) {
int ret ;
xmlAutomataPtr am ;
xmlAutomataStatePtr start , cur ;
xmlRegexpPtr regexp ;
xmlRegExecCtxtPtr exec ;
am = xmlNewAutomata ( ) ;
start = xmlAutomataGetInitState ( am ) ;
/* generate a[ba]*a */
cur = xmlAutomataNewTransition ( am , start , NULL , BAD_CAST " a " , NULL ) ;
xmlAutomataNewTransition ( am , cur , cur , BAD_CAST " b " , NULL ) ;
xmlAutomataNewTransition ( am , cur , cur , BAD_CAST " a " , NULL ) ;
cur = xmlAutomataNewCountTrans ( am , cur , NULL , BAD_CAST " a " , 2 , 3 , NULL ) ;
xmlAutomataSetFinalState ( am , cur ) ;
/* compile it in a regexp and free the automata */
regexp = xmlAutomataCompile ( am ) ;
xmlFreeAutomata ( am ) ;
/* test the regexp */
xmlRegexpPrint ( stdout , regexp ) ;
exec = xmlRegNewExecCtxt ( regexp , NULL , NULL ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " a " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " a " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " b " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " a " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " a " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " a " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
ret = xmlRegExecPushString ( exec , BAD_CAST " a " , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
if ( ret = = 0 ) {
ret = xmlRegExecPushString ( exec , NULL , NULL ) ;
if ( ret = = 1 )
printf ( " final \n " ) ;
else if ( ret < 0 )
printf ( " error \n " ) ;
}
xmlRegFreeExecCtxt ( exec ) ;
/* free the regexp */
xmlRegFreeRegexp ( regexp ) ;
} else {
int i ;
for ( i = 1 ; i < argc ; i + + )
testRegexpFile ( argv [ i ] ) ;
}
xmlCleanupParser ( ) ;
xmlMemoryDump ( ) ;
return ( 0 ) ;
}
# else
# include <stdio.h>
2003-09-29 17:20:24 +04:00
int main ( int argc ATTRIBUTE_UNUSED , char * * argv ATTRIBUTE_UNUSED ) {
2002-04-16 19:50:10 +04:00
printf ( " %s : Automata support not compiled in \n " , argv [ 0 ] ) ;
return ( 0 ) ;
}
# endif /* LIBXML_AUTOMATA_ENABLED */