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

  1. /*****************************************************************************
  2. emkwd.h
  3. Owner: DaleG
  4. Copyright (c) 1992-1997 Microsoft Corporation
  5. Keyword Table header file.
  6. *****************************************************************************/
  7. #ifndef KWD_H
  8. MSOEXTERN_C_BEGIN // ***************** Begin extern "C" ********************
  9. // Limits
  10. #define msoipkwdMax 997 // Size of keywd hash
  11. #ifndef KWD_HASH_ONLY
  12. // Limits...
  13. #define msoikwdAllocMax 100 // Max num KWDs/batch
  14. #define msoichKwdAllocMax 100 // Max # kwd chs/batch
  15. /*************************************************************************
  16. Types:
  17. kwdf Keyword-table entry record fixed.
  18. kwd Keyword-table entry record.
  19. kwtb Keyword table.
  20. *************************************************************************/
  21. #ifndef TK_DEFINED
  22. // Definition of token type returned by lexer
  23. typedef int TK;
  24. #define TK_DEFINED
  25. #endif /* !TK_DEFINED */
  26. /* M S O K W D */
  27. /*----------------------------------------------------------------------------
  28. %%Structure: MSOKWD
  29. %%Contact: daleg
  30. Keyword-table entry record, and batch-allocation record.
  31. ----------------------------------------------------------------------------*/
  32. // Look up as a string key value
  33. typedef struct _MSOKWDSZ
  34. {
  35. const XCHAR *pxch; // String key value
  36. short cch; // Length of kwd string
  37. TK tk; // Token value
  38. } MSOKWDSZ;
  39. // Hash-table look up as a string key value
  40. typedef struct _MSOKWD
  41. {
  42. const XCHAR *pxch; // String key value
  43. short cch; // Length of kwd string
  44. TK tk; // Token value
  45. struct _MSOKWD *pkwdNext; // Next key in hash row
  46. } MSOKWD;
  47. // Batch allocation
  48. typedef struct _MSOKWDBLK
  49. {
  50. struct _MSOKWDBLK *pkwdblkNext; // Next in chain
  51. MSOKWD *pkwdRg; // Rg of MSOKWDs
  52. } MSOKWDBLK;
  53. // Look up as an integer key value
  54. typedef struct _MSOKWDL
  55. {
  56. long lValue; // Integer key value
  57. TK tk; // Token value
  58. } MSOKWDL;
  59. // Hash-table look up as a integer key value
  60. typedef struct _MSOKWDLH
  61. {
  62. long lValue; // Integer key value
  63. TK tk; // Token value
  64. struct _MSOKWDLH *pkwdlhNext; // Next key in hash row
  65. } MSOKWDLH;
  66. /* M S O K W T B */
  67. /*----------------------------------------------------------------------------
  68. %%Structure: MSOKWTB
  69. %%Contact: daleg
  70. Keyword table record, and batch-allocation record.
  71. The hash table is in rgpkwdHash. It is an array of linked lists,
  72. of type MSOKWD.
  73. The string buffer pxchBuf contains the character strings, PLUS the
  74. MSOKWD records of the hash table at the end.
  75. REVIEW: rgpkwdHash, pxchBuf and pkwdStart should be moved to the end of
  76. this struct to avoid allocating excess space for non-hashed keytables.
  77. Mso*Lookup* routines should assert that input MSOKWTB* arguments are of
  78. suitable type.
  79. ----------------------------------------------------------------------------*/
  80. typedef struct _MSOKWTB
  81. {
  82. // Table data
  83. int kwtbt; // Keytable type
  84. int ckwdMax; // Num of MSOKWD recs
  85. MSOKWD *pkwdUnknown; // Returned when !found
  86. void *pvTable; // Hash/Binary table
  87. // Allocation/Init info
  88. unsigned char fStaticInit; // Static Init-ed?
  89. unsigned char fDynAlloced : 1; // MSOKWTB mem alloced?
  90. unsigned char fHashTblAlloced : 1; // pvTable mem alloced?
  91. unsigned char fSpare : 1;
  92. // String support
  93. XCHAR *pxchBuf; // String buffer
  94. MSOKWD *pkwdStart; // First MSOKWD rec
  95. // Extensions
  96. int cxchKwdBufRemain; // Num avail chars
  97. XCHAR *pxchKwdNext; // Next avail string
  98. MSOKWD *pkwdNextFree; // Next av MSOKWD rec
  99. struct _MSOKWDBLK *pkwdblkNext; // List of extra KWDs
  100. struct _MSOKWSBLK *pkwsblkNext; // List of extra bufs
  101. } MSOKWTB;
  102. #define msokwtbtString 0x00
  103. #define msokwtbtInteger 0x01
  104. #define msokwtbtHashed 0x02
  105. #define msokwtbtStringHashed 0x02
  106. #define msokwtbtIntegerHashed 0x03
  107. // String buffer batch allocation
  108. typedef struct _MSOKWSBLK
  109. {
  110. struct _MSOKWSBLK *pkwsblkNext; // Next in chain
  111. XCHAR *pxchBuf; // String buffer
  112. } MSOKWSBLK;
  113. /*************************************************************************
  114. STRING LOOKUP
  115. *************************************************************************/
  116. // Lookup keyword
  117. #define MsoTkLookupName(pxch, cchLen, pkwtb) \
  118. (MsoPkwdLookupName((pxch), (cchLen), (pkwtb))->tk)
  119. MSOAPI_(MSOKWD *) MsoPkwdLookupName( // Lookup keyword
  120. const XCHAR *pxchStr,
  121. int cchLen,
  122. MSOKWTB *pkwtb
  123. );
  124. MSOAPI_(MSOKWD *) MsoPkwdAddTkLookupName( // Add kwd to table
  125. const XCHAR *pxchStr,
  126. int cchLen,
  127. TK tk,
  128. MSOKWTB *pkwtb,
  129. int fCopyStr
  130. );
  131. MSOAPI_(int) MsoFRemoveTkLookupName( // Remove kwd from tbl
  132. const XCHAR *pxchStr,
  133. int cchLen,
  134. MSOKWTB *pkwtb,
  135. TK *ptk // RETURN
  136. );
  137. MSOAPI_(void) MsoInitHashKwtb(MSOKWTB *pkwtb); // Init a kwd hash tbl
  138. MSOAPI_(MSOKWD *) _MsoPkwdNew( // Batch-alloc MSOKWDs
  139. int ikwdMax,
  140. MSOKWTB *pkwtb
  141. );
  142. int _FAddKwdRgchBuf(int ixchMax, MSOKWTB *pkwtb); // Batch-alloc kwd stzs
  143. MSOAPI_(MSOKWTB *) MsoPkwtbNew(void); // Create new kwd tbl
  144. #ifdef DEBUG
  145. void _DumpKwds(MSOKWTB *pkwtb); // Print kwd table
  146. #endif /* DEBUG */
  147. // Get a new MSOKWD record from free list
  148. _inline MSOKWD *MsoPkwdNew(MSOKWTB *pkwtb)
  149. {
  150. MSOKWD *pkwd;
  151. return ((pkwtb)->pkwdNextFree
  152. ? (pkwd = (pkwtb)->pkwdNextFree,
  153. (pkwtb)->pkwdNextFree = pkwd->pkwdNext,
  154. pkwd->pkwdNext = (MSOKWD *) NULL,
  155. pkwd)
  156. : _MsoPkwdNew(msoikwdAllocMax, (pkwtb)));
  157. }
  158. // Put an existing MSOKWD record onto the free list
  159. #define MsoDiscardPkwd(pkwd, pkwtb) \
  160. ((pkwd)->pkwdNext = (pkwtb)->pkwdNextFree, \
  161. (pkwtb)->pkwdNextFree = (pkwd))
  162. // Return address of first MSOKWD record for hash value in keyword lookup table
  163. #define MsoPpkwdGetHashAddr(pkwtb, ikwd) \
  164. (&(MsoRgpkwdHashFromKwtb(pkwtb)[ikwd]))
  165. // Return hash table from keytable
  166. #define MsoRgpkwdHashFromKwtb(pkwtb) \
  167. ((MSOKWD **) (pkwtb)->pvTable)
  168. // Return integer binary table from keytable
  169. #define MsoPkwdlFromKwtb(pkwtb) \
  170. ((MSOKWDL *) (pkwtb)->pvTable)
  171. /*************************************************************************
  172. INTEGER LOOKUP
  173. *************************************************************************/
  174. // REVIEW: references to this function should become references to
  175. // MsoPkwdlLookupL with an MSOKWTB
  176. MSOAPI_(int) MsoWLookupKwdl( // Binary search lookup
  177. long lValue,
  178. MSOKWDL const *pkwdlTbl,
  179. int ikwdlMac
  180. );
  181. MSOAPI_(MSOKWDL *) MsoPkwdlLookupL( // Nohash-lookup a long
  182. long lValue,
  183. MSOKWTB *pkwtb
  184. );
  185. #ifdef DEBUG
  186. #define MsoAssertKwtb(pkwtb) \
  187. MsoAssertKwtbSz(pkwtb, #pkwtb)
  188. MSOAPI_(void) MsoAssertKwtbSz(MSOKWTB *pkwtb, char *szName); // Ensure sorted
  189. #else
  190. #define MsoAssertKwtb(pkwtb)
  191. #endif // DEBUG
  192. MSOAPI_(MSOKWDLH *) MsoPkwdlhLookupL( // Hash-lookup a long
  193. long lValue,
  194. MSOKWTB *pkwtb
  195. );
  196. MSOAPI_(MSOKWDLH *) MsoPkwdlhAddTkLookupL( // Add int hash lookup
  197. long lValue,
  198. TK tk,
  199. MSOKWTB *pkwtb
  200. );
  201. MSOAPI_(MSOKWDLH *) _MsoPkwdlhNew(int ikwdMax, MSOKWTB *pkwtb);
  202. // Return addr of first MSOKWDLH record for hash value in keyword lookup table
  203. #define MsoPpkwdlhGetHashAddr(pkwtb, ikwd) \
  204. (&(MsoRgpkwdlhFromKwtb(pkwtb)[ikwd]))
  205. // Return hash table from keytable
  206. #define MsoRgpkwdlhFromKwtb(pkwtb) \
  207. ((MSOKWDLH **) (pkwtb)->pvTable)
  208. // Get a new MSOKWDLH record from free list
  209. _inline MSOKWDLH *MsoPkwdlhNew(MSOKWTB *pkwtb)
  210. {
  211. MSOKWDLH *pkwdlh;
  212. if (pkwtb->pkwdNextFree)
  213. {
  214. pkwdlh = (MSOKWDLH *) (pkwtb)->pkwdNextFree;
  215. pkwtb->pkwdNextFree = (MSOKWD *) pkwdlh->pkwdlhNext;
  216. pkwdlh->pkwdlhNext = (MSOKWDLH *) NULL;
  217. return pkwdlh;
  218. }
  219. else
  220. return _MsoPkwdlhNew(msoikwdAllocMax, pkwtb);
  221. }
  222. // Put an existing MSOKWDLH record onto the free list
  223. #define MsoDiscardPkwdlh(pkwdlh, pkwtb) \
  224. ((pkwdlh)->pkwdlhNext = (MSOKWDLH *) (pkwtb)->pkwdNextFree, \
  225. (pkwtb)->pkwdNextFree = (MSOKWD *) (pkwdlh))
  226. #endif /* !KWD_HASH_ONLY */
  227. #ifndef ANSI_XCHAR
  228. #define MsoIpkwdHashPxch(pch, cch) MsoIpkwdHashPwch(pch, cch)
  229. #define MsoXchUpper MsoWchToUpper
  230. #else /* ANSI_XCHAR */
  231. #define MsoIpkwdHashPxch(pch, cch) MsoIpkwdHashPch(pch, cch)
  232. #define MsoXchUpper MsoChToUpper
  233. #endif /* !ANSI_XCHAR */
  234. /* M S O C H T O U P P E R */
  235. /*----------------------------------------------------------------------------
  236. %%Function: MsoChToUpper
  237. %%Contact: daleg
  238. Convert ANSI character to uppercase.
  239. ----------------------------------------------------------------------------*/
  240. _inline unsigned char MsoChToUpper(unsigned char ch)
  241. {
  242. return (islower(ch) ? (unsigned char) toupper(ch) : ch);
  243. }
  244. /* M S O I P K W D H A S H P C H */
  245. /*----------------------------------------------------------------------------
  246. %%Function: MsoIpkwdHashPch
  247. %%Contact: daleg
  248. Return a hash index for the given string and length, case insensitive.
  249. ----------------------------------------------------------------------------*/
  250. _inline int MsoIpkwdHashPch(const unsigned char *pchStr, int cchLen)
  251. {
  252. /* Hash on first and last character of string, ignoring case */
  253. return ((MsoChToUpper(*pchStr) * 419)
  254. + (MsoChToUpper(*(pchStr + (cchLen - 1)/2)) * 467)
  255. + (MsoChToUpper(*(pchStr + cchLen - 1)) * 359))
  256. % msoipkwdMax;
  257. }
  258. /* M S O I P K W D H A S H P W C H */
  259. /*----------------------------------------------------------------------------
  260. %%Function: MsoIpkwdHashPwch
  261. %%Contact: daleg
  262. Return a hash index for the given string and length, case insensitive.
  263. ----------------------------------------------------------------------------*/
  264. _inline int MsoIpkwdHashPwch(const WCHAR *pwchStr, int cchLen)
  265. {
  266. /* Hash on first and last character of string, ignoring case */
  267. return ((MsoWchToUpper(*pwchStr) * 419)
  268. + (MsoWchToUpper(*(pwchStr + (cchLen - 1)/2)) * 467)
  269. + (MsoWchToUpper(*(pwchStr + cchLen - 1)) * 359))
  270. % msoipkwdMax;
  271. }
  272. /* M S O I P K W D L H H A S H */
  273. /*----------------------------------------------------------------------------
  274. %%Function: MsoIpkwdlhHash
  275. %%Contact: daleg
  276. Return a hash index for the given integer value.
  277. ----------------------------------------------------------------------------*/
  278. _inline int MsoIpkwdlhHash(long lValue)
  279. {
  280. return (((lValue + (lValue >> 1)) & ~0x80000000) % msoipkwdMax);
  281. }
  282. MSOEXTERN_C_END // ****************** End extern "C" *********************
  283. #define KWD_H
  284. #endif /* !KWD_H */