clipsruby 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/ext/clipsruby/agenda.c +1373 -0
  3. data/ext/clipsruby/agenda.h +169 -0
  4. data/ext/clipsruby/analysis.c +1142 -0
  5. data/ext/clipsruby/analysis.h +61 -0
  6. data/ext/clipsruby/argacces.c +526 -0
  7. data/ext/clipsruby/argacces.h +77 -0
  8. data/ext/clipsruby/bload.c +884 -0
  9. data/ext/clipsruby/bload.h +94 -0
  10. data/ext/clipsruby/bmathfun.c +557 -0
  11. data/ext/clipsruby/bmathfun.h +66 -0
  12. data/ext/clipsruby/bsave.c +634 -0
  13. data/ext/clipsruby/bsave.h +130 -0
  14. data/ext/clipsruby/classcom.c +976 -0
  15. data/ext/clipsruby/classcom.h +115 -0
  16. data/ext/clipsruby/classexm.c +1376 -0
  17. data/ext/clipsruby/classexm.h +97 -0
  18. data/ext/clipsruby/classfun.c +1392 -0
  19. data/ext/clipsruby/classfun.h +164 -0
  20. data/ext/clipsruby/classinf.c +1245 -0
  21. data/ext/clipsruby/classinf.h +94 -0
  22. data/ext/clipsruby/classini.c +843 -0
  23. data/ext/clipsruby/classini.h +75 -0
  24. data/ext/clipsruby/classpsr.c +957 -0
  25. data/ext/clipsruby/classpsr.h +73 -0
  26. data/ext/clipsruby/clips.h +133 -0
  27. data/ext/clipsruby/clipsruby.c +619 -0
  28. data/ext/clipsruby/clsltpsr.c +931 -0
  29. data/ext/clipsruby/clsltpsr.h +72 -0
  30. data/ext/clipsruby/commline.c +1217 -0
  31. data/ext/clipsruby/commline.h +131 -0
  32. data/ext/clipsruby/conscomp.c +1593 -0
  33. data/ext/clipsruby/conscomp.h +150 -0
  34. data/ext/clipsruby/constant.h +264 -0
  35. data/ext/clipsruby/constrct.c +1090 -0
  36. data/ext/clipsruby/constrct.h +216 -0
  37. data/ext/clipsruby/constrnt.c +554 -0
  38. data/ext/clipsruby/constrnt.h +132 -0
  39. data/ext/clipsruby/crstrtgy.c +1088 -0
  40. data/ext/clipsruby/crstrtgy.h +85 -0
  41. data/ext/clipsruby/cstrcbin.c +185 -0
  42. data/ext/clipsruby/cstrcbin.h +61 -0
  43. data/ext/clipsruby/cstrccmp.h +43 -0
  44. data/ext/clipsruby/cstrccom.c +1791 -0
  45. data/ext/clipsruby/cstrccom.h +115 -0
  46. data/ext/clipsruby/cstrcpsr.c +835 -0
  47. data/ext/clipsruby/cstrcpsr.h +97 -0
  48. data/ext/clipsruby/cstrnbin.c +282 -0
  49. data/ext/clipsruby/cstrnbin.h +55 -0
  50. data/ext/clipsruby/cstrnchk.c +826 -0
  51. data/ext/clipsruby/cstrnchk.h +91 -0
  52. data/ext/clipsruby/cstrncmp.c +238 -0
  53. data/ext/clipsruby/cstrncmp.h +57 -0
  54. data/ext/clipsruby/cstrnops.c +1176 -0
  55. data/ext/clipsruby/cstrnops.h +47 -0
  56. data/ext/clipsruby/cstrnpsr.c +1394 -0
  57. data/ext/clipsruby/cstrnpsr.h +88 -0
  58. data/ext/clipsruby/cstrnutl.c +564 -0
  59. data/ext/clipsruby/cstrnutl.h +54 -0
  60. data/ext/clipsruby/default.c +454 -0
  61. data/ext/clipsruby/default.h +57 -0
  62. data/ext/clipsruby/defins.c +971 -0
  63. data/ext/clipsruby/defins.h +127 -0
  64. data/ext/clipsruby/developr.c +677 -0
  65. data/ext/clipsruby/developr.h +69 -0
  66. data/ext/clipsruby/dffctbin.c +477 -0
  67. data/ext/clipsruby/dffctbin.h +76 -0
  68. data/ext/clipsruby/dffctbsc.c +308 -0
  69. data/ext/clipsruby/dffctbsc.h +72 -0
  70. data/ext/clipsruby/dffctcmp.c +297 -0
  71. data/ext/clipsruby/dffctcmp.h +44 -0
  72. data/ext/clipsruby/dffctdef.c +364 -0
  73. data/ext/clipsruby/dffctdef.h +104 -0
  74. data/ext/clipsruby/dffctpsr.c +179 -0
  75. data/ext/clipsruby/dffctpsr.h +49 -0
  76. data/ext/clipsruby/dffnxbin.c +520 -0
  77. data/ext/clipsruby/dffnxbin.h +67 -0
  78. data/ext/clipsruby/dffnxcmp.c +378 -0
  79. data/ext/clipsruby/dffnxcmp.h +54 -0
  80. data/ext/clipsruby/dffnxexe.c +241 -0
  81. data/ext/clipsruby/dffnxexe.h +58 -0
  82. data/ext/clipsruby/dffnxfun.c +1192 -0
  83. data/ext/clipsruby/dffnxfun.h +155 -0
  84. data/ext/clipsruby/dffnxpsr.c +514 -0
  85. data/ext/clipsruby/dffnxpsr.h +57 -0
  86. data/ext/clipsruby/dfinsbin.c +509 -0
  87. data/ext/clipsruby/dfinsbin.h +66 -0
  88. data/ext/clipsruby/dfinscmp.c +345 -0
  89. data/ext/clipsruby/dfinscmp.h +48 -0
  90. data/ext/clipsruby/drive.c +1191 -0
  91. data/ext/clipsruby/drive.h +65 -0
  92. data/ext/clipsruby/emathfun.c +1213 -0
  93. data/ext/clipsruby/emathfun.h +99 -0
  94. data/ext/clipsruby/engine.c +1568 -0
  95. data/ext/clipsruby/engine.h +203 -0
  96. data/ext/clipsruby/entities.h +276 -0
  97. data/ext/clipsruby/envrnbld.c +514 -0
  98. data/ext/clipsruby/envrnbld.h +40 -0
  99. data/ext/clipsruby/envrnmnt.c +257 -0
  100. data/ext/clipsruby/envrnmnt.h +112 -0
  101. data/ext/clipsruby/evaluatn.c +1736 -0
  102. data/ext/clipsruby/evaluatn.h +211 -0
  103. data/ext/clipsruby/expressn.c +494 -0
  104. data/ext/clipsruby/expressn.h +154 -0
  105. data/ext/clipsruby/exprnbin.c +538 -0
  106. data/ext/clipsruby/exprnbin.h +60 -0
  107. data/ext/clipsruby/exprnops.c +564 -0
  108. data/ext/clipsruby/exprnops.h +67 -0
  109. data/ext/clipsruby/exprnpsr.c +1112 -0
  110. data/ext/clipsruby/exprnpsr.h +98 -0
  111. data/ext/clipsruby/extconf.rb +2 -0
  112. data/ext/clipsruby/extnfunc.c +1015 -0
  113. data/ext/clipsruby/extnfunc.h +157 -0
  114. data/ext/clipsruby/factbin.c +447 -0
  115. data/ext/clipsruby/factbin.h +56 -0
  116. data/ext/clipsruby/factbld.c +1035 -0
  117. data/ext/clipsruby/factbld.h +63 -0
  118. data/ext/clipsruby/factcmp.c +386 -0
  119. data/ext/clipsruby/factcmp.h +46 -0
  120. data/ext/clipsruby/factcom.c +759 -0
  121. data/ext/clipsruby/factcom.h +80 -0
  122. data/ext/clipsruby/factfile.c +1761 -0
  123. data/ext/clipsruby/factfile.h +54 -0
  124. data/ext/clipsruby/factfun.c +682 -0
  125. data/ext/clipsruby/factfun.h +77 -0
  126. data/ext/clipsruby/factgen.c +1305 -0
  127. data/ext/clipsruby/factgen.h +229 -0
  128. data/ext/clipsruby/facthsh.c +438 -0
  129. data/ext/clipsruby/facthsh.h +81 -0
  130. data/ext/clipsruby/factlhs.c +250 -0
  131. data/ext/clipsruby/factlhs.h +54 -0
  132. data/ext/clipsruby/factmch.c +905 -0
  133. data/ext/clipsruby/factmch.h +68 -0
  134. data/ext/clipsruby/factmngr.c +3373 -0
  135. data/ext/clipsruby/factmngr.h +325 -0
  136. data/ext/clipsruby/factprt.c +498 -0
  137. data/ext/clipsruby/factprt.h +60 -0
  138. data/ext/clipsruby/factqpsr.c +796 -0
  139. data/ext/clipsruby/factqpsr.h +61 -0
  140. data/ext/clipsruby/factqury.c +1267 -0
  141. data/ext/clipsruby/factqury.h +112 -0
  142. data/ext/clipsruby/factrete.c +978 -0
  143. data/ext/clipsruby/factrete.h +70 -0
  144. data/ext/clipsruby/factrhs.c +667 -0
  145. data/ext/clipsruby/factrhs.h +55 -0
  146. data/ext/clipsruby/filecom.c +353 -0
  147. data/ext/clipsruby/filecom.h +137 -0
  148. data/ext/clipsruby/filertr.c +481 -0
  149. data/ext/clipsruby/filertr.h +94 -0
  150. data/ext/clipsruby/fileutil.c +1020 -0
  151. data/ext/clipsruby/fileutil.h +50 -0
  152. data/ext/clipsruby/generate.c +1079 -0
  153. data/ext/clipsruby/generate.h +57 -0
  154. data/ext/clipsruby/genrcbin.c +902 -0
  155. data/ext/clipsruby/genrcbin.h +69 -0
  156. data/ext/clipsruby/genrccmp.c +640 -0
  157. data/ext/clipsruby/genrccmp.h +59 -0
  158. data/ext/clipsruby/genrccom.c +2017 -0
  159. data/ext/clipsruby/genrccom.h +119 -0
  160. data/ext/clipsruby/genrcexe.c +737 -0
  161. data/ext/clipsruby/genrcexe.h +73 -0
  162. data/ext/clipsruby/genrcfun.c +890 -0
  163. data/ext/clipsruby/genrcfun.h +185 -0
  164. data/ext/clipsruby/genrcpsr.c +1618 -0
  165. data/ext/clipsruby/genrcpsr.h +80 -0
  166. data/ext/clipsruby/globlbin.c +458 -0
  167. data/ext/clipsruby/globlbin.h +71 -0
  168. data/ext/clipsruby/globlbsc.c +361 -0
  169. data/ext/clipsruby/globlbsc.h +83 -0
  170. data/ext/clipsruby/globlcmp.c +330 -0
  171. data/ext/clipsruby/globlcmp.h +52 -0
  172. data/ext/clipsruby/globlcom.c +289 -0
  173. data/ext/clipsruby/globlcom.h +63 -0
  174. data/ext/clipsruby/globldef.c +1087 -0
  175. data/ext/clipsruby/globldef.h +151 -0
  176. data/ext/clipsruby/globlpsr.c +530 -0
  177. data/ext/clipsruby/globlpsr.h +59 -0
  178. data/ext/clipsruby/immthpsr.c +431 -0
  179. data/ext/clipsruby/immthpsr.h +55 -0
  180. data/ext/clipsruby/incrrset.c +530 -0
  181. data/ext/clipsruby/incrrset.h +73 -0
  182. data/ext/clipsruby/inherpsr.c +850 -0
  183. data/ext/clipsruby/inherpsr.h +52 -0
  184. data/ext/clipsruby/inscom.c +2076 -0
  185. data/ext/clipsruby/inscom.h +182 -0
  186. data/ext/clipsruby/insfile.c +1764 -0
  187. data/ext/clipsruby/insfile.h +96 -0
  188. data/ext/clipsruby/insfun.c +1451 -0
  189. data/ext/clipsruby/insfun.h +134 -0
  190. data/ext/clipsruby/insmngr.c +2550 -0
  191. data/ext/clipsruby/insmngr.h +125 -0
  192. data/ext/clipsruby/insmoddp.c +1041 -0
  193. data/ext/clipsruby/insmoddp.h +91 -0
  194. data/ext/clipsruby/insmult.c +804 -0
  195. data/ext/clipsruby/insmult.h +62 -0
  196. data/ext/clipsruby/inspsr.c +602 -0
  197. data/ext/clipsruby/inspsr.h +60 -0
  198. data/ext/clipsruby/insquery.c +1278 -0
  199. data/ext/clipsruby/insquery.h +115 -0
  200. data/ext/clipsruby/insqypsr.c +729 -0
  201. data/ext/clipsruby/insqypsr.h +63 -0
  202. data/ext/clipsruby/iofun.c +2045 -0
  203. data/ext/clipsruby/iofun.h +116 -0
  204. data/ext/clipsruby/lgcldpnd.c +644 -0
  205. data/ext/clipsruby/lgcldpnd.h +75 -0
  206. data/ext/clipsruby/main.c +112 -0
  207. data/ext/clipsruby/match.h +142 -0
  208. data/ext/clipsruby/memalloc.c +481 -0
  209. data/ext/clipsruby/memalloc.h +197 -0
  210. data/ext/clipsruby/miscfun.c +1801 -0
  211. data/ext/clipsruby/miscfun.h +132 -0
  212. data/ext/clipsruby/modulbin.c +607 -0
  213. data/ext/clipsruby/modulbin.h +84 -0
  214. data/ext/clipsruby/modulbsc.c +347 -0
  215. data/ext/clipsruby/modulbsc.h +67 -0
  216. data/ext/clipsruby/modulcmp.c +499 -0
  217. data/ext/clipsruby/modulcmp.h +54 -0
  218. data/ext/clipsruby/moduldef.c +817 -0
  219. data/ext/clipsruby/moduldef.h +271 -0
  220. data/ext/clipsruby/modulpsr.c +1150 -0
  221. data/ext/clipsruby/modulpsr.h +69 -0
  222. data/ext/clipsruby/modulutl.c +1036 -0
  223. data/ext/clipsruby/modulutl.h +84 -0
  224. data/ext/clipsruby/msgcom.c +1221 -0
  225. data/ext/clipsruby/msgcom.h +125 -0
  226. data/ext/clipsruby/msgfun.c +1076 -0
  227. data/ext/clipsruby/msgfun.h +118 -0
  228. data/ext/clipsruby/msgpass.c +1441 -0
  229. data/ext/clipsruby/msgpass.h +103 -0
  230. data/ext/clipsruby/msgpsr.c +698 -0
  231. data/ext/clipsruby/msgpsr.h +73 -0
  232. data/ext/clipsruby/multifld.c +1404 -0
  233. data/ext/clipsruby/multifld.h +130 -0
  234. data/ext/clipsruby/multifun.c +2182 -0
  235. data/ext/clipsruby/multifun.h +102 -0
  236. data/ext/clipsruby/network.h +142 -0
  237. data/ext/clipsruby/objbin.c +1522 -0
  238. data/ext/clipsruby/objbin.h +79 -0
  239. data/ext/clipsruby/objcmp.c +1507 -0
  240. data/ext/clipsruby/objcmp.h +71 -0
  241. data/ext/clipsruby/object.h +260 -0
  242. data/ext/clipsruby/objrtbin.c +701 -0
  243. data/ext/clipsruby/objrtbin.h +79 -0
  244. data/ext/clipsruby/objrtbld.c +2393 -0
  245. data/ext/clipsruby/objrtbld.h +66 -0
  246. data/ext/clipsruby/objrtcmp.c +734 -0
  247. data/ext/clipsruby/objrtcmp.h +66 -0
  248. data/ext/clipsruby/objrtfnx.c +1330 -0
  249. data/ext/clipsruby/objrtfnx.h +222 -0
  250. data/ext/clipsruby/objrtgen.c +736 -0
  251. data/ext/clipsruby/objrtgen.h +63 -0
  252. data/ext/clipsruby/objrtmch.c +1524 -0
  253. data/ext/clipsruby/objrtmch.h +160 -0
  254. data/ext/clipsruby/parsefun.c +415 -0
  255. data/ext/clipsruby/parsefun.h +67 -0
  256. data/ext/clipsruby/pattern.c +1265 -0
  257. data/ext/clipsruby/pattern.h +163 -0
  258. data/ext/clipsruby/pprint.c +328 -0
  259. data/ext/clipsruby/pprint.h +79 -0
  260. data/ext/clipsruby/prccode.c +1478 -0
  261. data/ext/clipsruby/prccode.h +145 -0
  262. data/ext/clipsruby/prcdrfun.c +640 -0
  263. data/ext/clipsruby/prcdrfun.h +95 -0
  264. data/ext/clipsruby/prcdrpsr.c +1068 -0
  265. data/ext/clipsruby/prcdrpsr.h +79 -0
  266. data/ext/clipsruby/prdctfun.c +869 -0
  267. data/ext/clipsruby/prdctfun.h +77 -0
  268. data/ext/clipsruby/prntutil.c +878 -0
  269. data/ext/clipsruby/prntutil.h +125 -0
  270. data/ext/clipsruby/proflfun.c +827 -0
  271. data/ext/clipsruby/proflfun.h +118 -0
  272. data/ext/clipsruby/reorder.c +2082 -0
  273. data/ext/clipsruby/reorder.h +172 -0
  274. data/ext/clipsruby/reteutil.c +1732 -0
  275. data/ext/clipsruby/reteutil.h +111 -0
  276. data/ext/clipsruby/retract.c +710 -0
  277. data/ext/clipsruby/retract.h +74 -0
  278. data/ext/clipsruby/router.c +737 -0
  279. data/ext/clipsruby/router.h +147 -0
  280. data/ext/clipsruby/rulebin.c +1136 -0
  281. data/ext/clipsruby/rulebin.h +153 -0
  282. data/ext/clipsruby/rulebld.c +1328 -0
  283. data/ext/clipsruby/rulebld.h +62 -0
  284. data/ext/clipsruby/rulebsc.c +517 -0
  285. data/ext/clipsruby/rulebsc.h +91 -0
  286. data/ext/clipsruby/rulecmp.c +733 -0
  287. data/ext/clipsruby/rulecmp.h +63 -0
  288. data/ext/clipsruby/rulecom.c +1583 -0
  289. data/ext/clipsruby/rulecom.h +116 -0
  290. data/ext/clipsruby/rulecstr.c +892 -0
  291. data/ext/clipsruby/rulecstr.h +53 -0
  292. data/ext/clipsruby/ruledef.c +559 -0
  293. data/ext/clipsruby/ruledef.h +179 -0
  294. data/ext/clipsruby/ruledlt.c +599 -0
  295. data/ext/clipsruby/ruledlt.h +58 -0
  296. data/ext/clipsruby/rulelhs.c +1216 -0
  297. data/ext/clipsruby/rulelhs.h +52 -0
  298. data/ext/clipsruby/rulepsr.c +1073 -0
  299. data/ext/clipsruby/rulepsr.h +61 -0
  300. data/ext/clipsruby/scanner.c +856 -0
  301. data/ext/clipsruby/scanner.h +112 -0
  302. data/ext/clipsruby/setup.h +488 -0
  303. data/ext/clipsruby/sortfun.c +433 -0
  304. data/ext/clipsruby/sortfun.h +55 -0
  305. data/ext/clipsruby/strngfun.c +1173 -0
  306. data/ext/clipsruby/strngfun.h +96 -0
  307. data/ext/clipsruby/strngrtr.c +523 -0
  308. data/ext/clipsruby/strngrtr.h +97 -0
  309. data/ext/clipsruby/symblbin.c +648 -0
  310. data/ext/clipsruby/symblbin.h +64 -0
  311. data/ext/clipsruby/symblcmp.c +893 -0
  312. data/ext/clipsruby/symblcmp.h +61 -0
  313. data/ext/clipsruby/symbol.c +1961 -0
  314. data/ext/clipsruby/symbol.h +243 -0
  315. data/ext/clipsruby/sysdep.c +894 -0
  316. data/ext/clipsruby/sysdep.h +164 -0
  317. data/ext/clipsruby/textpro.c +1388 -0
  318. data/ext/clipsruby/textpro.h +77 -0
  319. data/ext/clipsruby/tmpltbin.c +609 -0
  320. data/ext/clipsruby/tmpltbin.h +108 -0
  321. data/ext/clipsruby/tmpltbsc.c +327 -0
  322. data/ext/clipsruby/tmpltbsc.h +87 -0
  323. data/ext/clipsruby/tmpltcmp.c +450 -0
  324. data/ext/clipsruby/tmpltcmp.h +57 -0
  325. data/ext/clipsruby/tmpltdef.c +584 -0
  326. data/ext/clipsruby/tmpltdef.h +155 -0
  327. data/ext/clipsruby/tmpltfun.c +2477 -0
  328. data/ext/clipsruby/tmpltfun.h +122 -0
  329. data/ext/clipsruby/tmpltlhs.c +379 -0
  330. data/ext/clipsruby/tmpltlhs.h +50 -0
  331. data/ext/clipsruby/tmpltpsr.c +819 -0
  332. data/ext/clipsruby/tmpltpsr.h +59 -0
  333. data/ext/clipsruby/tmpltrhs.c +595 -0
  334. data/ext/clipsruby/tmpltrhs.h +55 -0
  335. data/ext/clipsruby/tmpltutl.c +637 -0
  336. data/ext/clipsruby/tmpltutl.h +82 -0
  337. data/ext/clipsruby/userdata.c +156 -0
  338. data/ext/clipsruby/userdata.h +72 -0
  339. data/ext/clipsruby/userfunctions.c +70 -0
  340. data/ext/clipsruby/usrsetup.h +7 -0
  341. data/ext/clipsruby/utility.c +1594 -0
  342. data/ext/clipsruby/utility.h +250 -0
  343. data/ext/clipsruby/watch.c +865 -0
  344. data/ext/clipsruby/watch.h +124 -0
  345. data/lib/clipsruby.rb +1 -0
  346. metadata +388 -0
