diff --git a/ChangeLog.txt b/ChangeLog.txt index 425171aaca..0e855942b5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,46 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2025-12-10 16:29 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * contrib/hbssl/evpmd.c + * contrib/hbssl/hbssl.h + * moved hb_EVP_MD_ptr_to_id() function from static to public area + + * contrib/hbssl/hbssl.hbx + * contrib/hbssl/hbssl.hbm + + contrib/hbssl/d2i.c + * added new functions to extract asynchronous keys and certificates + from DER data: + D2I_PUBKEY( ) -> + D2I_RSAPUBLICKEY( ) -> + D2I_X509( ) -> + + * contrib/hbssl/hbssl.hbx + * contrib/hbssl/evppkey.c + + added new functions to get/set RSA asymmetric keys parameters + encapsulated in EVP_PKEY structures: + EVP_PKEY_CTX_get_RSA_padding() + EVP_PKEY_CTX_set_RSA_padding() + EVP_PKEY_CTX_get_RSA_OAEP_md() + EVP_PKEY_CTX_set_RSA_OAEP_md() + EVP_PKEY_CTX_get_RSA_MGF1_md() + EVP_PKEY_CTX_set_RSA_MGF1_md() + + * src/common/hbdate.c + * accept up to 9 fractional digits (nanoseconds) in timestamp strings + though only first three ones (milliseconds) are significant. + Recently some tools begin to generate such timestamp values and + Harbour had problems with decoding them correctly. + + * src/compiler/hbmain.c + + allow to pass file name for source code compiled by hb_compileFromBuf() + It works like in all other versions of hb_compile*() functions - it's + enough to pass it as argument without option prefix (option prefix + is "-" on all platforms and also "/" on DOS, OS2, MS-Win). + Please remember that first parameter after control ones is used as + compiler name in generated output messages regardless of its option + prefix. + 2025-12-05 22:52 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rtl/gttrm/gttrm.c ! fixed memory leak diff --git a/contrib/hbssl/d2i.c b/contrib/hbssl/d2i.c new file mode 100644 index 0000000000..6f4398f72e --- /dev/null +++ b/contrib/hbssl/d2i.c @@ -0,0 +1,104 @@ +/* + * OpenSSL API (d2i) - Harbour interface. + * + * Copyright 2025 Przemyslaw Czerpak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file LICENSE.txt. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA (or visit https://www.gnu.org/licenses/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbssl.h" + +#include "hbapifs.h" +#include "hbapiitm.h" +#include "hbvm.h" + +#include + +HB_FUNC( D2I_PUBKEY ) +{ + const unsigned char * pszKeyDer = ( const unsigned char * ) hb_parc( 1 ); + + if( pszKeyDer ) + { + // EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); + EVP_PKEY * pKey = d2i_PUBKEY( NULL, &pszKeyDer, ( long ) hb_parclen( 1 ) ); + if( pKey ) + hb_EVP_PKEY_ret( pKey ); + else + hb_retptr( NULL ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( D2I_RSAPUBLICKEY ) +{ + const unsigned char * pszKeyDer = ( const unsigned char * ) hb_parc( 1 ); + + if( pszKeyDer ) + { + // RSA * rsa = d2i_RSAPublicKey(RSA **k, &p, pklen) + RSA * pKey = d2i_RSAPublicKey( NULL, &pszKeyDer, ( long ) hb_parclen( 1 ) ); + if( pKey ) + hb_RSA_ret( pKey ); + else + hb_retptr( NULL ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( D2I_X509 ) +{ + const unsigned char * pszCrtDer = ( const unsigned char * ) hb_parc( 1 ); + + if( pszCrtDer ) + { + // RSA * rsa = d2i_RSAPublicKey(RSA **k, &p, pklen) + X509 * x509 = d2i_X509( NULL, &pszCrtDer, ( long ) hb_parclen( 1 ) ); + if( x509 ) + hb_X509_ret( x509 ); + else + hb_retptr( NULL ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} diff --git a/contrib/hbssl/evpmd.c b/contrib/hbssl/evpmd.c index 9b55da348e..f3131cc0c7 100644 --- a/contrib/hbssl/evpmd.c +++ b/contrib/hbssl/evpmd.c @@ -157,7 +157,7 @@ const EVP_MD * hb_EVP_MD_par( int iParam ) return p; } -static int hb_EVP_MD_ptr_to_id( const EVP_MD * p ) +int hb_EVP_MD_ptr_to_id( const EVP_MD * p ) { int n; diff --git a/contrib/hbssl/evppkey.c b/contrib/hbssl/evppkey.c index 77ee457d62..a29166aafa 100644 --- a/contrib/hbssl/evppkey.c +++ b/contrib/hbssl/evppkey.c @@ -177,7 +177,7 @@ HB_FUNC( EVP_PKEY_BASE_ID ) #if OPENSSL_VERSION_NUMBER >= 0x10000000L hb_retni( EVP_PKEY_base_id( pkey ) ); #else - hb_retni( EVP_PKEY_type( hb_parni( 1 ) ) ); + hb_retni( EVP_PKEY_type( pkey->type ) ); #endif } else @@ -273,7 +273,7 @@ HB_FUNC( EVP_PKEY_ASSIGN_DSA ) HB_FUNC( EVP_PKEY_ASSIGN_DH ) { -#ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_DH if( hb_EVP_PKEY_is( 1 ) && HB_ISPOINTER( 2 ) ) { EVP_PKEY * pkey = hb_EVP_PKEY_par( 1 ); @@ -298,16 +298,174 @@ HB_FUNC( EVP_PKEY_CTX_NEW ) { hb_EVP_PKEY_CTX_ret( EVP_PKEY_CTX_new( pkey, ( ENGINE * ) hb_parptr( 2 ) ) ); } -#else + else +#elif ! defined( OPENSSL_NO_RSA ) if( hb_RSA_is( 1 ) ) { hb_itemReturn( hb_param( 1, HB_IT_POINTER ) ); } -#endif else +#endif hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); } +HB_FUNC( EVP_PKEY_CTX_SET_RSA_PADDING ) +{ +#if ! defined( OPENSSL_NO_RSA ) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx && HB_ISNUM( 2 ) ) + { + hb_retni( EVP_PKEY_CTX_set_rsa_padding( ctx, hb_parni( 2 ) ) ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#elif 0 + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + +HB_FUNC( EVP_PKEY_CTX_GET_RSA_PADDING ) +{ +#if ! defined( OPENSSL_NO_RSA ) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + int pad_mode = 0, ret; + + ret = EVP_PKEY_CTX_get_rsa_padding( ctx, &pad_mode ); + if( ret <= 0 ) + pad_mode = ret; + hb_retni( pad_mode ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#elif 0 + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + +HB_FUNC( EVP_PKEY_CTX_SET_RSA_OAEP_MD ) +{ +#if ! defined( OPENSSL_NO_RSA ) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + const EVP_MD * md = hb_EVP_MD_par( 2 ); + + if( ctx && md ) + { + hb_retni( EVP_PKEY_CTX_set_rsa_oaep_md( ctx, md ) ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#elif 0 + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + +HB_FUNC( EVP_PKEY_CTX_GET_RSA_OAEP_MD ) +{ +#if ! defined( OPENSSL_NO_RSA ) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + const EVP_MD * md = NULL; + int ret; + + ret = EVP_PKEY_CTX_get_rsa_oaep_md( ctx, &md ); + if( ret > 0 ) + ret = hb_EVP_MD_ptr_to_id( md ); + hb_retni( ret ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#elif 0 + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + +HB_FUNC( EVP_PKEY_CTX_SET_RSA_MGF1_MD ) +{ +#if ! defined( OPENSSL_NO_RSA ) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + const EVP_MD * md = hb_EVP_MD_par( 2 ); + + if( ctx && md ) + { + hb_retni( EVP_PKEY_CTX_set_rsa_mgf1_md( ctx, md ) ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#elif 0 + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + +HB_FUNC( EVP_PKEY_CTX_GET_RSA_MGF1_MD ) +{ +#if ! defined( OPENSSL_NO_RSA ) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EVP_PKEY_CTX * ctx = hb_EVP_PKEY_CTX_par( 1 ); + + if( ctx ) + { + const EVP_MD * md = NULL; + int ret; + + ret = EVP_PKEY_CTX_get_rsa_mgf1_md( ctx, &md ); + if( ret > 0 ) + ret = hb_EVP_MD_ptr_to_id( md ); + hb_retni( ret ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#elif 0 + if( hb_RSA_is( 1 ) ) + { + hb_retni( 1 ); + } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#else + hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif +} + HB_FUNC( EVP_PKEY_ENCRYPT_INIT ) { #if OPENSSL_VERSION_NUMBER >= 0x10000000L @@ -317,14 +475,16 @@ HB_FUNC( EVP_PKEY_ENCRYPT_INIT ) { hb_retni( EVP_PKEY_encrypt_init( ctx ) ); } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else if( hb_RSA_is( 1 ) ) { hb_retni( 1 ); } -#endif else hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif } #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -366,7 +526,10 @@ HB_FUNC( EVP_PKEY_ENCRYPT ) } hb_retni( ret ); } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else + #ifndef OPENSSL_NO_RSA if( hb_RSA_is( 1 ) ) { RSA * rsa = hb_RSA_par( 1 ); @@ -379,10 +542,10 @@ HB_FUNC( EVP_PKEY_ENCRYPT ) if( HB_RSA_KEY_ISPRIVATE( rsa ) ) /* private key */ - ret = RSA_private_encrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + ret = RSA_private_encrypt( flen, HB_UNCONST( from ), buffer, rsa, hb_parnidef( 4, RSA_PKCS1_PADDING ) ); else /* public key */ - ret = RSA_public_encrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + ret = RSA_public_encrypt( flen, HB_UNCONST( from ), buffer, rsa, hb_parnidef( 4, RSA_PKCS1_PADDING ) ); if( ret > 0 ) { @@ -397,9 +560,10 @@ HB_FUNC( EVP_PKEY_ENCRYPT ) } hb_retni( ret ); } -#endif else + #endif hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif } HB_FUNC( EVP_PKEY_DECRYPT_INIT ) @@ -411,14 +575,16 @@ HB_FUNC( EVP_PKEY_DECRYPT_INIT ) { hb_retni( EVP_PKEY_decrypt_init( ctx ) ); } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else if( hb_RSA_is( 1 ) ) { hb_retni( 1 ); } -#endif else hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif } HB_FUNC( EVP_PKEY_DECRYPT ) @@ -453,7 +619,10 @@ HB_FUNC( EVP_PKEY_DECRYPT ) } hb_retni( ret ); } + else + hb_errRT_BASE( EG_ARG, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); #else + #ifndef OPENSSL_NO_RSA if( hb_RSA_is( 1 ) ) { RSA * rsa = hb_RSA_par( 1 ); @@ -466,10 +635,10 @@ HB_FUNC( EVP_PKEY_DECRYPT ) if( HB_RSA_KEY_ISPRIVATE( rsa ) ) /* private key */ - ret = RSA_private_decrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + ret = RSA_private_decrypt( flen, HB_UNCONST( from ), buffer, rsa, hb_parnidef( 4, RSA_PKCS1_PADDING ) ); else /* public key */ - ret = RSA_public_decrypt( flen, HB_UNCONST( from ), buffer, rsa, RSA_PKCS1_PADDING ); + ret = RSA_public_decrypt( flen, HB_UNCONST( from ), buffer, rsa, hb_parnidef( 4, RSA_PKCS1_PADDING ) ); if( ret > 0 ) { @@ -485,9 +654,10 @@ HB_FUNC( EVP_PKEY_DECRYPT ) } hb_retni( ret ); } -#endif else + #endif hb_errRT_BASE( EG_NOFUNC, 2010, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +#endif } diff --git a/contrib/hbssl/hbssl.h b/contrib/hbssl/hbssl.h index 835a8686fc..711c8efb9a 100644 --- a/contrib/hbssl/hbssl.h +++ b/contrib/hbssl/hbssl.h @@ -236,6 +236,7 @@ extern void hb_RSA_ret( RSA * rsa ); extern HB_BOOL hb_EVP_MD_is( int iParam ); extern const EVP_MD * hb_EVP_MD_par( int iParam ); +extern int hb_EVP_MD_ptr_to_id( const EVP_MD * p ); extern HB_BOOL hb_EVP_CIPHER_is( int iParam ); extern const EVP_CIPHER * hb_EVP_CIPHER_par( int iParam ); diff --git a/contrib/hbssl/hbssl.hbm b/contrib/hbssl/hbssl.hbm index 0de61913b3..bbeeaa1f37 100644 --- a/contrib/hbssl/hbssl.hbm +++ b/contrib/hbssl/hbssl.hbm @@ -54,6 +54,7 @@ ssl_hb.c ssl_inet.c ssl_sock.c bio.c +d2i.c err.c evp.c evpciph.c diff --git a/contrib/hbssl/hbssl.hbx b/contrib/hbssl/hbssl.hbx index 0c27a70413..f681f47d64 100644 --- a/contrib/hbssl/hbssl.hbx +++ b/contrib/hbssl/hbssl.hbx @@ -72,6 +72,9 @@ DYNAMIC BIO_tell DYNAMIC BIO_test_flags DYNAMIC BIO_vfree DYNAMIC BIO_write +DYNAMIC D2I_PUBKEY +DYNAMIC D2I_RSAPUBLICKEY +DYNAMIC D2I_X509 DYNAMIC ERR_error_string DYNAMIC ERR_free_strings DYNAMIC ERR_func_error_string @@ -162,7 +165,13 @@ DYNAMIC EVP_PKEY_assign_DSA DYNAMIC EVP_PKEY_assign_RSA DYNAMIC EVP_PKEY_base_id DYNAMIC EVP_PKEY_bits +DYNAMIC EVP_PKEY_CTX_get_RSA_MGF1_md +DYNAMIC EVP_PKEY_CTX_get_RSA_OAEP_md +DYNAMIC EVP_PKEY_CTX_get_RSA_padding DYNAMIC EVP_PKEY_CTX_new +DYNAMIC EVP_PKEY_CTX_set_RSA_MGF1_md +DYNAMIC EVP_PKEY_CTX_set_RSA_OAEP_md +DYNAMIC EVP_PKEY_CTX_set_RSA_padding DYNAMIC EVP_PKEY_decrypt DYNAMIC EVP_PKEY_decrypt_init DYNAMIC EVP_PKEY_encrypt @@ -200,7 +209,7 @@ DYNAMIC OpenSSL_add_all_ciphers DYNAMIC OpenSSL_add_all_digests DYNAMIC OpenSSL_version DYNAMIC OpenSSL_version_num -DYNAMIC OPENSSL_VERSION_NUMBER +DYNAMIC OpenSSL_version_number DYNAMIC PEM_READ_BIO_DHPARAMS DYNAMIC PEM_READ_BIO_DSAPARAMS DYNAMIC PEM_READ_BIO_DSAPRIVATEKEY @@ -231,7 +240,7 @@ DYNAMIC RSA_public_decrypt DYNAMIC RSA_public_encrypt DYNAMIC RSA_size DYNAMIC SSLeay -DYNAMIC SSLEAY_VERSION +DYNAMIC SSLeay_version DYNAMIC SSL_accept DYNAMIC SSL_add_client_CA DYNAMIC SSL_alert_desc_string diff --git a/src/common/hbdate.c b/src/common/hbdate.c index 51ef993721..35747b3c28 100644 --- a/src/common/hbdate.c +++ b/src/common/hbdate.c @@ -538,10 +538,13 @@ HB_BOOL hb_timeStrGetUTC( const char * szTime, { iMSec += ( *szTime++ - '0' ) * 10; if( HB_ISDIGIT( *szTime ) ) + { + int iFrac = 3; iMSec += ( *szTime++ - '0' ); + while( HB_ISDIGIT( *szTime ) && ++iFrac <= 9 ) + ++szTime; + } } - if( HB_ISDIGIT( *szTime ) ) - ++szTime; } } } diff --git a/src/compiler/hbmain.c b/src/compiler/hbmain.c index 46e4ac1c8e..81e5a22b70 100644 --- a/src/compiler/hbmain.c +++ b/src/compiler/hbmain.c @@ -117,8 +117,19 @@ int hb_compMainExt( int argc, const char * const argv[], if( szSource ) { + const char * pszFileName = "{SOURCE}"; + int i; + /* Look for file name if any */ + for( i = 1; i < argc && ! HB_COMP_PARAM->fExit; i++ ) + { + if( ! HB_ISOPTSEP( argv[ i ][ 0 ] ) ) + { + pszFileName = argv[ i ]; + break; + } + } iFileCount++; - iStatus = hb_compCompile( HB_COMP_PARAM, "{SOURCE}", szSource, iStartLine ); + iStatus = hb_compCompile( HB_COMP_PARAM, pszFileName, szSource, iStartLine ); } else {