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.
- checksums.yaml +7 -0
- data/ext/clipsruby/agenda.c +1373 -0
- data/ext/clipsruby/agenda.h +169 -0
- data/ext/clipsruby/analysis.c +1142 -0
- data/ext/clipsruby/analysis.h +61 -0
- data/ext/clipsruby/argacces.c +526 -0
- data/ext/clipsruby/argacces.h +77 -0
- data/ext/clipsruby/bload.c +884 -0
- data/ext/clipsruby/bload.h +94 -0
- data/ext/clipsruby/bmathfun.c +557 -0
- data/ext/clipsruby/bmathfun.h +66 -0
- data/ext/clipsruby/bsave.c +634 -0
- data/ext/clipsruby/bsave.h +130 -0
- data/ext/clipsruby/classcom.c +976 -0
- data/ext/clipsruby/classcom.h +115 -0
- data/ext/clipsruby/classexm.c +1376 -0
- data/ext/clipsruby/classexm.h +97 -0
- data/ext/clipsruby/classfun.c +1392 -0
- data/ext/clipsruby/classfun.h +164 -0
- data/ext/clipsruby/classinf.c +1245 -0
- data/ext/clipsruby/classinf.h +94 -0
- data/ext/clipsruby/classini.c +843 -0
- data/ext/clipsruby/classini.h +75 -0
- data/ext/clipsruby/classpsr.c +957 -0
- data/ext/clipsruby/classpsr.h +73 -0
- data/ext/clipsruby/clips.h +133 -0
- data/ext/clipsruby/clipsruby.c +619 -0
- data/ext/clipsruby/clsltpsr.c +931 -0
- data/ext/clipsruby/clsltpsr.h +72 -0
- data/ext/clipsruby/commline.c +1217 -0
- data/ext/clipsruby/commline.h +131 -0
- data/ext/clipsruby/conscomp.c +1593 -0
- data/ext/clipsruby/conscomp.h +150 -0
- data/ext/clipsruby/constant.h +264 -0
- data/ext/clipsruby/constrct.c +1090 -0
- data/ext/clipsruby/constrct.h +216 -0
- data/ext/clipsruby/constrnt.c +554 -0
- data/ext/clipsruby/constrnt.h +132 -0
- data/ext/clipsruby/crstrtgy.c +1088 -0
- data/ext/clipsruby/crstrtgy.h +85 -0
- data/ext/clipsruby/cstrcbin.c +185 -0
- data/ext/clipsruby/cstrcbin.h +61 -0
- data/ext/clipsruby/cstrccmp.h +43 -0
- data/ext/clipsruby/cstrccom.c +1791 -0
- data/ext/clipsruby/cstrccom.h +115 -0
- data/ext/clipsruby/cstrcpsr.c +835 -0
- data/ext/clipsruby/cstrcpsr.h +97 -0
- data/ext/clipsruby/cstrnbin.c +282 -0
- data/ext/clipsruby/cstrnbin.h +55 -0
- data/ext/clipsruby/cstrnchk.c +826 -0
- data/ext/clipsruby/cstrnchk.h +91 -0
- data/ext/clipsruby/cstrncmp.c +238 -0
- data/ext/clipsruby/cstrncmp.h +57 -0
- data/ext/clipsruby/cstrnops.c +1176 -0
- data/ext/clipsruby/cstrnops.h +47 -0
- data/ext/clipsruby/cstrnpsr.c +1394 -0
- data/ext/clipsruby/cstrnpsr.h +88 -0
- data/ext/clipsruby/cstrnutl.c +564 -0
- data/ext/clipsruby/cstrnutl.h +54 -0
- data/ext/clipsruby/default.c +454 -0
- data/ext/clipsruby/default.h +57 -0
- data/ext/clipsruby/defins.c +971 -0
- data/ext/clipsruby/defins.h +127 -0
- data/ext/clipsruby/developr.c +677 -0
- data/ext/clipsruby/developr.h +69 -0
- data/ext/clipsruby/dffctbin.c +477 -0
- data/ext/clipsruby/dffctbin.h +76 -0
- data/ext/clipsruby/dffctbsc.c +308 -0
- data/ext/clipsruby/dffctbsc.h +72 -0
- data/ext/clipsruby/dffctcmp.c +297 -0
- data/ext/clipsruby/dffctcmp.h +44 -0
- data/ext/clipsruby/dffctdef.c +364 -0
- data/ext/clipsruby/dffctdef.h +104 -0
- data/ext/clipsruby/dffctpsr.c +179 -0
- data/ext/clipsruby/dffctpsr.h +49 -0
- data/ext/clipsruby/dffnxbin.c +520 -0
- data/ext/clipsruby/dffnxbin.h +67 -0
- data/ext/clipsruby/dffnxcmp.c +378 -0
- data/ext/clipsruby/dffnxcmp.h +54 -0
- data/ext/clipsruby/dffnxexe.c +241 -0
- data/ext/clipsruby/dffnxexe.h +58 -0
- data/ext/clipsruby/dffnxfun.c +1192 -0
- data/ext/clipsruby/dffnxfun.h +155 -0
- data/ext/clipsruby/dffnxpsr.c +514 -0
- data/ext/clipsruby/dffnxpsr.h +57 -0
- data/ext/clipsruby/dfinsbin.c +509 -0
- data/ext/clipsruby/dfinsbin.h +66 -0
- data/ext/clipsruby/dfinscmp.c +345 -0
- data/ext/clipsruby/dfinscmp.h +48 -0
- data/ext/clipsruby/drive.c +1191 -0
- data/ext/clipsruby/drive.h +65 -0
- data/ext/clipsruby/emathfun.c +1213 -0
- data/ext/clipsruby/emathfun.h +99 -0
- data/ext/clipsruby/engine.c +1568 -0
- data/ext/clipsruby/engine.h +203 -0
- data/ext/clipsruby/entities.h +276 -0
- data/ext/clipsruby/envrnbld.c +514 -0
- data/ext/clipsruby/envrnbld.h +40 -0
- data/ext/clipsruby/envrnmnt.c +257 -0
- data/ext/clipsruby/envrnmnt.h +112 -0
- data/ext/clipsruby/evaluatn.c +1736 -0
- data/ext/clipsruby/evaluatn.h +211 -0
- data/ext/clipsruby/expressn.c +494 -0
- data/ext/clipsruby/expressn.h +154 -0
- data/ext/clipsruby/exprnbin.c +538 -0
- data/ext/clipsruby/exprnbin.h +60 -0
- data/ext/clipsruby/exprnops.c +564 -0
- data/ext/clipsruby/exprnops.h +67 -0
- data/ext/clipsruby/exprnpsr.c +1112 -0
- data/ext/clipsruby/exprnpsr.h +98 -0
- data/ext/clipsruby/extconf.rb +2 -0
- data/ext/clipsruby/extnfunc.c +1015 -0
- data/ext/clipsruby/extnfunc.h +157 -0
- data/ext/clipsruby/factbin.c +447 -0
- data/ext/clipsruby/factbin.h +56 -0
- data/ext/clipsruby/factbld.c +1035 -0
- data/ext/clipsruby/factbld.h +63 -0
- data/ext/clipsruby/factcmp.c +386 -0
- data/ext/clipsruby/factcmp.h +46 -0
- data/ext/clipsruby/factcom.c +759 -0
- data/ext/clipsruby/factcom.h +80 -0
- data/ext/clipsruby/factfile.c +1761 -0
- data/ext/clipsruby/factfile.h +54 -0
- data/ext/clipsruby/factfun.c +682 -0
- data/ext/clipsruby/factfun.h +77 -0
- data/ext/clipsruby/factgen.c +1305 -0
- data/ext/clipsruby/factgen.h +229 -0
- data/ext/clipsruby/facthsh.c +438 -0
- data/ext/clipsruby/facthsh.h +81 -0
- data/ext/clipsruby/factlhs.c +250 -0
- data/ext/clipsruby/factlhs.h +54 -0
- data/ext/clipsruby/factmch.c +905 -0
- data/ext/clipsruby/factmch.h +68 -0
- data/ext/clipsruby/factmngr.c +3373 -0
- data/ext/clipsruby/factmngr.h +325 -0
- data/ext/clipsruby/factprt.c +498 -0
- data/ext/clipsruby/factprt.h +60 -0
- data/ext/clipsruby/factqpsr.c +796 -0
- data/ext/clipsruby/factqpsr.h +61 -0
- data/ext/clipsruby/factqury.c +1267 -0
- data/ext/clipsruby/factqury.h +112 -0
- data/ext/clipsruby/factrete.c +978 -0
- data/ext/clipsruby/factrete.h +70 -0
- data/ext/clipsruby/factrhs.c +667 -0
- data/ext/clipsruby/factrhs.h +55 -0
- data/ext/clipsruby/filecom.c +353 -0
- data/ext/clipsruby/filecom.h +137 -0
- data/ext/clipsruby/filertr.c +481 -0
- data/ext/clipsruby/filertr.h +94 -0
- data/ext/clipsruby/fileutil.c +1020 -0
- data/ext/clipsruby/fileutil.h +50 -0
- data/ext/clipsruby/generate.c +1079 -0
- data/ext/clipsruby/generate.h +57 -0
- data/ext/clipsruby/genrcbin.c +902 -0
- data/ext/clipsruby/genrcbin.h +69 -0
- data/ext/clipsruby/genrccmp.c +640 -0
- data/ext/clipsruby/genrccmp.h +59 -0
- data/ext/clipsruby/genrccom.c +2017 -0
- data/ext/clipsruby/genrccom.h +119 -0
- data/ext/clipsruby/genrcexe.c +737 -0
- data/ext/clipsruby/genrcexe.h +73 -0
- data/ext/clipsruby/genrcfun.c +890 -0
- data/ext/clipsruby/genrcfun.h +185 -0
- data/ext/clipsruby/genrcpsr.c +1618 -0
- data/ext/clipsruby/genrcpsr.h +80 -0
- data/ext/clipsruby/globlbin.c +458 -0
- data/ext/clipsruby/globlbin.h +71 -0
- data/ext/clipsruby/globlbsc.c +361 -0
- data/ext/clipsruby/globlbsc.h +83 -0
- data/ext/clipsruby/globlcmp.c +330 -0
- data/ext/clipsruby/globlcmp.h +52 -0
- data/ext/clipsruby/globlcom.c +289 -0
- data/ext/clipsruby/globlcom.h +63 -0
- data/ext/clipsruby/globldef.c +1087 -0
- data/ext/clipsruby/globldef.h +151 -0
- data/ext/clipsruby/globlpsr.c +530 -0
- data/ext/clipsruby/globlpsr.h +59 -0
- data/ext/clipsruby/immthpsr.c +431 -0
- data/ext/clipsruby/immthpsr.h +55 -0
- data/ext/clipsruby/incrrset.c +530 -0
- data/ext/clipsruby/incrrset.h +73 -0
- data/ext/clipsruby/inherpsr.c +850 -0
- data/ext/clipsruby/inherpsr.h +52 -0
- data/ext/clipsruby/inscom.c +2076 -0
- data/ext/clipsruby/inscom.h +182 -0
- data/ext/clipsruby/insfile.c +1764 -0
- data/ext/clipsruby/insfile.h +96 -0
- data/ext/clipsruby/insfun.c +1451 -0
- data/ext/clipsruby/insfun.h +134 -0
- data/ext/clipsruby/insmngr.c +2550 -0
- data/ext/clipsruby/insmngr.h +125 -0
- data/ext/clipsruby/insmoddp.c +1041 -0
- data/ext/clipsruby/insmoddp.h +91 -0
- data/ext/clipsruby/insmult.c +804 -0
- data/ext/clipsruby/insmult.h +62 -0
- data/ext/clipsruby/inspsr.c +602 -0
- data/ext/clipsruby/inspsr.h +60 -0
- data/ext/clipsruby/insquery.c +1278 -0
- data/ext/clipsruby/insquery.h +115 -0
- data/ext/clipsruby/insqypsr.c +729 -0
- data/ext/clipsruby/insqypsr.h +63 -0
- data/ext/clipsruby/iofun.c +2045 -0
- data/ext/clipsruby/iofun.h +116 -0
- data/ext/clipsruby/lgcldpnd.c +644 -0
- data/ext/clipsruby/lgcldpnd.h +75 -0
- data/ext/clipsruby/main.c +112 -0
- data/ext/clipsruby/match.h +142 -0
- data/ext/clipsruby/memalloc.c +481 -0
- data/ext/clipsruby/memalloc.h +197 -0
- data/ext/clipsruby/miscfun.c +1801 -0
- data/ext/clipsruby/miscfun.h +132 -0
- data/ext/clipsruby/modulbin.c +607 -0
- data/ext/clipsruby/modulbin.h +84 -0
- data/ext/clipsruby/modulbsc.c +347 -0
- data/ext/clipsruby/modulbsc.h +67 -0
- data/ext/clipsruby/modulcmp.c +499 -0
- data/ext/clipsruby/modulcmp.h +54 -0
- data/ext/clipsruby/moduldef.c +817 -0
- data/ext/clipsruby/moduldef.h +271 -0
- data/ext/clipsruby/modulpsr.c +1150 -0
- data/ext/clipsruby/modulpsr.h +69 -0
- data/ext/clipsruby/modulutl.c +1036 -0
- data/ext/clipsruby/modulutl.h +84 -0
- data/ext/clipsruby/msgcom.c +1221 -0
- data/ext/clipsruby/msgcom.h +125 -0
- data/ext/clipsruby/msgfun.c +1076 -0
- data/ext/clipsruby/msgfun.h +118 -0
- data/ext/clipsruby/msgpass.c +1441 -0
- data/ext/clipsruby/msgpass.h +103 -0
- data/ext/clipsruby/msgpsr.c +698 -0
- data/ext/clipsruby/msgpsr.h +73 -0
- data/ext/clipsruby/multifld.c +1404 -0
- data/ext/clipsruby/multifld.h +130 -0
- data/ext/clipsruby/multifun.c +2182 -0
- data/ext/clipsruby/multifun.h +102 -0
- data/ext/clipsruby/network.h +142 -0
- data/ext/clipsruby/objbin.c +1522 -0
- data/ext/clipsruby/objbin.h +79 -0
- data/ext/clipsruby/objcmp.c +1507 -0
- data/ext/clipsruby/objcmp.h +71 -0
- data/ext/clipsruby/object.h +260 -0
- data/ext/clipsruby/objrtbin.c +701 -0
- data/ext/clipsruby/objrtbin.h +79 -0
- data/ext/clipsruby/objrtbld.c +2393 -0
- data/ext/clipsruby/objrtbld.h +66 -0
- data/ext/clipsruby/objrtcmp.c +734 -0
- data/ext/clipsruby/objrtcmp.h +66 -0
- data/ext/clipsruby/objrtfnx.c +1330 -0
- data/ext/clipsruby/objrtfnx.h +222 -0
- data/ext/clipsruby/objrtgen.c +736 -0
- data/ext/clipsruby/objrtgen.h +63 -0
- data/ext/clipsruby/objrtmch.c +1524 -0
- data/ext/clipsruby/objrtmch.h +160 -0
- data/ext/clipsruby/parsefun.c +415 -0
- data/ext/clipsruby/parsefun.h +67 -0
- data/ext/clipsruby/pattern.c +1265 -0
- data/ext/clipsruby/pattern.h +163 -0
- data/ext/clipsruby/pprint.c +328 -0
- data/ext/clipsruby/pprint.h +79 -0
- data/ext/clipsruby/prccode.c +1478 -0
- data/ext/clipsruby/prccode.h +145 -0
- data/ext/clipsruby/prcdrfun.c +640 -0
- data/ext/clipsruby/prcdrfun.h +95 -0
- data/ext/clipsruby/prcdrpsr.c +1068 -0
- data/ext/clipsruby/prcdrpsr.h +79 -0
- data/ext/clipsruby/prdctfun.c +869 -0
- data/ext/clipsruby/prdctfun.h +77 -0
- data/ext/clipsruby/prntutil.c +878 -0
- data/ext/clipsruby/prntutil.h +125 -0
- data/ext/clipsruby/proflfun.c +827 -0
- data/ext/clipsruby/proflfun.h +118 -0
- data/ext/clipsruby/reorder.c +2082 -0
- data/ext/clipsruby/reorder.h +172 -0
- data/ext/clipsruby/reteutil.c +1732 -0
- data/ext/clipsruby/reteutil.h +111 -0
- data/ext/clipsruby/retract.c +710 -0
- data/ext/clipsruby/retract.h +74 -0
- data/ext/clipsruby/router.c +737 -0
- data/ext/clipsruby/router.h +147 -0
- data/ext/clipsruby/rulebin.c +1136 -0
- data/ext/clipsruby/rulebin.h +153 -0
- data/ext/clipsruby/rulebld.c +1328 -0
- data/ext/clipsruby/rulebld.h +62 -0
- data/ext/clipsruby/rulebsc.c +517 -0
- data/ext/clipsruby/rulebsc.h +91 -0
- data/ext/clipsruby/rulecmp.c +733 -0
- data/ext/clipsruby/rulecmp.h +63 -0
- data/ext/clipsruby/rulecom.c +1583 -0
- data/ext/clipsruby/rulecom.h +116 -0
- data/ext/clipsruby/rulecstr.c +892 -0
- data/ext/clipsruby/rulecstr.h +53 -0
- data/ext/clipsruby/ruledef.c +559 -0
- data/ext/clipsruby/ruledef.h +179 -0
- data/ext/clipsruby/ruledlt.c +599 -0
- data/ext/clipsruby/ruledlt.h +58 -0
- data/ext/clipsruby/rulelhs.c +1216 -0
- data/ext/clipsruby/rulelhs.h +52 -0
- data/ext/clipsruby/rulepsr.c +1073 -0
- data/ext/clipsruby/rulepsr.h +61 -0
- data/ext/clipsruby/scanner.c +856 -0
- data/ext/clipsruby/scanner.h +112 -0
- data/ext/clipsruby/setup.h +488 -0
- data/ext/clipsruby/sortfun.c +433 -0
- data/ext/clipsruby/sortfun.h +55 -0
- data/ext/clipsruby/strngfun.c +1173 -0
- data/ext/clipsruby/strngfun.h +96 -0
- data/ext/clipsruby/strngrtr.c +523 -0
- data/ext/clipsruby/strngrtr.h +97 -0
- data/ext/clipsruby/symblbin.c +648 -0
- data/ext/clipsruby/symblbin.h +64 -0
- data/ext/clipsruby/symblcmp.c +893 -0
- data/ext/clipsruby/symblcmp.h +61 -0
- data/ext/clipsruby/symbol.c +1961 -0
- data/ext/clipsruby/symbol.h +243 -0
- data/ext/clipsruby/sysdep.c +894 -0
- data/ext/clipsruby/sysdep.h +164 -0
- data/ext/clipsruby/textpro.c +1388 -0
- data/ext/clipsruby/textpro.h +77 -0
- data/ext/clipsruby/tmpltbin.c +609 -0
- data/ext/clipsruby/tmpltbin.h +108 -0
- data/ext/clipsruby/tmpltbsc.c +327 -0
- data/ext/clipsruby/tmpltbsc.h +87 -0
- data/ext/clipsruby/tmpltcmp.c +450 -0
- data/ext/clipsruby/tmpltcmp.h +57 -0
- data/ext/clipsruby/tmpltdef.c +584 -0
- data/ext/clipsruby/tmpltdef.h +155 -0
- data/ext/clipsruby/tmpltfun.c +2477 -0
- data/ext/clipsruby/tmpltfun.h +122 -0
- data/ext/clipsruby/tmpltlhs.c +379 -0
- data/ext/clipsruby/tmpltlhs.h +50 -0
- data/ext/clipsruby/tmpltpsr.c +819 -0
- data/ext/clipsruby/tmpltpsr.h +59 -0
- data/ext/clipsruby/tmpltrhs.c +595 -0
- data/ext/clipsruby/tmpltrhs.h +55 -0
- data/ext/clipsruby/tmpltutl.c +637 -0
- data/ext/clipsruby/tmpltutl.h +82 -0
- data/ext/clipsruby/userdata.c +156 -0
- data/ext/clipsruby/userdata.h +72 -0
- data/ext/clipsruby/userfunctions.c +70 -0
- data/ext/clipsruby/usrsetup.h +7 -0
- data/ext/clipsruby/utility.c +1594 -0
- data/ext/clipsruby/utility.h +250 -0
- data/ext/clipsruby/watch.c +865 -0
- data/ext/clipsruby/watch.h +124 -0
- data/lib/clipsruby.rb +1 -0
- 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 */
|