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,1041 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 06/22/18 */
|
5
|
+
/* */
|
6
|
+
/* INSTANCE MODIFY AND DUPLICATE MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Instance modify and duplicate support routines */
|
11
|
+
/* */
|
12
|
+
/* Principal Programmer(s): */
|
13
|
+
/* Brian L. Dantes */
|
14
|
+
/* */
|
15
|
+
/* Contributing Programmer(s): */
|
16
|
+
/* */
|
17
|
+
/* */
|
18
|
+
/* Revision History: */
|
19
|
+
/* */
|
20
|
+
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
|
21
|
+
/* */
|
22
|
+
/* Changed name of variable exp to theExp */
|
23
|
+
/* because of Unix compiler warnings of shadowed */
|
24
|
+
/* definitions. */
|
25
|
+
/* */
|
26
|
+
/* 6.24: Converted INSTANCE_PATTERN_MATCHING to */
|
27
|
+
/* DEFRULE_CONSTRUCT. */
|
28
|
+
/* */
|
29
|
+
/* 6.30: Added DATA_OBJECT_ARRAY primitive type. */
|
30
|
+
/* */
|
31
|
+
/* Changed integer type/precision. */
|
32
|
+
/* */
|
33
|
+
/* The return value of DirectMessage indicates */
|
34
|
+
/* whether an execution error has occurred. */
|
35
|
+
/* */
|
36
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
37
|
+
/* SetEvaluationError functions. */
|
38
|
+
/* */
|
39
|
+
/* Pragma once and other inclusion changes. */
|
40
|
+
/* */
|
41
|
+
/* Added support for booleans with <stdbool.h>. */
|
42
|
+
/* */
|
43
|
+
/* Removed use of void pointers for specific */
|
44
|
+
/* data structures. */
|
45
|
+
/* */
|
46
|
+
/* UDF redesign. */
|
47
|
+
/* */
|
48
|
+
/* Removed DATA_OBJECT_ARRAY primitive type. */
|
49
|
+
/* */
|
50
|
+
/* Eval support for run time and bload only. */
|
51
|
+
/* */
|
52
|
+
/*************************************************************/
|
53
|
+
|
54
|
+
/* =========================================
|
55
|
+
*****************************************
|
56
|
+
EXTERNAL DEFINITIONS
|
57
|
+
=========================================
|
58
|
+
***************************************** */
|
59
|
+
#include "setup.h"
|
60
|
+
|
61
|
+
#if OBJECT_SYSTEM
|
62
|
+
|
63
|
+
#include "argacces.h"
|
64
|
+
#include "envrnmnt.h"
|
65
|
+
#include "extnfunc.h"
|
66
|
+
#include "inscom.h"
|
67
|
+
#include "insfun.h"
|
68
|
+
#include "insmngr.h"
|
69
|
+
#include "inspsr.h"
|
70
|
+
#include "memalloc.h"
|
71
|
+
#include "miscfun.h"
|
72
|
+
#include "msgcom.h"
|
73
|
+
#include "msgfun.h"
|
74
|
+
#include "msgpass.h"
|
75
|
+
#if DEFRULE_CONSTRUCT
|
76
|
+
#include "network.h"
|
77
|
+
#include "objrtmch.h"
|
78
|
+
#endif
|
79
|
+
#include "prccode.h"
|
80
|
+
#include "prntutil.h"
|
81
|
+
#include "router.h"
|
82
|
+
|
83
|
+
#include "insmoddp.h"
|
84
|
+
|
85
|
+
/***************************************/
|
86
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
87
|
+
/***************************************/
|
88
|
+
|
89
|
+
static UDFValue *EvaluateSlotOverrides(Environment *,Expression *,unsigned short *,bool *);
|
90
|
+
static void DeleteSlotOverrideEvaluations(Environment *,UDFValue *,unsigned short);
|
91
|
+
static void ModifyMsgHandlerSupport(Environment *,UDFValue *,bool);
|
92
|
+
static void DuplicateMsgHandlerSupport(Environment *,UDFValue *,bool);
|
93
|
+
|
94
|
+
/* =========================================
|
95
|
+
*****************************************
|
96
|
+
EXTERNALLY VISIBLE FUNCTIONS
|
97
|
+
=========================================
|
98
|
+
***************************************** */
|
99
|
+
|
100
|
+
/***************************************************
|
101
|
+
NAME : SetupInstanceModDupCommands
|
102
|
+
DESCRIPTION : Defines function interfaces for
|
103
|
+
modify- and duplicate- instance
|
104
|
+
functions
|
105
|
+
INPUTS : None
|
106
|
+
RETURNS : Nothing useful
|
107
|
+
SIDE EFFECTS : Functions defined to KB
|
108
|
+
NOTES : None
|
109
|
+
***************************************************/
|
110
|
+
void SetupInstanceModDupCommands(
|
111
|
+
Environment *theEnv)
|
112
|
+
{
|
113
|
+
#if ! RUN_TIME
|
114
|
+
|
115
|
+
#if DEFRULE_CONSTRUCT
|
116
|
+
AddUDF(theEnv,"modify-instance","*",0,UNBOUNDED,NULL,InactiveModifyInstance,"InactiveModifyInstance",NULL);
|
117
|
+
AddUDF(theEnv,"active-modify-instance","*",0,UNBOUNDED,NULL,ModifyInstance,"ModifyInstance",NULL);
|
118
|
+
AddFunctionParser(theEnv,"active-modify-instance",ParseInitializeInstance);
|
119
|
+
AddUDF(theEnv,"message-modify-instance","*",0,UNBOUNDED,NULL,InactiveMsgModifyInstance,"InactiveMsgModifyInstance",NULL);
|
120
|
+
AddUDF(theEnv,"active-message-modify-instance","*",0,UNBOUNDED,NULL,MsgModifyInstance,"MsgModifyInstance",NULL);
|
121
|
+
AddFunctionParser(theEnv,"active-message-modify-instance",ParseInitializeInstance);
|
122
|
+
|
123
|
+
AddUDF(theEnv,"duplicate-instance","*",0,UNBOUNDED,NULL,InactiveDuplicateInstance,"InactiveDuplicateInstance",NULL);
|
124
|
+
AddUDF(theEnv,"active-duplicate-instance","*",0,UNBOUNDED,NULL,DuplicateInstance,"DuplicateInstance",NULL);
|
125
|
+
AddFunctionParser(theEnv,"active-duplicate-instance",ParseInitializeInstance);
|
126
|
+
AddUDF(theEnv,"message-duplicate-instance","*",0,UNBOUNDED,NULL,InactiveMsgDuplicateInstance,"InactiveMsgDuplicateInstance",NULL);
|
127
|
+
AddUDF(theEnv,"active-message-duplicate-instance","*",0,UNBOUNDED,NULL,MsgDuplicateInstance,"MsgDuplicateInstance",NULL);
|
128
|
+
AddFunctionParser(theEnv,"active-message-duplicate-instance",ParseInitializeInstance);
|
129
|
+
#else
|
130
|
+
AddUDF(theEnv,"modify-instance","*",0,UNBOUNDED,NULL,ModifyInstance,"ModifyInstance",NULL);
|
131
|
+
AddUDF(theEnv,"message-modify-instance","*",0,UNBOUNDED,NULL,MsgModifyInstance,"MsgModifyInstance",NULL);
|
132
|
+
AddUDF(theEnv,"duplicate-instance","*",0,UNBOUNDED,NULL,DuplicateInstance,"DuplicateInstance",NULL);
|
133
|
+
AddUDF(theEnv,"message-duplicate-instance","*",0,UNBOUNDED,NULL,MsgDuplicateInstance,"MsgDuplicateInstance",NULL);
|
134
|
+
#endif
|
135
|
+
|
136
|
+
AddUDF(theEnv,"(direct-modify)","*",0,UNBOUNDED,NULL,DirectModifyMsgHandler,"DirectModifyMsgHandler",NULL);
|
137
|
+
AddUDF(theEnv,"(message-modify)","*",0,UNBOUNDED,NULL,MsgModifyMsgHandler,"MsgModifyMsgHandler",NULL);
|
138
|
+
AddUDF(theEnv,"(direct-duplicate)","*",0,UNBOUNDED,NULL,DirectDuplicateMsgHandler,"DirectDuplicateMsgHandler",NULL);
|
139
|
+
AddUDF(theEnv,"(message-duplicate)","*",0,UNBOUNDED,NULL,MsgDuplicateMsgHandler,"MsgDuplicateMsgHandler",NULL);
|
140
|
+
|
141
|
+
#endif
|
142
|
+
|
143
|
+
#if DEFRULE_CONSTRUCT
|
144
|
+
AddFunctionParser(theEnv,"active-modify-instance",ParseInitializeInstance);
|
145
|
+
AddFunctionParser(theEnv,"active-message-modify-instance",ParseInitializeInstance);
|
146
|
+
|
147
|
+
AddFunctionParser(theEnv,"active-duplicate-instance",ParseInitializeInstance);
|
148
|
+
AddFunctionParser(theEnv,"active-message-duplicate-instance",ParseInitializeInstance);
|
149
|
+
#endif
|
150
|
+
|
151
|
+
AddFunctionParser(theEnv,"modify-instance",ParseInitializeInstance);
|
152
|
+
AddFunctionParser(theEnv,"message-modify-instance",ParseInitializeInstance);
|
153
|
+
AddFunctionParser(theEnv,"duplicate-instance",ParseInitializeInstance);
|
154
|
+
AddFunctionParser(theEnv,"message-duplicate-instance",ParseInitializeInstance);
|
155
|
+
}
|
156
|
+
|
157
|
+
/*************************************************************
|
158
|
+
NAME : ModifyInstance
|
159
|
+
DESCRIPTION : Modifies slots of an instance via the
|
160
|
+
direct-modify message
|
161
|
+
INPUTS : The address of the result value
|
162
|
+
RETURNS : Nothing useful
|
163
|
+
SIDE EFFECTS : Slot updates performed directly
|
164
|
+
NOTES : H/L Syntax:
|
165
|
+
(modify-instance <instance> <slot-override>*)
|
166
|
+
*************************************************************/
|
167
|
+
void ModifyInstance(
|
168
|
+
Environment *theEnv,
|
169
|
+
UDFContext *context,
|
170
|
+
UDFValue *returnValue)
|
171
|
+
{
|
172
|
+
Instance *ins;
|
173
|
+
Expression theExp;
|
174
|
+
UDFValue *overrides;
|
175
|
+
bool oldOMDMV;
|
176
|
+
unsigned short overrideCount;
|
177
|
+
bool error;
|
178
|
+
|
179
|
+
/* ===========================================
|
180
|
+
The slot-overrides need to be evaluated now
|
181
|
+
to resolve any variable references before a
|
182
|
+
new frame is pushed for message-handler
|
183
|
+
execution
|
184
|
+
=========================================== */
|
185
|
+
|
186
|
+
overrides = EvaluateSlotOverrides(theEnv,GetFirstArgument()->nextArg,
|
187
|
+
&overrideCount,&error);
|
188
|
+
if (error)
|
189
|
+
{
|
190
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
|
194
|
+
/* ==================================
|
195
|
+
Find the instance and make sure it
|
196
|
+
wasn't deleted by the overrides
|
197
|
+
================================== */
|
198
|
+
ins = CheckInstance(context);
|
199
|
+
if (ins == NULL)
|
200
|
+
{
|
201
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
202
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
203
|
+
return;
|
204
|
+
}
|
205
|
+
|
206
|
+
/* ======================================
|
207
|
+
We are passing the slot override
|
208
|
+
expression information along
|
209
|
+
to whatever message-handler implements
|
210
|
+
the modify
|
211
|
+
====================================== */
|
212
|
+
|
213
|
+
theExp.type = EXTERNAL_ADDRESS_TYPE;
|
214
|
+
theExp.value = CreateExternalAddress(theEnv,overrides,0);
|
215
|
+
theExp.argList = NULL;
|
216
|
+
theExp.nextArg = NULL;
|
217
|
+
|
218
|
+
oldOMDMV = InstanceData(theEnv)->ObjectModDupMsgValid;
|
219
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = true;
|
220
|
+
DirectMessage(theEnv,FindSymbolHN(theEnv,DIRECT_MODIFY_STRING,SYMBOL_BIT),ins,returnValue,&theExp);
|
221
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = oldOMDMV;
|
222
|
+
|
223
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
224
|
+
}
|
225
|
+
|
226
|
+
/*************************************************************
|
227
|
+
NAME : MsgModifyInstance
|
228
|
+
DESCRIPTION : Modifies slots of an instance via the
|
229
|
+
direct-modify message
|
230
|
+
INPUTS : The address of the result value
|
231
|
+
RETURNS : Nothing useful
|
232
|
+
SIDE EFFECTS : Slot updates performed with put- messages
|
233
|
+
NOTES : H/L Syntax:
|
234
|
+
(message-modify-instance <instance>
|
235
|
+
<slot-override>*)
|
236
|
+
*************************************************************/
|
237
|
+
void MsgModifyInstance(
|
238
|
+
Environment *theEnv,
|
239
|
+
UDFContext *context,
|
240
|
+
UDFValue *returnValue)
|
241
|
+
{
|
242
|
+
Instance *ins;
|
243
|
+
Expression theExp;
|
244
|
+
UDFValue *overrides;
|
245
|
+
bool oldOMDMV;
|
246
|
+
unsigned short overrideCount;
|
247
|
+
bool error;
|
248
|
+
|
249
|
+
/* ===========================================
|
250
|
+
The slot-overrides need to be evaluated now
|
251
|
+
to resolve any variable references before a
|
252
|
+
new frame is pushed for message-handler
|
253
|
+
execution
|
254
|
+
=========================================== */
|
255
|
+
overrides = EvaluateSlotOverrides(theEnv,GetFirstArgument()->nextArg,
|
256
|
+
&overrideCount,&error);
|
257
|
+
if (error)
|
258
|
+
{
|
259
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
260
|
+
return;
|
261
|
+
}
|
262
|
+
|
263
|
+
/* ==================================
|
264
|
+
Find the instance and make sure it
|
265
|
+
wasn't deleted by the overrides
|
266
|
+
================================== */
|
267
|
+
ins = CheckInstance(context);
|
268
|
+
if (ins == NULL)
|
269
|
+
{
|
270
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
271
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
272
|
+
return;
|
273
|
+
}
|
274
|
+
|
275
|
+
/* ======================================
|
276
|
+
We are passing the slot override
|
277
|
+
expression information along
|
278
|
+
to whatever message-handler implements
|
279
|
+
the modify
|
280
|
+
====================================== */
|
281
|
+
|
282
|
+
theExp.type = EXTERNAL_ADDRESS_TYPE;
|
283
|
+
theExp.value = CreateExternalAddress(theEnv,overrides,0);
|
284
|
+
theExp.argList = NULL;
|
285
|
+
theExp.nextArg = NULL;
|
286
|
+
|
287
|
+
oldOMDMV = InstanceData(theEnv)->ObjectModDupMsgValid;
|
288
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = true;
|
289
|
+
DirectMessage(theEnv,FindSymbolHN(theEnv,MSG_MODIFY_STRING,SYMBOL_BIT),ins,returnValue,&theExp);
|
290
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = oldOMDMV;
|
291
|
+
|
292
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
293
|
+
}
|
294
|
+
|
295
|
+
/*************************************************************
|
296
|
+
NAME : DuplicateInstance
|
297
|
+
DESCRIPTION : Duplicates an instance via the
|
298
|
+
direct-duplicate message
|
299
|
+
INPUTS : The address of the result value
|
300
|
+
RETURNS : Nothing useful
|
301
|
+
SIDE EFFECTS : Slot updates performed directly
|
302
|
+
NOTES : H/L Syntax:
|
303
|
+
(duplicate-instance <instance>
|
304
|
+
[to <instance-name>] <slot-override>*)
|
305
|
+
*************************************************************/
|
306
|
+
void DuplicateInstance(
|
307
|
+
Environment *theEnv,
|
308
|
+
UDFContext *context,
|
309
|
+
UDFValue *returnValue)
|
310
|
+
{
|
311
|
+
Instance *ins;
|
312
|
+
UDFValue newName;
|
313
|
+
Expression theExp[2];
|
314
|
+
UDFValue *overrides;
|
315
|
+
bool oldOMDMV;
|
316
|
+
unsigned short overrideCount;
|
317
|
+
bool error;
|
318
|
+
|
319
|
+
/* ===========================================
|
320
|
+
The slot-overrides need to be evaluated now
|
321
|
+
to resolve any variable references before a
|
322
|
+
new frame is pushed for message-handler
|
323
|
+
execution
|
324
|
+
=========================================== */
|
325
|
+
overrides = EvaluateSlotOverrides(theEnv,GetFirstArgument()->nextArg->nextArg,
|
326
|
+
&overrideCount,&error);
|
327
|
+
if (error)
|
328
|
+
{
|
329
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
330
|
+
return;
|
331
|
+
}
|
332
|
+
|
333
|
+
/* ==================================
|
334
|
+
Find the instance and make sure it
|
335
|
+
wasn't deleted by the overrides
|
336
|
+
================================== */
|
337
|
+
ins = CheckInstance(context);
|
338
|
+
if (ins == NULL)
|
339
|
+
{
|
340
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
341
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
342
|
+
return;
|
343
|
+
}
|
344
|
+
|
345
|
+
if (! UDFNextArgument(context,INSTANCE_NAME_BIT | SYMBOL_BIT,&newName))
|
346
|
+
{
|
347
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
348
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
349
|
+
return;
|
350
|
+
}
|
351
|
+
|
352
|
+
/* ======================================
|
353
|
+
We are passing the slot override
|
354
|
+
expression information along
|
355
|
+
to whatever message-handler implements
|
356
|
+
the duplicate
|
357
|
+
====================================== */
|
358
|
+
theExp[0].type = INSTANCE_NAME_TYPE;
|
359
|
+
theExp[0].value = newName.value;
|
360
|
+
theExp[0].argList = NULL;
|
361
|
+
theExp[0].nextArg = &theExp[1];
|
362
|
+
theExp[1].type = EXTERNAL_ADDRESS_TYPE;
|
363
|
+
theExp[1].value = CreateExternalAddress(theEnv,overrides,0);
|
364
|
+
theExp[1].argList = NULL;
|
365
|
+
theExp[1].nextArg = NULL;
|
366
|
+
|
367
|
+
oldOMDMV = InstanceData(theEnv)->ObjectModDupMsgValid;
|
368
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = true;
|
369
|
+
DirectMessage(theEnv,FindSymbolHN(theEnv,DIRECT_DUPLICATE_STRING,SYMBOL_BIT),ins,returnValue,&theExp[0]);
|
370
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = oldOMDMV;
|
371
|
+
|
372
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
373
|
+
}
|
374
|
+
|
375
|
+
/*************************************************************
|
376
|
+
NAME : MsgDuplicateInstance
|
377
|
+
DESCRIPTION : Duplicates an instance via the
|
378
|
+
message-duplicate message
|
379
|
+
INPUTS : The address of the result value
|
380
|
+
RETURNS : Nothing useful
|
381
|
+
SIDE EFFECTS : Slot updates performed w/ int & put- messages
|
382
|
+
NOTES : H/L Syntax:
|
383
|
+
(duplicate-instance <instance>
|
384
|
+
[to <instance-name>] <slot-override>*)
|
385
|
+
*************************************************************/
|
386
|
+
void MsgDuplicateInstance(
|
387
|
+
Environment *theEnv,
|
388
|
+
UDFContext *context,
|
389
|
+
UDFValue *returnValue)
|
390
|
+
{
|
391
|
+
Instance *ins;
|
392
|
+
UDFValue newName;
|
393
|
+
Expression theExp[2];
|
394
|
+
UDFValue *overrides;
|
395
|
+
bool oldOMDMV;
|
396
|
+
unsigned short overrideCount;
|
397
|
+
bool error;
|
398
|
+
|
399
|
+
/* ===========================================
|
400
|
+
The slot-overrides need to be evaluated now
|
401
|
+
to resolve any variable references before a
|
402
|
+
new frame is pushed for message-handler
|
403
|
+
execution
|
404
|
+
=========================================== */
|
405
|
+
overrides = EvaluateSlotOverrides(theEnv,GetFirstArgument()->nextArg->nextArg,
|
406
|
+
&overrideCount,&error);
|
407
|
+
if (error)
|
408
|
+
{
|
409
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
410
|
+
return;
|
411
|
+
}
|
412
|
+
|
413
|
+
/* ==================================
|
414
|
+
Find the instance and make sure it
|
415
|
+
wasn't deleted by the overrides
|
416
|
+
================================== */
|
417
|
+
ins = CheckInstance(context);
|
418
|
+
if (ins == NULL)
|
419
|
+
{
|
420
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
421
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
422
|
+
return;
|
423
|
+
}
|
424
|
+
if (! UDFNextArgument(context,INSTANCE_NAME_BIT | SYMBOL_BIT,&newName))
|
425
|
+
{
|
426
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
427
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
428
|
+
return;
|
429
|
+
}
|
430
|
+
|
431
|
+
/* ======================================
|
432
|
+
We are passing the slot override
|
433
|
+
expression information along
|
434
|
+
to whatever message-handler implements
|
435
|
+
the duplicate
|
436
|
+
====================================== */
|
437
|
+
theExp[0].type = INSTANCE_NAME_TYPE;
|
438
|
+
theExp[0].value = newName.value;
|
439
|
+
theExp[0].argList = NULL;
|
440
|
+
theExp[0].nextArg = &theExp[1];
|
441
|
+
theExp[1].type = EXTERNAL_ADDRESS_TYPE;
|
442
|
+
theExp[1].value = CreateExternalAddress(theEnv,overrides,0);
|
443
|
+
theExp[1].argList = NULL;
|
444
|
+
theExp[1].nextArg = NULL;
|
445
|
+
|
446
|
+
oldOMDMV = InstanceData(theEnv)->ObjectModDupMsgValid;
|
447
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = true;
|
448
|
+
DirectMessage(theEnv,FindSymbolHN(theEnv,MSG_DUPLICATE_STRING,SYMBOL_BIT),ins,returnValue,&theExp[0]);
|
449
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = oldOMDMV;
|
450
|
+
|
451
|
+
DeleteSlotOverrideEvaluations(theEnv,overrides,overrideCount);
|
452
|
+
}
|
453
|
+
|
454
|
+
#if DEFRULE_CONSTRUCT
|
455
|
+
|
456
|
+
/**************************************************************
|
457
|
+
NAME : InactiveModifyInstance
|
458
|
+
DESCRIPTION : Modifies slots of an instance of a class
|
459
|
+
Pattern-matching is automatically
|
460
|
+
delayed until the slot updates are done
|
461
|
+
INPUTS : The address of the result value
|
462
|
+
RETURNS : Nothing useful
|
463
|
+
SIDE EFFECTS : Slot updates performed directly
|
464
|
+
NOTES : H/L Syntax:
|
465
|
+
(modify-instance <instance-name>
|
466
|
+
<slot-override>*)
|
467
|
+
**************************************************************/
|
468
|
+
void InactiveModifyInstance(
|
469
|
+
Environment *theEnv,
|
470
|
+
UDFContext *context,
|
471
|
+
UDFValue *returnValue)
|
472
|
+
{
|
473
|
+
bool ov;
|
474
|
+
|
475
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
476
|
+
ModifyInstance(theEnv,context,returnValue);
|
477
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
478
|
+
}
|
479
|
+
|
480
|
+
/**************************************************************
|
481
|
+
NAME : InactiveMsgModifyInstance
|
482
|
+
DESCRIPTION : Modifies slots of an instance of a class
|
483
|
+
Pattern-matching is automatically
|
484
|
+
delayed until the slot updates are done
|
485
|
+
INPUTS : The address of the result value
|
486
|
+
RETURNS : Nothing useful
|
487
|
+
SIDE EFFECTS : Slot updates performed with put- messages
|
488
|
+
NOTES : H/L Syntax:
|
489
|
+
(message-modify-instance <instance-name>
|
490
|
+
<slot-override>*)
|
491
|
+
**************************************************************/
|
492
|
+
void InactiveMsgModifyInstance(
|
493
|
+
Environment *theEnv,
|
494
|
+
UDFContext *context,
|
495
|
+
UDFValue *returnValue)
|
496
|
+
{
|
497
|
+
bool ov;
|
498
|
+
|
499
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
500
|
+
MsgModifyInstance(theEnv,context,returnValue);
|
501
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
502
|
+
}
|
503
|
+
|
504
|
+
/*******************************************************************
|
505
|
+
NAME : InactiveDuplicateInstance
|
506
|
+
DESCRIPTION : Duplicates an instance of a class
|
507
|
+
Pattern-matching is automatically
|
508
|
+
delayed until the slot updates are done
|
509
|
+
INPUTS : The address of the result value
|
510
|
+
RETURNS : Nothing useful
|
511
|
+
SIDE EFFECTS : Slot updates performed directly
|
512
|
+
NOTES : H/L Syntax:
|
513
|
+
(duplicate-instance <instance> [to <instance-name>]
|
514
|
+
<slot-override>*)
|
515
|
+
*******************************************************************/
|
516
|
+
void InactiveDuplicateInstance(
|
517
|
+
Environment *theEnv,
|
518
|
+
UDFContext *context,
|
519
|
+
UDFValue *returnValue)
|
520
|
+
{
|
521
|
+
bool ov;
|
522
|
+
|
523
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
524
|
+
DuplicateInstance(theEnv,context,returnValue);
|
525
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
526
|
+
}
|
527
|
+
|
528
|
+
/**************************************************************
|
529
|
+
NAME : InactiveMsgDuplicateInstance
|
530
|
+
DESCRIPTION : Duplicates an instance of a class
|
531
|
+
Pattern-matching is automatically
|
532
|
+
delayed until the slot updates are done
|
533
|
+
INPUTS : The address of the result value
|
534
|
+
RETURNS : Nothing useful
|
535
|
+
SIDE EFFECTS : Slot updates performed with put- messages
|
536
|
+
NOTES : H/L Syntax:
|
537
|
+
(message-duplicate-instance <instance>
|
538
|
+
[to <instance-name>]
|
539
|
+
<slot-override>*)
|
540
|
+
**************************************************************/
|
541
|
+
void InactiveMsgDuplicateInstance(
|
542
|
+
Environment *theEnv,
|
543
|
+
UDFContext *context,
|
544
|
+
UDFValue *returnValue)
|
545
|
+
{
|
546
|
+
bool ov;
|
547
|
+
|
548
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
549
|
+
MsgDuplicateInstance(theEnv,context,returnValue);
|
550
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
551
|
+
}
|
552
|
+
|
553
|
+
#endif
|
554
|
+
|
555
|
+
/*****************************************************
|
556
|
+
NAME : DirectDuplicateMsgHandler
|
557
|
+
DESCRIPTION : Implementation for the USER class
|
558
|
+
handler direct-duplicate
|
559
|
+
|
560
|
+
Implements duplicate-instance message
|
561
|
+
with a series of direct slot
|
562
|
+
placements
|
563
|
+
INPUTS : A data object buffer to hold the
|
564
|
+
result
|
565
|
+
RETURNS : Nothing useful
|
566
|
+
SIDE EFFECTS : Slot values updated
|
567
|
+
NOTES : None
|
568
|
+
*****************************************************/
|
569
|
+
void DirectDuplicateMsgHandler(
|
570
|
+
Environment *theEnv,
|
571
|
+
UDFContext *context,
|
572
|
+
UDFValue *returnValue)
|
573
|
+
{
|
574
|
+
DuplicateMsgHandlerSupport(theEnv,returnValue,false);
|
575
|
+
}
|
576
|
+
|
577
|
+
/*****************************************************
|
578
|
+
NAME : MsgDuplicateMsgHandler
|
579
|
+
DESCRIPTION : Implementation for the USER class
|
580
|
+
handler message-duplicate
|
581
|
+
|
582
|
+
Implements duplicate-instance message
|
583
|
+
with a series of put- messages
|
584
|
+
INPUTS : A data object buffer to hold the
|
585
|
+
result
|
586
|
+
RETURNS : Nothing useful
|
587
|
+
SIDE EFFECTS : Slot values updated
|
588
|
+
NOTES : None
|
589
|
+
*****************************************************/
|
590
|
+
void MsgDuplicateMsgHandler(
|
591
|
+
Environment *theEnv,
|
592
|
+
UDFContext *context,
|
593
|
+
UDFValue *returnValue)
|
594
|
+
{
|
595
|
+
DuplicateMsgHandlerSupport(theEnv,returnValue,true);
|
596
|
+
}
|
597
|
+
|
598
|
+
/***************************************************
|
599
|
+
NAME : DirectModifyMsgHandler
|
600
|
+
DESCRIPTION : Implementation for the USER class
|
601
|
+
handler direct-modify
|
602
|
+
|
603
|
+
Implements modify-instance message
|
604
|
+
with a series of direct slot
|
605
|
+
placements
|
606
|
+
INPUTS : A data object buffer to hold the
|
607
|
+
result
|
608
|
+
RETURNS : Nothing useful
|
609
|
+
SIDE EFFECTS : Slot values updated
|
610
|
+
NOTES : None
|
611
|
+
***************************************************/
|
612
|
+
void DirectModifyMsgHandler(
|
613
|
+
Environment *theEnv,
|
614
|
+
UDFContext *context,
|
615
|
+
UDFValue *returnValue)
|
616
|
+
{
|
617
|
+
ModifyMsgHandlerSupport(theEnv,returnValue,false);
|
618
|
+
}
|
619
|
+
|
620
|
+
/***************************************************
|
621
|
+
NAME : MsgModifyMsgHandler
|
622
|
+
DESCRIPTION : Implementation for the USER class
|
623
|
+
handler message-modify
|
624
|
+
|
625
|
+
Implements modify-instance message
|
626
|
+
with a series of put- messages
|
627
|
+
INPUTS : A data object buffer to hold the
|
628
|
+
result
|
629
|
+
RETURNS : Nothing useful
|
630
|
+
SIDE EFFECTS : Slot values updated
|
631
|
+
NOTES : None
|
632
|
+
***************************************************/
|
633
|
+
void MsgModifyMsgHandler(
|
634
|
+
Environment *theEnv,
|
635
|
+
UDFContext *context,
|
636
|
+
UDFValue *returnValue)
|
637
|
+
{
|
638
|
+
ModifyMsgHandlerSupport(theEnv,returnValue,true);
|
639
|
+
}
|
640
|
+
|
641
|
+
/* =========================================
|
642
|
+
*****************************************
|
643
|
+
INTERNALLY VISIBLE FUNCTIONS
|
644
|
+
=========================================
|
645
|
+
***************************************** */
|
646
|
+
|
647
|
+
/***********************************************************
|
648
|
+
NAME : EvaluateSlotOverrides
|
649
|
+
DESCRIPTION : Evaluates the slot-override expressions
|
650
|
+
for modify-instance and duplicate-instance
|
651
|
+
Evaluations are stored in an array of
|
652
|
+
data objects, where the supplementalInfo
|
653
|
+
field points at the name of the slot
|
654
|
+
The data object next fields are used
|
655
|
+
to link the array as well.
|
656
|
+
INPUTS : 1) The slot override expressions
|
657
|
+
2) A buffer to hold the number
|
658
|
+
of slot overrides
|
659
|
+
3) A buffer to hold an error flag
|
660
|
+
RETURNS : The slot override data object array
|
661
|
+
SIDE EFFECTS : Data object array allocated and initialized
|
662
|
+
override count and error buffers set
|
663
|
+
NOTES : Slot overrides must be evaluated before
|
664
|
+
calling supporting message-handlers for
|
665
|
+
modify- and duplicate-instance in the
|
666
|
+
event that the overrides contain variable
|
667
|
+
references to an outer frame
|
668
|
+
***********************************************************/
|
669
|
+
static UDFValue *EvaluateSlotOverrides(
|
670
|
+
Environment *theEnv,
|
671
|
+
Expression *ovExprs,
|
672
|
+
unsigned short *ovCnt,
|
673
|
+
bool *error)
|
674
|
+
{
|
675
|
+
UDFValue *ovs;
|
676
|
+
unsigned ovi;
|
677
|
+
void *slotName;
|
678
|
+
|
679
|
+
*error = false;
|
680
|
+
|
681
|
+
/* ==========================================
|
682
|
+
There are two expressions chains for every
|
683
|
+
slot override: one for the slot name and
|
684
|
+
one for the slot value
|
685
|
+
========================================== */
|
686
|
+
*ovCnt = CountArguments(ovExprs) / 2;
|
687
|
+
if (*ovCnt == 0)
|
688
|
+
return NULL;
|
689
|
+
|
690
|
+
/* ===============================================
|
691
|
+
Evaluate all the slot override names and values
|
692
|
+
and store them in a contiguous array
|
693
|
+
=============================================== */
|
694
|
+
ovs = (UDFValue *) gm2(theEnv,(sizeof(UDFValue) * (*ovCnt)));
|
695
|
+
ovi = 0;
|
696
|
+
while (ovExprs != NULL)
|
697
|
+
{
|
698
|
+
if (EvaluateExpression(theEnv,ovExprs,&ovs[ovi]))
|
699
|
+
goto EvaluateOverridesError;
|
700
|
+
if (ovs[ovi].header->type != SYMBOL_TYPE)
|
701
|
+
{
|
702
|
+
ExpectedTypeError1(theEnv,ExpressionFunctionCallName(EvaluationData(theEnv)->CurrentExpression)->contents,
|
703
|
+
ovi+1,"slot name");
|
704
|
+
SetEvaluationError(theEnv,true);
|
705
|
+
goto EvaluateOverridesError;
|
706
|
+
}
|
707
|
+
slotName = ovs[ovi].value;
|
708
|
+
if (ovExprs->nextArg->argList)
|
709
|
+
{
|
710
|
+
if (EvaluateAndStoreInDataObject(theEnv,false,ovExprs->nextArg->argList,
|
711
|
+
&ovs[ovi],true) == false)
|
712
|
+
goto EvaluateOverridesError;
|
713
|
+
}
|
714
|
+
else
|
715
|
+
{
|
716
|
+
ovs[ovi].begin = 0;
|
717
|
+
ovs[ovi].range = 0;
|
718
|
+
ovs[ovi].value = ProceduralPrimitiveData(theEnv)->NoParamValue;
|
719
|
+
}
|
720
|
+
ovs[ovi].supplementalInfo = slotName;
|
721
|
+
ovExprs = ovExprs->nextArg->nextArg;
|
722
|
+
ovs[ovi].next = (ovExprs != NULL) ? &ovs[ovi+1] : NULL;
|
723
|
+
ovi++;
|
724
|
+
}
|
725
|
+
return(ovs);
|
726
|
+
|
727
|
+
EvaluateOverridesError:
|
728
|
+
rm(theEnv,ovs,(sizeof(UDFValue) * (*ovCnt)));
|
729
|
+
*error = true;
|
730
|
+
return NULL;
|
731
|
+
}
|
732
|
+
|
733
|
+
/**********************************************************
|
734
|
+
NAME : DeleteSlotOverrideEvaluations
|
735
|
+
DESCRIPTION : Deallocates slot override evaluation array
|
736
|
+
INPUTS : 1) The data object array
|
737
|
+
2) The number of elements
|
738
|
+
RETURNS : Nothing useful
|
739
|
+
SIDE EFFECTS : Deallocates slot override data object
|
740
|
+
array for modify- and duplicate- instance
|
741
|
+
NOTES : None
|
742
|
+
**********************************************************/
|
743
|
+
static void DeleteSlotOverrideEvaluations(
|
744
|
+
Environment *theEnv,
|
745
|
+
UDFValue *ovEvals,
|
746
|
+
unsigned short ovCnt)
|
747
|
+
{
|
748
|
+
if (ovEvals != NULL)
|
749
|
+
rm(theEnv,ovEvals,(sizeof(UDFValue) * ovCnt));
|
750
|
+
}
|
751
|
+
|
752
|
+
/**********************************************************
|
753
|
+
NAME : ModifyMsgHandlerSupport
|
754
|
+
DESCRIPTION : Support routine for DirectModifyMsgHandler
|
755
|
+
and MsgModifyMsgHandler
|
756
|
+
|
757
|
+
Performs a series of slot updates
|
758
|
+
directly or with messages
|
759
|
+
INPUTS : 1) A data object buffer to hold the result
|
760
|
+
2) A flag indicating whether to use
|
761
|
+
put- messages or direct placement
|
762
|
+
RETURNS : Nothing useful
|
763
|
+
SIDE EFFECTS : Slots updated (messages sent)
|
764
|
+
NOTES : None
|
765
|
+
**********************************************************/
|
766
|
+
static void ModifyMsgHandlerSupport(
|
767
|
+
Environment *theEnv,
|
768
|
+
UDFValue *returnValue,
|
769
|
+
bool msgpass)
|
770
|
+
{
|
771
|
+
UDFValue *slotOverrides,*newval,temp,junk;
|
772
|
+
Expression msgExp;
|
773
|
+
Instance *ins;
|
774
|
+
InstanceSlot *insSlot;
|
775
|
+
|
776
|
+
returnValue->value = FalseSymbol(theEnv);
|
777
|
+
if (InstanceData(theEnv)->ObjectModDupMsgValid == false)
|
778
|
+
{
|
779
|
+
PrintErrorID(theEnv,"INSMODDP",1,false);
|
780
|
+
WriteString(theEnv,STDERR,"Direct/message-modify message valid only in modify-instance.\n");
|
781
|
+
SetEvaluationError(theEnv,true);
|
782
|
+
return;
|
783
|
+
}
|
784
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = false;
|
785
|
+
|
786
|
+
ins = GetActiveInstance(theEnv);
|
787
|
+
if (ins->garbage)
|
788
|
+
{
|
789
|
+
StaleInstanceAddress(theEnv,"modify-instance",0);
|
790
|
+
SetEvaluationError(theEnv,true);
|
791
|
+
return;
|
792
|
+
}
|
793
|
+
|
794
|
+
/* =======================================
|
795
|
+
Retrieve the slot override data objects
|
796
|
+
passed from ModifyInstance - the slot
|
797
|
+
name is stored in the supplementalInfo
|
798
|
+
field - and the next fields are links
|
799
|
+
======================================= */
|
800
|
+
|
801
|
+
slotOverrides = (UDFValue *) ((CLIPSExternalAddress *) GetNthMessageArgument(theEnv,1)->value)->contents;
|
802
|
+
|
803
|
+
while (slotOverrides != NULL)
|
804
|
+
{
|
805
|
+
/* ===========================================================
|
806
|
+
No evaluation or error checking needs to be done
|
807
|
+
since this has already been done by EvaluateSlotOverrides()
|
808
|
+
=========================================================== */
|
809
|
+
insSlot = FindInstanceSlot(theEnv,ins,(CLIPSLexeme *) slotOverrides->supplementalInfo);
|
810
|
+
if (insSlot == NULL)
|
811
|
+
{
|
812
|
+
SlotExistError(theEnv,((CLIPSLexeme *) slotOverrides->supplementalInfo)->contents,"modify-instance");
|
813
|
+
SetEvaluationError(theEnv,true);
|
814
|
+
return;
|
815
|
+
}
|
816
|
+
if (msgpass)
|
817
|
+
{
|
818
|
+
msgExp.type = slotOverrides->header->type;
|
819
|
+
if (msgExp.type != MULTIFIELD_TYPE)
|
820
|
+
msgExp.value = slotOverrides->value;
|
821
|
+
else
|
822
|
+
msgExp.value = slotOverrides;
|
823
|
+
msgExp.argList = NULL;
|
824
|
+
msgExp.nextArg = NULL;
|
825
|
+
if (! DirectMessage(theEnv,insSlot->desc->overrideMessage,ins,&temp,&msgExp))
|
826
|
+
return;
|
827
|
+
}
|
828
|
+
else
|
829
|
+
{
|
830
|
+
if (insSlot->desc->multiple && (slotOverrides->header->type != MULTIFIELD_TYPE))
|
831
|
+
{
|
832
|
+
temp.value = CreateMultifield(theEnv,1L);
|
833
|
+
temp.begin = 0;
|
834
|
+
temp.range = 1;
|
835
|
+
temp.multifieldValue->contents[0].value = slotOverrides->value;
|
836
|
+
newval = &temp;
|
837
|
+
}
|
838
|
+
else
|
839
|
+
newval = slotOverrides;
|
840
|
+
if (PutSlotValue(theEnv,ins,insSlot,newval,&junk,"modify-instance") != PSE_NO_ERROR)
|
841
|
+
return;
|
842
|
+
}
|
843
|
+
|
844
|
+
slotOverrides = slotOverrides->next;
|
845
|
+
}
|
846
|
+
returnValue->value = TrueSymbol(theEnv);
|
847
|
+
}
|
848
|
+
|
849
|
+
/*************************************************************
|
850
|
+
NAME : DuplicateMsgHandlerSupport
|
851
|
+
DESCRIPTION : Support routine for DirectDuplicateMsgHandler
|
852
|
+
and MsgDuplicateMsgHandler
|
853
|
+
|
854
|
+
Performs a series of slot updates
|
855
|
+
directly or with messages
|
856
|
+
INPUTS : 1) A data object buffer to hold the result
|
857
|
+
2) A flag indicating whether to use
|
858
|
+
put- messages or direct placement
|
859
|
+
RETURNS : Nothing useful
|
860
|
+
SIDE EFFECTS : Slots updated (messages sent)
|
861
|
+
NOTES : None
|
862
|
+
*************************************************************/
|
863
|
+
static void DuplicateMsgHandlerSupport(
|
864
|
+
Environment *theEnv,
|
865
|
+
UDFValue *returnValue,
|
866
|
+
bool msgpass)
|
867
|
+
{
|
868
|
+
Instance *srcins,*dstins;
|
869
|
+
CLIPSLexeme *newName;
|
870
|
+
UDFValue *slotOverrides;
|
871
|
+
Expression *valArg,msgExp;
|
872
|
+
long i;
|
873
|
+
bool oldMkInsMsgPass;
|
874
|
+
InstanceSlot *dstInsSlot;
|
875
|
+
UDFValue temp,junk,*newval;
|
876
|
+
bool success;
|
877
|
+
|
878
|
+
returnValue->value = FalseSymbol(theEnv);
|
879
|
+
if (InstanceData(theEnv)->ObjectModDupMsgValid == false)
|
880
|
+
{
|
881
|
+
PrintErrorID(theEnv,"INSMODDP",2,false);
|
882
|
+
WriteString(theEnv,STDERR,"Direct/message-duplicate message valid only in duplicate-instance.\n");
|
883
|
+
SetEvaluationError(theEnv,true);
|
884
|
+
return;
|
885
|
+
}
|
886
|
+
InstanceData(theEnv)->ObjectModDupMsgValid = false;
|
887
|
+
|
888
|
+
/* ==================================
|
889
|
+
Grab the slot override expressions
|
890
|
+
and determine the source instance
|
891
|
+
and the name of the new instance
|
892
|
+
================================== */
|
893
|
+
srcins = GetActiveInstance(theEnv);
|
894
|
+
newName = GetNthMessageArgument(theEnv,1)->lexemeValue;
|
895
|
+
slotOverrides = (UDFValue *) ((CLIPSExternalAddress *) GetNthMessageArgument(theEnv,2)->value)->contents;
|
896
|
+
if (srcins->garbage)
|
897
|
+
{
|
898
|
+
StaleInstanceAddress(theEnv,"duplicate-instance",0);
|
899
|
+
SetEvaluationError(theEnv,true);
|
900
|
+
return;
|
901
|
+
}
|
902
|
+
if (((newName->header.type == srcins->name->header.type) &&
|
903
|
+
(newName == srcins->name)) ||
|
904
|
+
(strcmp(newName->contents,srcins->name->contents) == 0))
|
905
|
+
{
|
906
|
+
PrintErrorID(theEnv,"INSMODDP",3,false);
|
907
|
+
WriteString(theEnv,STDERR,"Instance copy must have a different name in duplicate-instance.\n");
|
908
|
+
SetEvaluationError(theEnv,true);
|
909
|
+
return;
|
910
|
+
}
|
911
|
+
|
912
|
+
/* ==========================================
|
913
|
+
Create an uninitialized new instance of
|
914
|
+
the new name (delete old version - if any)
|
915
|
+
========================================== */
|
916
|
+
oldMkInsMsgPass = InstanceData(theEnv)->MkInsMsgPass;
|
917
|
+
InstanceData(theEnv)->MkInsMsgPass = msgpass;
|
918
|
+
dstins = BuildInstance(theEnv,newName,srcins->cls,true);
|
919
|
+
InstanceData(theEnv)->MkInsMsgPass = oldMkInsMsgPass;
|
920
|
+
if (dstins == NULL)
|
921
|
+
return;
|
922
|
+
dstins->busy++;
|
923
|
+
|
924
|
+
/* ================================
|
925
|
+
Place slot overrides directly or
|
926
|
+
with put- messages
|
927
|
+
================================ */
|
928
|
+
while (slotOverrides != NULL)
|
929
|
+
{
|
930
|
+
/* ===========================================================
|
931
|
+
No evaluation or error checking needs to be done
|
932
|
+
since this has already been done by EvaluateSlotOverrides()
|
933
|
+
=========================================================== */
|
934
|
+
dstInsSlot = FindInstanceSlot(theEnv,dstins,(CLIPSLexeme *) slotOverrides->supplementalInfo);
|
935
|
+
if (dstInsSlot == NULL)
|
936
|
+
{
|
937
|
+
SlotExistError(theEnv,((CLIPSLexeme *) slotOverrides->supplementalInfo)->contents,
|
938
|
+
"duplicate-instance");
|
939
|
+
goto DuplicateError;
|
940
|
+
}
|
941
|
+
if (msgpass)
|
942
|
+
{
|
943
|
+
msgExp.type = slotOverrides->header->type;
|
944
|
+
if (msgExp.type != MULTIFIELD_TYPE)
|
945
|
+
msgExp.value = slotOverrides->value;
|
946
|
+
else
|
947
|
+
msgExp.value = slotOverrides;
|
948
|
+
|
949
|
+
msgExp.argList = NULL;
|
950
|
+
msgExp.nextArg = NULL;
|
951
|
+
if (! DirectMessage(theEnv,dstInsSlot->desc->overrideMessage,dstins,&temp,&msgExp))
|
952
|
+
goto DuplicateError;
|
953
|
+
}
|
954
|
+
else
|
955
|
+
{
|
956
|
+
if (dstInsSlot->desc->multiple && (slotOverrides->header->type != MULTIFIELD_TYPE))
|
957
|
+
{
|
958
|
+
temp.value = CreateMultifield(theEnv,1L);
|
959
|
+
temp.begin = 0;
|
960
|
+
temp.range = 1;
|
961
|
+
temp.multifieldValue->contents[0].value = slotOverrides->value;
|
962
|
+
newval = &temp;
|
963
|
+
}
|
964
|
+
else
|
965
|
+
newval = slotOverrides;
|
966
|
+
if (PutSlotValue(theEnv,dstins,dstInsSlot,newval,&junk,"duplicate-instance") != PSE_NO_ERROR)
|
967
|
+
goto DuplicateError;
|
968
|
+
}
|
969
|
+
dstInsSlot->override = true;
|
970
|
+
slotOverrides = slotOverrides->next;
|
971
|
+
}
|
972
|
+
|
973
|
+
/* =======================================
|
974
|
+
Copy values from source instance to new
|
975
|
+
directly or with put- messages
|
976
|
+
======================================= */
|
977
|
+
for (i = 0 ; i < dstins->cls->localInstanceSlotCount ; i++)
|
978
|
+
{
|
979
|
+
if (dstins->slots[i].override == false)
|
980
|
+
{
|
981
|
+
if (msgpass)
|
982
|
+
{
|
983
|
+
temp.value = srcins->slots[i].value;
|
984
|
+
if (temp.header->type == MULTIFIELD_TYPE)
|
985
|
+
{
|
986
|
+
temp.begin = 0;
|
987
|
+
temp.range = temp.multifieldValue->length;
|
988
|
+
}
|
989
|
+
valArg = ConvertValueToExpression(theEnv,&temp);
|
990
|
+
success = DirectMessage(theEnv,dstins->slots[i].desc->overrideMessage,
|
991
|
+
dstins,&temp,valArg);
|
992
|
+
ReturnExpression(theEnv,valArg);
|
993
|
+
if (! success)
|
994
|
+
goto DuplicateError;
|
995
|
+
}
|
996
|
+
else
|
997
|
+
{
|
998
|
+
temp.value = srcins->slots[i].value;
|
999
|
+
if (srcins->slots[i].type == MULTIFIELD_TYPE)
|
1000
|
+
{
|
1001
|
+
temp.begin = 0;
|
1002
|
+
temp.range = srcins->slots[i].multifieldValue->length;
|
1003
|
+
}
|
1004
|
+
if (PutSlotValue(theEnv,dstins,&dstins->slots[i],&temp,&junk,"duplicate-instance")
|
1005
|
+
!= PSE_NO_ERROR)
|
1006
|
+
goto DuplicateError;
|
1007
|
+
}
|
1008
|
+
}
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
/* =======================================
|
1012
|
+
Send init message for message-duplicate
|
1013
|
+
======================================= */
|
1014
|
+
if (msgpass)
|
1015
|
+
{
|
1016
|
+
for (i = 0 ; i < dstins->cls->instanceSlotCount ; i++)
|
1017
|
+
dstins->slotAddresses[i]->override = true;
|
1018
|
+
dstins->initializeInProgress = 1;
|
1019
|
+
DirectMessage(theEnv,MessageHandlerData(theEnv)->INIT_SYMBOL,dstins,returnValue,NULL);
|
1020
|
+
}
|
1021
|
+
dstins->busy--;
|
1022
|
+
if (dstins->garbage)
|
1023
|
+
{
|
1024
|
+
returnValue->value = FalseSymbol(theEnv);
|
1025
|
+
SetEvaluationError(theEnv,true);
|
1026
|
+
}
|
1027
|
+
else
|
1028
|
+
{
|
1029
|
+
returnValue->value = GetFullInstanceName(theEnv,dstins);
|
1030
|
+
}
|
1031
|
+
return;
|
1032
|
+
|
1033
|
+
DuplicateError:
|
1034
|
+
dstins->busy--;
|
1035
|
+
QuashInstance(theEnv,dstins);
|
1036
|
+
SetEvaluationError(theEnv,true);
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
#endif
|
1040
|
+
|
1041
|
+
|