/****************************** 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 define INCLUDING_FILE = 'TOOLS.E' include 'stdconst.e' const tryinclude 'mycnf.e' const compile if not defined( NLS_LANGUAGE) NLS_LANGUAGE = 'ENGLISH' compile endif include NLS_LANGUAGE'.e' compile endif ; --------------------------------------------------------------------------- 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 rc = 2 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.' rc = 87 -- ERROR_INVALID_PARAMETER 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) if FoundExe <> '' then rc = 0 endif return RetString ; --------------------------------------------------------------------------- ; This uses FindTool to search an executable in PATH;EPMTOOLSPATH; ; Name may be a fully-qualified filename. The extension is optional. ; It doesn't work with the EPM loader and the EPM executable, because ; the .exe filename is searched and not determined from current process. ; They can be queried with the env vars NEPMD_LOADEREXECUTABLE and ; NEPMD_EPMEXECUTABLE instead of FindTool. Passing the fullnames of the ; expanded env vars works. defproc FindExe( var Name, var Dir, var DateTime, var VersionString) do once = 1 to 1 Dir = '' DateTime = '' VersionString = '' -- Query full name FullName = FindTool( Name) if FullName = '' then leave endif FullName = GetRealCase( FullName) -- Get Name from FullName Name = GetFileSpec( 'N', FullName) -- Get dir from FullName Dir = NepmdQueryFullname( FullName'\..') -- Query DateTime for FullName DateTime = NepmdQueryPathInfo( FullName, 'MTIME') -- Query version string hModule = \0\0\0\0 Buff = copies( \0, 255) res = dynalink32( 'PMWIN', '#781', -- Win32LoadString GethWndC( EPMINFO_HAB) || hModule || -- NULLHANDLE atol( 65535) || -- IDD_BUILDDATE atol( length( Buff)) || address( Buff), 2) VersionString = leftstr( Buff, res) enddo return ; --------------------------------------------------------------------------- ; This queries a module handle for a DLL. The DLL is loaded if not already ; loaded before. Freeing it after further querying is only successful if ; the current process hasn't loaded it before. ; Name may be a fully-qualified filename. The extension is optional. ; It works with the EPM DLLs, too. defproc FindDll( var Name, var Dir, var DateTime, var VersionString) do once = 1 to 1 Dir = '' DateTime = '' VersionString = '' -- Load module and query module handle Name = Name\0 hModule = \0\0\0\0 rc = dynalink32( 'DOSCALLS', '#318', -- Dos32LoadModule atol( 0) || -- Buffer address atol( 0) || -- Buffer length address( Name) || address( hModule)) -- Query full name FullName = copies( \0, 260) call dynalink32( 'DOSCALLS', '#320', -- DosQueryModuleName hModule || -- Module handle atol( length( FullName)) || -- Buffer length address( FullName)) -- Module we've loaded parse value FullName with FullName \0 if FullName = '' then leave endif FullName = GetRealCase( FullName) -- Query version string Buff = copies( \0, 255) res = dynalink32( 'PMWIN', '#781', -- Win32LoadString GethWndC( EPMINFO_HAB) || hModule || -- NULLHANDLE atol( 65535) || -- IDD_BUILDDATE atol( length( Buff)) || address( Buff), 2) VersionString = leftstr( Buff, res) -- Get Name from FullName Name = GetFileSpec( 'N', FullName) -- Get dir from FullName if FullName = '' then Dir = '' else Dir = NepmdQueryFullname( FullName'\..') endif -- Query DateTime for FullName DateTime = NepmdQueryPathInfo( FullName, 'MTIME') enddo -- Free module call dynalink32( 'DOSCALLS', '#322', -- Dos32FreeModule hModule) return ; --------------------------------------------------------------------------- ; Save the value of a found tool or tool.exe as an array var. defproc CheckTool( ToolName) ToolName = lowcase( ToolName) if wordpos( rightstr( ToolName, 4), '.exe .cmd .com') then ToolBaseName = leftstr( ToolName, length( ToolName) - 4) else ToolBaseName = ToolName endif FoundTool = FindTool( ToolName) SetAVar( 'tool.'ToolBaseName, FoundTool) return ; --------------------------------------------------------------------------- ; 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 = '-EnHira' 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 Title = leftstr( Title, 100)'.' -- Add spaces to fit the text in titlebar parse value EntryBox( Title, '/'OK__MSG'/'CANCEL__MSG'/~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 default options 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 = '-EnHira' 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 endif if Options = '' then Options = DefaultOptions endif Args = arg( 1) if Args = GrepHelpArgs then call Grep( ToolExe, Args) return 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...' call 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' ShellPrefix = 'cmd.exe /c' rc = 0 do once = 1 to 1 -- Better use a cmd file for longer lines. Quietshell is limited to -- 229 ... 239 chars, while cmd.exe allows for 1023 chars. CmdFile = GetTmpPath()'tooltmp.cmd' if Exist( CmdFile) then call DeleteFile( CmdFile) endif 'xcom Edit /c 'CmdFile .autosave = 0 ToolCall = ToolExe GrepArgs '>'OutFile' 2>&1' if length( ToolCall) >= 1598 then 'SayError Line too long for E (max. 1599).' rc = 24 -- ERROR_BAD_LENGTH leave elseif length( ToolCall) > 1023 then 'SayError Line too long for 'ShellPrefix' (max 1023).' rc = 24 -- ERROR_BAD_LENGTH leave endif insertline ToolCall 'xcom Save' 'xcom Quit' CmdCall = ShellPrefix CmdFile quietshell CmdCall call DeleteFile( CmdFile) greprc = rc -- sets rc >= 1 on application error, rc < 0 on E error, otherwise rc = 0 if rc = sayerror( 'Insufficient memory') then leave elseif rc = sayerror( 'File Not found') then leave elseif rc then leave elseif not Exist( OutFile) then 'SayError Error: "'OutFile'" does not exist.' leave endif CurDir = directory() 'xcom Edit' OutFile editrc = rc if rc = -282 then -- sayerror( 'New file') 'xcom Quit' rc = editrc leave elseif rc <> 0 then leave endif .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. rc = greprc 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 DeleteFile( OutFile) rc = greprc enddo return ; --------------------------------------------------------------------------- ; 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% or %NEPMD_DEVDIR%\src\netlabs, then the current file is ; compared with the corresponding file of the other tree. defc CompareCurrentFile do once = 1 to 1 Tool = arg( 1) Name = .filename if IsVirtual( Name) then 'SayError A virtual file can''t be compared.' leave endif FirstFile = Name RootDir = NepmdScanEnv( 'NEPMD_ROOTDIR') if RootDir = '' then 'SayError Environment var NEPMD_ROOTDIR not set.' leave endif UserDir = NepmdScanEnv( 'NEPMD_USERDIR') if UserDir = '' then 'SayError Environment var NEPMD_USERDIR not set.' leave endif NepmdDevDir = NepmdScanEnv( 'NEPMD_DEVDIR') NetlabsDir = RootDir'\netlabs' if NepmdDevDir then NetlabsDevDir = NepmdDevDir'\src\netlabs' else NetlabsDevDir = '' endif UpName = upcase( Name) if abbrev( UpName, upcase( NetlabsDir)) then NameRest = substr( Name, length( NetlabsDir) + 1) SecondFile = UserDir''NameRest -- If user file doesn't exist, use src file if not Exist( SecondFile) then if NetlabsDevDir then SecondFile = NetlabsDevDir''NameRest endif endif elseif abbrev( UpName, upcase( NetlabsDevDir)) & NetlabsDevDir then NameRest = substr( Name, length( NetlabsDevDir) + 1) SecondFile = UserDir''NameRest -- If user file doesn't exist, use netlabs file if not Exist( SecondFile) then SecondFile = NetlabsDir''NameRest endif elseif abbrev( UpName, upcase( UserDir)) then NameRest = substr( Name, length( UserDir) + 1) -- Prefer NetlabsDevDir over NetlabsDir if NetlabsDevDir then SecondFile = NetlabsDevDir''NameRest -- If user file doesn't exist, use netlabs file if not Exist( SecondFile) then SecondFile = NetlabsDir''NameRest endif else SecondFile = NetlabsDir''NameRest -- If user file doesn't exist, use src file if not Exist( SecondFile) then if NetlabsDevDir then SecondFile = NetlabsDevDir''NameRest endif endif endif else SecondFile = '' endif if not Exist( SecondFile) then SecondFile = '' endif Params = EnquoteFileSpec( FirstFile) if SecondFile <> '' then Params = Params EnquoteFileSpec( SecondFile) endif ToolExe = FindTool( Tool) if ToolExe = '' then rc = -274 -- Unknown command 'SayError Error: CompareCurrentFile: Executable not found for FindTool( 'Tool').' return endif 'start /f 'ToolExe Params enddo ; --------------------------------------------------------------------------- defc CompareFiles parse arg File1 File2 if leftstr( File1, 1) = '"' then parse arg '"'File1'"' File2 endif if leftstr( File2, 1) = '"' then parse arg '"'File1'"' '"'File2'"' endif do once = 1 to 1 if File2 = '' then leave endif Tool = 'compare1' ToolExe = FindTool( Tool) if ToolExe = '' then rc = -274 -- Unknown command 'SayError Error: CompareFiles: Executable not found for FindTool( 'Tool').' return endif 'start /f 'ToolExe EnquoteFileSpec( File1) EnquoteFileSpec( File2) enddo ; --------------------------------------------------------------------------- defproc IsUrl( Url) UrlStrings = ':// www. ftp. mailto:' if pos( UrlStrings, Url) then return 1 else return 0 endif ; --------------------------------------------------------------------------- defproc GetUrlUnderPointer 'MH_GoToPointerPos' -- Move the cursor to the pointer position. return GetUrlUnderCursor() -- Process the rest. ; --------------------------------------------------------------------------- defproc GetUrlUnderCursor Url = '' rc = 2 -- default rc; 2: no Url found SeparatorList = '"'||"'"||'(){}[]<>| '\9'#' DiadList = 'NONE:' TrailingSepList = '.:,;!?-' -- extended by '-' -- Todo: Better use a regex for the URL identifier -- The strings 'www. ftp. mailto:' must be placed at the end of this list -- to give the full URL identifiers the precedence. UrlStrings = 'http:// ftp:// https:// news:// irc:// file:/// www. ftp. mailto:' do once = 1 to 1 -- Go to mouse position to ensure getting URL at mouse pointer and not at cursor call pSave_Pos( savedpos) call pSave_Mark( savedmark) -- Get word under cursor, separated by any char of SeparatorList StartCol = 0 EndCol = 0 rcx = Find_Token( StartCol, EndCol, SeparatorList, DiadList, TrailingSepList) fWordFound = (rcx == 1) getline LineStr call pRestore_Pos( savedpos) call pRestore_Mark( savedmark) if not fWordFound then leave endif Spec = substr( LineStr, StartCol, EndCol - StartCol + 1) -- Convert backslashes to slashes Spec = translate( Spec, '/', '\') -- 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 /* -- 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 leave endif rc = 0 enddo return Url ; --------------------------------------------------------------------------- ; EntryBox allows to edit the Url string, but has max. 4 buttons only. defc OpenUrlDlg Url = arg( 1) rc = 0 Title = 'Open URL' Text = 'The following URL was found:' Text = Text''copies( ' ', Max( 100 - length( Text), 0)) Entry = Url Buttons = '/Open in ~app/Open ~more.../'CANCEL__MSG -- max. 4 parse value EntryBox( Title, Buttons, Entry, 0, 240, atoi( 1) || atoi( 0) || atol( 0) || Text) with Button 2 Url \0 Url = strip( Url) if Url = '' then -- nop elseif Button = \1 then -- Open in app call OpenUrl( Url) 'Copy2Clip' Url elseif Button = \2 then -- More 'SelectOpenMoreUrlDlg' Url else -- Cancel, not Esc (Esc for EntryBoxes always closes) rc = 1 endif ; --------------------------------------------------------------------------- ; ListBox allows to select one of multiple items and has max. 8 buttons. ; Here, the only item is the Url string. defc SelectOpenMoreUrlDlg Url = arg( 1) rc = 0 DefaultItem = 1 DefaultButton = 1 HelpId = 0 Title = 'Download or save URL' Entries = \1''Url Ext = '' lp = lastpos( '.', Url) if lp > length( Url) - 10 then Ext = substr( Url, lp + 1) endif fExecute = 0 if wordpos( upcase( Ext), 'EXE WPI ZIP 7Z GZ GZIP TGZ') then fExecute = 1 endif if fExecute then ExecuteEditText = 'Download and ~Execute' else ExecuteEditText = 'Download and ~Edit' endif Buttons = '/Download and ~Save/'ExecuteEditText'/~Copy link location/Return' Text = 'Select how to open the URL:' refresh Result = ListBox( Title, Entries, Buttons, 0, 0, --5, 5, -- top, left, 1, 50, -- height, width GethWndC( APP_HANDLE) || atoi( DefaultItem) || atoi( DefaultButton) || atoi( HelpId) || Text\0) refresh -- Check result Button = asc( leftstr( Result, 1)) EOS = pos( \0, Result, 2) -- CHR( 0) signifies End Of String Selected = substr( Result, 2, EOS - 2) if Button = 1 then -- Download and Save call SaveUrl( Url) -- No error checking required, because on error of wget, the rest -- is not executed anymore elseif Button = 2 then -- Download and Edit/Execute if fExecute then call LoadUrl( Url, 'ExecuteFile') else call LoadUrl( Url, 'Edit') endif -- No error checking required, because on error of wget, the rest -- of Edit -> LoadFile is not executed anymore elseif Button = 3 then -- Copy link location 'Copy2Clip' Url else -- Return 'PostMe OpenUrlDlg' Url endif ; --------------------------------------------------------------------------- ; URL support with wget ; Dragging a URL from Mozilla onto an EPM program object loads the ; downloaded file into EPM, unless it contains following chars: [ ] ? ; They would cause an entrybox to popup for entering parameters. ; With DragText installed, support for dropping text onto the titlebar ; should better be disabled. EPM handles that itself: ; o Dropping it onto the EPM edit window inserts the URL. ; o Dropping it onto the EPM title bar adds a new file with the URL. ; o Ctrl-dropping it onto the EPM edit window won't load the file ; and says: 'File is empty: ""' ; o Ctrl-dropping it onto the EPM title bar adds an empty , ; reverting it after the download will load it. defproc LoadUrl( FileSpec) EpmCmd = arg( 2) if EpmCmd = '' then EpmCmd = 'Edit' endif EpmOpt = arg( 3) p1 = lastpos( '/', FileSpec) Name = substr( FileSpec, p1 + 1) -- Write Url to UrlFile to support longer URLs UrlFile = GetTmpDir()'\nepmd\tmp.url' call WriteFile( UrlFile, FileSpec) TmpFile = GetTmpPath()''Name next = TmpFile i = 0 do while NepmdDirExists( next) i = i + 1 next = TmpFile'_'i enddo TmpFile = next if Exist( TmpFile) then call DeleteFile( TmpFile) endif 'SayError Downloading 'FileSpec KeyPath = '\NEPMD\User\Tools' WgetTemplate = QueryConfigKey( KeyPath'\wget\Template') EpmTemplate = QueryConfigKey( KeyPath'\epm\Template') WgetCall = ExpandTemplate( WgetTemplate, 'uf='UrlFile, 'of='TmpFile) EpmCall = ExpandTemplate( EpmTemplate, 'eo='EpmOpt, 'ec='EpmCmd, 'ef='TmpFile) Cmd = 'os2 /k 'WgetCall'^&^&'EpmCall'^&^&exit' Cmd -- Can't get rc from the called command: -- rc from Cmd is rc from the Os2 command that opens a command prompt -- window, not the rc from the command that Os2 executes. return ; --------------------------------------------------------------------------- defproc SaveUrl( FileSpec) EpmOpt = '' EpmCmd = 'SelectSaveUrl' p1 = lastpos( '/', FileSpec) Name = substr( FileSpec, p1 + 1) -- Write Url to UrlFile to support longer URLs UrlFile = GetTmpDir()'\nepmd\tmp.url' call WriteFile( UrlFile, FileSpec) TmpFile = GetTmpPath()''Name next = TmpFile i = 0 do while NepmdDirExists( next) i = i + 1 next = TmpFile'_'i enddo TmpFile = next if Exist( TmpFile) then call DeleteFile( TmpFile) endif 'SayError Downloading 'FileSpec KeyPath = '\NEPMD\User\Tools' WgetTemplate = QueryConfigKey( KeyPath'\wget\Template') EpmTemplate = QueryConfigKey( KeyPath'\epm\Template') WgetCall = ExpandTemplate( WgetTemplate, 'uf='UrlFile, 'of='TmpFile) EpmCall = ExpandTemplate( EpmTemplate, 'eo='EpmOpt, 'ec='EpmCmd, 'ef='TmpFile) Cmd = 'os2 /k 'WgetCall'^&^&'EpmCall'^&^&exit' Cmd -- Can't get rc from the called command: -- rc from Cmd is rc from the Os2 command that opens a command prompt -- window, not the rc from the command that Os2 executes. return ; --------------------------------------------------------------------------- ; Syntax: ExpandedTemplate = ExpandTemplate( Template, ; Var1=Value1, Var2=Value2, ...) defproc ExpandTemplate( Template) ExpandedTemplate = Template -- Expand VarName=VarValue args do i = 2 to arg() next = arg( i) parse value next with VarName '=' VarValue startp = 1 VarLen = length( '%'VarName) -- Chars for env vars EnvNameChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-!' do forever p = pos( '%'upcase( VarName), upcase( ExpandedTemplate), startp) if p = 0 then leave endif -- Don't expand names longer then VarName if not verify( substr( ExpandedTemplate, p + VarLen, 1), EnvNameChars) then startp = p + 1 iterate endif LStr = leftstr( ExpandedTemplate, p - 1) RStr = substr( ExpandedTemplate, p + VarLen) ExpandedTemplate = LStr''VarValue''RStr startp = p - VarLen + length( VarValue) enddo enddo -- Expand env vars ExpandedTemplate = ExpandEnvVars( ExpandedTemplate) return ExpandedTemplate ; --------------------------------------------------------------------------- defc ExecuteFile universal wpsstarted FileMask = arg( 1) if wpsstarted then 'OpenObject' FileMask else 'start /f' FileMask endif ; --------------------------------------------------------------------------- defc SelectSaveUrl FileMask = arg( 1) Title = SAVE_AS__MSG Cmd = 'MoveFile' FileMask 'FileDlg' Title', 'Cmd', 'FileMask ; --------------------------------------------------------------------------- defc OpenUrl call OpenUrl( arg( 1)) defproc OpenUrl( Url) universal wpsstarted rc = 2 -- Default rc; 2: no Url or no App found if wpsstarted then Class = 'WPUrl' Title = 'NEPMD tmp URL' Setup = 'OBJECTID=;LOCATOR='Url';OPEN=DEFAULT;' Location = GetTmpDir()'\nepmd' call CreateObject( Class, Title, Setup, Location) else do once = 1 to 1 Exe = '' Parameters = '' WorkingDir = '' fTruncated = 0 -- Find app for each WPS-defined special URL type Tool = '' ToolString = '' KeywordList = 'Exe;Parameters;WorkingDir' 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) if rc then ToolString = '' endif endif -- Default app if ToolString = '' then Tool = 'browser' ToolString = FindTool( Tool, KeywordList) endif if rc then 'SayError Error: OpenUrl: Executable not found for FindTool( 'Tool').' leave endif parse value ToolString with 'Exe='Exe';Parameters='Parameters';WorkingDir='WorkingDir';' -- Save Parameters for debug OrgParameters = Parameters -- Use default parameter string if no parameter set if Parameters = '' then Parameters = '%*' endif -- Expand WPS parameter macros Parameters = ExpandWpsParameterMacros( Parameters, Url) StartUrlProgram( Exe, Parameters, WorkingDir) enddo endif return ; --------------------------------------------------------------------------- defproc StartUrlProgram( Exe, Parameters, WorkingDir) rc = 2 -- Default rc; 2: no Url or no App found do once = 1 to 1 -- 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 -- 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 Parameters if too long to avoid EPM crashing. -- Max. length for a command executed by cmd.exe is 300. -- Max. line length in a .cmd file executed by cmd.exe is 1023. -- Max. length of an E proc parameter and an E var is 255. -- Max. length of an REXX string is 255, but var values may be concatenated up to 16 MB. -- Better use a temporary REXX .cmd file. MaxLen = 239 - CmdLen -- why 239? fTruncated = 0 if length( Parameters) > MaxLen then Parameters = leftstr( Parameters, MaxLen) fTruncated = 1 -- Try to truncate before a % char, otherwise the URL gets unvalid sometimes, -- but only in the last 20 chars lp = lastpos( '%', Parameters) if lp > MaxLen - 20 then Parameters = leftstr( Parameters, lp - 1) endif endif if fTruncated then 'SayError Invoking' ExeShortName 'with (truncated):' Parameters else 'SayError Invoking' ExeShortName 'with:' Parameters endif -- Execute the command and set rc Cmd = CmdPre''Parameters''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 -- Index of ftp://ftp.netlabs.org/ -- Next works, but won't find anything: -- http://groups.google.com/groups?num=20&hl=en&scoring=d&as_drrb=b&q=epm+group%3Ade.comp.os.*+OR+group%3Acomp.os.*&btnG=Google-Suche&as_miny=2001&as_minm=1&as_mind=1 -- Next is much too long and also doesn't work any more: -- http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=4ebg22%24jod%40watnews2.watson.ibm.com&rnum=3&prev=/groups%3Fq%3Dautosave%2Bgroup:comp.os.os2.apps%26hl%3Dde%26lr%3D%26ie%3DUTF-8%26group%3Dcomp.os.os2.apps%26selm%3D4ebg22%2524jod%2540watnews2.watson.ibm.com%26rnum%3D3 -- Restore current drive and directory if fCurDirChanged then 'cdd' CurDir endif rc = exerc enddo return ; --------------------------------------------------------------------------- ; Syntax: ExpandWpsParameterMacros( Parameters, FileName) ; Parameters: Parameter string as used by WPS program objects. ; FileName : For WPS program objects, this would be the submitted file or ; folder name. It's used to expand the % parameter macros. defproc ExpandWpsParameterMacros( Parameters, FileName) -- Parse FileName FullName = FileName -- Path and Name lp = lastpos( '\', translate( FullName, '\', '/')) if lp > 0 then Path = leftstr( FullName, lp - 1) Name = substr( FullName, lp + 1) else Path = '' Name = FullName endif -- Drive if pos( ':', FullName) = 2 then Drive = leftstr( FullName, 2) elseif pos( '\\', FullName) = 1 then pBackSlash = pos( '\', translate( FullName, '\', '/'), 3) if pBackSlash > 0 then Drive = leftstr( FullName, pBackSlash - 1) else Drive = FullName endif else Drive = '' endif -- BaseName and Ext (This doesn't support FAT file names.) lp = lastpos( '.', Name) if lp > 0 then BaseName = leftstr( Name, lp - 1) Ext = substr( Name, lp + 1) else BaseName = Name Ext = '' endif -- Replace WPS macros in the parameter string MacroList = '%**P %**D %**F %**N %**E %*' do w = 1 to words( MacroList) Macro = word( MacroList, w) if Macro = '%**P' then Replace = Path elseif Macro = '%**D' then Replace = Drive elseif Macro = '%**F' then Replace = Name elseif Macro = '%**N' then Replace = BaseName elseif Macro = '%**E' then Replace = Ext elseif Macro = '%*' then Replace = FullName endif Parameters = ChangeStr( Macro, Parameters, Replace) enddo return Parameters ; --------------------------------------------------------------------------- const compile if not defined( VALIDATE_HTML_UPLOAD) VALIDATE_HTML_UPLOAD='http://validator.w3.org/#validate_by_upload+with_options' compile endif ;compile if not defined( VALIDATE_HTML_CHECK) ; -- file uris aren't accepted: ; VALIDATE_HTML_CHECK='http://validator.w3.org/check?uri=file:///' ;compile endif compile if not defined( VALIDATE_CSS_UPLOAD) VALIDATE_CSS_UPLOAD='http://jigsaw.w3.org/css-validator/#validate_by_upload+with_options' compile endif ; --------------------------------------------------------------------------- defc ValidateHtml 'CheckModify' 'OpenUrl' VALIDATE_HTML_UPLOAD --'OpenUrl' VALIDATE_HTML_CHECK''translate( .filename, '/', '\') ; --------------------------------------------------------------------------- defc ValidateCss 'CheckModify' 'OpenUrl' VALIDATE_CSS_UPLOAD ; --------------------------------------------------------------------------- defc EncodeFrom universal codepage SystemEncodingNum = codepage if lowcase( GetEncodingTool()) = 'recode' then SystemEncoding = 'ibm'SystemEncodingNum else SystemEncoding = 'ibm-'SystemEncodingNum endif 'Encode 'GetEncodingCode() SystemEncoding GetEncodingTool() ; --------------------------------------------------------------------------- defc EncodeTo universal codepage SystemEncodingNum = codepage if lowcase( GetEncodingTool()) = 'recode' then SystemEncoding = 'ibm'SystemEncodingNum else SystemEncoding = 'ibm-'SystemEncodingNum endif 'Encode 'SystemEncoding GetEncodingCode() GetEncodingTool() ; --------------------------------------------------------------------------- ; This includes protection to not apply the same encoding twice. It can ; only work after the EA EPM.ENCODING was written the first time. To allow ; for undoing all encoding changes, even unrecoverable, a backup is created ; before each encoding action. defc Encode do once = 1 to 1 parse arg FromCode ToCode Tool Tool = strip( Tool) if lowcase( Tool) <> 'recode' then Tool = 'uconv' endif Tool = lowcase( Tool) -- Handle virtual file lp = lastpos( '\', .filename) if lp = 0 then -- A virtual file: save it as tmp file File = GetTmpPath()''.filename .filename = File 'Save 'File lp = lastpos( '\', .filename) -- Check if file exists elseif not Exist( .filename) then 'SayError '.filename 'does not exist on disk. Save it first.' rc = sayerror( 'File not found') leave -- Check .modify state elseif .modify then if WinMessageBox( 'Convert encoding and reload file from disk', .filename' was modified.'\13 || 'Throw away changes to file on disk?', MB_OKCANCEL + MB_WARNING + MB_DEFBUTTON1 + MB_MOVEABLE) <> MBID_OK then rc = -293 -- sayerror( "has been modified") leave else .modify = 0 endif endif -- Reset readonly EPM field if .readonly then .readonly = 0 endif -- Unlock within EPM if .lockhandle then 'Unlock' endif -- Get Name and Basename Name = GetFileSpec( 'N', .filename) Basename = GetFileSpec( 'B', .filename) -- Input file InFile = .filename EnqInFile = EnquoteFileSpec( InFile) -- Temporary output file OutFile = GetTmpPath()''Basename'.enc' EnqOutFile = EnquoteFileSpec( OutFile) -- Temporary EA file EaFile = GetTmpPath()''Basename'.ea' EnqEaFile = EnquoteFileSpec( EaFile) -- Log file LogFile = GetTmpPath()'encode.log' EnqLogFile = EnquoteFileSpec( LogFile) -- Check if already encoded EaValue = NepmdQueryStringEa( InFile, 'EPM.ENCODING') parse value EaValue with EaPrevCode '('EaOrgCode')' if EaPrevCode = ToCode then -- Warn that the same encoding is applied a second time Title = 'Encode 'Name Text = '' Text = Text || 'Encoding "'FromCode'" to "'ToCode'".'\n Text = Text || 'Saved EA value is: "'EaValue'".'\n\n Text = Text || 'Do you really want to apply the same encoding a' Text = Text || ' second time?'\n\n Style = MB_OKCANCEL + MB_DEFBUTTON2 + MB_WARNING + MB_MOVEABLE rcx = WinMessageBox( Title, Text, Style) if rcx = MBID_CANCEL then rc = -18 leave endif endif -- Reset readonly file attribute if GetReadonly() then quietshell 'attrib -r' EnqInFile endif -- Todo: Create local InFile for network files and for -- a file from a read-only drive. -- Unlock caused by others quietshell 'unlock' EnqInFile -- Create a backup fForce = 1 -- 1 = bypas the checks for discarded and unmodified file MakeBackup( InFile, fForce) -- Save FileInfo and create EaFile call SaveFileInfoEa( InFile, FileInfo, EaFile) -- Determine if --add-signature should be added fUconv = (Tool = 'uconv') KeyPath = '\NEPMD\User\Encoding\WriteBom' fWriteBom = QueryConfigKey( KeyPath) KeyPath = '\NEPMD\User\Encoding\BomOnlyForEncodings' fBomOnlyForEncodings = QueryConfigKey( KeyPath) KeyPath = '\NEPMD\User\Encoding\BomEncodingList' EncodingList = QueryConfigKey( KeyPath) fAddBomOption = 0 do once2 = 1 to 1 if not fUconv then leave elseif not fWriteBom then leave elseif not fBomOnlyForEncodings then fAddBomOption = 1 leave endif do w = 1 to words( EncodingList) ThisFilter = word( EncodingList, w) if StrMatch( ToCode, ThisFilter) then fAddBomOption = 1 leave endif enddo enddo -- Execute encoding tool KeyPath = '\NEPMD\User\Tools' if fUconv & fAddBomOption then EncTemplate = QueryConfigKey( KeyPath'\uconv\AddBom\Template') elseif fUconv then EncTemplate = QueryConfigKey( KeyPath'\uconv\Template') else EncTemplate = QueryConfigKey( KeyPath'\recode\Template') endif LogTemplate = QueryConfigKey( KeyPath'\log\Template') Cmd = ExpandTemplate( EncTemplate LogTemplate, 'fe='FromCode, 'te='ToCode, 'if='InFile, 'of='OutFile, 'lf='LogFile) -- Edit command before execution KeyPath = '\NEPMD\User\Encoding\EditCmdBefore' if QueryConfigKey( KeyPath) = 1 then Title = 'Change encoding' Text = 'Executed command:' Text = Text''copies( ' ', Max( 100 - length(Text), 0)) DefaultEntry = Cmd DefaultButton = 1 HelpId = 0 parse value EntryBox( Title, '/'OK__MSG'/'Cancel__MSG, DefaultEntry, '', 300, atoi( DefaultButton) || atoi( HelpId) || GetHwndC( APP_HANDLE) || Text) with Button 2 CmdConfirmed \0 Button = asc( Button) if Button = 0 | Button = 2 then -- Esc or Cancel return endif Cmd = CmdConfirmed endif -- Execute Cmd CmdFile = GetTmpPath()'callencode.cmd' call RunCmdFile( CmdFile, Cmd) if rc <> 0 then if rc = -274 then Msg = 'Error from quietshell: 'sayerrortext( rc)', rc = 'rc', Cmd = 'Cmd else Msg = 'Error from 'Tool': rc = 'rc', Cmd = 'Cmd endif 'SayError 'Msg -- Quit old logfile getfileid startfid getfileid testfid, LogFile if testfid <> '' then display -2 activatefile testfid display 2 .modify = 0 'xcom quit' activatefile startfid endif -- Load file to view output from tool and prepend Msg 'e /d 'EnqLogFile insertline Msg, 1 .modify = 0 leave endif if Tool <> 'recode' then -- Copy OutFile over InFile if not Exist( OutFile) then 'SayError Error from 'Tool': OutFile doesn''t exist, Cmd = 'Cmd rc = 2 leave endif call CopyFile( OutFile, Infile) if not rc then call DeleteFile( OutFile) endif endif -- Restore FileInfo and join EaFile call RestoreFileInfoEa( InFile, FileInfo, EaFile) 'SayError Encoded from 'FromCode' to 'ToCode': 'InFile EaValue = ToCode '('FromCode')' call NepmdWriteStringEa( InFile, 'EPM.ENCODING', EaValue) -- Revert 'Revert' --'PostMe Revert' -- PostMe required for large files 'RefreshInfoLine ENCODING' if GetMenuAVar( 'curencoding') <> '' then SetMenuVarText( 'curencoding', GetEncodingType(), GetEncoding()) endif enddo ; --------------------------------------------------------------------------- ; Call uconv and revert current file defc Uconv parse arg args do once = 1 to 1 if .modify then if WinMessageBox( 'Convert encoding and reload file from disk', .filename' was modified.'\13 || 'Throw away changes to file on disk?', MB_OKCANCEL + MB_WARNING + MB_DEFBUTTON1 + MB_MOVEABLE) <> MBID_OK then rc = -293 -- sayerror( "has been modified") return else .modify = 0 'Unlock' endif endif Tool = 'uconv' DefaultOptions = '-i -f latin1 -t cp850' RetString = FindTool( Tool, 'Exe Options') parse value RetString with 'Exe='ToolExe';Options='Options';' if ToolExe = '' then rc = -274 -- Unknown command 'SayError Error: Uconv: Executable not found for FindTool( 'Tool').' return endif if Options = '' then Options = DefaultOptions endif Args = arg( 1) if Args = '' then 'CommandLine uconv 'DefaultOptions -- recursive call leave endif FileName = EnquoteFileSpec( .filename) -- uconv.exe can't write on the file that was read. -- Todo: Handle virtual files correctly. lp = lastpos( '\', .filename) fHasDir = 0 if lp > 1 then fHasDir = 1 Name = substr( .filename, lp + 1) else -- A virtual file Name = .filename endif OutFile = EnquoteFileSpec( GetTmpPath()''Name'.uconv') OutFileArgs = '-o' OutFile quietshell ToolExe Args OutFileArgs FileName if rc = 0 then if fHasDir then quietshell 'copy' OutFile FileName if rc = 0 then quietshell 'del' OutFile 'Revert' endif else 'Edit' OutFile endif 'RefreshInfoLine ENCODING' if GetMenuAVar( 'curencoding') then SetMenuVarText( 'curencoding', GetEncodingType(), GetEncoding()) endif else 'SayError Error from uconv: rc = 'rc'.' endif enddo ; --------------------------------------------------------------------------- ; Call recode and revert current file defc Recode parse arg args do once = 1 to 1 if .modify then if WinMessageBox( 'Recode and reload file from disk', .filename' was modified.'\13 || 'Throw away changes to file on disk?', MB_OKCANCEL + MB_WARNING + MB_DEFBUTTON1 + MB_MOVEABLE) <> MBID_OK then rc = -293 -- sayerror( "has been modified") return else .modify = 0 'unlock' endif endif Tool = 'recode' DefaultOptions = 'latin1:cp850' RetString = FindTool( Tool, 'Exe Options') parse value RetString with 'Exe='ToolExe';Options='Options';' if ToolExe = '' then rc = -274 -- Unknown command 'SayError Error: Recode: Executable not found for FindTool( 'Tool').' return endif if Options = '' then Options = DefaultOptions endif Args = arg( 1) if Args = '' then 'CommandLine recode 'DefaultOptions -- recursive call leave endif FileName = EnquoteFileSpec( .filename) quietshell ToolExe Args FileName if rc = 0 then 'Revert' 'RefreshInfoLine ENCODING' if GetMenuAVar( 'curencoding') then SetMenuVarText( 'curencoding', GetEncodingType(), GetEncoding()) endif else 'SayError Error from recode: rc = 'rc'.' endif enddo ; --------------------------------------------------------------------------- ; Queries current encoding from EA. If EA not set, returns system encoding. defproc GetEncoding universal codepage Filename = arg( 1) if Filename = '' then Filename = .filename endif EaValue = NepmdQueryStringEa( Filename, 'EPM.ENCODING') parse value EaValue with EaCurEnc '('EaPrevEnc')' if EaCurEnc = '' then SystemEncNum = codepage SystemEnc = 'ibm-'SystemEncNum CurEnc = SystemEnc else CurEnc = EaCurEnc endif return CurEnc ; --------------------------------------------------------------------------- ; Queries current encoding from EA. If EA not set, returns system encoding. defproc GetEncodingType Filename = arg( 1) if Filename = '' then Filename = .filename endif EaValue = NepmdQueryStringEa( Filename, 'EPM.ENCODING') parse value EaValue with EaCurEnc '('EaPrevEnc')' if EaCurEnc = '' then EncType = 'System' else EncType = 'EA' endif return EncType ; --------------------------------------------------------------------------- ; Compare 2 files using MD5.EXE or MD5SUM.EXE. Returns: ; 0 if equal ; 1 if different ; -1 on error (rc can be checked for details) defproc Md5Comp( File1, File2) DiffExe = arg( 3) DiffOpt = arg( 4) ret = -1 do once = 1 to 1 lp = lastpos( '.', File1) if lp > 1 then FullBaseName1 = substr( File1, 1, lp - 1) else FullBaseName1 = File1 endif lp = lastpos( '.', File2) if lp > 1 then FullBaseName2 = substr( File2, 1, lp - 1) else FullBaseName2 = File2 endif md51 = NepmdMd5( File1) md52 = NepmdMd5( File2) if md51 <> '' & md52 <> '' then if md51 <> md52 then -- If different, use diff to compare line-wise with ignore option if DiffExe <> '' | DiffOpt <> '' then if DiffExe = '' then DiffExe = FindTool( 'diff') endif if DiffExe = '' then ret = 1 else if DiffOpt = '' then DiffOpt = '-u -I "\$\(Date\|Revision\|Author\|HeadURL\|Id\).*$"' endif quietshell DiffExe DiffOpt EnquoteFileSpec( File1) EnquoteFileSpec( File2) '1>nul 2>nul' if rc = 0 then -- equal ret = 0 elseif rc = 1 then -- different ret = 1 elseif rc = 2 then -- error ret = 1 endif endif else ret = 1 endif else ret = 0 endif endif enddo return ret