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,1404 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.40 07/09/18 */
5
+ /* */
6
+ /* MULTIFIELD MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Gary D. Riley */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* Brian L. Dantes */
17
+ /* */
18
+ /* Revision History: */
19
+ /* */
20
+ /* 6.24: Renamed BOOLEAN macro type to intBool. */
21
+ /* */
22
+ /* Corrected code to remove compiler warnings. */
23
+ /* */
24
+ /* Moved ImplodeMultifield from multifun.c. */
25
+ /* */
26
+ /* 6.30: Changed integer type/precision. */
27
+ /* */
28
+ /* Changed garbage collection algorithm. */
29
+ /* */
30
+ /* Used DataObjectToString instead of */
31
+ /* ValueToString in implode$ to handle */
32
+ /* print representation of external addresses. */
33
+ /* */
34
+ /* Added const qualifiers to remove C++ */
35
+ /* deprecation warnings. */
36
+ /* */
37
+ /* Converted API macros to function calls. */
38
+ /* */
39
+ /* Fixed issue with StoreInMultifield when */
40
+ /* asserting void values in implied deftemplate */
41
+ /* facts. */
42
+ /* */
43
+ /* 6.40: Refactored code to reduce header dependencies */
44
+ /* in sysdep.c. */
45
+ /* */
46
+ /* Pragma once and other inclusion changes. */
47
+ /* */
48
+ /* Added support for booleans with <stdbool.h>. */
49
+ /* */
50
+ /* Removed use of void pointers for specific */
51
+ /* data structures. */
52
+ /* */
53
+ /* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
54
+ /* */
55
+ /* UDF redesign. */
56
+ /* */
57
+ /* The explode$ function via StringToMultifield */
58
+ /* now converts non-primitive value tokens */
59
+ /* (such as parentheses) to symbols rather than */
60
+ /* strings. */
61
+ /* */
62
+ /*************************************************************/
63
+
64
+ #include <stdio.h>
65
+
66
+ #include "setup.h"
67
+
68
+ #include "constant.h"
69
+ #include "envrnmnt.h"
70
+ #include "evaluatn.h"
71
+ #include "exprnops.h"
72
+ #include "memalloc.h"
73
+ #if OBJECT_SYSTEM
74
+ #include "object.h"
75
+ #endif
76
+ #include "scanner.h"
77
+ #include "prntutil.h"
78
+ #include "router.h"
79
+ #include "strngrtr.h"
80
+ #include "symbol.h"
81
+ #include "utility.h"
82
+
83
+ #include "multifld.h"
84
+
85
+ /******************************/
86
+ /* CreateUnmanagedMultifield: */
87
+ /******************************/
88
+ Multifield *CreateUnmanagedMultifield(
89
+ Environment *theEnv,
90
+ size_t size)
91
+ {
92
+ Multifield *theSegment;
93
+ size_t newSize = size;
94
+
95
+ if (size == 0) newSize = 1;
96
+
97
+ theSegment = get_var_struct(theEnv,multifield,sizeof(struct clipsValue) * (newSize - 1));
98
+
99
+ theSegment->header.type = MULTIFIELD_TYPE;
100
+ theSegment->length = size;
101
+ theSegment->busyCount = 0;
102
+ theSegment->next = NULL;
103
+
104
+ return theSegment;
105
+ }
106
+
107
+ /*********************/
108
+ /* ReturnMultifield: */
109
+ /*********************/
110
+ void ReturnMultifield(
111
+ Environment *theEnv,
112
+ Multifield *theSegment)
113
+ {
114
+ size_t newSize;
115
+
116
+ if (theSegment == NULL) return;
117
+
118
+ if (theSegment->length == 0) newSize = 1;
119
+ else newSize = theSegment->length;
120
+
121
+ rtn_var_struct(theEnv,multifield,sizeof(struct clipsValue) * (newSize - 1),theSegment);
122
+ }
123
+
124
+ /*********************/
125
+ /* RetainMultifield: */
126
+ /*********************/
127
+ void RetainMultifield(
128
+ Environment *theEnv,
129
+ Multifield *theSegment)
130
+ {
131
+ size_t length, i;
132
+ CLIPSValue *contents;
133
+
134
+ if (theSegment == NULL) return;
135
+
136
+ length = theSegment->length;
137
+
138
+ theSegment->busyCount++;
139
+ contents = theSegment->contents;
140
+
141
+ for (i = 0 ; i < length ; i++)
142
+ { AtomInstall(theEnv,contents[i].header->type,contents[i].value); }
143
+ }
144
+
145
+ /**********************/
146
+ /* ReleaseMultifield: */
147
+ /**********************/
148
+ void ReleaseMultifield(
149
+ Environment *theEnv,
150
+ Multifield *theSegment)
151
+ {
152
+ size_t length, i;
153
+ CLIPSValue *contents;
154
+
155
+ if (theSegment == NULL) return;
156
+
157
+ length = theSegment->length;
158
+ theSegment->busyCount--;
159
+ contents = theSegment->contents;
160
+
161
+ for (i = 0 ; i < length ; i++)
162
+ { AtomDeinstall(theEnv,contents[i].header->type,contents[i].value); }
163
+ }
164
+
165
+ /************************************************/
166
+ /* IncrementCLIPSValueMultifieldReferenceCount: */
167
+ /************************************************/
168
+ void IncrementCLIPSValueMultifieldReferenceCount(
169
+ Environment *theEnv,
170
+ Multifield *theSegment)
171
+ {
172
+ size_t length, i;
173
+ CLIPSValue *contents;
174
+
175
+ if (theSegment == NULL) return;
176
+
177
+ length = theSegment->length;
178
+
179
+ theSegment->busyCount++;
180
+ contents = theSegment->contents;
181
+
182
+ for (i = 0 ; i < length ; i++)
183
+ { Retain(theEnv,contents[i].header); }
184
+ }
185
+
186
+ /************************************************/
187
+ /* DecrementCLIPSValueMultifieldReferenceCount: */
188
+ /************************************************/
189
+ void DecrementCLIPSValueMultifieldReferenceCount(
190
+ Environment *theEnv,
191
+ Multifield *theSegment)
192
+ {
193
+ size_t length, i;
194
+ CLIPSValue *contents;
195
+
196
+ if (theSegment == NULL) return;
197
+
198
+ length = theSegment->length;
199
+ theSegment->busyCount--;
200
+ contents = theSegment->contents;
201
+
202
+ for (i = 0 ; i < length ; i++)
203
+ { Release(theEnv,contents[i].header); }
204
+ }
205
+
206
+ /*******************************************************/
207
+ /* StringToMultifield: Returns a multifield structure */
208
+ /* that represents the string sent as the argument. */
209
+ /*******************************************************/
210
+ Multifield *StringToMultifield(
211
+ Environment *theEnv,
212
+ const char *theString)
213
+ {
214
+ struct token theToken;
215
+ Multifield *theSegment;
216
+ CLIPSValue *contents;
217
+ unsigned long numberOfFields = 0;
218
+ struct expr *topAtom = NULL, *lastAtom = NULL, *theAtom;
219
+
220
+ /*====================================================*/
221
+ /* Open the string as an input source and read in the */
222
+ /* list of values to be stored in the multifield. */
223
+ /*====================================================*/
224
+
225
+ OpenStringSource(theEnv,"multifield-str",theString,0);
226
+
227
+ GetToken(theEnv,"multifield-str",&theToken);
228
+ while (theToken.tknType != STOP_TOKEN)
229
+ {
230
+ if ((theToken.tknType == SYMBOL_TOKEN) || (theToken.tknType == STRING_TOKEN) ||
231
+ (theToken.tknType == FLOAT_TOKEN) || (theToken.tknType == INTEGER_TOKEN) ||
232
+ (theToken.tknType == INSTANCE_NAME_TOKEN))
233
+ { theAtom = GenConstant(theEnv,TokenTypeToType(theToken.tknType),theToken.value); }
234
+ else
235
+ { theAtom = GenConstant(theEnv,SYMBOL_TYPE,CreateSymbol(theEnv,theToken.printForm)); }
236
+
237
+ numberOfFields++;
238
+ if (topAtom == NULL) topAtom = theAtom;
239
+ else lastAtom->nextArg = theAtom;
240
+
241
+ lastAtom = theAtom;
242
+ GetToken(theEnv,"multifield-str",&theToken);
243
+ }
244
+
245
+ CloseStringSource(theEnv,"multifield-str");
246
+
247
+ /*====================================================================*/
248
+ /* Create a multifield of the appropriate size for the values parsed. */
249
+ /*====================================================================*/
250
+
251
+ theSegment = CreateMultifield(theEnv,numberOfFields);
252
+ contents = theSegment->contents;
253
+
254
+ /*====================================*/
255
+ /* Copy the values to the multifield. */
256
+ /*====================================*/
257
+
258
+ theAtom = topAtom;
259
+ numberOfFields = 0;
260
+ while (theAtom != NULL)
261
+ {
262
+ contents[numberOfFields].value = theAtom->value;
263
+ numberOfFields++;
264
+ theAtom = theAtom->nextArg;
265
+ }
266
+
267
+ /*===========================*/
268
+ /* Return the parsed values. */
269
+ /*===========================*/
270
+
271
+ ReturnExpression(theEnv,topAtom);
272
+
273
+ /*============================*/
274
+ /* Return the new multifield. */
275
+ /*============================*/
276
+
277
+ return(theSegment);
278
+ }
279
+
280
+ /**********************/
281
+ /* ArrayToMultifield: */
282
+ /**********************/
283
+ Multifield *ArrayToMultifield(
284
+ Environment *theEnv,
285
+ CLIPSValue *theArray,
286
+ unsigned long size) // TBD size_t
287
+ {
288
+ Multifield *rv;
289
+ unsigned int i;
290
+
291
+ rv = CreateMultifield(theEnv,size);
292
+
293
+ for (i = 0; i < size; i++)
294
+ { rv->contents[i].value = theArray[i].value; }
295
+
296
+ return rv;
297
+ }
298
+
299
+ /***************************************************/
300
+ /* EmptyMultifield: Creates a multifield of length */
301
+ /* 0 and adds it to the list of segments. */
302
+ /***************************************************/
303
+ Multifield *EmptyMultifield(
304
+ Environment *theEnv)
305
+ {
306
+ return CreateMultifield(theEnv,0);
307
+ }
308
+
309
+ /***********************************************************/
310
+ /* CreateMultifield: Creates a multifield of the specified */
311
+ /* size and adds it to the list of segments. */
312
+ /***********************************************************/
313
+ Multifield *CreateMultifield(
314
+ Environment *theEnv,
315
+ size_t size)
316
+ {
317
+ Multifield *theSegment;
318
+ size_t newSize;
319
+
320
+ if (size == 0) newSize = 1;
321
+ else newSize = size;
322
+
323
+ theSegment = get_var_struct(theEnv,multifield,sizeof(struct clipsValue) * (newSize - 1));
324
+
325
+ theSegment->header.type = MULTIFIELD_TYPE;
326
+ theSegment->length = size;
327
+ theSegment->busyCount = 0;
328
+ theSegment->next = NULL;
329
+
330
+ theSegment->next = UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields;
331
+ UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields = theSegment;
332
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
333
+ if (UtilityData(theEnv)->CurrentGarbageFrame->LastMultifield == NULL)
334
+ { UtilityData(theEnv)->CurrentGarbageFrame->LastMultifield = theSegment; }
335
+
336
+ return theSegment;
337
+ }
338
+
339
+ /*******************/
340
+ /* DOToMultifield: */
341
+ /*******************/
342
+ Multifield *DOToMultifield(
343
+ Environment *theEnv,
344
+ UDFValue *theValue)
345
+ {
346
+ Multifield *dst, *src;
347
+
348
+ if (theValue->header->type != MULTIFIELD_TYPE) return NULL;
349
+
350
+ dst = CreateUnmanagedMultifield(theEnv,(unsigned long) theValue->range);
351
+
352
+ src = theValue->multifieldValue;
353
+ GenCopyMemory(struct clipsValue,dst->length,
354
+ &(dst->contents[0]),&(src->contents[theValue->begin]));
355
+
356
+ return dst;
357
+ }
358
+
359
+ /************************/
360
+ /* AddToMultifieldList: */
361
+ /************************/
362
+ void AddToMultifieldList(
363
+ Environment *theEnv,
364
+ Multifield *theSegment)
365
+ {
366
+ theSegment->next = UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields;
367
+ UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields = theSegment;
368
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
369
+ if (UtilityData(theEnv)->CurrentGarbageFrame->LastMultifield == NULL)
370
+ { UtilityData(theEnv)->CurrentGarbageFrame->LastMultifield = theSegment; }
371
+ }
372
+
373
+ /*********************/
374
+ /* FlushMultifields: */
375
+ /*********************/
376
+ void FlushMultifields(
377
+ Environment *theEnv)
378
+ {
379
+ Multifield *theSegment, *nextPtr, *lastPtr = NULL;
380
+ size_t newSize;
381
+
382
+ theSegment = UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields;
383
+ while (theSegment != NULL)
384
+ {
385
+ nextPtr = theSegment->next;
386
+ if (theSegment->busyCount == 0)
387
+ {
388
+ if (theSegment->length == 0) newSize = 1;
389
+ else newSize = theSegment->length;
390
+ rtn_var_struct(theEnv,multifield,sizeof(struct clipsValue) * (newSize - 1),theSegment);
391
+ if (lastPtr == NULL) UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields = nextPtr;
392
+ else lastPtr->next = nextPtr;
393
+
394
+ /*=================================================*/
395
+ /* If the multifield deleted was the last in the */
396
+ /* list, update the pointer to the last multifield */
397
+ /* to the prior multifield. */
398
+ /*=================================================*/
399
+
400
+ if (nextPtr == NULL)
401
+ { UtilityData(theEnv)->CurrentGarbageFrame->LastMultifield = lastPtr; }
402
+ }
403
+ else
404
+ { lastPtr = theSegment; }
405
+
406
+ theSegment = nextPtr;
407
+ }
408
+ }
409
+
410
+ /********************/
411
+ /* CLIPSToUDFValue: */
412
+ /********************/
413
+ void CLIPSToUDFValue(
414
+ CLIPSValue *cv,
415
+ UDFValue *uv)
416
+ {
417
+ uv->value = cv->value;
418
+ if (cv->header->type == MULTIFIELD_TYPE)
419
+ {
420
+ uv->begin = 0;
421
+ uv->range = cv->multifieldValue->length;
422
+ }
423
+ }
424
+
425
+ /********************/
426
+ /* UDFToCLIPSValue: */
427
+ /********************/
428
+ void UDFToCLIPSValue(
429
+ Environment *theEnv,
430
+ UDFValue *uv,
431
+ CLIPSValue *cv)
432
+ {
433
+ Multifield *copy;
434
+
435
+ if (uv->header->type != MULTIFIELD_TYPE)
436
+ {
437
+ cv->value = uv->value;
438
+ return;
439
+ }
440
+
441
+ if ((uv->begin == 0) &&
442
+ (uv->range == uv->multifieldValue->length))
443
+ {
444
+ cv->multifieldValue = uv->multifieldValue;
445
+ return;
446
+ }
447
+
448
+ copy = CreateMultifield(theEnv,uv->range);
449
+ GenCopyMemory(struct clipsValue,uv->range,&copy->contents[0],
450
+ &uv->multifieldValue->contents[uv->begin]);
451
+
452
+ cv->multifieldValue = copy;
453
+ }
454
+
455
+ /************************************************/
456
+ /* NormalizeMultifield: Allocates a new segment */
457
+ /* and copies results from old value to new. */
458
+ /************************************************/
459
+ void NormalizeMultifield(
460
+ Environment *theEnv,
461
+ UDFValue *theMF)
462
+ {
463
+ Multifield *copy;
464
+
465
+ if (theMF->header->type != MULTIFIELD_TYPE) return;
466
+
467
+ if ((theMF->begin == 0) &&
468
+ (theMF->range == theMF->multifieldValue->length))
469
+ { return; }
470
+
471
+ copy = CreateMultifield(theEnv,theMF->range);
472
+ GenCopyMemory(struct clipsValue,theMF->range,&copy->contents[0],
473
+ &theMF->multifieldValue->contents[theMF->begin]);
474
+ theMF->begin = 0;
475
+ theMF->value = copy;
476
+ }
477
+
478
+ /************************************************************************/
479
+ /* DuplicateMultifield: Allocates a new segment and copies results from */
480
+ /* old value to new. This value is not put on the ListOfMultifields. */
481
+ /************************************************************************/
482
+ void DuplicateMultifield(
483
+ Environment *theEnv,
484
+ UDFValue *dst,
485
+ UDFValue *src)
486
+ {
487
+ dst->begin = 0;
488
+ dst->range = src->range;
489
+ dst->value = CreateUnmanagedMultifield(theEnv,(unsigned long) dst->range);
490
+ GenCopyMemory(struct clipsValue,dst->range,&dst->multifieldValue->contents[0],
491
+ &src->multifieldValue->contents[src->begin]);
492
+ }
493
+
494
+ /*******************/
495
+ /* CopyMultifield: */
496
+ /*******************/
497
+ Multifield *CopyMultifield(
498
+ Environment *theEnv,
499
+ Multifield *src)
500
+ {
501
+ Multifield *dst;
502
+
503
+ dst = CreateUnmanagedMultifield(theEnv,src->length);
504
+ GenCopyMemory(struct clipsValue,src->length,&(dst->contents[0]),&(src->contents[0]));
505
+ return dst;
506
+ }
507
+
508
+ /**********************************************************/
509
+ /* EphemerateMultifield: Marks the values of a multifield */
510
+ /* as ephemeral if they have not already been marker. */
511
+ /**********************************************************/
512
+ void EphemerateMultifield(
513
+ Environment *theEnv,
514
+ Multifield *theSegment)
515
+ {
516
+ size_t length, i;
517
+ CLIPSValue *contents;
518
+
519
+ if (theSegment == NULL) return;
520
+
521
+ length = theSegment->length;
522
+
523
+ contents = theSegment->contents;
524
+
525
+ for (i = 0 ; i < length ; i++)
526
+ { EphemerateValue(theEnv,contents[i].value); }
527
+ }
528
+
529
+ /*********************************************/
530
+ /* WriteMultifield: Prints out a multifield. */
531
+ /*********************************************/
532
+ void WriteMultifield(
533
+ Environment *theEnv,
534
+ const char *fileid,
535
+ Multifield *segment)
536
+ {
537
+ PrintMultifieldDriver(theEnv,fileid,segment,0,segment->length,true);
538
+ }
539
+
540
+ /***************************************************/
541
+ /* PrintMultifieldDriver: Prints out a multifield. */
542
+ /***************************************************/
543
+ void PrintMultifieldDriver(
544
+ Environment *theEnv,
545
+ const char *fileid,
546
+ Multifield *segment,
547
+ size_t begin,
548
+ size_t range,
549
+ bool printParens)
550
+ {
551
+ CLIPSValue *theMultifield;
552
+ size_t i;
553
+
554
+ theMultifield = segment->contents;
555
+
556
+ if (printParens)
557
+ { WriteString(theEnv,fileid,"("); }
558
+
559
+ for (i = 0; i < range; i++)
560
+ {
561
+ PrintAtom(theEnv,fileid,theMultifield[begin+i].header->type,theMultifield[begin+i].value);
562
+
563
+ if ((i + 1) < range)
564
+ { WriteString(theEnv,fileid," "); }
565
+ }
566
+
567
+ if (printParens)
568
+ { WriteString(theEnv,fileid,")"); }
569
+ }
570
+
571
+ /****************************************************/
572
+ /* StoreInMultifield: Append function for segments. */
573
+ /****************************************************/
574
+ void StoreInMultifield(
575
+ Environment *theEnv,
576
+ UDFValue *returnValue,
577
+ Expression *expptr,
578
+ bool garbageSegment)
579
+ {
580
+ UDFValue val_ptr;
581
+ UDFValue *val_arr;
582
+ Multifield *theMultifield;
583
+ Multifield *orig_ptr;
584
+ size_t start, range;
585
+ size_t i, j, k;
586
+ unsigned int argCount;
587
+ unsigned long seg_size;
588
+
589
+ argCount = CountArguments(expptr);
590
+
591
+ /*=========================================*/
592
+ /* If no arguments are given return a NULL */
593
+ /* multifield of length zero. */
594
+ /*=========================================*/
595
+
596
+ if (argCount == 0)
597
+ {
598
+ returnValue->begin = 0;
599
+ returnValue->range = 0;
600
+ if (garbageSegment) theMultifield = CreateMultifield(theEnv,0L);
601
+ else theMultifield = CreateUnmanagedMultifield(theEnv,0L);
602
+ returnValue->value = theMultifield;
603
+ return;
604
+ }
605
+ else
606
+ {
607
+ /*========================================*/
608
+ /* Get a new segment with length equal to */
609
+ /* the total length of all the arguments. */
610
+ /*========================================*/
611
+
612
+ val_arr = (UDFValue *) gm2(theEnv,sizeof(UDFValue) * argCount);
613
+ seg_size = 0;
614
+
615
+ for (i = 1; i <= argCount; i++, expptr = expptr->nextArg)
616
+ {
617
+ EvaluateExpression(theEnv,expptr,&val_ptr);
618
+ if (EvaluationData(theEnv)->EvaluationError)
619
+ {
620
+ returnValue->begin = 0;
621
+ returnValue->range = 0;
622
+ if (garbageSegment)
623
+ { theMultifield = CreateMultifield(theEnv,0L); }
624
+ else theMultifield = CreateUnmanagedMultifield(theEnv,0L);
625
+ returnValue->value = theMultifield;
626
+ rm(theEnv,val_arr,sizeof(UDFValue) * argCount);
627
+ return;
628
+ }
629
+ if (val_ptr.header->type == MULTIFIELD_TYPE)
630
+ {
631
+ (val_arr+i-1)->value = val_ptr.value;
632
+ start = val_ptr.begin;
633
+ range = val_ptr.range;
634
+ }
635
+ else if (val_ptr.header->type == VOID_TYPE)
636
+ {
637
+ (val_arr+i-1)->value = val_ptr.value;
638
+ start = 0;
639
+ range = 0;
640
+ }
641
+ else
642
+ {
643
+ (val_arr+i-1)->value = val_ptr.value;
644
+ start = 0;
645
+ range = 1;
646
+ }
647
+
648
+ seg_size += (unsigned long) range;
649
+ (val_arr+i-1)->begin = start;
650
+ (val_arr+i-1)->range = range;
651
+ }
652
+
653
+ if (garbageSegment)
654
+ { theMultifield = CreateMultifield(theEnv,seg_size); }
655
+ else theMultifield = CreateUnmanagedMultifield(theEnv,seg_size);
656
+
657
+ /*========================================*/
658
+ /* Copy each argument into new segment. */
659
+ /*========================================*/
660
+
661
+ for (k = 0, j = 0; k < argCount; k++)
662
+ {
663
+ if ((val_arr+k)->header->type == MULTIFIELD_TYPE)
664
+ {
665
+ start = (val_arr+k)->begin;
666
+ range = (val_arr+k)->range;
667
+ orig_ptr = (val_arr+k)->multifieldValue;
668
+ for (i = start; i < (start + range); i++, j++)
669
+ {
670
+ theMultifield->contents[j].value = orig_ptr->contents[i].value;
671
+ }
672
+ }
673
+ else if ((val_arr+k)->header->type != VOID_TYPE)
674
+ {
675
+ theMultifield->contents[j].value = (val_arr+k)->value;
676
+ j++;
677
+ }
678
+ }
679
+
680
+ /*=========================*/
681
+ /* Return the new segment. */
682
+ /*=========================*/
683
+
684
+ returnValue->begin = 0;
685
+ returnValue->range = seg_size;
686
+ returnValue->value = theMultifield;
687
+ rm(theEnv,val_arr,sizeof(UDFValue) * argCount);
688
+ return;
689
+ }
690
+ }
691
+
692
+ /*************************************************************/
693
+ /* MultifieldDOsEqual: Determines if two segments are equal. */
694
+ /*************************************************************/
695
+ bool MultifieldDOsEqual(
696
+ UDFValue *dobj1,
697
+ UDFValue *dobj2)
698
+ {
699
+ size_t extent1, extent2;
700
+ CLIPSValue *e1, *e2;
701
+
702
+ extent1 = dobj1->range;
703
+ extent2 = dobj2->range;
704
+
705
+ if (extent1 != extent2)
706
+ { return false; }
707
+
708
+ e1 = &dobj1->multifieldValue->contents[dobj1->begin];
709
+ e2 = &dobj2->multifieldValue->contents[dobj2->begin];
710
+
711
+ while (extent1 > 0)
712
+ {
713
+ if (e1->value != e2->value)
714
+ { return false; }
715
+
716
+ extent1--;
717
+
718
+ if (extent1 > 0)
719
+ {
720
+ e1++;
721
+ e2++;
722
+ }
723
+ }
724
+
725
+ return true;
726
+ }
727
+
728
+ /******************************************************************/
729
+ /* MultifieldsEqual: Determines if two multifields are identical. */
730
+ /******************************************************************/
731
+ bool MultifieldsEqual(
732
+ Multifield *segment1,
733
+ Multifield *segment2)
734
+ {
735
+ CLIPSValue *elem1;
736
+ CLIPSValue *elem2;
737
+ size_t length, i = 0;
738
+
739
+ length = segment1->length;
740
+ if (length != segment2->length)
741
+ { return false; }
742
+
743
+ elem1 = segment1->contents;
744
+ elem2 = segment2->contents;
745
+
746
+ /*==================================================*/
747
+ /* Compare each field of both facts until the facts */
748
+ /* match completely or the facts mismatch. */
749
+ /*==================================================*/
750
+
751
+ while (i < length)
752
+ {
753
+ if (elem1[i].header->type == MULTIFIELD_TYPE)
754
+ {
755
+ if (MultifieldsEqual(elem1[i].multifieldValue,
756
+ elem2[i].multifieldValue) == false)
757
+ { return false; }
758
+ }
759
+ else if (elem1[i].value != elem2[i].value)
760
+ { return false; }
761
+
762
+ i++;
763
+ }
764
+ return true;
765
+ }
766
+
767
+ /************************************************************/
768
+ /* HashMultifield: Returns the hash value for a multifield. */
769
+ /************************************************************/
770
+ size_t HashMultifield(
771
+ Multifield *theSegment,
772
+ size_t theRange)
773
+ {
774
+ size_t length, i;
775
+ size_t tvalue;
776
+ size_t count;
777
+ CLIPSValue *fieldPtr;
778
+ union
779
+ {
780
+ double fv;
781
+ void *vv;
782
+ unsigned long liv;
783
+ } fis;
784
+
785
+ /*================================================*/
786
+ /* Initialize variables for computing hash value. */
787
+ /*================================================*/
788
+
789
+ count = 0;
790
+ length = theSegment->length;
791
+ fieldPtr = theSegment->contents;
792
+
793
+ /*====================================================*/
794
+ /* Loop through each value in the multifield, compute */
795
+ /* its hash value, and add it to the running total. */
796
+ /*====================================================*/
797
+
798
+ for (i = 0;
799
+ i < length;
800
+ i++)
801
+ {
802
+ switch(fieldPtr[i].header->type)
803
+ {
804
+ case MULTIFIELD_TYPE:
805
+ count += HashMultifield(fieldPtr[i].multifieldValue,theRange);
806
+ break;
807
+
808
+ case FLOAT_TYPE:
809
+ fis.liv = 0;
810
+ fis.fv = fieldPtr[i].floatValue->contents;
811
+ count += (fis.liv * (i + 29)) +
812
+ (unsigned long) fieldPtr[i].floatValue->contents;
813
+ break;
814
+
815
+ case INTEGER_TYPE:
816
+ count += (((unsigned long) fieldPtr[i].integerValue->contents) * (i + 29)) +
817
+ ((unsigned long) fieldPtr[i].integerValue->contents);
818
+ break;
819
+
820
+ case FACT_ADDRESS_TYPE:
821
+ #if OBJECT_SYSTEM
822
+ case INSTANCE_ADDRESS_TYPE:
823
+ #endif
824
+ fis.liv = 0;
825
+ fis.vv = fieldPtr[i].value;
826
+ count += fis.liv * (i + 29);
827
+ break;
828
+
829
+ case EXTERNAL_ADDRESS_TYPE:
830
+ fis.liv = 0;
831
+ fis.vv = fieldPtr[i].externalAddressValue->contents;
832
+ count += fis.liv * (i + 29);
833
+ break;
834
+
835
+ case SYMBOL_TYPE:
836
+ case STRING_TYPE:
837
+ #if OBJECT_SYSTEM
838
+ case INSTANCE_NAME_TYPE:
839
+ #endif
840
+ tvalue = HashSymbol(fieldPtr[i].lexemeValue->contents,theRange);
841
+ count += tvalue * (i + 29);
842
+ break;
843
+ }
844
+ }
845
+
846
+ /*========================*/
847
+ /* Return the hash value. */
848
+ /*========================*/
849
+
850
+ return count;
851
+ }
852
+
853
+ /**********************/
854
+ /* GetMultifieldList: */
855
+ /**********************/
856
+ Multifield *GetMultifieldList(
857
+ Environment *theEnv)
858
+ {
859
+ return(UtilityData(theEnv)->CurrentGarbageFrame->ListOfMultifields);
860
+ }
861
+
862
+ /***************************************/
863
+ /* ImplodeMultifield: C access routine */
864
+ /* for the implode$ function. */
865
+ /***************************************/
866
+ CLIPSLexeme *ImplodeMultifield(
867
+ Environment *theEnv,
868
+ UDFValue *value)
869
+ {
870
+ size_t strsize = 0;
871
+ size_t i, j;
872
+ const char *tmp_str;
873
+ char *ret_str;
874
+ CLIPSLexeme *rv;
875
+ Multifield *theMultifield;
876
+ UDFValue tempDO;
877
+
878
+ /*===================================================*/
879
+ /* Determine the size of the string to be allocated. */
880
+ /*===================================================*/
881
+
882
+ theMultifield = value->multifieldValue;
883
+ for (i = value->begin ; i < (value->begin + value->range) ; i++)
884
+ {
885
+ if (theMultifield->contents[i].header->type == FLOAT_TYPE)
886
+ {
887
+ tmp_str = FloatToString(theEnv,theMultifield->contents[i].floatValue->contents);
888
+ strsize += strlen(tmp_str) + 1;
889
+ }
890
+ else if (theMultifield->contents[i].header->type == INTEGER_TYPE)
891
+ {
892
+ tmp_str = LongIntegerToString(theEnv,theMultifield->contents[i].integerValue->contents);
893
+ strsize += strlen(tmp_str) + 1;
894
+ }
895
+ else if (theMultifield->contents[i].header->type == STRING_TYPE)
896
+ {
897
+ strsize += strlen(theMultifield->contents[i].lexemeValue->contents) + 3;
898
+ tmp_str = theMultifield->contents[i].lexemeValue->contents;
899
+ while(*tmp_str)
900
+ {
901
+ if (*tmp_str == '"')
902
+ { strsize++; }
903
+ else if (*tmp_str == '\\') /* GDR 111599 #835 */
904
+ { strsize++; } /* GDR 111599 #835 */
905
+ tmp_str++;
906
+ }
907
+ }
908
+ else
909
+ {
910
+ tempDO.value = theMultifield->contents[i].value;
911
+ strsize += strlen(DataObjectToString(theEnv,&tempDO)) + 1;
912
+ }
913
+ }
914
+
915
+ /*=============================================*/
916
+ /* Allocate the string and copy all components */
917
+ /* of the MULTIFIELD_TYPE variable to it. */
918
+ /*=============================================*/
919
+
920
+ if (strsize == 0) return(CreateString(theEnv,""));
921
+ ret_str = (char *) gm2(theEnv,strsize);
922
+ for(j = 0, i = value->begin ; i < (value->begin + value->range) ; i++)
923
+ {
924
+ /*============================*/
925
+ /* Convert numbers to strings */
926
+ /*============================*/
927
+
928
+ if (theMultifield->contents[i].header->type == FLOAT_TYPE)
929
+ {
930
+ tmp_str = FloatToString(theEnv,theMultifield->contents[i].floatValue->contents);
931
+ while(*tmp_str)
932
+ {
933
+ *(ret_str+j) = *tmp_str;
934
+ j++;
935
+ tmp_str++;
936
+ }
937
+ }
938
+ else if (theMultifield->contents[i].header->type == INTEGER_TYPE)
939
+ {
940
+ tmp_str = LongIntegerToString(theEnv,theMultifield->contents[i].integerValue->contents);
941
+ while(*tmp_str)
942
+ {
943
+ *(ret_str+j) = *tmp_str;
944
+ j++;
945
+ tmp_str++;
946
+ }
947
+ }
948
+
949
+ /*=======================================*/
950
+ /* Enclose strings in quotes and preceed */
951
+ /* imbedded quotes with a backslash */
952
+ /*=======================================*/
953
+
954
+ else if (theMultifield->contents[i].header->type == STRING_TYPE)
955
+ {
956
+ tmp_str = theMultifield->contents[i].lexemeValue->contents;
957
+ *(ret_str+j) = '"';
958
+ j++;
959
+ while(*tmp_str)
960
+ {
961
+ if (*tmp_str == '"')
962
+ {
963
+ *(ret_str+j) = '\\';
964
+ j++;
965
+ }
966
+ else if (*tmp_str == '\\') /* GDR 111599 #835 */
967
+ { /* GDR 111599 #835 */
968
+ *(ret_str+j) = '\\'; /* GDR 111599 #835 */
969
+ j++; /* GDR 111599 #835 */
970
+ } /* GDR 111599 #835 */
971
+
972
+ *(ret_str+j) = *tmp_str;
973
+ j++;
974
+ tmp_str++;
975
+ }
976
+ *(ret_str+j) = '"';
977
+ j++;
978
+ }
979
+ else
980
+ {
981
+ tempDO.value = theMultifield->contents[i].value;
982
+ tmp_str = DataObjectToString(theEnv,&tempDO);
983
+ while(*tmp_str)
984
+ {
985
+ *(ret_str+j) = *tmp_str;
986
+ j++;
987
+ tmp_str++;
988
+ }
989
+ }
990
+ *(ret_str+j) = ' ';
991
+ j++;
992
+ }
993
+ *(ret_str+j-1) = '\0';
994
+
995
+ /*====================*/
996
+ /* Return the string. */
997
+ /*====================*/
998
+
999
+ rv = CreateString(theEnv,ret_str);
1000
+ rm(theEnv,ret_str,strsize);
1001
+ return rv;
1002
+ }
1003
+
1004
+ /****************************/
1005
+ /* CreateMultifieldBuilder: */
1006
+ /****************************/
1007
+ MultifieldBuilder *CreateMultifieldBuilder(
1008
+ Environment *theEnv,
1009
+ size_t theSize)
1010
+ {
1011
+ MultifieldBuilder *theMB;
1012
+
1013
+ theMB = get_struct(theEnv,multifieldBuilder);
1014
+
1015
+ theMB->mbEnv = theEnv;
1016
+ theMB->bufferReset = theSize;
1017
+ theMB->bufferMaximum = theSize;
1018
+ theMB->length = 0;
1019
+
1020
+ if (theSize == 0)
1021
+ { theMB->contents = NULL; }
1022
+ else
1023
+ { theMB->contents = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * theSize); }
1024
+
1025
+ return theMB;
1026
+ }
1027
+
1028
+ /*********************/
1029
+ /* MBAppendUDFValue: */
1030
+ /*********************/
1031
+ void MBAppendUDFValue(
1032
+ MultifieldBuilder *theMB,
1033
+ UDFValue *theValue)
1034
+ {
1035
+ Environment *theEnv = theMB->mbEnv;
1036
+ size_t i, neededSize, newSize;
1037
+ size_t j;
1038
+ CLIPSValue *newArray;
1039
+
1040
+ /*==============================================*/
1041
+ /* A void value can't be added to a multifield. */
1042
+ /*==============================================*/
1043
+
1044
+ if (theValue->header->type == VOID_TYPE)
1045
+ { return; }
1046
+
1047
+ /*=======================================*/
1048
+ /* Determine the amount of space needed. */
1049
+ /*=======================================*/
1050
+
1051
+ if (theValue->header->type == MULTIFIELD_TYPE)
1052
+ {
1053
+ if (theValue->range == 0)
1054
+ { return; }
1055
+
1056
+ neededSize = theMB->length + theValue->range;
1057
+ }
1058
+ else
1059
+ { neededSize = theMB->length + 1; }
1060
+
1061
+ /*============================================*/
1062
+ /* Increase the size of the buffer if needed. */
1063
+ /*============================================*/
1064
+
1065
+ if (neededSize > theMB->bufferMaximum)
1066
+ {
1067
+ newSize = neededSize * 2;
1068
+
1069
+ newArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * newSize);
1070
+
1071
+ for (i = 0; i < theMB->length; i++)
1072
+ { newArray[i] = theMB->contents[i]; }
1073
+
1074
+ if (theMB->bufferMaximum != 0)
1075
+ { rm(theMB->mbEnv,theMB->contents,sizeof(CLIPSValue) * theMB->bufferMaximum); }
1076
+
1077
+ theMB->bufferMaximum = newSize;
1078
+ theMB->contents = newArray;
1079
+ }
1080
+
1081
+ /*===================================*/
1082
+ /* Copy the new values to the array. */
1083
+ /*===================================*/
1084
+
1085
+ if (theValue->header->type == MULTIFIELD_TYPE)
1086
+ {
1087
+ for (j = theValue->begin; j < (theValue->begin +theValue->range); j++)
1088
+ {
1089
+ theMB->contents[theMB->length].value = theValue->multifieldValue->contents[j].value;
1090
+ Retain(theEnv,theMB->contents[theMB->length].header);
1091
+ theMB->length++;
1092
+ }
1093
+ }
1094
+ else
1095
+ {
1096
+ theMB->contents[theMB->length].value = theValue->value;
1097
+ Retain(theEnv,theMB->contents[theMB->length].header);
1098
+ theMB->length++;
1099
+ }
1100
+ }
1101
+
1102
+ /*************/
1103
+ /* MBAppend: */
1104
+ /*************/
1105
+ void MBAppend(
1106
+ MultifieldBuilder *theMB,
1107
+ CLIPSValue *theValue)
1108
+ {
1109
+ Environment *theEnv = theMB->mbEnv;
1110
+ size_t i, neededSize, newSize;
1111
+ size_t j;
1112
+ CLIPSValue *newArray;
1113
+
1114
+ /*==============================================*/
1115
+ /* A void value can't be added to a multifield. */
1116
+ /*==============================================*/
1117
+
1118
+ if (theValue->header->type == VOID_TYPE)
1119
+ { return; }
1120
+
1121
+ /*=======================================*/
1122
+ /* Determine the amount of space needed. */
1123
+ /*=======================================*/
1124
+
1125
+ if (theValue->header->type == MULTIFIELD_TYPE)
1126
+ {
1127
+ if (theValue->multifieldValue->length == 0)
1128
+ { return; }
1129
+
1130
+ neededSize = theMB->length + theValue->multifieldValue->length;
1131
+ }
1132
+ else
1133
+ { neededSize = theMB->length + 1; }
1134
+
1135
+ /*============================================*/
1136
+ /* Increase the size of the buffer if needed. */
1137
+ /*============================================*/
1138
+
1139
+ if (neededSize > theMB->bufferMaximum)
1140
+ {
1141
+ newSize = neededSize * 2;
1142
+
1143
+ newArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * newSize);
1144
+
1145
+ for (i = 0; i < theMB->length; i++)
1146
+ { newArray[i] = theMB->contents[i]; }
1147
+
1148
+ if (theMB->bufferMaximum != 0)
1149
+ { rm(theMB->mbEnv,theMB->contents,sizeof(CLIPSValue) * theMB->bufferMaximum); }
1150
+
1151
+ theMB->bufferMaximum = newSize;
1152
+ theMB->contents = newArray;
1153
+ }
1154
+
1155
+ /*===================================*/
1156
+ /* Copy the new values to the array. */
1157
+ /*===================================*/
1158
+
1159
+ if (theValue->header->type == MULTIFIELD_TYPE)
1160
+ {
1161
+ for (j = 0; j < theValue->multifieldValue->length; j++)
1162
+ {
1163
+ theMB->contents[theMB->length].value = theValue->multifieldValue->contents[j].value;
1164
+ Retain(theEnv,theMB->contents[theMB->length].header);
1165
+ theMB->length++;
1166
+ }
1167
+ }
1168
+ else
1169
+ {
1170
+ theMB->contents[theMB->length].value = theValue->value;
1171
+ Retain(theEnv,theMB->contents[theMB->length].header);
1172
+ theMB->length++;
1173
+ }
1174
+ }
1175
+
1176
+ /*************************/
1177
+ /* MBAppendCLIPSInteger: */
1178
+ /*************************/
1179
+ void MBAppendCLIPSInteger(
1180
+ MultifieldBuilder *theMB,
1181
+ CLIPSInteger *pv)
1182
+ {
1183
+ CLIPSValue theValue;
1184
+
1185
+ theValue.integerValue = pv;
1186
+ MBAppend(theMB,&theValue);
1187
+ }
1188
+
1189
+ /********************/
1190
+ /* MBAppendInteger: */
1191
+ /********************/
1192
+ void MBAppendInteger(
1193
+ MultifieldBuilder *theMB,
1194
+ long long intValue)
1195
+ {
1196
+ CLIPSValue theValue;
1197
+ CLIPSInteger *pv = CreateInteger(theMB->mbEnv,intValue);
1198
+
1199
+ theValue.integerValue = pv;
1200
+ MBAppend(theMB,&theValue);
1201
+ }
1202
+
1203
+ /***********************/
1204
+ /* MBAppendCLIPSFloat: */
1205
+ /***********************/
1206
+ void MBAppendCLIPSFloat(
1207
+ MultifieldBuilder *theMB,
1208
+ CLIPSFloat *pv)
1209
+ {
1210
+ CLIPSValue theValue;
1211
+
1212
+ theValue.floatValue = pv;
1213
+ MBAppend(theMB,&theValue);
1214
+ }
1215
+
1216
+ /******************/
1217
+ /* MBAppendFloat: */
1218
+ /******************/
1219
+ void MBAppendFloat(
1220
+ MultifieldBuilder *theMB,
1221
+ double floatValue)
1222
+ {
1223
+ CLIPSValue theValue;
1224
+ CLIPSFloat *pv = CreateFloat(theMB->mbEnv,floatValue);
1225
+
1226
+ theValue.floatValue = pv;
1227
+ MBAppend(theMB,&theValue);
1228
+ }
1229
+
1230
+ /************************/
1231
+ /* MBAppendCLIPSLexeme: */
1232
+ /************************/
1233
+ void MBAppendCLIPSLexeme(
1234
+ MultifieldBuilder *theMB,
1235
+ CLIPSLexeme *pv)
1236
+ {
1237
+ CLIPSValue theValue;
1238
+
1239
+ theValue.lexemeValue = pv;
1240
+ MBAppend(theMB,&theValue);
1241
+ }
1242
+
1243
+ /*******************/
1244
+ /* MBAppendSymbol: */
1245
+ /*******************/
1246
+ void MBAppendSymbol(
1247
+ MultifieldBuilder *theMB,
1248
+ const char *strValue)
1249
+ {
1250
+ CLIPSValue theValue;
1251
+ CLIPSLexeme *pv = CreateSymbol(theMB->mbEnv,strValue);
1252
+
1253
+ theValue.lexemeValue = pv;
1254
+ MBAppend(theMB,&theValue);
1255
+ }
1256
+
1257
+ /*******************/
1258
+ /* MBAppendString: */
1259
+ /*******************/
1260
+ void MBAppendString(
1261
+ MultifieldBuilder *theMB,
1262
+ const char *strValue)
1263
+ {
1264
+ CLIPSValue theValue;
1265
+ CLIPSLexeme *pv = CreateString(theMB->mbEnv,strValue);
1266
+
1267
+ theValue.lexemeValue = pv;
1268
+ MBAppend(theMB,&theValue);
1269
+ }
1270
+
1271
+ /*************************/
1272
+ /* MBAppendInstanceName: */
1273
+ /*************************/
1274
+ void MBAppendInstanceName(
1275
+ MultifieldBuilder *theMB,
1276
+ const char *strValue)
1277
+ {
1278
+ CLIPSValue theValue;
1279
+ CLIPSLexeme *pv = CreateInstanceName(theMB->mbEnv,strValue);
1280
+
1281
+ theValue.lexemeValue = pv;
1282
+ MBAppend(theMB,&theValue);
1283
+ }
1284
+
1285
+ /*********************************/
1286
+ /* MBAppendCLIPSExternalAddress: */
1287
+ /*********************************/
1288
+ void MBAppendCLIPSExternalAddress(
1289
+ MultifieldBuilder *theMB,
1290
+ CLIPSExternalAddress *pv)
1291
+ {
1292
+ CLIPSValue theValue;
1293
+
1294
+ theValue.externalAddressValue = pv;
1295
+ MBAppend(theMB,&theValue);
1296
+ }
1297
+
1298
+ /*****************/
1299
+ /* MBAppendFact: */
1300
+ /*****************/
1301
+ void MBAppendFact(
1302
+ MultifieldBuilder *theMB,
1303
+ Fact *pv)
1304
+ {
1305
+ CLIPSValue theValue;
1306
+
1307
+ theValue.factValue = pv;
1308
+ MBAppend(theMB,&theValue);
1309
+ }
1310
+
1311
+ /*********************/
1312
+ /* MBAppendInstance: */
1313
+ /*********************/
1314
+ void MBAppendInstance(
1315
+ MultifieldBuilder *theMB,
1316
+ Instance *pv)
1317
+ {
1318
+ CLIPSValue theValue;
1319
+
1320
+ theValue.instanceValue = pv;
1321
+ MBAppend(theMB,&theValue);
1322
+ }
1323
+
1324
+ /***********************/
1325
+ /* MBAppendMultifield: */
1326
+ /***********************/
1327
+ void MBAppendMultifield(
1328
+ MultifieldBuilder *theMB,
1329
+ Multifield *pv)
1330
+ {
1331
+ CLIPSValue theValue;
1332
+
1333
+ theValue.multifieldValue = pv;
1334
+ MBAppend(theMB,&theValue);
1335
+ }
1336
+
1337
+ /*************/
1338
+ /* MBCreate: */
1339
+ /*************/
1340
+ Multifield *MBCreate(
1341
+ MultifieldBuilder *theMB)
1342
+ {
1343
+ size_t i;
1344
+ Multifield *rv;
1345
+
1346
+ rv = CreateMultifield(theMB->mbEnv,theMB->length);
1347
+
1348
+ if (rv == NULL) return NULL;
1349
+
1350
+ for (i = 0; i < theMB->length; i++)
1351
+ {
1352
+ rv->contents[i].value = theMB->contents[i].value;
1353
+ Release(theMB->mbEnv,rv->contents[i].header);
1354
+ }
1355
+
1356
+ theMB->length = 0;
1357
+
1358
+ return rv;
1359
+ }
1360
+
1361
+ /************/
1362
+ /* MBReset: */
1363
+ /************/
1364
+ void MBReset(
1365
+ MultifieldBuilder *theMB)
1366
+ {
1367
+ size_t i;
1368
+
1369
+ for (i = 0; i < theMB->length; i++)
1370
+ { Release(theMB->mbEnv,theMB->contents[i].header); }
1371
+
1372
+ if (theMB->bufferReset != theMB->bufferMaximum)
1373
+ {
1374
+ if (theMB->bufferMaximum != 0)
1375
+ { rm(theMB->mbEnv,theMB->contents,sizeof(CLIPSValue) * theMB->bufferMaximum); }
1376
+
1377
+ if (theMB->bufferReset == 0)
1378
+ { theMB->contents = NULL; }
1379
+ else
1380
+ { theMB->contents = (CLIPSValue *) gm2(theMB->mbEnv,sizeof(CLIPSValue) * theMB->bufferReset); }
1381
+
1382
+ theMB->bufferMaximum = theMB->bufferReset;
1383
+ }
1384
+
1385
+ theMB->length = 0;
1386
+ }
1387
+
1388
+ /**************/
1389
+ /* MBDispose: */
1390
+ /**************/
1391
+ void MBDispose(
1392
+ MultifieldBuilder *theMB)
1393
+ {
1394
+ Environment *theEnv = theMB->mbEnv;
1395
+ size_t i;
1396
+
1397
+ for (i = 0; i < theMB->length; i++)
1398
+ { Release(theMB->mbEnv,theMB->contents[i].header); }
1399
+
1400
+ if (theMB->bufferMaximum != 0)
1401
+ { rm(theMB->mbEnv,theMB->contents,sizeof(CLIPSValue) * theMB->bufferMaximum); }
1402
+
1403
+ rtn_struct(theEnv,multifieldBuilder,theMB);
1404
+ }