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,2550 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.41 03/11/23 */
5
+ /* */
6
+ /* INSTANCE PRIMITIVE SUPPORT MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Creation and Deletion of Instances Routines */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Brian L. Dantes */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* */
17
+ /* */
18
+ /* Revision History: */
19
+ /* */
20
+ /* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
21
+ /* */
22
+ /* 6.24: Removed LOGICAL_DEPENDENCIES compilation flag. */
23
+ /* */
24
+ /* Converted INSTANCE_PATTERN_MATCHING to */
25
+ /* DEFRULE_CONSTRUCT. */
26
+ /* */
27
+ /* Renamed BOOLEAN macro type to intBool. */
28
+ /* */
29
+ /* 6.30: Changed integer type/precision. */
30
+ /* */
31
+ /* Used gensprintf instead of sprintf. */
32
+ /* */
33
+ /* Changed garbage collection algorithm. */
34
+ /* */
35
+ /* Added const qualifiers to remove C++ */
36
+ /* deprecation warnings. */
37
+ /* */
38
+ /* Newly created instances can no longer use */
39
+ /* a preexisting instance name of another class */
40
+ /* [INSMNGR16]. */
41
+ /* */
42
+ /* 6.31: Marked deleted instances so that partial */
43
+ /* matches will not be propagated when the match */
44
+ /* is based on both the existence and */
45
+ /* non-existence of an instance. */
46
+ /* */
47
+ /* 6.32: Fixed instance redefinition crash with rules */
48
+ /* in JNSimpleCompareFunction1 when deleted */
49
+ /* instance slots are referenced. */
50
+ /* */
51
+ /* 6.40: Added Env prefix to GetEvaluationError and */
52
+ /* SetEvaluationError functions. */
53
+ /* */
54
+ /* Pragma once and other inclusion changes. */
55
+ /* */
56
+ /* Added support for booleans with <stdbool.h>. */
57
+ /* */
58
+ /* Removed use of void pointers for specific */
59
+ /* data structures. */
60
+ /* */
61
+ /* UDF redesign. */
62
+ /* */
63
+ /* 6.41: Instance builders and modifiers were not */
64
+ /* allocating storage for inherited slots. */
65
+ /* */
66
+ /* Removed unnecessary variable initialization */
67
+ /* in IBAbort. */
68
+ /* */
69
+ /* Calling IMPutSlot with empty multifield to */
70
+ /* multifield slot did not assign value. */
71
+ /* */
72
+ /*************************************************************/
73
+
74
+ /* =========================================
75
+ *****************************************
76
+ EXTERNAL DEFINITIONS
77
+ =========================================
78
+ ***************************************** */
79
+ #include "setup.h"
80
+
81
+ #if OBJECT_SYSTEM
82
+
83
+ #if DEFRULE_CONSTRUCT
84
+ #include "network.h"
85
+ #include "drive.h"
86
+ #include "objrtmch.h"
87
+ #include "lgcldpnd.h"
88
+ #include "objrtfnx.h"
89
+ #endif
90
+
91
+ #include "classcom.h"
92
+ #include "classfun.h"
93
+ #include "cstrnchk.h"
94
+ #include "engine.h"
95
+ #include "envrnmnt.h"
96
+ #include "extnfunc.h"
97
+ #include "insfun.h"
98
+ #include "memalloc.h"
99
+ #include "miscfun.h"
100
+ #include "modulutl.h"
101
+ #include "msgcom.h"
102
+ #include "msgfun.h"
103
+ #include "prccode.h"
104
+ #include "prntutil.h"
105
+ #include "router.h"
106
+ #include "sysdep.h"
107
+ #include "utility.h"
108
+
109
+ #include "insmngr.h"
110
+
111
+ #include "inscom.h"
112
+ #include "watch.h"
113
+
114
+ /* =========================================
115
+ *****************************************
116
+ CONSTANTS
117
+ =========================================
118
+ ***************************************** */
119
+ #define MAKE_TRACE "==>"
120
+ #define UNMAKE_TRACE "<=="
121
+
122
+ /***************************************/
123
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
124
+ /***************************************/
125
+
126
+ static Instance *NewInstance(Environment *);
127
+ static Instance *InstanceLocationInfo(Environment *,Defclass *,CLIPSLexeme *,Instance **,
128
+ unsigned *);
129
+ static void InstallInstance(Environment *,Instance *,bool);
130
+ static void BuildDefaultSlots(Environment *,bool);
131
+ static bool CoreInitializeInstance(Environment *,Instance *,Expression *);
132
+ static bool CoreInitializeInstanceCV(Environment *,Instance *,CLIPSValue *);
133
+ static bool InsertSlotOverrides(Environment *,Instance *,Expression *);
134
+ static bool InsertSlotOverridesCV(Environment *,Instance *,CLIPSValue *);
135
+ static void EvaluateClassDefaults(Environment *,Instance *);
136
+ static bool IMModifySlots(Environment *,Instance *,CLIPSValue *);
137
+
138
+ #if DEBUGGING_FUNCTIONS
139
+ static void PrintInstanceWatch(Environment *,const char *,Instance *);
140
+ #endif
141
+
142
+ /* =========================================
143
+ *****************************************
144
+ EXTERNALLY VISIBLE FUNCTIONS
145
+ =========================================
146
+ ***************************************** */
147
+
148
+ /***********************************************************
149
+ NAME : InitializeInstanceCommand
150
+ DESCRIPTION : Initializes an instance of a class
151
+ INPUTS : The address of the result value
152
+ RETURNS : Nothing useful
153
+ SIDE EFFECTS : Instance intialized
154
+ NOTES : H/L Syntax:
155
+ (active-initialize-instance <instance-name>
156
+ <slot-override>*)
157
+ ***********************************************************/
158
+ void InitializeInstanceCommand(
159
+ Environment *theEnv,
160
+ UDFContext *context,
161
+ UDFValue *returnValue)
162
+ {
163
+ Instance *ins;
164
+
165
+ returnValue->lexemeValue = FalseSymbol(theEnv);
166
+ ins = CheckInstance(context);
167
+ if (ins == NULL)
168
+ return;
169
+ if (CoreInitializeInstance(theEnv,ins,GetFirstArgument()->nextArg) == true)
170
+ { returnValue->value = ins->name; }
171
+ }
172
+
173
+ /****************************************************************
174
+ NAME : MakeInstanceCommand
175
+ DESCRIPTION : Creates and initializes an instance of a class
176
+ INPUTS : The address of the result value
177
+ RETURNS : Nothing useful
178
+ SIDE EFFECTS : Instance intialized
179
+ NOTES : H/L Syntax:
180
+ (active-make-instance <instance-name> of <class>
181
+ <slot-override>*)
182
+ CHANGES : It's now possible to create an instance of a
183
+ class that's not in scope if the module name
184
+ is specified.
185
+ ****************************************************************/
186
+ void MakeInstanceCommand(
187
+ Environment *theEnv,
188
+ UDFContext *context,
189
+ UDFValue *returnValue)
190
+ {
191
+ CLIPSLexeme *iname;
192
+ Instance *ins;
193
+ UDFValue temp;
194
+ Defclass *cls;
195
+
196
+ returnValue->lexemeValue = FalseSymbol(theEnv);
197
+ EvaluateExpression(theEnv,GetFirstArgument(),&temp);
198
+
199
+ if (temp.header->type == INSTANCE_NAME_TYPE)
200
+ { iname = temp.lexemeValue; }
201
+ else if (temp.header->type == SYMBOL_TYPE)
202
+ { iname = CreateInstanceName(theEnv,temp.lexemeValue->contents); }
203
+ else
204
+ {
205
+ PrintErrorID(theEnv,"INSMNGR",1,false);
206
+ WriteString(theEnv,STDERR,"Expected a valid name for new instance.\n");
207
+ SetEvaluationError(theEnv,true);
208
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
209
+ return;
210
+ }
211
+
212
+ if (GetFirstArgument()->nextArg->type == DEFCLASS_PTR)
213
+ cls = (Defclass *) GetFirstArgument()->nextArg->value;
214
+ else
215
+ {
216
+ EvaluateExpression(theEnv,GetFirstArgument()->nextArg,&temp);
217
+ if (temp.header->type != SYMBOL_TYPE)
218
+ {
219
+ PrintErrorID(theEnv,"INSMNGR",2,false);
220
+ WriteString(theEnv,STDERR,"Expected a valid class name for new instance.\n");
221
+ SetEvaluationError(theEnv,true);
222
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
223
+ return;
224
+ }
225
+
226
+ cls = LookupDefclassByMdlOrScope(theEnv,temp.lexemeValue->contents); // Module or scope is now allowed
227
+
228
+ if (cls == NULL)
229
+ {
230
+ ClassExistError(theEnv,ExpressionFunctionCallName(EvaluationData(theEnv)->CurrentExpression)->contents,
231
+ temp.lexemeValue->contents);
232
+ SetEvaluationError(theEnv,true);
233
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
234
+ return;
235
+ }
236
+ }
237
+
238
+ ins = BuildInstance(theEnv,iname,cls,true);
239
+ if (ins == NULL) return;
240
+
241
+ if (CoreInitializeInstance(theEnv,ins,GetFirstArgument()->nextArg->nextArg) == true)
242
+ { returnValue->value = GetFullInstanceName(theEnv,ins); }
243
+ else
244
+ QuashInstance(theEnv,ins);
245
+ }
246
+
247
+ /***************************************************
248
+ NAME : GetFullInstanceName
249
+ DESCRIPTION : If this function is called while
250
+ the current module is other than
251
+ the one in which the instance
252
+ resides, then the module name is
253
+ prepended to the instance name.
254
+ Otherwise - the base name only is
255
+ returned.
256
+ INPUTS : The instance
257
+ RETURNS : The instance name symbol (with
258
+ module name and :: prepended)
259
+ SIDE EFFECTS : Temporary buffer allocated possibly
260
+ and new symbol created
261
+ NOTES : Used to differentiate between
262
+ instances of the same name in
263
+ different modules.
264
+ Instances are now global in scope so
265
+ each instance name must belong to a
266
+ single instance. It's no longer
267
+ necessary to return the full instance
268
+ name.
269
+ ***************************************************/
270
+ CLIPSLexeme *GetFullInstanceName(
271
+ Environment *theEnv,
272
+ Instance *ins)
273
+ {
274
+ if (ins == &InstanceData(theEnv)->DummyInstance)
275
+ { return CreateInstanceName(theEnv,"Dummy Instance"); }
276
+
277
+ return ins->name;
278
+ }
279
+
280
+ /***************************************************
281
+ NAME : BuildInstance
282
+ DESCRIPTION : Creates an uninitialized instance
283
+ INPUTS : 1) Name of the instance
284
+ 2) Class pointer
285
+ 3) Flag indicating whether init
286
+ message will be called for
287
+ this instance or not
288
+ RETURNS : The address of the new instance,
289
+ NULL on errors (or when a
290
+ a logical basis in a rule was
291
+ deleted int the same RHS in
292
+ which the instance creation
293
+ occurred)
294
+ SIDE EFFECTS : Old definition (if any) is deleted
295
+ NOTES : None
296
+ ***************************************************/
297
+ Instance *BuildInstance(
298
+ Environment *theEnv,
299
+ CLIPSLexeme *iname,
300
+ Defclass *cls,
301
+ bool initMessage)
302
+ {
303
+ Instance *ins,*iprv;
304
+ unsigned hashTableIndex;
305
+ unsigned modulePosition;
306
+ CLIPSLexeme *moduleName;
307
+ UDFValue temp;
308
+
309
+ if (iname->header.type == SYMBOL_TYPE)
310
+ { iname = CreateInstanceName(theEnv,iname->contents); }
311
+
312
+ #if DEFRULE_CONSTRUCT
313
+ if (EngineData(theEnv)->JoinOperationInProgress && cls->reactive)
314
+ {
315
+ PrintErrorID(theEnv,"INSMNGR",10,false);
316
+ WriteString(theEnv,STDERR,"Cannot create instances of reactive classes while ");
317
+ WriteString(theEnv,STDERR,"pattern-matching is in process.\n");
318
+ SetEvaluationError(theEnv,true);
319
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
320
+ return NULL;
321
+ }
322
+ #endif
323
+ if (cls->abstract)
324
+ {
325
+ PrintErrorID(theEnv,"INSMNGR",3,false);
326
+ WriteString(theEnv,STDERR,"Cannot create instances of abstract class '");
327
+ WriteString(theEnv,STDERR,DefclassName(cls));
328
+ WriteString(theEnv,STDERR,"'.\n");
329
+ SetEvaluationError(theEnv,true);
330
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
331
+ return NULL;
332
+ }
333
+ modulePosition = FindModuleSeparator(iname->contents);
334
+ if (modulePosition)
335
+ {
336
+ moduleName = ExtractModuleName(theEnv,modulePosition,iname->contents);
337
+ if ((moduleName == NULL) ||
338
+ (moduleName != cls->header.whichModule->theModule->header.name))
339
+ {
340
+ PrintErrorID(theEnv,"INSMNGR",11,true);
341
+ WriteString(theEnv,STDERR,"Invalid module specifier in new instance name.\n");
342
+ SetEvaluationError(theEnv,true);
343
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
344
+ return NULL;
345
+ }
346
+ iname = ExtractConstructName(theEnv,modulePosition,iname->contents,INSTANCE_NAME_TYPE);
347
+ }
348
+ ins = InstanceLocationInfo(theEnv,cls,iname,&iprv,&hashTableIndex);
349
+
350
+ if (ins != NULL)
351
+ {
352
+ if (ins->cls != cls)
353
+ {
354
+ PrintErrorID(theEnv,"INSMNGR",16,false);
355
+ WriteString(theEnv,STDERR,"The instance name [");
356
+ WriteString(theEnv,STDERR,iname->contents);
357
+ WriteString(theEnv,STDERR,"] is in use by an instance of class '");
358
+ WriteString(theEnv,STDERR,ins->cls->header.name->contents);
359
+ WriteString(theEnv,STDERR,"'.\n");
360
+ SetEvaluationError(theEnv,true);
361
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
362
+ return NULL;
363
+ }
364
+
365
+ if (ins->installed == 0)
366
+ {
367
+ PrintErrorID(theEnv,"INSMNGR",4,false);
368
+ WriteString(theEnv,STDERR,"The instance [");
369
+ WriteString(theEnv,STDERR,iname->contents);
370
+ WriteString(theEnv,STDERR,"] has a slot-value which depends on the instance definition.\n");
371
+ SetEvaluationError(theEnv,true);
372
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
373
+ return NULL;
374
+ }
375
+ ins->busy++;
376
+ IncrementLexemeCount(iname);
377
+ if (ins->garbage == 0)
378
+ {
379
+ if (InstanceData(theEnv)->MkInsMsgPass)
380
+ DirectMessage(theEnv,MessageHandlerData(theEnv)->DELETE_SYMBOL,ins,NULL,NULL);
381
+ else
382
+ QuashInstance(theEnv,ins);
383
+ }
384
+ ins->busy--;
385
+ ReleaseLexeme(theEnv,iname);
386
+ if (ins->garbage == 0)
387
+ {
388
+ PrintErrorID(theEnv,"INSMNGR",5,false);
389
+ WriteString(theEnv,STDERR,"Unable to delete old instance [");
390
+ WriteString(theEnv,STDERR,iname->contents);
391
+ WriteString(theEnv,STDERR,"].\n");
392
+ SetEvaluationError(theEnv,true);
393
+ InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
394
+ return NULL;
395
+ }
396
+ }
397
+
398
+ /* =============================================================
399
+ Create the base instance from the defaults of the inheritance
400
+ precedence list
401
+ ============================================================= */
402
+ InstanceData(theEnv)->CurrentInstance = NewInstance(theEnv);
403
+
404
+ #if DEFRULE_CONSTRUCT
405
+ /* ==============================================
406
+ Add this new instance as a dependent to
407
+ any currently active basis - if the partial
408
+ match was deleted, abort the instance creation
409
+ ============================================== */
410
+ if (AddLogicalDependencies(theEnv,(struct patternEntity *) InstanceData(theEnv)->CurrentInstance,false)
411
+ == false)
412
+ {
413
+ rtn_struct(theEnv,instance,InstanceData(theEnv)->CurrentInstance);
414
+ InstanceData(theEnv)->CurrentInstance = NULL;
415
+ return NULL;
416
+ }
417
+ #endif
418
+
419
+ InstanceData(theEnv)->CurrentInstance->name = iname;
420
+ InstanceData(theEnv)->CurrentInstance->cls = cls;
421
+ BuildDefaultSlots(theEnv,initMessage);
422
+
423
+ /* ============================================================
424
+ Put the instance in the instance hash table and put it on its
425
+ class's instance list
426
+ ============================================================ */
427
+ InstanceData(theEnv)->CurrentInstance->hashTableIndex = hashTableIndex;
428
+ if (iprv == NULL)
429
+ {
430
+ InstanceData(theEnv)->CurrentInstance->nxtHash = InstanceData(theEnv)->InstanceTable[hashTableIndex];
431
+ if (InstanceData(theEnv)->InstanceTable[hashTableIndex] != NULL)
432
+ InstanceData(theEnv)->InstanceTable[hashTableIndex]->prvHash = InstanceData(theEnv)->CurrentInstance;
433
+ InstanceData(theEnv)->InstanceTable[hashTableIndex] = InstanceData(theEnv)->CurrentInstance;
434
+ }
435
+ else
436
+ {
437
+ InstanceData(theEnv)->CurrentInstance->nxtHash = iprv->nxtHash;
438
+ if (iprv->nxtHash != NULL)
439
+ iprv->nxtHash->prvHash = InstanceData(theEnv)->CurrentInstance;
440
+ iprv->nxtHash = InstanceData(theEnv)->CurrentInstance;
441
+ InstanceData(theEnv)->CurrentInstance->prvHash = iprv;
442
+ }
443
+
444
+ /* ======================================
445
+ Put instance in global and class lists
446
+ ====================================== */
447
+ if (InstanceData(theEnv)->CurrentInstance->cls->instanceList == NULL)
448
+ InstanceData(theEnv)->CurrentInstance->cls->instanceList = InstanceData(theEnv)->CurrentInstance;
449
+ else
450
+ InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom->nxtClass = InstanceData(theEnv)->CurrentInstance;
451
+ InstanceData(theEnv)->CurrentInstance->prvClass = InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom;
452
+ InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom = InstanceData(theEnv)->CurrentInstance;
453
+
454
+ if (InstanceData(theEnv)->InstanceList == NULL)
455
+ InstanceData(theEnv)->InstanceList = InstanceData(theEnv)->CurrentInstance;
456
+ else
457
+ InstanceData(theEnv)->InstanceListBottom->nxtList = InstanceData(theEnv)->CurrentInstance;
458
+ InstanceData(theEnv)->CurrentInstance->prvList = InstanceData(theEnv)->InstanceListBottom;
459
+ InstanceData(theEnv)->InstanceListBottom = InstanceData(theEnv)->CurrentInstance;
460
+ InstanceData(theEnv)->ChangesToInstances = true;
461
+
462
+ /* ==============================================================================
463
+ Install the instance's name and slot-value symbols (prevent them from becoming
464
+ ephemeral) - the class name and slot names are accounted for by the class
465
+ ============================================================================== */
466
+ InstallInstance(theEnv,InstanceData(theEnv)->CurrentInstance,true);
467
+
468
+ ins = InstanceData(theEnv)->CurrentInstance;
469
+ InstanceData(theEnv)->CurrentInstance = NULL;
470
+
471
+ if (InstanceData(theEnv)->MkInsMsgPass)
472
+ { DirectMessage(theEnv,MessageHandlerData(theEnv)->CREATE_SYMBOL,ins,&temp,NULL); }
473
+
474
+ #if DEFRULE_CONSTRUCT
475
+ if (ins->cls->reactive)
476
+ ObjectNetworkAction(theEnv,OBJECT_ASSERT,ins,-1);
477
+ #endif
478
+
479
+ if (EvaluationData(theEnv)->EvaluationError)
480
+ { InstanceData(theEnv)->makeInstanceError = MIE_RULE_NETWORK_ERROR; }
481
+ else
482
+ { InstanceData(theEnv)->makeInstanceError = MIE_NO_ERROR; }
483
+
484
+ return ins;
485
+ }
486
+
487
+ /*****************************************************************************
488
+ NAME : InitSlotsCommand
489
+ DESCRIPTION : Calls Kernel Expression Evaluator EvaluateExpression
490
+ for each expression-value of an instance expression
491
+
492
+ Evaluates default slots only - slots that were specified
493
+ by overrides (sp->override == 1) are ignored)
494
+ INPUTS : 1) Instance address
495
+ RETURNS : Nothing useful
496
+ SIDE EFFECTS : Each UDFValue slot in the instance's slot array is replaced
497
+ by the evaluation (by EvaluateExpression) of the expression
498
+ in the slot list. The old expression-values
499
+ are deleted.
500
+ NOTES : H/L Syntax: (init-slots <instance>)
501
+ *****************************************************************************/
502
+ void InitSlotsCommand(
503
+ Environment *theEnv,
504
+ UDFContext *context,
505
+ UDFValue *returnValue)
506
+ {
507
+ EvaluationData(theEnv)->EvaluationError = false;
508
+
509
+ if (CheckCurrentMessage(theEnv,"init-slots",true) == false)
510
+ {
511
+ returnValue->lexemeValue = FalseSymbol(theEnv);
512
+ return;
513
+ }
514
+
515
+ EvaluateClassDefaults(theEnv,GetActiveInstance(theEnv));
516
+
517
+ if (! EvaluationData(theEnv)->EvaluationError)
518
+ { returnValue->instanceValue = GetActiveInstance(theEnv); }
519
+ else
520
+ { returnValue->lexemeValue = FalseSymbol(theEnv); }
521
+ }
522
+
523
+ /******************************************************
524
+ NAME : QuashInstance
525
+ DESCRIPTION : Deletes an instance if it is not in
526
+ use, otherwise sticks it on the
527
+ garbage list
528
+ INPUTS : The instance
529
+ RETURNS : 1 if successful, 0 otherwise
530
+ SIDE EFFECTS : Instance deleted or added to garbage
531
+ NOTES : Even though the instance is removed
532
+ from the class list, hash table and
533
+ instance list, its links remain
534
+ unchanged so that outside loops
535
+ can still determine where the next
536
+ node in the list is (assuming the
537
+ instance was garbage collected).
538
+ ******************************************************/
539
+ UnmakeInstanceError QuashInstance(
540
+ Environment *theEnv,
541
+ Instance *ins)
542
+ {
543
+ int iflag;
544
+ IGARBAGE *gptr;
545
+
546
+ #if DEFRULE_CONSTRUCT
547
+ int syncFlag;
548
+
549
+ if (EngineData(theEnv)->JoinOperationInProgress && ins->cls->reactive)
550
+ {
551
+ PrintErrorID(theEnv,"INSMNGR",12,false);
552
+ WriteString(theEnv,STDERR,"Cannot delete instances of reactive classes while ");
553
+ WriteString(theEnv,STDERR,"pattern-matching is in process.\n");
554
+ SetEvaluationError(theEnv,true);
555
+ InstanceData(theEnv)->unmakeInstanceError = UIE_COULD_NOT_DELETE_ERROR;
556
+ return UIE_COULD_NOT_DELETE_ERROR;
557
+ }
558
+ #endif
559
+
560
+ if (ins->garbage == 1)
561
+ {
562
+ InstanceData(theEnv)->unmakeInstanceError = UIE_COULD_NOT_DELETE_ERROR;
563
+ return UIE_DELETED_ERROR;
564
+ }
565
+
566
+ if (ins->installed == 0)
567
+ {
568
+ PrintErrorID(theEnv,"INSMNGR",6,false);
569
+ WriteString(theEnv,STDERR,"Cannot delete instance [");
570
+ WriteString(theEnv,STDERR,ins->name->contents);
571
+ WriteString(theEnv,STDERR,"] during initialization.\n");
572
+ SetEvaluationError(theEnv,true);
573
+ InstanceData(theEnv)->unmakeInstanceError = UIE_COULD_NOT_DELETE_ERROR;
574
+ return UIE_COULD_NOT_DELETE_ERROR;
575
+ }
576
+
577
+ #if DEBUGGING_FUNCTIONS
578
+ if (ins->cls->traceInstances)
579
+ PrintInstanceWatch(theEnv,UNMAKE_TRACE,ins);
580
+ #endif
581
+
582
+ #if DEFRULE_CONSTRUCT
583
+ syncFlag = ins->reteSynchronized;
584
+ RemoveEntityDependencies(theEnv,(struct patternEntity *) ins);
585
+
586
+ if (ins->cls->reactive)
587
+ {
588
+ ins->garbage = 1;
589
+ ObjectNetworkAction(theEnv,OBJECT_RETRACT,ins,-1);
590
+ ins->garbage = 0;
591
+ }
592
+ #endif
593
+
594
+ if (ins->prvHash != NULL)
595
+ ins->prvHash->nxtHash = ins->nxtHash;
596
+ else
597
+ InstanceData(theEnv)->InstanceTable[ins->hashTableIndex] = ins->nxtHash;
598
+ if (ins->nxtHash != NULL)
599
+ ins->nxtHash->prvHash = ins->prvHash;
600
+
601
+ if (ins->prvClass != NULL)
602
+ ins->prvClass->nxtClass = ins->nxtClass;
603
+ else
604
+ ins->cls->instanceList = ins->nxtClass;
605
+ if (ins->nxtClass != NULL)
606
+ ins->nxtClass->prvClass = ins->prvClass;
607
+ else
608
+ ins->cls->instanceListBottom = ins->prvClass;
609
+
610
+ if (ins->prvList != NULL)
611
+ ins->prvList->nxtList = ins->nxtList;
612
+ else
613
+ InstanceData(theEnv)->InstanceList = ins->nxtList;
614
+ if (ins->nxtList != NULL)
615
+ ins->nxtList->prvList = ins->prvList;
616
+ else
617
+ InstanceData(theEnv)->InstanceListBottom = ins->prvList;
618
+
619
+ iflag = ins->installed;
620
+ InstallInstance(theEnv,ins,false);
621
+
622
+ /* ==============================================
623
+ If the instance is the basis for an executing
624
+ rule, don't bother deleting its slots yet, for
625
+ they may still be needed by pattern variables
626
+ ============================================== */
627
+
628
+ #if DEFRULE_CONSTRUCT
629
+ if ((iflag == 1) && (ins->patternHeader.busyCount == 0))
630
+ {
631
+ if ((ObjectReteData(theEnv)->DelayObjectPatternMatching == false) ||
632
+ (syncFlag == false))
633
+ { RemoveInstanceData(theEnv,ins); }
634
+ else
635
+ { ins->dataRemovalDeferred = true; }
636
+ }
637
+ #else
638
+ if (iflag == 1)
639
+ { RemoveInstanceData(theEnv,ins); }
640
+ #endif
641
+
642
+ if ((ins->busy == 0) &&
643
+ (InstanceData(theEnv)->MaintainGarbageInstances == false)
644
+ #if DEFRULE_CONSTRUCT
645
+ && (ins->patternHeader.busyCount == 0)
646
+ #endif
647
+ )
648
+ {
649
+ ReleaseLexeme(theEnv,ins->name);
650
+ rtn_struct(theEnv,instance,ins);
651
+ }
652
+ else
653
+ {
654
+ gptr = get_struct(theEnv,igarbage);
655
+ ins->garbage = 1;
656
+ gptr->ins = ins;
657
+ gptr->nxt = InstanceData(theEnv)->InstanceGarbageList;
658
+ InstanceData(theEnv)->InstanceGarbageList = gptr;
659
+ UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
660
+ }
661
+
662
+ InstanceData(theEnv)->ChangesToInstances = true;
663
+
664
+ if (EvaluationData(theEnv)->EvaluationError)
665
+ {
666
+ InstanceData(theEnv)->unmakeInstanceError = UIE_RULE_NETWORK_ERROR;
667
+ return UIE_RULE_NETWORK_ERROR;
668
+ }
669
+
670
+ InstanceData(theEnv)->unmakeInstanceError = UIE_NO_ERROR;
671
+ return UIE_NO_ERROR;
672
+ }
673
+
674
+
675
+ #if DEFRULE_CONSTRUCT
676
+
677
+ /****************************************************
678
+ NAME : InactiveInitializeInstance
679
+ DESCRIPTION : Initializes an instance of a class
680
+ Pattern-matching is automatically
681
+ delayed until the instance is
682
+ completely initialized
683
+ INPUTS : The address of the result value
684
+ RETURNS : Nothing useful
685
+ SIDE EFFECTS : Instance intialized
686
+ NOTES : H/L Syntax:
687
+ (initialize-instance <instance-name>
688
+ <slot-override>*)
689
+ ****************************************************/
690
+ void InactiveInitializeInstance(
691
+ Environment *theEnv,
692
+ UDFContext *context,
693
+ UDFValue *returnValue)
694
+ {
695
+ bool ov;
696
+
697
+ ov = SetDelayObjectPatternMatching(theEnv,true);
698
+ InitializeInstanceCommand(theEnv,context,returnValue);
699
+ SetDelayObjectPatternMatching(theEnv,ov);
700
+ }
701
+
702
+ /**************************************************************
703
+ NAME : InactiveMakeInstance
704
+ DESCRIPTION : Creates and initializes an instance of a class
705
+ Pattern-matching is automatically
706
+ delayed until the instance is
707
+ completely initialized
708
+ INPUTS : The address of the result value
709
+ RETURNS : Nothing useful
710
+ SIDE EFFECTS : Instance intialized
711
+ NOTES : H/L Syntax:
712
+ (make-instance <instance-name> of <class>
713
+ <slot-override>*)
714
+ **************************************************************/
715
+ void InactiveMakeInstance(
716
+ Environment *theEnv,
717
+ UDFContext *context,
718
+ UDFValue *returnValue)
719
+ {
720
+ bool ov;
721
+
722
+ ov = SetDelayObjectPatternMatching(theEnv,true);
723
+ MakeInstanceCommand(theEnv,context,returnValue);
724
+ SetDelayObjectPatternMatching(theEnv,ov);
725
+ }
726
+
727
+ #endif
728
+
729
+ /* =========================================
730
+ *****************************************
731
+ INTERNALLY VISIBLE FUNCTIONS
732
+ =========================================
733
+ ***************************************** */
734
+
735
+ /********************************************************
736
+ NAME : NewInstance
737
+ DESCRIPTION : Allocates and initializes a new instance
738
+ INPUTS : None
739
+ RETURNS : The address of the new instance
740
+ SIDE EFFECTS : None
741
+ NOTES : None
742
+ ********************************************************/
743
+ static Instance *NewInstance(
744
+ Environment *theEnv)
745
+ {
746
+ Instance *instance;
747
+
748
+ instance = get_struct(theEnv,instance);
749
+ #if DEFRULE_CONSTRUCT
750
+ instance->patternHeader.theInfo = &InstanceData(theEnv)->InstanceInfo;
751
+
752
+ instance->patternHeader.dependents = NULL;
753
+ instance->patternHeader.busyCount = 0;
754
+ instance->patternHeader.timeTag = 0L;
755
+
756
+ instance->partialMatchList = NULL;
757
+ instance->basisSlots = NULL;
758
+ instance->reteSynchronized = false;
759
+ instance->dataRemovalDeferred = false;
760
+ #endif
761
+ instance->patternHeader.header.type = INSTANCE_ADDRESS_TYPE;
762
+ instance->busy = 0;
763
+ instance->installed = 0;
764
+ instance->garbage = 0;
765
+ instance->initSlotsCalled = 0;
766
+ instance->initializeInProgress = 0;
767
+ instance->name = NULL;
768
+ instance->hashTableIndex = 0;
769
+ instance->cls = NULL;
770
+ instance->slots = NULL;
771
+ instance->slotAddresses = NULL;
772
+ instance->prvClass = NULL;
773
+ instance->nxtClass = NULL;
774
+ instance->prvHash = NULL;
775
+ instance->nxtHash = NULL;
776
+ instance->prvList = NULL;
777
+ instance->nxtList = NULL;
778
+ return(instance);
779
+ }
780
+
781
+ /*****************************************************************
782
+ NAME : InstanceLocationInfo
783
+ DESCRIPTION : Determines where a specified instance belongs
784
+ in the instance hash table
785
+ INPUTS : 1) The class of the new instance
786
+ 2) The symbol for the name of the instance
787
+ 3) Caller's buffer for previous node address
788
+ 4) Caller's buffer for hash value
789
+ RETURNS : The address of the found instance, NULL otherwise
790
+ SIDE EFFECTS : None
791
+ NOTES : Instance names only have to be unique within
792
+ a module.
793
+ Change: instance names must be unique regardless
794
+ of module.
795
+ *****************************************************************/
796
+ static Instance *InstanceLocationInfo(
797
+ Environment *theEnv,
798
+ Defclass *cls,
799
+ CLIPSLexeme *iname,
800
+ Instance **prv,
801
+ unsigned *hashTableIndex)
802
+ {
803
+ Instance *ins;
804
+
805
+ *hashTableIndex = HashInstance(iname);
806
+ ins = InstanceData(theEnv)->InstanceTable[*hashTableIndex];
807
+
808
+ /* ========================================
809
+ Make sure all instances of the same name
810
+ are grouped together regardless of what
811
+ module their classes are in
812
+ ======================================== */
813
+ *prv = NULL;
814
+ while (ins != NULL)
815
+ {
816
+ if (ins->name == iname)
817
+ { return(ins); }
818
+ *prv = ins;
819
+ ins = ins->nxtHash;
820
+ }
821
+
822
+ /*
823
+ while ((ins != NULL) ? (ins->name != iname) : false)
824
+ {
825
+ *prv = ins;
826
+ ins = ins->nxtHash;
827
+ }
828
+ while ((ins != NULL) ? (ins->name == iname) : false)
829
+ {
830
+ if (ins->cls->header.whichModule->theModule ==
831
+ cls->header.whichModule->theModule)
832
+ return(ins);
833
+ *prv = ins;
834
+ ins = ins->nxtHash;
835
+ }
836
+ */
837
+ return NULL;
838
+ }
839
+
840
+ /********************************************************
841
+ NAME : InstallInstance
842
+ DESCRIPTION : Prevent name and slot value symbols
843
+ from being ephemeral (all others
844
+ taken care of by class defn)
845
+ INPUTS : 1) The address of the instance
846
+ 2) A flag indicating whether to
847
+ install or deinstall
848
+ RETURNS : Nothing useful
849
+ SIDE EFFECTS : Symbol counts incremented or decremented
850
+ NOTES : Slot symbol installations are handled
851
+ by PutSlotValue
852
+ ********************************************************/
853
+ static void InstallInstance(
854
+ Environment *theEnv,
855
+ Instance *ins,
856
+ bool set)
857
+ {
858
+ if (set == true)
859
+ {
860
+ if (ins->installed)
861
+ return;
862
+ #if DEBUGGING_FUNCTIONS
863
+ if (ins->cls->traceInstances)
864
+ PrintInstanceWatch(theEnv,MAKE_TRACE,ins);
865
+ #endif
866
+ ins->installed = 1;
867
+ IncrementLexemeCount(ins->name);
868
+ IncrementDefclassBusyCount(theEnv,ins->cls);
869
+ InstanceData(theEnv)->GlobalNumberOfInstances++;
870
+ }
871
+ else
872
+ {
873
+ if (! ins->installed)
874
+ return;
875
+ ins->installed = 0;
876
+ InstanceData(theEnv)->GlobalNumberOfInstances--;
877
+
878
+ /* =======================================
879
+ Class counts is decremented by
880
+ RemoveInstanceData() when slot data is
881
+ truly deleted - and name count is
882
+ deleted by CleanupInstances() or
883
+ QuashInstance() when instance is
884
+ truly deleted
885
+ ======================================= */
886
+ }
887
+ }
888
+
889
+ /****************************************************************
890
+ NAME : BuildDefaultSlots
891
+ DESCRIPTION : The current instance's address is
892
+ in the global variable CurrentInstance.
893
+ This builds the slots and the default values
894
+ from the direct class of the instance and its
895
+ inheritances.
896
+ INPUTS : Flag indicating whether init message will be
897
+ called for this instance or not
898
+ RETURNS : Nothing useful
899
+ SIDE EFFECTS : Allocates the slot array for
900
+ the current instance
901
+ NOTES : The current instance's address is
902
+ stored in a global variable
903
+ ****************************************************************/
904
+ static void BuildDefaultSlots(
905
+ Environment *theEnv,
906
+ bool initMessage)
907
+ {
908
+ unsigned i,j;
909
+ unsigned scnt;
910
+ unsigned lscnt;
911
+ InstanceSlot *dst = NULL,**adst;
912
+ SlotDescriptor **src;
913
+
914
+ scnt = InstanceData(theEnv)->CurrentInstance->cls->instanceSlotCount;
915
+ lscnt = InstanceData(theEnv)->CurrentInstance->cls->localInstanceSlotCount;
916
+ if (scnt > 0)
917
+ {
918
+ InstanceData(theEnv)->CurrentInstance->slotAddresses = adst =
919
+ (InstanceSlot **) gm2(theEnv,(sizeof(InstanceSlot *) * scnt));
920
+ if (lscnt != 0)
921
+ InstanceData(theEnv)->CurrentInstance->slots = dst =
922
+ (InstanceSlot *) gm2(theEnv,(sizeof(InstanceSlot) * lscnt));
923
+ src = InstanceData(theEnv)->CurrentInstance->cls->instanceTemplate;
924
+
925
+ /* ==================================================
926
+ A map of slot addresses is created - shared slots
927
+ point at values in the class, and local slots
928
+ point at values in the instance
929
+
930
+ Also - slots are always given an initial value
931
+ (since slots cannot be unbound). If there is
932
+ already an instance of a class with a shared slot,
933
+ that value is left alone
934
+ ================================================== */
935
+ for (i = 0 , j = 0 ; i < scnt ; i++)
936
+ {
937
+ if (src[i]->shared)
938
+ {
939
+ src[i]->sharedCount++;
940
+ adst[i] = &(src[i]->sharedValue);
941
+ }
942
+ else
943
+ {
944
+ dst[j].desc = src[i];
945
+ dst[j].value = NULL;
946
+ adst[i] = &dst[j++];
947
+ }
948
+ if (adst[i]->value == NULL)
949
+ {
950
+ adst[i]->valueRequired = initMessage;
951
+ if (adst[i]->desc->multiple)
952
+ {
953
+ adst[i]->type = MULTIFIELD_TYPE;
954
+ adst[i]->value = CreateUnmanagedMultifield(theEnv,0L);
955
+ RetainMultifield(theEnv,adst[i]->multifieldValue);
956
+ }
957
+ else
958
+ {
959
+ adst[i]->type = SYMBOL_TYPE;
960
+ adst[i]->value = CreateSymbol(theEnv,"nil");
961
+ AtomInstall(theEnv,adst[i]->type,adst[i]->value);
962
+ }
963
+ }
964
+ else
965
+ adst[i]->valueRequired = false;
966
+ adst[i]->override = false;
967
+ }
968
+ }
969
+ }
970
+
971
+ /*******************************************************************
972
+ NAME : CoreInitializeInstance
973
+ DESCRIPTION : Performs the core work for initializing an instance
974
+ INPUTS : 1) The instance address
975
+ 2) Slot override expressions
976
+ RETURNS : True if all OK, false otherwise
977
+ SIDE EFFECTS : EvaluationError set on errors - slots evaluated
978
+ NOTES : None
979
+ *******************************************************************/
980
+ static bool CoreInitializeInstance(
981
+ Environment *theEnv,
982
+ Instance *ins,
983
+ Expression *ovrexp)
984
+ {
985
+ UDFValue temp;
986
+
987
+ if (ins->installed == 0)
988
+ {
989
+ PrintErrorID(theEnv,"INSMNGR",7,false);
990
+ WriteString(theEnv,STDERR,"Instance [");
991
+ WriteString(theEnv,STDERR,ins->name->contents);
992
+ WriteString(theEnv,STDERR,"] is already being initialized.\n");
993
+ SetEvaluationError(theEnv,true);
994
+ return false;
995
+ }
996
+
997
+ /* =======================================================
998
+ Replace all default-slot values with any slot-overrides
999
+ ======================================================= */
1000
+ ins->busy++;
1001
+ ins->installed = 0;
1002
+
1003
+ /* =================================================================
1004
+ If the slots are initialized properly - the initializeInProgress
1005
+ flag will be turned off.
1006
+ ================================================================= */
1007
+ ins->initializeInProgress = 1;
1008
+ ins->initSlotsCalled = 0;
1009
+
1010
+ if (InsertSlotOverrides(theEnv,ins,ovrexp) == false)
1011
+ {
1012
+ ins->installed = 1;
1013
+ ins->busy--;
1014
+ return false;
1015
+ }
1016
+
1017
+ /* =================================================================
1018
+ Now that all the slot expressions are established - replace them
1019
+ with their evaluation
1020
+ ================================================================= */
1021
+
1022
+ if (InstanceData(theEnv)->MkInsMsgPass)
1023
+ DirectMessage(theEnv,MessageHandlerData(theEnv)->INIT_SYMBOL,ins,&temp,NULL);
1024
+ else
1025
+ EvaluateClassDefaults(theEnv,ins);
1026
+
1027
+ ins->busy--;
1028
+ ins->installed = 1;
1029
+ if (EvaluationData(theEnv)->EvaluationError)
1030
+ {
1031
+ PrintErrorID(theEnv,"INSMNGR",8,false);
1032
+ WriteString(theEnv,STDERR,"An error occurred during the initialization of instance [");
1033
+ WriteString(theEnv,STDERR,ins->name->contents);
1034
+ WriteString(theEnv,STDERR,"].\n");
1035
+ return false;
1036
+ }
1037
+
1038
+ ins->initializeInProgress = 0;
1039
+ return (ins->initSlotsCalled == 0) ? false : true;
1040
+ }
1041
+
1042
+ /*******************************************************************
1043
+ NAME : CoreInitializeInstanceCV
1044
+ DESCRIPTION : Performs the core work for initializing an instance
1045
+ INPUTS : 1) The instance address
1046
+ 2) Slot override CLIPSValues
1047
+ RETURNS : True if all OK, false otherwise
1048
+ SIDE EFFECTS : EvaluationError set on errors - slots evaluated
1049
+ NOTES : None
1050
+ *******************************************************************/
1051
+ static bool CoreInitializeInstanceCV(
1052
+ Environment *theEnv,
1053
+ Instance *ins,
1054
+ CLIPSValue *overrides)
1055
+ {
1056
+ UDFValue temp;
1057
+
1058
+ if (ins->installed == 0)
1059
+ {
1060
+ PrintErrorID(theEnv,"INSMNGR",7,false);
1061
+ WriteString(theEnv,STDERR,"Instance ");
1062
+ WriteString(theEnv,STDERR,ins->name->contents);
1063
+ WriteString(theEnv,STDERR," is already being initialized.\n");
1064
+ SetEvaluationError(theEnv,true);
1065
+ return false;
1066
+ }
1067
+
1068
+ /*==========================================================*/
1069
+ /* Replace all default-slot values with any slot-overrides. */
1070
+ /*==========================================================*/
1071
+
1072
+ ins->busy++;
1073
+ ins->installed = 0;
1074
+
1075
+ /*===============================================*/
1076
+ /* If the slots are initialized properly - the */
1077
+ /* initializeInProgress flag will be turned off. */
1078
+ /*===============================================*/
1079
+
1080
+ ins->initializeInProgress = 1;
1081
+ ins->initSlotsCalled = 0;
1082
+
1083
+ if (InsertSlotOverridesCV(theEnv,ins,overrides) == false)
1084
+ {
1085
+ ins->installed = 1;
1086
+ ins->busy--;
1087
+ return false;
1088
+ }
1089
+
1090
+ /*====================================================*/
1091
+ /* Now that all the slot expressions are established, */
1092
+ /* replace them with their evaluation. */
1093
+ /*====================================================*/
1094
+
1095
+ if (InstanceData(theEnv)->MkInsMsgPass)
1096
+ { DirectMessage(theEnv,MessageHandlerData(theEnv)->INIT_SYMBOL,ins,&temp,NULL); }
1097
+ else
1098
+ { EvaluateClassDefaults(theEnv,ins); }
1099
+
1100
+ ins->busy--;
1101
+ ins->installed = 1;
1102
+ if (EvaluationData(theEnv)->EvaluationError)
1103
+ {
1104
+ PrintErrorID(theEnv,"INSMNGR",8,false);
1105
+ WriteString(theEnv,STDERR,"An error occurred during the initialization of instance [");
1106
+ WriteString(theEnv,STDERR,ins->name->contents);
1107
+ WriteString(theEnv,STDERR,"].\n");
1108
+ return false;
1109
+ }
1110
+
1111
+ ins->initializeInProgress = 0;
1112
+ return (ins->initSlotsCalled == 0) ? false : true;
1113
+ }
1114
+
1115
+ /**********************************************************
1116
+ NAME : InsertSlotOverrides
1117
+ DESCRIPTION : Replaces value-expression for a slot
1118
+ INPUTS : 1) The instance address
1119
+ 2) The address of the beginning of the
1120
+ list of slot-expressions
1121
+ RETURNS : True if all okay, false otherwise
1122
+ SIDE EFFECTS : Old slot expression deallocated
1123
+ NOTES : Assumes symbols not yet installed
1124
+ EVALUATES the slot-name expression but
1125
+ simply copies the slot value-expression
1126
+ **********************************************************/
1127
+ static bool InsertSlotOverrides(
1128
+ Environment *theEnv,
1129
+ Instance *ins,
1130
+ Expression *slot_exp)
1131
+ {
1132
+ InstanceSlot *slot;
1133
+ UDFValue temp, junk;
1134
+
1135
+ EvaluationData(theEnv)->EvaluationError = false;
1136
+ while (slot_exp != NULL)
1137
+ {
1138
+ if ((EvaluateExpression(theEnv,slot_exp,&temp) == true) ? true :
1139
+ (temp.header->type != SYMBOL_TYPE))
1140
+ {
1141
+ PrintErrorID(theEnv,"INSMNGR",9,false);
1142
+ WriteString(theEnv,STDERR,"Expected a valid slot name for slot-override.\n");
1143
+ SetEvaluationError(theEnv,true);
1144
+ return false;
1145
+ }
1146
+ slot = FindInstanceSlot(theEnv,ins,temp.lexemeValue);
1147
+ if (slot == NULL)
1148
+ {
1149
+ PrintErrorID(theEnv,"INSMNGR",13,false);
1150
+ WriteString(theEnv,STDERR,"Slot '");
1151
+ WriteString(theEnv,STDERR,temp.lexemeValue->contents);
1152
+ WriteString(theEnv,STDERR,"' does not exist in instance [");
1153
+ WriteString(theEnv,STDERR,ins->name->contents);
1154
+ WriteString(theEnv,STDERR,"].\n");
1155
+ SetEvaluationError(theEnv,true);
1156
+ return false;
1157
+ }
1158
+
1159
+ if (InstanceData(theEnv)->MkInsMsgPass)
1160
+ { DirectMessage(theEnv,slot->desc->overrideMessage,
1161
+ ins,NULL,slot_exp->nextArg->argList); }
1162
+ else if (slot_exp->nextArg->argList)
1163
+ {
1164
+ if (EvaluateAndStoreInDataObject(theEnv,slot->desc->multiple,
1165
+ slot_exp->nextArg->argList,&temp,true))
1166
+ PutSlotValue(theEnv,ins,slot,&temp,&junk,"function make-instance");
1167
+ }
1168
+ else
1169
+ {
1170
+ temp.begin = 0;
1171
+ temp.range = 0;
1172
+ temp.value = ProceduralPrimitiveData(theEnv)->NoParamValue;
1173
+ PutSlotValue(theEnv,ins,slot,&temp,&junk,"function make-instance");
1174
+ }
1175
+
1176
+ if (EvaluationData(theEnv)->EvaluationError)
1177
+ return false;
1178
+ slot->override = true;
1179
+ slot_exp = slot_exp->nextArg->nextArg;
1180
+ }
1181
+ return true;
1182
+ }
1183
+
1184
+ /**********************************************************
1185
+ NAME : InsertSlotOverridesCV
1186
+ DESCRIPTION : Replaces value-expression for a slot
1187
+ INPUTS : 1) The instance address
1188
+ 2) The address of the beginning of the
1189
+ list of slot-expressions
1190
+ RETURNS : True if all okay, false otherwise
1191
+ SIDE EFFECTS : Old slot expression deallocated
1192
+ NOTES : Assumes symbols not yet installed
1193
+ EVALUATES the slot-name expression but
1194
+ simply copies the slot value-expression
1195
+ **********************************************************/
1196
+ static bool InsertSlotOverridesCV(
1197
+ Environment *theEnv,
1198
+ Instance *ins,
1199
+ CLIPSValue *overrides)
1200
+ {
1201
+ unsigned int i;
1202
+ InstanceSlot *slot;
1203
+ UDFValue temp, junk;
1204
+
1205
+ EvaluationData(theEnv)->EvaluationError = false;
1206
+
1207
+ for (i = 0; i < ins->cls->instanceSlotCount; i++)
1208
+ {
1209
+ if (overrides[i].value == VoidConstant(theEnv)) continue;
1210
+
1211
+ slot = ins->slotAddresses[i];
1212
+ CLIPSToUDFValue(&overrides[i],&temp);
1213
+ PutSlotValue(theEnv,ins,slot,&temp,&junk,"InstanceBuilder call");
1214
+
1215
+ if (EvaluationData(theEnv)->EvaluationError)
1216
+ { return false; }
1217
+
1218
+ slot->override = true;
1219
+ }
1220
+
1221
+ return true;
1222
+ }
1223
+
1224
+ /*****************************************************************************
1225
+ NAME : EvaluateClassDefaults
1226
+ DESCRIPTION : Evaluates default slots only - slots that were specified
1227
+ by overrides (sp->override == 1) are ignored)
1228
+ INPUTS : 1) Instance address
1229
+ RETURNS : Nothing useful
1230
+ SIDE EFFECTS : Each UDFValue slot in the instance's slot array is replaced
1231
+ by the evaluation (by EvaluateExpression) of the expression
1232
+ in the slot list. The old expression-values
1233
+ are deleted.
1234
+ NOTES : None
1235
+ *****************************************************************************/
1236
+ static void EvaluateClassDefaults(
1237
+ Environment *theEnv,
1238
+ Instance *ins)
1239
+ {
1240
+ InstanceSlot *slot;
1241
+ UDFValue temp,junk;
1242
+ unsigned long i;
1243
+
1244
+ if (ins->initializeInProgress == 0)
1245
+ {
1246
+ PrintErrorID(theEnv,"INSMNGR",15,false);
1247
+ SetEvaluationError(theEnv,true);
1248
+ WriteString(theEnv,STDERR,"init-slots not valid in this context.\n");
1249
+ return;
1250
+ }
1251
+ for (i = 0 ; i < ins->cls->instanceSlotCount ; i++)
1252
+ {
1253
+ slot = ins->slotAddresses[i];
1254
+
1255
+ /* ===========================================================
1256
+ Slot-overrides are just a short-hand for put-slots, so they
1257
+ should be done with messages. Defaults are from the class
1258
+ definition and can be placed directly.
1259
+ =========================================================== */
1260
+ if (!slot->override)
1261
+ {
1262
+ if (slot->desc->dynamicDefault)
1263
+ {
1264
+ if (EvaluateAndStoreInDataObject(theEnv,slot->desc->multiple,
1265
+ (Expression *) slot->desc->defaultValue,
1266
+ &temp,true))
1267
+ PutSlotValue(theEnv,ins,slot,&temp,&junk,"function init-slots");
1268
+ }
1269
+ else if (((slot->desc->shared == 0) || (slot->desc->sharedCount == 1)) &&
1270
+ (slot->desc->noDefault == 0))
1271
+ DirectPutSlotValue(theEnv,ins,slot,(UDFValue *) slot->desc->defaultValue,&junk);
1272
+ else if (slot->valueRequired)
1273
+ {
1274
+ PrintErrorID(theEnv,"INSMNGR",14,false);
1275
+ WriteString(theEnv,STDERR,"Override required for slot '");
1276
+ WriteString(theEnv,STDERR,slot->desc->slotName->name->contents);
1277
+ WriteString(theEnv,STDERR,"' in instance [");
1278
+ WriteString(theEnv,STDERR,ins->name->contents);
1279
+ WriteString(theEnv,STDERR,"].\n");
1280
+ SetEvaluationError(theEnv,true);
1281
+ }
1282
+ slot->valueRequired = false;
1283
+ if (ins->garbage == 1)
1284
+ {
1285
+ WriteString(theEnv,STDERR,ins->name->contents);
1286
+ WriteString(theEnv,STDERR," instance deleted by slot-override evaluation.\n");
1287
+ SetEvaluationError(theEnv,true);
1288
+ }
1289
+ if (EvaluationData(theEnv)->EvaluationError)
1290
+ return;
1291
+ }
1292
+ slot->override = false;
1293
+ }
1294
+ ins->initSlotsCalled = 1;
1295
+ }
1296
+
1297
+ #if DEBUGGING_FUNCTIONS
1298
+
1299
+ /***************************************************
1300
+ NAME : PrintInstanceWatch
1301
+ DESCRIPTION : Prints out a trace message for the
1302
+ creation/deletion of an instance
1303
+ INPUTS : 1) The trace string indicating if
1304
+ this is a creation or deletion
1305
+ 2) The instance
1306
+ RETURNS : Nothing usful
1307
+ SIDE EFFECTS : Watch message printed
1308
+ NOTES : None
1309
+ ***************************************************/
1310
+ static void PrintInstanceWatch(
1311
+ Environment *theEnv,
1312
+ const char *traceString,
1313
+ Instance *theInstance)
1314
+ {
1315
+ if (ConstructData(theEnv)->ClearReadyInProgress ||
1316
+ ConstructData(theEnv)->ClearInProgress)
1317
+ { return; }
1318
+
1319
+ WriteString(theEnv,STDOUT,traceString);
1320
+ WriteString(theEnv,STDOUT," instance ");
1321
+ PrintInstanceNameAndClass(theEnv,STDOUT,theInstance,true);
1322
+ }
1323
+
1324
+ #endif
1325
+
1326
+ /**************************/
1327
+ /* CreateInstanceBuilder: */
1328
+ /**************************/
1329
+ InstanceBuilder *CreateInstanceBuilder(
1330
+ Environment *theEnv,
1331
+ const char *defclassName)
1332
+ {
1333
+ InstanceBuilder *theIB;
1334
+ Defclass *theDefclass;
1335
+ unsigned int i;
1336
+
1337
+ if (theEnv == NULL) return NULL;
1338
+
1339
+ if (defclassName != NULL)
1340
+ {
1341
+ theDefclass = FindDefclass(theEnv,defclassName);
1342
+ if (theDefclass == NULL)
1343
+ {
1344
+ InstanceData(theEnv)->instanceBuilderError = IBE_DEFCLASS_NOT_FOUND_ERROR;
1345
+ return NULL;
1346
+ }
1347
+ }
1348
+ else
1349
+ { theDefclass = NULL; }
1350
+
1351
+ theIB = get_struct(theEnv,instanceBuilder);
1352
+ theIB->ibEnv = theEnv;
1353
+ theIB->ibDefclass = theDefclass;
1354
+
1355
+ if ((theDefclass == NULL) || (theDefclass->instanceSlotCount == 0))
1356
+ { theIB->ibValueArray = NULL; }
1357
+ else
1358
+ {
1359
+ theIB->ibValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * theDefclass->instanceSlotCount);
1360
+
1361
+ for (i = 0; i < theDefclass->instanceSlotCount; i++)
1362
+ { theIB->ibValueArray[i].voidValue = VoidConstant(theEnv); }
1363
+ }
1364
+
1365
+ InstanceData(theEnv)->instanceBuilderError = IBE_NO_ERROR;
1366
+
1367
+ return theIB;
1368
+ }
1369
+
1370
+ /*************************/
1371
+ /* IBPutSlotCLIPSInteger */
1372
+ /*************************/
1373
+ PutSlotError IBPutSlotCLIPSInteger(
1374
+ InstanceBuilder *theIB,
1375
+ const char *slotName,
1376
+ CLIPSInteger *slotValue)
1377
+ {
1378
+ CLIPSValue theValue;
1379
+
1380
+ theValue.integerValue = slotValue;
1381
+ return IBPutSlot(theIB,slotName,&theValue);
1382
+ }
1383
+
1384
+ /********************/
1385
+ /* IBPutSlotInteger */
1386
+ /********************/
1387
+ PutSlotError IBPutSlotInteger(
1388
+ InstanceBuilder *theIB,
1389
+ const char *slotName,
1390
+ long long longLongValue)
1391
+ {
1392
+ CLIPSValue theValue;
1393
+
1394
+ if (theIB == NULL)
1395
+ { return PSE_NULL_POINTER_ERROR; }
1396
+
1397
+ theValue.integerValue = CreateInteger(theIB->ibEnv,longLongValue);
1398
+ return IBPutSlot(theIB,slotName,&theValue);
1399
+ }
1400
+
1401
+ /************************/
1402
+ /* IBPutSlotCLIPSLexeme */
1403
+ /************************/
1404
+ PutSlotError IBPutSlotCLIPSLexeme(
1405
+ InstanceBuilder *theIB,
1406
+ const char *slotName,
1407
+ CLIPSLexeme *slotValue)
1408
+ {
1409
+ CLIPSValue theValue;
1410
+
1411
+ theValue.lexemeValue = slotValue;
1412
+ return IBPutSlot(theIB,slotName,&theValue);
1413
+ }
1414
+
1415
+ /*******************/
1416
+ /* IBPutSlotSymbol */
1417
+ /*******************/
1418
+ PutSlotError IBPutSlotSymbol(
1419
+ InstanceBuilder *theIB,
1420
+ const char *slotName,
1421
+ const char *stringValue)
1422
+ {
1423
+ CLIPSValue theValue;
1424
+
1425
+ if (theIB == NULL)
1426
+ { return PSE_NULL_POINTER_ERROR; }
1427
+
1428
+ theValue.lexemeValue = CreateSymbol(theIB->ibEnv,stringValue);
1429
+ return IBPutSlot(theIB,slotName,&theValue);
1430
+ }
1431
+
1432
+ /*******************/
1433
+ /* IBPutSlotString */
1434
+ /*******************/
1435
+ PutSlotError IBPutSlotString(
1436
+ InstanceBuilder *theIB,
1437
+ const char *slotName,
1438
+ const char *stringValue)
1439
+ {
1440
+ CLIPSValue theValue;
1441
+
1442
+ if (theIB == NULL)
1443
+ { return PSE_NULL_POINTER_ERROR; }
1444
+
1445
+ theValue.lexemeValue = CreateString(theIB->ibEnv,stringValue);
1446
+ return IBPutSlot(theIB,slotName,&theValue);
1447
+ }
1448
+
1449
+ /*************************/
1450
+ /* IBPutSlotInstanceName */
1451
+ /*************************/
1452
+ PutSlotError IBPutSlotInstanceName(
1453
+ InstanceBuilder *theIB,
1454
+ const char *slotName,
1455
+ const char *stringValue)
1456
+ {
1457
+ CLIPSValue theValue;
1458
+
1459
+ if (theIB == NULL)
1460
+ { return PSE_NULL_POINTER_ERROR; }
1461
+
1462
+ theValue.lexemeValue = CreateInstanceName(theIB->ibEnv,stringValue);
1463
+ return IBPutSlot(theIB,slotName,&theValue);
1464
+ }
1465
+
1466
+ /***********************/
1467
+ /* IBPutSlotCLIPSFloat */
1468
+ /***********************/
1469
+ PutSlotError IBPutSlotCLIPSFloat(
1470
+ InstanceBuilder *theIB,
1471
+ const char *slotName,
1472
+ CLIPSFloat *slotValue)
1473
+ {
1474
+ CLIPSValue theValue;
1475
+
1476
+ theValue.floatValue = slotValue;
1477
+ return IBPutSlot(theIB,slotName,&theValue);
1478
+ }
1479
+
1480
+ /******************/
1481
+ /* IBPutSlotFloat */
1482
+ /******************/
1483
+ PutSlotError IBPutSlotFloat(
1484
+ InstanceBuilder *theIB,
1485
+ const char *slotName,
1486
+ double doubleValue)
1487
+ {
1488
+ CLIPSValue theValue;
1489
+
1490
+ if (theIB == NULL)
1491
+ { return PSE_NULL_POINTER_ERROR; }
1492
+
1493
+ theValue.floatValue = CreateFloat(theIB->ibEnv,doubleValue);
1494
+ return IBPutSlot(theIB,slotName,&theValue);
1495
+ }
1496
+
1497
+ /*****************/
1498
+ /* IBPutSlotFact */
1499
+ /*****************/
1500
+ PutSlotError IBPutSlotFact(
1501
+ InstanceBuilder *theIB,
1502
+ const char *slotName,
1503
+ Fact *slotValue)
1504
+ {
1505
+ CLIPSValue theValue;
1506
+
1507
+ theValue.factValue = slotValue;
1508
+ return IBPutSlot(theIB,slotName,&theValue);
1509
+ }
1510
+
1511
+ /*********************/
1512
+ /* IBPutSlotInstance */
1513
+ /*********************/
1514
+ PutSlotError IBPutSlotInstance(
1515
+ InstanceBuilder *theIB,
1516
+ const char *slotName,
1517
+ Instance *slotValue)
1518
+ {
1519
+ CLIPSValue theValue;
1520
+
1521
+ theValue.instanceValue = slotValue;
1522
+ return IBPutSlot(theIB,slotName,&theValue);
1523
+ }
1524
+
1525
+ /****************************/
1526
+ /* IBPutSlotExternalAddress */
1527
+ /****************************/
1528
+ PutSlotError IBPutSlotExternalAddress(
1529
+ InstanceBuilder *theIB,
1530
+ const char *slotName,
1531
+ CLIPSExternalAddress *slotValue)
1532
+ {
1533
+ CLIPSValue theValue;
1534
+
1535
+ theValue.externalAddressValue = slotValue;
1536
+ return IBPutSlot(theIB,slotName,&theValue);
1537
+ }
1538
+
1539
+ /***********************/
1540
+ /* IBPutSlotMultifield */
1541
+ /***********************/
1542
+ PutSlotError IBPutSlotMultifield(
1543
+ InstanceBuilder *theIB,
1544
+ const char *slotName,
1545
+ Multifield *slotValue)
1546
+ {
1547
+ CLIPSValue theValue;
1548
+
1549
+ theValue.multifieldValue = slotValue;
1550
+ return IBPutSlot(theIB,slotName,&theValue);
1551
+ }
1552
+
1553
+ /**************/
1554
+ /* IBPutSlot: */
1555
+ /**************/
1556
+ PutSlotError IBPutSlot(
1557
+ InstanceBuilder *theIB,
1558
+ const char *slotName,
1559
+ CLIPSValue *slotValue)
1560
+ {
1561
+ Environment *theEnv;
1562
+ int whichSlot;
1563
+ CLIPSValue oldValue;
1564
+ unsigned int i;
1565
+ SlotDescriptor *theSlot;
1566
+ ConstraintViolationType cvType;
1567
+
1568
+ /*==========================*/
1569
+ /* Check for NULL pointers. */
1570
+ /*==========================*/
1571
+
1572
+ if ((theIB == NULL) || (slotName == NULL) || (slotValue == NULL))
1573
+ { return PSE_NULL_POINTER_ERROR; }
1574
+
1575
+ if ((theIB->ibDefclass == NULL) || (slotValue->value == NULL))
1576
+ { return PSE_NULL_POINTER_ERROR; }
1577
+
1578
+ theEnv = theIB->ibEnv;
1579
+
1580
+ /*===================================*/
1581
+ /* Make sure the slot name requested */
1582
+ /* corresponds to a valid slot name. */
1583
+ /*===================================*/
1584
+
1585
+ whichSlot = FindInstanceTemplateSlot(theEnv,theIB->ibDefclass,CreateSymbol(theIB->ibEnv,slotName));
1586
+ if (whichSlot == -1)
1587
+ { return PSE_SLOT_NOT_FOUND_ERROR; }
1588
+ theSlot = theIB->ibDefclass->instanceTemplate[whichSlot];
1589
+
1590
+ /*=============================================*/
1591
+ /* Make sure a single field value is not being */
1592
+ /* stored in a multifield slot or vice versa. */
1593
+ /*=============================================*/
1594
+
1595
+ if (((theSlot->multiple == 0) && (slotValue->header->type == MULTIFIELD_TYPE)) ||
1596
+ ((theSlot->multiple == 1) && (slotValue->header->type != MULTIFIELD_TYPE)))
1597
+ { return PSE_CARDINALITY_ERROR; }
1598
+
1599
+ /*=================================*/
1600
+ /* Check constraints for the slot. */
1601
+ /*=================================*/
1602
+
1603
+ if (theSlot->constraint != NULL)
1604
+ {
1605
+ if ((cvType = ConstraintCheckValue(theEnv,slotValue->header->type,slotValue->value,theSlot->constraint)) != NO_VIOLATION)
1606
+ {
1607
+ switch(cvType)
1608
+ {
1609
+ case NO_VIOLATION:
1610
+ case FUNCTION_RETURN_TYPE_VIOLATION:
1611
+ SystemError(theEnv,"INSMNGR",1);
1612
+ ExitRouter(theEnv,EXIT_FAILURE);
1613
+ break;
1614
+
1615
+ case TYPE_VIOLATION:
1616
+ return PSE_TYPE_ERROR;
1617
+
1618
+ case RANGE_VIOLATION:
1619
+ return PSE_RANGE_ERROR;
1620
+
1621
+ case ALLOWED_VALUES_VIOLATION:
1622
+ return PSE_ALLOWED_VALUES_ERROR;
1623
+
1624
+ case CARDINALITY_VIOLATION:
1625
+ return PSE_CARDINALITY_ERROR;
1626
+
1627
+ case ALLOWED_CLASSES_VIOLATION:
1628
+ return PSE_ALLOWED_CLASSES_ERROR;
1629
+ }
1630
+ }
1631
+ }
1632
+
1633
+ /*===================================*/
1634
+ /* Create the value array if needed. */
1635
+ /*===================================*/
1636
+
1637
+ if (theIB->ibValueArray == NULL)
1638
+ {
1639
+ theIB->ibValueArray = (CLIPSValue *) gm2(theIB->ibEnv,sizeof(CLIPSValue) * theIB->ibDefclass->instanceSlotCount);
1640
+ for (i = 0; i < theIB->ibDefclass->instanceSlotCount; i++)
1641
+ { theIB->ibValueArray[i].voidValue = theIB->ibEnv->VoidConstant; }
1642
+ }
1643
+
1644
+ /*=====================*/
1645
+ /* Set the slot value. */
1646
+ /*=====================*/
1647
+
1648
+ oldValue.value = theIB->ibValueArray[whichSlot].value;
1649
+
1650
+ if (oldValue.header->type == MULTIFIELD_TYPE)
1651
+ {
1652
+ if (MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
1653
+ { return PSE_NO_ERROR; }
1654
+ }
1655
+ else
1656
+ {
1657
+ if (oldValue.value == slotValue->value)
1658
+ { return PSE_NO_ERROR; }
1659
+ }
1660
+
1661
+ Release(theEnv,oldValue.header);
1662
+
1663
+ if (oldValue.header->type == MULTIFIELD_TYPE)
1664
+ { ReturnMultifield(theEnv,oldValue.multifieldValue); }
1665
+
1666
+ if (slotValue->header->type == MULTIFIELD_TYPE)
1667
+ { theIB->ibValueArray[whichSlot].multifieldValue = CopyMultifield(theEnv,slotValue->multifieldValue); }
1668
+ else
1669
+ { theIB->ibValueArray[whichSlot].value = slotValue->value; }
1670
+
1671
+ Retain(theEnv,theIB->ibValueArray[whichSlot].header);
1672
+
1673
+ return PSE_NO_ERROR;
1674
+ }
1675
+
1676
+ /***********/
1677
+ /* IBMake: */
1678
+ /***********/
1679
+ Instance *IBMake(
1680
+ InstanceBuilder *theIB,
1681
+ const char *instanceName)
1682
+ {
1683
+ Environment *theEnv;
1684
+ Instance *theInstance;
1685
+ CLIPSLexeme *instanceLexeme;
1686
+ UDFValue rv;
1687
+ unsigned int i;
1688
+ #if DEFRULE_CONSTRUCT
1689
+ bool ov;
1690
+ #endif
1691
+
1692
+ if (theIB == NULL) return NULL;
1693
+ theEnv = theIB->ibEnv;
1694
+
1695
+ if (theIB->ibDefclass == NULL)
1696
+ {
1697
+ InstanceData(theEnv)->instanceBuilderError = IBE_NULL_POINTER_ERROR;
1698
+ return NULL;
1699
+ }
1700
+
1701
+ if (instanceName == NULL)
1702
+ {
1703
+ GensymStar(theEnv,&rv);
1704
+ instanceLexeme = CreateInstanceName(theEnv,rv.lexemeValue->contents);
1705
+ }
1706
+ else
1707
+ { instanceLexeme = CreateInstanceName(theEnv,instanceName); }
1708
+
1709
+ #if DEFRULE_CONSTRUCT
1710
+ ov = SetDelayObjectPatternMatching(theEnv,true);
1711
+ #endif
1712
+
1713
+ theInstance = BuildInstance(theEnv,instanceLexeme,theIB->ibDefclass,true);
1714
+
1715
+ if (theInstance == NULL)
1716
+ {
1717
+ if (InstanceData(theEnv)->makeInstanceError == MIE_COULD_NOT_CREATE_ERROR)
1718
+ { InstanceData(theEnv)->instanceBuilderError = IBE_COULD_NOT_CREATE_ERROR; }
1719
+ else if (InstanceData(theEnv)->makeInstanceError == MIE_RULE_NETWORK_ERROR)
1720
+ { InstanceData(theEnv)->instanceBuilderError = IBE_RULE_NETWORK_ERROR; }
1721
+ else
1722
+ {
1723
+ SystemError(theEnv,"INSMNGR",3);
1724
+ ExitRouter(theEnv,EXIT_FAILURE);
1725
+ }
1726
+
1727
+ #if DEFRULE_CONSTRUCT
1728
+ SetDelayObjectPatternMatching(theEnv,ov);
1729
+ #endif
1730
+
1731
+ return NULL;
1732
+ }
1733
+
1734
+ if (CoreInitializeInstanceCV(theIB->ibEnv,theInstance,theIB->ibValueArray) == false)
1735
+ {
1736
+ InstanceData(theEnv)->instanceBuilderError = IBE_COULD_NOT_CREATE_ERROR;
1737
+ QuashInstance(theIB->ibEnv,theInstance);
1738
+ #if DEFRULE_CONSTRUCT
1739
+ SetDelayObjectPatternMatching(theEnv,ov);
1740
+ #endif
1741
+ return NULL;
1742
+ }
1743
+
1744
+ #if DEFRULE_CONSTRUCT
1745
+ SetDelayObjectPatternMatching(theEnv,ov);
1746
+ #endif
1747
+
1748
+ for (i = 0; i < theIB->ibDefclass->instanceSlotCount; i++)
1749
+ {
1750
+ if (theIB->ibValueArray[i].voidValue != VoidConstant(theEnv))
1751
+ {
1752
+ Release(theEnv,theIB->ibValueArray[i].header);
1753
+
1754
+ if (theIB->ibValueArray[i].header->type == MULTIFIELD_TYPE)
1755
+ { ReturnMultifield(theEnv,theIB->ibValueArray[i].multifieldValue); }
1756
+
1757
+ theIB->ibValueArray[i].voidValue = VoidConstant(theEnv);
1758
+ }
1759
+ }
1760
+
1761
+ InstanceData(theEnv)->instanceBuilderError = IBE_NO_ERROR;
1762
+
1763
+ return theInstance;
1764
+ }
1765
+
1766
+ /**************/
1767
+ /* IBDispose: */
1768
+ /**************/
1769
+ void IBDispose(
1770
+ InstanceBuilder *theIB)
1771
+ {
1772
+ Environment *theEnv;
1773
+
1774
+ if (theIB == NULL) return;
1775
+
1776
+ theEnv = theIB->ibEnv;
1777
+
1778
+ IBAbort(theIB);
1779
+
1780
+ if (theIB->ibValueArray != NULL)
1781
+ { rm(theEnv,theIB->ibValueArray,sizeof(CLIPSValue) * theIB->ibDefclass->instanceSlotCount); }
1782
+
1783
+ rtn_struct(theEnv,instanceBuilder,theIB);
1784
+ }
1785
+
1786
+ /************/
1787
+ /* IBAbort: */
1788
+ /************/
1789
+ void IBAbort(
1790
+ InstanceBuilder *theIB)
1791
+ {
1792
+ Environment *theEnv;
1793
+ unsigned int i;
1794
+
1795
+ if (theIB == NULL) return;
1796
+
1797
+ if (theIB->ibDefclass == NULL) return;
1798
+
1799
+ theEnv = theIB->ibEnv;
1800
+
1801
+ for (i = 0; i < theIB->ibDefclass->instanceSlotCount; i++)
1802
+ {
1803
+ Release(theEnv,theIB->ibValueArray[i].header);
1804
+
1805
+ if (theIB->ibValueArray[i].header->type == MULTIFIELD_TYPE)
1806
+ { ReturnMultifield(theEnv,theIB->ibValueArray[i].multifieldValue); }
1807
+
1808
+ theIB->ibValueArray[i].voidValue = VoidConstant(theEnv);
1809
+ }
1810
+ }
1811
+
1812
+ /*****************/
1813
+ /* IBSetDefclass */
1814
+ /*****************/
1815
+ InstanceBuilderError IBSetDefclass(
1816
+ InstanceBuilder *theIB,
1817
+ const char *defclassName)
1818
+ {
1819
+ Defclass *theDefclass;
1820
+ Environment *theEnv;
1821
+ unsigned int i;
1822
+
1823
+ if (theIB == NULL)
1824
+ { return IBE_NULL_POINTER_ERROR; }
1825
+
1826
+ theEnv = theIB->ibEnv;
1827
+
1828
+ IBAbort(theIB);
1829
+
1830
+ if (defclassName != NULL)
1831
+ {
1832
+ theDefclass = FindDefclass(theIB->ibEnv,defclassName);
1833
+
1834
+ if (theDefclass == NULL)
1835
+ {
1836
+ InstanceData(theEnv)->instanceBuilderError = IBE_DEFCLASS_NOT_FOUND_ERROR;
1837
+ return IBE_DEFCLASS_NOT_FOUND_ERROR;
1838
+ }
1839
+ }
1840
+ else
1841
+ { theDefclass = NULL; }
1842
+
1843
+ if (theIB->ibValueArray != NULL)
1844
+ { rm(theEnv,theIB->ibValueArray,sizeof(CLIPSValue) * theIB->ibDefclass->instanceSlotCount); }
1845
+
1846
+ theIB->ibDefclass = theDefclass;
1847
+
1848
+ if ((theDefclass == NULL) || (theDefclass->instanceSlotCount == 0))
1849
+ { theIB->ibValueArray = NULL; }
1850
+ else
1851
+ {
1852
+ theIB->ibValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * theDefclass->instanceSlotCount);
1853
+
1854
+ for (i = 0; i < theDefclass->instanceSlotCount; i++)
1855
+ { theIB->ibValueArray[i].voidValue = VoidConstant(theEnv); }
1856
+ }
1857
+
1858
+ InstanceData(theEnv)->instanceBuilderError = IBE_NO_ERROR;
1859
+ return IBE_NO_ERROR;
1860
+ }
1861
+
1862
+ /************/
1863
+ /* IBError: */
1864
+ /************/
1865
+ InstanceBuilderError IBError(
1866
+ Environment *theEnv)
1867
+ {
1868
+ return InstanceData(theEnv)->instanceBuilderError;
1869
+ }
1870
+
1871
+ /***************************/
1872
+ /* CreateInstanceModifier: */
1873
+ /***************************/
1874
+ InstanceModifier *CreateInstanceModifier(
1875
+ Environment *theEnv,
1876
+ Instance *oldInstance)
1877
+ {
1878
+ InstanceModifier *theIM;
1879
+ unsigned int i;
1880
+
1881
+ if (theEnv == NULL) return NULL;
1882
+
1883
+ if (oldInstance != NULL)
1884
+ {
1885
+ if (oldInstance->garbage)
1886
+ {
1887
+ InstanceData(theEnv)->instanceModifierError = IME_DELETED_ERROR;
1888
+ return NULL;
1889
+ }
1890
+
1891
+ RetainInstance(oldInstance);
1892
+ }
1893
+
1894
+ theIM = get_struct(theEnv,instanceModifier);
1895
+ theIM->imEnv = theEnv;
1896
+ theIM->imOldInstance = oldInstance;
1897
+
1898
+ if ((oldInstance == NULL) || (oldInstance->cls->instanceSlotCount == 0))
1899
+ {
1900
+ theIM->imValueArray = NULL;
1901
+ theIM->changeMap = NULL;
1902
+ }
1903
+ else
1904
+ {
1905
+ unsigned short slotCount = oldInstance->cls->instanceSlotCount;
1906
+
1907
+ theIM->imValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * slotCount);
1908
+
1909
+ for (i = 0; i < slotCount; i++)
1910
+ { theIM->imValueArray[i].voidValue = VoidConstant(theEnv); }
1911
+
1912
+ theIM->changeMap = (char *) gm2(theEnv,CountToBitMapSize(slotCount));
1913
+ ClearBitString((void *) theIM->changeMap,CountToBitMapSize(slotCount));
1914
+ }
1915
+
1916
+ InstanceData(theEnv)->instanceModifierError = IME_NO_ERROR;
1917
+ return theIM;
1918
+ }
1919
+
1920
+ /*************************/
1921
+ /* IMPutSlotCLIPSInteger */
1922
+ /*************************/
1923
+ PutSlotError IMPutSlotCLIPSInteger(
1924
+ InstanceModifier *theFM,
1925
+ const char *slotName,
1926
+ CLIPSInteger *slotValue)
1927
+ {
1928
+ CLIPSValue theValue;
1929
+
1930
+ theValue.integerValue = slotValue;
1931
+ return IMPutSlot(theFM,slotName,&theValue);
1932
+ }
1933
+
1934
+ /********************/
1935
+ /* IMPutSlotInteger */
1936
+ /********************/
1937
+ PutSlotError IMPutSlotInteger(
1938
+ InstanceModifier *theIM,
1939
+ const char *slotName,
1940
+ long long longLongValue)
1941
+ {
1942
+ CLIPSValue theValue;
1943
+
1944
+ if (theIM == NULL)
1945
+ { return PSE_NULL_POINTER_ERROR; }
1946
+
1947
+ theValue.integerValue = CreateInteger(theIM->imEnv,longLongValue);
1948
+ return IMPutSlot(theIM,slotName,&theValue);
1949
+ }
1950
+
1951
+ /************************/
1952
+ /* IMPutSlotCLIPSLexeme */
1953
+ /************************/
1954
+ PutSlotError IMPutSlotCLIPSLexeme(
1955
+ InstanceModifier *theFM,
1956
+ const char *slotName,
1957
+ CLIPSLexeme *slotValue)
1958
+ {
1959
+ CLIPSValue theValue;
1960
+
1961
+ theValue.lexemeValue = slotValue;
1962
+ return IMPutSlot(theFM,slotName,&theValue);
1963
+ }
1964
+
1965
+ /*******************/
1966
+ /* IMPutSlotSymbol */
1967
+ /*******************/
1968
+ PutSlotError IMPutSlotSymbol(
1969
+ InstanceModifier *theIM,
1970
+ const char *slotName,
1971
+ const char *stringValue)
1972
+ {
1973
+ CLIPSValue theValue;
1974
+
1975
+ if (theIM == NULL)
1976
+ { return PSE_NULL_POINTER_ERROR; }
1977
+
1978
+ theValue.lexemeValue = CreateSymbol(theIM->imEnv,stringValue);
1979
+ return IMPutSlot(theIM,slotName,&theValue);
1980
+ }
1981
+
1982
+ /*******************/
1983
+ /* IMPutSlotString */
1984
+ /*******************/
1985
+ PutSlotError IMPutSlotString(
1986
+ InstanceModifier *theIM,
1987
+ const char *slotName,
1988
+ const char *stringValue)
1989
+ {
1990
+ CLIPSValue theValue;
1991
+
1992
+ if (theIM == NULL)
1993
+ { return PSE_NULL_POINTER_ERROR; }
1994
+
1995
+ theValue.lexemeValue = CreateString(theIM->imEnv,stringValue);
1996
+ return IMPutSlot(theIM,slotName,&theValue);
1997
+ }
1998
+
1999
+ /*************************/
2000
+ /* IMPutSlotInstanceName */
2001
+ /*************************/
2002
+ PutSlotError IMPutSlotInstanceName(
2003
+ InstanceModifier *theIM,
2004
+ const char *slotName,
2005
+ const char *stringValue)
2006
+ {
2007
+ CLIPSValue theValue;
2008
+
2009
+ if (theIM == NULL)
2010
+ { return PSE_NULL_POINTER_ERROR; }
2011
+
2012
+ theValue.lexemeValue = CreateInstanceName(theIM->imEnv,stringValue);
2013
+ return IMPutSlot(theIM,slotName,&theValue);
2014
+ }
2015
+
2016
+ /***********************/
2017
+ /* IMPutSlotCLIPSFloat */
2018
+ /***********************/
2019
+ PutSlotError IMPutSlotCLIPSFloat(
2020
+ InstanceModifier *theFM,
2021
+ const char *slotName,
2022
+ CLIPSFloat *slotValue)
2023
+ {
2024
+ CLIPSValue theValue;
2025
+
2026
+ theValue.floatValue = slotValue;
2027
+ return IMPutSlot(theFM,slotName,&theValue);
2028
+ }
2029
+
2030
+ /******************/
2031
+ /* IMPutSlotFloat */
2032
+ /******************/
2033
+ PutSlotError IMPutSlotFloat(
2034
+ InstanceModifier *theIM,
2035
+ const char *slotName,
2036
+ double doubleValue)
2037
+ {
2038
+ CLIPSValue theValue;
2039
+
2040
+ if (theIM == NULL)
2041
+ { return PSE_NULL_POINTER_ERROR; }
2042
+
2043
+ theValue.floatValue = CreateFloat(theIM->imEnv,doubleValue);
2044
+ return IMPutSlot(theIM,slotName,&theValue);
2045
+ }
2046
+
2047
+ /*****************/
2048
+ /* IMPutSlotFact */
2049
+ /*****************/
2050
+ PutSlotError IMPutSlotFact(
2051
+ InstanceModifier *theFM,
2052
+ const char *slotName,
2053
+ Fact *slotValue)
2054
+ {
2055
+ CLIPSValue theValue;
2056
+
2057
+ theValue.factValue = slotValue;
2058
+ return IMPutSlot(theFM,slotName,&theValue);
2059
+ }
2060
+
2061
+ /*********************/
2062
+ /* IMPutSlotInstance */
2063
+ /*********************/
2064
+ PutSlotError IMPutSlotInstance(
2065
+ InstanceModifier *theFM,
2066
+ const char *slotName,
2067
+ Instance *slotValue)
2068
+ {
2069
+ CLIPSValue theValue;
2070
+
2071
+ theValue.instanceValue = slotValue;
2072
+ return IMPutSlot(theFM,slotName,&theValue);
2073
+ }
2074
+
2075
+ /****************************/
2076
+ /* IMPutSlotExternalAddress */
2077
+ /****************************/
2078
+ PutSlotError IMPutSlotExternalAddress(
2079
+ InstanceModifier *theFM,
2080
+ const char *slotName,
2081
+ CLIPSExternalAddress *slotValue)
2082
+ {
2083
+ CLIPSValue theValue;
2084
+
2085
+ theValue.externalAddressValue = slotValue;
2086
+ return IMPutSlot(theFM,slotName,&theValue);
2087
+ }
2088
+
2089
+ /***********************/
2090
+ /* IMPutSlotMultifield */
2091
+ /***********************/
2092
+ PutSlotError IMPutSlotMultifield(
2093
+ InstanceModifier *theFM,
2094
+ const char *slotName,
2095
+ Multifield *slotValue)
2096
+ {
2097
+ CLIPSValue theValue;
2098
+
2099
+ theValue.multifieldValue = slotValue;
2100
+ return IMPutSlot(theFM,slotName,&theValue);
2101
+ }
2102
+
2103
+ /**************/
2104
+ /* IMPutSlot: */
2105
+ /**************/
2106
+ PutSlotError IMPutSlot(
2107
+ InstanceModifier *theIM,
2108
+ const char *slotName,
2109
+ CLIPSValue *slotValue)
2110
+ {
2111
+ Environment *theEnv;
2112
+ int whichSlot;
2113
+ CLIPSValue oldValue;
2114
+ CLIPSValue oldInstanceValue;
2115
+ unsigned int i;
2116
+ SlotDescriptor *theSlot;
2117
+ ConstraintViolationType cvType;
2118
+
2119
+ /*==========================*/
2120
+ /* Check for NULL pointers. */
2121
+ /*==========================*/
2122
+
2123
+ if ((theIM == NULL) || (slotName == NULL) || (slotValue == NULL))
2124
+ { return PSE_NULL_POINTER_ERROR; }
2125
+
2126
+ if ((theIM->imOldInstance == NULL) || (slotValue->value == NULL))
2127
+ { return PSE_NULL_POINTER_ERROR; }
2128
+
2129
+ theEnv = theIM->imEnv;
2130
+
2131
+ /*======================================*/
2132
+ /* Deleted instances can't be modified. */
2133
+ /*======================================*/
2134
+
2135
+ if (theIM->imOldInstance->garbage)
2136
+ { return PSE_INVALID_TARGET_ERROR; }
2137
+
2138
+ /*===================================*/
2139
+ /* Make sure the slot name requested */
2140
+ /* corresponds to a valid slot name. */
2141
+ /*===================================*/
2142
+
2143
+ whichSlot = FindInstanceTemplateSlot(theEnv,theIM->imOldInstance->cls,CreateSymbol(theIM->imEnv,slotName));
2144
+ if (whichSlot == -1)
2145
+ { return PSE_SLOT_NOT_FOUND_ERROR; }
2146
+ theSlot = theIM->imOldInstance->cls->instanceTemplate[whichSlot];
2147
+
2148
+ /*=============================================*/
2149
+ /* Make sure a single field value is not being */
2150
+ /* stored in a multifield slot or vice versa. */
2151
+ /*=============================================*/
2152
+
2153
+ if (((theSlot->multiple == 0) && (slotValue->header->type == MULTIFIELD_TYPE)) ||
2154
+ ((theSlot->multiple == 1) && (slotValue->header->type != MULTIFIELD_TYPE)))
2155
+ { return PSE_CARDINALITY_ERROR; }
2156
+
2157
+ /*=================================*/
2158
+ /* Check constraints for the slot. */
2159
+ /*=================================*/
2160
+
2161
+ if (theSlot->constraint != NULL)
2162
+ {
2163
+ if ((cvType = ConstraintCheckValue(theEnv,slotValue->header->type,slotValue->value,theSlot->constraint)) != NO_VIOLATION)
2164
+ {
2165
+ switch(cvType)
2166
+ {
2167
+ case NO_VIOLATION:
2168
+ case FUNCTION_RETURN_TYPE_VIOLATION:
2169
+ SystemError(theEnv,"INSMNGR",2);
2170
+ ExitRouter(theEnv,EXIT_FAILURE);
2171
+ break;
2172
+
2173
+ case TYPE_VIOLATION:
2174
+ return PSE_TYPE_ERROR;
2175
+
2176
+ case RANGE_VIOLATION:
2177
+ return PSE_RANGE_ERROR;
2178
+
2179
+ case ALLOWED_VALUES_VIOLATION:
2180
+ return PSE_ALLOWED_VALUES_ERROR;
2181
+
2182
+ case CARDINALITY_VIOLATION:
2183
+ return PSE_CARDINALITY_ERROR;
2184
+
2185
+ case ALLOWED_CLASSES_VIOLATION:
2186
+ return PSE_ALLOWED_CLASSES_ERROR;
2187
+ }
2188
+ }
2189
+ }
2190
+
2191
+ /*===========================*/
2192
+ /* Set up the change arrays. */
2193
+ /*===========================*/
2194
+
2195
+ if (theIM->imValueArray == NULL)
2196
+ {
2197
+ theIM->imValueArray = (CLIPSValue *) gm2(theIM->imEnv,sizeof(CLIPSValue) * theIM->imOldInstance->cls->instanceSlotCount);
2198
+ for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
2199
+ { theIM->imValueArray[i].voidValue = theIM->imEnv->VoidConstant; }
2200
+ }
2201
+
2202
+ if (theIM->changeMap == NULL)
2203
+ {
2204
+ theIM->changeMap = (char *) gm2(theIM->imEnv,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount));
2205
+ ClearBitString((void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount));
2206
+ }
2207
+
2208
+ /*=====================*/
2209
+ /* Set the slot value. */
2210
+ /*=====================*/
2211
+
2212
+ oldValue.value = theIM->imValueArray[whichSlot].value;
2213
+ oldInstanceValue.value = theIM->imOldInstance->slotAddresses[whichSlot]->value;
2214
+
2215
+ if (oldInstanceValue.header->type == MULTIFIELD_TYPE)
2216
+ {
2217
+ if (MultifieldsEqual(oldInstanceValue.multifieldValue,slotValue->multifieldValue))
2218
+ {
2219
+ Release(theIM->imEnv,oldValue.header);
2220
+ if (oldValue.header->type == MULTIFIELD_TYPE)
2221
+ { ReturnMultifield(theIM->imEnv,oldValue.multifieldValue); }
2222
+ theIM->imValueArray[whichSlot].voidValue = theIM->imEnv->VoidConstant;
2223
+ ClearBitMap(theIM->changeMap,whichSlot);
2224
+ return PSE_NO_ERROR;
2225
+ }
2226
+
2227
+ if ((oldValue.header->type == MULTIFIELD_TYPE) &&
2228
+ MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
2229
+ { return PSE_NO_ERROR; }
2230
+ }
2231
+ else
2232
+ {
2233
+ if (slotValue->value == oldInstanceValue.value)
2234
+ {
2235
+ Release(theIM->imEnv,oldValue.header);
2236
+ theIM->imValueArray[whichSlot].voidValue = theIM->imEnv->VoidConstant;
2237
+ ClearBitMap(theIM->changeMap,whichSlot);
2238
+ return PSE_NO_ERROR;
2239
+ }
2240
+
2241
+ if (oldValue.value == slotValue->value)
2242
+ { return PSE_NO_ERROR; }
2243
+ }
2244
+
2245
+ SetBitMap(theIM->changeMap,whichSlot);
2246
+
2247
+ Release(theIM->imEnv,oldValue.header);
2248
+
2249
+ if (oldValue.header->type == MULTIFIELD_TYPE)
2250
+ { ReturnMultifield(theIM->imEnv,oldValue.multifieldValue); }
2251
+
2252
+ if (slotValue->header->type == MULTIFIELD_TYPE)
2253
+ { theIM->imValueArray[whichSlot].multifieldValue = CopyMultifield(theIM->imEnv,slotValue->multifieldValue); }
2254
+ else
2255
+ { theIM->imValueArray[whichSlot].value = slotValue->value; }
2256
+
2257
+ Retain(theIM->imEnv,theIM->imValueArray[whichSlot].header);
2258
+
2259
+ return PSE_NO_ERROR;
2260
+ }
2261
+
2262
+ /*************/
2263
+ /* IMModify: */
2264
+ /*************/
2265
+ Instance *IMModify(
2266
+ InstanceModifier *theIM)
2267
+ {
2268
+ Environment *theEnv;
2269
+ #if DEFRULE_CONSTRUCT
2270
+ bool ov;
2271
+ #endif
2272
+
2273
+ if (theIM == NULL)
2274
+ { return NULL; }
2275
+
2276
+ theEnv = theIM->imEnv;
2277
+
2278
+ if (theIM->imOldInstance == NULL)
2279
+ {
2280
+ InstanceData(theEnv)->instanceModifierError = IME_NULL_POINTER_ERROR;
2281
+ return NULL;
2282
+ }
2283
+
2284
+ if (theIM->imOldInstance->garbage)
2285
+ {
2286
+ InstanceData(theEnv)->instanceModifierError = IME_DELETED_ERROR;
2287
+ return NULL;
2288
+ }
2289
+
2290
+ if (theIM->changeMap == NULL)
2291
+ { return theIM->imOldInstance; }
2292
+
2293
+ if (! BitStringHasBitsSet(theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)))
2294
+ { return theIM->imOldInstance; }
2295
+
2296
+ #if DEFRULE_CONSTRUCT
2297
+ ov = SetDelayObjectPatternMatching(theIM->imEnv,true);
2298
+ #endif
2299
+
2300
+ IMModifySlots(theIM->imEnv,theIM->imOldInstance,theIM->imValueArray);
2301
+
2302
+ if ((InstanceData(theEnv)->makeInstanceError == MIE_RULE_NETWORK_ERROR) ||
2303
+ (InstanceData(theEnv)->unmakeInstanceError == UIE_RULE_NETWORK_ERROR))
2304
+ { InstanceData(theEnv)->instanceModifierError = IME_RULE_NETWORK_ERROR; }
2305
+ else if ((InstanceData(theEnv)->unmakeInstanceError == UIE_COULD_NOT_DELETE_ERROR) ||
2306
+ (InstanceData(theEnv)->makeInstanceError == MIE_COULD_NOT_CREATE_ERROR))
2307
+ { InstanceData(theEnv)->instanceModifierError = IME_COULD_NOT_MODIFY_ERROR; }
2308
+ else
2309
+ { InstanceData(theEnv)->instanceModifierError = IME_NO_ERROR; }
2310
+
2311
+ #if DEFRULE_CONSTRUCT
2312
+ SetDelayObjectPatternMatching(theIM->imEnv,ov);
2313
+ #endif
2314
+
2315
+ IMAbort(theIM);
2316
+
2317
+ return theIM->imOldInstance;
2318
+ }
2319
+
2320
+ /*****************/
2321
+ /* IMModifySlots */
2322
+ /*****************/
2323
+ static bool IMModifySlots(
2324
+ Environment *theEnv,
2325
+ Instance *theInstance,
2326
+ CLIPSValue *overrides)
2327
+ {
2328
+ UDFValue temp, junk;
2329
+ InstanceSlot *insSlot;
2330
+ unsigned int i;
2331
+
2332
+ for (i = 0; i < theInstance->cls->instanceSlotCount; i++)
2333
+ {
2334
+ if (overrides[i].value == VoidConstant(theEnv))
2335
+ { continue; }
2336
+
2337
+ insSlot = theInstance->slotAddresses[i];
2338
+
2339
+ if (insSlot->desc->multiple && (overrides[i].header->type != MULTIFIELD_TYPE))
2340
+ {
2341
+ temp.value = CreateMultifield(theEnv,1L);
2342
+ temp.begin = 0;
2343
+ temp.range = 1;
2344
+ temp.multifieldValue->contents[0].value = overrides[i].value;
2345
+ }
2346
+ else
2347
+ { CLIPSToUDFValue(&overrides[i],&temp); }
2348
+
2349
+ if (PutSlotValue(theEnv,theInstance,insSlot,&temp,&junk,"InstanceModifier call") != PSE_NO_ERROR)
2350
+ { return false; }
2351
+ }
2352
+
2353
+ return true;
2354
+ }
2355
+
2356
+ /**************/
2357
+ /* IMDispose: */
2358
+ /**************/
2359
+ void IMDispose(
2360
+ InstanceModifier *theIM)
2361
+ {
2362
+ Environment *theEnv = theIM->imEnv;
2363
+ unsigned int i;
2364
+
2365
+ /*========================*/
2366
+ /* Clear the value array. */
2367
+ /*========================*/
2368
+
2369
+ if (theIM->imOldInstance != NULL)
2370
+ {
2371
+ for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
2372
+ {
2373
+ Release(theEnv,theIM->imValueArray[i].header);
2374
+
2375
+ if (theIM->imValueArray[i].header->type == MULTIFIELD_TYPE)
2376
+ { ReturnMultifield(theEnv,theIM->imValueArray[i].multifieldValue); }
2377
+ }
2378
+ }
2379
+
2380
+ /*=====================================*/
2381
+ /* Return the value and change arrays. */
2382
+ /*=====================================*/
2383
+
2384
+ if (theIM->imValueArray != NULL)
2385
+ { rm(theEnv,theIM->imValueArray,sizeof(CLIPSValue) * theIM->imOldInstance->cls->instanceSlotCount); }
2386
+
2387
+ if (theIM->changeMap != NULL)
2388
+ { rm(theEnv,(void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)); }
2389
+
2390
+ /*========================================*/
2391
+ /* Return the InstanceModifier structure. */
2392
+ /*========================================*/
2393
+
2394
+ ReleaseInstance(theIM->imOldInstance);
2395
+
2396
+ rtn_struct(theEnv,instanceModifier,theIM);
2397
+ }
2398
+
2399
+ /************/
2400
+ /* IMAbort: */
2401
+ /************/
2402
+ void IMAbort(
2403
+ InstanceModifier *theIM)
2404
+ {
2405
+ GCBlock gcb;
2406
+ Environment *theEnv;
2407
+ unsigned int i;
2408
+
2409
+ if (theIM == NULL) return;
2410
+
2411
+ if (theIM->imOldInstance == NULL) return;
2412
+
2413
+ theEnv = theIM->imEnv;
2414
+
2415
+ GCBlockStart(theEnv,&gcb);
2416
+
2417
+ for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
2418
+ {
2419
+ Release(theEnv,theIM->imValueArray[i].header);
2420
+
2421
+ if (theIM->imValueArray[i].header->type == MULTIFIELD_TYPE)
2422
+ { ReturnMultifield(theEnv,theIM->imValueArray[i].multifieldValue); }
2423
+
2424
+ theIM->imValueArray[i].voidValue = theIM->imEnv->VoidConstant;
2425
+ }
2426
+
2427
+ if (theIM->changeMap != NULL)
2428
+ { ClearBitString((void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)); }
2429
+
2430
+ GCBlockEnd(theEnv,&gcb);
2431
+ }
2432
+
2433
+ /******************/
2434
+ /* IMSetInstance: */
2435
+ /******************/
2436
+ InstanceModifierError IMSetInstance(
2437
+ InstanceModifier *theIM,
2438
+ Instance *oldInstance)
2439
+ {
2440
+ Environment *theEnv;
2441
+ unsigned int currentSlotCount, newSlotCount;
2442
+ unsigned int i;
2443
+
2444
+ if (theIM == NULL)
2445
+ { return IME_NULL_POINTER_ERROR; }
2446
+
2447
+ theEnv = theIM->imEnv;
2448
+
2449
+ /*=============================================*/
2450
+ /* Modifiers can only be created for instances */
2451
+ /* that have not been deleted. */
2452
+ /*=============================================*/
2453
+
2454
+ if (oldInstance != NULL)
2455
+ {
2456
+ if (oldInstance->garbage)
2457
+ {
2458
+ InstanceData(theEnv)->instanceModifierError = IME_DELETED_ERROR;
2459
+ return IME_DELETED_ERROR;
2460
+ }
2461
+ }
2462
+
2463
+ /*========================*/
2464
+ /* Clear the value array. */
2465
+ /*========================*/
2466
+
2467
+ if (theIM->imValueArray != NULL)
2468
+ {
2469
+ for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
2470
+ {
2471
+ Release(theEnv,theIM->imValueArray[i].header);
2472
+
2473
+ if (theIM->imValueArray[i].header->type == MULTIFIELD_TYPE)
2474
+ { ReturnMultifield(theEnv,theIM->imValueArray[i].multifieldValue); }
2475
+ }
2476
+ }
2477
+
2478
+ /*==================================================*/
2479
+ /* Resize the value and change arrays if necessary. */
2480
+ /*==================================================*/
2481
+
2482
+ if (theIM->imOldInstance == NULL)
2483
+ { currentSlotCount = 0; }
2484
+ else
2485
+ { currentSlotCount = theIM->imOldInstance->cls->instanceSlotCount; }
2486
+
2487
+ if (oldInstance == NULL)
2488
+ { newSlotCount = 0; }
2489
+ else
2490
+ { newSlotCount = oldInstance->cls->instanceSlotCount; }
2491
+
2492
+ if (newSlotCount != currentSlotCount)
2493
+ {
2494
+ if (theIM->imValueArray != NULL)
2495
+ { rm(theEnv,theIM->imValueArray,sizeof(CLIPSValue) * currentSlotCount); }
2496
+
2497
+ if (theIM->changeMap != NULL)
2498
+ { rm(theEnv,(void *) theIM->changeMap,currentSlotCount); }
2499
+
2500
+ if (oldInstance->cls->instanceSlotCount == 0)
2501
+ {
2502
+ theIM->imValueArray = NULL;
2503
+ theIM->changeMap = NULL;
2504
+ }
2505
+ else
2506
+ {
2507
+ theIM->imValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * newSlotCount);
2508
+ theIM->changeMap = (char *) gm2(theEnv,CountToBitMapSize(newSlotCount));
2509
+ }
2510
+ }
2511
+
2512
+ /*=================================*/
2513
+ /* Update the fact being modified. */
2514
+ /*=================================*/
2515
+
2516
+ RetainInstance(oldInstance);
2517
+ ReleaseInstance(theIM->imOldInstance);
2518
+ theIM->imOldInstance = oldInstance;
2519
+
2520
+ /*=========================================*/
2521
+ /* Initialize the value and change arrays. */
2522
+ /*=========================================*/
2523
+
2524
+ for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
2525
+ { theIM->imValueArray[i].voidValue = theIM->imEnv->VoidConstant; }
2526
+
2527
+ if (newSlotCount != 0)
2528
+ { ClearBitString((void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)); }
2529
+
2530
+ /*================================================================*/
2531
+ /* Return true to indicate the modifier was successfully created. */
2532
+ /*================================================================*/
2533
+
2534
+ InstanceData(theEnv)->instanceModifierError = IME_NO_ERROR;
2535
+ return IME_NO_ERROR;
2536
+ }
2537
+
2538
+ /************/
2539
+ /* IMError: */
2540
+ /************/
2541
+ InstanceModifierError IMError(
2542
+ Environment *theEnv)
2543
+ {
2544
+ return InstanceData(theEnv)->instanceModifierError;
2545
+ }
2546
+
2547
+ #endif
2548
+
2549
+
2550
+