2018-01-09 16:20:44 -08:00
# include <Efl_Net.h>
2016-08-29 20:28:00 -07:00
# include <Ecore_Getopt.h>
# include <fcntl.h>
# include <ctype.h>
static char * address = NULL ;
static char * agent = " efl_net_dialer_websocket " ;
static unsigned int start_index = 0 ;
static unsigned int end_index = UINT32_MAX ;
static unsigned int current_index = 0 ;
static Eina_Bool no_report_update = EINA_FALSE ;
static Eina_List * case_tuples = NULL ;
static Eina_Bool verbose = 0 ;
static Eo * pending = NULL ;
/* https://www.w3.org/International/questions/qa-forms-utf-8 */
static Eina_Bool
_utf8_check ( const char * text )
{
const unsigned char * bytes = ( const unsigned char * ) text ;
while ( * bytes )
{
const unsigned char c = bytes [ 0 ] ;
/* ascii: [\x09\x0A\x0D\x20-\x7E] */
if ( ( ( c > = 0x20 ) & & ( c < = 0x7e ) ) | |
( c = = 0x09 ) | | ( c = = 0x0a ) | | ( c = = 0x0d ) )
{
bytes + = 1 ;
continue ;
}
/* autobahnsuite says 0x7f is valid */
if ( c = = 0x7f )
{
bytes + = 1 ;
continue ;
}
# define VALUE_BYTE_CHECK(x) ((x >= 0x80) && (x <= 0xbf))
/* non-overlong 2-byte: [\xC2-\xDF][\x80-\xBF] */
if ( ( c > = 0xc2 ) & & ( c < = 0xdf ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 1 ] ) )
{
bytes + = 2 ;
continue ;
}
}
/* excluding overlongs: \xE0[\xA0-\xBF][\x80-\xBF] */
if ( c = = 0xe0 )
{
const unsigned char d = bytes [ 1 ] ;
if ( ( d > = 0xa0 ) & & ( d < = 0xbf ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 2 ] ) )
{
bytes + = 3 ;
continue ;
}
}
}
/* straight 3-byte: [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} */
if ( ( ( c > = 0xe1 ) & & ( c < = 0xec ) ) | |
( c = = 0xee ) | | ( c = = 0xef ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 1 ] ) & & VALUE_BYTE_CHECK ( bytes [ 2 ] ) )
{
bytes + = 3 ;
continue ;
}
}
/* excluding surrogates: \xED[\x80-\x9F][\x80-\xBF] */
if ( c = = 0xed )
{
const unsigned char d = bytes [ 1 ] ;
if ( ( d > = 0x80 ) & & ( d < = 0x9f ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 2 ] ) )
{
bytes + = 3 ;
continue ;
}
}
}
/* planes 1-3: \xF0[\x90-\xBF][\x80-\xBF]{2} */
if ( c = = 0xf0 )
{
const unsigned char d = bytes [ 1 ] ;
if ( ( d > = 0x90 ) & & ( d < = 0xbf ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 2 ] ) & & VALUE_BYTE_CHECK ( bytes [ 3 ] ) )
{
bytes + = 4 ;
continue ;
}
}
}
/* planes 4-15: [\xF1-\xF3][\x80-\xBF]{3} */
if ( ( c > = 0xf1 ) & & ( c < = 0xf3 ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 1 ] ) & & VALUE_BYTE_CHECK ( bytes [ 2 ] ) & & VALUE_BYTE_CHECK ( bytes [ 3 ] ) )
{
bytes + = 4 ;
continue ;
}
}
/* plane 16: \xF4[\x80-\x8F][\x80-\xBF]{2} */
if ( c = = 0xf4 )
{
const unsigned char d = bytes [ 1 ] ;
if ( ( d > = 0x80 ) & & ( d < = 0x8f ) )
{
if ( VALUE_BYTE_CHECK ( bytes [ 2 ] ) & & VALUE_BYTE_CHECK ( bytes [ 3 ] ) )
{
bytes + = 4 ;
continue ;
}
}
}
if ( verbose ) fprintf ( stderr , " INFO: failed unicode byte #%zd '%s' \n " , ( const char * ) bytes - text , text ) ;
return EINA_FALSE ;
}
return EINA_TRUE ;
}
static void
_ws_pong ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
const char * text = event - > info ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s got PONG: %s \n " ,
efl_name_get ( dialer ) , text ) ;
}
static void
_ws_closed_reason ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
Efl_Net_Dialer_Websocket_Closed_Reason * reason = event - > info ;
if ( ! _utf8_check ( reason - > message ) )
{
efl_net_dialer_websocket_close_request ( dialer , EFL_NET_DIALER_WEBSOCKET_CLOSE_REASON_PROTOCOL_ERROR , " invalid UTF-8 " ) ;
if ( verbose ) fprintf ( stderr , " INFO: %s got CLOSE with invalid UTF-8 \n " , efl_name_get ( dialer ) ) ;
}
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s got CLOSE: %4d '%s' \n " ,
efl_name_get ( dialer ) , reason - > reason , reason - > message ) ;
}
static void
_ws_message_text ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
const char * text = event - > info ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s got TEXT %zd bytes: \n %s \n " ,
efl_name_get ( dialer ) , strlen ( text ) , text ) ;
}
static void
_ws_message_binary ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
const Eina_Slice * slice = event - > info ;
size_t i ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s got BINARY %zd bytes \n " ,
efl_name_get ( dialer ) , slice - > len ) ;
for ( i = 0 ; i < slice - > len ; i + + )
{
const int c = slice - > bytes [ i ] ;
if ( isprint ( c ) )
fprintf ( stderr , " %#4x(%c) " , c , c ) ;
else
fprintf ( stderr , " %#4x " , c ) ;
}
fprintf ( stderr , " \n " ) ;
}
static void
_closed ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s closed \n " , efl_name_get ( dialer ) ) ;
}
static void
_eos ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s eos \n " , efl_name_get ( dialer ) ) ;
}
static void
_connected ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s connected %s \n " ,
efl_name_get ( dialer ) ,
efl_net_dialer_address_dial_get ( dialer ) ) ;
}
static void
_error ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
const Eina_Error * perr = event - > info ;
fprintf ( stderr , " ERROR: %s error: %d '%s' \n " ,
efl_name_get ( dialer ) , * perr , eina_error_msg_get ( * perr ) ) ;
2018-01-09 16:20:44 -08:00
efl_loop_quit ( efl_loop_get ( event - > object ) , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
}
static void
_del ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
if ( pending = = dialer )
pending = NULL ;
}
EFL_CALLBACKS_ARRAY_DEFINE ( dialer_cbs ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_PONG , _ws_pong } ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_CLOSED_REASON , _ws_closed_reason } ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_TEXT , _ws_message_text } ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_BINARY , _ws_message_binary } ,
2019-03-09 06:54:38 -08:00
{ EFL_NET_DIALER_EVENT_DIALER_CONNECTED , _connected } ,
2016-08-29 20:28:00 -07:00
{ EFL_NET_DIALER_EVENT_ERROR , _error } ,
{ EFL_IO_CLOSER_EVENT_CLOSED , _closed } ,
{ EFL_IO_READER_EVENT_EOS , _eos } ,
{ EFL_EVENT_DEL , _del } ) ;
static Eo *
2018-01-09 16:20:44 -08:00
_websocket_new ( const char * name , Eo * loop )
2016-08-29 20:28:00 -07:00
{
Eo * dialer ;
2018-01-09 16:20:44 -08:00
dialer = efl_add ( EFL_NET_DIALER_WEBSOCKET_CLASS , loop ,
2016-09-05 08:57:35 -07:00
efl_name_set ( efl_added , name ) ,
efl_event_callback_array_add ( efl_added , dialer_cbs ( ) , NULL ) ) ;
2016-08-29 20:28:00 -07:00
if ( ! dialer )
{
2018-01-09 16:20:44 -08:00
efl_loop_quit ( loop , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
fprintf ( stderr , " ERROR: could not create WebSockets dialer '%s' \n " , name ) ;
return NULL ;
}
pending = dialer ;
return dialer ;
}
static void
_closed_quit ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
efl_del ( dialer ) ;
ecore_main_loop_quit ( ) ;
}
static void
2018-01-09 16:20:44 -08:00
_tests_finished ( Eo * loop )
2016-08-29 20:28:00 -07:00
{
Eo * dialer ;
char url [ 4096 ] ;
int len ;
Eina_Error err ;
if ( no_report_update )
{
if ( verbose )
fprintf ( stderr , " INFO: tests finished, user required to not update the reports \n " ) ;
ecore_main_loop_quit ( ) ;
return ;
}
case_tuples = eina_list_remove ( case_tuples , case_tuples ) ;
len = snprintf ( url , sizeof ( url ) , " %s/updateReports?agent=%s " ,
address , agent ) ;
if ( len < 0 )
{
fprintf ( stderr , " ERROR: could not create URL "
" '%s/updateReports?agent=%s': %s " ,
address , agent , strerror ( errno ) ) ;
ecore_main_loop_quit ( ) ;
return ;
}
else if ( ( size_t ) len > sizeof ( url ) )
{
fprintf ( stderr , " ERROR: could not create URL "
" '%s/updateReports?agent=%s': no space. " ,
address , agent ) ;
ecore_main_loop_quit ( ) ;
return ;
}
2018-01-09 16:20:44 -08:00
dialer = _websocket_new ( " update-reports " , loop ) ;
2016-08-29 20:28:00 -07:00
if ( ! dialer )
{
ecore_main_loop_quit ( ) ;
return ;
}
efl_event_callback_add ( dialer , EFL_IO_CLOSER_EVENT_CLOSED , _closed_quit , NULL ) ;
err = efl_net_dialer_dial ( dialer , url ) ;
if ( err ! = 0 )
{
fprintf ( stderr , " ERROR: could not dial '%s': %s " ,
url , eina_error_msg_get ( err ) ) ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
efl_loop_quit ( loop , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
return ;
}
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: %s '%s' \n " ,
efl_name_get ( dialer ) , efl_net_dialer_address_dial_get ( dialer ) ) ;
}
static void
_echo_text ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
const char * text = event - > info ;
if ( ! _utf8_check ( text ) )
{
if ( verbose ) fprintf ( stderr , " INFO: invalid UTF-8 sequence '%s'. Close the connection. \n " , text ) ;
efl_net_dialer_websocket_close_request ( dialer , EFL_NET_DIALER_WEBSOCKET_CLOSE_REASON_INCONSISTENT_DATA , " invalid UTF-8 " ) ;
return ;
}
efl_net_dialer_websocket_text_send ( dialer , text ) ;
}
static void
_echo_binary ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
const Eina_Slice * slice = event - > info ;
efl_net_dialer_websocket_binary_send ( dialer , * slice ) ;
}
2018-01-09 16:20:44 -08:00
static Eina_Bool _websocket_test_next_case_tuple ( Eo * loop ) ;
2016-08-29 20:28:00 -07:00
static void
_test_next_case_closed ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
if ( ! _websocket_test_next_case_tuple ( efl_loop_get ( event - > object ) ) )
_tests_finished ( efl_loop_get ( event - > object ) ) ;
2016-08-29 20:28:00 -07:00
}
EFL_CALLBACKS_ARRAY_DEFINE ( _test_next_case_tuple_cbs ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_TEXT , _echo_text } ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_BINARY , _echo_binary } ,
{ EFL_IO_CLOSER_EVENT_CLOSED , _test_next_case_closed } ) ;
static Eina_Bool
2018-01-09 16:20:44 -08:00
_websocket_test_next_case_tuple ( Eo * loop )
2016-08-29 20:28:00 -07:00
{
Eo * dialer ;
char url [ 4096 ] ;
char name [ 256 ] ;
char * str ;
int len ;
Eina_Error err ;
if ( ! case_tuples )
return EINA_FALSE ;
str = case_tuples - > data ;
case_tuples = eina_list_remove_list ( case_tuples , case_tuples ) ;
len = snprintf ( url , sizeof ( url ) , " %s/runCase?casetuple=%s&agent=%s " ,
address , str , agent ) ;
if ( len < 0 )
{
fprintf ( stderr , " ERROR: could not create URL "
" '%s/runCase?casetuple=%s&agent=%s': %s " ,
address , str , agent , strerror ( errno ) ) ;
free ( str ) ;
return EINA_FALSE ;
}
else if ( ( size_t ) len > sizeof ( url ) )
{
fprintf ( stderr , " ERROR: could not create URL "
" '%s/runCase?casetuple=%s&agent=%s': no space. " ,
address , str , agent ) ;
free ( str ) ;
return EINA_FALSE ;
}
snprintf ( name , sizeof ( name ) , " test_case=%s " , str ) ;
free ( str ) ;
2018-01-09 16:20:44 -08:00
dialer = _websocket_new ( name , loop ) ;
2016-08-29 20:28:00 -07:00
if ( ! dialer ) return EINA_FALSE ;
efl_event_callback_array_add ( dialer , _test_next_case_tuple_cbs ( ) , NULL ) ;
err = efl_net_dialer_dial ( dialer , url ) ;
if ( err ! = 0 )
{
fprintf ( stderr , " ERROR: could not dial '%s': %s " ,
url , eina_error_msg_get ( err ) ) ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
efl_loop_quit ( loop , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
return EINA_FALSE ;
}
fprintf ( stderr , " TEST: %s '%s' \n " , efl_name_get ( dialer ) , efl_net_dialer_address_dial_get ( dialer ) ) ;
return EINA_TRUE ;
}
2018-01-09 16:20:44 -08:00
static Eina_Bool _websocket_test_index ( unsigned int idx , Eo * loop ) ;
2016-08-29 20:28:00 -07:00
static void
_test_index_closed ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
if ( ! _websocket_test_index ( current_index + 1 , efl_loop_get ( event - > object ) ) )
_tests_finished ( efl_loop_get ( event - > object ) ) ;
2016-08-29 20:28:00 -07:00
}
EFL_CALLBACKS_ARRAY_DEFINE ( _test_index_cbs ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_TEXT , _echo_text } ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_BINARY , _echo_binary } ,
{ EFL_IO_CLOSER_EVENT_CLOSED , _test_index_closed } ) ;
static Eina_Bool
2018-01-09 16:20:44 -08:00
_websocket_test_index ( unsigned int idx , Eo * loop )
2016-08-29 20:28:00 -07:00
{
Eo * dialer ;
char url [ 4096 ] ;
char name [ 64 ] ;
int len ;
Eina_Error err ;
if ( idx > end_index )
return EINA_FALSE ;
len = snprintf ( url , sizeof ( url ) , " %s/runCase?case=%u&agent=%s " ,
address , idx , agent ) ;
if ( len < 0 )
{
fprintf ( stderr , " ERROR: could not create URL "
" '%s/runCase?case=%u&agent=%s': %s " ,
address , idx , agent , strerror ( errno ) ) ;
return EINA_FALSE ;
}
else if ( ( size_t ) len > sizeof ( url ) )
{
fprintf ( stderr , " ERROR: could not create URL "
" '%s/runCase?case=%u&agent=%s': no space. " ,
address , idx , agent ) ;
return EINA_FALSE ;
}
snprintf ( name , sizeof ( name ) , " test_case=%u " , idx ) ;
2018-01-09 16:20:44 -08:00
dialer = _websocket_new ( name , loop ) ;
2016-08-29 20:28:00 -07:00
if ( ! dialer ) return EINA_FALSE ;
efl_event_callback_array_add ( dialer , _test_index_cbs ( ) , NULL ) ;
err = efl_net_dialer_dial ( dialer , url ) ;
if ( err ! = 0 )
{
fprintf ( stderr , " ERROR: could not dial '%s': %s " ,
url , eina_error_msg_get ( err ) ) ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
efl_loop_quit ( loop , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
return EINA_FALSE ;
}
current_index = idx ;
fprintf ( stderr , " TEST: %s '%s' \n " , efl_name_get ( dialer ) , efl_net_dialer_address_dial_get ( dialer ) ) ;
return EINA_TRUE ;
}
static void
_load_tests_text ( void * data EINA_UNUSED , const Efl_Event * event )
{
const char * text = event - > info ;
unsigned int n = strtoul ( text , NULL , 10 ) ;
if ( start_index = = 0 )
start_index = 1 ;
else if ( start_index > n )
start_index = n ;
if ( end_index = = 0 | | end_index > n )
end_index = n ;
if ( ! verbose ) return ;
fprintf ( stderr , " INFO: test count: %u, start_index=%u, end_index=%u \n " ,
n , start_index , end_index ) ;
}
static void
_load_tests_closed ( void * data EINA_UNUSED , const Efl_Event * event )
{
Eo * dialer = event - > object ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
if ( ! _websocket_test_index ( start_index , efl_loop_get ( event - > object ) ) )
_tests_finished ( efl_loop_get ( event - > object ) ) ;
2016-08-29 20:28:00 -07:00
}
EFL_CALLBACKS_ARRAY_DEFINE ( _load_tests_cbs ,
{ EFL_NET_DIALER_WEBSOCKET_EVENT_MESSAGE_TEXT , _load_tests_text } ,
{ EFL_IO_CLOSER_EVENT_CLOSED , _load_tests_closed } ) ;
static Eina_Bool
2018-01-09 16:20:44 -08:00
_websocket_load_tests ( Eo * loop )
2016-08-29 20:28:00 -07:00
{
Eo * dialer ;
char url [ 4096 ] ;
int len ;
Eina_Error err ;
len = snprintf ( url , sizeof ( url ) , " %s/getCaseCount " , address ) ;
if ( len < 0 )
{
fprintf ( stderr , " ERROR: could not create URL '%s/getCaseCount': %s " ,
address , strerror ( errno ) ) ;
return EINA_FALSE ;
}
else if ( ( size_t ) len > sizeof ( url ) )
{
fprintf ( stderr , " ERROR: could not create URL '%s/getCaseCount': no space. " ,
address ) ;
return EINA_FALSE ;
}
2018-01-09 16:20:44 -08:00
dialer = _websocket_new ( " get-case-count " , loop ) ;
2016-08-29 20:28:00 -07:00
if ( ! dialer ) return EINA_FALSE ;
efl_event_callback_array_add ( dialer , _load_tests_cbs ( ) , NULL ) ;
err = efl_net_dialer_dial ( dialer , url ) ;
if ( err ! = 0 )
{
fprintf ( stderr , " ERROR: could not dial '%s': %s " ,
url , eina_error_msg_get ( err ) ) ;
efl_del ( dialer ) ;
2018-01-09 16:20:44 -08:00
efl_loop_quit ( loop , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
return EINA_FALSE ;
}
if ( verbose ) fprintf ( stderr , " INFO: %s '%s' \n " , efl_name_get ( dialer ) , efl_net_dialer_address_dial_get ( dialer ) ) ;
return EINA_TRUE ;
}
static const Ecore_Getopt options = {
" efl_net_dialer_websocket_autobahntestee " , /* program name */
NULL , /* usage line */
" 1 " , /* version */
" (C) 2016 Enlightenment Project " , /* copyright */
" BSD 2-Clause " , /* license */
/* long description, may be multiline and contain \n */
" Use Efl_Net_Dialer_Websocket to implement a testee client for the Autobahn Test Suite. "
" \n "
" Autobahn Test Suite http://autobahn.ws/testsuite provides a fully automated test suite to verify client and server implementations of the WebSocket Protocol for specification conformance and implementation robustness. "
" \n "
" This is a client to talk to their test server, that should be executed as: \n "
" wstest -m fuzzingserver \n "
" \n " ,
EINA_FALSE ,
{
ECORE_GETOPT_STORE_UINT ( ' s ' , " start-index " , " when running batch, specifies the start (first) index " ) ,
ECORE_GETOPT_STORE_UINT ( ' e ' , " end-index " , " when running batch, specifies the end (last) index " ) ,
ECORE_GETOPT_STORE_TRUE ( ' n ' , " no-report-update " , " do not trigger autobahn to update report " ) ,
ECORE_GETOPT_STORE_TRUE ( ' v ' , " verbose " , " print messages " ) ,
ECORE_GETOPT_APPEND ( ' t ' , " test-case " , " the test-case tuple such as '1.2.8' " , ECORE_GETOPT_TYPE_STR ) ,
ECORE_GETOPT_STORE_STR ( ' a ' , " agent " , " the agent identifier " ) ,
ECORE_GETOPT_VERSION ( ' V ' , " version " ) ,
ECORE_GETOPT_COPYRIGHT ( ' C ' , " copyright " ) ,
ECORE_GETOPT_LICENSE ( ' L ' , " license " ) ,
ECORE_GETOPT_HELP ( ' h ' , " help " ) ,
ECORE_GETOPT_STORE_METAVAR_STR ( 0 , NULL ,
" The address (URL) to dial, such as ws://127.0.0.1:9001 " , " address " ) ,
ECORE_GETOPT_SENTINEL
}
} ;
2018-01-09 16:20:44 -08:00
EAPI_MAIN void
efl_pause ( void * data EINA_UNUSED ,
const Efl_Event * ev EINA_UNUSED )
{
}
EAPI_MAIN void
efl_resume ( void * data EINA_UNUSED ,
const Efl_Event * ev EINA_UNUSED )
{
}
EAPI_MAIN void
efl_terminate ( void * data EINA_UNUSED ,
const Efl_Event * ev EINA_UNUSED )
{
/* FIXME: For the moment the main loop doesn't get
properly destroyed on shutdown which disallow
relying on parent destroying their children */
if ( pending )
{
efl_del ( pending ) ;
pending = NULL ;
}
if ( verbose ) fprintf ( stderr , " INFO: main loop finished. \n " ) ;
}
EAPI_MAIN void
efl_main ( void * data EINA_UNUSED ,
const Efl_Event * ev )
2016-08-29 20:28:00 -07:00
{
Eina_Bool quit_option = EINA_FALSE ;
Ecore_Getopt_Value values [ ] = {
ECORE_GETOPT_VALUE_UINT ( start_index ) ,
ECORE_GETOPT_VALUE_UINT ( end_index ) ,
ECORE_GETOPT_VALUE_BOOL ( no_report_update ) ,
ECORE_GETOPT_VALUE_BOOL ( verbose ) ,
ECORE_GETOPT_VALUE_LIST ( case_tuples ) ,
ECORE_GETOPT_VALUE_STR ( agent ) ,
/* standard block to provide version, copyright, license and help */
ECORE_GETOPT_VALUE_BOOL ( quit_option ) , /* -V/--version quits */
ECORE_GETOPT_VALUE_BOOL ( quit_option ) , /* -C/--copyright quits */
ECORE_GETOPT_VALUE_BOOL ( quit_option ) , /* -L/--license quits */
ECORE_GETOPT_VALUE_BOOL ( quit_option ) , /* -h/--help quits */
/* positional argument */
ECORE_GETOPT_VALUE_STR ( address ) ,
ECORE_GETOPT_VALUE_NONE /* sentinel */
} ;
int args ;
Eina_Bool r ;
2018-01-09 16:20:44 -08:00
args = ecore_getopt_parse ( & options , values , 0 , NULL ) ;
2016-08-29 20:28:00 -07:00
if ( args < 0 )
{
fputs ( " ERROR: Could not parse command line options. \n " , stderr ) ;
goto end ;
}
if ( quit_option ) goto end ;
2018-01-09 16:20:44 -08:00
args = ecore_getopt_parse_positional ( & options , values , 0 , NULL , args ) ;
2016-08-29 20:28:00 -07:00
if ( args < 0 )
{
fputs ( " ERROR: Could not parse positional arguments. \n " , stderr ) ;
goto end ;
}
if ( case_tuples )
2018-01-09 16:20:44 -08:00
r = _websocket_test_next_case_tuple ( ev - > object ) ;
2016-08-29 20:28:00 -07:00
else if ( start_index = = end_index )
2018-01-09 16:20:44 -08:00
r = _websocket_test_index ( start_index , ev - > object ) ;
2016-08-29 20:28:00 -07:00
else
2018-01-09 16:20:44 -08:00
r = _websocket_load_tests ( ev - > object ) ;
2016-08-29 20:28:00 -07:00
if ( r )
{
ecore_main_loop_begin ( ) ;
}
if ( pending )
efl_del ( pending ) ;
2018-01-09 16:20:44 -08:00
return ;
2016-08-29 20:28:00 -07:00
2018-01-09 16:20:44 -08:00
end :
efl_loop_quit ( efl_loop_get ( ev - > object ) , eina_value_int_init ( EXIT_FAILURE ) ) ;
2016-08-29 20:28:00 -07:00
}
2018-01-09 16:20:44 -08:00
EFL_MAIN_EX ( ) ;