/****************************** Module Header ******************************* * * Module Name: kwhelp.e * * Copyright (c) Netlabs EPM Distribution Project 2002 * * $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. * ****************************************************************************/ /* Format of index file: EXTENSIONS: ... DESCRIPTION: ... MODE: ... (Win*, view winhelp.inf ~) (printf, view edchelp.inf printf) - Line comment char is '*' in column 1. - MODE was added for NEPMD. Either EXTENSIONS or MODE is optional. DESCRIPTION is optional. - Multiple MODE and EXTENSION values must be space-separated. - As wildcard, '*' can be used at the following places: - Instead of a mode or extension. - At the end or instead of a keyword specification. - Other places are not supported. '?' is not supported. - The tilde in the command is replaced by the current keyword at the cursor, provided that the keyword specification of that entry matches. */ compile if not defined( SMALL) -- If compiled separately define INCLUDING_FILE = 'KWHELP.E' include 'stdconst.e' const tryinclude 'mycnf.e' const compile if not defined( NLS_LANGUAGE) NLS_LANGUAGE = 'ENGLISH' compile endif include NLS_LANGUAGE'.e' defmain 'KwHelp' arg( 1) compile endif ; --------------------------------------------------------------------------- defc KwhelpSelect Title = 'Keyword help' Text = 'Enter a keyword to perform a helpfile search on:' DefaultButton = 1 -- The following must be posted in some cases, e.g. when a nodismiss -- menu item was toggled before: parse value EntryBox( Title, '/'OK__MSG'/'CANCEL__MSG, -- max. 4 buttons '', '', 260, atoi( DefaultButton) || atoi( 0000) || -- help id GethWndC( APP_HANDLE) || Text) with Button 2 NewValue \0 NewValue = strip( NewValue) if Button = \1 & NewValue <> '' then Identifier = NewValue 'KwHelp' Identifier return else return endif ; --------------------------------------------------------------------------- const compile if not defined( NEWVIEW_VERSION) NEWVIEW_VERSION = 2.19 compile endif defc Kwhelp do once = 1 to 1 lrc = -1 FoundLineStr = '' Ext = Filetype() Mode = GetMode() -- 1) Get Identifier Identifier = arg( 1) if Identifier = '?' then -- Open entrybox 'KwhelpSelect' leave -- once elseif Identifier = '' then -- Identifier = keyword under cursor fIncludeLitCom = 1 CurIdStr = CurIdentifier( Mode, fIncludeLitCom) if CurIdStr = '' then 'SayError No keyword under cursor.' leave -- once endif parse value CurIdStr with pIdStart pIdEnd FoundId Identifier = FoundId do once2 = 1 to 1 -- Mode E: prepend '.' if present to find field vars if Mode <> 'E' then leave -- once2 endif LineStr = textline( .line) p = pIdStart - 1 if p < 1 then leave -- once2 endif PrevChr = substr( LineStr, p, 1) if PrevChr <> '.' then leave -- once2 endif Identifier = '.'Identifier enddo endif -- 2) Build help index call pSave_Pos( SavedPos) getfileid startfid -- Always rebuild both index files. The first one is for a matched mode or -- extension, the second one for a wildcard '*' instead of a mode or -- extension. 'SayError Building help index for' Ext '...' dprintf( 'kwhelp', 'Building help index for' Ext '...') call BuildHelpIndex( Ext, Mode, helpindexfid, helpindexallfid) if helpindexfid = '' & helpindexallfid = '' then 'SayError Unable to build help file' leave -- once endif -- 3) Search help index for Identifier match display -2 -- Suppress 'String not found' messages from 'xcom l' getsearch savesearch fCaseSensitive = (QueryModeKey( Mode, 'CaseSensitive') = 1) if fCaseSensitive then Case = 'e' else Case = 'c' endif s = 0 len = length( Identifier) do i = 1 to 2 -- Both help index files are processed consecutively to ensure that -- all lines of the first one are processed before the common one. if i = 1 then helpfid = helpindexfid else helpfid = helpindexallfid endif activatefile helpfid do l = len to 0 by -1 if l = len then IdStr = Identifier else -- Support appended '*' as wildcard -- Support also only '*', maybe as fallback entry IdStr = leftstr( Identifier, l)'*' endif Search = '('IdStr',' top .col = 1 -- Search for a match 'xcom l '\1''Search''\1''Case lrc = rc dprintf( 'kwhelp', 'xcom l '\1''Search''\1''Case', rc = 'lrc', .line = '.line', .last = '.last) if not lrc then FoundLineStr = textline( .line) leave -- l endif enddo if not lrc then leave -- i endif enddo 'SayError 0' -- Delete 'Building help index ...' setsearch savesearch display 2 call CloseHiddenFile( helpindexfid) call CloseHiddenFile( helpindexallfid, startfid) call pRestore_Pos( SavedPos) -- 4) Display help file if lrc then 'SayError No matching indexfile found for "'Identifier'".' else parse value FoundLineStr with . ',' CmdStr ')' CmdStr = strip( CmdStr) dprintf( 'kwhelp', 'rc = 'lrc', Found CmdStr = ['CmdStr']') CmdStr = ChangeStr( '~', CmdStr, Identifier) -- Expand env vars, check for existing env vars next = ExpandEnvVars( CmdStr, 1) if rc then leave -- once endif CmdStr = next -- Parse line dprintf( 'kwhelp', 'Parsing help line: 'CmdStr) parse value CmdStr with App Arg1 Arg2 if upcase( App) = 'START' then parse value CmdStr with . App Arg1 Arg2 endif -- Search the file, if the command is a view dprintf( 'kwhelp', 'Building CheckedFileList') if upcase( App) = 'VIEW' then -- Second word is the file. -- Convert a possible ViewFileList to CheckedFileList, in order -- to continue searching if an .inf file doesn't exist. ViewFileList = Arg1 rest = ViewFileList CheckedFileList = '' ExpandedEnvVarList = ';' do while rest <> '' parse value rest with ViewFile'+'rest section -- EnvVars are already expanded at this point -- Check if ViewFile specifies an EnvVar (e.g. PMREF) -- Expand each env var only once to omit an infinite loop (ticket #17) if pos( ';'upcase( ViewFile)';', ExpandedEnvVarList) = 0 then next = Get_Env( ViewFile) if next <> '' then -- If found, add next to rest and re-parse it ExpandedEnvVarList = ExpandedEnvVarList''upcase( ViewFile)';' rest = next'+'rest iterate endif endif if pos( '.', ViewFile) = 0 then ViewFile = ViewFile'.inf' endif dprintf( 'kwhelp', 'ViewFile = 'ViewFile) -- Search the file SearchFile = ViewFile FoundFile = '' findfile FoundFile, SearchFile, 'BOOKSHELF' -- The syntax in epmtech.inf is wrong if rc then 'SayError INF file' ViewFile 'could not be found.' else CheckedFileList = CheckedFileList''ViewFile'+' endif enddo -- while rest <> '' -- Re-build the line with a file list containing only found files. CheckedFileList = strip( CheckedFileList, 'B', '+' ) if CheckedFileList = '' then CmdStr = '' -- Don't try to execute a CmdStr but execute -- "activatefile" at the end. .helpfile is currently -- active and would become visible on a "return" here. else CmdStr = App CheckedFileList Arg2 endif endif -- upcase( App) = 'VIEW' dprintf( 'kwhelp', 'CmdStr = ['CmdStr']') if CmdStr = '' then rc = 1 else rc = 0 fFound = 1 -- For newview: Maybe execute a real search instead of just a lookup -- in the index. -- Unfortunately their is no reliable way to check the install state -- nor the version of NewView, to handle its buggy command line -- parsing. if upcase( App) = 'VIEW' then parse value CmdStr with App Inf SearchStr SearchStr = strip( SearchStr) -- Use NewView, if found in PATH fUseNewView = 0 KeyPath = '\NEPMD\User\KeywordHelp\NewView\UseIfFound' next = QueryConfigKey( KeyPath) if next <> 0 then -- If NewView was installed as View replacement, then -- IBMVIEW.EXE exists next = NepmdSearchPath( 'ibmview.exe') if next <> '' then -- Better don't change 'VIEW', because NewView can re-use a file, -- that is already loaded, when its stub (renamed to VIEW.EXE) -- is used. Otherwise a new window is opened on every KwHelp. --cmd = 'newview' fUseNewView = 1 else -- If NewView was not installed as View replacement, then -- search for NEWVIEW.EXE in PATH next = NepmdSearchPath( 'newview.exe') if next <> '' then fUseNewView = 1 cmd = 'newview' endif endif endif -- Use NewView's extended search? fNewViewExtendedSearch = 0 if fUseNewView then KeyPath = '\NEPMD\User\KeywordHelp\NewView\ExtendedSearch' next = QueryConfigKey( KeyPath) if next <> 0 then fNewViewExtendedSearch = 1 endif endif -- Testcases, press Alt+0 on a following line: /* start ibmview cmdref net view start ibmview cmdref "net view" start newview cmdref net view start newview cmdref "net view" start newview cmdref /s:net view start newview cmdref /s:"net view" start newview cmdref /s:"net view"" start newview cmdref /s:"""net view""" start newview cmdref /s"""net view""" start newview cmdref /s net view start newview cmdref /s "net view" start newview cmdref /s "net view"" start newview cmdref /s """net view"" start newview cmdref /s """net view""" */ if fUseNewView & leftstr( SearchStr, 1) <> '"' & pos( ' ', SearchStr) then -- NewView before 2.19.b2 requires "..." for strings with spaces, -- View strips them. Newer NewView versions can handle both, with -- or without double quotes. So always add them. SearchStr = '"'SearchStr'"' -- NewView 2.19.b2 and up requires the doublequotes only for the ; -- extended search with /s:SearchStr. -- extended search with /s SearchStr. endif if fNewViewExtendedSearch & leftstr( SearchStr, 1) = '"' then compile if NEWVIEW_VERSION < 2.19 -- Newview before 2.19.b2 needs a doubled closing double quote SearchStr = SearchStr'"' ;compile elseif NEWVIEW_VERSION >= 2.19 ; -- NewView 2.19.b2 and up needs tripled double quotes ; SearchStr = '""'SearchStr'""' compile endif endif if fNewViewExtendedSearch then ; CmdStr = 'view 'Inf' /s:'SearchStr CmdStr = 'newview 'Inf' /s 'SearchStr endif endif -- upcase( App) = 'VIEW' if wordpos( upcase( word( CmdStr, 1)), 'START QS QUIETSHELL DOS OS2') then -- Omit the 'dos' or 'start' command if specified in .ndx file or -- as an alternative VIEW command. HelpCmd = CmdStr else HelpCmd = 'start /f' CmdStr endif 'SayError Invoking "'HelpCmd'"' HelpCmd -- execute the command dprintf( 'kwhelp', 'rc = 'rc' from HelpCmd = 'HelpCmd) endif -- CmdStr = '' else endif -- lrc else enddo -- once rc = lrc ; --------------------------------------------------------------------------- defproc BuildHelpIndex( Ext, Mode, var helpindexfid, var helpindexallfid) helpindexfid = '' helpindexallfid = '' -- Search all files on shelf first, put list into ShelfList BookShelf = Get_Env( 'BOOKSHELF') HelpNdx = Get_Env( 'HELPNDX') ShelfList = '' -- If EnvVar HELPNDXSHELF is set then find *.ndx in all pathes Rest = BookShelf do while Rest <> '' -- Get single HelpDir from HelpNdxShelf parse value Rest with NdxDir';'Rest -- Search all ndx files in this directory of the Ndx shelf path Filemask = NepmdQueryFullname( NdxDir'\*.ndx') Handle = '' -- Always create a new handle! Filename = '' do while NepmdGetNextFile( FileMask, Handle, Filename) --dprintf( 'kwhelp', 'Found .ndx file = 'Filename) -- Add filename only to NdxFileList, if not already in Filename = substr( Filename, lastpos( '\', Filename) + 1) if pos( translate( Filename), translate( ShelfList'+'HelpNdx)) = 0 then ShelfList = ShelfList'+'Filename endif enddo enddo -- Now prepend given help list to previous searchlist NdxFileList = HelpNdx''ShelfList if NdxFileList = '' then compile if defined( KEYWORD_HELP_INDEX_FILE) NdxFileList = KEYWORD_HELP_INDEX_FILE compile else NdxFileList = 'epmkwhlp.ndx' compile endif endif -- Remove leading '+' char NdxFileList = strip( NdxFileList) NdxFileList = strip( NdxFileList, 'L', '+') dprintf( 'kwhelp', 'NdxFileList = 'NdxFileList) RestList = NdxFileList do while RestList <> '' -- Parse thru all entries within the help list parse value RestList with NdxFile'+'RestList -- Skip empty entries, they may show up due to a double plus character if NdxFile = '' then iterate endif SearchFile = NdxFile FoundFile = '' do once = 1 to 1 -- Look for the help index file in BOOKSHELF first findfile FoundFile, SearchFile, 'BOOKSHELF' -- The syntax in epmtech.inf is wrong if not rc then leave endif -- If that fails, look for the help index file in current -- dir, EPMPATH, DPATH, and EPM.EXE's dir: findfile FoundFile, SearchFile, '', 'D' -- The syntax in epmtech.inf is wrong if not rc then leave endif -- If that fails, try the standard path. findfile FoundFile, SearchFile, 'PATH' -- The syntax in epmtech.inf is wrong if rc then sayerror 'Help index 'NdxFile' not found' rc = 0 -- return -- Changed this so that error is informational, not severe endif enddo NdxFile = FoundFile -- Load next NdxFile 'xcom e /d 'NdxFile if rc then iterate endif getfileid ndxfid fFound = 0 MatchType = '' NdxStartLine = 0 do l = 1 to .last UpLineStr = strip( upcase( textline( l))) chr1 = leftstr( UpLineStr, 1) parse value UpLineStr with wrd1 ':' rest wrd1 = strip( wrd1) if UpLineStr = '' then iterate elseif chr1 = '*' then -- Comment iterate elseif chr1 = '(' then -- End of header NdxStartLine = l leave elseif wrd1 = 'DESCRIPTION' then iterate elseif wrd1 = 'EXTENSIONS' then if wordpos( Ext, rest) then fFound = 1 MatchType = MatchType 'extension' elseif wordpos( '*', rest) then fFound = 1 MatchType = MatchType 'wildcard' endif elseif wrd1 = 'MODE' then if wordpos( Mode, rest) then fFound = 1 MatchType = MatchType 'mode' elseif wordpos( '*', rest) then fFound = 1 MatchType = MatchType 'wildcard' endif endif enddo MatchType = strip( MatchType) if not fFound | NdxStartLine = 0 then .modify = 0 'xcom quit' iterate endif dprintf( 'kwhelp', 'NdxFile = 'NdxFile', ndxfid = 'ndxfid', MatchType = 'MatchType', NdxStartLine = 'NdxStartLine', helpindexfid = 'helpindexfid', helpindexallfid = 'helpindexallfid) if not helpindexfid then helpindexfid = LoadHiddenFile( '.helpindex') if not helpindexfid then return endif dprintf( 'kwhelp', '.helpindex loaded, helpindexfid = 'helpindexfid) endif if not helpindexallfid then helpindexallfid = LoadHiddenFile( '.helpindexall') if not helpindexallfid then return endif dprintf( 'kwhelp', '.helpindexall loaded, helpindexallfid = 'helpindexallfid) endif -- Copy index part of this ndxfid to helpindexfid activatefile ndxfid call pSave_Mark( SavedMark) call pSet_Mark( NdxStartLine, ndxfid.last, 1, MAXCOL, 'LINE', ndxfid) if wordpos( 'extension', Matchtype) then activatefile helpindexfid .line = .last copymark elseif wordpos( 'mode', Matchtype) then activatefile helpindexfid .line = .last copymark elseif wordpos( 'wildcard', Matchtype) then activatefile helpindexallfid .line = .last copymark endif call pRestore_Mark( SavedMark) activatefile ndxfid .modify = 0 'xcom quit' enddo return ; --------------------------------------------------------------------------- defc ViewWord -- arg(1) is name of .inf file if Find_Token( startcol, endcol) then InfFile = arg( 1) InfFile = ExpandEnvVars( InfFile) -- specifying the extension is optional if upcase( rightstr( InfFile, 4)) <> '.INF' then InfFile = InfFile'.inf' endif if pos( ':\', InfFile) = 0 then SearchFile = InfFile FoundFile = '' findfile FoundFile, SearchFile, 'BOOKSHELF' -- The syntax in epmtech.inf is wrong if rc then sayerror FILE_NOT_FOUND__MSG '"'InfFile'"' return endif InfFile = FoundFile endif 'start view' InfFile substr( textline( .line), startcol, endcol - startcol + 1) endif