From 57cfb43c6b6005ea85b793b52fc360fbcf7edc04 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Wed, 6 Jun 2012 00:09:09 +0000 Subject: [PATCH] 2012-06-06 02:07 UTC+0200 Viktor Szakats (harbour syenar.net) + contrib/hbrun/pullextp.hb * contrib/hbrun/hbrun.hbp * contrib/hbrun/hbrun.prg * contrib/hbrun/plugins.prg * contrib/hbrun/pullext.prg + added experimental support for dynamic loading of modules into hbrun. Modules can be speficied using HBRUN_DYN envvar using space delimited list, or using text file named 'hbrun.dyn' in the same dir as hbrun, each line containing module name, lines beginning with '#' are considered comments. Modules can be loaded/unloaded from the console using 'dyn.load ', 'dyn.unload ' commands and listed using 'dyn.list'. F.e.: 'dyn.load hbgd' Names, UI and everything else may still change. Important: hbrun must be built in -shared mode for this to work, notice that by default it's built in -static mode ATM. Loadable modules can be created using HB_BUILD_CONTRIB_DYN=yes Harbour build-time option. Headers belonging to dynamic modules are not available in embedded for, so they need to be present on disk in current dir. --- harbour/ChangeLog | 32 ++++- harbour/contrib/hbrun/hbrun.hbp | 3 +- harbour/contrib/hbrun/hbrun.prg | 208 ++++++++++++++++++------------ harbour/contrib/hbrun/plugins.prg | 1 + harbour/contrib/hbrun/pullext.prg | 55 +++++++- harbour/contrib/hbrun/pullextp.hb | 113 ++++++++++++++++ 6 files changed, 320 insertions(+), 92 deletions(-) create mode 100644 harbour/contrib/hbrun/pullextp.hb diff --git a/harbour/ChangeLog b/harbour/ChangeLog index f33a8a3fd8..8513b9f734 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,18 +16,42 @@ The license applies to all entries newer than 2009-04-28. */ +2012-06-06 02:07 UTC+0200 Viktor Szakats (harbour syenar.net) + + contrib/hbrun/pullextp.hb + * contrib/hbrun/hbrun.hbp + * contrib/hbrun/hbrun.prg + * contrib/hbrun/plugins.prg + * contrib/hbrun/pullext.prg + + added experimental support for dynamic loading of + modules into hbrun. Modules can be speficied using + HBRUN_DYN envvar using space delimited list, or + using text file named 'hbrun.dyn' in the same dir + as hbrun, each line containing module name, lines + beginning with '#' are considered comments. Modules + can be loaded/unloaded from the console using + 'dyn.load ', 'dyn.unload ' commands + and listed using 'dyn.list'. F.e.: 'dyn.load hbgd' + Names, UI and everything else may still change. + Important: hbrun must be built in -shared mode + for this to work, notice that by default it's built + in -static mode ATM. Loadable modules can be created + using HB_BUILD_CONTRIB_DYN=yes Harbour build-time + option. Headers belonging to dynamic modules are + not available in embedded for, so they need to + be present on disk in current dir. + 2012-06-05 15:54 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com) * contrib/hbqt/qtcore/hbqt_bind.cpp + Implemented: Harbour way of looking at hbQT. QAction has been controlled, which has facilitated to achieve the desired behavior. + contrib/hbqt/tests/qtrevamp.prg - + Added: demo source to review if __HBQT_REVAMP__ protocol is - upto Harbour expectations. I have added few notes here and there + + Added: demo source to review if __HBQT_REVAMP__ protocol is + upto Harbour expectations. I have added few notes here and there so that user is aware of some sublities. - ; NOTE: please add to qtrevamp.prg any functionality to test all - parts of Qt which may not be confirming to Harbour vision, + ; NOTE: please add to qtrevamp.prg any functionality to test all + parts of Qt which may not be confirming to Harbour vision, and report back on the list. 2012-06-05 23:00 UTC+0200 Viktor Szakats (harbour syenar.net) diff --git a/harbour/contrib/hbrun/hbrun.hbp b/harbour/contrib/hbrun/hbrun.hbp index 1c88eed77d..6d1a86c79a 100644 --- a/harbour/contrib/hbrun/hbrun.hbp +++ b/harbour/contrib/hbrun/hbrun.hbp @@ -18,7 +18,7 @@ hbrun.prg --request=__hbrun_extensions +-request=__hbrun_extensions_get_list headers.prg plugins.prg pullext.prg @@ -33,6 +33,7 @@ hbrun.rc # Plugins +-I. -I../hbnetio/utils/hbnetio # Here comes the list of contribs linked in: diff --git a/harbour/contrib/hbrun/hbrun.prg b/harbour/contrib/hbrun/hbrun.prg index 3ecf9e1654..402220f0a1 100644 --- a/harbour/contrib/hbrun/hbrun.prg +++ b/harbour/contrib/hbrun/hbrun.prg @@ -6,8 +6,8 @@ * Harbour Project source code: * "DOt Prompt" Console and .prg/.hrb runner for the Harbour Language * - * Copyright 2007 Przemyslaw Czerpak * Copyright 2008-2012 Viktor Szakats (harbour syenar.net) + * Copyright 2007 Przemyslaw Czerpak * www - http://harbour-project.org * * This program is free software; you can redistribute it and/or modify @@ -92,94 +92,104 @@ PROCEDURE _APPMAIN( cFile, ... ) LOCAL cExt LOCAL hHeaders + LOCAL aDynamic := {} + + LoadDynamicFromFile( aDynamic, hb_DirBase() + "hbrun.dyn" ) + LoadDynamicFromString( aDynamic, GetEnv( "HBRUN_DYN" ) ) + /* TODO: Rework parameter handling */ IF PCount() > 0 SWITCH Lower( cFile ) - CASE "-?" - CASE "-h" - CASE "--help" - CASE "/?" - CASE "/h" - hbrun_Usage() - EXIT - CASE "-v" - CASE "/v" - hbrun_Prompt( hb_AParams(), "? hb_version()" ) - EXIT + CASE "-?" + CASE "-h" + CASE "--help" + CASE "/?" + CASE "/h" + hbrun_Usage() + EXIT + CASE "-v" + CASE "/v" + hbrun_Prompt( hb_AParams(), "? hb_version()" ) + EXIT #if defined( __PLATFORM__WINDOWS ) - CASE "-r" - CASE "-ra" - CASE "/r" - CASE "/ra" - IF win_reg_self( .T., Right( Lower( cFile ), 1 ) == "a" ) - OutStd( "hbrun: Harbour Script File registered" + hb_eol() ) - ELSE - OutErr( "hbrun: Error: Registering Harbour Script File" + hb_eol() ) - ENDIF - EXIT - CASE "-u" - CASE "-ua" - CASE "/u" - CASE "/ua" - IF win_reg_self( .F., Right( Lower( cFile ), 1 ) == "a" ) - OutStd( "hbrun: Harbour Script File unregistered" + hb_eol() ) - ELSE - OutErr( "hbrun: Error: Unregistering Harbour Script File" + hb_eol() ) - ENDIF - EXIT + CASE "-r" + CASE "-ra" + CASE "/r" + CASE "/ra" + IF win_reg_self( .T., Right( Lower( cFile ), 1 ) == "a" ) + OutStd( "hbrun: Harbour Script File registered" + hb_eol() ) + ELSE + OutErr( "hbrun: Error: Registering Harbour Script File" + hb_eol() ) + ENDIF + EXIT + CASE "-u" + CASE "-ua" + CASE "/u" + CASE "/ua" + IF win_reg_self( .F., Right( Lower( cFile ), 1 ) == "a" ) + OutStd( "hbrun: Harbour Script File unregistered" + hb_eol() ) + ELSE + OutErr( "hbrun: Error: Unregistering Harbour Script File" + hb_eol() ) + ENDIF + EXIT #endif - CASE "-p" - CASE "/p" - s_lPreserveHistory := .F. + CASE "-p" + CASE "/p" + s_lPreserveHistory := .F. + hbrun_extensionlist_init( aDynamic ) + hbrun_Prompt( hb_AParams() ) + EXIT + OTHERWISE + IF Left( cFile, 2 ) == "--" + hbrun_extensionlist_init( aDynamic ) hbrun_Prompt( hb_AParams() ) EXIT - OTHERWISE - IF Left( cFile, 2 ) == "--" - hbrun_Prompt( hb_AParams() ) - EXIT - ELSE - cFile := hbrun_FindInPath( cFile ) - IF ! Empty( cFile ) - hb_FNameSplit( cFile, NIL, NIL, @cExt ) - cExt := Lower( cExt ) - SWITCH cExt - CASE ".prg" - CASE ".hb" - CASE ".hbs" - CASE ".hrb" - CASE ".dbf" - EXIT - OTHERWISE - cExt := hbrun_FileSig( cFile ) - ENDSWITCH - SWITCH cExt - CASE ".dbf" - hbrun_Prompt( hb_AParams(), "USE " + cFile + " SHARED" ) - EXIT - CASE ".prg" - CASE ".hb" - CASE ".hbs" - IF Empty( GetEnv( "HBRUN_NOHEAD" ) ) - hHeaders := __hbrun_CoreHeaderFiles() /* add core header files */ - ENDIF + ELSE + cFile := hbrun_FindInPath( cFile ) + IF ! Empty( cFile ) + hb_FNameSplit( cFile, NIL, NIL, @cExt ) + cExt := Lower( cExt ) + SWITCH cExt + CASE ".prg" + CASE ".hb" + CASE ".hbs" + CASE ".hrb" + CASE ".dbf" + EXIT + OTHERWISE + cExt := hbrun_FileSig( cFile ) + ENDSWITCH + SWITCH cExt + CASE ".dbf" + hbrun_extensionlist_init( aDynamic ) + hbrun_Prompt( hb_AParams(), "USE " + cFile + " SHARED" ) + EXIT + CASE ".prg" + CASE ".hb" + CASE ".hbs" + IF Empty( GetEnv( "HBRUN_NOHEAD" ) ) + hHeaders := __hbrun_CoreHeaderFiles() /* add core header files */ + ENDIF - cFile := hb_compileBuf( hHeaders, hb_ProgName(), "-n2", "-w", "-es2", "-q0", ; - "-I" + hb_FNameDir( cFile ), "-D" + "__HBSCRIPT__HBRUN", cFile ) - IF cFile == NIL - ErrorLevel( 1 ) - EXIT - ENDIF - OTHERWISE - s_cDirBase := hb_DirBase() - s_cProgName := hb_ProgName() - hb_argShift( .T. ) - hb_hrbRun( cFile, ... ) + cFile := hb_compileBuf( hHeaders, hb_ProgName(), "-n2", "-w", "-es2", "-q0", ; + "-I" + hb_FNameDir( cFile ), "-D" + "__HBSCRIPT__HBRUN", cFile ) + IF cFile == NIL + ErrorLevel( 1 ) EXIT - ENDSWITCH - ENDIF + ENDIF + OTHERWISE + hbrun_extensionlist_init( aDynamic ) + s_cDirBase := hb_DirBase() + s_cProgName := hb_ProgName() + hb_argShift( .T. ) + hb_hrbRun( cFile, ... ) + EXIT + ENDSWITCH ENDIF + ENDIF ENDSWITCH ELSE + hbrun_extensionlist_init( aDynamic ) hbrun_Prompt( hb_AParams() ) ENDIF @@ -199,15 +209,47 @@ EXIT PROCEDURE hbrun_exit() RETURN -STATIC FUNCTION hbrun_extensionlist() - STATIC s_aList +STATIC PROCEDURE LoadDynamicFromFile( aDynamic, cFileName ) + LOCAL cItem - IF s_aList == NIL - s_aList := iif( Type( "__HBRUN_EXTENSIONS()" ) == "UI", &( "__hbrun_extensions()" ), {} ) - ASort( s_aList ) + FOR EACH cItem IN hb_ATokens( StrTran( MemoRead( cFileName ), Chr( 13 ) ), Chr( 10 ) ) + IF "#" $ cItem + cItem := Left( cItem, At( "#", cItem ) - 1 ) + ENDIF + AAdd( aDynamic, cItem ) + NEXT + + RETURN + +STATIC PROCEDURE LoadDynamicFromString( aDynamic, cString ) + LOCAL cItem + + FOR EACH cItem IN hb_ATokens( cString,, .T. ) + AAdd( aDynamic, cItem ) + NEXT + + RETURN + +STATIC PROCEDURE hbrun_extensionlist_init( aDynamic ) + STATIC s_lInit := .F. + + IF ! s_lInit + IF Type( "__HBRUN_EXTENSIONS_GET_LIST()" ) == "UI" + Do( "__hbrun_extensions_init_static" ) + Do( "__hbrun_extensions_init_dynamic", aDynamic ) + ENDIF + s_lInit := .T. ENDIF - RETURN s_aList + RETURN + +STATIC FUNCTION hbrun_extensionlist() + LOCAL aList := iif( Type( "__HBRUN_EXTENSIONS_GET_LIST()" ) == "UI", Do( "__hbrun_extensions_get_list" ), {} ) + ASort( aList,,, {| x, y | __proc_name_for_sort( x ) < __proc_name_for_sort( y ) } ) + RETURN aList + +STATIC FUNCTION __proc_name_for_sort( c ) + RETURN iif( IsAlpha( Left( c, 1 ) ) .OR. IsDigit( Left( c, 1 ) ), c, SubStr( c, 2 ) ) STATIC FUNCTION hbrun_FileSig( cFile ) LOCAL hFile diff --git a/harbour/contrib/hbrun/plugins.prg b/harbour/contrib/hbrun/plugins.prg index f3fce38161..d9b04c54b5 100644 --- a/harbour/contrib/hbrun/plugins.prg +++ b/harbour/contrib/hbrun/plugins.prg @@ -60,6 +60,7 @@ FUNCTION __hbrun_plugins() LOCAL file ADD PLUGIN TO hPlugins FILE "netiomgm.prg" + ADD PLUGIN TO hPlugins FILE "pullextp.hb" FOR EACH file IN Directory( hb_DirBase() + "*.hb" ) hPlugins[ hb_DirBase() + file[ F_NAME ] ] := MemoRead( hb_DirBase() + file[ F_NAME ] ) diff --git a/harbour/contrib/hbrun/pullext.prg b/harbour/contrib/hbrun/pullext.prg index 9f2b360f75..5f3df8476a 100644 --- a/harbour/contrib/hbrun/pullext.prg +++ b/harbour/contrib/hbrun/pullext.prg @@ -50,10 +50,11 @@ * */ -FUNCTION __hbrun_extensions() - LOCAL aList := {} +STATIC s_hLib := { => } - #xtranslate PULLEXT => REQUEST __HBEXTERN____ ; AAdd( aList, Lower( <"cName"> ) ) +PROCEDURE __hbrun_extensions_init_static() + + #xtranslate PULLEXT => REQUEST __HBEXTERN____ ; s_hLib\[ Lower( <"cName"> ) \] := NIL PULLEXT hbct PULLEXT hbxpp @@ -68,4 +69,50 @@ FUNCTION __hbrun_extensions() PULLEXT hbwin #endif - RETURN aList + RETURN + +/* Requires hbrun to be built in -shared mode */ + +PROCEDURE __hbrun_extensions_init_dynamic( aDynamic ) + LOCAL cName + + IF ! Empty( aDynamic ) + FOR EACH cName IN aDynamic + __hbrun_extensions_load_one( cName ) + NEXT + ENDIF + + RETURN + +PROCEDURE __hbrun_extensions_load_one( cName ) + LOCAL cFileName + LOCAL hLib + + IF !( cName $ s_hLib ) + IF hb_FileExists( cFileName := hb_libName( cName + hb_libPostfix() ) ) + hLib := hb_libLoad( cFileName ) + IF ! Empty( hLib ) + s_hLib[ cName ] := hLib + ENDIF + ENDIF + ENDIF + + RETURN + +PROCEDURE __hbrun_extensions_unload_one( cName ) + + IF cName $ s_hLib .AND. s_hLib[ cName ] != NIL + hb_HDel( s_hLib, cName ) + ENDIF + + RETURN + +FUNCTION __hbrun_extensions_get_list() + LOCAL aName := Array( Len( s_hLib ) ) + LOCAL hLib + + FOR EACH hLib IN s_hLib + aName[ hLib:__enumIndex() ] := iif( Empty( hLib ), "", "*" ) + hLib:__enumKey() + NEXT + + RETURN aName diff --git a/harbour/contrib/hbrun/pullextp.hb b/harbour/contrib/hbrun/pullextp.hb new file mode 100644 index 0000000000..5c729807e7 --- /dev/null +++ b/harbour/contrib/hbrun/pullextp.hb @@ -0,0 +1,113 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * dynamic module manager plugin + * + * Copyright 2012 Viktor Szakats (harbour syenar.net) + * www - http://harbour-project.org + * + * 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * 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. + * + */ + +FUNCTION __hbrun_plugin() + RETURN {; + "id" => "dyn",; + "init" => {| hConIO | dyn_init( hConIO ) } ,; + "exit" => {| context | HB_SYMBOL_UNUSED( context ) } ,; + "cmd" => {| context, cCommand | dyn_command( context, cCommand ) } } + +STATIC FUNCTION dyn_init( hConIO ) + RETURN { hConIO, { ; + "load" => { "" , "Load." , {| context, cCommand | cmdLoad( context, cCommand ) } },; + "unload" => { "" , "Unload." , {| context, cCommand | cmdUnload( context, cCommand ) } },; + "list" => { "" , "List." , {| context, cCommand | cmdList( context ) } } } } + +STATIC PROCEDURE dyn_disp( context, cText ) + Eval( context[ 1 ][ "displine" ], cText ) + RETURN + +STATIC FUNCTION dyn_command( context, cCommand ) + LOCAL aCommand + LOCAL nPos + + IF ! Empty( context ) + aCommand := hb_ATokens( cCommand, " " ) + IF ! Empty( aCommand ) .AND. ( nPos := hb_HPos( context[ 2 ], Lower( aCommand[ 1 ] ) ) ) > 0 + Eval( hb_HValueAt( context[ 2 ], nPos )[ 3 ], context, cCommand ) + RETURN .T. + ENDIF + ENDIF + + RETURN .F. + +/* Commands */ + +STATIC PROCEDURE cmdLoad( context, cCommand ) + LOCAL aToken := hb_ATokens( cCommand, " " ) + LOCAL tmp + + FOR tmp := 2 TO Len( aToken ) + __hbrun_extensions_load_one( aToken[ tmp ] ) + NEXT + + RETURN + +STATIC PROCEDURE cmdUnload( context, cCommand ) + LOCAL aToken := hb_ATokens( cCommand, " " ) + LOCAL tmp + + FOR tmp := 2 TO Len( aToken ) + __hbrun_extensions_unload_one( aToken[ tmp ] ) + NEXT + + RETURN + +STATIC PROCEDURE cmdList( context ) + LOCAL cName + + FOR EACH cName IN __hbrun_extensions_get_list() + dyn_disp( context, cName ) + NEXT + + RETURN