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.

344 lines
9.3 KiB

  1. /*************************************************************************
  2. **
  3. ** mhfile - file manipulation for the help extension for the Microsoft Editor
  4. **
  5. ** Copyright <C> 1988, Microsoft Corporation
  6. **
  7. ** Revision History:
  8. **
  9. ** 09-Dec-1988 ln Changes for Dialog help
  10. ** 02-Sep-1988 ln Make all data inited. Add info in debug vers.
  11. ** 15-Aug-1988 ln New HelpOpen return values
  12. ** [] 16-May-1988 Created, extracted from mehelp.c
  13. */
  14. #include <stdlib.h> /* ultoa */
  15. #include <string.h> /* string functions */
  16. #define _INCLUDE_TOOLS_
  17. #include "mh.h" /* help extension include file */
  18. /*************************************************************************
  19. **
  20. ** static data
  21. */
  22. static uchar envvar[]= "HELPFILES"; /* help file list env var */
  23. static flagType fOpen = FALSE;/* file open attempted */
  24. static uchar szfiles[BUFLEN] = ""; /* string for open help files */
  25. /************************************************************************
  26. **
  27. ** closehelp - close an open help file
  28. **
  29. ** Purpose:
  30. **
  31. ** Entry:
  32. ** pfn = pointer to filename.
  33. **
  34. ** Exit:
  35. **
  36. ** Exceptions:
  37. **
  38. */
  39. flagType pascal near closehelp(pfn)
  40. char *pfn;
  41. {
  42. int iHelpNew; /* index into file table */
  43. nc ncNew; /* new file's initial nc */
  44. /*
  45. ** attempt to open the file first, to get the initial context. If we cannot
  46. ** open the file, we stop here, since it wasn't open to begin with.
  47. */
  48. ncNew = HelpOpen(pfn);
  49. if (ISERROR(ncNew)) {
  50. /*
  51. ** Scan the current file list for the same handle. If the handle returned
  52. ** by HelpOpen above is already in the table, then the file was already open,
  53. ** and we zero out that table entry.
  54. */
  55. for (iHelpNew=MAXFILES-1; iHelpNew>=0; iHelpNew--) {
  56. if ((files[iHelpNew].ncInit.mh == ncNew.mh) &&
  57. (files[iHelpNew].ncInit.cn == ncNew.cn)) { /* if already open */
  58. files[iHelpNew].ncInit.mh = 0;
  59. files[iHelpNew].ncInit.cn = 0; /* remove from list */
  60. }
  61. }
  62. /*
  63. ** We destory all traces of back-trace and currency, since these contexts may
  64. ** reference the now closed helpfile, close it and return.
  65. */
  66. HelpClose(ncNew); /* close the file */
  67. while (HelpNcBack().cn); /* destroy back-trace */
  68. ncCur.mh = ncLast.mh = 0; /* and clear currancy */
  69. ncCur.cn = ncLast.cn = 0;
  70. }
  71. return TRUE; /* and we're done */
  72. /* end closehelp */}
  73. /************************************************************************
  74. **
  75. ** openhelp - open a help file & add to list of files
  76. **
  77. ** Purpose:
  78. **
  79. ** Entry:
  80. ** pfn = pointer to filename.
  81. **
  82. ** Exit:
  83. **
  84. ** Exceptions:
  85. **
  86. */
  87. void pascal near openhelp(char *pfn, struct findType *dummy1, void *ReturnValue)
  88. {
  89. int iHelpNew; /* index into file table */
  90. nc ncNew; /* new file's initial nc */
  91. char *pExt = 0; /* pointer to extension string */
  92. flagType RetVal;
  93. buffer pfnbuf;
  94. assert (pfn);
  95. fOpen = TRUE; /* we HAVE openned something */
  96. /*
  97. ** preserve any prepended extensions.
  98. */
  99. if (*pfn == '.') {
  100. pExt = pfn;
  101. while (*pfn && (*pfn != ':'))
  102. pfn++; /* point to actual filename */
  103. if (*pfn) *pfn++ = 0; /* terminate ext string */
  104. }
  105. /*
  106. ** attempt to open the file. If we cannot open the file, we stop here.
  107. */
  108. ncNew = HelpOpen(pfn);
  109. if (ISERROR(ncNew)) {
  110. strcpy (pfnbuf, pfn);
  111. strcpy(buf,"Can't open [");
  112. strcat(buf,pfnbuf);
  113. switch (ncNew.cn) {
  114. case HELPERR_FNF:
  115. pfn = "]: Not Found";
  116. break;
  117. case HELPERR_READ:
  118. pfn = "]: Read Error";
  119. break;
  120. case HELPERR_LIMIT:
  121. pfn = "]: Too many help files";
  122. break;
  123. case HELPERR_BADAPPEND:
  124. pfn = "]: Bad appended help file";
  125. break;
  126. case HELPERR_NOTHELP:
  127. pfn = "]: Not a help file";
  128. break;
  129. case HELPERR_BADVERS:
  130. pfn = "]: Bad help file version";
  131. break;
  132. case HELPERR_MEMORY:
  133. pfn = "]: Out of Memory";
  134. break;
  135. default:
  136. pfn = "]: Unkown error 0x ";
  137. _ultoa (ncNew.cn, &pfn[18], 16);
  138. }
  139. strcat(buf,pfn);
  140. errstat(buf,NULL);
  141. debmsg (buf);
  142. debend (TRUE);
  143. if ( ReturnValue ) {
  144. *((flagType *)ReturnValue) = FALSE;
  145. }
  146. return;
  147. }
  148. /*
  149. ** Scan the current file list for the same handle. If the handle returned
  150. ** by HelpOpen above is already in the table, then the file was already open,
  151. ** and we don't need to add it.
  152. */
  153. for (iHelpNew=MAXFILES-1; iHelpNew>=0; iHelpNew--)
  154. if ((files[iHelpNew].ncInit.mh == ncNew.mh) &&
  155. (files[iHelpNew].ncInit.cn == ncNew.cn)) { /* if already open */
  156. ifileCur = iHelpNew; /* set currency */
  157. procExt(iHelpNew,pExt); /* process extensions */
  158. if ( ReturnValue ) {
  159. *((flagType *)ReturnValue) = TRUE;
  160. }
  161. return;
  162. }
  163. /*
  164. ** Scan the file list again for an unused slot. Once found, save the initial
  165. ** context for that help file, and finally set it up as the first help file
  166. ** to be searched.
  167. */
  168. for (iHelpNew=MAXFILES-1; iHelpNew>=0; iHelpNew--)
  169. if ((files[iHelpNew].ncInit.mh == 0) &&
  170. (files[iHelpNew].ncInit.cn == 0)) { /* if available slot */
  171. files[iHelpNew].ncInit = ncNew; /* save initial context */
  172. ifileCur = iHelpNew; /* and set currency */
  173. procExt(iHelpNew,pExt); /* process extensions */
  174. if ( ReturnValue ) {
  175. *((flagType *)ReturnValue) = TRUE;
  176. }
  177. return;
  178. }
  179. /*
  180. ** If we got here, it's because the loop above didn't find any open slots in
  181. ** our file table. Complain, close and exit.
  182. */
  183. errstat ("Too many help files",NULL);
  184. HelpClose(ncNew);
  185. if ( ReturnValue ) {
  186. *((flagType *)ReturnValue) = FALSE;
  187. }
  188. dummy1;
  189. /* end openhelp */}
  190. /************************************************************************
  191. **
  192. ** procExt - process default extensions for file
  193. **
  194. ** Purpose:
  195. ** fill in extension table for an openned file
  196. **
  197. ** Entry:
  198. ** ifileCur = filetable index
  199. ** pExt = pointer to extension string
  200. **
  201. ** Exit:
  202. ** filetable entry updated
  203. */
  204. void pascal near procExt(ifileCur, pExt)
  205. int ifileCur;
  206. char *pExt;
  207. {
  208. int i,j;
  209. char *pExtDst; /* place to put it */
  210. if (pExt) { /* if there is one */
  211. pExt++; /* skip leading period */
  212. for (i=0; i<MAXEXT; i++) { /* for all possible ext slots */
  213. pExtDst = files[ifileCur].exts[i]; /* point to destination */
  214. j = 0;
  215. while (*pExt && (*pExt != '.') && (j++ < 3))
  216. *pExtDst++ = *pExt++;
  217. if (*pExt == '.')
  218. pExt++; /* skip period separator */
  219. *pExtDst = 0; /* always terminate */
  220. }
  221. }
  222. /* end procExt */}
  223. /*** opendefault - if no files open yet, open the default set
  224. *
  225. * We delay this operation, in the case that the user will have a helpfiles:
  226. * switch which will locate the helpfiles explicitly. In those cases this
  227. * routine does nothing, and we don;t waste time up front openning files
  228. * only to close them later.
  229. *
  230. * On the other hand, if he has not set a helpfiles switch by his first
  231. * request for help, we want to try either the environment variable, if it
  232. * exists, or when all else fails, default to mep.hlp.
  233. *
  234. * Input:
  235. * none
  236. *
  237. * Output:
  238. * Returns nothing. Helpfiles open, we hope.
  239. *
  240. *************************************************************************/
  241. void pascal near opendefault ( void ) {
  242. char *tmp;
  243. if (!fOpen) {
  244. if (getenv (envvar)) {
  245. // prochelpfiles (getenv (envvar)); /* Process user-spec'd files */
  246. prochelpfiles (tmp=getenvOem (envvar)); /* Process user-spec'd files */
  247. free( tmp );
  248. }
  249. else
  250. openhelp ("mep.hlp", NULL, NULL); /* else use default */
  251. }
  252. /* end opendefault */}
  253. /************************************************************************
  254. **
  255. ** prochelpfiles - process helpfiles: switch
  256. **
  257. ** Purpose:
  258. ** called by the editor each time the helpfiles switch is changed.
  259. **
  260. ** Entry:
  261. ** pszfiles = pointer to new switch value
  262. **
  263. ** Exit:
  264. **
  265. ** Exceptions:
  266. **
  267. */
  268. flagType pascal EXTERNAL prochelpfiles (pszfiles)
  269. char *pszfiles;
  270. {
  271. char cTerm; /* terminating character */
  272. int iHelp;
  273. char *pEnd; /* pointer to end of current fn */
  274. if ( !ExtensionLoaded ) {
  275. return FALSE;
  276. }
  277. strncpy(szfiles,pszfiles,BUFLEN); /* save specified string */
  278. /*
  279. ** begin by closing all open help files and loosing curency
  280. */
  281. for (iHelp=MAXFILES-1; iHelp>=0; iHelp--)
  282. if ((files[iHelp].ncInit.mh) &&
  283. (files[iHelp].ncInit.cn)) { /* if open file */
  284. HelpClose(files[iHelp].ncInit); /* close it */
  285. files[iHelp].ncInit.mh = 0;
  286. files[iHelp].ncInit.cn = 0;
  287. }
  288. while (HelpNcBack().cn); /* destroy back-trace */
  289. ncCur.mh = ncLast.mh = 0; /* and clear currancy */
  290. ncCur.cn = ncLast.cn = 0;
  291. while (*pszfiles) { /* while files to proc */
  292. if (*pszfiles == ' ') /* strip leading spaces */
  293. pszfiles++;
  294. else {
  295. pEnd = pszfiles;
  296. while (*pEnd && (*pEnd != ' ') && (*pEnd != ';')) pEnd++; /* move to end of fn */
  297. cTerm = *pEnd; /* save terminator */
  298. *pEnd = 0;
  299. forfile(pszfiles, A_ALL, openhelp, NULL);
  300. #if rjsa
  301. // Since pszfiles may contain wild characters, we use
  302. // ffirst/fnext to open all of them
  303. //
  304. rc = ffirst(pszfiles, A_ALL, &buffer);
  305. while (!rc) {
  306. buffer.fbuf.achName[buffer.fbuf.cchName] = '\0';
  307. openhelp(buffer.fbuf.achName, NULL, NULL);
  308. rc = fnext(&buffer);
  309. }
  310. #endif
  311. pszfiles = pEnd; /* point to end */
  312. if (cTerm) pszfiles++; /* if more, move to next */
  313. }
  314. }
  315. ifileCur = MAXFILES-1;
  316. return TRUE;
  317. /* end prochelpfiles */}