windows-nt/Source/XPSP1/NT/sdktools/mep/extens/mhelp/mhutil.c

343 lines
8 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*** mhutil - utilities for the help extension for the Microsoft Editor
*
* Copyright <C> 1988, Microsoft Corporation
*
* Revision History (most recent first):
*
* 01-Dec-1988 ln Cleanup & dislog help
* 28-Sep-1988 ln Correct GrabWord return value
* 02-Sep-1988 ln Make all data inited. Add info in debug vers.
* [] 16-May-1988 Extracted from mehelp.c
*
*************************************************************************/
#include <string.h> /* string functions */
#include <malloc.h>
#include "mh.h" /* help extension include file */
/************************************************************************
**
** procArgs
**
** Purpose:
** decode arguments passed into extension into commonly used variables.
**
** Entry:
** pArg = pointer to arg structure, courtesy of Z
**
** Exit:
** returns pArg->argType. Global variables updated.
*/
int pascal near procArgs (pArg)
ARG far *pArg; /* argument data */
{
buf[0] = 0;
pArgWord = pArgText = 0;
rnArg.flFirst.col = rnArg.flLast.col = 0;
rnArg.flFirst.lin = rnArg.flLast.lin = 0;
cArg = 0;
opendefault ();
pFileCur = FileNameToHandle ("", ""); /* get current file handle */
fnCur[0] = 0;
GetEditorObject(RQ_FILE_NAME,0,fnCur); /* get filename */
fnExtCur = strchr (fnCur, '.'); /* and pointer to extension */
switch (pArg->argType) {
case NOARG: /* <function> only, no arg */
cArg = 0;
pArgText = NULL;
break;
case NULLARG: /* <arg><function> */
cArg = pArg->arg.nullarg.cArg; /* get <arg> count */
GrabWord (); /* get argtext and argword */
break;
case STREAMARG: /* <arg>line movement<function> */
cArg = pArg->arg.streamarg.cArg;/* get <arg> count */
rnArg.flFirst.col = pArg->arg.streamarg.xStart;
rnArg.flLast.col = pArg->arg.streamarg.xEnd;
rnArg.flFirst.lin = pArg->arg.streamarg.yStart;
if (GetLine(rnArg.flFirst.lin, buf, pFileCur) > rnArg.flFirst.col) {
pArgText = &buf[rnArg.flFirst.col]; /* point at word */
buf[rnArg.flLast.col] = 0; /* terminate string */
}
break;
case TEXTARG: /* <arg> text <function> */
cArg = pArg->arg.textarg.cArg; /* get <arg> count */
pArgText = pArg->arg.textarg.pText;
break;
}
return pArg->argType;
/* end procArgs */}
/************************************************************************
**
** GrabWord - Grab the word under the editor cursor
**
** Purpose:
** grabs the word underneath the cursor for context sensitive help look-up.
**
** Entry:
** none
**
** Returns:
** nothing. pArgWord points to word, if it was parsed.
*/
void pascal near GrabWord () {
pArgText = pArgWord = 0;
pFileCur = FileNameToHandle ("", ""); /* get current file handle */
GetTextCursor (&rnArg.flFirst.col, &rnArg.flFirst.lin);
if (GetLine(rnArg.flFirst.lin, buf, pFileCur)) { /* get line */
pArgText = &buf[rnArg.flFirst.col]; /* point at word */
while (!wordSepar((int)*pArgText))
pArgText++; /* search for end */
*pArgText = 0; /* and terminate */
pArgWord = pArgText = &buf[rnArg.flFirst.col]; /* point at word */
while ((pArgWord > &buf[0]) && !wordSepar ((int)*(pArgWord-1)))
pArgWord--;
}
/* end GrabWord */}
/*** appTitle - Append help file title to buffer
*
* Read in the title of a help file and append it to a buffer.
*
* Input:
* fpDest - far pointer to destination of string
* ncInit - Any nc of file to get title for
*
* Output:
* Returns
*
*************************************************************************/
void pascal near appTitle (
char far *pDest,
nc ncInit
) {
/*
** first, point to end of string to append to
*/
while (*pDest)
pDest++;
/*
** Start by getting the info on the file referenced, so that we can get the
** ncInit for that file.
*/
if (!HelpGetInfo (ncInit, &hInfoCur, sizeof(hInfoCur))) {
ncInit = NCINIT(&hInfoCur);
/*
** Find the context string, and read the topic. Then just read the first
** line into the destination
*/
ncInit = HelpNc ("h.title",ncInit);
if (ncInit.cn && (fReadNc(ncInit))) {
pDest += HelpGetLine (1, BUFLEN, pDest, pTopic);
*pDest = 0;
free (pTopic);
pTopic = NULL;
}
/*
** If no title was found, then just place the help file name there.
*/
else
strcpy (pDest, HFNAME(&hInfoCur));
}
/*
** If we couldn't even get the info, then punt...
*/
else
strcpy (pDest, "** unknown **");
/* end appTitle */}
/*** errstat - display error status message
*
* In non cw, just display the strings on the status line. In CW, bring up
* a message box.
*
* Input:
* sz1 = first error message line
* sz2 = second. May be NULL.
*
* Output:
* Returns FALSE
*************************************************************************/
flagType pascal near errstat (
char *sz1,
char *sz2
) {
#if defined(PWB)
DoMessageBox (sz1, sz2, NULL, MBOX_OK);
#else
buffer buf;
strcpy (buf, sz1);
if (sz2) {
strcat (buf, " ");
strcat (buf, sz2);
}
stat (buf);
#endif
return FALSE;
/* end errstat */}
/*** stat - display status line message
*
* Places extension name and message on the status line
*
* Entry:
* pszFcn - Pointer to string to be prepended.
*
* Exit:
* none
*
*************************************************************************/
void pascal near stat(pszFcn)
char *pszFcn; /* function name */
{
buffer buf; /* message buffer */
strcpy(buf,"mhelp: "); /* start with name */
if (strlen(pszFcn) > 72) {
pszFcn+= strlen(pszFcn) - 69;
strcat (buf, "...");
}
strcat(buf,pszFcn); /* append message */
DoMessage (buf); /* display */
/* end stat */}
#ifdef DEBUG
buffer debstring = {0};
extern int delay; /* message delay */
/*** debhex - output long in hex
*
* Display the value of a long in hex
*
* Input:
* lval = long value
*
* Output:
* Returns nothing
*
*************************************************************************/
void pascal near debhex (
long lval
) {
char lbuf[10];
_ultoa (lval, lbuf, 16);
debmsg (lbuf);
/* end debhex */}
/*** debmsg - piece together debug message
*
* Outputs a the cummulative message formed by successive calls.
*
* Input:
* psz = pointer to message part
*
* Output:
* Returns nothing
*************************************************************************/
void pascal near debmsg (
char far *psz
) {
_stat (strcat (debstring, psz ? psz : "<NULL>" ));
/* end debmsg */}
/*** debend - terminates message accumulation & pauses
*
* Terminates the message accumulation, displays the final message, and
* pauses, either for the pause time, or for a keystroke.
*
* Input:
* fWait = TRUE => wait for a keystroke
*
* Output:
* Returns nothing
*
*************************************************************************/
void pascal near debend (
flagType fWait
) {
if (fWait && delay) {
#if defined(PWB)
DoMessageBox (debstring, NULL, NULL, MBOX_OK);
#else
_stat (strcat (debstring, " Press a key..."));
ReadChar ();
#endif
}
#ifdef OS2
else if (delay)
DosSleep ((long)delay);
#endif
debstring[0] = 0;
/* end debend */}
/*** _mhassertexit - display assertion message and exit
*
* Input:
* pszExp - expression which failed
* pszFn - filename containing failure
* line - line number failed at
*
* Output:
* Doesn't return
*
*************************************************************************/
void pascal near _mhassertexit (
char *pszExp,
char *pszFn,
int line
) {
char lbuf[10];
_ultoa (line, lbuf, 10);
strcpy (buf, pszExp);
strcat (buf, " in ");
strcat (buf, pszFn);
strcat (buf, ": line ");
strcat (buf, lbuf);
errstat ("Help assertion failed", buf);
fExecute ("exit");
/* end _mhassertexit */}
#endif
flagType pascal wordSepar (int i) {
CHAR c = (CHAR)i;
if (((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
((c >= '0') && (c <= '9')) ||
( c == '_' ) ||
( c == '$' ) ) {
return FALSE;
} else {
return TRUE;
}
}
char far * pascal near xrefCopy (char far *dst, char far *src)
{
if ( *src ) {
strcpy( dst, src );
} else {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
}
return dst;
}