diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 49a5ecda64..7bb6b5b944 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,33 @@ The license applies to all entries newer than 2009-04-28. */ +2012-06-06 12:44 UTC+0200 Viktor Szakats (harbour syenar.net) + + contrib/hbrun/extdyn.prg + + contrib/hbrun/extdynpl.hb + + contrib/hbrun/extstat.prg + - contrib/hbrun/pullext.prg + - contrib/hbrun/pullextp.hb + * contrib/hbrun/hbrun.hbp + * contrib/hbrun/hbrun.prg + * contrib/hbrun/plugins.prg + * internal cleanup, renames and restructuring + + findinpath function to accept arrays + + loaded dynamic extensions are now searched in curdir, + hbrun dir and PATH on non-*nix and LD_LIBRARY_PATH on *nix + systems + ! fixed findinpath always returning success + * renamed some stuff recently introduced: + HBRUN_DYN -> HBRUN_EXT + hbrun.dyn -> hbrun.ext + dyn plugin -> ext plugin (f.e. ext.list, ext.load, ext.unload) + ; all non-core modules are called "extensions", the ones + linked at build time are called "static extensions", ones loaded + dynamically are called "dynamic extensions". Console command + plugins are called "plugins". It's still not final. + + * utils/hbmk2/hbmk2.prg + ! misplaced comment + 2012-06-06 10:26 UTC+0200 Viktor Szakats (harbour syenar.net) * src/pp/ppcore.c + accept and ignore '#require' PP directive @@ -76,13 +103,13 @@ * 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 + HBRUN_EXT envvar using space delimited list, or + using text file named 'hbrun.ext' 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' + 'ext.load ', 'ext.unload ' commands + and listed using 'ext.list'. F.e.: 'ext.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 diff --git a/harbour/contrib/hbrun/pullext.prg b/harbour/contrib/hbrun/extdyn.prg similarity index 79% rename from harbour/contrib/hbrun/pullext.prg rename to harbour/contrib/hbrun/extdyn.prg index c5426a8cbd..87cccf7208 100644 --- a/harbour/contrib/hbrun/pullext.prg +++ b/harbour/contrib/hbrun/extdyn.prg @@ -4,7 +4,7 @@ /* * Harbour Project source code: - * extern puller + * extensions (dynamic + core) * * Copyright 2011 Viktor Szakats (harbour syenar.net) * www - http://harbour-project.org @@ -54,46 +54,33 @@ STATIC s_hLib := { => } -PROCEDURE __hbrun_extensions_init_static() - - #xtranslate PULLEXT => REQUEST __HBEXTERN____ ; s_hLib\[ Lower( <"cName"> ) \] := NIL - - PULLEXT hbct - PULLEXT hbxpp - PULLEXT hbexpat - PULLEXT hbmemio - PULLEXT hbmzip - PULLEXT hbnetio - #if defined( __PLATFORM__UNIX ) - PULLEXT hbunix - #endif - #if defined( __PLATFORM__WINDOWS ) - PULLEXT hbwin - #endif - +PROCEDURE __hbrun_extensions_static_load( cName ) + s_hLib[ Lower( cName ) ] := NIL RETURN /* Requires hbrun to be built in -shared mode */ -PROCEDURE __hbrun_extensions_init_dynamic( aDynamic ) +PROCEDURE __hbrun_extensions_dynamic_init( aDynamic ) LOCAL cName IF ! Empty( aDynamic ) FOR EACH cName IN aDynamic - __hbrun_extensions_load_one( cName ) + __hbrun_extensions_dynamic_load( cName ) NEXT ENDIF RETURN -PROCEDURE __hbrun_extensions_load_one( cName ) +PROCEDURE __hbrun_extensions_dynamic_load( cName ) LOCAL cFileName LOCAL hLib IF ! Empty( cName ) IF hb_Version( HB_VERSION_SHARED ) IF !( cName $ s_hLib ) - IF hb_FileExists( cFileName := hb_libName( cName + hb_libPostfix() ) ) + cFileName := __hbrun_FindInPath( hb_libName( cName + hb_libPostfix() ),; + iif( hb_Version( HB_VERSION_UNIX_COMPAT ), GetEnv( "LD_LIBRARY_PATH" ), GetEnv( "PATH" ) ) ) + IF ! Empty( cFileName ) hLib := hb_libLoad( cFileName ) IF ! Empty( hLib ) s_hLib[ cName ] := hLib @@ -101,13 +88,13 @@ PROCEDURE __hbrun_extensions_load_one( cName ) ENDIF ENDIF ELSE - OutErr( hb_StrFormat( "Cannot load %1$s. Requires -shared hbrun build", cName ) + hb_eol() ) + OutErr( hb_StrFormat( "Cannot load %1$s. Requires -shared hbrun build.", cName ) + hb_eol() ) ENDIF ENDIF RETURN -PROCEDURE __hbrun_extensions_unload_one( cName ) +PROCEDURE __hbrun_extensions_dynamic_unload( cName ) IF cName $ s_hLib .AND. s_hLib[ cName ] != NIL hb_HDel( s_hLib, cName ) @@ -120,7 +107,9 @@ FUNCTION __hbrun_extensions_get_list() LOCAL hLib FOR EACH hLib IN s_hLib - aName[ hLib:__enumIndex() ] := iif( Empty( hLib ), "", "*" ) + hLib:__enumKey() + aName[ hLib:__enumIndex() ] := hLib:__enumKey() + iif( Empty( hLib ), "", "*" ) NEXT + ASort( aName ) + RETURN aName diff --git a/harbour/contrib/hbrun/pullextp.hb b/harbour/contrib/hbrun/extdynpl.hb similarity index 82% rename from harbour/contrib/hbrun/pullextp.hb rename to harbour/contrib/hbrun/extdynpl.hb index 5c729807e7..4dd0cee394 100644 --- a/harbour/contrib/hbrun/pullextp.hb +++ b/harbour/contrib/hbrun/extdynpl.hb @@ -4,7 +4,7 @@ /* * Harbour Project source code: - * dynamic module manager plugin + * extensions (dynamic manager plugin) * * Copyright 2012 Viktor Szakats (harbour syenar.net) * www - http://harbour-project.org @@ -52,22 +52,22 @@ FUNCTION __hbrun_plugin() RETURN {; - "id" => "dyn",; - "init" => {| hConIO | dyn_init( hConIO ) } ,; + "id" => "ext",; + "init" => {| hConIO | __init( hConIO ) } ,; "exit" => {| context | HB_SYMBOL_UNUSED( context ) } ,; - "cmd" => {| context, cCommand | dyn_command( context, cCommand ) } } + "cmd" => {| context, cCommand | __command( context, cCommand ) } } -STATIC FUNCTION dyn_init( hConIO ) +STATIC FUNCTION __init( hConIO ) RETURN { hConIO, { ; - "load" => { "" , "Load." , {| context, cCommand | cmdLoad( context, cCommand ) } },; - "unload" => { "" , "Unload." , {| context, cCommand | cmdUnload( context, cCommand ) } },; - "list" => { "" , "List." , {| context, cCommand | cmdList( context ) } } } } + "load" => { "" , "Load." , {| context, cCommand | load( context, cCommand ) } },; + "unload" => { "" , "Unload." , {| context, cCommand | unload( context, cCommand ) } },; + "list" => { "" , "List." , {| context, cCommand | list( context ) } } } } -STATIC PROCEDURE dyn_disp( context, cText ) +STATIC PROCEDURE __disp( context, cText ) Eval( context[ 1 ][ "displine" ], cText ) RETURN -STATIC FUNCTION dyn_command( context, cCommand ) +STATIC FUNCTION __command( context, cCommand ) LOCAL aCommand LOCAL nPos @@ -83,31 +83,31 @@ STATIC FUNCTION dyn_command( context, cCommand ) /* Commands */ -STATIC PROCEDURE cmdLoad( context, cCommand ) +STATIC PROCEDURE load( context, cCommand ) LOCAL aToken := hb_ATokens( cCommand, " " ) LOCAL tmp FOR tmp := 2 TO Len( aToken ) - __hbrun_extensions_load_one( aToken[ tmp ] ) + __hbrun_extensions_dynamic_load( aToken[ tmp ] ) NEXT RETURN -STATIC PROCEDURE cmdUnload( context, cCommand ) +STATIC PROCEDURE unload( context, cCommand ) LOCAL aToken := hb_ATokens( cCommand, " " ) LOCAL tmp FOR tmp := 2 TO Len( aToken ) - __hbrun_extensions_unload_one( aToken[ tmp ] ) + __hbrun_extensions_dynamic_unload( aToken[ tmp ] ) NEXT RETURN -STATIC PROCEDURE cmdList( context ) +STATIC PROCEDURE list( context ) LOCAL cName FOR EACH cName IN __hbrun_extensions_get_list() - dyn_disp( context, cName ) + __disp( context, cName ) NEXT RETURN diff --git a/harbour/contrib/hbrun/extstat.prg b/harbour/contrib/hbrun/extstat.prg new file mode 100644 index 0000000000..c2b3efff26 --- /dev/null +++ b/harbour/contrib/hbrun/extstat.prg @@ -0,0 +1,70 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * extensions (static puller) + * + * Copyright 2011 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. + * + */ + +PROCEDURE __hbrun_extensions_static_init() + + #xtranslate PULLEXT => REQUEST __HBEXTERN____ ; __hbrun_extensions_static_load( <"cName"> ) + + PULLEXT hbct + PULLEXT hbxpp + PULLEXT hbexpat + PULLEXT hbmemio + PULLEXT hbmzip + PULLEXT hbnetio + #if defined( __PLATFORM__UNIX ) + PULLEXT hbunix + #endif + #if defined( __PLATFORM__WINDOWS ) + PULLEXT hbwin + #endif + + RETURN diff --git a/harbour/contrib/hbrun/hbrun.hbp b/harbour/contrib/hbrun/hbrun.hbp index 6d1a86c79a..18c3fce7e4 100644 --- a/harbour/contrib/hbrun/hbrun.hbp +++ b/harbour/contrib/hbrun/hbrun.hbp @@ -18,10 +18,11 @@ hbrun.prg --request=__hbrun_extensions_get_list +-request=__hbrun_extensions_static_init headers.prg plugins.prg -pullext.prg +extdyn.prg +extstat.prg -lhbpmcom{dos} @@ -49,3 +50,7 @@ hbmzip.hbc hbnetio.hbc hbunix.hbc{unix} hbwin.hbc{allwin} + +# Always build in shared mode for these platforms because the +# it's required for dynamic extension loading. +#{_HB_BUILD_&(!(HB_BUILD_DYN='no')&(win|wce|os2))}-shared diff --git a/harbour/contrib/hbrun/hbrun.prg b/harbour/contrib/hbrun/hbrun.prg index 32d78210be..e3c50856f7 100644 --- a/harbour/contrib/hbrun/hbrun.prg +++ b/harbour/contrib/hbrun/hbrun.prg @@ -94,8 +94,8 @@ PROCEDURE _APPMAIN( cFile, ... ) LOCAL aDynamic := {} - LoadDynamicFromFile( aDynamic, hb_DirBase() + "hbrun.dyn" ) - LoadDynamicFromString( aDynamic, GetEnv( "HBRUN_DYN" ) ) + LoadExtDynamicFromFile( aDynamic, hb_DirBase() + "hbrun.ext" ) + LoadExtDynamicFromString( aDynamic, GetEnv( "HBRUN_EXT" ) ) /* TODO: Rework parameter handling */ IF PCount() > 0 @@ -145,7 +145,7 @@ PROCEDURE _APPMAIN( cFile, ... ) hbrun_Prompt( hb_AParams() ) EXIT ELSE - cFile := hbrun_FindInPath( cFile ) + cFile := __hbrun_FindInPath( cFile ) IF ! Empty( cFile ) hb_FNameSplit( cFile, NIL, NIL, @cExt ) cExt := Lower( cExt ) @@ -171,7 +171,7 @@ PROCEDURE _APPMAIN( cFile, ... ) hHeaders := __hbrun_CoreHeaderFiles() /* add core header files */ ENDIF - LoadDynamicFromSource( aDynamic, cFile ) + LoadExtDynamicFromSource( aDynamic, cFile ) cFile := hb_compileBuf( hHeaders, hb_ProgName(), "-n2", "-w", "-es2", "-q0", ; "-I" + hb_FNameDir( cFile ), "-D" + "__HBSCRIPT__HBRUN", cFile ) @@ -211,7 +211,7 @@ EXIT PROCEDURE hbrun_exit() RETURN -STATIC PROCEDURE LoadDynamicFromFile( aDynamic, cFileName ) +STATIC PROCEDURE LoadExtDynamicFromFile( aDynamic, cFileName ) LOCAL cItem FOR EACH cItem IN hb_ATokens( StrTran( MemoRead( cFileName ), Chr( 13 ) ), Chr( 10 ) ) @@ -225,7 +225,7 @@ STATIC PROCEDURE LoadDynamicFromFile( aDynamic, cFileName ) RETURN -STATIC PROCEDURE LoadDynamicFromString( aDynamic, cString ) +STATIC PROCEDURE LoadExtDynamicFromString( aDynamic, cString ) LOCAL cItem FOR EACH cItem IN hb_ATokens( cString,, .T. ) @@ -236,7 +236,7 @@ STATIC PROCEDURE LoadDynamicFromString( aDynamic, cString ) RETURN -STATIC PROCEDURE LoadDynamicFromSource( aDynamic, cFileName ) +STATIC PROCEDURE LoadExtDynamicFromSource( aDynamic, cFileName ) LOCAL cFile := MemoRead( cFileName ) LOCAL pRegex LOCAL tmp @@ -261,23 +261,15 @@ 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 ) + IF Type( "__hbrun_extensions_static_init()" ) == "UI" + Do( "__hbrun_extensions_static_init" ) ENDIF + __hbrun_extensions_dynamic_init( aDynamic ) s_lInit := .T. ENDIF 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 LOCAL cBuff, cSig, cExt @@ -442,7 +434,7 @@ STATIC PROCEDURE hbrun_Prompt( aParams, cCommand ) Set( _SET_EVENTMASK, hb_bitOr( INKEY_KEYBOARD, HB_INKEY_GTEVENT ) ) - s_nRow := 2 + iif( Empty( hbrun_extensionlist() ), 0, 1 ) + s_nRow := 2 + iif( Empty( __hbrun_extensions_get_list() ), 0, 1 ) plugins := plugins_load( __hbrun_plugins(), aParams ) @@ -528,7 +520,7 @@ STATIC PROCEDURE hbrun_Prompt( aParams, cCommand ) ENDIF IF s_nRow >= MaxRow() - Scroll( 2 + iif( Empty( hbrun_extensionlist() ), 0, 1 ), 0, MaxRow(), MaxCol(), 1 ) + Scroll( 2 + iif( Empty( __hbrun_extensions_get_list() ), 0, 1 ), 0, MaxRow(), MaxCol(), 1 ) s_nRow := MaxRow() - 1 ENDIF ENDIF @@ -613,8 +605,8 @@ STATIC PROCEDURE hbrun_Info( cCommand ) IF s_lPreserveHistory hb_DispOutAt( 1, MaxCol(), "o", "R/BG" ) ENDIF - IF ! Empty( hbrun_extensionlist() ) - hb_DispOutAt( 2, 0, PadR( "Ext: " + ArrayToList( hbrun_extensionlist() ), MaxCol() + 1 ), "W/B" ) + IF ! Empty( __hbrun_extensions_get_list() ) + hb_DispOutAt( 2, 0, PadR( "Ext: " + ArrayToList( __hbrun_extensions_get_list() ), MaxCol() + 1 ), "W/B" ) ENDIF RETURN @@ -684,7 +676,7 @@ STATIC PROCEDURE hbrun_Exec( cCommand ) Eval( bBlock ) s_nRow := Row() s_nCol := Col() - nRowMin := 2 + iif( Empty( hbrun_extensionlist() ), 0, 1 ) + nRowMin := 2 + iif( Empty( __hbrun_extensions_get_list() ), 0, 1 ) IF s_nRow < nRowMin s_nRow := nRowMin ENDIF @@ -774,7 +766,7 @@ STATIC FUNCTION hbrun_HistoryFileName() RETURN cDir + hb_ps() + cFileName -STATIC FUNCTION hbrun_FindInPath( cFileName ) +FUNCTION __hbrun_FindInPath( cFileName, xPath ) LOCAL cDir LOCAL cName LOCAL cExt @@ -801,18 +793,27 @@ STATIC FUNCTION hbrun_FindInPath( cFileName ) NEXT ENDIF - FOR EACH cExt IN aExt - /* Check in the PATH. */ + IF ! HB_ISSTRING( xPath ) .AND. ; + ! HB_ISARRAY( xPath ) + xPath := GetEnv( "PATH" ) + ENDIF + + IF HB_ISSTRING( xPath ) #if defined( __PLATFORM__WINDOWS ) .OR. ; defined( __PLATFORM__DOS ) .OR. ; defined( __PLATFORM__OS2 ) - FOR EACH cDir IN hb_ATokens( GetEnv( "PATH" ), hb_osPathListSeparator(), .T., .T. ) + xPath := hb_ATokens( xPath, hb_osPathListSeparator(), .T., .T. ) + #else + xPath := hb_ATokens( xPath, hb_osPathListSeparator() ) + #endif + ENDIF + + FOR EACH cExt IN aExt + /* Check in the PATH. */ + FOR EACH cDir IN xPath IF Left( cDir, 1 ) == '"' .AND. Right( cDir, 1 ) == '"' cDir := SubStr( cDir, 2, Len( cDir ) - 2 ) ENDIF - #else - FOR EACH cDir IN hb_ATokens( GetEnv( "PATH" ), hb_osPathListSeparator() ) - #endif IF ! Empty( cDir ) IF hb_FileExists( cFullName := hb_FNameMerge( cDir, cName, cExt ) ) RETURN cFullName @@ -822,7 +823,7 @@ STATIC FUNCTION hbrun_FindInPath( cFileName ) NEXT ENDIF - RETURN cFileName + RETURN NIL #if defined( __PLATFORM__WINDOWS ) diff --git a/harbour/contrib/hbrun/plugins.prg b/harbour/contrib/hbrun/plugins.prg index d9b04c54b5..d448846369 100644 --- a/harbour/contrib/hbrun/plugins.prg +++ b/harbour/contrib/hbrun/plugins.prg @@ -60,7 +60,7 @@ FUNCTION __hbrun_plugins() LOCAL file ADD PLUGIN TO hPlugins FILE "netiomgm.prg" - ADD PLUGIN TO hPlugins FILE "pullextp.hb" + ADD PLUGIN TO hPlugins FILE "extdynpl.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/utils/hbmk2/hbmk2.prg b/harbour/utils/hbmk2/hbmk2.prg index 57f2cf3565..bee3eae431 100644 --- a/harbour/utils/hbmk2/hbmk2.prg +++ b/harbour/utils/hbmk2/hbmk2.prg @@ -8927,7 +8927,6 @@ STATIC FUNCTION FindInPath( cFileName, xPath ) xPath := GetEnv( "PATH" ) ENDIF - /* Check in the PATH. */ IF HB_ISSTRING( xPath ) #if defined( __PLATFORM__WINDOWS ) .OR. ; defined( __PLATFORM__DOS ) .OR. ; @@ -8938,6 +8937,7 @@ STATIC FUNCTION FindInPath( cFileName, xPath ) #endif ENDIF + /* Check in the PATH. */ FOR EACH cDir IN xPath IF ! Empty( cDir ) IF hb_FileExists( cFileName := hb_FNameMerge( hb_DirSepAdd( StrStripQuote( cDir ) ), cName, cExt ) )