/****************************** Module Header ******************************* * * Module Name: tools.e * * Copyright (c) Netlabs EPM Distribution Project 2014 * * $Id$ * * =========================================================================== * * This file is part of the Netlabs EPM Distribution package and 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, in version 2 as it comes in the "COPYING" file of the * Netlabs EPM Distribution. This library 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. * ****************************************************************************/ compile if not defined(SMALL) -- If SMALL not defined, then being separately compiled include 'stdconst.e' define INCLUDING_FILE = 'TOOLS.E' const compile if not defined(NLS_LANGUAGE) NLS_LANGUAGE = 'ENGLISH' compile endif include NLS_LANGUAGE'.e' compile endif -- not defined(SMALL) ; --------------------------------------------------------------------------- defc FindTool parse arg Tool Keywords RetString = FindTool( Tool, Keywords) sayerror 'FindTool( 'arg(1)') = 'RetString const ; 0 = search for tool at every call ; 1 = search for tool once per EPM window compile if not defined( FINDTOOL_SAVE_FOUND_TO_ARRAY_VAR) FINDTOOL_SAVE_FOUND_TO_ARRAY_VAR = 1 compile endif ; --------------------------------------------------------------------------- ; Syntax: RetVal = FindTool( tool) ; RetVal = FindTool( tool, keywordlist) ; If only tool was specified, RetVal contains the FoundExe filename. ; If tool and keywordlist was specified, RetVal returns a string ; consististing of all specified keywords and in that order: ; keyword1=val1;...;keywordn=valn; ; Valid keywords are: Exe Parameters WorkingDir Options ; keywordlist maybe specified space-separated or semicolon-separated. ; If Exe wasn't found, an empty string is returned, even when keywordlist ; was specified. Thus it can be checked easily, if Exe is configured. defproc FindTool Exe = '' Parameters = '' WorkingDir = '' DefaultCmd = '' ValidKeywords = 'Exe Parameters WorkingDir Options' WpsTools = 'mail news ftp irc browser' -- Use WPS expressions 'EXENAME PARAMETERS STARTUPDIR' instead? FoundExe = '' fWpsEntry = 0 do once = 1 to 1 Tool = lowcase( arg(1)) -- Allow for a space- or a semicolon-separated keyword list. -- Keywords are case-sensitive (camel-case). Keywords = strip( translate( arg(2), ' ', ';')) -- Check keywords UnknownKeywords = '' do w = 1 to words( Keywords) next = word( Keywords, w) if wordpos( next, ValidKeywords) = 0 then UnknownKeywords = strip( UnknownKeywords next) endif enddo if UnknownKeywords <> '' then sayerror 'FindTool: Unknown keyword(s) "'UnknownKeywords'" specified.' return '' endif -- Strip extension ToolBaseName = Tool p1 = lastpos( '.exe', ToolBaseName) if p1 > 1 then ToolBaseName = substr( ToolBaseName, 1, p1 - 1) endif -- Check if key \ToolBaseName is defined -- This key can be used as a reference to another exe KeyPath = '\NEPMD\User\Tools\'ToolBaseName'\ToolBaseName' CfgToolBaseName = lowcase( QueryConfigKey( KeyPath)) -- Strip extension p2 = lastpos( '.exe', CfgToolBaseName) if p2 > 1 then CFgToolBaseName = substr( CfgToolBaseName, 1, p2 - 1) endif if CfgToolBaseName <> '' then ToolBaseName = CfgToolBaseName endif -- Refer to defined config key if wordpos( ToolBaseName,'md5sum md5suml md5') then ToolBaseName = 'md5' endif -- Read entries from ini KeyPath = '\NEPMD\User\Tools\'ToolBaseName Exe = QueryConfigKey( KeyPath'\Exe') Parameters = QueryConfigKey( KeyPath'\Parameters') WorkingDir = QueryConfigKey( KeyPath'\WorkingDir') Options = QueryConfigKey( KeyPath'\Options') -- Allow for specifying env vars in value Exe = ExpandEnvVars( Exe) WorkingDir = ExpandEnvVars( WorkingDir) if upcase( Exe) = 'WPS' then fWpsEntry = 1 leave elseif Exe = '' then -- Check if WpsTool if wordpos( ToolBaseName, WpsTools) then fWpsEntry = 1 leave else -- Use fallback value if config key isn't defined Exe = ToolBaseName'.exe' endif endif -- Handle fully qualified filenames if pos( ':\', Exe) | leftstr( Exe, 2) = '\\' then if Exist( Exe) then FoundExe = Exe leave endif endif ToolList = Exe PathEnvVarList = 'PATH EPMTOOLSPATH' FoundExe = '' do w = 1 to words( PathEnvVarList) CurPath = word( PathEnvVarList, w) Rest = ToolList do forever if Rest = '' then leave endif parse value Rest with FileSpec';'Rest --dprintf( 'NepmdSearchPath: searching "'FileSpec'" in 'CurPath) FoundExe = NepmdSearchPath( FileSpec, CurPath) if FoundExe <> '' then leave endif enddo if FoundExe <> '' then leave endif enddo enddo compile if FINDTOOL_SAVE_FOUND_TO_ARRAY_VAR = 1 if FoundExe <> '' then -- Write found entry to array var SetAVar( ToolBaseName'exe', FoundExe) endif compile endif if fWpsEntry then if Tool = 'mail' then Exe = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultMailExe') Parameters = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultMailParameters') WorkingDir = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultMailWorkingDir') elseif Tool = 'news' then Exe = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultNewsExe') Parameters = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultNewsParameters') WorkingDir = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultNewsWorkingDir') elseif Tool = 'ftp' then Exe = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultFTPExe') Parameters = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultFTPParameters') WorkingDir = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultFTPWorkingDir') elseif Tool = 'irc' then Exe = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultIRCExe') Parameters = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultIRCParameters') WorkingDir = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultIRCWorkingDir') endif if Tool = 'browser' | Exe = '' then Exe = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultBrowserExe') Parameters = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultParameters') WorkingDir = queryprofile( HINI_USERPROFILE, 'WPURLDEFAULTSETTINGS', 'DefaultWorkingDir') endif FoundExe = Exe endif RetString = '' if Keywords = '' then RetString = FoundExe else do k = 1 to words( Keywords) Keyword = word( Keywords, k) Val = '' if Keyword = 'Exe' then Val = FoundExe elseif Keyword = 'Parameters' then Val = Parameters elseif Keyword = 'WorkingDir' then Val = WorkingDir elseif Keyword = 'Options' then Val = Options endif RetString = RetString''Keyword'='Val';' enddo endif --dprintf( 'FindTool( 'arg(1)', 'arg(2)') = 'RetString', rc = 'rc) return RetString ; --------------------------------------------------------------------------- ; For use as menu item. defc GrepDlg Title = 'Scan for text in files' Text = 'Enter string (in quotes if it contains spaces) and file spec:' Tool = 'grep' -- Options are queried from ini. The following is used as fallback value: -- GNU grep DefaultOptions = '-EnHir' GrepHelpArgs = '--help' -- Ralph Yozzo's grep (IBM, contained in CSTEPM, support for it removed) --DefaultOptions = '-qlys' --GrepHelpArgs = '' RetString = FindTool( Tool, 'Options') parse value RetString with 'Options='Options';' if Options = '' then Options = DefaultOptions endif DefaultValue = Options' ' DefaultButton = 1 parse value entrybox( Title, '/~OK/Cancel/Grep ~Help', -- max. 4 buttons DefaultValue, '', 260, atoi(DefaultButton) || atoi(0000) || -- help id gethwndc(APP_HANDLE) || Text) with Button 2 NewValue \0 NewValue = strip(NewValue) if Button = \1 then --'buffer_command' put_in_buffer( 'Grep' NewValue) 'Grep' NewValue call AddToHistory( 'CommandLine', 'Grep' NewValue) elseif Button = \2 then -- nop elseif Button = \3 then -- Show help "Open 'Grep "GrepHelpArgs"'" -- use an extra window to show Grep's help 'postme GrepDlg' -- call this cmd again endif ; --------------------------------------------------------------------------- ; Call an external GREP utility and display the results in an EPM file. ; The modified Alt+1 definition in ALT_1.E will let you place the ; cursor on a line in the results file and press Alt+1 to load the ; corresponding source file. ; ; Syntax: grep [options] pattern filemask ; ; If no options where specified, the defaultoptions are submitted to grep. defc Grep universal vepm_pointer Tool = 'grep' -- Options are queried from ini. The following is used as fallback value: -- GNU grep DefaultOptions = '-EnHir' GrepHelpArgs = '--help' -- Ralph Yozzo's grep (IBM, contained in CSTEPM, support for it removed) --DefaultOptions = '-qlys' --GrepHelpArgs = '' RetString = FindTool( Tool, 'Exe Options') parse value RetString with 'Exe='ToolExe';Options='Options';' if ToolExe = '' then rc = -274 -- Unknown command sayerror 'Error: Grep: Executable not found for FindTool( 'Tool').' return rc endif if Options = '' then Options = DefaultOptions endif Args = arg(1) if Args = GrepHelpArgs then rc = Grep( ToolExe, Args) return rc endif if leftstr( Args, 1) = '-' | leftstr( Args, 1) = '/' then -- Options specified GrepArgs = Args else -- No options specified, use default options GrepArgs = Options Args endif if words( GrepArgs) < 3 then sayerror 'Syntax: grep [options] pattern filemask' 'postme GrepDlg' return endif -- sayerror 'Syntax: grep [options] pattern filemask (default options = 'DefaultOptions')' mouse_setpointer WAIT_POINTER sayerror 'Scanning files...' rc = Grep( ToolExe, GrepArgs) 'SayHint' ALT_1_LOAD__MSG mouse_setpointer vepm_pointer ; --------------------------------------------------------------------------- ; Syntax: Grep( ToolExe, GrepArgs) ; If GrepArgs doesnot contain options, the default options, either ; GNU_GREP_OPTIONS or RY_GREP_OPTIONS, depending on GrepVersion are prepended ; to GrepArgs. ; Used by Grep, GrepDlg and FindDef. defproc Grep ToolExe = arg(1) GrepArgs = arg(2) OutFile = GetTmpPath()'grep____.out' do once = 1 to 1 quietshell ToolExe GrepArgs '>'OutFile '2>&1' greprc = rc -- sets rc >= 1 on application error, rc < 0 on E error, otherwise rc = 0 if rc = sayerror( 'Insufficient memory') or rc = sayerror( 'File Not found') then leave endif CurDir = directory() 'edit' OutFile editrc = rc if rc = -282 then -- sayerror('New file') 'xcom quit' rc = editrc leave elseif rc <> 0 then leave endif rc = greprc .autosave = 0 LongName = '.Output from grep' GrepArgs .filename = translate( LongName, '!!!!!', '*\/:?') -- This won't work, because file doesn't exist on disk: --call delete_ea('.LONGNAME') --'add_ea .LONGNAME' LongName --NepmdWriteStringEa( .filename, '.LONGNAME', LongName) if .last > 0 then next = textline(1) else next = '' endif if leftstr( next, 3) = 'SYS' then -- Check for DLL not found errors -- SYS1804: Datei REGEX kann nicht gefunden werden. parse value next with 'SYS'rc':' . sayerror next endif -- If current path is searched only, GNU grep won't output the files' paths. insertline 'Current directory = 'CurDir, 1 -- Insert grep command as line 1 insertline 'grep 'GrepArgs, 1 .modify = 0 call EraseTemp( OutFile) enddo return rc ; --------------------------------------------------------------------------- ; Search all NEPMD E macros for a string ; input: a string to search for ; output: a grep window showing all matches suitable for use with ALT+1 defc MacGrep RootDir = NepmdScanEnv( 'NEPMD_ROOTDIR') UserDir = NepmdScanEnv( 'NEPMD_USERDIR') FileMask = UserDir'\macros\*.e' RootDir'\netlabs\macros\*.e' 'Grep' arg(1) FileMask if rc = 0 then 'postme SayHint' ALT_1_LOAD__MSG endif ; --------------------------------------------------------------------------- ; Support for KDiff3, GFC and maybe others. ; Compares current file with another. File open dialog of kDiff3 or GFC will ; open to select the second file. ; If current file is located in any tree of %NEPMD_ROOTDIR%\netlabs or ; %NEPMD_USERDIR%, then the current file is compared with the ; corresponding file of the other tree. defc CompareCurrentFile Tool = arg(1) fn = .filename Params = '"'fn'"' RootDir = NepmdScanEnv( 'NEPMD_ROOTDIR') rc1 = rc if rc then sayerror 'Environment var NEPMD_ROOTDIR not set.' endif NetlabsDir = RootDir'\netlabs' UserDir = NepmdScanEnv( 'NEPMD_USERDIR') rc2 = rc if rc then sayerror 'Environment var NEPMD_USERDIR not set.' endif NetlabsDir = strip( NetlabsDir, 't', '\') UserDir = strip( UserDir , 't', '\') if not rc2 then if abbrev( upcase( fn), upcase( NetlabsDir)'\') then rest = substr( fn, length( NetlabsDir) + 1) -- including leading \ fn2 = UserDir''rest if NepmdFileExists( fn2) then Params = strip( Params '"'fn2'"') endif elseif abbrev( upcase( fn), upcase( UserDir)'\') then rest = substr( fn, length( UserDir) + 1) -- including leading \ fn2 = NetlabsDir''rest if NepmdFileExists( fn2) then Params = strip( Params '"'fn2'"') endif endif endif ToolExe = FindTool( Tool) if ToolExe = '' then rc = -274 -- Unknown command sayerror 'Error: CompareCurrentFile: Executable not found for FindTool( 'Tool').' return rc endif 'start /f 'ToolExe Params ; --------------------------------------------------------------------------- defc OpenUrl, StartBrowser UrlStrings = 'http:// ftp:// www. ftp. https:// mailto: news:// irc:// file:///' Url = arg(1) rc = 1 -- default rc; 1: browser not started or no Url do once = 1 to 1 if leftstr( Url, 1) = '"' & rightstr( Url, 1) = '"' then -- Strip surrounding doublequotes Url = substr( Url, 2, length( Url) - 2) endif -- No Url submitted, find Url under cursor if Url = '' then -- Go to mouse position to ensure getting URL at mouse pointer and not at cursor call psave_pos(saved_pos) call psave_mark(saved_mark) 'MH_gotoposition' -- Get word under cursor, separated by any char of SeparatorList StartCol = 0 EndCol = 0 -- Todo: Remove trailing chars of ',;|+#=' only if a space follows: -- Sync this with alt_1.e SeparatorList = '"'||"'"||'(){}[]<>,;|+ '\9'#' call find_token( StartCol, EndCol, SeparatorList, '') getline line call prestore_pos(saved_pos) call prestore_mark(saved_mark) fWordFound = (StartCol <> 0 & EndCol >= StartCol) if not fWordFound then rc = 1 leave endif Spec = substr( line, StartCol, EndCol - StartCol + 1) -- Strip trailing punctuation chars and '-' if wordpos( rightstr( Spec, 1), ', ; . ! ? -') then Spec = substr( Spec, 1, length(Spec) - 1) endif -- Locate URL in double-clicked word do u = 1 to words( UrlStrings) UrlString = word( UrlStrings, u) p1 = pos( UrlString, Spec) if p1 > 0 then -- get URL Url = substr( Spec, p1) -- add default protocol identifier if (pos( ':', Url) = 0) then if substr( Url, 1, 4) = 'ftp.' then Url = 'ftp://'Url else Url = 'http://'Url endif endif leave endif enddo endif /* -- If no URL found, automatically process special URLs if Url = '' then filename = .filename p1 = lastpos( '\', filename) fname = substr( filename, p1 + 1) if translate( leftstr( fname, 6)) = 'FILES.' then Url = 'ftp://ftp.dante.de/tex-archive/'Spec p2 = lastpos( '/', Url) Parent = substr( Url, 1, p2) Url = Parent endif if translate( leftstr( Spec, 6)) = 'DANTE:' or translate( leftstr( Spec, 5)) = 'CTAN:' then Url = substr( Spec, 7) -- <--- ToDo Url = strip( Url, 'L') Url = strip( Url, 'L', '/') Url = 'ftp://ftp.dante.de/tex-archive/'Url p2 = lastpos( '/', Url) Parent = substr( Url, 1, p2) Url = Parent endif endif -- Url = '' */ if Url = '' then rc = 1 leave endif -- Find app for each WPS-defined special URL type Tool = '' KeywordList = 'Exe;Parameters;WorkingDir' ToolString = '' if pos( 'mailto:', Url) = 1 then Tool = 'mail' elseif pos( 'news://', Url) then Tool = 'news' elseif pos( 'ftp://', Url) then Tool = 'ftp' elseif pos( 'irc://', Url) then Tool = 'irc' endif if Tool <> '' then ToolString = FindTool( Tool, KeywordList) endif -- Default app if ToolString = '' then Tool = 'browser' ToolString = FindTool( Tool, KeywordList) endif if ToolString = '' then rc = -274 -- Unknown command sayerror 'Error: OpenUrl: Executable not found for FindTool( 'Tool').' return rc endif parse value ToolString with 'Exe='Exe';Parameters='Parameters';WorkingDir='WorkingDir';' -- Exe ExeDir = '' p1 = lastpos( '\', Exe) if p1 > 0 then ExeName = substr( Exe, p1 + 1) ExeDir = leftstr( Exe, p1 - 1) if rightstr( ExeDir, 1) = ':' then -- Root dir ExeDir = ExeDir'\' endif else ExeName = Exe endif p2 = lastpos( '.', ExeName) if p2 > 0 then ExeBaseName = leftstr( ExeName, p2 - 1) else ExeBaseName = ExeName endif ExeShortName = ExeBaseName -- Strip addition for Run! p3 = pos( '!', ExeShortName) if p3 then ExeShortName = leftstr( ExeShortName, p3 - 1) endif -- If all lowercase or uppercase, capitalize the first letter only if ExeShortName = lowcase( ExeShortName) | ExeShortName = upcase( ExeShortName) then ExeShortName = upcase( leftstr( ExeShortName, 1))''lowcase( substr( ExeShortName, 2)) endif -- Save Parameters for debug OrgParameters = Parameters -- Resolve WPS parameter macros Parameters = ResolveWpsParameterMacros( Parameters, Url) -- WorkingDir CallDir = '' CurDir = directory() fCurDirChanged = 0 if WorkingDir <> '' then CallDir = WorkingDir elseif ExeDir <> '' then CallDir = ExeDir endif if CallDir <> '' then 'cdd' CallDir fCurDirChanged = 1 endif CmdPre = 'start /f' Exe' "' CmdPost = '"' CmdLen = length( CmdPre) + length( CmdPost) -- Truncate URL if too long to avoid EPM crashing. -- Max. length for a command executed by cmd.exe is 300. MaxLen = 239 - CmdLen -- why 239? IsTruncated = 0 if length( Url) > MaxLen then Url = leftstr( Url, MaxLen) IsTruncated = 1 -- Try to truncate before a % char, otherwise the URL gets unvalid sometimes, -- but only in the last 20 chars lp = lastpos( '%', Url) if lp > MaxLen - 20 then Url = leftstr( Url, lp - 1) endif endif if IsTruncated then sayerror 'Invoking' ExeShortName 'with (truncated):' Url else sayerror 'Invoking' ExeShortName 'with:' Url endif -- Execute the command and set rc Cmd = CmdPre''Url''CmdPost Cmd exerc = rc -- Teststrings here: -- http://www.os2.org -- ftp://ftp.netlabs.org,www.netlabs.org,ftp://ftp.os2.org -- (ftp://ftp.netlabs.org) -- ####ftp://ftp.netlabs.org)###) -- ftp://ftp.netlabs.org -- www.netlabs.org -- mailto:C.Langanke@Teamos2.de --