256 lines
6.7 KiB
C
256 lines
6.7 KiB
C
|
/*** mhlook - Help Look-Up code.
|
||
|
*
|
||
|
* Copyright <C> 1988, Microsoft Corporation
|
||
|
*
|
||
|
* This module contains routines dealing with searching for and (hopefully)
|
||
|
* finding help information
|
||
|
*
|
||
|
* Revision History (most recent first):
|
||
|
*
|
||
|
* 30-Mar-1989 ln pass popup flag around correctly.
|
||
|
* [] 12-Mar-1989 LN Split off of mhdisp.c
|
||
|
*
|
||
|
*************************************************************************/
|
||
|
#include <string.h> /* string functions */
|
||
|
|
||
|
#include "mh.h" /* help extension include file */
|
||
|
|
||
|
|
||
|
/*** fHelpCmd - Display topic text or execute command.
|
||
|
*
|
||
|
* Input:
|
||
|
* szCur = context string
|
||
|
* fStay = TRUE => keep focus in current window, else move focus to
|
||
|
* newly opened help window.
|
||
|
* fWantPopUp = TRUE => display as popup window. (Ignored in non-CW)
|
||
|
*
|
||
|
* Exit:
|
||
|
* returns TRUE on success.
|
||
|
*
|
||
|
*************************************************************************/
|
||
|
flagType pascal near fHelpCmd (
|
||
|
char *szCur,
|
||
|
flagType fStay,
|
||
|
flagType fWantPopUp
|
||
|
) {
|
||
|
|
||
|
int i; /* index while checking for helpfiles*/
|
||
|
nc ncCur = {0,0}; /* nc found */
|
||
|
|
||
|
|
||
|
//
|
||
|
// If a command to display a context (!C), just remove the command
|
||
|
//
|
||
|
if (*(ushort UNALIGNED *)szCur == 0x4321) {
|
||
|
szCur += 2;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If the command starts with an exclamation point, then go execute it.
|
||
|
//
|
||
|
if (*szCur == '!') {
|
||
|
return fContextCommand (szCur+1);
|
||
|
}
|
||
|
|
||
|
stat(szCur);
|
||
|
|
||
|
debmsg ("Searching:");
|
||
|
|
||
|
//
|
||
|
// search algorithm:
|
||
|
// 1) if help is not up, or we're looking for a different string than the
|
||
|
// last string we found, or it's a local context, try the same help file
|
||
|
// as the last look-up, if there was a last lookup.
|
||
|
// 2) If that fails, and it's not a local context, and we're not to present
|
||
|
// a list, then look in the help file(s) that are associated with the
|
||
|
// current file extension.
|
||
|
// 3) If that fails, and it's not a local context, then search all the help
|
||
|
// files.
|
||
|
// 4) If THAT fails, then check to see if there are any help files open
|
||
|
// at all, and return an appropriate error message on that.
|
||
|
//
|
||
|
if (ncInitLast.mh && ncInitLast.cn && (strcmp (szCur, szLastFound) || !(*szCur))) {
|
||
|
ncCur = ncSearch (szCur, NULL, ncInitLast, FALSE, FALSE);
|
||
|
}
|
||
|
|
||
|
if (!ncCur.mh && !ncCur.cn && *szCur && fnExtCur && !fList) {
|
||
|
nc ncTmp = {0,0};
|
||
|
ncCur = ncSearch (szCur, fnExtCur, ncTmp, FALSE, FALSE);
|
||
|
}
|
||
|
|
||
|
if (!ncCur.mh && !ncCur.cn && *szCur) {
|
||
|
nc ncTmp = {0,0};
|
||
|
ncCur = ncSearch (szCur, NULL, ncTmp, FALSE, fList);
|
||
|
}
|
||
|
|
||
|
if (!ncCur.mh && !ncCur.cn) {
|
||
|
for (i=MAXFILES-1; i; i--) {
|
||
|
if ((files[i].ncInit.mh || files[i].ncInit.cn)) {
|
||
|
return errstat ("Help on topic not found:",szCur);
|
||
|
}
|
||
|
}
|
||
|
return errstat ("No Open Help Files", NULL);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save this as the last context string actually found
|
||
|
//
|
||
|
xrefCopy (szLastFound, szCur);
|
||
|
|
||
|
debend (TRUE);
|
||
|
return fDisplayNc ( ncCur /* nc to display */
|
||
|
, TRUE /* add to backtrace list */
|
||
|
, fStay /* keep focus in current win? */
|
||
|
, fWantPopUp); /* as a pop-up? */
|
||
|
|
||
|
}
|
||
|
|
||
|
/*** fContextCommand - execute context command
|
||
|
*
|
||
|
* Input:
|
||
|
* szCur = pointer to context command
|
||
|
*
|
||
|
* Output:
|
||
|
* Returns TRUE if it was executed
|
||
|
*
|
||
|
*************************************************************************/
|
||
|
flagType pascal near fContextCommand (
|
||
|
char *szCur
|
||
|
) {
|
||
|
switch (*szCur++) {
|
||
|
|
||
|
case ' ': /* exeute DOS command */
|
||
|
case '!': /* exeute DOS command */
|
||
|
strcpy(buf,"arg \"");
|
||
|
strcat(buf,szCur);
|
||
|
strcat(buf,"\" shell");
|
||
|
fExecute(buf); /* execute as shell cmd */
|
||
|
break;
|
||
|
|
||
|
case 'm': /* execute editor macro */
|
||
|
fExecute(szCur);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
Display ();
|
||
|
return TRUE;
|
||
|
|
||
|
/* end fContextCommand */}
|
||
|
|
||
|
/** ncSearch - find help on context string
|
||
|
*
|
||
|
* search all the currently active help files for help on a particular
|
||
|
* topic. If desired, restricts the search to those files which are
|
||
|
* associated with a particular extension.
|
||
|
*
|
||
|
* Entry:
|
||
|
* pText = text to get help on
|
||
|
* pExt = If non-null, the extension to restrict the search to.
|
||
|
* ncInit = if non-null, ncInit of the only help file to look in
|
||
|
* fAgain = If non-null, skip helpfiles until ncInit found, then
|
||
|
* pick up the search.
|
||
|
* fList = if true, present a list box of the posibilities.
|
||
|
*
|
||
|
* Exit:
|
||
|
* returns nc found, or NULL
|
||
|
*
|
||
|
*************************************************************************/
|
||
|
nc pascal near ncSearch (
|
||
|
uchar far *pText,
|
||
|
uchar far *pExt,
|
||
|
nc ncInit,
|
||
|
flagType fAgain,
|
||
|
flagType fList
|
||
|
) {
|
||
|
int iHelp; /* index into helpfile table */
|
||
|
int j;
|
||
|
nc ncRet = {0,0}; /* nc found */
|
||
|
|
||
|
UNREFERENCED_PARAMETER( fList );
|
||
|
|
||
|
debmsg (" [");
|
||
|
debmsg (pText);
|
||
|
debmsg ("]:");
|
||
|
/*
|
||
|
* If this is just a single search (ncInit specified, and not a search
|
||
|
* "again"), then JUST look in the single file.
|
||
|
*/
|
||
|
if ((ncInit.mh || ncInit.cn) && !fAgain)
|
||
|
ncRet = HelpNc(pText,ncInit);
|
||
|
/*
|
||
|
* If fList is specified, then search ALL the databases for ALL ocurrances
|
||
|
* of the string, and make a list of the nc's we find.
|
||
|
*/
|
||
|
#if defined(PWB)
|
||
|
else if (fList) {
|
||
|
iHelp = ifileCur;
|
||
|
cList = 0;
|
||
|
do {
|
||
|
if (files[iHelp].ncInit) {
|
||
|
ncRet = files[iHelp].ncInit;
|
||
|
while ( (cList < CLISTMAX)
|
||
|
&& (rgncList[cList] = HelpNc(pText,ncRet))) {
|
||
|
ncRet = rgncList[cList++];
|
||
|
ncRet.cn++;
|
||
|
}
|
||
|
}
|
||
|
iHelp += iHelp ? -1 : MAXFILES-1;
|
||
|
}
|
||
|
while ((iHelp != ifileCur) && (cList < CLISTMAX));
|
||
|
|
||
|
if (cList == 0) {
|
||
|
ncRet.mh = ncRet.cn = 0;
|
||
|
return ncRet;
|
||
|
}
|
||
|
if (cList == 1)
|
||
|
return rgncList[0];
|
||
|
return ncChoose(pText);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
else {
|
||
|
iHelp = ifileCur; /* start with current file */
|
||
|
do {
|
||
|
if ((files[iHelp].ncInit.mh) &&
|
||
|
(files[iHelp].ncInit.cn)) { /* if helpfile open */
|
||
|
if (pExt) { /* if an extension was specified*/
|
||
|
for (j=0; j<MAXEXT; j++) { /* for all listed defaults */
|
||
|
if (fAgain) {
|
||
|
if ((ncInit.mh == files[iHelp].ncInit.mh) &&
|
||
|
(ncInit.cn == files[iHelp].ncInit.cn)) {
|
||
|
fAgain = FALSE;
|
||
|
}
|
||
|
}
|
||
|
else if (strcmp(files[iHelp].exts[j],pExt) == 0) {
|
||
|
debmsg (":");
|
||
|
ncRet = HelpNc(pText,files[iHelp].ncInit);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else { /* no extension specified */
|
||
|
if (fAgain && ((ncInit.mh == files[iHelp].ncInit.mh) &&
|
||
|
(ncInit.cn == files[iHelp].ncInit.cn)))
|
||
|
fAgain = FALSE;
|
||
|
else {
|
||
|
ncRet = HelpNc(pText,files[iHelp].ncInit);
|
||
|
debmsg (":");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (ncRet.mh || ncRet.cn)
|
||
|
ncInitLastFile = files[iHelp].ncInit;
|
||
|
iHelp += iHelp ? -1 : MAXFILES-1;
|
||
|
}
|
||
|
while ((iHelp != ifileCur) && ((ncRet.mh == 0) && (ncRet.cn == 0)));
|
||
|
}
|
||
|
|
||
|
debmsg ((ncRet.mh && ncRet.cn) ? "Y" : "N");
|
||
|
|
||
|
return ncRet;
|
||
|
/* end ncSearch */}
|