windows-nt/Source/XPSP1/NT/sdktools/mep/extens/mhelp/mhlook.c
2020-09-26 16:20:57 +08:00

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 */}