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,1764 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.40 10/03/19 */
5
+ /* */
6
+ /* INSTANCE LOAD/SAVE (ASCII/BINARY) MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: File load/save routines for instances */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Brian L. Dantes */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* */
17
+ /* Revision History: */
18
+ /* */
19
+ /* 6.24: Added environment parameter to GenClose. */
20
+ /* Added environment parameter to GenOpen. */
21
+ /* */
22
+ /* Renamed BOOLEAN macro type to intBool. */
23
+ /* */
24
+ /* Corrected code to remove compiler warnings. */
25
+ /* */
26
+ /* 6.30: Removed conditional code for unsupported */
27
+ /* compilers/operating systems (IBM_MCW, */
28
+ /* MAC_MCW, and IBM_TBC). */
29
+ /* */
30
+ /* Changed integer type/precision. */
31
+ /* */
32
+ /* Added const qualifiers to remove C++ */
33
+ /* deprecation warnings. */
34
+ /* */
35
+ /* Converted API macros to function calls. */
36
+ /* */
37
+ /* For save-instances, bsave-instances, and */
38
+ /* bload-instances, the class name does not */
39
+ /* have to be in scope if the module name is */
40
+ /* specified. */
41
+ /* */
42
+ /* 6.31: Prior error flags are cleared before */
43
+ /* EnvLoadInstances, EnvRestoreInstances, */
44
+ /* EnvLoadInstancesFromString, and */
45
+ /* EnvRestoreInstancesFromString are processed. */
46
+ /* */
47
+ /* Added code to keep track of pointers to */
48
+ /* constructs that are contained externally to */
49
+ /* to constructs, DanglingConstructs. */
50
+ /* */
51
+ /* If embedded, LoadInstances and */
52
+ /* RestoreInstances clean the current garbage */
53
+ /* frame. */
54
+ /* */
55
+ /* Fixed external address issue with binary */
56
+ /* instance files. */
57
+ /* */
58
+ /* 6.40: Added Env prefix to GetEvaluationError and */
59
+ /* SetEvaluationError functions. */
60
+ /* */
61
+ /* Refactored code to reduce header dependencies */
62
+ /* in sysdep.c. */
63
+ /* */
64
+ /* Pragma once and other inclusion changes. */
65
+ /* */
66
+ /* Added support for booleans with <stdbool.h>. */
67
+ /* */
68
+ /* Removed use of void pointers for specific */
69
+ /* data structures. */
70
+ /* */
71
+ /* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
72
+ /* */
73
+ /* UDF redesign. */
74
+ /* */
75
+ /* Moved BufferedRead and FreeReadBuffer from */
76
+ /* insfile.c to utility.c */
77
+ /* */
78
+ /* SaveInstances and BinarySaveInstances now */
79
+ /* return -1 instead of 0 if an error occurs. */
80
+ /* */
81
+ /*************************************************************/
82
+
83
+ /* =========================================
84
+ *****************************************
85
+ EXTERNAL DEFINITIONS
86
+ =========================================
87
+ ***************************************** */
88
+
89
+ #include <stdlib.h>
90
+
91
+ #include "setup.h"
92
+
93
+ #if OBJECT_SYSTEM
94
+
95
+ #include "argacces.h"
96
+ #include "classcom.h"
97
+ #include "classfun.h"
98
+ #include "memalloc.h"
99
+ #include "envrnmnt.h"
100
+ #include "extnfunc.h"
101
+ #if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT
102
+ #include "factmngr.h"
103
+ #endif
104
+ #include "inscom.h"
105
+ #include "insfun.h"
106
+ #include "insmngr.h"
107
+ #include "inspsr.h"
108
+ #include "object.h"
109
+ #include "prntutil.h"
110
+ #include "router.h"
111
+ #include "strngrtr.h"
112
+ #include "symblbin.h"
113
+ #include "sysdep.h"
114
+ #include "utility.h"
115
+
116
+ #include "insfile.h"
117
+
118
+ /* =========================================
119
+ *****************************************
120
+ CONSTANTS
121
+ =========================================
122
+ ***************************************** */
123
+
124
+ /* =========================================
125
+ *****************************************
126
+ MACROS AND TYPES
127
+ =========================================
128
+ ***************************************** */
129
+ struct bsaveSlotValue
130
+ {
131
+ unsigned long slotName;
132
+ unsigned long valueCount;
133
+ };
134
+
135
+ struct bsaveSlotValueAtom
136
+ {
137
+ unsigned short type;
138
+ unsigned long value;
139
+ };
140
+
141
+ struct classItem
142
+ {
143
+ Defclass *classPtr;
144
+ struct classItem *next;
145
+ };
146
+
147
+ /***************************************/
148
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
149
+ /***************************************/
150
+
151
+ static long InstancesSaveCommandParser(UDFContext *,
152
+ long (*)(Environment *,const char *,
153
+ SaveScope,Expression *,bool));
154
+ static struct classItem *ProcessSaveClassList(Environment *,const char *,Expression *,SaveScope,bool);
155
+ static void ReturnSaveClassList(Environment *,struct classItem *);
156
+ static long SaveOrMarkInstances(Environment *,FILE *,SaveScope,struct classItem *,bool,bool,
157
+ void (*)(Environment *,FILE *,Instance *));
158
+ static long SaveOrMarkInstancesOfClass(Environment *,FILE *,Defmodule *,SaveScope,Defclass *,
159
+ bool,int,void (*)(Environment *,FILE *,Instance *));
160
+ static void SaveSingleInstanceText(Environment *,FILE *,Instance *);
161
+ static void ProcessFileErrorMessage(Environment *,const char *,const char *);
162
+ #if BSAVE_INSTANCES
163
+ static void WriteBinaryHeader(Environment *,FILE *);
164
+ static void MarkSingleInstance(Environment *,FILE *,Instance *);
165
+ static void MarkNeededAtom(Environment *,unsigned short,void *);
166
+ static void SaveSingleInstanceBinary(Environment *,FILE *,Instance *);
167
+ static void SaveAtomBinary(Environment *,unsigned short,void *,FILE *);
168
+ #endif
169
+
170
+ static long LoadOrRestoreInstances(Environment *,const char *,bool,bool);
171
+
172
+ #if BLOAD_INSTANCES
173
+ static bool VerifyBinaryHeader(Environment *,const char *);
174
+ static bool LoadSingleBinaryInstance(Environment *);
175
+ static void BinaryLoadInstanceError(Environment *,CLIPSLexeme *,Defclass *);
176
+ static void CreateSlotValue(Environment *,UDFValue *,struct bsaveSlotValueAtom *,unsigned long);
177
+ static void *GetBinaryAtomValue(Environment *,struct bsaveSlotValueAtom *);
178
+ #endif
179
+
180
+ /* =========================================
181
+ *****************************************
182
+ EXTERNALLY VISIBLE FUNCTIONS
183
+ =========================================
184
+ ***************************************** */
185
+
186
+ /***************************************************
187
+ NAME : SetupInstanceFileCommands
188
+ DESCRIPTION : Defines function interfaces for
189
+ saving instances to files
190
+ INPUTS : None
191
+ RETURNS : Nothing useful
192
+ SIDE EFFECTS : Functions defined to KB
193
+ NOTES : None
194
+ ***************************************************/
195
+ void SetupInstanceFileCommands(
196
+ Environment *theEnv)
197
+ {
198
+ #if BLOAD_INSTANCES || BSAVE_INSTANCES
199
+ AllocateEnvironmentData(theEnv,INSTANCE_FILE_DATA,sizeof(struct instanceFileData),NULL);
200
+
201
+ InstanceFileData(theEnv)->InstanceBinaryPrefixID = "\5\6\7CLIPS";
202
+ InstanceFileData(theEnv)->InstanceBinaryVersionID = "V6.00";
203
+ #endif
204
+
205
+ #if (! RUN_TIME)
206
+ AddUDF(theEnv,"save-instances","l",1,UNBOUNDED,"y;sy",SaveInstancesCommand,"SaveInstancesCommand",NULL);
207
+ AddUDF(theEnv,"load-instances","l",1,1,"sy",LoadInstancesCommand,"LoadInstancesCommand",NULL);
208
+ AddUDF(theEnv,"restore-instances","l",1,1,"sy",RestoreInstancesCommand,"RestoreInstancesCommand",NULL);
209
+
210
+ #if BSAVE_INSTANCES
211
+ AddUDF(theEnv,"bsave-instances","l",1,UNBOUNDED,"y;sy",BinarySaveInstancesCommand,"BinarySaveInstancesCommand",NULL);
212
+ #endif
213
+ #if BLOAD_INSTANCES
214
+ AddUDF(theEnv,"bload-instances","l",1,1,"sy",BinaryLoadInstancesCommand,"BinaryLoadInstancesCommand",NULL);
215
+ #endif
216
+
217
+ #endif
218
+ }
219
+
220
+
221
+ /****************************************************************************
222
+ NAME : SaveInstancesCommand
223
+ DESCRIPTION : H/L interface for saving
224
+ current instances to a file
225
+ INPUTS : None
226
+ RETURNS : The number of instances saved
227
+ SIDE EFFECTS : Instances saved to named file
228
+ NOTES : H/L Syntax :
229
+ (save-instances <file> [local|visible [[inherit] <class>+]])
230
+ ****************************************************************************/
231
+ void SaveInstancesCommand(
232
+ Environment *theEnv,
233
+ UDFContext *context,
234
+ UDFValue *returnValue)
235
+ {
236
+ returnValue->integerValue = CreateInteger(theEnv,InstancesSaveCommandParser(context,SaveInstancesDriver));
237
+ }
238
+
239
+ /******************************************************
240
+ NAME : LoadInstancesCommand
241
+ DESCRIPTION : H/L interface for loading
242
+ instances from a file
243
+ INPUTS : None
244
+ RETURNS : The number of instances loaded
245
+ SIDE EFFECTS : Instances loaded from named file
246
+ NOTES : H/L Syntax : (load-instances <file>)
247
+ ******************************************************/
248
+ void LoadInstancesCommand(
249
+ Environment *theEnv,
250
+ UDFContext *context,
251
+ UDFValue *returnValue)
252
+ {
253
+ const char *fileFound;
254
+ UDFValue theArg;
255
+ long instanceCount;
256
+
257
+ if (! UDFFirstArgument(context,LEXEME_BITS,&theArg))
258
+ { return; }
259
+
260
+ fileFound = theArg.lexemeValue->contents;
261
+
262
+ instanceCount = LoadInstances(theEnv,fileFound);
263
+ if (EvaluationData(theEnv)->EvaluationError)
264
+ { ProcessFileErrorMessage(theEnv,"load-instances",fileFound); }
265
+
266
+ returnValue->integerValue = CreateInteger(theEnv,instanceCount);
267
+ }
268
+
269
+ /***************************************************
270
+ NAME : LoadInstances
271
+ DESCRIPTION : Loads instances from named file
272
+ INPUTS : The name of the input file
273
+ RETURNS : The number of instances loaded
274
+ SIDE EFFECTS : Instances loaded from file
275
+ NOTES : None
276
+ ***************************************************/
277
+ long LoadInstances(
278
+ Environment *theEnv,
279
+ const char *file)
280
+ {
281
+ return(LoadOrRestoreInstances(theEnv,file,true,true));
282
+ }
283
+
284
+ /***************************************************
285
+ NAME : LoadInstancesFromString
286
+ DESCRIPTION : Loads instances from given string
287
+ INPUTS : 1) The input string
288
+ 2) Index of char in string after
289
+ last valid char (-1 for all chars)
290
+ RETURNS : The number of instances loaded
291
+ SIDE EFFECTS : Instances loaded from string
292
+ NOTES : Uses string routers
293
+ ***************************************************/
294
+ long LoadInstancesFromString(
295
+ Environment *theEnv,
296
+ const char *theString,
297
+ size_t theMax)
298
+ {
299
+ long theCount;
300
+ const char * theStrRouter = "*** load-instances-from-string ***";
301
+
302
+ if ((theMax == SIZE_MAX) ? (! OpenStringSource(theEnv,theStrRouter,theString,0)) :
303
+ (! OpenTextSource(theEnv,theStrRouter,theString,0,theMax)))
304
+ { return -1; }
305
+
306
+ theCount = LoadOrRestoreInstances(theEnv,theStrRouter,true,false);
307
+
308
+ CloseStringSource(theEnv,theStrRouter);
309
+
310
+ return theCount;
311
+ }
312
+
313
+ /*********************************************************
314
+ NAME : RestoreInstancesCommand
315
+ DESCRIPTION : H/L interface for loading
316
+ instances from a file w/o messages
317
+ INPUTS : None
318
+ RETURNS : The number of instances restored
319
+ SIDE EFFECTS : Instances loaded from named file
320
+ NOTES : H/L Syntax : (restore-instances <file>)
321
+ *********************************************************/
322
+ void RestoreInstancesCommand(
323
+ Environment *theEnv,
324
+ UDFContext *context,
325
+ UDFValue *returnValue)
326
+ {
327
+ const char *fileFound;
328
+ UDFValue theArg;
329
+ long instanceCount;
330
+
331
+ if (! UDFFirstArgument(context,LEXEME_BITS,&theArg))
332
+ { return; }
333
+
334
+ fileFound = theArg.lexemeValue->contents;
335
+
336
+ instanceCount = RestoreInstances(theEnv,fileFound);
337
+ if (EvaluationData(theEnv)->EvaluationError)
338
+ { ProcessFileErrorMessage(theEnv,"restore-instances",fileFound); }
339
+
340
+ returnValue->integerValue = CreateInteger(theEnv,instanceCount);
341
+ }
342
+
343
+ /***************************************************
344
+ NAME : RestoreInstances
345
+ DESCRIPTION : Restores instances from named file
346
+ INPUTS : The name of the input file
347
+ RETURNS : The number of instances restored
348
+ SIDE EFFECTS : Instances restored from file
349
+ NOTES : None
350
+ ***************************************************/
351
+ long RestoreInstances(
352
+ Environment *theEnv,
353
+ const char *file)
354
+ {
355
+ return(LoadOrRestoreInstances(theEnv,file,false,true));
356
+ }
357
+
358
+ /***************************************************
359
+ NAME : RestoreInstancesFromString
360
+ DESCRIPTION : Restores instances from given string
361
+ INPUTS : 1) The input string
362
+ 2) Index of char in string after
363
+ last valid char (-1 for all chars)
364
+ RETURNS : The number of instances loaded
365
+ SIDE EFFECTS : Instances loaded from string
366
+ NOTES : Uses string routers
367
+ ***************************************************/
368
+ long RestoreInstancesFromString(
369
+ Environment *theEnv,
370
+ const char *theString,
371
+ size_t theMax)
372
+ {
373
+ long theCount;
374
+ const char *theStrRouter = "*** load-instances-from-string ***";
375
+
376
+ if ((theMax == SIZE_MAX) ? (! OpenStringSource(theEnv,theStrRouter,theString,0)) :
377
+ (! OpenTextSource(theEnv,theStrRouter,theString,0,theMax)))
378
+ { return(-1); }
379
+
380
+ theCount = LoadOrRestoreInstances(theEnv,theStrRouter,false,false);
381
+
382
+ CloseStringSource(theEnv,theStrRouter);
383
+
384
+ return(theCount);
385
+ }
386
+
387
+ #if BLOAD_INSTANCES
388
+
389
+ /*******************************************************
390
+ NAME : BinaryLoadInstancesCommand
391
+ DESCRIPTION : H/L interface for loading
392
+ instances from a binary file
393
+ INPUTS : None
394
+ RETURNS : The number of instances loaded
395
+ SIDE EFFECTS : Instances loaded from named binary file
396
+ NOTES : H/L Syntax : (bload-instances <file>)
397
+ *******************************************************/
398
+ void BinaryLoadInstancesCommand(
399
+ Environment *theEnv,
400
+ UDFContext *context,
401
+ UDFValue *returnValue)
402
+ {
403
+ const char *fileFound;
404
+ UDFValue theArg;
405
+ long instanceCount;
406
+
407
+ if (! UDFFirstArgument(context,LEXEME_BITS,&theArg))
408
+ { return; }
409
+
410
+ fileFound = theArg.lexemeValue->contents;
411
+
412
+ instanceCount = BinaryLoadInstances(theEnv,fileFound);
413
+ if (EvaluationData(theEnv)->EvaluationError)
414
+ { ProcessFileErrorMessage(theEnv,"bload-instances",fileFound); }
415
+ returnValue->integerValue = CreateInteger(theEnv,instanceCount);
416
+ }
417
+
418
+ /****************************************************
419
+ NAME : BinaryLoadInstances
420
+ DESCRIPTION : Loads instances quickly from a
421
+ binary file
422
+ INPUTS : The file name
423
+ RETURNS : The number of instances loaded
424
+ SIDE EFFECTS : Instances loaded w/o message-passing
425
+ NOTES : None
426
+ ****************************************************/
427
+ long BinaryLoadInstances(
428
+ Environment *theEnv,
429
+ const char *theFile)
430
+ {
431
+ long i,instanceCount;
432
+ GCBlock gcb;
433
+
434
+ /*=====================================*/
435
+ /* If embedded, clear the error flags. */
436
+ /*=====================================*/
437
+
438
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
439
+ { ResetErrorFlags(theEnv); }
440
+
441
+ if (GenOpenReadBinary(theEnv,"bload-instances",theFile) == false)
442
+ {
443
+ OpenErrorMessage(theEnv,"bload-instances",theFile);
444
+ SetEvaluationError(theEnv,true);
445
+ return -1L;
446
+ }
447
+ if (VerifyBinaryHeader(theEnv,theFile) == false)
448
+ {
449
+ GenCloseBinary(theEnv);
450
+ SetEvaluationError(theEnv,true);
451
+ return -1L;
452
+ }
453
+
454
+ GCBlockStart(theEnv,&gcb);
455
+ ReadNeededAtomicValues(theEnv);
456
+
457
+ UtilityData(theEnv)->BinaryFileOffset = 0L;
458
+
459
+ GenReadBinary(theEnv,&UtilityData(theEnv)->BinaryFileSize,sizeof(size_t));
460
+ GenReadBinary(theEnv,&instanceCount,sizeof(long));
461
+
462
+ for (i = 0L ; i < instanceCount ; i++)
463
+ {
464
+ if (LoadSingleBinaryInstance(theEnv) == false)
465
+ {
466
+ FreeReadBuffer(theEnv);
467
+ FreeAtomicValueStorage(theEnv);
468
+ GenCloseBinary(theEnv);
469
+ SetEvaluationError(theEnv,true);
470
+ GCBlockEnd(theEnv,&gcb);
471
+ return i;
472
+ }
473
+ }
474
+
475
+ FreeReadBuffer(theEnv);
476
+ FreeAtomicValueStorage(theEnv);
477
+ GenCloseBinary(theEnv);
478
+
479
+ GCBlockEnd(theEnv,&gcb);
480
+ return instanceCount;
481
+ }
482
+
483
+ #endif
484
+
485
+ /*******************************************************
486
+ NAME : SaveInstances
487
+ DESCRIPTION : Saves current instances to named file
488
+ INPUTS : 1) The name of the output file
489
+ 2) A flag indicating whether to
490
+ save local (current module only)
491
+ or visible instances
492
+ LOCAL_SAVE or VISIBLE_SAVE
493
+ 3) A list of expressions containing
494
+ the names of classes for which
495
+ instances are to be saved
496
+ 4) A flag indicating if the subclasses
497
+ of specified classes shoudl also
498
+ be processed
499
+ RETURNS : The number of instances saved
500
+ SIDE EFFECTS : Instances saved to file
501
+ NOTES : None
502
+ *******************************************************/
503
+ long SaveInstances(
504
+ Environment *theEnv,
505
+ const char *file,
506
+ SaveScope saveCode)
507
+ {
508
+ return SaveInstancesDriver(theEnv,file,saveCode,NULL,true);
509
+ }
510
+
511
+ /*******************************************************
512
+ NAME : SaveInstancesDriver
513
+ DESCRIPTION : Saves current instances to named file
514
+ INPUTS : 1) The name of the output file
515
+ 2) A flag indicating whether to
516
+ save local (current module only)
517
+ or visible instances
518
+ LOCAL_SAVE or VISIBLE_SAVE
519
+ 3) A list of expressions containing
520
+ the names of classes for which
521
+ instances are to be saved
522
+ 4) A flag indicating if the subclasses
523
+ of specified classes shoudl also
524
+ be processed
525
+ RETURNS : The number of instances saved
526
+ SIDE EFFECTS : Instances saved to file
527
+ NOTES : None
528
+ *******************************************************/
529
+ long SaveInstancesDriver(
530
+ Environment *theEnv,
531
+ const char *file,
532
+ SaveScope saveCode,
533
+ Expression *classExpressionList,
534
+ bool inheritFlag)
535
+ {
536
+ FILE *sfile = NULL;
537
+ bool oldPEC, oldATS, oldIAN;
538
+ struct classItem *classList;
539
+ long instanceCount;
540
+
541
+ /*=====================================*/
542
+ /* If embedded, clear the error flags. */
543
+ /*=====================================*/
544
+
545
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
546
+ { ResetErrorFlags(theEnv); }
547
+
548
+ classList = ProcessSaveClassList(theEnv,"save-instances",classExpressionList,
549
+ saveCode,inheritFlag);
550
+ if ((classList == NULL) && (classExpressionList != NULL))
551
+ return -1L;
552
+
553
+ SaveOrMarkInstances(theEnv,sfile,saveCode,classList,
554
+ inheritFlag,true,NULL);
555
+
556
+ if ((sfile = GenOpen(theEnv,file,"w")) == NULL)
557
+ {
558
+ OpenErrorMessage(theEnv,"save-instances",file);
559
+ ReturnSaveClassList(theEnv,classList);
560
+ SetEvaluationError(theEnv,true);
561
+ return -1L;
562
+ }
563
+
564
+ oldPEC = PrintUtilityData(theEnv)->PreserveEscapedCharacters;
565
+ PrintUtilityData(theEnv)->PreserveEscapedCharacters = true;
566
+ oldATS = PrintUtilityData(theEnv)->AddressesToStrings;
567
+ PrintUtilityData(theEnv)->AddressesToStrings = true;
568
+ oldIAN = PrintUtilityData(theEnv)->InstanceAddressesToNames;
569
+ PrintUtilityData(theEnv)->InstanceAddressesToNames = true;
570
+
571
+ SetFastSave(theEnv,sfile);
572
+ instanceCount = SaveOrMarkInstances(theEnv,sfile,saveCode,classList,
573
+ inheritFlag,true,SaveSingleInstanceText);
574
+ GenClose(theEnv,sfile);
575
+ SetFastSave(theEnv,NULL);
576
+
577
+ PrintUtilityData(theEnv)->PreserveEscapedCharacters = oldPEC;
578
+ PrintUtilityData(theEnv)->AddressesToStrings = oldATS;
579
+ PrintUtilityData(theEnv)->InstanceAddressesToNames = oldIAN;
580
+ ReturnSaveClassList(theEnv,classList);
581
+ return(instanceCount);
582
+ }
583
+
584
+ #if BSAVE_INSTANCES
585
+
586
+ /****************************************************************************
587
+ NAME : BinarySaveInstancesCommand
588
+ DESCRIPTION : H/L interface for saving
589
+ current instances to a binary file
590
+ INPUTS : None
591
+ RETURNS : The number of instances saved
592
+ SIDE EFFECTS : Instances saved (in binary format) to named file
593
+ NOTES : H/L Syntax :
594
+ (bsave-instances <file> [local|visible [[inherit] <class>+]])
595
+ *****************************************************************************/
596
+ void BinarySaveInstancesCommand(
597
+ Environment *theEnv,
598
+ UDFContext *context,
599
+ UDFValue *returnValue)
600
+ {
601
+ returnValue->integerValue = CreateInteger(theEnv,InstancesSaveCommandParser(context,BinarySaveInstancesDriver));
602
+ }
603
+
604
+ /*******************************************************
605
+ NAME : BinarySaveInstances
606
+ DESCRIPTION : Saves current instances to binary file
607
+ INPUTS : 1) The name of the output file
608
+ 2) A flag indicating whether to
609
+ save local (current module only)
610
+ or visible instances
611
+ LOCAL_SAVE or VISIBLE_SAVE
612
+ RETURNS : The number of instances saved
613
+ SIDE EFFECTS : Instances saved to file
614
+ NOTES : None
615
+ *******************************************************/
616
+ long BinarySaveInstances(
617
+ Environment *theEnv,
618
+ const char *file,
619
+ SaveScope saveCode)
620
+ {
621
+ return BinarySaveInstancesDriver(theEnv,file,saveCode,NULL,true);
622
+ }
623
+
624
+ /*******************************************************
625
+ NAME : BinarySaveInstancesDriver
626
+ DESCRIPTION : Saves current instances to binary file
627
+ INPUTS : 1) The name of the output file
628
+ 2) A flag indicating whether to
629
+ save local (current module only)
630
+ or visible instances
631
+ LOCAL_SAVE or VISIBLE_SAVE
632
+ 3) A list of expressions containing
633
+ the names of classes for which
634
+ instances are to be saved
635
+ 4) A flag indicating if the subclasses
636
+ of specified classes shoudl also
637
+ be processed
638
+ RETURNS : The number of instances saved
639
+ SIDE EFFECTS : Instances saved to file
640
+ NOTES : None
641
+ *******************************************************/
642
+ long BinarySaveInstancesDriver(
643
+ Environment *theEnv,
644
+ const char *file,
645
+ SaveScope saveCode,
646
+ Expression *classExpressionList,
647
+ bool inheritFlag)
648
+ {
649
+ struct classItem *classList;
650
+ FILE *bsaveFP;
651
+ long instanceCount;
652
+
653
+ /*=====================================*/
654
+ /* If embedded, clear the error flags. */
655
+ /*=====================================*/
656
+
657
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
658
+ { ResetErrorFlags(theEnv); }
659
+
660
+ classList = ProcessSaveClassList(theEnv,"bsave-instances",classExpressionList,
661
+ saveCode,inheritFlag);
662
+ if ((classList == NULL) && (classExpressionList != NULL))
663
+ return -1L;
664
+
665
+ UtilityData(theEnv)->BinaryFileSize = 0L;
666
+ InitAtomicValueNeededFlags(theEnv);
667
+ instanceCount = SaveOrMarkInstances(theEnv,NULL,saveCode,classList,inheritFlag,
668
+ false,MarkSingleInstance);
669
+
670
+ if ((bsaveFP = GenOpen(theEnv,file,"wb")) == NULL)
671
+ {
672
+ OpenErrorMessage(theEnv,"bsave-instances",file);
673
+ ReturnSaveClassList(theEnv,classList);
674
+ SetEvaluationError(theEnv,true);
675
+ return -1L;
676
+ }
677
+ WriteBinaryHeader(theEnv,bsaveFP);
678
+ WriteNeededAtomicValues(theEnv,bsaveFP);
679
+
680
+ fwrite(&UtilityData(theEnv)->BinaryFileSize,sizeof(size_t),1,bsaveFP);
681
+ fwrite(&instanceCount,sizeof(long),1,bsaveFP);
682
+
683
+ SetAtomicValueIndices(theEnv,false);
684
+ SaveOrMarkInstances(theEnv,bsaveFP,saveCode,classList,
685
+ inheritFlag,false,SaveSingleInstanceBinary);
686
+ RestoreAtomicValueBuckets(theEnv);
687
+ GenClose(theEnv,bsaveFP);
688
+ ReturnSaveClassList(theEnv,classList);
689
+ return(instanceCount);
690
+ }
691
+
692
+ #endif
693
+
694
+ /* =========================================
695
+ *****************************************
696
+ INTERNALLY VISIBLE FUNCTIONS
697
+ =========================================
698
+ ***************************************** */
699
+
700
+ /******************************************************
701
+ NAME : InstancesSaveCommandParser
702
+ DESCRIPTION : Argument parser for save-instances
703
+ and bsave-instances
704
+ INPUTS : 1) The name of the calling function
705
+ 2) A pointer to the support
706
+ function to call for the save/bsave
707
+ RETURNS : The number of instances saved
708
+ SIDE EFFECTS : Instances saved/bsaved
709
+ NOTES : None
710
+ ******************************************************/
711
+ static long InstancesSaveCommandParser(
712
+ UDFContext *context,
713
+ long (*saveFunction)(Environment *,const char *,SaveScope,Expression *,bool))
714
+ {
715
+ const char *fileFound;
716
+ UDFValue temp;
717
+ unsigned int argCount;
718
+ SaveScope saveCode = LOCAL_SAVE;
719
+ Expression *classList = NULL;
720
+ bool inheritFlag = false;
721
+ Environment *theEnv = context->environment;
722
+
723
+ if (! UDFFirstArgument(context,LEXEME_BITS,&temp))
724
+ { return 0L; }
725
+ fileFound = temp.lexemeValue->contents;
726
+
727
+ argCount = UDFArgumentCount(context);
728
+ if (argCount > 1)
729
+ {
730
+ if (! UDFNextArgument(context,SYMBOL_BIT,&temp))
731
+ { return 0L; }
732
+
733
+ if (strcmp(temp.lexemeValue->contents,"local") == 0)
734
+ saveCode = LOCAL_SAVE;
735
+ else if (strcmp(temp.lexemeValue->contents,"visible") == 0)
736
+ saveCode = VISIBLE_SAVE;
737
+ else
738
+ {
739
+ UDFInvalidArgumentMessage(context,"symbol \"local\" or \"visible\"");
740
+ SetEvaluationError(theEnv,true);
741
+ return(0L);
742
+ }
743
+ classList = GetFirstArgument()->nextArg->nextArg;
744
+
745
+ /* ===========================
746
+ Check for "inherit" keyword
747
+ Must be at least one class
748
+ name following
749
+ =========================== */
750
+ if ((classList != NULL) ? (classList->nextArg != NULL) : false)
751
+ {
752
+ if ((classList->type != SYMBOL_TYPE) ? false :
753
+ (strcmp(classList->lexemeValue->contents,"inherit") == 0))
754
+ {
755
+ inheritFlag = true;
756
+ classList = classList->nextArg;
757
+ }
758
+ }
759
+ }
760
+
761
+ return((*saveFunction)(theEnv,fileFound,saveCode,classList,inheritFlag));
762
+ }
763
+
764
+ /****************************************************
765
+ NAME : ProcessSaveClassList
766
+ DESCRIPTION : Evaluates a list of class name
767
+ expressions and stores them in a
768
+ data object list
769
+ INPUTS : 1) The name of the calling function
770
+ 2) The class expression list
771
+ 3) A flag indicating if only local
772
+ or all visible instances are
773
+ being saved
774
+ 4) A flag indicating if inheritance
775
+ relationships should be checked
776
+ between classes
777
+ RETURNS : The evaluated class pointer data
778
+ objects - NULL on errors
779
+ SIDE EFFECTS : Data objects allocated and
780
+ classes validated
781
+ NOTES : None
782
+ ****************************************************/
783
+ static struct classItem *ProcessSaveClassList(
784
+ Environment *theEnv,
785
+ const char *functionName,
786
+ Expression *classExps,
787
+ SaveScope saveCode,
788
+ bool inheritFlag)
789
+ {
790
+ struct classItem *head = NULL, *prv, *newItem;
791
+ UDFValue tmp;
792
+ Defclass *theDefclass;
793
+ Defmodule *currentModule;
794
+ unsigned int argIndex = inheritFlag ? 4 : 3;
795
+
796
+ currentModule = GetCurrentModule(theEnv);
797
+ while (classExps != NULL)
798
+ {
799
+ if (EvaluateExpression(theEnv,classExps,&tmp))
800
+ goto ProcessClassListError;
801
+
802
+ if (tmp.header->type != SYMBOL_TYPE)
803
+ goto ProcessClassListError;
804
+
805
+ if (saveCode == LOCAL_SAVE)
806
+ { theDefclass = LookupDefclassAnywhere(theEnv,currentModule,tmp.lexemeValue->contents); }
807
+ else
808
+ { theDefclass = LookupDefclassByMdlOrScope(theEnv,tmp.lexemeValue->contents); }
809
+
810
+ if (theDefclass == NULL)
811
+ goto ProcessClassListError;
812
+ else if (theDefclass->abstract && (inheritFlag == false))
813
+ goto ProcessClassListError;
814
+
815
+ prv = newItem = head;
816
+ while (newItem != NULL)
817
+ {
818
+ if (newItem->classPtr == theDefclass)
819
+ goto ProcessClassListError;
820
+ else if (inheritFlag)
821
+ {
822
+ if (HasSuperclass(newItem->classPtr,theDefclass) ||
823
+ HasSuperclass(theDefclass,newItem->classPtr))
824
+ goto ProcessClassListError;
825
+ }
826
+ prv = newItem;
827
+ newItem = newItem->next;
828
+ }
829
+
830
+ newItem = get_struct(theEnv,classItem);
831
+ newItem->classPtr = theDefclass;
832
+ newItem->next = NULL;
833
+
834
+ if (prv == NULL)
835
+ head = newItem;
836
+ else
837
+ prv->next = newItem;
838
+
839
+ argIndex++;
840
+ classExps = classExps->nextArg;
841
+ }
842
+ return head;
843
+
844
+ ProcessClassListError:
845
+ if (inheritFlag)
846
+ ExpectedTypeError1(theEnv,functionName,argIndex,"'valid class name'");
847
+ else
848
+ ExpectedTypeError1(theEnv,functionName,argIndex,"'valid concrete class name'");
849
+
850
+ ReturnSaveClassList(theEnv,head);
851
+
852
+ SetEvaluationError(theEnv,true);
853
+ return NULL;
854
+ }
855
+
856
+ /****************************************************
857
+ NAME : ReturnSaveClassList
858
+ DESCRIPTION : Deallocates the class data object
859
+ list created by ProcessSaveClassList
860
+ INPUTS : The class data object list
861
+ RETURNS : Nothing useful
862
+ SIDE EFFECTS : Class data object returned
863
+ NOTES : None
864
+ ****************************************************/
865
+ static void ReturnSaveClassList(
866
+ Environment *theEnv,
867
+ struct classItem *classList)
868
+ {
869
+ struct classItem *tmp;
870
+
871
+ while (classList != NULL)
872
+ {
873
+ tmp = classList;
874
+ classList = classList->next;
875
+ rtn_struct(theEnv,classItem,tmp);
876
+ }
877
+ }
878
+
879
+ /***************************************************
880
+ NAME : SaveOrMarkInstances
881
+ DESCRIPTION : Iterates through all specified
882
+ instances either marking needed
883
+ atoms or writing instances in
884
+ binary/text format
885
+ INPUTS : 1) NULL (for marking) or
886
+ file pointer (for text/binary saves)
887
+ 2) A cope flag indicating LOCAL
888
+ or VISIBLE saves only
889
+ 3) A list of data objects
890
+ containing the names of classes
891
+ of instances to be saved
892
+ 4) A flag indicating whether to
893
+ include subclasses of arg #3
894
+ 5) A flag indicating if the
895
+ iteration can be interrupted
896
+ or not
897
+ 6) The access function to mark
898
+ or save an instance (can be NULL
899
+ if only counting instances)
900
+ RETURNS : The number of instances saved
901
+ SIDE EFFECTS : Instances amrked or saved
902
+ NOTES : None
903
+ ***************************************************/
904
+ static long SaveOrMarkInstances(
905
+ Environment *theEnv,
906
+ FILE *theOutput,
907
+ SaveScope saveCode,
908
+ struct classItem *classList,
909
+ bool inheritFlag,
910
+ bool interruptOK,
911
+ void (*saveInstanceFunc)(Environment *,FILE *,Instance *))
912
+ {
913
+ Defmodule *currentModule;
914
+ int traversalID;
915
+ struct classItem *tmp;
916
+ Instance *ins;
917
+ long instanceCount = 0L;
918
+
919
+ currentModule = GetCurrentModule(theEnv);
920
+ if (classList != NULL)
921
+ {
922
+ traversalID = GetTraversalID(theEnv);
923
+ if (traversalID != -1)
924
+ {
925
+ for (tmp = classList ;
926
+ (! ((tmp == NULL) || (EvaluationData(theEnv)->HaltExecution && interruptOK))) ;
927
+ tmp = tmp->next)
928
+ instanceCount += SaveOrMarkInstancesOfClass(theEnv,theOutput,currentModule,saveCode,
929
+ tmp->classPtr,inheritFlag,
930
+ traversalID,saveInstanceFunc);
931
+ ReleaseTraversalID(theEnv);
932
+ }
933
+ }
934
+ else
935
+ {
936
+ for (ins = GetNextInstanceInScope(theEnv,NULL) ;
937
+ (ins != NULL) && (EvaluationData(theEnv)->HaltExecution != true) ;
938
+ ins = GetNextInstanceInScope(theEnv,ins))
939
+ {
940
+ if ((saveCode == VISIBLE_SAVE) ? true :
941
+ (ins->cls->header.whichModule->theModule == currentModule))
942
+ {
943
+ if (saveInstanceFunc != NULL)
944
+ (*saveInstanceFunc)(theEnv,theOutput,ins);
945
+ instanceCount++;
946
+ }
947
+ }
948
+ }
949
+ return(instanceCount);
950
+ }
951
+
952
+ /***************************************************
953
+ NAME : SaveOrMarkInstancesOfClass
954
+ DESCRIPTION : Saves off the direct (and indirect)
955
+ instance of the specified class
956
+ INPUTS : 1) The logical name of the output
957
+ (or file pointer for binary
958
+ output)
959
+ 2) The current module
960
+ 3) A flag indicating local
961
+ or visible saves
962
+ 4) The defclass
963
+ 5) A flag indicating whether to
964
+ save subclass instances or not
965
+ 6) A traversal id for marking
966
+ visited classes
967
+ 7) A pointer to the instance
968
+ manipulation function to call
969
+ (can be NULL for only counting
970
+ instances)
971
+ RETURNS : The number of instances saved
972
+ SIDE EFFECTS : Appropriate instances saved
973
+ NOTES : None
974
+ ***************************************************/
975
+ static long SaveOrMarkInstancesOfClass(
976
+ Environment *theEnv,
977
+ FILE *theOutput,
978
+ Defmodule *currentModule,
979
+ SaveScope saveCode,
980
+ Defclass *theDefclass,
981
+ bool inheritFlag,
982
+ int traversalID,
983
+ void (*saveInstanceFunc)(Environment *,FILE *,Instance *))
984
+ {
985
+ Instance *theInstance;
986
+ Defclass *subclass;
987
+ unsigned long i;
988
+ long instanceCount = 0L;
989
+
990
+ if (TestTraversalID(theDefclass->traversalRecord,traversalID))
991
+ return(instanceCount);
992
+ SetTraversalID(theDefclass->traversalRecord,traversalID);
993
+ if (((saveCode == LOCAL_SAVE) &&
994
+ (theDefclass->header.whichModule->theModule == currentModule)) ||
995
+ ((saveCode == VISIBLE_SAVE) &&
996
+ DefclassInScope(theEnv,theDefclass,currentModule)))
997
+ {
998
+ for (theInstance = GetNextInstanceInClass(theDefclass,NULL);
999
+ theInstance != NULL;
1000
+ theInstance = GetNextInstanceInClass(theDefclass,theInstance))
1001
+ {
1002
+ if (saveInstanceFunc != NULL)
1003
+ (*saveInstanceFunc)(theEnv,theOutput,theInstance);
1004
+ instanceCount++;
1005
+ }
1006
+ }
1007
+ if (inheritFlag)
1008
+ {
1009
+ for (i = 0 ; i < theDefclass->directSubclasses.classCount ; i++)
1010
+ {
1011
+ subclass = theDefclass->directSubclasses.classArray[i];
1012
+ instanceCount += SaveOrMarkInstancesOfClass(theEnv,theOutput,currentModule,saveCode,
1013
+ subclass,true,traversalID,
1014
+ saveInstanceFunc);
1015
+ }
1016
+ }
1017
+ return(instanceCount);
1018
+ }
1019
+
1020
+ /***************************************************
1021
+ NAME : SaveSingleInstanceText
1022
+ DESCRIPTION : Writes given instance to file
1023
+ INPUTS : 1) The logical name of the output
1024
+ 2) The instance to save
1025
+ RETURNS : Nothing useful
1026
+ SIDE EFFECTS : Instance written
1027
+ NOTES : None
1028
+ ***************************************************/
1029
+ static void SaveSingleInstanceText(
1030
+ Environment *theEnv,
1031
+ FILE *fastSaveFile,
1032
+ Instance *theInstance)
1033
+ {
1034
+ long i;
1035
+ InstanceSlot *sp;
1036
+ const char *logicalName = (const char *) fastSaveFile;
1037
+
1038
+ WriteString(theEnv,logicalName,"([");
1039
+ WriteString(theEnv,logicalName,theInstance->name->contents);
1040
+ WriteString(theEnv,logicalName,"] of ");
1041
+ WriteString(theEnv,logicalName,theInstance->cls->header.name->contents);
1042
+ for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
1043
+ {
1044
+ sp = theInstance->slotAddresses[i];
1045
+ WriteString(theEnv,logicalName,"\n (");
1046
+ WriteString(theEnv,logicalName,sp->desc->slotName->name->contents);
1047
+ if (sp->type != MULTIFIELD_TYPE)
1048
+ {
1049
+ WriteString(theEnv,logicalName," ");
1050
+ PrintAtom(theEnv,logicalName,sp->type,sp->value);
1051
+ }
1052
+ else if (sp->multifieldValue->length != 0)
1053
+ {
1054
+ WriteString(theEnv,logicalName," ");
1055
+ PrintMultifieldDriver(theEnv,logicalName,sp->multifieldValue,0,
1056
+ sp->multifieldValue->length,false);
1057
+ }
1058
+ WriteString(theEnv,logicalName,")");
1059
+ }
1060
+ WriteString(theEnv,logicalName,")\n\n");
1061
+ }
1062
+
1063
+ #if BSAVE_INSTANCES
1064
+
1065
+ /***************************************************
1066
+ NAME : WriteBinaryHeader
1067
+ DESCRIPTION : Writes identifying string to
1068
+ instance binary file to assist in
1069
+ later verification
1070
+ INPUTS : The binary file pointer
1071
+ RETURNS : Nothing useful
1072
+ SIDE EFFECTS : Binary prefix headers written
1073
+ NOTES : None
1074
+ ***************************************************/
1075
+ static void WriteBinaryHeader(
1076
+ Environment *theEnv,
1077
+ FILE *bsaveFP)
1078
+ {
1079
+ fwrite(InstanceFileData(theEnv)->InstanceBinaryPrefixID,
1080
+ (STD_SIZE) (strlen(InstanceFileData(theEnv)->InstanceBinaryPrefixID) + 1),1,bsaveFP);
1081
+ fwrite(InstanceFileData(theEnv)->InstanceBinaryVersionID,
1082
+ (STD_SIZE) (strlen(InstanceFileData(theEnv)->InstanceBinaryVersionID) + 1),1,bsaveFP);
1083
+ }
1084
+
1085
+ /***************************************************
1086
+ NAME : MarkSingleInstance
1087
+ DESCRIPTION : Marks all the atoms needed in
1088
+ the slot values of an instance
1089
+ INPUTS : 1) The output (ignored)
1090
+ 2) The instance
1091
+ RETURNS : Nothing useful
1092
+ SIDE EFFECTS : Instance slot value atoms marked
1093
+ NOTES : None
1094
+ ***************************************************/
1095
+ static void MarkSingleInstance(
1096
+ Environment *theEnv,
1097
+ FILE *theOutput,
1098
+ Instance *theInstance)
1099
+ {
1100
+ #if MAC_XCD
1101
+ #pragma unused(theOutput)
1102
+ #endif
1103
+ InstanceSlot *sp;
1104
+ unsigned int i;
1105
+ size_t j;
1106
+
1107
+ UtilityData(theEnv)->BinaryFileSize += (sizeof(unsigned long) * 2);
1108
+ theInstance->name->neededSymbol = true;
1109
+ theInstance->cls->header.name->neededSymbol = true;
1110
+
1111
+ UtilityData(theEnv)->BinaryFileSize +=
1112
+ (sizeof(unsigned short) +
1113
+ (sizeof(struct bsaveSlotValue) *
1114
+ theInstance->cls->instanceSlotCount) +
1115
+ sizeof(unsigned long));
1116
+
1117
+ for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
1118
+ {
1119
+ sp = theInstance->slotAddresses[i];
1120
+ sp->desc->slotName->name->neededSymbol = true;
1121
+ if (sp->desc->multiple)
1122
+ {
1123
+ for (j = 0 ; j < sp->multifieldValue->length ; j++)
1124
+ MarkNeededAtom(theEnv,sp->multifieldValue->contents[j].header->type,
1125
+ sp->multifieldValue->contents[j].value);
1126
+ }
1127
+ else
1128
+ MarkNeededAtom(theEnv,sp->type,sp->value);
1129
+ }
1130
+ }
1131
+
1132
+ /***************************************************
1133
+ NAME : MarkNeededAtom
1134
+ DESCRIPTION : Marks an integer/float/symbol as
1135
+ being need by a set of instances
1136
+ INPUTS : 1) The type of atom
1137
+ 2) The value of the atom
1138
+ RETURNS : Nothing useful
1139
+ SIDE EFFECTS : Atom marked for saving
1140
+ NOTES : None
1141
+ ***************************************************/
1142
+ static void MarkNeededAtom(
1143
+ Environment *theEnv,
1144
+ unsigned short type,
1145
+ void *value)
1146
+ {
1147
+ UtilityData(theEnv)->BinaryFileSize += sizeof(struct bsaveSlotValueAtom);
1148
+
1149
+ /* =====================================
1150
+ Assumes slot value atoms can only be
1151
+ floats, integers, symbols, strings,
1152
+ instance-names, instance-addresses,
1153
+ fact-addresses or external-addresses
1154
+ ===================================== */
1155
+ switch (type)
1156
+ {
1157
+ case SYMBOL_TYPE:
1158
+ case STRING_TYPE:
1159
+ case INSTANCE_NAME_TYPE:
1160
+ ((CLIPSLexeme *) value)->neededSymbol = true;
1161
+ break;
1162
+ case FLOAT_TYPE:
1163
+ ((CLIPSFloat *) value)->neededFloat = true;
1164
+ break;
1165
+ case INTEGER_TYPE:
1166
+ ((CLIPSInteger *) value)->neededInteger = true;
1167
+ break;
1168
+ case INSTANCE_ADDRESS_TYPE:
1169
+ GetFullInstanceName(theEnv,(Instance *) value)->neededSymbol = true;
1170
+ break;
1171
+ }
1172
+ }
1173
+
1174
+ /****************************************************
1175
+ NAME : SaveSingleInstanceBinary
1176
+ DESCRIPTION : Writes given instance to binary file
1177
+ INPUTS : 1) Binary file pointer
1178
+ 2) The instance to save
1179
+ RETURNS : Nothing useful
1180
+ SIDE EFFECTS : Instance written
1181
+ NOTES : None
1182
+ ****************************************************/
1183
+ static void SaveSingleInstanceBinary(
1184
+ Environment *theEnv,
1185
+ FILE *bsaveFP,
1186
+ Instance *theInstance)
1187
+ {
1188
+ unsigned long nameIndex;
1189
+ unsigned long i;
1190
+ size_t j;
1191
+ InstanceSlot *sp;
1192
+ struct bsaveSlotValue bs;
1193
+ unsigned long totalValueCount = 0;
1194
+ size_t slotLen;
1195
+
1196
+ /*==============================*/
1197
+ /* Write out the instance name. */
1198
+ /*==============================*/
1199
+
1200
+ nameIndex = theInstance->name->bucket;
1201
+ fwrite(&nameIndex,sizeof(unsigned long),1,bsaveFP);
1202
+
1203
+ /*===========================*/
1204
+ /* Write out the class name. */
1205
+ /*===========================*/
1206
+
1207
+ nameIndex = theInstance->cls->header.name->bucket;
1208
+ fwrite(&nameIndex,sizeof(unsigned long),1,bsaveFP);
1209
+
1210
+ /*=========================================*/
1211
+ /* Write out the number of slot-overrides. */
1212
+ /*=========================================*/
1213
+
1214
+ fwrite(&theInstance->cls->instanceSlotCount,
1215
+ sizeof(unsigned short),1,bsaveFP);
1216
+
1217
+ /*============================================*/
1218
+ /* Write out the slot names and value counts. */
1219
+ /*============================================*/
1220
+
1221
+ for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
1222
+ {
1223
+ sp = theInstance->slotAddresses[i];
1224
+
1225
+ /* ===============================================
1226
+ Write out the number of atoms in the slot value
1227
+ =============================================== */
1228
+ bs.slotName = sp->desc->slotName->name->bucket;
1229
+ bs.valueCount = (unsigned long) (sp->desc->multiple ? sp->multifieldValue->length : 1);
1230
+ fwrite(&bs,sizeof(struct bsaveSlotValue),1,bsaveFP);
1231
+ totalValueCount += bs.valueCount;
1232
+ }
1233
+
1234
+ /* ==================================
1235
+ Write out the number of slot value
1236
+ atoms for the whole instance
1237
+ ================================== */
1238
+ if (theInstance->cls->instanceSlotCount != 0) // (totalValueCount != 0L) : Bug fix if any slots, write out count
1239
+ fwrite(&totalValueCount,sizeof(unsigned long),1,bsaveFP);
1240
+
1241
+ /* ==============================
1242
+ Write out the slot value atoms
1243
+ ============================== */
1244
+ for (i = 0 ; i < theInstance->cls->instanceSlotCount ; i++)
1245
+ {
1246
+ sp = theInstance->slotAddresses[i];
1247
+ slotLen = sp->desc->multiple ? sp->multifieldValue->length : 1;
1248
+
1249
+ /* =========================================
1250
+ Write out the type and index of each atom
1251
+ ========================================= */
1252
+ if (sp->desc->multiple)
1253
+ {
1254
+ for (j = 0 ; j < slotLen ; j++)
1255
+ SaveAtomBinary(theEnv,sp->multifieldValue->contents[j].header->type,
1256
+ sp->multifieldValue->contents[j].value,bsaveFP);
1257
+ }
1258
+ else
1259
+ SaveAtomBinary(theEnv,sp->type,sp->value,bsaveFP);
1260
+ }
1261
+ }
1262
+
1263
+ /***************************************************
1264
+ NAME : SaveAtomBinary
1265
+ DESCRIPTION : Writes out an instance slot value
1266
+ atom to the binary file
1267
+ INPUTS : 1) The atom type
1268
+ 2) The atom value
1269
+ 3) The binary file pointer
1270
+ RETURNS : Nothing useful
1271
+ SIDE EFFECTS : atom written
1272
+ NOTES :
1273
+ ***************************************************/
1274
+ static void SaveAtomBinary(
1275
+ Environment *theEnv,
1276
+ unsigned short type,
1277
+ void *value,
1278
+ FILE *bsaveFP)
1279
+ {
1280
+ struct bsaveSlotValueAtom bsa;
1281
+
1282
+ /* =====================================
1283
+ Assumes slot value atoms can only be
1284
+ floats, integers, symbols, strings,
1285
+ instance-names, instance-addresses,
1286
+ fact-addresses or external-addresses
1287
+ ===================================== */
1288
+ bsa.type = type;
1289
+ switch (type)
1290
+ {
1291
+ case SYMBOL_TYPE:
1292
+ case STRING_TYPE:
1293
+ case INSTANCE_NAME_TYPE:
1294
+ bsa.value = ((CLIPSLexeme *) value)->bucket;
1295
+ break;
1296
+ case FLOAT_TYPE:
1297
+ bsa.value = ((CLIPSFloat *) value)->bucket;
1298
+ break;
1299
+ case INTEGER_TYPE:
1300
+ bsa.value = ((CLIPSInteger *) value)->bucket;
1301
+ break;
1302
+ case INSTANCE_ADDRESS_TYPE:
1303
+ bsa.type = INSTANCE_NAME_TYPE;
1304
+ bsa.value = GetFullInstanceName(theEnv,(Instance *) value)->bucket;
1305
+ break;
1306
+ default:
1307
+ bsa.value = ULONG_MAX;
1308
+ }
1309
+
1310
+ fwrite(&bsa,sizeof(struct bsaveSlotValueAtom),1,bsaveFP);
1311
+ }
1312
+
1313
+ #endif
1314
+
1315
+ /**********************************************************************
1316
+ NAME : LoadOrRestoreInstances
1317
+ DESCRIPTION : Loads instances from named file
1318
+ INPUTS : 1) The name of the input file
1319
+ 2) An integer flag indicating whether or
1320
+ not to use message-passing to create
1321
+ the new instances and delete old versions
1322
+ 3) An integer flag indicating if arg #1
1323
+ is a file name or the name of a string router
1324
+ RETURNS : The number of instances loaded/restored
1325
+ SIDE EFFECTS : Instances loaded from file
1326
+ NOTES : None
1327
+ **********************************************************************/
1328
+ static long LoadOrRestoreInstances(
1329
+ Environment *theEnv,
1330
+ const char *file,
1331
+ bool usemsgs,
1332
+ bool isFileName)
1333
+ {
1334
+ UDFValue temp;
1335
+ FILE *sfile = NULL,*svload = NULL;
1336
+ const char *ilog;
1337
+ Expression *top;
1338
+ bool svoverride;
1339
+ long instanceCount = 0L;
1340
+ int danglingConstructs;
1341
+ GCBlock gcb;
1342
+
1343
+ /*=====================================*/
1344
+ /* If embedded, clear the error flags. */
1345
+ /*=====================================*/
1346
+
1347
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
1348
+ { ResetErrorFlags(theEnv); }
1349
+
1350
+ if (isFileName)
1351
+ {
1352
+ if ((sfile = GenOpen(theEnv,file,"r")) == NULL)
1353
+ {
1354
+ SetEvaluationError(theEnv,true);
1355
+ return -1L;
1356
+ }
1357
+ svload = GetFastLoad(theEnv);
1358
+ ilog = (char *) sfile;
1359
+ SetFastLoad(theEnv,sfile);
1360
+ }
1361
+ else
1362
+ { ilog = file; }
1363
+
1364
+ top = GenConstant(theEnv,FCALL,FindFunction(theEnv,"make-instance"));
1365
+ GetToken(theEnv,ilog,&DefclassData(theEnv)->ObjectParseToken);
1366
+ svoverride = InstanceData(theEnv)->MkInsMsgPass;
1367
+ InstanceData(theEnv)->MkInsMsgPass = usemsgs;
1368
+
1369
+ danglingConstructs = ConstructData(theEnv)->DanglingConstructs;
1370
+
1371
+ /*========================================*/
1372
+ /* Set up the frame for tracking garbage. */
1373
+ /*========================================*/
1374
+
1375
+ GCBlockStart(theEnv,&gcb);
1376
+
1377
+ while ((DefclassData(theEnv)->ObjectParseToken.tknType != STOP_TOKEN) && (EvaluationData(theEnv)->HaltExecution != true))
1378
+ {
1379
+ if (DefclassData(theEnv)->ObjectParseToken.tknType != LEFT_PARENTHESIS_TOKEN)
1380
+ {
1381
+ SyntaxErrorMessage(theEnv,"instance definition");
1382
+ rtn_struct(theEnv,expr,top);
1383
+ if (isFileName)
1384
+ {
1385
+ GenClose(theEnv,sfile);
1386
+ SetFastLoad(theEnv,svload);
1387
+ }
1388
+ SetEvaluationError(theEnv,true);
1389
+ InstanceData(theEnv)->MkInsMsgPass = svoverride;
1390
+
1391
+ GCBlockEnd(theEnv,&gcb);
1392
+
1393
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
1394
+ {
1395
+ ConstructData(theEnv)->DanglingConstructs = danglingConstructs;
1396
+ CleanCurrentGarbageFrame(theEnv,NULL);
1397
+ }
1398
+
1399
+ return instanceCount;
1400
+ }
1401
+
1402
+ if (ParseSimpleInstance(theEnv,top,ilog) == NULL)
1403
+ {
1404
+ if (isFileName)
1405
+ {
1406
+ GenClose(theEnv,sfile);
1407
+ SetFastLoad(theEnv,svload);
1408
+ }
1409
+ InstanceData(theEnv)->MkInsMsgPass = svoverride;
1410
+ SetEvaluationError(theEnv,true);
1411
+
1412
+ GCBlockEnd(theEnv,&gcb);
1413
+
1414
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
1415
+ {
1416
+ ConstructData(theEnv)->DanglingConstructs = danglingConstructs;
1417
+ CleanCurrentGarbageFrame(theEnv,NULL);
1418
+ }
1419
+
1420
+ return instanceCount;
1421
+ }
1422
+ ExpressionInstall(theEnv,top);
1423
+ EvaluateExpression(theEnv,top,&temp);
1424
+ ExpressionDeinstall(theEnv,top);
1425
+ if (! EvaluationData(theEnv)->EvaluationError)
1426
+ { instanceCount++; }
1427
+ ReturnExpression(theEnv,top->argList);
1428
+ top->argList = NULL;
1429
+ GetToken(theEnv,ilog,&DefclassData(theEnv)->ObjectParseToken);
1430
+ }
1431
+
1432
+ /*================================*/
1433
+ /* Restore the old garbage frame. */
1434
+ /*================================*/
1435
+
1436
+ GCBlockEnd(theEnv,&gcb);
1437
+
1438
+ /*===============================================*/
1439
+ /* If embedded, clean the topmost garbage frame. */
1440
+ /*===============================================*/
1441
+
1442
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
1443
+ {
1444
+ ConstructData(theEnv)->DanglingConstructs = danglingConstructs;
1445
+ CleanCurrentGarbageFrame(theEnv,NULL);
1446
+ }
1447
+
1448
+ rtn_struct(theEnv,expr,top);
1449
+ if (isFileName)
1450
+ {
1451
+ GenClose(theEnv,sfile);
1452
+ SetFastLoad(theEnv,svload);
1453
+ }
1454
+ InstanceData(theEnv)->MkInsMsgPass = svoverride;
1455
+ return instanceCount;
1456
+ }
1457
+
1458
+ /***************************************************
1459
+ NAME : ProcessFileErrorMessage
1460
+ DESCRIPTION : Prints an error message when a
1461
+ file containing text or binary
1462
+ instances cannot be processed.
1463
+ INPUTS : The name of the input file and the
1464
+ function which opened it.
1465
+ RETURNS : No value
1466
+ SIDE EFFECTS : None
1467
+ NOTES : None
1468
+ ***************************************************/
1469
+ static void ProcessFileErrorMessage(
1470
+ Environment *theEnv,
1471
+ const char *functionName,
1472
+ const char *fileName)
1473
+ {
1474
+ PrintErrorID(theEnv,"INSFILE",1,false);
1475
+ WriteString(theEnv,STDERR,"Function '");
1476
+ WriteString(theEnv,STDERR,functionName);
1477
+ WriteString(theEnv,STDERR,"' could not completely process file '");
1478
+ WriteString(theEnv,STDERR,fileName);
1479
+ WriteString(theEnv,STDERR,"'.\n");
1480
+ }
1481
+
1482
+ #if BLOAD_INSTANCES
1483
+
1484
+ /*******************************************************
1485
+ NAME : VerifyBinaryHeader
1486
+ DESCRIPTION : Reads the prefix and version headers
1487
+ from a file to verify that the
1488
+ input is a valid binary instances file
1489
+ INPUTS : The name of the file
1490
+ RETURNS : True if OK, false otherwise
1491
+ SIDE EFFECTS : Input prefix and version read
1492
+ NOTES : Assumes file already open with
1493
+ GenOpenReadBinary
1494
+ *******************************************************/
1495
+ static bool VerifyBinaryHeader(
1496
+ Environment *theEnv,
1497
+ const char *theFile)
1498
+ {
1499
+ char buf[20];
1500
+
1501
+ GenReadBinary(theEnv,buf,(strlen(InstanceFileData(theEnv)->InstanceBinaryPrefixID) + 1));
1502
+ if (strcmp(buf,InstanceFileData(theEnv)->InstanceBinaryPrefixID) != 0)
1503
+ {
1504
+ PrintErrorID(theEnv,"INSFILE",2,false);
1505
+ WriteString(theEnv,STDERR,"File '");
1506
+ WriteString(theEnv,STDERR,theFile);
1507
+ WriteString(theEnv,STDERR,"' is not a binary instances file.\n");
1508
+ return false;
1509
+ }
1510
+ GenReadBinary(theEnv,buf,(strlen(InstanceFileData(theEnv)->InstanceBinaryVersionID) + 1));
1511
+ if (strcmp(buf,InstanceFileData(theEnv)->InstanceBinaryVersionID) != 0)
1512
+ {
1513
+ PrintErrorID(theEnv,"INSFILE",3,false);
1514
+ WriteString(theEnv,STDERR,"File '");
1515
+ WriteString(theEnv,STDERR,theFile);
1516
+ WriteString(theEnv,STDERR,"' is not a compatible binary instances file.\n");
1517
+ return false;
1518
+ }
1519
+ return true;
1520
+ }
1521
+
1522
+ /***************************************************
1523
+ NAME : LoadSingleBinaryInstance
1524
+ DESCRIPTION : Reads the binary data for a new
1525
+ instance and its slot values and
1526
+ creates/initializes the instance
1527
+ INPUTS : None
1528
+ RETURNS : True if all OK,
1529
+ false otherwise
1530
+ SIDE EFFECTS : Binary data read and instance
1531
+ created
1532
+ NOTES : Uses global GenReadBinary(theEnv,)
1533
+ ***************************************************/
1534
+ static bool LoadSingleBinaryInstance(
1535
+ Environment *theEnv)
1536
+ {
1537
+ CLIPSLexeme *instanceName,
1538
+ *className;
1539
+ unsigned short slotCount;
1540
+ Defclass *theDefclass;
1541
+ Instance *newInstance;
1542
+ struct bsaveSlotValue *bsArray;
1543
+ struct bsaveSlotValueAtom *bsaArray = NULL;
1544
+ long nameIndex;
1545
+ unsigned long totalValueCount;
1546
+ long i, j;
1547
+ InstanceSlot *sp;
1548
+ UDFValue slotValue, junkValue;
1549
+
1550
+ /* =====================
1551
+ Get the instance name
1552
+ ===================== */
1553
+ BufferedRead(theEnv,&nameIndex,sizeof(long));
1554
+ instanceName = SymbolPointer(nameIndex);
1555
+
1556
+ /* ==================
1557
+ Get the class name
1558
+ ================== */
1559
+ BufferedRead(theEnv,&nameIndex,sizeof(long));
1560
+ className = SymbolPointer(nameIndex);
1561
+
1562
+ /* ==================
1563
+ Get the slot count
1564
+ ================== */
1565
+ BufferedRead(theEnv,&slotCount,sizeof(unsigned short));
1566
+
1567
+ /* =============================
1568
+ Make sure the defclass exists
1569
+ and check the slot count
1570
+ ============================= */
1571
+ theDefclass = LookupDefclassByMdlOrScope(theEnv,className->contents);
1572
+ if (theDefclass == NULL)
1573
+ {
1574
+ ClassExistError(theEnv,"bload-instances",className->contents);
1575
+ return false;
1576
+ }
1577
+ if (theDefclass->instanceSlotCount != slotCount)
1578
+ {
1579
+ BinaryLoadInstanceError(theEnv,instanceName,theDefclass);
1580
+ return false;
1581
+ }
1582
+
1583
+ /* ===================================
1584
+ Create the new unitialized instance
1585
+ =================================== */
1586
+ newInstance = BuildInstance(theEnv,instanceName,theDefclass,false);
1587
+ if (newInstance == NULL)
1588
+ {
1589
+ BinaryLoadInstanceError(theEnv,instanceName,theDefclass);
1590
+ return false;
1591
+ }
1592
+ if (slotCount == 0)
1593
+ return true;
1594
+
1595
+ /* ====================================
1596
+ Read all slot override info and slot
1597
+ value atoms into big arrays
1598
+ ==================================== */
1599
+ bsArray = (struct bsaveSlotValue *) gm2(theEnv,(sizeof(struct bsaveSlotValue) * slotCount));
1600
+ BufferedRead(theEnv,bsArray,(sizeof(struct bsaveSlotValue) * slotCount));
1601
+
1602
+ BufferedRead(theEnv,&totalValueCount,sizeof(unsigned long));
1603
+
1604
+ if (totalValueCount != 0L)
1605
+ {
1606
+ bsaArray = (struct bsaveSlotValueAtom *)
1607
+ gm2(theEnv,(totalValueCount * sizeof(struct bsaveSlotValueAtom)));
1608
+ BufferedRead(theEnv,bsaArray,(totalValueCount * sizeof(struct bsaveSlotValueAtom)));
1609
+ }
1610
+
1611
+ /* =========================
1612
+ Insert the values for the
1613
+ slot overrides
1614
+ ========================= */
1615
+ for (i = 0 , j = 0L ; i < slotCount ; i++)
1616
+ {
1617
+ /* ===========================================================
1618
+ Here is another check for the validity of the binary file -
1619
+ the order of the slots in the file should match the
1620
+ order in the class definition
1621
+ =========================================================== */
1622
+ sp = newInstance->slotAddresses[i];
1623
+ if (sp->desc->slotName->name != SymbolPointer(bsArray[i].slotName))
1624
+ goto LoadError;
1625
+ CreateSlotValue(theEnv,&slotValue,(struct bsaveSlotValueAtom *) &bsaArray[j],
1626
+ bsArray[i].valueCount);
1627
+
1628
+ if (PutSlotValue(theEnv,newInstance,sp,&slotValue,&junkValue,"bload-instances") != PSE_NO_ERROR)
1629
+ goto LoadError;
1630
+
1631
+ j += (unsigned long) bsArray[i].valueCount;
1632
+ }
1633
+
1634
+ rm(theEnv,bsArray,(sizeof(struct bsaveSlotValue) * slotCount));
1635
+
1636
+ if (totalValueCount != 0L)
1637
+ rm(theEnv,bsaArray,(totalValueCount * sizeof(struct bsaveSlotValueAtom)));
1638
+
1639
+ return true;
1640
+
1641
+ LoadError:
1642
+ BinaryLoadInstanceError(theEnv,instanceName,theDefclass);
1643
+ QuashInstance(theEnv,newInstance);
1644
+ rm(theEnv,bsArray,(sizeof(struct bsaveSlotValue) * slotCount));
1645
+ rm(theEnv,bsaArray,(totalValueCount * sizeof(struct bsaveSlotValueAtom)));
1646
+ return false;
1647
+ }
1648
+
1649
+ /***************************************************
1650
+ NAME : BinaryLoadInstanceError
1651
+ DESCRIPTION : Prints out an error message when
1652
+ an instance could not be
1653
+ successfully loaded from a
1654
+ binary file
1655
+ INPUTS : 1) The instance name
1656
+ 2) The defclass
1657
+ RETURNS : Nothing useful
1658
+ SIDE EFFECTS : Error message printed
1659
+ NOTES : None
1660
+ ***************************************************/
1661
+ static void BinaryLoadInstanceError(
1662
+ Environment *theEnv,
1663
+ CLIPSLexeme *instanceName,
1664
+ Defclass *theDefclass)
1665
+ {
1666
+ PrintErrorID(theEnv,"INSFILE",4,false);
1667
+ WriteString(theEnv,STDERR,"Function 'bload-instances' is unable to load instance [");
1668
+ WriteString(theEnv,STDERR,instanceName->contents);
1669
+ WriteString(theEnv,STDERR,"] of class ");
1670
+ PrintClassName(theEnv,STDERR,theDefclass,true,true);
1671
+ }
1672
+
1673
+ /***************************************************
1674
+ NAME : CreateSlotValue
1675
+ DESCRIPTION : Creates a data object value from
1676
+ the binary slot value atom data
1677
+ INPUTS : 1) A data object buffer
1678
+ 2) The slot value atoms array
1679
+ 3) The number of values to put
1680
+ in the data object
1681
+ RETURNS : Nothing useful
1682
+ SIDE EFFECTS : Data object initialized
1683
+ (if more than one value, a
1684
+ multifield is created)
1685
+ NOTES : None
1686
+ ***************************************************/
1687
+ static void CreateSlotValue(
1688
+ Environment *theEnv,
1689
+ UDFValue *returnValue,
1690
+ struct bsaveSlotValueAtom *bsaValues,
1691
+ unsigned long valueCount)
1692
+ {
1693
+ unsigned i;
1694
+
1695
+ if (valueCount == 0)
1696
+ {
1697
+ returnValue->value = CreateMultifield(theEnv,0L);
1698
+ returnValue->begin = 0;
1699
+ returnValue->range = 0;
1700
+ }
1701
+ else if (valueCount == 1)
1702
+ {
1703
+ returnValue->value = GetBinaryAtomValue(theEnv,&bsaValues[0]);
1704
+ }
1705
+ else
1706
+ {
1707
+ returnValue->value = CreateMultifield(theEnv,valueCount);
1708
+ returnValue->begin = 0;
1709
+ returnValue->range = valueCount;
1710
+ for (i = 0 ; i < valueCount ; i++)
1711
+ {
1712
+ returnValue->multifieldValue->contents[i].value = GetBinaryAtomValue(theEnv,&bsaValues[i]);
1713
+ }
1714
+ }
1715
+ }
1716
+
1717
+ /***************************************************
1718
+ NAME : GetBinaryAtomValue
1719
+ DESCRIPTION : Uses the binary index of an atom
1720
+ to find the ephemeris value
1721
+ INPUTS : The binary type and index
1722
+ RETURNS : The symbol/etc. pointer
1723
+ SIDE EFFECTS : None
1724
+ NOTES : None
1725
+ ***************************************************/
1726
+ static void *GetBinaryAtomValue(
1727
+ Environment *theEnv,
1728
+ struct bsaveSlotValueAtom *ba)
1729
+ {
1730
+ switch (ba->type)
1731
+ {
1732
+ case SYMBOL_TYPE:
1733
+ case STRING_TYPE:
1734
+ case INSTANCE_NAME_TYPE:
1735
+ return((void *) SymbolPointer(ba->value));
1736
+
1737
+ case FLOAT_TYPE:
1738
+ return((void *) FloatPointer(ba->value));
1739
+
1740
+ case INTEGER_TYPE:
1741
+ return((void *) IntegerPointer(ba->value));
1742
+
1743
+ case FACT_ADDRESS_TYPE:
1744
+ #if DEFTEMPLATE_CONSTRUCT && DEFRULE_CONSTRUCT
1745
+ return((void *) &FactData(theEnv)->DummyFact);
1746
+ #else
1747
+ return NULL;
1748
+ #endif
1749
+
1750
+ case EXTERNAL_ADDRESS_TYPE:
1751
+ return CreateExternalAddress(theEnv,NULL,0);
1752
+
1753
+ default:
1754
+ {
1755
+ SystemError(theEnv,"INSFILE",1);
1756
+ ExitRouter(theEnv,EXIT_FAILURE);
1757
+ }
1758
+ }
1759
+ return NULL;
1760
+ }
1761
+
1762
+ #endif /* BLOAD_INSTANCES */
1763
+
1764
+ #endif /* OBJECT_SYSTEM */