diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 3d19ec4491..da3217c5b0 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -10,10 +10,58 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ -2012-11-20 04:09 UTC+0100 Viktor Szakats (harbour syenar.net) - * ChangeLog - ! fixed name in recent entries. and configured hbcommit.hb - locally in yet another env. +2012-11-20 05:05 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * harbour/include/hbdefs.h + * harbour/src/common/hbwin.c + + added new C function hb_wctomblen() + + * harbour/include/hbapi.h + * harbour/src/vm/cmdarg.c + + added new C functions hb_winmainArgVBuild() and hb_winmainArgVFree() + These functions are available only in MS-Windows builds and they + use GetCommandLine() and GetModuleFileName() to build argument list. + * updated to operate on MS-Windows unicode buffers if possible. + + * harbour/src/vm/hvm.c + * initialize MS-Windows application startup parameters in hb_vmInit() + * free MS-Windows application startup parameters in hb_vmQuit() + + * harbour/include/hbwmain.c + * do not build argument list HB_VM_STARTUP mode - leave this job to + new functions + + * harbour/src/rtl/teditor.prg + * harbour/src/rtl/memoedit.prg + % do eliminated NextKey() calls to avoid unnecessary key polling + It also fixes key dropping in small typeahead buffers. + + * harbour/src/rtl/dbedit.prg + % do eliminated NextKey() calls to avoid unnecessary key polling + + * harbour/src/rtl/getsys.prg + * harbour/src/rtl/tgetlist.prg + ! fixed active loops (100% CPU usage) + + * harbour/src/rtl/gtsln/gtsln.h + ! define REAL_UNIX_SYSTEM in AIX builds - thanks to Luiz Rafael Culik + for the information + + * harbour/src/rtl/achoice.prg + % replaced Empty( NextKey() ) with NextKey() == 0 + + * harbour/src/rtl/gtsln/gtsln.h + ! define REAL_UNIX_SYSTEM in AIX builds - thanks to Luiz Rafael Culik + for the information + + * harbour/src/rtl/hbinet.c + * uese hb_parni()/hb_retni() instead of hb_parnl()/hb_retnl() for int + values + + * harbour/src/rtl/hbgtcore.c + ! comment cleanup + + * harbour/contrib/hbwin/win_svc.c + ! eliminated HB_TCHAR_* macros 2012-11-20 03:08 UTC+0100 Viktor Szakats (harbour syenar.net) * contrib/hbgd/gdwrp.c diff --git a/harbour/contrib/hbwin/win_svc.c b/harbour/contrib/hbwin/win_svc.c index 1952ee5e6f..7d9935b5a3 100644 --- a/harbour/contrib/hbwin/win_svc.c +++ b/harbour/contrib/hbwin/win_svc.c @@ -51,9 +51,9 @@ */ #include "hbwapi.h" - -#include "hbvm.h" #include "hbapiitm.h" +#include "hbvm.h" +#include "hbstack.h" #if ! defined( HB_OS_WIN_CE ) @@ -115,15 +115,13 @@ static VOID WINAPI hbwin_SvcMainFunction( DWORD dwArgc, LPTSTR * lpszArgv ) for( i = 1; i < dwArgc; ++i ) { - char * pszArg = HB_TCHAR_CONVFROM( lpszArgv[ i ] ); + PHB_ITEM pItem = hb_stackAllocItem(); - if( ! hb_cmdargIsInternal( pszArg, NULL ) ) - { - hb_vmPushString( pszArg, strlen( pszArg ) ); + HB_ITEMPUTSTR( pItem, lpszArgv[ i ] ); + if( hb_cmdargIsInternal( hb_itemGetCPtr( pItem ), NULL ) ) + hb_stackPop(); + else ++iArgCount; - } - - HB_TCHAR_FREE( pszArg ); } hb_vmSend( ( HB_USHORT ) iArgCount ); diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index c7c0b0693f..0c954237ed 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -1051,6 +1051,8 @@ extern HB_U32 hb_cmdargProcessVM( int * pCancelKey, int * pCanc #if defined( HB_OS_WIN ) extern HB_EXPORT void hb_winmainArgInit( void * hInstance, void * hPrevInstance, int iCmdShow ); /* Set WinMain() parameters */ extern HB_EXPORT HB_BOOL hb_winmainArgGet( void * phInstance, void * phPrevInstance, int * piCmdShow ); /* Retrieve WinMain() parameters */ +extern HB_EXPORT void hb_winmainArgVBuild( void ); +extern HB_EXPORT void hb_winmainArgVFree( void ); #endif /* Codeblock management */ diff --git a/harbour/include/hbdefs.h b/harbour/include/hbdefs.h index 75db65ba19..6f8a283626 100644 --- a/harbour/include/hbdefs.h +++ b/harbour/include/hbdefs.h @@ -1547,6 +1547,7 @@ typedef HB_U32 HB_FATTR; /* Features provided for Windows builds only */ HB_EXTERN_BEGIN + extern HB_EXPORT int hb_wctomblen( const wchar_t * szText ); extern HB_EXPORT wchar_t * hb_mbtowc( const char * srcA ); extern HB_EXPORT char * hb_wctomb( const wchar_t * srcW ); extern HB_EXPORT wchar_t * hb_mbntowc( const char * srcA, HB_SIZE nLen ); diff --git a/harbour/include/hbwmain.c b/harbour/include/hbwmain.c index 5e0c0c4130..b64c60b738 100644 --- a/harbour/include/hbwmain.c +++ b/harbour/include/hbwmain.c @@ -52,11 +52,6 @@ #include -#define HB_MAX_ARGS 128 - -static int s_argc = 0; -static char * s_argv[ HB_MAX_ARGS ]; - #if defined( HB_OS_WIN_CE ) # define HB_LPSTR LPWSTR #else @@ -68,30 +63,46 @@ int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ HB_LPSTR lpCmdLine, /* pointer to command line */ int iCmdShow ) /* show state of window */ { - LPSTR pArgs, pArg, pDst, pSrc; - HB_BOOL fQuoted; int iErrorCode; - HANDLE hHeap; -#if defined( HB_OS_WIN_CE ) - LPSTR pFree; -#endif + +#if defined( HB_VM_STARTUP ) + + HB_SYMBOL_UNUSED( lpCmdLine ); /* HB_TRACE(HB_TR_DEBUG, ("WinMain(%p, %p, %s, %d)", hInstance, hPrevInstance, lpCmdLine, iCmdShow)); */ - s_argv[ s_argc++ ] = ( char * ) ""; + hb_winmainArgInit( hInstance, hPrevInstance, iCmdShow ); + + hb_vmInit( HB_TRUE ); + iErrorCode = hb_vmQuit(); + +#else +# define HB_MAX_ARGS 256 + + int argc = 0; + char ** argv[ HB_MAX_ARGS ]; + + LPSTR pArgs, pArg, pDst, pSrc; + HB_BOOL fQuoted; + HANDLE hHeap; +# if defined( HB_OS_WIN_CE ) + LPSTR pFree; +# endif + + argv[ argc++ ] = ( char * ) ""; pArg = NULL; -#if defined( HB_OS_WIN_CE ) - pSrc = pFree = hb_wctomb( lpCmdLine ); -#else +# if defined( HB_OS_WIN_CE ) + pSrc = pFree = hb_wctomb( lpCmdLine ); /* No HVM stack */ +# else pSrc = lpCmdLine; -#endif +# endif hHeap = GetProcessHeap(); pDst = pArgs = ( LPSTR ) HeapAlloc( hHeap, 0, strlen( pSrc ) + 1 ); fQuoted = HB_FALSE; - while( *pSrc != 0 && s_argc < HB_MAX_ARGS ) + while( *pSrc != 0 && argc < HB_MAX_ARGS ) { if( *pSrc == '"' ) { @@ -110,7 +121,7 @@ int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ if( pArg ) { *pDst++ = '\0'; - s_argv[ s_argc++ ] = pArg; + argv[ argc++ ] = pArg; pArg = NULL; } } @@ -119,28 +130,21 @@ int WINAPI WinMain( HINSTANCE hInstance, /* handle to current instance */ if( pArg ) { *pDst = '\0'; - s_argv[ s_argc++ ] = pArg; + argv[ argc++ ] = pArg; } -#if defined( HB_OS_WIN_CE ) +# if defined( HB_OS_WIN_CE ) hb_xfree( pFree ); -#endif +# endif -#if defined( HB_VM_STARTUP ) - hb_winmainArgInit( hInstance, hPrevInstance, iCmdShow ); - hb_cmdargInit( s_argc, s_argv ); - - hb_vmInit( HB_TRUE ); - iErrorCode = hb_vmQuit(); -#else HB_SYMBOL_UNUSED( hInstance ); HB_SYMBOL_UNUSED( hPrevInstance ); HB_SYMBOL_UNUSED( iCmdShow ); - iErrorCode = main( s_argc, s_argv ); -#endif + iErrorCode = main( argc, argv ); HeapFree( hHeap, 0, ( void * ) pArgs ); +#endif return iErrorCode; } diff --git a/harbour/src/common/hbwin.c b/harbour/src/common/hbwin.c index 5ddda14f91..d96c48fad0 100644 --- a/harbour/src/common/hbwin.c +++ b/harbour/src/common/hbwin.c @@ -66,6 +66,11 @@ static HB_SIZE hb_wcnlen( const wchar_t * szText, HB_SIZE nCount ) return nLen; } +int hb_wctomblen( const wchar_t * szText ) +{ + return WideCharToMultiByte( CP_ACP, 0, szText, -1, NULL, 0, NULL, NULL ) - 1; +} + void hb_wcntombcpy( char * dstA, const wchar_t * srcW, HB_SIZE nLen ) { WideCharToMultiByte( CP_ACP, 0, srcW, -1, dstA, ( int ) nLen, NULL, NULL ); diff --git a/harbour/src/rtl/achoice.prg b/harbour/src/rtl/achoice.prg index dd7fd588f7..3775bbbc80 100644 --- a/harbour/src/rtl/achoice.prg +++ b/harbour/src/rtl/achoice.prg @@ -143,7 +143,7 @@ FUNCTION AChoice( nTop, nLeft, nBottom, nRight, acItems, xSelect, xUserFunc, nPo CASE ( bAction := SetKey( nKey ) ) != NIL Eval( bAction, ProcName( 1 ), ProcLine( 1 ), "" ) - IF Empty( NextKey() ) + IF NextKey() == 0 hb_keySetLast( 255 ) nKey := 0 ENDIF diff --git a/harbour/src/rtl/dbedit.prg b/harbour/src/rtl/dbedit.prg index 81d183da65..5d33b15b11 100644 --- a/harbour/src/rtl/dbedit.prg +++ b/harbour/src/rtl/dbedit.prg @@ -200,7 +200,7 @@ FUNCTION dbEdit( nTop, nLeft, nBottom, nRight, ; DO WHILE lContinue DO WHILE ! oBrowse:stabilize() - nKey := NextKey() + nKey := InKey() #ifdef HB_COMPAT_C53 IF nKey != 0 .AND. nKey != K_MOUSEMOVE EXIT @@ -212,7 +212,10 @@ FUNCTION dbEdit( nTop, nLeft, nBottom, nRight, ; #endif ENDDO - IF ( nKey := Inkey() ) == 0 + IF nKey == 0 + nKey := InKey() + ENDIF + IF nKey == 0 IF lDoIdleCall lContinue := CallUser( oBrowse, xUserFunc, 0, @lAppend, @lFlag ) oBrowse:forceStable() diff --git a/harbour/src/rtl/getsys.prg b/harbour/src/rtl/getsys.prg index 8dff28d22d..fa5cc15bae 100644 --- a/harbour/src/rtl/getsys.prg +++ b/harbour/src/rtl/getsys.prg @@ -310,6 +310,7 @@ FUNCTION RangeCheck( oGet, xDummy, xLow, xHigh ) LOCAL xValue LOCAL cMessage + LOCAL nKey HB_SYMBOL_UNUSED( xDummy ) @@ -330,8 +331,9 @@ FUNCTION RangeCheck( oGet, xDummy, xLow, xHigh ) hb_DispOutAt( SCORE_ROW, Min( 60, MaxCol() - Len( cMessage ) ), cMessage ) - DO WHILE NextKey() == 0 + DO WHILE ( nKey := InKey( 0 ) ) == 0 ENDDO + hb_keyIns( nKey ) hb_DispOutAt( SCORE_ROW, Min( 60, MaxCol() - Len( cMessage ) ), Space( Len( cMessage ) ) ) diff --git a/harbour/src/rtl/gtsln/gtsln.h b/harbour/src/rtl/gtsln/gtsln.h index ef7df37afd..0cd1fc0eec 100644 --- a/harbour/src/rtl/gtsln/gtsln.h +++ b/harbour/src/rtl/gtsln/gtsln.h @@ -65,7 +65,9 @@ #include "hbapicdp.h" #include "hbdate.h" -#if defined( HB_OS_DARWIN ) || ( defined( HB_OS_LINUX ) && defined( __WATCOMC__ ) ) +#if defined( HB_OS_DARWIN ) || \ + defined( HB_OS_AIX ) || \ + ( defined( HB_OS_LINUX ) && defined( __WATCOMC__ ) ) #define REAL_UNIX_SYSTEM /* this is for slang.h to include some defs */ #endif #include diff --git a/harbour/src/rtl/hbgtcore.c b/harbour/src/rtl/hbgtcore.c index e53506e4c1..f9f7033ec3 100644 --- a/harbour/src/rtl/hbgtcore.c +++ b/harbour/src/rtl/hbgtcore.c @@ -2831,8 +2831,8 @@ static void hb_gt_def_InkeyPoll( PHB_GT pGT ) /* * Clipper 5.3 always poll events without respecting * _SET_TYPEAHEAD when CL5.2 only when it's non zero. - * IMHO keeping CL5.2 behavior will be more accurate for xharbour - * because it allow to control it by user what some times could be + * IMHO keeping CL5.2 behavior will be more accurate for harbour + * because it allows to control it by user what some times could be * necessary due to different low level GT behavior on some platforms */ if( hb_setGetTypeAhead() ) diff --git a/harbour/src/rtl/hbinet.c b/harbour/src/rtl/hbinet.c index 25fb86118f..f37d293d06 100644 --- a/harbour/src/rtl/hbinet.c +++ b/harbour/src/rtl/hbinet.c @@ -478,10 +478,10 @@ HB_FUNC( HB_INETTIMELIMIT ) if( socket ) { - hb_retnl( socket->iTimeLimit ); + hb_retni( socket->iTimeLimit ); if( HB_ISNUM( 2 ) ) - socket->iTimeLimit = hb_parnl( 2 ); + socket->iTimeLimit = hb_parni( 2 ); } else hb_inetErrRT(); diff --git a/harbour/src/rtl/memoedit.prg b/harbour/src/rtl/memoedit.prg index 8671488f18..436bd290cf 100644 --- a/harbour/src/rtl/memoedit.prg +++ b/harbour/src/rtl/memoedit.prg @@ -115,12 +115,11 @@ METHOD Edit() CLASS HBMemoEditor // I need to test this condition here since I never block inside HBEditor:Edit() // if there is an user function - IF NextKey() == 0 + IF ( nKey := Inkey() ) == 0 ::IdleHook() + nKey := Inkey( 0 ) ENDIF - nKey := Inkey( 0 ) - IF ( bKeyBlock := SetKey( nKey ) ) != NIL Eval( bKeyBlock ) LOOP diff --git a/harbour/src/rtl/teditor.prg b/harbour/src/rtl/teditor.prg index 2a09137e0e..392bb1ca3e 100644 --- a/harbour/src/rtl/teditor.prg +++ b/harbour/src/rtl/teditor.prg @@ -686,12 +686,10 @@ METHOD Edit( nPassedKey ) CLASS HBEditor // If I haven't been called with a key already preset, evaluate this key and then exit IF nPassedKey == NIL - - IF NextKey() == 0 + IF ( nKey := Inkey() ) == 0 ::IdleHook() + nKey := Inkey( 0 ) ENDIF - - nKey := Inkey( 0 ) ELSE lSingleKeyProcess := .T. nKey := nPassedKey @@ -971,12 +969,10 @@ METHOD BrowseText( nPassedKey ) // If I haven't been called with a key already preset, evaluate this key and then exit IF nPassedKey == NIL - - IF NextKey() == 0 + IF ( nKey := Inkey() ) == 0 ::IdleHook() + nKey := Inkey( 0 ) ENDIF - - nKey := Inkey( 0 ) ELSE nKey := nPassedKey ENDIF diff --git a/harbour/src/rtl/tgetlist.prg b/harbour/src/rtl/tgetlist.prg index a79cd76146..3f7f14bf19 100644 --- a/harbour/src/rtl/tgetlist.prg +++ b/harbour/src/rtl/tgetlist.prg @@ -815,13 +815,15 @@ METHOD ShowScoreboard() CLASS HBGetList RETURN Self METHOD DateMsg() CLASS HBGetList + LOCAL nKey IF Set( _SET_SCOREBOARD ) hb_DispOutAt( SCORE_ROW, SCORE_COL, __natMsg( _GET_INVD_DATE ) ) - DO WHILE NextKey() == 0 + DO WHILE ( nKey := InKey( 0 ) ) == 0 ENDDO + hb_keyIns( nKey ) hb_DispOutAt( SCORE_ROW, SCORE_COL, Space( Len( __natMsg( _GET_INVD_DATE ) ) ) ) diff --git a/harbour/src/vm/cmdarg.c b/harbour/src/vm/cmdarg.c index a8eef3a233..cc0a682dc1 100644 --- a/harbour/src/vm/cmdarg.c +++ b/harbour/src/vm/cmdarg.c @@ -82,16 +82,194 @@ static char s_szAppName[ HB_PATH_MAX ]; #include "hbwinuni.h" #include -/* static LPTSTR* s_lpArgV = NULL; */ -static TCHAR s_lpAppName[ MAX_PATH ]; -static char s_szAppName[ MAX_PATH ]; -static int s_fSkipAppName = HB_FALSE; +static LPTSTR* s_lpArgV = NULL; +#ifdef UNICODE +static LPSTR * s_lpArgVStr = NULL; +#endif static HANDLE s_hInstance = 0; static HANDLE s_hPrevInstance = 0; static int s_iCmdShow = 0; static HB_BOOL s_WinMainParam = HB_FALSE; +void hb_winmainArgVBuild( void ) +{ + LPCTSTR lpCmdLine, lpSrc; + LPTSTR * lpArgV; + LPTSTR lpDst, lpArg; + HB_SIZE nSize, nModuleName; + int iArgC; + HB_BOOL fQuoted; + HANDLE hHeap; + + hHeap = GetProcessHeap(); + lpCmdLine = GetCommandLine(); + nModuleName = GetModuleFileName( NULL, NULL, 0 ); + lpArgV = NULL; + lpDst = NULL; + nSize = 0; + iArgC = -1; + + while( lpCmdLine && !lpArgV && iArgC != 0 ) + { + if( nSize != 0 ) + { + lpArgV = ( LPTSTR * ) HeapAlloc( hHeap, 0, + iArgC * sizeof( LPTSTR ) + + nSize * sizeof( TCHAR ) ); + lpDst = ( LPTSTR ) ( lpArgV + iArgC ); + lpArgV[ 0 ] = lpDst; + lpDst += nModuleName; + } + else + { + lpDst = ( LPTSTR ) lpCmdLine; + nSize = nModuleName; + } + + lpSrc = lpCmdLine; + lpArg = NULL; + iArgC = 0; + fQuoted = HB_FALSE; + + while( *lpSrc != 0 ) + { + if( *lpSrc == TEXT( '"' ) ) + { + if( lpArg == NULL ) + lpArg = lpDst; + fQuoted = !fQuoted; + } + else if( fQuoted || !HB_ISSPACE( *lpSrc ) ) + { + if( lpArg == NULL ) + lpArg = lpDst; + if( iArgC > 0 || nModuleName == 0 ) + { + if( lpArgV ) + *lpDst++ = *lpSrc; + else + nSize++; + } + } + else + { + if( lpArg ) + { + if( iArgC > 0 || nModuleName == 0 ) + { + if( lpArgV ) + { + *lpDst++ = '\0'; + lpArgV[ iArgC ] = lpArg; + } + else + nSize++; + } + iArgC++; + lpArg = NULL; + } + } + ++lpSrc; + } + if( lpArg ) + { + if( iArgC > 0 || nModuleName == 0 ) + { + if( lpArgV ) + { + *lpDst = '\0'; + lpArgV[ iArgC ] = lpArg; + } + else + nSize++; + } + iArgC++; + } + } + + if( iArgC <= 0 ) + { + if( nModuleName != 0 ) + { + iArgC = 1; + lpArgV = ( LPTSTR * ) HeapAlloc( hHeap, 0, + iArgC * sizeof( LPTSTR ) + + nSize * sizeof( TCHAR ) ); + lpArgV[ 0 ] = ( LPTSTR ) ( lpArgV + iArgC );; + } + else + iArgC = 0; + } + if( iArgC > 0 && nModuleName ) + { + /* NOTE: Manually setup the executable name in Windows, + because in console apps the name may be truncated + in some cases, and in GUI apps it's not filled + at all. [vszakats] */ + if( GetModuleFileName( NULL, lpArgV[ 0 ], nModuleName ) != 0 ) + { + /* Windows XP does not set trailing 0 if buffer is not large enough [druzus] */ + lpArgV[ 0 ][ nModuleName - 1 ] = 0; + } + } + + hb_winmainArgVFree(); + + if( iArgC > 0 ) + { + s_lpArgV = lpArgV; + s_argc = iArgC; +#ifdef UNICODE + { + LPSTR lpStr; + + nSize = 0; + for( iArgC = 0; iArgC < s_argc; ++iArgC ) + nSize += hb_wctomblen( s_lpArgV[ iArgC ] ) + 1; + + s_lpArgVStr = ( LPSTR * ) HeapAlloc( hHeap, 0, + iArgC * sizeof( LPSTR ) + + nSize * sizeof( char ) ); + lpStr = ( LPSTR ) ( s_lpArgVStr + iArgC ); + for( iArgC = 0; iArgC < s_argc; ++iArgC ) + { + nSize = hb_wctomblen( s_lpArgV[ iArgC ] ) + 1; + hb_wcntombcpy( lpStr, s_lpArgV[ iArgC ], nSize ); + s_lpArgVStr[ iArgC ] = lpStr; + lpStr += nSize; + } + s_argv = s_lpArgVStr; + } +#else + s_argv = s_lpArgV; +#endif + } +} + +void hb_winmainArgVFree( void ) +{ + if( s_lpArgV ) + { +#ifdef UNICODE + if( s_lpArgVStr ) + { + if( s_argv == s_lpArgVStr ) + s_argv = NULL; + HeapFree( GetProcessHeap(), 0, ( void * ) s_lpArgVStr ); + s_lpArgVStr = NULL; + } +#else + if( s_argv == s_lpArgV ) + s_argv = NULL; +#endif + + HeapFree( GetProcessHeap(), 0, ( void * ) s_lpArgV ); + s_lpArgV = NULL; + s_argc = 0; + } +} + void hb_winmainArgInit( void * hInstance, void * hPrevInstance, int iCmdShow ) { s_hInstance = ( HANDLE ) hInstance; @@ -118,6 +296,11 @@ void hb_cmdargInit( int argc, char * argv[] ) { HB_TRACE( HB_TR_DEBUG, ( "hb_cmdargInit(%d, %p)", argc, argv ) ); +#if defined( HB_OS_WIN ) + if( s_lpArgV ) + return; +#endif + if( argc == 0 || argv == NULL ) { s_argc = 0; @@ -149,7 +332,10 @@ const char * hb_cmdargARGVN( int argc ) static char * hb_cmdargDup( int argc ) { - /* TODO: TCHAR conv */ +#if defined( HB_OS_WIN ) + if( s_lpArgV ) + return argc >= 0 && argc < s_argc ? HB_OSSTRDUP( s_lpArgV[ argc ] ) : NULL; +#endif return argc >= 0 && argc < s_argc ? hb_osStrDecode( s_argv[ argc ] ) : NULL; } @@ -157,26 +343,10 @@ void hb_cmdargUpdate( void ) { HB_TRACE( HB_TR_DEBUG, ( "hb_cmdargUpdate()" ) ); +#if !defined( HB_OS_WIN ) if( s_argc > 0 ) { -#if defined( HB_OS_WIN ) - /* TODO: TCHAR conv */ - - /* NOTE: Manually setup the executable name in Windows, - because in console apps the name may be truncated - in some cases, and in GUI apps it's not filled - at all. [vszakats] */ - if( GetModuleFileName( NULL, s_lpAppName, HB_SIZEOFARRAY( s_lpAppName ) ) != 0 ) - { - /* Windows XP does not set trailing 0 if buffer is not large enough [druzus] */ - s_lpAppName[ HB_SIZEOFARRAY( s_lpAppName ) - 1 ] = 0; - HB_TCHAR_COPYFROM( s_szAppName, s_lpAppName, HB_SIZEOFARRAY( s_szAppName ) - 1 ); - s_argv[ 0 ] = s_szAppName; - } - else - s_lpAppName[ 0 ] = 0; - -#elif defined( HB_OS_OS2 ) +# if defined( HB_OS_OS2 ) { PPIB ppib = NULL; APIRET ulrc; @@ -191,7 +361,7 @@ void hb_cmdargUpdate( void ) s_argv[ 0 ] = s_szAppName; } } -#else +# else /* NOTE: try to create absolute path from s_argv[ 0 ] if necessary */ { PHB_FNAME pFName = hb_fsFNameSplit( s_argv[ 0 ] ); @@ -235,11 +405,11 @@ void hb_cmdargUpdate( void ) } if( pFName->szPath ) { -# if defined( HB_OS_HAS_DRIVE_LETTER ) +# if defined( HB_OS_HAS_DRIVE_LETTER ) if( pFName->szPath[ 0 ] != HB_OS_PATH_DELIM_CHR && ! pFName->szDrive ) -# else +# else if( pFName->szPath[ 0 ] != HB_OS_PATH_DELIM_CHR ) -# endif +# endif { if( pFName->szPath[ 0 ] == '.' && pFName->szPath[ 1 ] == HB_OS_PATH_DELIM_CHR ) @@ -261,24 +431,28 @@ void hb_cmdargUpdate( void ) } hb_xfree( pFName ); } -#endif +# endif } +#endif } /* places application parameters on the HVM stack */ int hb_cmdargPushArgs( void ) { - int argc = hb_cmdargARGC(); - char ** argv = hb_cmdargARGV(); int iArgCount = 0, i; - for( i = 1; i < argc; i++ ) + for( i = 1; i < s_argc; i++ ) { /* Filter out any parameters beginning with //, like //INFO */ - if( ! hb_cmdargIsInternal( argv[ i ], NULL ) ) + if( ! hb_cmdargIsInternal( s_argv[ i ], NULL ) ) { - hb_vmPushString( argv[ i ], strlen( argv[ i ] ) ); +#if defined( HB_OS_WIN ) + if( s_lpArgV ) + HB_ITEMPUTSTR( hb_stackAllocItem(), s_lpArgV[ i ] ); + else +#endif + hb_vmPushString( s_argv[ i ], strlen( s_argv[ i ] ) ); iArgCount++; } } @@ -332,13 +506,25 @@ static char * hb_cmdargGet( const char * pszName, HB_BOOL bRetValue ) { if( bRetValue ) { - /* TODO: TCHAR conv */ - char * pszPos = s_argv[ i ] + iPrefixLen + strlen( pszName ); +#if defined( HB_OS_WIN ) + if( s_lpArgV ) + { + LPCTSTR lpPos = s_lpArgV[ i ] + iPrefixLen + strlen( pszName ); - if( *pszPos == ':' ) - pszPos++; + if( *lpPos == TEXT( ':' ) ) + lpPos++; + return HB_OSSTRDUP( lpPos ); + } + else +#endif + { + char * pszPos = s_argv[ i ] + iPrefixLen + strlen( pszName ); - return hb_osStrDecode( pszPos ); + if( *pszPos == ':' ) + pszPos++; + + return hb_osStrDecode( pszPos ); + } } else return ( char * ) ""; @@ -451,22 +637,6 @@ int hb_cmdargNum( const char * pszName ) char * hb_cmdargProgName( void ) { -#if defined( HB_OS_WIN ) - /* TODO: TCHAR conv */ - if( ! s_fSkipAppName ) - { - if( s_lpAppName[ 0 ] == 0 ) - { - if( GetModuleFileName( NULL, s_lpAppName, HB_SIZEOFARRAY( s_lpAppName ) ) != 0 ) - /* Windows XP does not set trailing 0 if buffer is not large enough [druzus] */ - s_lpAppName[ HB_SIZEOFARRAY( s_lpAppName ) - 1 ] = 0; - else - s_lpAppName[ 0 ] = 0; - } - if( s_lpAppName[ 0 ] != 0 ) - return HB_OSSTRDUP( s_lpAppName ); - } -#endif return hb_cmdargDup( 0 ); } @@ -545,10 +715,10 @@ HB_FUNC( HB_ARGSHIFT ) { if( ! hb_cmdargIsInternal( s_argv[ iArg ], NULL ) ) { - /* TODO: TCHAR conv */ s_argv[ 0 ] = s_argv[ iArg ]; #if defined( HB_OS_WIN ) - s_fSkipAppName = HB_TRUE; + if( s_lpArgV ) + s_lpArgV[ 0 ] = s_lpArgV[ iArg ]; #endif break; } @@ -560,8 +730,11 @@ HB_FUNC( HB_ARGSHIFT ) --s_argc; while( iArg < s_argc ) { - /* TODO: TCHAR conv */ s_argv[ iArg ] = s_argv[ iArg + 1 ]; +#if defined( HB_OS_WIN ) + if( s_lpArgV ) + s_lpArgV[ iArg ] = s_lpArgV[ iArg + 1 ]; +#endif ++iArg; } } @@ -569,32 +742,58 @@ HB_FUNC( HB_ARGSHIFT ) HB_FUNC( HB_CMDLINE ) { - char** argv = hb_cmdargARGV(); - int argc = hb_cmdargARGC(); - char * pszBuffer, * ptr; - HB_SIZE nLen; - int iArg; - - /* TODO: TCHAR conv */ - - nLen = 0; - for( iArg = 1; iArg < argc; iArg++ ) - nLen += strlen( argv[ iArg ] ) + 1; - - if( nLen ) + if( s_argc > 1 ) { - ptr = pszBuffer = ( char * ) hb_xgrab( nLen ); - for( iArg = 1; iArg < argc; iArg++ ) - { - nLen = strlen( argv[ iArg ] ); - memcpy( ptr, argv[ iArg ], nLen ); - ptr += nLen; - *ptr++ = ' '; - } - *--ptr = '\0'; + HB_SIZE nLen = 0; + int iArg; - /* Convert from OS codepage */ - hb_retc_buffer( ( char * ) hb_osDecodeCP( pszBuffer, NULL, NULL ) ); +#if defined( HB_OS_WIN ) + if( s_lpArgV ) + { + LPTSTR lpBuffer, ptr; + + for( iArg = 1; iArg < s_argc; iArg++ ) + nLen += HB_STRLEN( s_lpArgV[ iArg ] ) + 1; + + ptr = lpBuffer = ( LPTSTR ) hb_xgrab( nLen * sizeof( TCHAR ) ); + for( iArg = 1; iArg < s_argc; iArg++ ) + { + nLen = HB_STRLEN( s_lpArgV[ iArg ] ); + memcpy( ptr, s_lpArgV[ iArg ], nLen * sizeof( TCHAR ) ); + ptr += nLen; + *ptr++ = TEXT( ' ' ); + } + *--ptr = TEXT( '\0' ); + + /* Convert from OS codepage */ +#ifdef UNICODE + HB_RETSTR( lpBuffer ); + hb_xfree( lpBuffer ); +#else + hb_retc_buffer( ( char * ) hb_osDecodeCP( lpBuffer, NULL, NULL ) ); +#endif + } + else +#endif + { + char * pszBuffer, * ptr; + + for( iArg = 1; iArg < s_argc; iArg++ ) + nLen += strlen( s_argv[ iArg ] ) + 1; + + ptr = pszBuffer = ( char * ) hb_xgrab( nLen ); + for( iArg = 1; iArg < s_argc; iArg++ ) + { + nLen = strlen( s_argv[ iArg ] ); + memcpy( ptr, s_argv[ iArg ], nLen ); + ptr += nLen; + *ptr++ = ' '; + } + *--ptr = '\0'; + + /* Convert from OS codepage */ + hb_retc_buffer( ( char * ) hb_osDecodeCP( pszBuffer, NULL, NULL ) ); + } } else hb_retc_null(); diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 968a33b9ad..4f3df4bfca 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -972,6 +972,10 @@ void hb_vmInit( HB_BOOL bStartMainProc ) { HB_TRACE( HB_TR_DEBUG, ( "hb_vmInit()" ) ); +#if defined( HB_OS_WIN ) + hb_winmainArgVBuild(); +#endif + hb_xinit(); hb_vmSetExceptionHandler(); @@ -1218,6 +1222,10 @@ int hb_vmQuit( void ) hb_xexit(); +#if defined( HB_OS_WIN ) + hb_winmainArgVFree(); +#endif + return s_nErrorLevel; }