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

/*****************************************************************************
* *
* NEXTLIST.C *
* *
* Copyright (C) Microsoft Corporation 1990. *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* This module processes nextlist footnotes, putting the information into *
* a temporary file. After parsing all the RTF files, it then processes *
* this file. Eventually it will backpatch the |TOPIC file with the correct *
* browse topic addresses; for now, it just creates the |TOMAP with the *
* correct addresses. *
* *
*****************************************************************************/
/*****************************************************************************
*
* Revision History: Created 00/00/00 by LarryPo
*
* 11/21/90 JohnSc RcSortFm() replaces RcMegasortFm()
* 12/02/90 JohnSc do case insensitive sort of browse tags
* 12/14/90 JohnSc FErrorRc(rc) -> FErrorHce(HceFromRc(rc))
* 25-Feb-1991 JohnSc bug 948: unsafe calls to HceFromRc()
*
*****************************************************************************/
#include "stdafx.h"
#pragma hdrstop
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*****************************************************************************
* *
* Defines *
* *
*****************************************************************************/
#define chMinorDelimiter ((char) ':')
#define szMajorDefault "R"
/* This is the offset from the start of a topic FC to the previous
* and next fields in the packed MTOP structure.
* Note that the MOBJ structure contains a WORD parameter at the end
* that we currently don't write out in topic objects.
*/
#define cbOffsetToPrevInMTOP &(((QMTOP)0)->prev)
#define cbOffsetToNextInMTOP &(((QMTOP)0)->next)
/*****************************************************************************
* *
* Typedefs *
* *
*****************************************************************************/
// Next List Info.
typedef struct {
FCL fclTopic; // backpatch location of MTOP struct.
WORD iBitdex; // magic zeck-compression code-bits bitdex for that fcl.
ADDR addr; // addr to backpatch.
BOOL fNewSeq; // TRUE if this NLI starts a new sequence.
} NLI;
/*****************************************************************************
* *
* Static Variables *
* *
*****************************************************************************/
/*
* This variable contains the number of entries that have been written
* out to ptfBrowse.
*/
static long cnliMac;
/***************************************************************************
FUNCTION: FProcNextlistSz
PURPOSE: Processes a nextlist footnote string.
PARAMETERS:
szNextlist -- The nextlist footnote string
idfcp
perr
RETURNS:
COMMENTS:
MODIFICATION DATES:
30-Jul-1993 [ralphw]
***************************************************************************/
static int autoBrowse = 1;
static const char txtAuto[] = "auto";
BOOL STDCALL FProcNextlistSz(PSTR szNextlist, IDFCP idfcp, PERR perr)
{
PSTR pszMinor, pszMajor;
static BOOL fCreateFailed = FALSE;
char szBuf[10];
// Check if no browse sequences to be made
if (!ptblBrowse)
ptblBrowse = new CTable;
if (fBrowseDefined) {
VReportError(HCERR_BROWSE_DEFINED, &errHpj);
return FALSE;
}
pszMinor = StrChr(szNextlist, chMinorDelimiter, fDBCSSystem);
if (pszMinor == NULL) {
pszMajor = szMajorDefault;
pszMinor = SzTrimSz(szNextlist);
if (*pszMinor == '\0') {
pszMinor = szBuf;
_ltoa(autoBrowse++, szBuf, 10);
}
}
else {
*pszMinor = '\0';
pszMinor = SzTrimSz(pszMinor + 1);
if (*pszMinor == '\0' || _stricmp(pszMinor, txtAuto) == 0) {
pszMinor = szBuf;
_ltoa(autoBrowse++, szBuf, 10);
}
pszMajor = SzTrimSz(szNextlist);
if (*pszMajor == '\0')
pszMajor = szMajorDefault; // REVIEW: Warning needed ?
}
// Check for browse sequence defined too late
if (fHasTopicFCP) {
VReportError(HCERR_LATE_BROWSE, &errHpj);
return FALSE;
}
fBrowseDefined = TRUE;
FDelayExecutionBrowse(pszMajor, pszMinor, idfcp);
cnliMac++;
return TRUE;
}
/***************************************************************************
*
- Name FResolveNextlist
-
* Purpose
* This function processes the file of browse sequences to do
* what needs to be done to make browsing happen. Right now, that
* is to write FCL's to the |TOMAP file. In the future, this
* will consist of backpatching PA's into the |TOPIC file.
*
* Arguments
*
* Returns
*
* Globals
* This function uses the static variable cnliMac, which contains
* the number of entries in ptfBrowse.
*
* +++
*
* Notes
*
***************************************************************************/
static const int GRIND_INCREMENT = 100;
BOOL STDCALL FResolveNextlist(HF hfTopic)
{
#ifdef _DEBUG
int inli = 0;
#endif
PSTR szMajor, szMinor, pchFcl, pchAddr, pchBitdex;
int cGrind = 0;
//ADDR addr;
NLI nliPrev, nliCur, nliNext;
if (!ptblBrowse)
return TRUE; // Nothing to be done
// Check for no browse sequences:
if (cnliMac == 0) {
delete ptblBrowse;
ptblBrowse = NULL;
return TRUE;
}
SendStringToParent(IDS_RESOLVING_BROWSE);
if (!hwndParent && hwndGrind)
SetWindowText(hwndGrind, GetStringResource(IDS_RESOLVING_BROWSE));
ptblBrowse->SetSorting(lcid, kwlcid.fsCompareI, kwlcid.fsCompare);
ptblBrowse->SortTable();
doGrind();
/*
* When reading in new strings, we need to check if the major string
* matches the previous major string. To do this, the previous major
* string is stored at szScratchBuf, and the current major string is read
* in following that. The first previous major string is nil to always
* make it different.
*/
szScratchBuf[0] = '\0';
szMajor = szScratchBuf + 1;
nliCur.fclTopic = fclNil;
ptblBrowse->SetPosition(1);
while (ptblBrowse->GetString(szMajor)) {
if (++cGrind >= GRIND_INCREMENT) {
cGrind = 0;
doGrind();
}
// Split input into different strings
szMinor = StrChr(szMajor, chMinorDelimiter, fDBCSSystem);
ASSERT(szMinor != NULL);
*szMinor++ = '\0';
/* NOTE: While we are guaranteed that the major sequence string will
* not contain a delimiter character, we have no such guarantee for
* the minor sequence string. To calculate pointers to the fcl
* and addr fields, then, we need to backtrack from the end of
* the string.
*
* Each field is eight characters wide, and they are separated
* by ':' characters. The string will be terminated by a newline,
* unless buffer overflow has occured.
*/
pchAddr = StrChr(szMinor, '\n', fDBCSSystem);
ASSERT(pchAddr != NULL);
pchAddr -= 9;
pchBitdex = pchAddr - 9;
pchFcl = pchBitdex - 9;
ASSERT(*pchAddr == ':' && *pchFcl == ':' && *pchBitdex == ':');
*pchFcl++ = '\0';
*pchBitdex++ = '\0';
*pchAddr++ = '\0';
nliNext.fclTopic = strtoul(pchFcl, NULL, 16);
nliNext.iBitdex = (WORD) strtoul(pchBitdex, NULL, 16);
nliNext.addr = strtoul(pchAddr, NULL, 16);
nliNext.fNewSeq = (strcmp(szScratchBuf, szMajor) != 0);
// Copy new szMajor to rgch, and move next szMajor to just beyond it
strcpy(szScratchBuf, szMajor);
szMajor = StrChr(szScratchBuf, '\0', FALSE) + 1;
// Write out next and previous addresses
if (nliCur.fclTopic != fclNil) {
// use magic zeck-backpatch code:
// Write out address of previous topic, if any
FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
(int) cbOffsetToPrevInMTOP,
nliCur.iBitdex, (nliCur.fNewSeq ? addrNil : nliPrev.addr));
// Write out address of next topic, if any
FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
(int) cbOffsetToNextInMTOP,
nliCur.iBitdex, (nliNext.fNewSeq ? addrNil : nliNext.addr));
}
nliPrev = nliCur;
nliCur = nliNext;
#ifdef _DEBUG
++inli;
#endif
}
delete ptblBrowse;
ptblBrowse = NULL;
ASSERT(inli == cnliMac);
// Process last browse sequence:
ASSERT(nliCur.fclTopic != fclNil);
// use magic zeck-backpatch code:
// Write out address of previous topic, if any
FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
(int) cbOffsetToPrevInMTOP,
nliCur.iBitdex, (nliCur.fNewSeq ? addrNil : nliPrev.addr));
// Write out address next address (always nil)
FDiskBackpatchZeck(hfTopic, nliCur.fclTopic,
(DWORD) cbOffsetToNextInMTOP, nliCur.iBitdex, (DWORD) addrNil);
return TRUE;
}