Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

342 lines
8.0 KiB

  1. /*** mhutil - utilities for the help extension for the Microsoft Editor
  2. *
  3. * Copyright <C> 1988, Microsoft Corporation
  4. *
  5. * Revision History (most recent first):
  6. *
  7. * 01-Dec-1988 ln Cleanup & dislog help
  8. * 28-Sep-1988 ln Correct GrabWord return value
  9. * 02-Sep-1988 ln Make all data inited. Add info in debug vers.
  10. * [] 16-May-1988 Extracted from mehelp.c
  11. *
  12. *************************************************************************/
  13. #include <string.h> /* string functions */
  14. #include <malloc.h>
  15. #include "mh.h" /* help extension include file */
  16. /************************************************************************
  17. **
  18. ** procArgs
  19. **
  20. ** Purpose:
  21. ** decode arguments passed into extension into commonly used variables.
  22. **
  23. ** Entry:
  24. ** pArg = pointer to arg structure, courtesy of Z
  25. **
  26. ** Exit:
  27. ** returns pArg->argType. Global variables updated.
  28. */
  29. int pascal near procArgs (pArg)
  30. ARG far *pArg; /* argument data */
  31. {
  32. buf[0] = 0;
  33. pArgWord = pArgText = 0;
  34. rnArg.flFirst.col = rnArg.flLast.col = 0;
  35. rnArg.flFirst.lin = rnArg.flLast.lin = 0;
  36. cArg = 0;
  37. opendefault ();
  38. pFileCur = FileNameToHandle ("", ""); /* get current file handle */
  39. fnCur[0] = 0;
  40. GetEditorObject(RQ_FILE_NAME,0,fnCur); /* get filename */
  41. fnExtCur = strchr (fnCur, '.'); /* and pointer to extension */
  42. switch (pArg->argType) {
  43. case NOARG: /* <function> only, no arg */
  44. cArg = 0;
  45. pArgText = NULL;
  46. break;
  47. case NULLARG: /* <arg><function> */
  48. cArg = pArg->arg.nullarg.cArg; /* get <arg> count */
  49. GrabWord (); /* get argtext and argword */
  50. break;
  51. case STREAMARG: /* <arg>line movement<function> */
  52. cArg = pArg->arg.streamarg.cArg;/* get <arg> count */
  53. rnArg.flFirst.col = pArg->arg.streamarg.xStart;
  54. rnArg.flLast.col = pArg->arg.streamarg.xEnd;
  55. rnArg.flFirst.lin = pArg->arg.streamarg.yStart;
  56. if (GetLine(rnArg.flFirst.lin, buf, pFileCur) > rnArg.flFirst.col) {
  57. pArgText = &buf[rnArg.flFirst.col]; /* point at word */
  58. buf[rnArg.flLast.col] = 0; /* terminate string */
  59. }
  60. break;
  61. case TEXTARG: /* <arg> text <function> */
  62. cArg = pArg->arg.textarg.cArg; /* get <arg> count */
  63. pArgText = pArg->arg.textarg.pText;
  64. break;
  65. }
  66. return pArg->argType;
  67. /* end procArgs */}
  68. /************************************************************************
  69. **
  70. ** GrabWord - Grab the word under the editor cursor
  71. **
  72. ** Purpose:
  73. ** grabs the word underneath the cursor for context sensitive help look-up.
  74. **
  75. ** Entry:
  76. ** none
  77. **
  78. ** Returns:
  79. ** nothing. pArgWord points to word, if it was parsed.
  80. */
  81. void pascal near GrabWord () {
  82. pArgText = pArgWord = 0;
  83. pFileCur = FileNameToHandle ("", ""); /* get current file handle */
  84. GetTextCursor (&rnArg.flFirst.col, &rnArg.flFirst.lin);
  85. if (GetLine(rnArg.flFirst.lin, buf, pFileCur)) { /* get line */
  86. pArgText = &buf[rnArg.flFirst.col]; /* point at word */
  87. while (!wordSepar((int)*pArgText))
  88. pArgText++; /* search for end */
  89. *pArgText = 0; /* and terminate */
  90. pArgWord = pArgText = &buf[rnArg.flFirst.col]; /* point at word */
  91. while ((pArgWord > &buf[0]) && !wordSepar ((int)*(pArgWord-1)))
  92. pArgWord--;
  93. }
  94. /* end GrabWord */}
  95. /*** appTitle - Append help file title to buffer
  96. *
  97. * Read in the title of a help file and append it to a buffer.
  98. *
  99. * Input:
  100. * fpDest - far pointer to destination of string
  101. * ncInit - Any nc of file to get title for
  102. *
  103. * Output:
  104. * Returns
  105. *
  106. *************************************************************************/
  107. void pascal near appTitle (
  108. char far *pDest,
  109. nc ncInit
  110. ) {
  111. /*
  112. ** first, point to end of string to append to
  113. */
  114. while (*pDest)
  115. pDest++;
  116. /*
  117. ** Start by getting the info on the file referenced, so that we can get the
  118. ** ncInit for that file.
  119. */
  120. if (!HelpGetInfo (ncInit, &hInfoCur, sizeof(hInfoCur))) {
  121. ncInit = NCINIT(&hInfoCur);
  122. /*
  123. ** Find the context string, and read the topic. Then just read the first
  124. ** line into the destination
  125. */
  126. ncInit = HelpNc ("h.title",ncInit);
  127. if (ncInit.cn && (fReadNc(ncInit))) {
  128. pDest += HelpGetLine (1, BUFLEN, pDest, pTopic);
  129. *pDest = 0;
  130. free (pTopic);
  131. pTopic = NULL;
  132. }
  133. /*
  134. ** If no title was found, then just place the help file name there.
  135. */
  136. else
  137. strcpy (pDest, HFNAME(&hInfoCur));
  138. }
  139. /*
  140. ** If we couldn't even get the info, then punt...
  141. */
  142. else
  143. strcpy (pDest, "** unknown **");
  144. /* end appTitle */}
  145. /*** errstat - display error status message
  146. *
  147. * In non cw, just display the strings on the status line. In CW, bring up
  148. * a message box.
  149. *
  150. * Input:
  151. * sz1 = first error message line
  152. * sz2 = second. May be NULL.
  153. *
  154. * Output:
  155. * Returns FALSE
  156. *************************************************************************/
  157. flagType pascal near errstat (
  158. char *sz1,
  159. char *sz2
  160. ) {
  161. #if defined(PWB)
  162. DoMessageBox (sz1, sz2, NULL, MBOX_OK);
  163. #else
  164. buffer buf;
  165. strcpy (buf, sz1);
  166. if (sz2) {
  167. strcat (buf, " ");
  168. strcat (buf, sz2);
  169. }
  170. stat (buf);
  171. #endif
  172. return FALSE;
  173. /* end errstat */}
  174. /*** stat - display status line message
  175. *
  176. * Places extension name and message on the status line
  177. *
  178. * Entry:
  179. * pszFcn - Pointer to string to be prepended.
  180. *
  181. * Exit:
  182. * none
  183. *
  184. *************************************************************************/
  185. void pascal near stat(pszFcn)
  186. char *pszFcn; /* function name */
  187. {
  188. buffer buf; /* message buffer */
  189. strcpy(buf,"mhelp: "); /* start with name */
  190. if (strlen(pszFcn) > 72) {
  191. pszFcn+= strlen(pszFcn) - 69;
  192. strcat (buf, "...");
  193. }
  194. strcat(buf,pszFcn); /* append message */
  195. DoMessage (buf); /* display */
  196. /* end stat */}
  197. #ifdef DEBUG
  198. buffer debstring = {0};
  199. extern int delay; /* message delay */
  200. /*** debhex - output long in hex
  201. *
  202. * Display the value of a long in hex
  203. *
  204. * Input:
  205. * lval = long value
  206. *
  207. * Output:
  208. * Returns nothing
  209. *
  210. *************************************************************************/
  211. void pascal near debhex (
  212. long lval
  213. ) {
  214. char lbuf[10];
  215. _ultoa (lval, lbuf, 16);
  216. debmsg (lbuf);
  217. /* end debhex */}
  218. /*** debmsg - piece together debug message
  219. *
  220. * Outputs a the cummulative message formed by successive calls.
  221. *
  222. * Input:
  223. * psz = pointer to message part
  224. *
  225. * Output:
  226. * Returns nothing
  227. *************************************************************************/
  228. void pascal near debmsg (
  229. char far *psz
  230. ) {
  231. _stat (strcat (debstring, psz ? psz : "<NULL>" ));
  232. /* end debmsg */}
  233. /*** debend - terminates message accumulation & pauses
  234. *
  235. * Terminates the message accumulation, displays the final message, and
  236. * pauses, either for the pause time, or for a keystroke.
  237. *
  238. * Input:
  239. * fWait = TRUE => wait for a keystroke
  240. *
  241. * Output:
  242. * Returns nothing
  243. *
  244. *************************************************************************/
  245. void pascal near debend (
  246. flagType fWait
  247. ) {
  248. if (fWait && delay) {
  249. #if defined(PWB)
  250. DoMessageBox (debstring, NULL, NULL, MBOX_OK);
  251. #else
  252. _stat (strcat (debstring, " Press a key..."));
  253. ReadChar ();
  254. #endif
  255. }
  256. #ifdef OS2
  257. else if (delay)
  258. DosSleep ((long)delay);
  259. #endif
  260. debstring[0] = 0;
  261. /* end debend */}
  262. /*** _mhassertexit - display assertion message and exit
  263. *
  264. * Input:
  265. * pszExp - expression which failed
  266. * pszFn - filename containing failure
  267. * line - line number failed at
  268. *
  269. * Output:
  270. * Doesn't return
  271. *
  272. *************************************************************************/
  273. void pascal near _mhassertexit (
  274. char *pszExp,
  275. char *pszFn,
  276. int line
  277. ) {
  278. char lbuf[10];
  279. _ultoa (line, lbuf, 10);
  280. strcpy (buf, pszExp);
  281. strcat (buf, " in ");
  282. strcat (buf, pszFn);
  283. strcat (buf, ": line ");
  284. strcat (buf, lbuf);
  285. errstat ("Help assertion failed", buf);
  286. fExecute ("exit");
  287. /* end _mhassertexit */}
  288. #endif
  289. flagType pascal wordSepar (int i) {
  290. CHAR c = (CHAR)i;
  291. if (((c >= 'a') && (c <= 'z')) ||
  292. ((c >= 'A') && (c <= 'Z')) ||
  293. ((c >= '0') && (c <= '9')) ||
  294. ( c == '_' ) ||
  295. ( c == '$' ) ) {
  296. return FALSE;
  297. } else {
  298. return TRUE;
  299. }
  300. }
  301. char far * pascal near xrefCopy (char far *dst, char far *src)
  302. {
  303. if ( *src ) {
  304. strcpy( dst, src );
  305. } else {
  306. dst[0] = src[0];
  307. dst[1] = src[1];
  308. dst[2] = src[2];
  309. }
  310. return dst;
  311. }