diff --git a/ChangeLog.txt b/ChangeLog.txt index 664ccc60d7..f29e76e431 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,32 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2025-01-23 11:47 UTC+0100 Aleksander Czajczynski (hb fki.pl) + * contrib/hbcurl/core.c + * contrib/hbcurl/hbcurl.ch + * contrib/hbcurl/hbcurl.hbx + * applied more cleanups, following Viktor Szakats guidance in his repo: + https://github.com/vszakats/hb/commit/61276032177e2f4e8cfac22080c1e0b14eb0d432 + - add `HB_CURLM_ERROR` to indicate error in hbcurl wrapper. + - replace use of `HB_CURLM_INTERNAL_ERROR` with `HB_CURLM_ERROR`. + - sync Harbour variable integer sizes with curl ones. + - tidy up a variable scopes. + - drop unused variable. + - omit `hb_ret()` (it's a no-op). + - formatting. + - add functions to `hbcurl.hbx`. + + + add curl_ws_send()/curl_ws_recv() - WebSocket connectivity, + borrowed from Viktor's fork, thanks again! + https://github.com/vszakats/hb/commit/2c71a5c9402cdbb7a649598e5a5ed6f3217d94b4 + + * src/rdd/dbcmd.c + * note about C5.3 and Harbour extensions to + DBAPPEND( [=.t.] ), thanks Viktor + + * ChangeLog.txt + ! typos + 2025-01-22 21:08 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * utils/hbmk2/hbmk2.prg * do not interrupt whole build process when optional dependency package @@ -214,7 +240,7 @@ 2025-01-10 10:15 UTC+0100 Aleksander Czajczynski (hb fki.pl) * src/rtl/listbox.prg - * merged #371 from Kamil, thanks for the patch. + * merged #372 from Kamil, thanks for the patch. Applied minor reformat .NOT. -> ! and added a comment about buggy ListBox:hitTest() on no-box dropdown in Cl*pper 5.3. @@ -246,7 +272,7 @@ + added curl lib version guards - * minor code and code formattings + * minor code and comment formattings + extended function curl_multi_info_read( [, ]) -> diff --git a/contrib/hbcurl/core.c b/contrib/hbcurl/core.c index e10d1a00e3..3d076ca85b 100644 --- a/contrib/hbcurl/core.c +++ b/contrib/hbcurl/core.c @@ -137,8 +137,7 @@ typedef struct _HB_CURL typedef struct _HB_CURLM { CURLM * curlm; - -} HB_CURLM, * PHB_CURLM; +} HB_CURLM, *PHB_CURLM; #endif /* functions to keep passed string values accessible even if HVM @@ -594,6 +593,7 @@ static void hb_curl_buff_ul_free( PHB_CURL hb_curl ) hb_curl->ul_pos = 0; } } + #if LIBCURL_VERSION_NUM >= 0x070100 static void hb_curl_buff_er_free( PHB_CURL hb_curl ) { @@ -605,6 +605,7 @@ static void hb_curl_buff_er_free( PHB_CURL hb_curl ) } } #endif + static void hb_curl_buff_dl_free( PHB_CURL hb_curl ) { if( hb_curl && hb_curl->dl_ptr ) @@ -671,9 +672,9 @@ static void PHB_CURL_free( PHB_CURL hb_curl, HB_BOOL bFree ) hb_curl_buff_ul_free( hb_curl ); hb_curl_buff_dl_free( hb_curl ); -#if LIBCURL_VERSION_NUM >= 0x070100 +#if LIBCURL_VERSION_NUM >= 0x070100 hb_curl_buff_er_free( hb_curl ); -#endif +#endif if( hb_curl->pProgressCallback ) { @@ -979,7 +980,7 @@ HB_FUNC( CURL_EASY_SETOPT ) /* HB_CURLOPT_CONV_FROM_UTF8_FUNCTION */ /* Error */ -#if LIBCURL_VERSION_NUM >= 0x070100 +#if LIBCURL_VERSION_NUM >= 0x070100 case HB_CURLOPT_ER_BUFF_SETUP: hb_curl_buff_er_free( hb_curl ); hb_curl->er_len = hb_parnldef( 3, HB_CURL_ER_BUFF_SIZE_INIT ); @@ -2551,6 +2552,77 @@ HB_FUNC( CURL_GETDATE ) hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } +/* CURLcode curl_ws_send(struct Curl_easy *data, + const void *buffer, size_t buflen, + size_t *sent, + curl_off_t framesize, + unsigned int sendflags) */ +HB_FUNC( CURL_WS_SEND ) +{ + if( PHB_CURL_is( 1 ) ) + { + CURLcode res = HB_CURLE_ERROR; + size_t sent = 0; + +#if LIBCURL_VERSION_NUM >= 0x075600 + PHB_CURL hb_curl = PHB_CURL_par( 1 ); + + if( hb_curl ) + res = curl_ws_send( hb_curl->curl, + ( const void * ) hb_parc( 2 ), ( size_t ) hb_parclen( 2 ), + &sent, + ( curl_off_t ) hb_parnint( 4 ), + ( unsigned int ) hb_parnl( 5 ) ); +#endif + + hb_storns( ( HB_SIZE ) sent, 3 ); + hb_retnl( res ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +/* CURLcode curl_ws_recv(struct Curl_easy *data, + void *buffer, size_t buflen, + size_t *recv, struct curl_ws_frame **meta) */ +HB_FUNC( CURL_WS_RECV ) +{ + if( PHB_CURL_is( 1 ) && HB_ISBYREF( 2 ) ) + { + CURLcode res = HB_CURLE_ERROR; + size_t recv = 0; + +#if LIBCURL_VERSION_NUM >= 0x075600 + PHB_CURL hb_curl = PHB_CURL_par( 1 ); + + const struct curl_ws_frame * meta = NULL; + + PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); + char * buffer; + HB_SIZE buflen; + + if( hb_itemGetWriteCL( pBuffer, &buffer, &buflen ) ) + res = curl_ws_recv( hb_curl->curl, + ( void * ) buffer, ( size_t ) buflen, + &recv, + &meta ); + + hb_stornl( meta ? meta->flags : 0, 4 ); + hb_stornint( meta ? meta->offset: 0, 5 ); + hb_stornint( meta ? meta->bytesleft: 0, 6 ); +#else + hb_stornl( 0, 4 ); + hb_stornint( 0, 5 ); + hb_stornint( 0, 6 ); +#endif + + hb_storns( ( HB_SIZE ) recv, 3 ); + hb_retnl( res ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + /* Multi interface Constructor/Destructor */ /* -------------------------------------- */ @@ -2561,7 +2633,7 @@ static void PHB_CURLM_free( PHB_CURLM hb_curlm ) hb_xfree( hb_curlm ); } -static PHB_CURLM PHB_CURLM_create( ) +static PHB_CURLM PHB_CURLM_create( void ) { CURLM * curlm = curl_multi_init(); @@ -2601,7 +2673,7 @@ static void PHB_CURLM_ret() { void ** ph = ( void ** ) hb_gcAllocate( sizeof( PHB_CURLM ), &s_gcCURLMFuncs ); - *ph = PHB_CURLM_create( ); + *ph = PHB_CURLM_create(); hb_retptrGC( ph ); } @@ -2625,7 +2697,7 @@ static PHB_CURLM PHB_CURLM_par( int iParam ) HB_FUNC( CURL_MULTI_INIT ) { #if LIBCURL_VERSION_NUM >= 0x070906 - PHB_CURLM_ret( ); + PHB_CURLM_ret(); #endif } @@ -2654,9 +2726,9 @@ HB_FUNC( CURL_MULTI_ADD_HANDLE ) if( PHB_CURLM_is( 1 ) && PHB_CURL_is( 2 ) ) { PHB_CURLM hb_curlm = PHB_CURLM_par( 1 ); - PHB_CURL hb_curl = PHB_CURL_par( 2 ); + PHB_CURL hb_curl = PHB_CURL_par( 2 ); - hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_add_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_INTERNAL_ERROR ); + hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_add_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_ERROR ); } else #endif @@ -2669,9 +2741,9 @@ HB_FUNC( CURL_MULTI_REMOVE_HANDLE ) if( PHB_CURLM_is( 1 ) && PHB_CURL_is( 2 ) ) { PHB_CURLM hb_curlm = PHB_CURLM_par( 1 ); - PHB_CURL hb_curl = PHB_CURL_par( 2 ); + PHB_CURL hb_curl = PHB_CURL_par( 2 ); - hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_remove_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_INTERNAL_ERROR ); + hb_retnl( hb_curlm && hb_curl ? ( long ) curl_multi_remove_handle( hb_curlm->curlm, hb_curl->curl) : HB_CURLM_ERROR ); } else #endif @@ -2684,7 +2756,7 @@ HB_FUNC( CURL_MULTI_PERFORM ) if( PHB_CURLM_is( 1 ) && HB_ISBYREF( 2 ) ) { - CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR; + CURLMcode res = ( CURLMcode ) HB_CURLM_ERROR; PHB_CURLM hb_curlm = PHB_CURLM_par( 1 ); if( hb_curlm ) @@ -2707,21 +2779,17 @@ HB_FUNC( CURL_MULTI_POLL ) #if LIBCURL_VERSION_NUM >= 0x074200 if( PHB_CURLM_is( 1 ) && HB_ISNUM( 2 ) ) { - - CURLMcode res = ( CURLMcode ) HB_CURLM_INTERNAL_ERROR; + CURLMcode res = ( CURLMcode ) HB_CURLM_ERROR; PHB_CURLM hb_curlm = PHB_CURLM_par( 1 ); if( hb_curlm ) - { - res = curl_multi_poll( hb_curlm->curlm, - NULL, - 0, - hb_parni(2), - NULL ); - } + res = curl_multi_poll( hb_curlm->curlm, + NULL, + 0, + hb_parni(2), + NULL ); hb_retnl( ( long ) res ); - } else #endif @@ -2734,23 +2802,21 @@ HB_FUNC( CURL_MULTI_INFO_READ ) #if LIBCURL_VERSION_NUM >= 0x070906 if( PHB_CURLM_is( 1 ) ) { - - PHB_ITEM pReturn = NULL; PHB_CURLM hb_curlm = PHB_CURLM_par( 1 ); if( hb_curlm ) { - int msgs_in_queue = 0; + int msgs_in_queue = 0; long response_code = 0; - struct CURLMsg * msg = curl_multi_info_read( hb_curlm->curlm, &msgs_in_queue ); + struct CURLMsg * msg = curl_multi_info_read( hb_curlm->curlm, &msgs_in_queue ); if( msg && curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code ) == CURLE_OK ) { PHB_ITEM pHandles = hb_param( 2, HB_IT_ARRAY ); - pReturn = hb_itemArrayNew( HB_CURLMSG_RESP_LAST ); + PHB_ITEM pReturn = hb_itemArrayNew( HB_CURLMSG_RESP_LAST ); - hb_arraySetNL( pReturn, HB_CURLMSG_RESP_LEN, ( long ) msgs_in_queue ); - hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESPONSE_CODE, ( long ) response_code ); + hb_arraySetNI( pReturn, HB_CURLMSG_RESP_LEN, msgs_in_queue ); + hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESPONSE_CODE, response_code ); hb_arraySetNL( pReturn, HB_CURLMSG_RESP_MSG, ( long ) msg->msg ); hb_arraySetNL( pReturn, HB_CURLMSG_RESP_RESULT, ( long ) msg->data.result ); hb_arraySetNI( pReturn, HB_CURLMSG_RESP_HPOS, 0 ); @@ -2766,6 +2832,7 @@ HB_FUNC( CURL_MULTI_INFO_READ ) if( ph && *ph ) { PHB_CURL hbcurl = ( PHB_CURL ) *ph; + if( hbcurl->curl == msg->easy_handle ) { hb_arraySetNL( pReturn, HB_CURLMSG_RESP_HPOS, ( long ) i ); @@ -2774,14 +2841,9 @@ HB_FUNC( CURL_MULTI_INFO_READ ) } } } + hb_itemReturnRelease( pReturn ); } } - - if( pReturn ) - hb_itemReturnRelease( pReturn ); - else - hb_ret(); - } else hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); diff --git a/contrib/hbcurl/hbcurl.ch b/contrib/hbcurl/hbcurl.ch index 566ca8616b..89e1941454 100644 --- a/contrib/hbcurl/hbcurl.ch +++ b/contrib/hbcurl/hbcurl.ch @@ -584,34 +584,33 @@ #define HB_CURLE_FTP_BAD_FILE_LIST 87 /* unable to parse FTP file list */ #define HB_CURLE_CHUNK_FAILED 88 /* chunk callback reported error */ -/* curl multi result codes. */ +/* multi interface result codes. */ +#define HB_CURLM_ERROR -9 /* request not passed to libcurl */ +#define HB_CURLM_CALL_MULTI_PERFORM -1 /* please call curl_multi_perform() or curl_multi_socket*() soon */ +#define HB_CURLM_OK 0 +#define HB_CURLM_BAD_HANDLE 1 /* the passed-in handle is not a valid CURLM handle */ +#define HB_CURLM_BAD_EASY_HANDLE 2 /* an easy handle was not good/valid */ +#define HB_CURLM_OUT_OF_MEMORY 3 /* if you ever get this, you're in deep sh*t */ +#define HB_CURLM_INTERNAL_ERROR 4 /* this is a libcurl bug */ +#define HB_CURLM_BAD_SOCKET 5 /* the passed in socket argument did not match */ +#define HB_CURLM_UNKNOWN_OPTION 6 /* curl_multi_setopt() with unsupported option */ +#define HB_CURLM_ADDED_ALREADY 7 /* an easy handle already added to a multi handle was attempted to get added - again */ +#define HB_CURLM_RECURSIVE_API_CALL 8 /* an api function was called from inside a callback */ +#define HB_CURLM_WAKEUP_FAILURE 9 /* wakeup is unavailable or failed */ +#define HB_CURLM_BAD_FUNCTION_ARGUMENT 10 /* function called with a bad parameter */ +#define HB_CURLM_ABORTED_BY_CALLBACK 11 +#define HB_CURLM_UNRECOVERABLE_POLL 12 -#define HB_CURLM_CALL_MULTI_PERFORM -1 /* please call curl_multi_perform() or curl_multi_socket*() soon */ -#define HB_CURLM_OK 0 -#define HB_CURLM_BAD_HANDLE 1 /* the passed-in handle is not a valid CURLM handle */ -#define HB_CURLM_BAD_EASY_HANDLE 2 /* an easy handle was not good/valid */ -#define HB_CURLM_OUT_OF_MEMORY 3 /* if you ever get this, you're in deep sh*t */ -#define HB_CURLM_INTERNAL_ERROR 4 /* this is a libcurl bug */ -#define HB_CURLM_BAD_SOCKET 5 /* the passed in socket argument did not match */ -#define HB_CURLM_UNKNOWN_OPTION 6 /* curl_multi_setopt() with unsupported option */ -#define HB_CURLM_ADDED_ALREADY 7 /* an easy handle already added to a multi handle was attempted to get added - again */ -#define HB_CURLM_RECURSIVE_API_CALL 8 /* an api function was called from inside a callback */ -#define HB_CURLM_WAKEUP_FAILURE 9 /* wakeup is unavailable or failed */ -#define HB_CURLM_BAD_FUNCTION_ARGUMENT 10 /* function called with a bad parameter */ -#define HB_CURLM_ABORTED_BY_CALLBACK 11 -#define HB_CURLM_UNRECOVERABLE_POLL 12 +/* curl_multi_info_read() result codes. */ +#define HB_CURLMSG_NONE 0 /* first, not used */ +#define HB_CURLMSG_DONE 1 /* This easy handle has completed. 'result' contains the CURLcode of the transfer */ -/* curl_multi_info_read result codes. */ - -#define HB_CURLMSG_NONE 0 /* first, not used */ -#define HB_CURLMSG_DONE 1 /* This easy handle has completed. 'result' contains the CURLcode of the transfer */ - -#define HB_CURLMSG_RESP_LEN 1 /* queue len */ -#define HB_CURLMSG_RESP_RESPONSE_CODE 2 /* curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE ) */ -#define HB_CURLMSG_RESP_MSG 3 /* CURLMSG */ -#define HB_CURLMSG_RESP_RESULT 4 /* CURLcode */ -#define HB_CURLMSG_RESP_HANDLE 5 /* handle to original curl_easy_init */ -#define HB_CURLMSG_RESP_HPOS 6 /* position in handle passed to curl_multi_info_read(, ) */ -#define HB_CURLMSG_RESP_LAST HB_CURLMSG_RESP_HPOS +#define HB_CURLMSG_RESP_LEN 1 /* queue len */ +#define HB_CURLMSG_RESP_RESPONSE_CODE 2 /* curl_easy_getinfo( msg->easy_handle, CURLINFO_RESPONSE_CODE ) */ +#define HB_CURLMSG_RESP_MSG 3 /* CURLMSG */ +#define HB_CURLMSG_RESP_RESULT 4 /* CURLcode */ +#define HB_CURLMSG_RESP_HANDLE 5 /* handle to original curl_easy_init */ +#define HB_CURLMSG_RESP_HPOS 6 /* position in handle passed to curl_multi_info_read(, ) */ +#define HB_CURLMSG_RESP_LAST HB_CURLMSG_RESP_HPOS #endif /* HBCURL_CH_ */ diff --git a/contrib/hbcurl/hbcurl.hbx b/contrib/hbcurl/hbcurl.hbx index 98f52a4e5c..0070883eb7 100644 --- a/contrib/hbcurl/hbcurl.hbx +++ b/contrib/hbcurl/hbcurl.hbx @@ -50,6 +50,8 @@ DYNAMIC curl_multi_remove_handle DYNAMIC curl_unescape DYNAMIC curl_version DYNAMIC curl_version_info +DYNAMIC curl_ws_recv +DYNAMIC curl_ws_send #if defined( __HBEXTREQ__ ) .OR. defined( __HBEXTERN__HBCURL__REQUEST ) #uncommand DYNAMIC => EXTERNAL diff --git a/src/rdd/dbcmd.c b/src/rdd/dbcmd.c index 282b010126..6962b07446 100644 --- a/src/rdd/dbcmd.c +++ b/src/rdd/dbcmd.c @@ -264,13 +264,14 @@ HB_FUNC( DBAPPEND ) if( pArea ) { + /* NOTE: parameter is Clipper 5.3 extension, 5.2 always unlocks */ HB_BOOL bUnLockAll = hb_parldef( 1, HB_TRUE ); HB_ERRCODE errCode; /* Clipper clears NETERR flag before APPEND */ hb_rddSetNetErr( HB_FALSE ); errCode = SELF_APPEND( pArea, bUnLockAll ); - hb_retl( errCode == HB_SUCCESS ); + hb_retl( errCode == HB_SUCCESS ); /* HB_EXTENSION */ } else hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, HB_ERR_FUNCNAME );