@@ -0,0 +1,1961 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.40 11/20/17 */
5
+ /* */
6
+ /* SYMBOL MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Manages the atomic data value hash tables for */
11
+ /* storing symbols, integers, floats, and bit maps. */
12
+ /* Contains routines for adding entries, examining the */
13
+ /* hash tables, and performing garbage collection to */
14
+ /* remove entries no longer in use. */
15
+ /* */
16
+ /* Principal Programmer(s): */
17
+ /* Gary D. Riley */
18
+ /* */
19
+ /* Contributing Programmer(s): */
20
+ /* Brian L. Dantes */
21
+ /* */
22
+ /* Revision History: */
23
+ /* */
24
+ /* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
25
+ /* */
26
+ /* 6.24: CLIPS crashing on AMD64 processor in the */
27
+ /* function used to generate a hash value for */
28
+ /* integers. DR0871 */
29
+ /* */
30
+ /* Support for run-time programs directly passing */
31
+ /* the hash tables for initialization. */
32
+ /* */
33
+ /* Corrected code generating compilation */
34
+ /* warnings. */
35
+ /* */
36
+ /* 6.30: Changed integer type/precision. */
37
+ /* */
38
+ /* Removed conditional code for unsupported */
39
+ /* compilers/operating systems (IBM_MCW, */
40
+ /* MAC_MCW, and IBM_TBC). */
41
+ /* */
42
+ /* Support for hashing EXTERNAL_ADDRESS_TYPE */
43
+ /* data type. */
44
+ /* */
45
+ /* Support for long long integers. */
46
+ /* */
47
+ /* Changed garbage collection algorithm. */
48
+ /* */
49
+ /* Used genstrcpy instead of strcpy. */
50
+ /* */
51
+ /* Added support for external address hash table */
52
+ /* and subtyping. */
53
+ /* */
54
+ /* Added const qualifiers to remove C++ */
55
+ /* deprecation warnings. */
56
+ /* */
57
+ /* Converted API macros to function calls. */
58
+ /* */
59
+ /* 6.40: Refactored code to reduce header dependencies */
60
+ /* in sysdep.c. */
61
+ /* */
62
+ /* Pragma once and other inclusion changes. */
63
+ /* */
64
+ /* Added support for booleans with <stdbool.h>. */
65
+ /* */
66
+ /* Removed use of void pointers for specific */
67
+ /* data structures. */
68
+ /* */
69
+ /* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
70
+ /* */
71
+ /*************************************************************/
72
+
73
+ #include <stdio.h>
74
+ #include <stdlib.h>
75
+ #include <string.h>
76
+
77
+ #include "setup.h"
78
+
79
+ #include "argacces.h"
80
+ #include "constant.h"
81
+ #include "envrnmnt.h"
82
+ #include "memalloc.h"
83
+ #include "multifld.h"
84
+ #include "prntutil.h"
85
+ #include "router.h"
86
+ #include "sysdep.h"
87
+ #include "utility.h"
88
+
89
+ #include "symbol.h"
90
+
91
+ /***************/
92
+ /* DEFINITIONS */
93
+ /***************/
94
+
95
+ #define FALSE_STRING "FALSE"
96
+ #define TRUE_STRING "TRUE"
97
+ #define POSITIVE_INFINITY_STRING "+oo"
98
+ #define NEGATIVE_INFINITY_STRING "-oo"
99
+
100
+ #define AVERAGE_STRING_SIZE 10
101
+ #define AVERAGE_BITMAP_SIZE sizeof(long)
102
+ #define NUMBER_OF_LONGS_FOR_HASH 25
103
+
104
+ /***************************************/
105
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
106
+ /***************************************/
107
+
108
+ static void RemoveHashNode(Environment *,GENERIC_HN *,GENERIC_HN **,int,int);
109
+ static void AddEphemeralHashNode(Environment *,GENERIC_HN *,struct ephemeron **,
110
+ int,int,bool);
111
+ static void RemoveEphemeralHashNodes(Environment *,struct ephemeron **,
112
+ GENERIC_HN **,
113
+ int,int,int);
114
+ static const char *StringWithinString(const char *,const char *);
115
+ static size_t CommonPrefixLength(const char *,const char *);
116
+ static void DeallocateSymbolData(Environment *);
117
+
118
+ /*******************************************************/
119
+ /* InitializeAtomTables: Initializes the SymbolTable, */
120
+ /* IntegerTable, and FloatTable. It also initializes */
121
+ /* the TrueSymbol and FalseSymbol. */
122
+ /*******************************************************/
123
+ void InitializeAtomTables(
124
+ Environment *theEnv,
125
+ CLIPSLexeme **symbolTable,
126
+ CLIPSFloat **floatTable,
127
+ CLIPSInteger **integerTable,
128
+ CLIPSBitMap **bitmapTable,
129
+ CLIPSExternalAddress **externalAddressTable)
130
+ {
131
+ #if MAC_XCD
132
+ #pragma unused(symbolTable)
133
+ #pragma unused(floatTable)
134
+ #pragma unused(integerTable)
135
+ #pragma unused(bitmapTable)
136
+ #pragma unused(externalAddressTable)
137
+ #endif
138
+ unsigned long i;
139
+
140
+ AllocateEnvironmentData(theEnv,SYMBOL_DATA,sizeof(struct symbolData),DeallocateSymbolData);
141
+
142
+ #if ! RUN_TIME
143
+ /*=========================*/
144
+ /* Create the hash tables. */
145
+ /*=========================*/
146
+
147
+ SymbolData(theEnv)->SymbolTable = (CLIPSLexeme **)
148
+ gm2(theEnv,sizeof (CLIPSLexeme *) * SYMBOL_HASH_SIZE);
149
+
150
+ SymbolData(theEnv)->FloatTable = (CLIPSFloat **)
151
+ gm2(theEnv,sizeof (CLIPSFloat *) * FLOAT_HASH_SIZE);
152
+
153
+ SymbolData(theEnv)->IntegerTable = (CLIPSInteger **)
154
+ gm2(theEnv,sizeof (CLIPSInteger *) * INTEGER_HASH_SIZE);
155
+
156
+ SymbolData(theEnv)->BitMapTable = (CLIPSBitMap **)
157
+ gm2(theEnv,sizeof (CLIPSBitMap *) * BITMAP_HASH_SIZE);
158
+
159
+ SymbolData(theEnv)->ExternalAddressTable = (CLIPSExternalAddress **)
160
+ gm2(theEnv,sizeof (CLIPSExternalAddress *) * EXTERNAL_ADDRESS_HASH_SIZE);
161
+
162
+ /*===================================================*/
163
+ /* Initialize all of the hash table entries to NULL. */
164
+ /*===================================================*/
165
+
166
+ for (i = 0; i < SYMBOL_HASH_SIZE; i++) SymbolData(theEnv)->SymbolTable[i] = NULL;
167
+ for (i = 0; i < FLOAT_HASH_SIZE; i++) SymbolData(theEnv)->FloatTable[i] = NULL;
168
+ for (i = 0; i < INTEGER_HASH_SIZE; i++) SymbolData(theEnv)->IntegerTable[i] = NULL;
169
+ for (i = 0; i < BITMAP_HASH_SIZE; i++) SymbolData(theEnv)->BitMapTable[i] = NULL;
170
+ for (i = 0; i < EXTERNAL_ADDRESS_HASH_SIZE; i++) SymbolData(theEnv)->ExternalAddressTable[i] = NULL;
171
+
172
+ /*========================*/
173
+ /* Predefine some values. */
174
+ /*========================*/
175
+
176
+ theEnv->TrueSymbol = AddSymbol(theEnv,TRUE_STRING,SYMBOL_TYPE);
177
+ IncrementLexemeCount(TrueSymbol(theEnv));
178
+ theEnv->FalseSymbol = AddSymbol(theEnv,FALSE_STRING,SYMBOL_TYPE);
179
+ IncrementLexemeCount(FalseSymbol(theEnv));
180
+ SymbolData(theEnv)->PositiveInfinity = AddSymbol(theEnv,POSITIVE_INFINITY_STRING,SYMBOL_TYPE);
181
+ IncrementLexemeCount(SymbolData(theEnv)->PositiveInfinity);
182
+ SymbolData(theEnv)->NegativeInfinity = AddSymbol(theEnv,NEGATIVE_INFINITY_STRING,SYMBOL_TYPE);
183
+ IncrementLexemeCount(SymbolData(theEnv)->NegativeInfinity);
184
+ SymbolData(theEnv)->Zero = CreateInteger(theEnv,0LL);
185
+ IncrementIntegerCount(SymbolData(theEnv)->Zero);
186
+ #else
187
+ SetSymbolTable(theEnv,symbolTable);
188
+ SetFloatTable(theEnv,floatTable);
189
+ SetIntegerTable(theEnv,integerTable);
190
+ SetBitMapTable(theEnv,bitmapTable);
191
+
192
+ SymbolData(theEnv)->ExternalAddressTable = (CLIPSExternalAddress **)
193
+ gm2(theEnv,sizeof (CLIPSExternalAddress *) * EXTERNAL_ADDRESS_HASH_SIZE);
194
+
195
+ for (i = 0; i < EXTERNAL_ADDRESS_HASH_SIZE; i++) SymbolData(theEnv)->ExternalAddressTable[i] = NULL;
196
+
197
+ theEnv->TrueSymbol = FindSymbolHN(theEnv,TRUE_STRING,SYMBOL_BIT);
198
+ theEnv->FalseSymbol = FindSymbolHN(theEnv,FALSE_STRING,SYMBOL_BIT);
199
+ #endif
200
+
201
+ theEnv->VoidConstant = get_struct(theEnv,clipsVoid);
202
+ theEnv->VoidConstant->header.type = VOID_TYPE;
203
+ }
204
+
205
+ /*************************************************/
206
+ /* DeallocateSymbolData: Deallocates environment */
207
+ /* data for symbols. */
208
+ /*************************************************/
209
+ static void DeallocateSymbolData(
210
+ Environment *theEnv)
211
+ {
212
+ int i;
213
+ CLIPSLexeme *shPtr, *nextSHPtr;
214
+ CLIPSInteger *ihPtr, *nextIHPtr;
215
+ CLIPSFloat *fhPtr, *nextFHPtr;
216
+ CLIPSBitMap *bmhPtr, *nextBMHPtr;
217
+ CLIPSExternalAddress *eahPtr, *nextEAHPtr;
218
+
219
+ if ((SymbolData(theEnv)->SymbolTable == NULL) ||
220
+ (SymbolData(theEnv)->FloatTable == NULL) ||
221
+ (SymbolData(theEnv)->IntegerTable == NULL) ||
222
+ (SymbolData(theEnv)->BitMapTable == NULL) ||
223
+ (SymbolData(theEnv)->ExternalAddressTable == NULL))
224
+ { return; }
225
+
226
+ genfree(theEnv,theEnv->VoidConstant,sizeof(TypeHeader));
227
+
228
+ for (i = 0; i < SYMBOL_HASH_SIZE; i++)
229
+ {
230
+ shPtr = SymbolData(theEnv)->SymbolTable[i];
231
+
232
+ while (shPtr != NULL)
233
+ {
234
+ nextSHPtr = shPtr->next;
235
+ if (! shPtr->permanent)
236
+ {
237
+ rm(theEnv,(void *) shPtr->contents,strlen(shPtr->contents)+1);
238
+ rtn_struct(theEnv,clipsLexeme,shPtr);
239
+ }
240
+ shPtr = nextSHPtr;
241
+ }
242
+ }
243
+
244
+ for (i = 0; i < FLOAT_HASH_SIZE; i++)
245
+ {
246
+ fhPtr = SymbolData(theEnv)->FloatTable[i];
247
+
248
+ while (fhPtr != NULL)
249
+ {
250
+ nextFHPtr = fhPtr->next;
251
+ if (! fhPtr->permanent)
252
+ { rtn_struct(theEnv,clipsFloat,fhPtr); }
253
+ fhPtr = nextFHPtr;
254
+ }
255
+ }
256
+
257
+ for (i = 0; i < INTEGER_HASH_SIZE; i++)
258
+ {
259
+ ihPtr = SymbolData(theEnv)->IntegerTable[i];
260
+
261
+ while (ihPtr != NULL)
262
+ {
263
+ nextIHPtr = ihPtr->next;
264
+ if (! ihPtr->permanent)
265
+ { rtn_struct(theEnv,clipsInteger,ihPtr); }
266
+ ihPtr = nextIHPtr;
267
+ }
268
+ }
269
+
270
+ for (i = 0; i < BITMAP_HASH_SIZE; i++)
271
+ {
272
+ bmhPtr = SymbolData(theEnv)->BitMapTable[i];
273
+
274
+ while (bmhPtr != NULL)
275
+ {
276
+ nextBMHPtr = bmhPtr->next;
277
+ if (! bmhPtr->permanent)
278
+ {
279
+ rm(theEnv,(void *) bmhPtr->contents,bmhPtr->size);
280
+ rtn_struct(theEnv,clipsBitMap,bmhPtr);
281
+ }
282
+ bmhPtr = nextBMHPtr;
283
+ }
284
+ }
285
+
286
+ for (i = 0; i < EXTERNAL_ADDRESS_HASH_SIZE; i++)
287
+ {
288
+ eahPtr = SymbolData(theEnv)->ExternalAddressTable[i];
289
+
290
+ while (eahPtr != NULL)
291
+ {
292
+ nextEAHPtr = eahPtr->next;
293
+ if (! eahPtr->permanent)
294
+ {
295
+ rtn_struct(theEnv,clipsExternalAddress,eahPtr);
296
+ }
297
+ eahPtr = nextEAHPtr;
298
+ }
299
+ }
300
+
301
+ /*================================*/
302
+ /* Remove the symbol hash tables. */
303
+ /*================================*/
304
+
305
+ #if ! RUN_TIME
306
+ rm(theEnv,SymbolData(theEnv)->SymbolTable,sizeof (CLIPSLexeme *) * SYMBOL_HASH_SIZE);
307
+
308
+ genfree(theEnv,SymbolData(theEnv)->FloatTable,sizeof (CLIPSFloat *) * FLOAT_HASH_SIZE);
309
+
310
+ genfree(theEnv,SymbolData(theEnv)->IntegerTable,sizeof (CLIPSInteger *) * INTEGER_HASH_SIZE);
311
+
312
+ genfree(theEnv,SymbolData(theEnv)->BitMapTable,sizeof (CLIPSBitMap *) * BITMAP_HASH_SIZE);
313
+ #endif
314
+
315
+ genfree(theEnv,SymbolData(theEnv)->ExternalAddressTable,sizeof (CLIPSExternalAddress *) * EXTERNAL_ADDRESS_HASH_SIZE);
316
+
317
+ /*==============================*/
318
+ /* Remove binary symbol tables. */
319
+ /*==============================*/
320
+
321
+ #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE || BLOAD_INSTANCES || BSAVE_INSTANCES
322
+ if (SymbolData(theEnv)->SymbolArray != NULL)
323
+ rm(theEnv,SymbolData(theEnv)->SymbolArray,sizeof(CLIPSLexeme *) * SymbolData(theEnv)->NumberOfSymbols);
324
+ if (SymbolData(theEnv)->FloatArray != NULL)
325
+ rm(theEnv,SymbolData(theEnv)->FloatArray,sizeof(CLIPSFloat *) * SymbolData(theEnv)->NumberOfFloats);
326
+ if (SymbolData(theEnv)->IntegerArray != NULL)
327
+ rm(theEnv,SymbolData(theEnv)->IntegerArray,sizeof(CLIPSInteger *) * SymbolData(theEnv)->NumberOfIntegers);
328
+ if (SymbolData(theEnv)->BitMapArray != NULL)
329
+ rm(theEnv,SymbolData(theEnv)->BitMapArray,sizeof(CLIPSBitMap *) * SymbolData(theEnv)->NumberOfBitMaps);
330
+ #endif
331
+ }
332
+
333
+ /*****************/
334
+ /* CreateBoolean */
335
+ /*****************/
336
+ CLIPSLexeme *CreateBoolean(
337
+ Environment *theEnv,
338
+ bool theValue)
339
+ {
340
+ if (theValue)
341
+ { return TrueSymbol(theEnv); }
342
+ else
343
+ { return FalseSymbol(theEnv); }
344
+ }
345
+
346
+ /****************/
347
+ /* CreateSymbol */
348
+ /****************/
349
+ CLIPSLexeme *CreateSymbol(
350
+ Environment *theEnv,
351
+ const char *str)
352
+ {
353
+ return AddSymbol(theEnv,str,SYMBOL_TYPE);
354
+ }
355
+
356
+ /****************/
357
+ /* CreateString */
358
+ /****************/
359
+ CLIPSLexeme *CreateString(
360
+ Environment *theEnv,
361
+ const char *str)
362
+ {
363
+ return AddSymbol(theEnv,str,STRING_TYPE);
364
+ }
365
+
366
+ /**********************/
367
+ /* CreateInstanceName */
368
+ /**********************/
369
+ CLIPSLexeme *CreateInstanceName(
370
+ Environment *theEnv,
371
+ const char *str)
372
+ {
373
+ return AddSymbol(theEnv,str,INSTANCE_NAME_TYPE);
374
+ }
375
+
376
+ /********************************************************************/
377
+ /* AddSymbol: Searches for the string in the symbol table. If the */
378
+ /* string is already in the symbol table, then the address of the */
379
+ /* string's location in the symbol table is returned. Otherwise, */
380
+ /* the string is added to the symbol table and then the address */
381
+ /* of the string's location in the symbol table is returned. */
382
+ /********************************************************************/
383
+ CLIPSLexeme *AddSymbol(
384
+ Environment *theEnv,
385
+ const char *str,
386
+ unsigned short theType)
387
+ {
388
+ size_t tally;
389
+ size_t length;
390
+ CLIPSLexeme *past = NULL, *peek;
391
+ char *buffer;
392
+
393
+ /*====================================*/
394
+ /* Get the hash value for the string. */
395
+ /*====================================*/
396
+
397
+ if (str == NULL)
398
+ {
399
+ SystemError(theEnv,"SYMBOL",1);
400
+ ExitRouter(theEnv,EXIT_FAILURE);
401
+ }
402
+
403
+ tally = HashSymbol(str,SYMBOL_HASH_SIZE);
404
+ peek = SymbolData(theEnv)->SymbolTable[tally];
405
+
406
+ /*==================================================*/
407
+ /* Search for the string in the list of entries for */
408
+ /* this symbol table location. If the string is */
409
+ /* found, then return the address of the string. */
410
+ /*==================================================*/
411
+
412
+ while (peek != NULL)
413
+ {
414
+ if ((peek->header.type == theType) &&
415
+ (strcmp(str,peek->contents) == 0))
416
+ { return peek; }
417
+ past = peek;
418
+ peek = peek->next;
419
+ }
420
+
421
+ /*==================================================*/
422
+ /* Add the string at the end of the list of entries */
423
+ /* for this symbol table location. */
424
+ /*==================================================*/
425
+
426
+ peek = get_struct(theEnv,clipsLexeme);
427
+
428
+ if (past == NULL) SymbolData(theEnv)->SymbolTable[tally] = peek;
429
+ else past->next = peek;
430
+
431
+ length = strlen(str) + 1;
432
+ buffer = (char *) gm2(theEnv,length);
433
+ genstrcpy(buffer,str);
434
+ peek->contents = buffer;
435
+ peek->next = NULL;
436
+ peek->bucket = (unsigned int) tally;
437
+ peek->count = 0;
438
+ peek->permanent = false;
439
+ peek->header.type = theType;
440
+
441
+ /*================================================*/
442
+ /* Add the string to the list of ephemeral items. */
443
+ /*================================================*/
444
+
445
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralSymbolList,
446
+ sizeof(CLIPSLexeme),AVERAGE_STRING_SIZE,true);
447
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
448
+
449
+ /*===================================*/
450
+ /* Return the address of the symbol. */
451
+ /*===================================*/
452
+
453
+ return peek;
454
+ }
455
+
456
+ /*****************************************************************/
457
+ /* FindSymbolHN: Searches for the string in the symbol table and */
458
+ /* returns a pointer to it if found, otherwise returns NULL. */
459
+ /*****************************************************************/
460
+ CLIPSLexeme *FindSymbolHN(
461
+ Environment *theEnv,
462
+ const char *str,
463
+ unsigned short expectedType)
464
+ {
465
+ size_t tally;
466
+ CLIPSLexeme *peek;
467
+
468
+ tally = HashSymbol(str,SYMBOL_HASH_SIZE);
469
+
470
+ for (peek = SymbolData(theEnv)->SymbolTable[tally];
471
+ peek != NULL;
472
+ peek = peek->next)
473
+ {
474
+ if (((1 << peek->header.type) & expectedType) &&
475
+ (strcmp(str,peek->contents) == 0))
476
+ { return peek; }
477
+ }
478
+
479
+ return NULL;
480
+ }
481
+
482
+ /******************************************************************/
483
+ /* CreateFloat: Searches for the double in the hash table. If the */
484
+ /* double is already in the hash table, then the address of the */
485
+ /* double is returned. Otherwise, the double is hashed into the */
486
+ /* table and the address of the double is also returned. */
487
+ /******************************************************************/
488
+ CLIPSFloat *CreateFloat(
489
+ Environment *theEnv,
490
+ double number)
491
+ {
492
+ size_t tally;
493
+ CLIPSFloat *past = NULL, *peek;
494
+
495
+ /*====================================*/
496
+ /* Get the hash value for the double. */
497
+ /*====================================*/
498
+
499
+ tally = HashFloat(number,FLOAT_HASH_SIZE);
500
+ peek = SymbolData(theEnv)->FloatTable[tally];
501
+
502
+ /*==================================================*/
503
+ /* Search for the double in the list of entries for */
504
+ /* this hash location. If the double is found, */
505
+ /* then return the address of the double. */
506
+ /*==================================================*/
507
+
508
+ while (peek != NULL)
509
+ {
510
+ if (number == peek->contents)
511
+ { return peek; }
512
+ past = peek;
513
+ peek = peek->next;
514
+ }
515
+
516
+ /*=================================================*/
517
+ /* Add the float at the end of the list of entries */
518
+ /* for this hash location. */
519
+ /*=================================================*/
520
+
521
+ peek = get_struct(theEnv,clipsFloat);
522
+
523
+ if (past == NULL) SymbolData(theEnv)->FloatTable[tally] = peek;
524
+ else past->next = peek;
525
+
526
+ peek->contents = number;
527
+ peek->next = NULL;
528
+ peek->bucket = (unsigned int) tally;
529
+ peek->count = 0;
530
+ peek->permanent = false;
531
+ peek->header.type = FLOAT_TYPE;
532
+
533
+ /*===============================================*/
534
+ /* Add the float to the list of ephemeral items. */
535
+ /*===============================================*/
536
+
537
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralFloatList,
538
+ sizeof(CLIPSFloat),0,true);
539
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
540
+
541
+ /*==================================*/
542
+ /* Return the address of the float. */
543
+ /*==================================*/
544
+
545
+ return peek;
546
+ }
547
+
548
+ /****************************************************************/
549
+ /* CreateInteger: Searches for the long in the hash table. If */
550
+ /* the long is already in the hash table, then the address of */
551
+ /* the long is returned. Otherwise, the long is hashed into */
552
+ /* the table and the address of the long is also returned. */
553
+ /****************************************************************/
554
+ CLIPSInteger *CreateInteger(
555
+ Environment *theEnv,
556
+ long long number)
557
+ {
558
+ size_t tally;
559
+ CLIPSInteger *past = NULL, *peek;
560
+
561
+ /*==================================*/
562
+ /* Get the hash value for the long. */
563
+ /*==================================*/
564
+
565
+ tally = HashInteger(number,INTEGER_HASH_SIZE);
566
+ peek = SymbolData(theEnv)->IntegerTable[tally];
567
+
568
+ /*================================================*/
569
+ /* Search for the long in the list of entries for */
570
+ /* this hash location. If the long is found, then */
571
+ /* return the address of the long. */
572
+ /*================================================*/
573
+
574
+ while (peek != NULL)
575
+ {
576
+ if (number == peek->contents)
577
+ { return peek; }
578
+ past = peek;
579
+ peek = peek->next;
580
+ }
581
+
582
+ /*================================================*/
583
+ /* Add the long at the end of the list of entries */
584
+ /* for this hash location. */
585
+ /*================================================*/
586
+
587
+ peek = get_struct(theEnv,clipsInteger);
588
+ if (past == NULL) SymbolData(theEnv)->IntegerTable[tally] = peek;
589
+ else past->next = peek;
590
+
591
+ peek->contents = number;
592
+ peek->next = NULL;
593
+ peek->bucket = (unsigned int) tally;
594
+ peek->count = 0;
595
+ peek->permanent = false;
596
+ peek->header.type = INTEGER_TYPE;
597
+
598
+ /*=================================================*/
599
+ /* Add the integer to the list of ephemeral items. */
600
+ /*=================================================*/
601
+
602
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralIntegerList,
603
+ sizeof(CLIPSInteger),0,true);
604
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
605
+
606
+ /*====================================*/
607
+ /* Return the address of the integer. */
608
+ /*====================================*/
609
+
610
+ return peek;
611
+ }
612
+
613
+ /*****************************************************************/
614
+ /* FindLongHN: Searches for the integer in the integer table and */
615
+ /* returns a pointer to it if found, otherwise returns NULL. */
616
+ /*****************************************************************/
617
+ CLIPSInteger *FindLongHN(
618
+ Environment *theEnv,
619
+ long long theLong)
620
+ {
621
+ size_t tally;
622
+ CLIPSInteger *peek;
623
+
624
+ tally = HashInteger(theLong,INTEGER_HASH_SIZE);
625
+
626
+ for (peek = SymbolData(theEnv)->IntegerTable[tally];
627
+ peek != NULL;
628
+ peek = peek->next)
629
+ { if (peek->contents == theLong) return(peek); }
630
+
631
+ return NULL;
632
+ }
633
+
634
+ /******************************************************************/
635
+ /* AddBitMap: Searches for the bitmap in the hash table. If the */
636
+ /* bitmap is already in the hash table, then the address of the */
637
+ /* bitmap is returned. Otherwise, the bitmap is hashed into the */
638
+ /* table and the address of the bitmap is also returned. */
639
+ /******************************************************************/
640
+ void *AddBitMap(
641
+ Environment *theEnv,
642
+ void *vTheBitMap,
643
+ unsigned short size)
644
+ {
645
+ char *theBitMap = (char *) vTheBitMap;
646
+ size_t tally;
647
+ unsigned short i;
648
+ CLIPSBitMap *past = NULL, *peek;
649
+ char *buffer;
650
+
651
+ /*====================================*/
652
+ /* Get the hash value for the bitmap. */
653
+ /*====================================*/
654
+
655
+ if (theBitMap == NULL)
656
+ {
657
+ SystemError(theEnv,"SYMBOL",2);
658
+ ExitRouter(theEnv,EXIT_FAILURE);
659
+ }
660
+
661
+ tally = HashBitMap(theBitMap,BITMAP_HASH_SIZE,size);
662
+ peek = SymbolData(theEnv)->BitMapTable[tally];
663
+
664
+ /*==================================================*/
665
+ /* Search for the bitmap in the list of entries for */
666
+ /* this hash table location. If the bitmap is */
667
+ /* found, then return the address of the bitmap. */
668
+ /*==================================================*/
669
+
670
+ while (peek != NULL)
671
+ {
672
+ if (peek->size == size)
673
+ {
674
+ for (i = 0; i < size ; i++)
675
+ { if (peek->contents[i] != theBitMap[i]) break; }
676
+
677
+ if (i == size) return((void *) peek);
678
+ }
679
+
680
+ past = peek;
681
+ peek = peek->next;
682
+ }
683
+
684
+ /*==================================================*/
685
+ /* Add the bitmap at the end of the list of entries */
686
+ /* for this hash table location. Return the */
687
+ /*==================================================*/
688
+
689
+ peek = get_struct(theEnv,clipsBitMap);
690
+ if (past == NULL) SymbolData(theEnv)->BitMapTable[tally] = peek;
691
+ else past->next = peek;
692
+
693
+ buffer = (char *) gm2(theEnv,size);
694
+ for (i = 0; i < size ; i++) buffer[i] = theBitMap[i];
695
+ peek->contents = buffer;
696
+ peek->next = NULL;
697
+ peek->bucket = (unsigned int) tally;
698
+ peek->count = 0;
699
+ peek->permanent = false;
700
+ peek->size = size;
701
+ peek->header.type = BITMAP_TYPE;
702
+
703
+ /*================================================*/
704
+ /* Add the bitmap to the list of ephemeral items. */
705
+ /*================================================*/
706
+
707
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralBitMapList,
708
+ sizeof(CLIPSBitMap),sizeof(long),true);
709
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
710
+
711
+ /*===================================*/
712
+ /* Return the address of the bitmap. */
713
+ /*===================================*/
714
+
715
+ return((void *) peek);
716
+ }
717
+
718
+ /***********************************************/
719
+ /* CreateCExternalAddress: Creates an external */
720
+ /* address for a C pointer. */
721
+ /***********************************************/
722
+ CLIPSExternalAddress *CreateCExternalAddress(
723
+ Environment *theEnv,
724
+ void *theExternalAddress)
725
+ {
726
+ return CreateExternalAddress(theEnv,theExternalAddress,C_POINTER_EXTERNAL_ADDRESS);
727
+ }
728
+
729
+ /*******************************************************************/
730
+ /* CreateExternalAddress: Searches for the external address in the */
731
+ /* hash table. If the external address is already in the hash */
732
+ /* table, then the address of the external address is returned. */
733
+ /* Otherwise, the external address is hashed into the table and */
734
+ /* the address of the external address is also returned. */
735
+ /*******************************************************************/
736
+ CLIPSExternalAddress *CreateExternalAddress(
737
+ Environment *theEnv,
738
+ void *theExternalAddress,
739
+ unsigned short theType)
740
+ {
741
+ size_t tally;
742
+ CLIPSExternalAddress *past = NULL, *peek;
743
+
744
+ /*====================================*/
745
+ /* Get the hash value for the bitmap. */
746
+ /*====================================*/
747
+
748
+ tally = HashExternalAddress(theExternalAddress,EXTERNAL_ADDRESS_HASH_SIZE);
749
+
750
+ peek = SymbolData(theEnv)->ExternalAddressTable[tally];
751
+
752
+ /*=============================================================*/
753
+ /* Search for the external address in the list of entries for */
754
+ /* this hash table location. If the external addressis found, */
755
+ /* then return the address of the external address. */
756
+ /*=============================================================*/
757
+
758
+ while (peek != NULL)
759
+ {
760
+ if ((peek->type == theType) &&
761
+ (peek->contents == theExternalAddress))
762
+ { return peek; }
763
+
764
+ past = peek;
765
+ peek = peek->next;
766
+ }
767
+
768
+ /*=================================================*/
769
+ /* Add the external address at the end of the list */
770
+ /* of entries for this hash table location. */
771
+ /*=================================================*/
772
+
773
+ peek = get_struct(theEnv,clipsExternalAddress);
774
+ if (past == NULL) SymbolData(theEnv)->ExternalAddressTable[tally] = peek;
775
+ else past->next = peek;
776
+
777
+ peek->contents = theExternalAddress;
778
+ peek->type = theType;
779
+ peek->next = NULL;
780
+ peek->bucket = (unsigned int) tally;
781
+ peek->count = 0;
782
+ peek->permanent = false;
783
+ peek->header.type = EXTERNAL_ADDRESS_TYPE;
784
+
785
+ /*================================================*/
786
+ /* Add the bitmap to the list of ephemeral items. */
787
+ /*================================================*/
788
+
789
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) peek,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralExternalAddressList,
790
+ sizeof(CLIPSExternalAddress),sizeof(long),true);
791
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
792
+
793
+ /*=============================================*/
794
+ /* Return the address of the external address. */
795
+ /*=============================================*/
796
+
797
+ return peek;
798
+ }
799
+
800
+ /***************************************************/
801
+ /* HashSymbol: Computes a hash value for a symbol. */
802
+ /***************************************************/
803
+ size_t HashSymbol(
804
+ const char *word,
805
+ size_t range)
806
+ {
807
+ size_t i;
808
+ size_t tally = 0;
809
+
810
+ for (i = 0; word[i]; i++)
811
+ { tally = tally * 127 + (size_t) word[i]; }
812
+
813
+ if (range == 0)
814
+ { return tally; }
815
+
816
+ return tally % range;
817
+ }
818
+
819
+ /*************************************************/
820
+ /* HashFloat: Computes a hash value for a float. */
821
+ /*************************************************/
822
+ size_t HashFloat(
823
+ double number,
824
+ size_t range)
825
+ {
826
+ size_t tally = 0;
827
+ char *word;
828
+ size_t i;
829
+
830
+ word = (char *) &number;
831
+
832
+ for (i = 0; i < sizeof(double); i++)
833
+ { tally = tally * 127 + (size_t) word[i]; }
834
+
835
+ if (range == 0)
836
+ { return tally; }
837
+
838
+ return tally % range;
839
+ }
840
+
841
+ /******************************************************/
842
+ /* HashInteger: Computes a hash value for an integer. */
843
+ /******************************************************/
844
+ size_t HashInteger(
845
+ long long number,
846
+ size_t range)
847
+ {
848
+ size_t tally;
849
+
850
+ #if WIN_MVC
851
+ if (number < 0)
852
+ { number = - number; }
853
+ tally = (((size_t) number) % range);
854
+ #else
855
+ tally = (((size_t) llabs(number)) % range);
856
+ #endif
857
+
858
+ if (range == 0)
859
+ { return tally; }
860
+
861
+ return tally;
862
+ }
863
+
864
+ /****************************************/
865
+ /* HashExternalAddress: Computes a hash */
866
+ /* value for an external address. */
867
+ /****************************************/
868
+ size_t HashExternalAddress(
869
+ void *theExternalAddress,
870
+ size_t range)
871
+ {
872
+ size_t tally;
873
+ union
874
+ {
875
+ void *vv;
876
+ unsigned uv;
877
+ } fis;
878
+
879
+ fis.uv = 0;
880
+ fis.vv = theExternalAddress;
881
+ tally = (fis.uv / 256);
882
+
883
+ if (range == 0)
884
+ { return tally; }
885
+
886
+ return(tally % range);
887
+ }
888
+
889
+ /***************************************************/
890
+ /* HashBitMap: Computes a hash value for a bitmap. */
891
+ /***************************************************/
892
+ size_t HashBitMap(
893
+ const char *word,
894
+ size_t range,
895
+ unsigned length)
896
+ {
897
+ unsigned k,j,i;
898
+ size_t tally;
899
+ unsigned longLength;
900
+ unsigned long count = 0L,tmpLong;
901
+ char *tmpPtr;
902
+
903
+ tmpPtr = (char *) &tmpLong;
904
+
905
+ /*============================================================*/
906
+ /* Add up the first part of the word as unsigned long values. */
907
+ /*============================================================*/
908
+
909
+ longLength = length / sizeof(unsigned long);
910
+ for (i = 0 , j = 0 ; i < longLength; i++)
911
+ {
912
+ for (k = 0 ; k < sizeof(unsigned long) ; k++ , j++)
913
+ tmpPtr[k] = word[j];
914
+ count += tmpLong;
915
+ }
916
+
917
+ /*============================================*/
918
+ /* Add the remaining characters to the count. */
919
+ /*============================================*/
920
+
921
+ for (; j < length; j++) count += (size_t) word[j];
922
+
923
+ /*========================*/
924
+ /* Return the hash value. */
925
+ /*========================*/
926
+
927
+ if (range == 0)
928
+ { return count; }
929
+
930
+ tally = (count % range);
931
+
932
+ return tally;
933
+ }
934
+
935
+ /****************************************************/
936
+ /* RetainLexeme: Increments the count value for a */
937
+ /* SymbolTable entry. Adds the symbol to the */
938
+ /* EphemeralSymbolList if the count becomes zero. */
939
+ /****************************************************/
940
+ void RetainLexeme(
941
+ Environment *theEnv,
942
+ CLIPSLexeme *theValue)
943
+ {
944
+ theValue->count++;
945
+ }
946
+
947
+ /****************************************************/
948
+ /* ReleaseLexeme: Decrements the count value for a */
949
+ /* SymbolTable entry. Adds the symbol to the */
950
+ /* EphemeralSymbolList if the count becomes zero. */
951
+ /****************************************************/
952
+ void ReleaseLexeme(
953
+ Environment *theEnv,
954
+ CLIPSLexeme *theValue)
955
+ {
956
+ if (theValue->count < 0)
957
+ {
958
+ SystemError(theEnv,"SYMBOL",3);
959
+ ExitRouter(theEnv,EXIT_FAILURE);
960
+ }
961
+
962
+ if (theValue->count == 0)
963
+ {
964
+ SystemError(theEnv,"SYMBOL",4);
965
+ ExitRouter(theEnv,EXIT_FAILURE);
966
+ }
967
+
968
+ theValue->count--;
969
+
970
+ if (theValue->count != 0) return;
971
+
972
+ if (theValue->markedEphemeral == false)
973
+ {
974
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralSymbolList,
975
+ sizeof(CLIPSLexeme),AVERAGE_STRING_SIZE,true);
976
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
977
+ }
978
+
979
+ return;
980
+ }
981
+
982
+ /***************************************************/
983
+ /* RetainFloat: Increments the count value for a */
984
+ /* FloatTable entry. Adds the float to the */
985
+ /* EphemeralFloatList if the count becomes zero. */
986
+ /***************************************************/
987
+ void RetainFloat(
988
+ Environment *theEnv,
989
+ CLIPSFloat *theValue)
990
+ {
991
+ theValue->count++;
992
+ }
993
+
994
+ /***************************************************/
995
+ /* ReleaseFloat: Decrements the count value for a */
996
+ /* FloatTable entry. Adds the float to the */
997
+ /* EphemeralFloatList if the count becomes zero. */
998
+ /***************************************************/
999
+ void ReleaseFloat(
1000
+ Environment *theEnv,
1001
+ CLIPSFloat *theValue)
1002
+ {
1003
+ if (theValue->count <= 0)
1004
+ {
1005
+ SystemError(theEnv,"SYMBOL",5);
1006
+ ExitRouter(theEnv,EXIT_FAILURE);
1007
+ }
1008
+
1009
+ theValue->count--;
1010
+
1011
+ if (theValue->count != 0) return;
1012
+
1013
+ if (theValue->markedEphemeral == false)
1014
+ {
1015
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralFloatList,
1016
+ sizeof(CLIPSFloat),0,true);
1017
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1018
+ }
1019
+
1020
+ return;
1021
+ }
1022
+
1023
+ /*****************************************************/
1024
+ /* RetainInteger: Increments the count value for an */
1025
+ /* IntegerTable entry. Adds the integer to the */
1026
+ /* EphemeralIntegerList if the count becomes zero. */
1027
+ /*****************************************************/
1028
+ void RetainInteger(
1029
+ Environment *theEnv,
1030
+ CLIPSInteger *theValue)
1031
+ {
1032
+ theValue->count++;
1033
+ }
1034
+
1035
+ /*****************************************************/
1036
+ /* ReleaseInteger: Decrements the count value for */
1037
+ /* an IntegerTable entry. Adds the integer to the */
1038
+ /* EphemeralIntegerList if the count becomes zero. */
1039
+ /*****************************************************/
1040
+ void ReleaseInteger(
1041
+ Environment *theEnv,
1042
+ CLIPSInteger *theValue)
1043
+ {
1044
+ if (theValue->count <= 0)
1045
+ {
1046
+ SystemError(theEnv,"SYMBOL",6);
1047
+ ExitRouter(theEnv,EXIT_FAILURE);
1048
+ }
1049
+
1050
+ theValue->count--;
1051
+
1052
+ if (theValue->count != 0) return;
1053
+
1054
+ if (theValue->markedEphemeral == false)
1055
+ {
1056
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralIntegerList,
1057
+ sizeof(CLIPSInteger),0,true);
1058
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1059
+ }
1060
+
1061
+ return;
1062
+ }
1063
+
1064
+ /**************************************************************/
1065
+ /* IncrementBitMapReferenceCount: Increments the count value */
1066
+ /* for a BitmapTable entry. Adds the bitmap to the */
1067
+ /* EphemeralBitMapList if the count becomes zero. */
1068
+ /**************************************************************/
1069
+ void IncrementBitMapReferenceCount(
1070
+ Environment *theEnv,
1071
+ CLIPSBitMap *theValue)
1072
+ {
1073
+ theValue->count++;
1074
+ }
1075
+
1076
+ /**************************************************************/
1077
+ /* DecrementBitMapReferenceCount: Decrements the count value */
1078
+ /* for a BitmapTable entry. Adds the bitmap to the */
1079
+ /* EphemeralBitMapList if the count becomes zero. */
1080
+ /**************************************************************/
1081
+ void DecrementBitMapReferenceCount(
1082
+ Environment *theEnv,
1083
+ CLIPSBitMap *theValue)
1084
+ {
1085
+ if (theValue->count < 0)
1086
+ {
1087
+ SystemError(theEnv,"SYMBOL",7);
1088
+ ExitRouter(theEnv,EXIT_FAILURE);
1089
+ }
1090
+
1091
+ if (theValue->count == 0)
1092
+ {
1093
+ SystemError(theEnv,"SYMBOL",8);
1094
+ ExitRouter(theEnv,EXIT_FAILURE);
1095
+ }
1096
+
1097
+ theValue->count--;
1098
+
1099
+ if (theValue->count != 0) return;
1100
+
1101
+ if (theValue->markedEphemeral == false)
1102
+ {
1103
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralBitMapList,
1104
+ sizeof(CLIPSBitMap),sizeof(long),true);
1105
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1106
+ }
1107
+
1108
+ return;
1109
+ }
1110
+
1111
+ /*************************************************************/
1112
+ /* RetainExternalAddress: Decrements the count value for an */
1113
+ /* ExternAddressTable entry. Adds the bitmap to the */
1114
+ /* EphemeralExternalAddressList if the count becomes zero. */
1115
+ /*************************************************************/
1116
+ void RetainExternalAddress(
1117
+ Environment *theEnv,
1118
+ CLIPSExternalAddress *theValue)
1119
+ {
1120
+ theValue->count++;
1121
+ }
1122
+
1123
+ /*************************************************************/
1124
+ /* ReleaseExternalAddress: Decrements the count value for */
1125
+ /* an ExternAddressTable entry. Adds the bitmap to the */
1126
+ /* EphemeralExternalAddressList if the count becomes zero. */
1127
+ /*************************************************************/
1128
+ void ReleaseExternalAddress(
1129
+ Environment *theEnv,
1130
+ CLIPSExternalAddress *theValue)
1131
+ {
1132
+ if (theValue->count < 0)
1133
+ {
1134
+ SystemError(theEnv,"SYMBOL",9);
1135
+ ExitRouter(theEnv,EXIT_FAILURE);
1136
+ }
1137
+
1138
+ if (theValue->count == 0)
1139
+ {
1140
+ SystemError(theEnv,"SYMBOL",10);
1141
+ ExitRouter(theEnv,EXIT_FAILURE);
1142
+ }
1143
+
1144
+ theValue->count--;
1145
+
1146
+ if (theValue->count != 0) return;
1147
+
1148
+ if (theValue->markedEphemeral == false)
1149
+ {
1150
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,&UtilityData(theEnv)->CurrentGarbageFrame->ephemeralExternalAddressList,
1151
+ sizeof(CLIPSExternalAddress),sizeof(long),true);
1152
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1153
+ }
1154
+
1155
+ return;
1156
+ }
1157
+
1158
+ /************************************************/
1159
+ /* RemoveHashNode: Removes a hash node from the */
1160
+ /* SymbolTable, FloatTable, IntegerTable, */
1161
+ /* BitMapTable, or ExternalAddressTable. */
1162
+ /************************************************/
1163
+ static void RemoveHashNode(
1164
+ Environment *theEnv,
1165
+ GENERIC_HN *theValue,
1166
+ GENERIC_HN **theTable,
1167
+ int size,
1168
+ int type)
1169
+ {
1170
+ GENERIC_HN *previousNode, *currentNode;
1171
+ CLIPSExternalAddress *theAddress;
1172
+
1173
+ /*=============================================*/
1174
+ /* Find the entry in the specified hash table. */
1175
+ /*=============================================*/
1176
+
1177
+ previousNode = NULL;
1178
+ currentNode = theTable[theValue->bucket];
1179
+
1180
+ while (currentNode != theValue)
1181
+ {
1182
+ previousNode = currentNode;
1183
+ currentNode = currentNode->next;
1184
+
1185
+ if (currentNode == NULL)
1186
+ {
1187
+ SystemError(theEnv,"SYMBOL",11);
1188
+ ExitRouter(theEnv,EXIT_FAILURE);
1189
+ }
1190
+ }
1191
+
1192
+ /*===========================================*/
1193
+ /* Remove the entry from the list of entries */
1194
+ /* stored in the hash table bucket. */
1195
+ /*===========================================*/
1196
+
1197
+ if (previousNode == NULL)
1198
+ { theTable[theValue->bucket] = theValue->next; }
1199
+ else
1200
+ { previousNode->next = currentNode->next; }
1201
+
1202
+ /*=================================================*/
1203
+ /* Symbol and bit map nodes have additional memory */
1204
+ /* use to store the character or bitmap string. */
1205
+ /*=================================================*/
1206
+
1207
+ if (type == SYMBOL_TYPE)
1208
+ {
1209
+ rm(theEnv,(void *) ((CLIPSLexeme *) theValue)->contents,
1210
+ strlen(((CLIPSLexeme *) theValue)->contents) + 1);
1211
+ }
1212
+ else if (type == BITMAPARRAY)
1213
+ {
1214
+ rm(theEnv,(void *) ((CLIPSBitMap *) theValue)->contents,
1215
+ ((CLIPSBitMap *) theValue)->size);
1216
+ }
1217
+ else if (type == EXTERNAL_ADDRESS_TYPE)
1218
+ {
1219
+ theAddress = (CLIPSExternalAddress *) theValue;
1220
+
1221
+ if ((EvaluationData(theEnv)->ExternalAddressTypes[theAddress->type] != NULL) &&
1222
+ (EvaluationData(theEnv)->ExternalAddressTypes[theAddress->type]->discardFunction != NULL))
1223
+ { (*EvaluationData(theEnv)->ExternalAddressTypes[theAddress->type]->discardFunction)(theEnv,theAddress->contents); }
1224
+ }
1225
+
1226
+ /*===========================*/
1227
+ /* Return the table entry to */
1228
+ /* the pool of free memory. */
1229
+ /*===========================*/
1230
+
1231
+ rtn_sized_struct(theEnv,size,theValue);
1232
+ }
1233
+
1234
+ /***********************************************************/
1235
+ /* AddEphemeralHashNode: Adds a symbol, integer, float, or */
1236
+ /* bit map table entry to the list of ephemeral atomic */
1237
+ /* values. These entries have a zero count indicating */
1238
+ /* that no structure is using the data value. */
1239
+ /***********************************************************/
1240
+ static void AddEphemeralHashNode(
1241
+ Environment *theEnv,
1242
+ GENERIC_HN *theHashNode,
1243
+ struct ephemeron **theEphemeralList,
1244
+ int hashNodeSize,
1245
+ int averageContentsSize,
1246
+ bool checkCount)
1247
+ {
1248
+ struct ephemeron *temp;
1249
+
1250
+ /*===========================================*/
1251
+ /* If the count isn't zero then this routine */
1252
+ /* should never have been called. */
1253
+ /*===========================================*/
1254
+
1255
+ if (checkCount && (theHashNode->count != 0))
1256
+ {
1257
+ SystemError(theEnv,"SYMBOL",12);
1258
+ ExitRouter(theEnv,EXIT_FAILURE);
1259
+ }
1260
+
1261
+ /*=====================================*/
1262
+ /* Mark the atomic value as ephemeral. */
1263
+ /*=====================================*/
1264
+
1265
+ theHashNode->markedEphemeral = true;
1266
+
1267
+ /*=============================*/
1268
+ /* Add the atomic value to the */
1269
+ /* list of ephemeral values. */
1270
+ /*=============================*/
1271
+
1272
+ temp = get_struct(theEnv,ephemeron);
1273
+ temp->associatedValue = theHashNode;
1274
+ temp->next = *theEphemeralList;
1275
+ *theEphemeralList = temp;
1276
+ }
1277
+
1278
+ /***************************************************/
1279
+ /* RemoveEphemeralAtoms: Causes the removal of all */
1280
+ /* ephemeral symbols, integers, floats, and bit */
1281
+ /* maps that still have a count value of zero, */
1282
+ /* from their respective storage tables. */
1283
+ /***************************************************/
1284
+ void RemoveEphemeralAtoms(
1285
+ Environment *theEnv)
1286
+ {
1287
+ struct garbageFrame *theGarbageFrame;
1288
+
1289
+ theGarbageFrame = UtilityData(theEnv)->CurrentGarbageFrame;
1290
+ if (! theGarbageFrame->dirty) return;
1291
+
1292
+ RemoveEphemeralHashNodes(theEnv,&theGarbageFrame->ephemeralSymbolList,(GENERIC_HN **) SymbolData(theEnv)->SymbolTable,
1293
+ sizeof(CLIPSLexeme),SYMBOL_TYPE,AVERAGE_STRING_SIZE);
1294
+ RemoveEphemeralHashNodes(theEnv,&theGarbageFrame->ephemeralFloatList,(GENERIC_HN **) SymbolData(theEnv)->FloatTable,
1295
+ sizeof(CLIPSFloat),FLOAT_TYPE,0);
1296
+ RemoveEphemeralHashNodes(theEnv,&theGarbageFrame->ephemeralIntegerList,(GENERIC_HN **) SymbolData(theEnv)->IntegerTable,
1297
+ sizeof(CLIPSInteger),INTEGER_TYPE,0);
1298
+ RemoveEphemeralHashNodes(theEnv,&theGarbageFrame->ephemeralBitMapList,(GENERIC_HN **) SymbolData(theEnv)->BitMapTable,
1299
+ sizeof(CLIPSBitMap),BITMAPARRAY,AVERAGE_BITMAP_SIZE);
1300
+ RemoveEphemeralHashNodes(theEnv,&theGarbageFrame->ephemeralExternalAddressList,(GENERIC_HN **) SymbolData(theEnv)->ExternalAddressTable,
1301
+ sizeof(CLIPSExternalAddress),EXTERNAL_ADDRESS_TYPE,0);
1302
+ }
1303
+
1304
+ /***********************************************/
1305
+ /* EphemerateValue: Marks a value as ephemeral */
1306
+ /* if it is not already marked. */
1307
+ /***********************************************/
1308
+ void EphemerateValue(
1309
+ Environment *theEnv,
1310
+ void *theValue)
1311
+ {
1312
+ CLIPSLexeme *theSymbol;
1313
+ CLIPSFloat *theFloat;
1314
+ CLIPSInteger *theInteger;
1315
+ CLIPSExternalAddress *theExternalAddress;
1316
+
1317
+ switch (((TypeHeader *) theValue)->type)
1318
+ {
1319
+ case SYMBOL_TYPE:
1320
+ case STRING_TYPE:
1321
+ #if OBJECT_SYSTEM
1322
+ case INSTANCE_NAME_TYPE:
1323
+ #endif
1324
+ theSymbol = (CLIPSLexeme *) theValue;
1325
+ if (theSymbol->markedEphemeral) return;
1326
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,
1327
+ &UtilityData(theEnv)->CurrentGarbageFrame->ephemeralSymbolList,
1328
+ sizeof(CLIPSLexeme),AVERAGE_STRING_SIZE,false);
1329
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1330
+ break;
1331
+
1332
+ case FLOAT_TYPE:
1333
+ theFloat = (CLIPSFloat *) theValue;
1334
+ if (theFloat->markedEphemeral) return;
1335
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,
1336
+ &UtilityData(theEnv)->CurrentGarbageFrame->ephemeralFloatList,
1337
+ sizeof(CLIPSFloat),0,false);
1338
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1339
+ break;
1340
+
1341
+ case INTEGER_TYPE:
1342
+ theInteger = (CLIPSInteger *) theValue;
1343
+ if (theInteger->markedEphemeral) return;
1344
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,
1345
+ &UtilityData(theEnv)->CurrentGarbageFrame->ephemeralIntegerList,
1346
+ sizeof(CLIPSInteger),0,false);
1347
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1348
+ break;
1349
+
1350
+ case EXTERNAL_ADDRESS_TYPE:
1351
+ theExternalAddress = (CLIPSExternalAddress *) theValue;
1352
+ if (theExternalAddress->markedEphemeral) return;
1353
+ AddEphemeralHashNode(theEnv,(GENERIC_HN *) theValue,
1354
+ &UtilityData(theEnv)->CurrentGarbageFrame->ephemeralExternalAddressList,
1355
+ sizeof(CLIPSExternalAddress),sizeof(long),false);
1356
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
1357
+ break;
1358
+
1359
+ case MULTIFIELD_TYPE:
1360
+ EphemerateMultifield(theEnv,(Multifield *) theValue);
1361
+ break;
1362
+
1363
+ }
1364
+ }
1365
+
1366
+ /****************************************************************/
1367
+ /* RemoveEphemeralHashNodes: Removes symbols from the ephemeral */
1368
+ /* symbol list that have a count of zero and were placed on */
1369
+ /* the list at a higher level than the current evaluation */
1370
+ /* depth. Since symbols are ordered in the list in descending */
1371
+ /* order, the removal process can end when a depth is reached */
1372
+ /* less than the current evaluation depth. Because ephemeral */
1373
+ /* symbols can be "pulled" up through an evaluation depth, */
1374
+ /* this routine needs to check through both the previous and */
1375
+ /* current evaluation depth. */
1376
+ /****************************************************************/
1377
+ static void RemoveEphemeralHashNodes(
1378
+ Environment *theEnv,
1379
+ struct ephemeron **theEphemeralList,
1380
+ GENERIC_HN **theTable,
1381
+ int hashNodeSize,
1382
+ int hashNodeType,
1383
+ int averageContentsSize)
1384
+ {
1385
+ struct ephemeron *edPtr, *lastPtr = NULL, *nextPtr;
1386
+
1387
+ edPtr = *theEphemeralList;
1388
+
1389
+ while (edPtr != NULL)
1390
+ {
1391
+ /*======================================================*/
1392
+ /* Check through previous and current evaluation depth */
1393
+ /* because these symbols can be interspersed, otherwise */
1394
+ /* symbols are stored in descending evaluation depth. */
1395
+ /*======================================================*/
1396
+
1397
+ nextPtr = edPtr->next;
1398
+
1399
+ /*==================================================*/
1400
+ /* Remove any symbols that have a count of zero and */
1401
+ /* were added to the ephemeral list at a higher */
1402
+ /* evaluation depth. */
1403
+ /*==================================================*/
1404
+
1405
+ if (edPtr->associatedValue->count == 0)
1406
+ {
1407
+ RemoveHashNode(theEnv,edPtr->associatedValue,theTable,hashNodeSize,hashNodeType);
1408
+ rtn_struct(theEnv,ephemeron,edPtr);
1409
+ if (lastPtr == NULL) *theEphemeralList = nextPtr;
1410
+ else lastPtr->next = nextPtr;
1411
+ }
1412
+
1413
+ /*=======================================*/
1414
+ /* Remove ephemeral status of any symbol */
1415
+ /* with a count greater than zero. */
1416
+ /*=======================================*/
1417
+
1418
+ else if (edPtr->associatedValue->count > 0)
1419
+ {
1420
+ edPtr->associatedValue->markedEphemeral = false;
1421
+
1422
+ rtn_struct(theEnv,ephemeron,edPtr);
1423
+
1424
+ if (lastPtr == NULL) *theEphemeralList = nextPtr;
1425
+ else lastPtr->next = nextPtr;
1426
+ }
1427
+
1428
+ /*==================================================*/
1429
+ /* Otherwise keep the symbol in the ephemeral list. */
1430
+ /*==================================================*/
1431
+
1432
+ else
1433
+ { lastPtr = edPtr; }
1434
+
1435
+ edPtr = nextPtr;
1436
+ }
1437
+ }
1438
+
1439
+ /*********************************************************/
1440
+ /* GetSymbolTable: Returns a pointer to the SymbolTable. */
1441
+ /*********************************************************/
1442
+ CLIPSLexeme **GetSymbolTable(
1443
+ Environment *theEnv)
1444
+ {
1445
+ return(SymbolData(theEnv)->SymbolTable);
1446
+ }
1447
+
1448
+ /******************************************************/
1449
+ /* SetSymbolTable: Sets the value of the SymbolTable. */
1450
+ /******************************************************/
1451
+ void SetSymbolTable(
1452
+ Environment *theEnv,
1453
+ CLIPSLexeme **value)
1454
+ {
1455
+ SymbolData(theEnv)->SymbolTable = value;
1456
+ }
1457
+
1458
+ /*******************************************************/
1459
+ /* GetFloatTable: Returns a pointer to the FloatTable. */
1460
+ /*******************************************************/
1461
+ CLIPSFloat **GetFloatTable(
1462
+ Environment *theEnv)
1463
+ {
1464
+ return(SymbolData(theEnv)->FloatTable);
1465
+ }
1466
+
1467
+ /****************************************************/
1468
+ /* SetFloatTable: Sets the value of the FloatTable. */
1469
+ /****************************************************/
1470
+ void SetFloatTable(
1471
+ Environment *theEnv,
1472
+ CLIPSFloat **value)
1473
+ {
1474
+ SymbolData(theEnv)->FloatTable = value;
1475
+ }
1476
+
1477
+ /***********************************************************/
1478
+ /* GetIntegerTable: Returns a pointer to the IntegerTable. */
1479
+ /***********************************************************/
1480
+ CLIPSInteger **GetIntegerTable(
1481
+ Environment *theEnv)
1482
+ {
1483
+ return(SymbolData(theEnv)->IntegerTable);
1484
+ }
1485
+
1486
+ /********************************************************/
1487
+ /* SetIntegerTable: Sets the value of the IntegerTable. */
1488
+ /********************************************************/
1489
+ void SetIntegerTable(
1490
+ Environment *theEnv,
1491
+ CLIPSInteger **value)
1492
+ {
1493
+ SymbolData(theEnv)->IntegerTable = value;
1494
+ }
1495
+
1496
+ /*********************************************************/
1497
+ /* GetBitMapTable: Returns a pointer to the BitMapTable. */
1498
+ /*********************************************************/
1499
+ CLIPSBitMap **GetBitMapTable(
1500
+ Environment *theEnv)
1501
+ {
1502
+ return(SymbolData(theEnv)->BitMapTable);
1503
+ }
1504
+
1505
+ /******************************************************/
1506
+ /* SetBitMapTable: Sets the value of the BitMapTable. */
1507
+ /******************************************************/
1508
+ void SetBitMapTable(
1509
+ Environment *theEnv,
1510
+ CLIPSBitMap **value)
1511
+ {
1512
+ SymbolData(theEnv)->BitMapTable = value;
1513
+ }
1514
+
1515
+ /***************************************************************************/
1516
+ /* GetExternalAddressTable: Returns a pointer to the ExternalAddressTable. */
1517
+ /***************************************************************************/
1518
+ CLIPSExternalAddress **GetExternalAddressTable(
1519
+ Environment *theEnv)
1520
+ {
1521
+ return(SymbolData(theEnv)->ExternalAddressTable);
1522
+ }
1523
+
1524
+ /************************************************************************/
1525
+ /* SetExternalAddressTable: Sets the value of the ExternalAddressTable. */
1526
+ /************************************************************************/
1527
+ void SetExternalAddressTable(
1528
+ Environment *theEnv,
1529
+ CLIPSExternalAddress **value)
1530
+ {
1531
+ SymbolData(theEnv)->ExternalAddressTable = value;
1532
+ }
1533
+
1534
+ /******************************************************/
1535
+ /* RefreshSpecialSymbols: Resets the values of the */
1536
+ /* TrueSymbol, FalseSymbol, Zero, PositiveInfinity, */
1537
+ /* and NegativeInfinity symbols. */
1538
+ /******************************************************/
1539
+ void RefreshSpecialSymbols(
1540
+ Environment *theEnv)
1541
+ {
1542
+ SymbolData(theEnv)->PositiveInfinity = FindSymbolHN(theEnv,POSITIVE_INFINITY_STRING,SYMBOL_BIT);
1543
+ SymbolData(theEnv)->NegativeInfinity = FindSymbolHN(theEnv,NEGATIVE_INFINITY_STRING,SYMBOL_BIT);
1544
+ SymbolData(theEnv)->Zero = FindLongHN(theEnv,0L);
1545
+ }
1546
+
1547
+ /***********************************************************/
1548
+ /* FindSymbolMatches: Finds all symbols in the SymbolTable */
1549
+ /* which begin with a specified symbol. This function is */
1550
+ /* used to implement the command completion feature */
1551
+ /* found in some of the machine specific interfaces. */
1552
+ /***********************************************************/
1553
+ struct symbolMatch *FindSymbolMatches(
1554
+ Environment *theEnv,
1555
+ const char *searchString,
1556
+ unsigned *numberOfMatches,
1557
+ size_t *commonPrefixLength)
1558
+ {
1559
+ struct symbolMatch *reply = NULL, *temp;
1560
+ CLIPSLexeme *hashPtr = NULL;
1561
+ size_t searchLength;
1562
+
1563
+ searchLength = strlen(searchString);
1564
+ *numberOfMatches = 0;
1565
+
1566
+ while ((hashPtr = GetNextSymbolMatch(theEnv,searchString,searchLength,hashPtr,
1567
+ false,commonPrefixLength)) != NULL)
1568
+ {
1569
+ *numberOfMatches = *numberOfMatches + 1;
1570
+ temp = get_struct(theEnv,symbolMatch);
1571
+ temp->match = hashPtr;
1572
+ temp->next = reply;
1573
+ reply = temp;
1574
+ }
1575
+
1576
+ return(reply);
1577
+ }
1578
+
1579
+ /*********************************************************/
1580
+ /* ReturnSymbolMatches: Returns a set of symbol matches. */
1581
+ /*********************************************************/
1582
+ void ReturnSymbolMatches(
1583
+ Environment *theEnv,
1584
+ struct symbolMatch *listOfMatches)
1585
+ {
1586
+ struct symbolMatch *temp;
1587
+
1588
+ while (listOfMatches != NULL)
1589
+ {
1590
+ temp = listOfMatches->next;
1591
+ rtn_struct(theEnv,symbolMatch,listOfMatches);
1592
+ listOfMatches = temp;
1593
+ }
1594
+ }
1595
+
1596
+ /***************************************************************/
1597
+ /* ClearBitString: Initializes the values of a bitmap to zero. */
1598
+ /***************************************************************/
1599
+ void ClearBitString(
1600
+ void *vTheBitMap,
1601
+ size_t length)
1602
+ {
1603
+ char *theBitMap = (char *) vTheBitMap;
1604
+ size_t i;
1605
+
1606
+ for (i = 0; i < length; i++) theBitMap[i] = '\0';
1607
+ }
1608
+
1609
+ /****************************************/
1610
+ /* BitStringHasBitsSet: Returns true if */
1611
+ /* the bit string has any bits set. */
1612
+ /****************************************/
1613
+ bool BitStringHasBitsSet(
1614
+ void *vTheBitMap,
1615
+ unsigned length)
1616
+ {
1617
+ char *theBitMap = (char *) vTheBitMap;
1618
+ unsigned i;
1619
+
1620
+ for (i = 0; i < length; i++)
1621
+ { if (theBitMap[i] != '\0') return true; }
1622
+
1623
+ return false;
1624
+ }
1625
+
1626
+ /*****************************************************************/
1627
+ /* GetNextSymbolMatch: Finds the next symbol in the SymbolTable */
1628
+ /* which begins with a specified symbol. This function is used */
1629
+ /* to implement the command completion feature found in some */
1630
+ /* of the machine specific interfaces. */
1631
+ /*****************************************************************/
1632
+ CLIPSLexeme *GetNextSymbolMatch(
1633
+ Environment *theEnv,
1634
+ const char *searchString,
1635
+ size_t searchLength,
1636
+ CLIPSLexeme *prevSymbol,
1637
+ bool anywhere,
1638
+ size_t *commonPrefixLength)
1639
+ {
1640
+ unsigned long i;
1641
+ CLIPSLexeme *hashPtr;
1642
+ bool flag = true;
1643
+ size_t prefixLength;
1644
+
1645
+ /*==========================================*/
1646
+ /* If we're looking anywhere in the string, */
1647
+ /* then there's no common prefix length. */
1648
+ /*==========================================*/
1649
+
1650
+ if (anywhere && (commonPrefixLength != NULL))
1651
+ *commonPrefixLength = 0;
1652
+
1653
+ /*========================================================*/
1654
+ /* If we're starting the search from the beginning of the */
1655
+ /* symbol table, the previous symbol argument is NULL. */
1656
+ /*========================================================*/
1657
+
1658
+ if (prevSymbol == NULL)
1659
+ {
1660
+ i = 0;
1661
+ hashPtr = SymbolData(theEnv)->SymbolTable[0];
1662
+ }
1663
+
1664
+ /*==========================================*/
1665
+ /* Otherwise start the search at the symbol */
1666
+ /* after the last symbol found. */
1667
+ /*==========================================*/
1668
+
1669
+ else
1670
+ {
1671
+ i = prevSymbol->bucket;
1672
+ hashPtr = prevSymbol->next;
1673
+ }
1674
+
1675
+ /*==============================================*/
1676
+ /* Search through all the symbol table buckets. */
1677
+ /*==============================================*/
1678
+
1679
+ while (flag)
1680
+ {
1681
+ /*===================================*/
1682
+ /* Search through all of the entries */
1683
+ /* in the bucket being examined. */
1684
+ /*===================================*/
1685
+
1686
+ for (; hashPtr != NULL; hashPtr = hashPtr->next)
1687
+ {
1688
+ /*================================================*/
1689
+ /* Skip symbols that being with ( since these are */
1690
+ /* typically symbols for internal use. Also skip */
1691
+ /* any symbols that are marked ephemeral since */
1692
+ /* these aren't in use. */
1693
+ /*================================================*/
1694
+
1695
+ if ((hashPtr->contents[0] == '(') ||
1696
+ (hashPtr->markedEphemeral))
1697
+ { continue; }
1698
+
1699
+ /*==================================================*/
1700
+ /* Two types of matching can be performed: the type */
1701
+ /* comparing just to the beginning of the string */
1702
+ /* and the type which looks for the substring */
1703
+ /* anywhere within the string being examined. */
1704
+ /*==================================================*/
1705
+
1706
+ if (! anywhere)
1707
+ {
1708
+ /*=============================================*/
1709
+ /* Determine the common prefix length between */
1710
+ /* the previously found match (if available or */
1711
+ /* the search string if not) and the symbol */
1712
+ /* table entry. */
1713
+ /*=============================================*/
1714
+
1715
+ if (prevSymbol != NULL)
1716
+ prefixLength = CommonPrefixLength(prevSymbol->contents,hashPtr->contents);
1717
+ else
1718
+ prefixLength = CommonPrefixLength(searchString,hashPtr->contents);
1719
+
1720
+ /*===================================================*/
1721
+ /* If the prefix length is greater than or equal to */
1722
+ /* the length of the search string, then we've found */
1723
+ /* a match. If this is the first match, the common */
1724
+ /* prefix length is set to the length of the first */
1725
+ /* match, otherwise the common prefix length is the */
1726
+ /* smallest prefix length found among all matches. */
1727
+ /*===================================================*/
1728
+
1729
+ if (prefixLength >= searchLength)
1730
+ {
1731
+ if (commonPrefixLength != NULL)
1732
+ {
1733
+ if (prevSymbol == NULL)
1734
+ *commonPrefixLength = strlen(hashPtr->contents);
1735
+ else if (prefixLength < *commonPrefixLength)
1736
+ *commonPrefixLength = prefixLength;
1737
+ }
1738
+ return(hashPtr);
1739
+ }
1740
+ }
1741
+ else
1742
+ {
1743
+ if (StringWithinString(hashPtr->contents,searchString) != NULL)
1744
+ { return(hashPtr); }
1745
+ }
1746
+ }
1747
+
1748
+ /*=================================================*/
1749
+ /* Move on to the next bucket in the symbol table. */
1750
+ /*=================================================*/
1751
+
1752
+ if (++i >= SYMBOL_HASH_SIZE) flag = false;
1753
+ else hashPtr = SymbolData(theEnv)->SymbolTable[i];
1754
+ }
1755
+
1756
+ /*=====================================*/
1757
+ /* There are no more matching symbols. */
1758
+ /*=====================================*/
1759
+
1760
+ return NULL;
1761
+ }
1762
+
1763
+ /**********************************************/
1764
+ /* StringWithinString: Determines if a string */
1765
+ /* is contained within another string. */
1766
+ /**********************************************/
1767
+ static const char *StringWithinString(
1768
+ const char *cs,
1769
+ const char *ct)
1770
+ {
1771
+ unsigned i,j,k;
1772
+
1773
+ for (i = 0 ; cs[i] != '\0' ; i++)
1774
+ {
1775
+ for (j = i , k = 0 ; ct[k] != '\0' && cs[j] == ct[k] ; j++, k++) ;
1776
+ if ((ct[k] == '\0') && (k != 0))
1777
+ return(cs + i);
1778
+ }
1779
+ return NULL;
1780
+ }
1781
+
1782
+ /************************************************/
1783
+ /* CommonPrefixLength: Determines the length of */
1784
+ /* the maximumcommon prefix of two strings */
1785
+ /************************************************/
1786
+ static size_t CommonPrefixLength(
1787
+ const char *cs,
1788
+ const char *ct)
1789
+ {
1790
+ unsigned i;
1791
+
1792
+ for (i = 0 ; (cs[i] != '\0') && (ct[i] != '\0') ; i++)
1793
+ if (cs[i] != ct[i])
1794
+ break;
1795
+ return(i);
1796
+ }
1797
+
1798
+ #if BLOAD_AND_BSAVE || CONSTRUCT_COMPILER || BSAVE_INSTANCES
1799
+
1800
+ /****************************************************************/
1801
+ /* SetAtomicValueIndices: Sets the bucket values for hash table */
1802
+ /* entries with an index value that indicates the position of */
1803
+ /* the hash table in a hash table traversal (e.g. this is the */
1804
+ /* fifth entry in the hash table. */
1805
+ /****************************************************************/
1806
+ void SetAtomicValueIndices(
1807
+ Environment *theEnv,
1808
+ bool setAll)
1809
+ {
1810
+ unsigned int count;
1811
+ unsigned int i;
1812
+ CLIPSLexeme *symbolPtr, **symbolArray;
1813
+ CLIPSFloat *floatPtr, **floatArray;
1814
+ CLIPSInteger *integerPtr, **integerArray;
1815
+ CLIPSBitMap *bitMapPtr, **bitMapArray;
1816
+
1817
+ /*===================================*/
1818
+ /* Set indices for the symbol table. */
1819
+ /*===================================*/
1820
+
1821
+ count = 0;
1822
+ symbolArray = GetSymbolTable(theEnv);
1823
+
1824
+ for (i = 0; i < SYMBOL_HASH_SIZE; i++)
1825
+ {
1826
+ for (symbolPtr = symbolArray[i];
1827
+ symbolPtr != NULL;
1828
+ symbolPtr = symbolPtr->next)
1829
+ {
1830
+ if ((symbolPtr->neededSymbol == true) || setAll)
1831
+ { symbolPtr->bucket = count++; }
1832
+ }
1833
+ }
1834
+
1835
+ /*==================================*/
1836
+ /* Set indices for the float table. */
1837
+ /*==================================*/
1838
+
1839
+ count = 0;
1840
+ floatArray = GetFloatTable(theEnv);
1841
+
1842
+ for (i = 0; i < FLOAT_HASH_SIZE; i++)
1843
+ {
1844
+ for (floatPtr = floatArray[i];
1845
+ floatPtr != NULL;
1846
+ floatPtr = floatPtr->next)
1847
+ {
1848
+ if ((floatPtr->neededFloat == true) || setAll)
1849
+ { floatPtr->bucket = count++; }
1850
+ }
1851
+ }
1852
+
1853
+ /*====================================*/
1854
+ /* Set indices for the integer table. */
1855
+ /*====================================*/
1856
+
1857
+ count = 0;
1858
+ integerArray = GetIntegerTable(theEnv);
1859
+
1860
+ for (i = 0; i < INTEGER_HASH_SIZE; i++)
1861
+ {
1862
+ for (integerPtr = integerArray[i];
1863
+ integerPtr != NULL;
1864
+ integerPtr = integerPtr->next)
1865
+ {
1866
+ if ((integerPtr->neededInteger == true) || setAll)
1867
+ { integerPtr->bucket = count++; }
1868
+ }
1869
+ }
1870
+
1871
+ /*===================================*/
1872
+ /* Set indices for the bitmap table. */
1873
+ /*===================================*/
1874
+
1875
+ count = 0;
1876
+ bitMapArray = GetBitMapTable(theEnv);
1877
+
1878
+ for (i = 0; i < BITMAP_HASH_SIZE; i++)
1879
+ {
1880
+ for (bitMapPtr = bitMapArray[i];
1881
+ bitMapPtr != NULL;
1882
+ bitMapPtr = bitMapPtr->next)
1883
+ {
1884
+ if ((bitMapPtr->neededBitMap == true) || setAll)
1885
+ { bitMapPtr->bucket = count++; }
1886
+ }
1887
+ }
1888
+ }
1889
+
1890
+ /***********************************************************************/
1891
+ /* RestoreAtomicValueBuckets: Restores the bucket values of hash table */
1892
+ /* entries to the appropriate values. Normally called to undo the */
1893
+ /* effects of a call to the SetAtomicValueIndices function. */
1894
+ /***********************************************************************/
1895
+ void RestoreAtomicValueBuckets(
1896
+ Environment *theEnv)
1897
+ {
1898
+ unsigned int i;
1899
+ CLIPSLexeme *symbolPtr, **symbolArray;
1900
+ CLIPSFloat *floatPtr, **floatArray;
1901
+ CLIPSInteger *integerPtr, **integerArray;
1902
+ CLIPSBitMap *bitMapPtr, **bitMapArray;
1903
+
1904
+ /*================================================*/
1905
+ /* Restore the bucket values in the symbol table. */
1906
+ /*================================================*/
1907
+
1908
+ symbolArray = GetSymbolTable(theEnv);
1909
+
1910
+ for (i = 0; i < SYMBOL_HASH_SIZE; i++)
1911
+ {
1912
+ for (symbolPtr = symbolArray[i];
1913
+ symbolPtr != NULL;
1914
+ symbolPtr = symbolPtr->next)
1915
+ { symbolPtr->bucket = i; }
1916
+ }
1917
+
1918
+ /*===============================================*/
1919
+ /* Restore the bucket values in the float table. */
1920
+ /*===============================================*/
1921
+
1922
+ floatArray = GetFloatTable(theEnv);
1923
+
1924
+ for (i = 0; i < FLOAT_HASH_SIZE; i++)
1925
+ {
1926
+ for (floatPtr = floatArray[i];
1927
+ floatPtr != NULL;
1928
+ floatPtr = floatPtr->next)
1929
+ { floatPtr->bucket = i; }
1930
+ }
1931
+
1932
+ /*=================================================*/
1933
+ /* Restore the bucket values in the integer table. */
1934
+ /*=================================================*/
1935
+
1936
+ integerArray = GetIntegerTable(theEnv);
1937
+
1938
+ for (i = 0; i < INTEGER_HASH_SIZE; i++)
1939
+ {
1940
+ for (integerPtr = integerArray[i];
1941
+ integerPtr != NULL;
1942
+ integerPtr = integerPtr->next)
1943
+ { integerPtr->bucket = i; }
1944
+ }
1945
+
1946
+ /*================================================*/
1947
+ /* Restore the bucket values in the bitmap table. */
1948
+ /*================================================*/
1949
+
1950
+ bitMapArray = GetBitMapTable(theEnv);
1951
+
1952
+ for (i = 0; i < BITMAP_HASH_SIZE; i++)
1953
+ {
1954
+ for (bitMapPtr = bitMapArray[i];
1955
+ bitMapPtr != NULL;
1956
+ bitMapPtr = bitMapPtr->next)
1957
+ { bitMapPtr->bucket = i; }
1958
+ }
1959
+ }
1960
+
1961
+ #endif /* BLOAD_AND_BSAVE || CONSTRUCT_COMPILER || BSAVE_INSTANCES */