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.
 
 
 
 
 
 

390 lines
12 KiB

/*****************************************************************************
emkwd.h
Owner: DaleG
Copyright (c) 1992-1997 Microsoft Corporation
Keyword Table header file.
*****************************************************************************/
#ifndef KWD_H
MSOEXTERN_C_BEGIN // ***************** Begin extern "C" ********************
// Limits
#define msoipkwdMax 997 // Size of keywd hash
#ifndef KWD_HASH_ONLY
// Limits...
#define msoikwdAllocMax 100 // Max num KWDs/batch
#define msoichKwdAllocMax 100 // Max # kwd chs/batch
/*************************************************************************
Types:
kwdf Keyword-table entry record fixed.
kwd Keyword-table entry record.
kwtb Keyword table.
*************************************************************************/
#ifndef TK_DEFINED
// Definition of token type returned by lexer
typedef int TK;
#define TK_DEFINED
#endif /* !TK_DEFINED */
/* M S O K W D */
/*----------------------------------------------------------------------------
%%Structure: MSOKWD
%%Contact: daleg
Keyword-table entry record, and batch-allocation record.
----------------------------------------------------------------------------*/
// Look up as a string key value
typedef struct _MSOKWDSZ
{
const XCHAR *pxch; // String key value
short cch; // Length of kwd string
TK tk; // Token value
} MSOKWDSZ;
// Hash-table look up as a string key value
typedef struct _MSOKWD
{
const XCHAR *pxch; // String key value
short cch; // Length of kwd string
TK tk; // Token value
struct _MSOKWD *pkwdNext; // Next key in hash row
} MSOKWD;
// Batch allocation
typedef struct _MSOKWDBLK
{
struct _MSOKWDBLK *pkwdblkNext; // Next in chain
MSOKWD *pkwdRg; // Rg of MSOKWDs
} MSOKWDBLK;
// Look up as an integer key value
typedef struct _MSOKWDL
{
long lValue; // Integer key value
TK tk; // Token value
} MSOKWDL;
// Hash-table look up as a integer key value
typedef struct _MSOKWDLH
{
long lValue; // Integer key value
TK tk; // Token value
struct _MSOKWDLH *pkwdlhNext; // Next key in hash row
} MSOKWDLH;
/* M S O K W T B */
/*----------------------------------------------------------------------------
%%Structure: MSOKWTB
%%Contact: daleg
Keyword table record, and batch-allocation record.
The hash table is in rgpkwdHash. It is an array of linked lists,
of type MSOKWD.
The string buffer pxchBuf contains the character strings, PLUS the
MSOKWD records of the hash table at the end.
REVIEW: rgpkwdHash, pxchBuf and pkwdStart should be moved to the end of
this struct to avoid allocating excess space for non-hashed keytables.
Mso*Lookup* routines should assert that input MSOKWTB* arguments are of
suitable type.
----------------------------------------------------------------------------*/
typedef struct _MSOKWTB
{
// Table data
int kwtbt; // Keytable type
int ckwdMax; // Num of MSOKWD recs
MSOKWD *pkwdUnknown; // Returned when !found
void *pvTable; // Hash/Binary table
// Allocation/Init info
unsigned char fStaticInit; // Static Init-ed?
unsigned char fDynAlloced : 1; // MSOKWTB mem alloced?
unsigned char fHashTblAlloced : 1; // pvTable mem alloced?
unsigned char fSpare : 1;
// String support
XCHAR *pxchBuf; // String buffer
MSOKWD *pkwdStart; // First MSOKWD rec
// Extensions
int cxchKwdBufRemain; // Num avail chars
XCHAR *pxchKwdNext; // Next avail string
MSOKWD *pkwdNextFree; // Next av MSOKWD rec
struct _MSOKWDBLK *pkwdblkNext; // List of extra KWDs
struct _MSOKWSBLK *pkwsblkNext; // List of extra bufs
} MSOKWTB;
#define msokwtbtString 0x00
#define msokwtbtInteger 0x01
#define msokwtbtHashed 0x02
#define msokwtbtStringHashed 0x02
#define msokwtbtIntegerHashed 0x03
// String buffer batch allocation
typedef struct _MSOKWSBLK
{
struct _MSOKWSBLK *pkwsblkNext; // Next in chain
XCHAR *pxchBuf; // String buffer
} MSOKWSBLK;
/*************************************************************************
STRING LOOKUP
*************************************************************************/
// Lookup keyword
#define MsoTkLookupName(pxch, cchLen, pkwtb) \
(MsoPkwdLookupName((pxch), (cchLen), (pkwtb))->tk)
MSOAPI_(MSOKWD *) MsoPkwdLookupName( // Lookup keyword
const XCHAR *pxchStr,
int cchLen,
MSOKWTB *pkwtb
);
MSOAPI_(MSOKWD *) MsoPkwdAddTkLookupName( // Add kwd to table
const XCHAR *pxchStr,
int cchLen,
TK tk,
MSOKWTB *pkwtb,
int fCopyStr
);
MSOAPI_(int) MsoFRemoveTkLookupName( // Remove kwd from tbl
const XCHAR *pxchStr,
int cchLen,
MSOKWTB *pkwtb,
TK *ptk // RETURN
);
MSOAPI_(void) MsoInitHashKwtb(MSOKWTB *pkwtb); // Init a kwd hash tbl
MSOAPI_(MSOKWD *) _MsoPkwdNew( // Batch-alloc MSOKWDs
int ikwdMax,
MSOKWTB *pkwtb
);
int _FAddKwdRgchBuf(int ixchMax, MSOKWTB *pkwtb); // Batch-alloc kwd stzs
MSOAPI_(MSOKWTB *) MsoPkwtbNew(void); // Create new kwd tbl
#ifdef DEBUG
void _DumpKwds(MSOKWTB *pkwtb); // Print kwd table
#endif /* DEBUG */
// Get a new MSOKWD record from free list
_inline MSOKWD *MsoPkwdNew(MSOKWTB *pkwtb)
{
MSOKWD *pkwd;
return ((pkwtb)->pkwdNextFree
? (pkwd = (pkwtb)->pkwdNextFree,
(pkwtb)->pkwdNextFree = pkwd->pkwdNext,
pkwd->pkwdNext = (MSOKWD *) NULL,
pkwd)
: _MsoPkwdNew(msoikwdAllocMax, (pkwtb)));
}
// Put an existing MSOKWD record onto the free list
#define MsoDiscardPkwd(pkwd, pkwtb) \
((pkwd)->pkwdNext = (pkwtb)->pkwdNextFree, \
(pkwtb)->pkwdNextFree = (pkwd))
// Return address of first MSOKWD record for hash value in keyword lookup table
#define MsoPpkwdGetHashAddr(pkwtb, ikwd) \
(&(MsoRgpkwdHashFromKwtb(pkwtb)[ikwd]))
// Return hash table from keytable
#define MsoRgpkwdHashFromKwtb(pkwtb) \
((MSOKWD **) (pkwtb)->pvTable)
// Return integer binary table from keytable
#define MsoPkwdlFromKwtb(pkwtb) \
((MSOKWDL *) (pkwtb)->pvTable)
/*************************************************************************
INTEGER LOOKUP
*************************************************************************/
// REVIEW: references to this function should become references to
// MsoPkwdlLookupL with an MSOKWTB
MSOAPI_(int) MsoWLookupKwdl( // Binary search lookup
long lValue,
MSOKWDL const *pkwdlTbl,
int ikwdlMac
);
MSOAPI_(MSOKWDL *) MsoPkwdlLookupL( // Nohash-lookup a long
long lValue,
MSOKWTB *pkwtb
);
#ifdef DEBUG
#define MsoAssertKwtb(pkwtb) \
MsoAssertKwtbSz(pkwtb, #pkwtb)
MSOAPI_(void) MsoAssertKwtbSz(MSOKWTB *pkwtb, char *szName); // Ensure sorted
#else
#define MsoAssertKwtb(pkwtb)
#endif // DEBUG
MSOAPI_(MSOKWDLH *) MsoPkwdlhLookupL( // Hash-lookup a long
long lValue,
MSOKWTB *pkwtb
);
MSOAPI_(MSOKWDLH *) MsoPkwdlhAddTkLookupL( // Add int hash lookup
long lValue,
TK tk,
MSOKWTB *pkwtb
);
MSOAPI_(MSOKWDLH *) _MsoPkwdlhNew(int ikwdMax, MSOKWTB *pkwtb);
// Return addr of first MSOKWDLH record for hash value in keyword lookup table
#define MsoPpkwdlhGetHashAddr(pkwtb, ikwd) \
(&(MsoRgpkwdlhFromKwtb(pkwtb)[ikwd]))
// Return hash table from keytable
#define MsoRgpkwdlhFromKwtb(pkwtb) \
((MSOKWDLH **) (pkwtb)->pvTable)
// Get a new MSOKWDLH record from free list
_inline MSOKWDLH *MsoPkwdlhNew(MSOKWTB *pkwtb)
{
MSOKWDLH *pkwdlh;
if (pkwtb->pkwdNextFree)
{
pkwdlh = (MSOKWDLH *) (pkwtb)->pkwdNextFree;
pkwtb->pkwdNextFree = (MSOKWD *) pkwdlh->pkwdlhNext;
pkwdlh->pkwdlhNext = (MSOKWDLH *) NULL;
return pkwdlh;
}
else
return _MsoPkwdlhNew(msoikwdAllocMax, pkwtb);
}
// Put an existing MSOKWDLH record onto the free list
#define MsoDiscardPkwdlh(pkwdlh, pkwtb) \
((pkwdlh)->pkwdlhNext = (MSOKWDLH *) (pkwtb)->pkwdNextFree, \
(pkwtb)->pkwdNextFree = (MSOKWD *) (pkwdlh))
#endif /* !KWD_HASH_ONLY */
#ifndef ANSI_XCHAR
#define MsoIpkwdHashPxch(pch, cch) MsoIpkwdHashPwch(pch, cch)
#define MsoXchUpper MsoWchToUpper
#else /* ANSI_XCHAR */
#define MsoIpkwdHashPxch(pch, cch) MsoIpkwdHashPch(pch, cch)
#define MsoXchUpper MsoChToUpper
#endif /* !ANSI_XCHAR */
/* M S O C H T O U P P E R */
/*----------------------------------------------------------------------------
%%Function: MsoChToUpper
%%Contact: daleg
Convert ANSI character to uppercase.
----------------------------------------------------------------------------*/
_inline unsigned char MsoChToUpper(unsigned char ch)
{
return (islower(ch) ? (unsigned char) toupper(ch) : ch);
}
/* M S O I P K W D H A S H P C H */
/*----------------------------------------------------------------------------
%%Function: MsoIpkwdHashPch
%%Contact: daleg
Return a hash index for the given string and length, case insensitive.
----------------------------------------------------------------------------*/
_inline int MsoIpkwdHashPch(const unsigned char *pchStr, int cchLen)
{
/* Hash on first and last character of string, ignoring case */
return ((MsoChToUpper(*pchStr) * 419)
+ (MsoChToUpper(*(pchStr + (cchLen - 1)/2)) * 467)
+ (MsoChToUpper(*(pchStr + cchLen - 1)) * 359))
% msoipkwdMax;
}
/* M S O I P K W D H A S H P W C H */
/*----------------------------------------------------------------------------
%%Function: MsoIpkwdHashPwch
%%Contact: daleg
Return a hash index for the given string and length, case insensitive.
----------------------------------------------------------------------------*/
_inline int MsoIpkwdHashPwch(const WCHAR *pwchStr, int cchLen)
{
/* Hash on first and last character of string, ignoring case */
return ((MsoWchToUpper(*pwchStr) * 419)
+ (MsoWchToUpper(*(pwchStr + (cchLen - 1)/2)) * 467)
+ (MsoWchToUpper(*(pwchStr + cchLen - 1)) * 359))
% msoipkwdMax;
}
/* M S O I P K W D L H H A S H */
/*----------------------------------------------------------------------------
%%Function: MsoIpkwdlhHash
%%Contact: daleg
Return a hash index for the given integer value.
----------------------------------------------------------------------------*/
_inline int MsoIpkwdlhHash(long lValue)
{
return (((lValue + (lValue >> 1)) & ~0x80000000) % msoipkwdMax);
}
MSOEXTERN_C_END // ****************** End extern "C" *********************
#define KWD_H
#endif /* !KWD_H */