Windows NT 4.0 source code leak
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.

322 lines
8.5 KiB

4 years ago
  1. /*****************************************************************************
  2. * *
  3. * NEXTLIST.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1990. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * This module processes nextlist footnotes, putting the information into *
  12. * a temporary file. After parsing all the RTF files, it then processes *
  13. * this file. Eventually it will backpatch the |TOPIC file with the correct *
  14. * browse topic addresses; for now, it just creates the |TOMAP with the *
  15. * correct addresses. *
  16. * *
  17. *****************************************************************************/
  18. /*****************************************************************************
  19. *
  20. * Revision History: Created 00/00/00 by LarryPo
  21. *
  22. * 11/21/90 JohnSc RcSortFm() replaces RcMegasortFm()
  23. * 12/02/90 JohnSc do case insensitive sort of browse tags
  24. * 12/14/90 JohnSc FErrorRc(rc) -> FErrorHce(HceFromRc(rc))
  25. * 25-Feb-1991 JohnSc bug 948: unsafe calls to HceFromRc()
  26. *
  27. *****************************************************************************/
  28. #include "stdafx.h"
  29. #pragma hdrstop
  30. #ifdef _DEBUG
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. /*****************************************************************************
  35. * *
  36. * Defines *
  37. * *
  38. *****************************************************************************/
  39. #define chMinorDelimiter ((char) ':')
  40. #define szMajorDefault "R"
  41. /* This is the offset from the start of a topic FC to the previous
  42. * and next fields in the packed MTOP structure.
  43. * Note that the MOBJ structure contains a WORD parameter at the end
  44. * that we currently don't write out in topic objects.
  45. */
  46. #define cbOffsetToPrevInMTOP &(((QMTOP)0)->prev)
  47. #define cbOffsetToNextInMTOP &(((QMTOP)0)->next)
  48. /*****************************************************************************
  49. * *
  50. * Typedefs *
  51. * *
  52. *****************************************************************************/
  53. // Next List Info.
  54. typedef struct {
  55. FCL fclTopic; // backpatch location of MTOP struct.
  56. WORD iBitdex; // magic zeck-compression code-bits bitdex for that fcl.
  57. ADDR addr; // addr to backpatch.
  58. BOOL fNewSeq; // TRUE if this NLI starts a new sequence.
  59. } NLI;
  60. /*****************************************************************************
  61. * *
  62. * Static Variables *
  63. * *
  64. *****************************************************************************/
  65. /*
  66. * This variable contains the number of entries that have been written
  67. * out to ptfBrowse.
  68. */
  69. static long cnliMac;
  70. /***************************************************************************
  71. FUNCTION: FProcNextlistSz
  72. PURPOSE: Processes a nextlist footnote string.
  73. PARAMETERS:
  74. szNextlist -- The nextlist footnote string
  75. idfcp
  76. perr
  77. RETURNS:
  78. COMMENTS:
  79. MODIFICATION DATES:
  80. 30-Jul-1993 [ralphw]
  81. ***************************************************************************/
  82. static int autoBrowse = 1;
  83. static const char txtAuto[] = "auto";
  84. BOOL STDCALL FProcNextlistSz(PSTR szNextlist, IDFCP idfcp, PERR perr)
  85. {
  86. PSTR pszMinor, pszMajor;
  87. static BOOL fCreateFailed = FALSE;
  88. char szBuf[10];
  89. // Check if no browse sequences to be made
  90. if (!ptblBrowse)
  91. ptblBrowse = new CTable;
  92. if (fBrowseDefined) {
  93. VReportError(HCERR_BROWSE_DEFINED, &errHpj);
  94. return FALSE;
  95. }
  96. pszMinor = StrChr(szNextlist, chMinorDelimiter, fDBCSSystem);
  97. if (pszMinor == NULL) {
  98. pszMajor = szMajorDefault;
  99. pszMinor = SzTrimSz(szNextlist);
  100. if (*pszMinor == '\0') {
  101. pszMinor = szBuf;
  102. _ltoa(autoBrowse++, szBuf, 10);
  103. }
  104. }
  105. else {
  106. *pszMinor = '\0';
  107. pszMinor = SzTrimSz(pszMinor + 1);
  108. if (*pszMinor == '\0' || _stricmp(pszMinor, txtAuto) == 0) {
  109. pszMinor = szBuf;
  110. _ltoa(autoBrowse++, szBuf, 10);
  111. }
  112. pszMajor = SzTrimSz(szNextlist);
  113. if (*pszMajor == '\0')
  114. pszMajor = szMajorDefault; // REVIEW: Warning needed ?
  115. }
  116. // Check for browse sequence defined too late
  117. if (fHasTopicFCP) {
  118. VReportError(HCERR_LATE_BROWSE, &errHpj);
  119. return FALSE;
  120. }
  121. fBrowseDefined = TRUE;
  122. FDelayExecutionBrowse(pszMajor, pszMinor, idfcp);
  123. cnliMac++;
  124. return TRUE;
  125. }
  126. /***************************************************************************
  127. *
  128. - Name FResolveNextlist
  129. -
  130. * Purpose
  131. * This function processes the file of browse sequences to do
  132. * what needs to be done to make browsing happen. Right now, that
  133. * is to write FCL's to the |TOMAP file. In the future, this
  134. * will consist of backpatching PA's into the |TOPIC file.
  135. *
  136. * Arguments
  137. *
  138. * Returns
  139. *
  140. * Globals
  141. * This function uses the static variable cnliMac, which contains
  142. * the number of entries in ptfBrowse.
  143. *
  144. * +++
  145. *
  146. * Notes
  147. *
  148. ***************************************************************************/
  149. static const int GRIND_INCREMENT = 100;
  150. BOOL STDCALL FResolveNextlist(HF hfTopic)
  151. {
  152. #ifdef _DEBUG
  153. int inli = 0;
  154. #endif
  155. PSTR szMajor, szMinor, pchFcl, pchAddr, pchBitdex;
  156. int cGrind = 0;
  157. //ADDR addr;
  158. NLI nliPrev, nliCur, nliNext;
  159. if (!ptblBrowse)
  160. return TRUE; // Nothing to be done
  161. // Check for no browse sequences:
  162. if (cnliMac == 0) {
  163. delete ptblBrowse;
  164. ptblBrowse = NULL;
  165. return TRUE;
  166. }
  167. SendStringToParent(IDS_RESOLVING_BROWSE);
  168. if (!hwndParent && hwndGrind)
  169. SetWindowText(hwndGrind, GetStringResource(IDS_RESOLVING_BROWSE));
  170. ptblBrowse->SetSorting(lcid, kwlcid.fsCompareI, kwlcid.fsCompare);
  171. ptblBrowse->SortTable();
  172. doGrind();
  173. /*
  174. * When reading in new strings, we need to check if the major string
  175. * matches the previous major string. To do this, the previous major
  176. * string is stored at szScratchBuf, and the current major string is read
  177. * in following that. The first previous major string is nil to always
  178. * make it different.
  179. */
  180. szScratchBuf[0] = '\0';
  181. szMajor = szScratchBuf + 1;
  182. nliCur.fclTopic = fclNil;
  183. ptblBrowse->SetPosition(1);
  184. while (ptblBrowse->GetString(szMajor)) {
  185. if (++cGrind >= GRIND_INCREMENT) {
  186. cGrind = 0;
  187. doGrind();
  188. }
  189. // Split input into different strings
  190. szMinor = StrChr(szMajor, chMinorDelimiter, fDBCSSystem);
  191. ASSERT(szMinor != NULL);
  192. *szMinor++ = '\0';
  193. /* NOTE: While we are guaranteed that the major sequence string will
  194. * not contain a delimiter character, we have no such guarantee for
  195. * the minor sequence string. To calculate pointers to the fcl
  196. * and addr fields, then, we need to backtrack from the end of
  197. * the string.
  198. *
  199. * Each field is eight characters wide, and they are separated
  200. * by ':' characters. The string will be terminated by a newline,
  201. * unless buffer overflow has occured.
  202. */
  203. pchAddr = StrChr(szMinor, '\n', fDBCSSystem);
  204. ASSERT(pchAddr != NULL);
  205. pchAddr -= 9;
  206. pchBitdex = pchAddr - 9;
  207. pchFcl = pchBitdex - 9;
  208. ASSERT(*pchAddr == ':' && *pchFcl == ':' && *pchBitdex == ':');
  209. *pchFcl++ = '\0';
  210. *pchBitdex++ = '\0';
  211. *pchAddr++ = '\0';
  212. nliNext.fclTopic = strtoul(pchFcl, NULL, 16);
  213. nliNext.iBitdex = (WORD) strtoul(pchBitdex, NULL, 16);
  214. nliNext.addr = strtoul(pchAddr, NULL, 16);
  215. nliNext.fNewSeq = (strcmp(szScratchBuf, szMajor) != 0);
  216. // Copy new szMajor to rgch, and move next szMajor to just beyond it
  217. strcpy(szScratchBuf, szMajor);
  218. szMajor = StrChr(szScratchBuf, '\0', FALSE) + 1;
  219. // Write out next and previous addresses
  220. if (nliCur.fclTopic != fclNil) {
  221. // use magic zeck-backpatch code:
  222. // Write out address of previous topic, if any
  223. FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
  224. (int) cbOffsetToPrevInMTOP,
  225. nliCur.iBitdex, (nliCur.fNewSeq ? addrNil : nliPrev.addr));
  226. // Write out address of next topic, if any
  227. FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
  228. (int) cbOffsetToNextInMTOP,
  229. nliCur.iBitdex, (nliNext.fNewSeq ? addrNil : nliNext.addr));
  230. }
  231. nliPrev = nliCur;
  232. nliCur = nliNext;
  233. #ifdef _DEBUG
  234. ++inli;
  235. #endif
  236. }
  237. delete ptblBrowse;
  238. ptblBrowse = NULL;
  239. ASSERT(inli == cnliMac);
  240. // Process last browse sequence:
  241. ASSERT(nliCur.fclTopic != fclNil);
  242. // use magic zeck-backpatch code:
  243. // Write out address of previous topic, if any
  244. FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
  245. (int) cbOffsetToPrevInMTOP,
  246. nliCur.iBitdex, (nliCur.fNewSeq ? addrNil : nliPrev.addr));
  247. // Write out address next address (always nil)
  248. FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
  249. (DWORD) cbOffsetToNextInMTOP, nliCur.iBitdex, (DWORD) addrNil);
  250. return TRUE;
  251. }