mirror of https://github.com/lianthony/NT4.0
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.
823 lines
18 KiB
823 lines
18 KiB
/*****************************************************************************
|
|
* *
|
|
* HCFILE.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1990. *
|
|
* All Rights reserved. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Module Intent *
|
|
* *
|
|
* This module creates the output file from the compiler. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Testing Notes *
|
|
* This module assumes that whenever any field of the file smag is not *
|
|
* nil, it corresponds to a file resource that needs cleaning up. *
|
|
* Therefore, it is essential that all these fields are initialized to nil *
|
|
* values, and that all the code that allocates or frees file resources *
|
|
* appropriately modifies the file smag immediately. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Current Owner: LarryPo *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "whclass.h"
|
|
|
|
#include <time.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#include "..\hwdll\coutput.h"
|
|
|
|
COutput* pcout;
|
|
|
|
static void STDCALL FWriteTag(HF, TAG, WORD, LPVOID);
|
|
static void STDCALL WriteIcon(PSTR szIcon, HF hfSystem);
|
|
static RC_TYPE STDCALL RcInsertBaggage(void);
|
|
static void STDCALL AbandonContextFiles(BOOL fPreviousError);
|
|
static void STDCALL VAbandonTTLBtree(BOOL fPreviousError);
|
|
static INLINE void STDCALL FreePkwi(void);
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: RcInsertBaggage
|
|
-
|
|
* Purpose:
|
|
* Copy files named in the [baggage] section into the output FS.
|
|
*
|
|
* Arguments:
|
|
* hfs - output file system
|
|
*
|
|
***************************************************************************/
|
|
|
|
const int CB_READ_BUFFER = (64 * 1024);
|
|
|
|
static RC_TYPE STDCALL RcInsertBaggage(void)
|
|
{
|
|
if (!ptblBaggage || ptblBaggage->CountStrings() == 0)
|
|
return RC_Success;
|
|
|
|
CMem mem(CB_READ_BUFFER);
|
|
|
|
RC_TYPE rc = RC_Success;
|
|
for (int pos = 1; pos <= ptblBaggage->CountStrings(); pos++) {
|
|
CFMDirCurrent cfm(ptblBaggage->GetPointer(pos));
|
|
if (!cfm.fm)
|
|
return RC_OutOfMemory; // REVIEW: FmNewSzDir() is broken.
|
|
|
|
char szTmpFile[_MAX_PATH];
|
|
SzPartsFm(cfm.fm, szTmpFile, PARTBASE);
|
|
|
|
CRead crFile(cfm.fm);
|
|
if (crFile.hf == HFILE_ERROR)
|
|
return RcGetLastError();
|
|
|
|
HF hf = HfCreateFileHfs(hfsOut, szTmpFile, 0);
|
|
|
|
int cbRead;
|
|
do {
|
|
if ((cbRead = crFile.read(mem.pb, CB_READ_BUFFER)) == HFILE_ERROR) {
|
|
rc = RcGetLastError();
|
|
break;
|
|
}
|
|
LcbWriteHf(hf, mem.pb, cbRead);
|
|
} while (cbRead == CB_READ_BUFFER);
|
|
|
|
RcCloseHf(hf);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: FCreatePfsmgSz
|
|
-
|
|
* Purpose:
|
|
* Creates the following files in the pfsmg structure:
|
|
* hfsOut
|
|
* hfTopic
|
|
* hfFont
|
|
*
|
|
* Arguments:
|
|
* pfsmg: Pointer to file smag to initialize. InitPfsmg() must
|
|
* have already been called on this pfmsg.
|
|
* szFile: Name of output file.
|
|
*
|
|
* Returns:
|
|
* TRUE if sucessful.
|
|
*
|
|
*
|
|
***************************************************************************/
|
|
|
|
BOOL STDCALL FCreatePfsmgSz(PCSTR szFile)
|
|
{
|
|
BYTE bFileOptions;
|
|
|
|
// create the output file system
|
|
|
|
CFMDirCurrent cfm(szFile);
|
|
if (!cfm.fm)
|
|
OOM(); // doesn't return
|
|
|
|
// Report the name of the .HLP file
|
|
|
|
wsprintf(szParentString, GetStringResource(IDS_COMPILING_HLP), szFile);
|
|
SendStringToParent(szParentString);
|
|
|
|
if (!(hfsOut = HfsCreateFileSysFm(cfm.fm)))
|
|
return FALSE;
|
|
|
|
// create the topic file
|
|
|
|
/*
|
|
* if OPTCDROM option is turned on, request magic alignment file
|
|
* attribute:
|
|
*/
|
|
|
|
if (options.fOptCdRom)
|
|
bFileOptions = FS_CDROM;
|
|
else
|
|
bFileOptions = 0;
|
|
|
|
fmsg.hfTopic = HfCreateFileHfs(hfsOut, txtTopic,
|
|
options.fOptCdRom ? FS_CDROM : 0);
|
|
InitTopicHf(fmsg.hfTopic);
|
|
|
|
// create the font output file
|
|
|
|
fmsg.hfFont = HfCreateFileHfs(hfsOut, txtFont, 0);
|
|
|
|
FCreateTTLBtree(&fmsg); // create the Title B-Tree
|
|
|
|
FCreateContextFiles(); // Create context B-Tree
|
|
|
|
char szShortFile[MAX_PATH];
|
|
SzPartsFm(szHlpFile, szShortFile, PARTBASE);
|
|
pszShortHelpName = lcStrDup(szShortFile);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: CloseFilesPfsmg
|
|
-
|
|
* Purpose:
|
|
* This function closes all the files that remain open in pfsmg,
|
|
* finishing whatever processing needs to be finished before they
|
|
* are closed.
|
|
*
|
|
* Arguments:
|
|
* pfsmg: Pointer to file smag.
|
|
*
|
|
* Returns:
|
|
* nothing.
|
|
*
|
|
* +++
|
|
*
|
|
* Notes:
|
|
* This function also currently closes the keyword information
|
|
* files refered to by kwi.
|
|
*
|
|
***************************************************************************/
|
|
|
|
void STDCALL CloseFilesPfsmg(void)
|
|
{
|
|
if (fmsg.hfTopic) {
|
|
if (RcCloseHf(fmsg.hfTopic) != RC_Success) {
|
|
fmsg.hfTopic = NULL;
|
|
}
|
|
else
|
|
fmsg.hfTopic = NULL;
|
|
}
|
|
|
|
if (fmsg.hfFont) {
|
|
if (RcCloseHf(fmsg.hfFont) != RC_Success) {
|
|
fmsg.hfFont = NULL;
|
|
}
|
|
else
|
|
fmsg.hfFont = NULL;
|
|
}
|
|
|
|
if (fmsg.hfCtxOMap) {
|
|
if (RcCloseHf(fmsg.hfCtxOMap) != RC_Success) {
|
|
fmsg.hfCtxOMap = NULL;
|
|
}
|
|
else
|
|
fmsg.hfCtxOMap = NULL;
|
|
}
|
|
|
|
// if (!fPhraseOnly && !fHallPassOne) {
|
|
if (!fPhraseOnly) {
|
|
|
|
// Finish keyword processing
|
|
|
|
if (!FResolveKeysPkwi())
|
|
HardExit();
|
|
|
|
VCloseTTLBtree(); // Close the Title B-Tree
|
|
|
|
// Write out WindowTopic mappings -- do this BEFORE closing the
|
|
// Context btree.
|
|
|
|
OutWindowTopics();
|
|
|
|
CloseContextBtree();
|
|
|
|
ASSERT(fmsg.ptfScratch == NULL);
|
|
|
|
// Write out secondary window configuration macros
|
|
|
|
OutConfgMacros();
|
|
|
|
// Write out bitmap files.
|
|
|
|
OutBitmapFiles();
|
|
|
|
// Insert baggage files
|
|
|
|
RcInsertBaggage();
|
|
}
|
|
|
|
if (hfsOut) {
|
|
RcCloseHfs(hfsOut);
|
|
hfsOut = NULL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: AbandonPfsmg
|
|
-
|
|
* Purpose:
|
|
* Removes all files created in the compilation process. Used to
|
|
* clean up after an aborted compilation. Never emits error messages.
|
|
*
|
|
* Arguments:
|
|
* pfsmg: Pointer to file smag.
|
|
* szHlpFile: Name of help file to remove.
|
|
* REVIEW -- Should this be in the pfsmg somehow?
|
|
*
|
|
* Returns:
|
|
*
|
|
* Globals:
|
|
*
|
|
* +++
|
|
*
|
|
* Notes:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void STDCALL AbandonPfsmg(void)
|
|
{
|
|
static BOOL fBeenHere = FALSE;
|
|
|
|
if (fBeenHere)
|
|
return;
|
|
|
|
if (fmsg.hfTopic)
|
|
RcAbandonHf(fmsg.hfTopic);
|
|
|
|
if (fmsg.hfFont)
|
|
RcAbandonHf(fmsg.hfFont);
|
|
|
|
if (fmsg.hfSystem)
|
|
RcAbandonHf(fmsg.hfSystem);
|
|
|
|
if (fmsg.hfCtxOMap)
|
|
RcAbandonHf(fmsg.hfCtxOMap);
|
|
|
|
FreePkwi();
|
|
|
|
VAbandonTTLBtree(TRUE); // REVIEW - fPreviousError
|
|
AbandonContextFiles(TRUE); // REVIEW - fPreviousError
|
|
|
|
FRemovePtf(&fmsg.ptfScratch);
|
|
|
|
if (ptblBrowse)
|
|
delete ptblBrowse;
|
|
|
|
if (hfsOut)
|
|
RcCloseHfs(hfsOut);
|
|
|
|
remove(szHlpFile);
|
|
|
|
fBeenHere = TRUE;
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: OOM
|
|
|
|
PURPOSE: Called when we run out of memory
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
13-Jun-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
void STDCALL OOM(void)
|
|
{
|
|
AbandonPfsmg(); // Try to free up some memory
|
|
|
|
// Try to report it to parent and in log file
|
|
|
|
if (hwndParent && pszMap) {
|
|
strcpy(pszMap, GetStringResource(HCERR_OOM));
|
|
SendMessage(hwndParent, WMP_MSG, 0, 0);
|
|
if (pcout)
|
|
pcout->outstring(pszMap);
|
|
}
|
|
|
|
VReportError(HCERR_OOM, &errHpj, NULL);
|
|
#ifdef _DEBUG
|
|
if (MessageBox(NULL, "Out of memory", "Click Retry to break into MSVC debugger", MB_RETRYCANCEL) == IDRETRY)
|
|
DebugBreak();
|
|
#endif
|
|
|
|
throw EXCEPT_DIE_HORRIBLY;
|
|
}
|
|
|
|
void STDCALL HardExit(void)
|
|
{
|
|
#ifdef _DEBUG
|
|
if (MessageBox(NULL, "HardExit()", "Click Retry to break into MSVC debugger", MB_RETRYCANCEL) == IDRETRY)
|
|
DebugBreak();
|
|
#endif
|
|
AbandonPfsmg();
|
|
throw EXCEPT_DIE_HORRIBLY;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: VerifyPhpj
|
|
-
|
|
* Purpose:
|
|
* Verifies the self consistency of the phpj structure. The main
|
|
* criteria is, if we perform a hard exit at this point, can we
|
|
* successfully abandon all the files in the pfsmg?
|
|
*
|
|
* Arguments:
|
|
* PHPJ: Pointer to help file info
|
|
*
|
|
* Returns:
|
|
* Nothing.
|
|
*
|
|
* +++
|
|
*
|
|
* Notes:
|
|
* This code will assert if phpj is not self-consistent.
|
|
*
|
|
***************************************************************************/
|
|
|
|
void STDCALL VerifyPhpj(void)
|
|
{
|
|
VerifyPtf(fmsg.ptfScratch);
|
|
|
|
// Check bitmap files
|
|
|
|
VerifyCbmFiles();
|
|
}
|
|
|
|
#endif
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: FWriteTag
|
|
-
|
|
* Purpose:
|
|
* Writes out a tag to the given file system file.
|
|
*
|
|
* Arguments:
|
|
* HF: File to write tag to.
|
|
* TAG: Tag to write.
|
|
* int: Size of tag data.
|
|
* QV: Pointer to tag data.
|
|
*
|
|
* Returns:
|
|
* TRUE if successful, FALSE if I/O error.
|
|
*
|
|
***************************************************************************/
|
|
|
|
static void STDCALL FWriteTag(HF hf, TAG tag, WORD cbData, PVOID pdata)
|
|
{
|
|
WORD tg = (WORD) tag;
|
|
|
|
LcbWriteHf(hf, &tg, sizeof(WORD));
|
|
LcbWriteHf(hf, &cbData, sizeof(WORD));
|
|
LcbWriteHf(hf, pdata, cbData);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: WriteIcon( PSTR szIcon, HF hfSystem )
|
|
-
|
|
* Purpose: Copy the named icon file to the specified system HF.
|
|
*
|
|
* ASSUMES
|
|
* args IN: szIcon - name of an existing icon file to copy
|
|
* hfSystem - valid handle to open |SYSTEM file
|
|
*
|
|
* PROMISES
|
|
* args OUT: hfSystem - tagged data written here on success
|
|
*
|
|
* Side Effects: may emit error messages
|
|
*
|
|
* Notes: We don't actually check the validity of the icon file:
|
|
* the first few bytes were checked at .HPJ parse time.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
static void STDCALL WriteIcon(PSTR szIcon, HF hfSystem)
|
|
{
|
|
int cb; // off_t happens to be a long for us...
|
|
FM fm;
|
|
HFILE hf;
|
|
|
|
if ((fm = FmNewSzDir(szIcon, DIR_CURRENT)) == NULL)
|
|
|
|
// REVIEW: there should probably be some error checking
|
|
|
|
goto egress;
|
|
|
|
hf = FidOpenFm(fm, OF_READ);
|
|
if (HFILE_ERROR == hf) {
|
|
VReportError(HCERR_CANNOT_OPEN, &errHpj, szIcon);
|
|
goto egress_dispose;
|
|
}
|
|
|
|
cb = GetFileSize((HANDLE) hf, NULL);
|
|
if (UINT_MAX < cb) // note that if the file size is
|
|
|
|
// negative, we correctly emit error
|
|
|
|
{
|
|
VReportError(HCERR_INVALID_ICON, NULL, szIcon);
|
|
goto egress_close;
|
|
}
|
|
|
|
{
|
|
CMem mem(cb);
|
|
|
|
if (cb != LcbReadFid(hf, mem.pb, cb))
|
|
VReportError(HCERR_INVALID_ICON, NULL, szIcon);
|
|
else
|
|
FWriteTag(hfSystem, tagIcon, (WORD) cb, mem.pb);
|
|
}
|
|
|
|
egress_close:
|
|
RcCloseFid(hf);
|
|
egress_dispose:
|
|
DisposeFm(fm);
|
|
egress:
|
|
return;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: VOutSystemFile
|
|
-
|
|
* Purpose:
|
|
* This function creates the system file in the help filesystem.
|
|
*
|
|
* Arguments:
|
|
* pfsmg: Pointer to file smag. Eventually will be contained in phpj.
|
|
* phpj: Pointer to help file information to be put in system file.
|
|
*
|
|
* Returns:
|
|
* nothing
|
|
*
|
|
***************************************************************************/
|
|
|
|
void STDCALL VOutSystemFile()
|
|
{
|
|
|
|
HHDR hhdr;
|
|
hhdr.wMagic = MagicWord;
|
|
hhdr.wVersionNo = (version < 4) ? wVersion3_5 : wVersion40;
|
|
hhdr.wVersionFmt = VersionFmt;
|
|
time((time_t *) &hhdr.lDateCreated);
|
|
|
|
hhdr.wFlags = 0;
|
|
#ifdef MAGIC
|
|
hhdr.wFlags |= fDEBUG;
|
|
#endif
|
|
|
|
if (options.fsCompress & COMPRESS_TEXT_ZECK)
|
|
hhdr.wFlags |= fBLOCK_COMPRESSION;
|
|
|
|
// If HfCreateFileHfs fails, it won't return
|
|
|
|
fmsg.hfSystem = HfCreateFileHfs(hfsOut, txtSystem, 0); // |SYSTEM
|
|
|
|
LcbWriteHf(fmsg.hfSystem, &hhdr, sizeof(HHDR));
|
|
|
|
if (options.pszTitle)
|
|
FWriteTag(fmsg.hfSystem, tagTitle,
|
|
(WORD) (strlen(options.pszTitle) + 1), options.pszTitle);
|
|
|
|
{
|
|
ADDR addrContents = AddrGetContents(options.pszContentsTopic);
|
|
|
|
FWriteTag(fmsg.hfSystem, tagContents, sizeof(ADDR), &addrContents);
|
|
}
|
|
|
|
if (options.pszCopyright)
|
|
FWriteTag(fmsg.hfSystem, tagCopyright,
|
|
(WORD) strlen(options.pszCopyright) + 1,
|
|
options.pszCopyright);
|
|
|
|
if (options.pszCitation)
|
|
FWriteTag(fmsg.hfSystem, tagCitation,
|
|
(WORD) strlen(options.pszCitation) + 1,
|
|
options.pszCitation);
|
|
|
|
#if 0 // not unless we support icons again
|
|
if (options.pszIcon)
|
|
WriteIcon(options.pszIcon, fmsg.hfSystem);
|
|
#endif
|
|
|
|
if (ptblConfig) {
|
|
for (int pos = 1; pos <= ptblConfig->CountStrings(); pos++) {
|
|
FWriteTag(fmsg.hfSystem, tagConfig,
|
|
(WORD) strlen(ptblConfig->GetPointer(pos)) + 1,
|
|
ptblConfig->GetPointer(pos));
|
|
}
|
|
}
|
|
|
|
if (pdrgWsmag && pdrgWsmag->Count() > 0) {
|
|
PWSMAG pwsmag, pwsmagMax;
|
|
for (pwsmag = (PWSMAG) pdrgWsmag->GetBasePtr(),
|
|
pwsmagMax = pwsmag + pdrgWsmag->Count();
|
|
pwsmag < pwsmagMax;
|
|
pwsmag++) {
|
|
FWriteTag(fmsg.hfSystem, tagWindow, sizeof(WSMAG), pwsmag);
|
|
}
|
|
}
|
|
|
|
// New for 4.0
|
|
|
|
if (kwlcid.langid)
|
|
FWriteTag(fmsg.hfSystem, tagLCID, sizeof(kwlcid), &kwlcid);
|
|
|
|
if (options.pszCntFile)
|
|
FWriteTag(fmsg.hfSystem, tagCNT,
|
|
(WORD) strlen(options.pszCntFile) + 1, options.pszCntFile);
|
|
|
|
FWriteTag(fmsg.hfSystem, tagCHARSET, idHighestUsedFont + 1, paCharSets);
|
|
|
|
if (clrPopup != (COLORREF) -1)
|
|
FWriteTag(fmsg.hfSystem, tagPopupColor, sizeof(COLORREF), &clrPopup);
|
|
|
|
if (options.pszDefFont)
|
|
FWriteTag(fmsg.hfSystem, tagDefFont,
|
|
strlen(options.pszDefFont + 2) + 3,
|
|
options.pszDefFont);
|
|
|
|
if (options.pszIndexSeparators)
|
|
FWriteTag(fmsg.hfSystem, tagIndexSep,
|
|
strlen(options.pszIndexSeparators) + 1,
|
|
options.pszIndexSeparators);
|
|
|
|
if (RcCloseHf(fmsg.hfSystem) != RC_Success)
|
|
fmsg.hfSystem = NULL;
|
|
|
|
fmsg.hfSystem = NULL;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name FreePkwi
|
|
-
|
|
* Purpose
|
|
* This function removes any tables allocated by kwi
|
|
*
|
|
* Arguments
|
|
*
|
|
* Returns
|
|
* Nothing.
|
|
*
|
|
***************************************************************************/
|
|
|
|
static INLINE void STDCALL FreePkwi(void)
|
|
{
|
|
for (int ikwl = 0; ikwl < kwi.ckwlMac; ++ikwl) {
|
|
if (kwi.rgkwl[ikwl].ptbl != NULL)
|
|
delete kwi.rgkwl[ikwl].ptbl;
|
|
}
|
|
}
|
|
|
|
static void STDCALL AbandonContextFiles(BOOL fPreviousError)
|
|
{
|
|
if (fmsg.qbthrCtx != NULL) {
|
|
RcAbandonHbt(fmsg.qbthrCtx);
|
|
fmsg.qbthrCtx = NULL;
|
|
}
|
|
if (fmsg.hbtSource != NULL) {
|
|
RcAbandonHbt(fmsg.hbtSource);
|
|
fmsg.hbtSource = NULL;
|
|
}
|
|
|
|
delete ptblCtx;
|
|
ptblCtx = NULL;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
* VAbandonTTLBtree()
|
|
*
|
|
* Description:
|
|
* This function closes the Title Btree.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* Returns;
|
|
* NOTHING.
|
|
*-----------------------------------------------------------------------------*/
|
|
|
|
static void STDCALL VAbandonTTLBtree(BOOL fPreviousError)
|
|
{
|
|
int rc;
|
|
|
|
if (fmsg.qbthrTTL != NULL) {
|
|
rc = RcAbandonHbt(fmsg.qbthrTTL);
|
|
fmsg.qbthrTTL = NULL;
|
|
}
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: InitBtreeStruct
|
|
|
|
PURPOSE: Initialize btree structure
|
|
|
|
PARAMETERS:
|
|
pbt -- address of BTREE_PARAMS
|
|
pszFormat -- format string
|
|
cbBlock -- size of block
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
11-Jan-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
void STDCALL InitBtreeStruct(BTREE_PARAMS* pbt, PCSTR pszFormat, DWORD cbBlock)
|
|
{
|
|
pbt->cbBlock = (WORD) cbBlock;
|
|
pbt->bFlags = FS_OPEN_READ_WRITE;
|
|
if (options.fOptCdRom)
|
|
pbt->bFlags |= FS_CDROM;
|
|
strcpy(pbt->rgchFormat, pszFormat);
|
|
pbt->hfs = hfsOut;
|
|
}
|
|
|
|
void STDCALL OutConfgMacros(void)
|
|
{
|
|
for (int i = 0; i <= cwsmag; i++) {
|
|
if (pptblConfig[i] && pptblConfig[i]->CountStrings()) {
|
|
char szName[10];
|
|
wsprintf(szName, "|CF%u", i);
|
|
HF hf = HfCreateFileHfs(hfsOut, szName, FS_READ_WRITE);
|
|
CStr csz(pptblConfig[i]->GetPointer(1));
|
|
for (int j = 2; j <= pptblConfig[i]->CountStrings(); j++) {
|
|
csz += ":";
|
|
csz += pptblConfig[i]->GetPointer(j);
|
|
|
|
// Remove any trailing colons or semi-colons
|
|
|
|
int cb = strlen(csz) - 1;
|
|
if (csz.psz[cb] == ';' || csz.psz[cb] == ':')
|
|
csz.psz[cb] = '\0';
|
|
}
|
|
LcbWriteHf(hf, csz.psz, strlen(csz) + 1);
|
|
RcCloseHf(hf);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
FUNCTION: OutWindowTopics
|
|
|
|
PURPOSE: Output the |VIOLA btree -- a list of topic addresses that
|
|
go to a specific window
|
|
|
|
PARAMETERS:
|
|
void
|
|
|
|
RETURNS:
|
|
|
|
COMMENTS:
|
|
|
|
MODIFICATION DATES:
|
|
08-Nov-1994 [ralphw]
|
|
|
|
***************************************************************************/
|
|
|
|
const char *txtViola = "|VIOLA";
|
|
|
|
void STDCALL OutWindowTopics(void)
|
|
{
|
|
HASH_WINDOW* phashWindow;
|
|
ADDR addr;
|
|
BTREE_PARAMS bp;
|
|
|
|
if (!pdrgHashWindow)
|
|
return;
|
|
|
|
// Create hash btree file
|
|
|
|
int cbBlock = 4096;
|
|
|
|
// REVIEW: can we use block sizes smaller then 1024?
|
|
|
|
if (cbBlock > pdrgHashWindow->Count()) {
|
|
do {
|
|
cbBlock -= 1024;
|
|
} while (cbBlock > pdrgHashWindow->Count());
|
|
cbBlock += 1024;
|
|
}
|
|
|
|
InitBtreeStruct(&bp, "L4", cbBlock); // KT_LONG
|
|
|
|
QBTHR qbthr = HbtCreateBtreeSz(txtViola, &bp);
|
|
|
|
// REVIEW: what if HbtCreateBtreeSz fail?
|
|
|
|
ASSERT(qbthr);
|
|
int i;
|
|
for (i = 0, phashWindow = (HASH_WINDOW*) pdrgHashWindow->GetBasePtr();
|
|
i < pdrgHashWindow->Count();
|
|
i++, phashWindow++) {
|
|
RC_TYPE rc = RcLookupByKey(fmsg.qbthrCtx,
|
|
(KEY) &phashWindow->hash, NULL, &addr);
|
|
ASSERT(rc == RC_Success); // theoretically impossible
|
|
rc = RcInsertHbt(qbthr, (KEY) &addr, &phashWindow->iWindow);
|
|
if (rc != RC_Success) {
|
|
|
|
// BUGBUG: need an error message
|
|
|
|
}
|
|
}
|
|
|
|
if (RcCloseBtreeHbt(qbthr) != RC_Success) {
|
|
|
|
// BUGBUG: need and error message
|
|
|
|
}
|
|
}
|
|
|
|
void STDCALL FRemovePtf(PTF* pptf)
|
|
{
|
|
PTF ptf = *pptf;
|
|
|
|
if (ptf == NULL)
|
|
return;
|
|
|
|
if (ptf->pf)
|
|
fclose(ptf->pf);
|
|
|
|
if (ptf->fExists)
|
|
RcUnlinkFm(ptf->fm);
|
|
|
|
DisposeFm(ptf->fm);
|
|
lcFree(ptf);
|
|
pptf = NULL;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void VerifyPtf(PTF ptf )
|
|
{
|
|
if (ptf == NULL)
|
|
return;
|
|
|
|
// Check ptf->pf
|
|
|
|
if (ptf->fExists)
|
|
ASSERT(FValidFm(ptf->fm));
|
|
|
|
//VerifyFm(ptf->fm);
|
|
}
|
|
#endif /* DEBUG */
|