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,1392 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 04/08/20 */
|
5
|
+
/* */
|
6
|
+
/* CLASS FUNCTIONS MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Internal class manipulation routines */
|
11
|
+
/* */
|
12
|
+
/* Principal Programmer(s): */
|
13
|
+
/* Brian L. Dantes */
|
14
|
+
/* */
|
15
|
+
/* Contributing Programmer(s): */
|
16
|
+
/* */
|
17
|
+
/* Revision History: */
|
18
|
+
/* */
|
19
|
+
/* 6.24: Renamed BOOLEAN macro type to intBool. */
|
20
|
+
/* */
|
21
|
+
/* Corrected code to remove run-time program */
|
22
|
+
/* compiler warning. */
|
23
|
+
/* */
|
24
|
+
/* 6.30: Borland C (IBM_TBC) and Metrowerks CodeWarrior */
|
25
|
+
/* (MAC_MCW, IBM_MCW) are no longer supported. */
|
26
|
+
/* */
|
27
|
+
/* Changed integer type/precision. */
|
28
|
+
/* */
|
29
|
+
/* Changed garbage collection algorithm. */
|
30
|
+
/* */
|
31
|
+
/* Used genstrcpy and genstrcat instead of strcpy */
|
32
|
+
/* and strcat. */
|
33
|
+
/* */
|
34
|
+
/* Added const qualifiers to remove C++ */
|
35
|
+
/* deprecation warnings. */
|
36
|
+
/* */
|
37
|
+
/* Converted API macros to function calls. */
|
38
|
+
/* */
|
39
|
+
/* Fixed linkage issue when BLOAD_AND_SAVE */
|
40
|
+
/* compiler flag is set to 0. */
|
41
|
+
/* */
|
42
|
+
/* 6.31: Optimization of slot ID creation previously */
|
43
|
+
/* provided by NewSlotNameID function. */
|
44
|
+
/* */
|
45
|
+
/* Optimization for marking relevant alpha nodes */
|
46
|
+
/* in the object pattern network. */
|
47
|
+
/* */
|
48
|
+
/* Changed allocation of multifield slot default */
|
49
|
+
/* from ephemeral to explicit deallocation. */
|
50
|
+
/* */
|
51
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
52
|
+
/* SetEvaluationError functions. */
|
53
|
+
/* */
|
54
|
+
/* Pragma once and other inclusion changes. */
|
55
|
+
/* */
|
56
|
+
/* Added support for booleans with <stdbool.h>. */
|
57
|
+
/* */
|
58
|
+
/* Removed use of void pointers for specific */
|
59
|
+
/* data structures. */
|
60
|
+
/* */
|
61
|
+
/* UDF redesign. */
|
62
|
+
/* */
|
63
|
+
/*************************************************************/
|
64
|
+
|
65
|
+
/* =========================================
|
66
|
+
*****************************************
|
67
|
+
EXTERNAL DEFINITIONS
|
68
|
+
=========================================
|
69
|
+
***************************************** */
|
70
|
+
|
71
|
+
#include <stdlib.h>
|
72
|
+
|
73
|
+
#include "setup.h"
|
74
|
+
|
75
|
+
#if OBJECT_SYSTEM
|
76
|
+
|
77
|
+
#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
|
78
|
+
#include "bload.h"
|
79
|
+
#endif
|
80
|
+
|
81
|
+
#include "classcom.h"
|
82
|
+
#include "classini.h"
|
83
|
+
#include "constant.h"
|
84
|
+
#include "constrct.h"
|
85
|
+
#include "cstrccom.h"
|
86
|
+
#include "cstrcpsr.h"
|
87
|
+
#include "envrnmnt.h"
|
88
|
+
#include "evaluatn.h"
|
89
|
+
#include "inscom.h"
|
90
|
+
#include "insfun.h"
|
91
|
+
#include "insmngr.h"
|
92
|
+
#include "memalloc.h"
|
93
|
+
#include "modulutl.h"
|
94
|
+
#include "msgfun.h"
|
95
|
+
#include "prntutil.h"
|
96
|
+
#include "router.h"
|
97
|
+
#include "scanner.h"
|
98
|
+
#include "sysdep.h"
|
99
|
+
#include "utility.h"
|
100
|
+
|
101
|
+
#include "classfun.h"
|
102
|
+
|
103
|
+
/* =========================================
|
104
|
+
*****************************************
|
105
|
+
CONSTANTS
|
106
|
+
=========================================
|
107
|
+
***************************************** */
|
108
|
+
#define BIG_PRIME 11329
|
109
|
+
|
110
|
+
#define CLASS_ID_MAP_CHUNK 30
|
111
|
+
|
112
|
+
#define PUT_PREFIX "put-"
|
113
|
+
#define PUT_PREFIX_LENGTH 4
|
114
|
+
|
115
|
+
/***************************************/
|
116
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
117
|
+
/***************************************/
|
118
|
+
|
119
|
+
static unsigned int HashSlotName(CLIPSLexeme *);
|
120
|
+
|
121
|
+
#if (! RUN_TIME)
|
122
|
+
static void DeassignClassID(Environment *,unsigned short);
|
123
|
+
#endif
|
124
|
+
|
125
|
+
/* =========================================
|
126
|
+
*****************************************
|
127
|
+
EXTERNALLY VISIBLE FUNCTIONS
|
128
|
+
=========================================
|
129
|
+
***************************************** */
|
130
|
+
|
131
|
+
/***************************************************
|
132
|
+
NAME : IncrementDefclassBusyCount
|
133
|
+
DESCRIPTION : Increments use count of defclass
|
134
|
+
INPUTS : The class
|
135
|
+
RETURNS : Nothing useful
|
136
|
+
SIDE EFFECTS : Busy count incremented
|
137
|
+
NOTES : None
|
138
|
+
***************************************************/
|
139
|
+
void IncrementDefclassBusyCount(
|
140
|
+
Environment *theEnv,
|
141
|
+
Defclass *theDefclass)
|
142
|
+
{
|
143
|
+
#if MAC_XCD
|
144
|
+
#pragma unused(theEnv)
|
145
|
+
#endif
|
146
|
+
|
147
|
+
theDefclass->busy++;
|
148
|
+
}
|
149
|
+
|
150
|
+
/***************************************************
|
151
|
+
NAME : DecrementDefclassBusyCount
|
152
|
+
DESCRIPTION : Decrements use count of defclass
|
153
|
+
INPUTS : The class
|
154
|
+
RETURNS : Nothing useful
|
155
|
+
SIDE EFFECTS : Busy count decremented
|
156
|
+
NOTES : Since use counts are ignored on
|
157
|
+
a clear and defclasses might be
|
158
|
+
deleted already anyway, this is
|
159
|
+
a no-op on a clear
|
160
|
+
***************************************************/
|
161
|
+
void DecrementDefclassBusyCount(
|
162
|
+
Environment *theEnv,
|
163
|
+
Defclass *theDefclass)
|
164
|
+
{
|
165
|
+
if (! ConstructData(theEnv)->ClearInProgress)
|
166
|
+
{ theDefclass->busy--; }
|
167
|
+
}
|
168
|
+
|
169
|
+
/****************************************************
|
170
|
+
NAME : InstancesPurge
|
171
|
+
DESCRIPTION : Removes all instances
|
172
|
+
INPUTS : None
|
173
|
+
RETURNS : True if all instances deleted,
|
174
|
+
false otherwise
|
175
|
+
SIDE EFFECTS : The instance hash table is cleared
|
176
|
+
NOTES : None
|
177
|
+
****************************************************/
|
178
|
+
bool InstancesPurge(
|
179
|
+
Environment *theEnv,
|
180
|
+
void *context)
|
181
|
+
{
|
182
|
+
DestroyAllInstances(theEnv,NULL);
|
183
|
+
CleanupInstances(theEnv,NULL);
|
184
|
+
return((InstanceData(theEnv)->InstanceList != NULL) ? false : true);
|
185
|
+
}
|
186
|
+
|
187
|
+
#if ! RUN_TIME
|
188
|
+
|
189
|
+
/***************************************************
|
190
|
+
NAME : InitializeClasses
|
191
|
+
DESCRIPTION : Allocates class hash table
|
192
|
+
Initializes class hash table
|
193
|
+
to all NULL addresses
|
194
|
+
Creates system classes
|
195
|
+
INPUTS : None
|
196
|
+
RETURNS : Nothing useful
|
197
|
+
SIDE EFFECTS : Hash table initialized
|
198
|
+
NOTES : None
|
199
|
+
***************************************************/
|
200
|
+
void InitializeClasses(
|
201
|
+
Environment *theEnv)
|
202
|
+
{
|
203
|
+
int i;
|
204
|
+
|
205
|
+
DefclassData(theEnv)->ClassTable =
|
206
|
+
(Defclass **) gm2(theEnv,(sizeof(Defclass *) * CLASS_TABLE_HASH_SIZE));
|
207
|
+
for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)
|
208
|
+
DefclassData(theEnv)->ClassTable[i] = NULL;
|
209
|
+
DefclassData(theEnv)->SlotNameTable =
|
210
|
+
(SLOT_NAME **) gm2(theEnv,(sizeof(SLOT_NAME *) * SLOT_NAME_TABLE_HASH_SIZE));
|
211
|
+
for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)
|
212
|
+
DefclassData(theEnv)->SlotNameTable[i] = NULL;
|
213
|
+
}
|
214
|
+
|
215
|
+
#endif
|
216
|
+
|
217
|
+
/********************************************************
|
218
|
+
NAME : FindClassSlot
|
219
|
+
DESCRIPTION : Searches for a named slot in a class
|
220
|
+
INPUTS : 1) The class address
|
221
|
+
2) The symbolic slot name
|
222
|
+
RETURNS : Address of slot if found, NULL otherwise
|
223
|
+
SIDE EFFECTS : None
|
224
|
+
NOTES : Only looks in class defn, does not
|
225
|
+
examine inheritance paths
|
226
|
+
********************************************************/
|
227
|
+
SlotDescriptor *FindClassSlot(
|
228
|
+
Defclass *cls,
|
229
|
+
CLIPSLexeme *sname)
|
230
|
+
{
|
231
|
+
long i;
|
232
|
+
|
233
|
+
for (i = 0 ; i < cls->slotCount ; i++)
|
234
|
+
{
|
235
|
+
if (cls->slots[i].slotName->name == sname)
|
236
|
+
return(&cls->slots[i]);
|
237
|
+
}
|
238
|
+
return NULL;
|
239
|
+
}
|
240
|
+
|
241
|
+
/***************************************************************
|
242
|
+
NAME : ClassExistError
|
243
|
+
DESCRIPTION : Prints out error message for non-existent class
|
244
|
+
INPUTS : 1) Name of function having the error
|
245
|
+
2) The name of the non-existent class
|
246
|
+
RETURNS : Nothing useful
|
247
|
+
SIDE EFFECTS : None
|
248
|
+
NOTES : None
|
249
|
+
***************************************************************/
|
250
|
+
void ClassExistError(
|
251
|
+
Environment *theEnv,
|
252
|
+
const char *func,
|
253
|
+
const char *cname)
|
254
|
+
{
|
255
|
+
PrintErrorID(theEnv,"CLASSFUN",1,false);
|
256
|
+
WriteString(theEnv,STDERR,"Unable to find class '");
|
257
|
+
WriteString(theEnv,STDERR,cname);
|
258
|
+
WriteString(theEnv,STDERR,"' in function '");
|
259
|
+
WriteString(theEnv,STDERR,func);
|
260
|
+
WriteString(theEnv,STDERR,"'.\n");
|
261
|
+
SetEvaluationError(theEnv,true);
|
262
|
+
}
|
263
|
+
|
264
|
+
/*********************************************
|
265
|
+
NAME : DeleteClassLinks
|
266
|
+
DESCRIPTION : Deallocates a class link list
|
267
|
+
INPUTS : The address of the list
|
268
|
+
RETURNS : Nothing useful
|
269
|
+
SIDE EFFECTS : None
|
270
|
+
NOTES : None
|
271
|
+
*********************************************/
|
272
|
+
void DeleteClassLinks(
|
273
|
+
Environment *theEnv,
|
274
|
+
CLASS_LINK *clink)
|
275
|
+
{
|
276
|
+
CLASS_LINK *ctmp;
|
277
|
+
|
278
|
+
for (ctmp = clink ; ctmp != NULL ; ctmp = clink)
|
279
|
+
{
|
280
|
+
clink = clink->nxt;
|
281
|
+
rtn_struct(theEnv,classLink,ctmp);
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
/******************************************************
|
286
|
+
NAME : PrintClassName
|
287
|
+
DESCRIPTION : Displays a class's name
|
288
|
+
INPUTS : 1) Logical name of output
|
289
|
+
2) The class
|
290
|
+
3) Flag indicating whether to
|
291
|
+
print carriage-return at end
|
292
|
+
RETURNS : Nothing useful
|
293
|
+
SIDE EFFECTS : Class name printed (and module name
|
294
|
+
too if class is not in current module)
|
295
|
+
NOTES : None
|
296
|
+
******************************************************/
|
297
|
+
void PrintClassName(
|
298
|
+
Environment *theEnv,
|
299
|
+
const char *logicalName,
|
300
|
+
Defclass *theDefclass,
|
301
|
+
bool useQuotes,
|
302
|
+
bool linefeedFlag)
|
303
|
+
{
|
304
|
+
if (useQuotes) WriteString(theEnv,logicalName,"'");
|
305
|
+
if ((theDefclass->header.whichModule->theModule != GetCurrentModule(theEnv)) &&
|
306
|
+
(theDefclass->system == 0))
|
307
|
+
{
|
308
|
+
WriteString(theEnv,logicalName,
|
309
|
+
DefmoduleName(theDefclass->header.whichModule->theModule));
|
310
|
+
WriteString(theEnv,logicalName,"::");
|
311
|
+
}
|
312
|
+
WriteString(theEnv,logicalName,theDefclass->header.name->contents);
|
313
|
+
if (useQuotes) WriteString(theEnv,logicalName,"'");
|
314
|
+
if (linefeedFlag)
|
315
|
+
WriteString(theEnv,logicalName,"\n");
|
316
|
+
}
|
317
|
+
|
318
|
+
#if DEBUGGING_FUNCTIONS || ((! BLOAD_ONLY) && (! RUN_TIME))
|
319
|
+
|
320
|
+
/***************************************************
|
321
|
+
NAME : PrintPackedClassLinks
|
322
|
+
DESCRIPTION : Displays the names of classes in
|
323
|
+
a list with a title
|
324
|
+
INPUTS : 1) The logical name of the output
|
325
|
+
2) Title string
|
326
|
+
3) List of class links
|
327
|
+
RETURNS : Nothing useful
|
328
|
+
SIDE EFFECTS : None
|
329
|
+
NOTES : None
|
330
|
+
***************************************************/
|
331
|
+
void PrintPackedClassLinks(
|
332
|
+
Environment *theEnv,
|
333
|
+
const char *logicalName,
|
334
|
+
const char *title,
|
335
|
+
PACKED_CLASS_LINKS *plinks)
|
336
|
+
{
|
337
|
+
unsigned long i;
|
338
|
+
|
339
|
+
WriteString(theEnv,logicalName,title);
|
340
|
+
for (i = 0 ; i < plinks->classCount ; i++)
|
341
|
+
{
|
342
|
+
WriteString(theEnv,logicalName," ");
|
343
|
+
PrintClassName(theEnv,logicalName,plinks->classArray[i],false,false);
|
344
|
+
}
|
345
|
+
WriteString(theEnv,logicalName,"\n");
|
346
|
+
}
|
347
|
+
|
348
|
+
#endif
|
349
|
+
|
350
|
+
#if ! RUN_TIME
|
351
|
+
|
352
|
+
/*******************************************************
|
353
|
+
NAME : PutClassInTable
|
354
|
+
DESCRIPTION : Inserts a class in the class hash table
|
355
|
+
INPUTS : The class
|
356
|
+
RETURNS : Nothing useful
|
357
|
+
SIDE EFFECTS : Class inserted
|
358
|
+
NOTES : None
|
359
|
+
*******************************************************/
|
360
|
+
void PutClassInTable(
|
361
|
+
Environment *theEnv,
|
362
|
+
Defclass *cls)
|
363
|
+
{
|
364
|
+
cls->hashTableIndex = HashClass(GetDefclassNamePointer(cls));
|
365
|
+
cls->nxtHash = DefclassData(theEnv)->ClassTable[cls->hashTableIndex];
|
366
|
+
DefclassData(theEnv)->ClassTable[cls->hashTableIndex] = cls;
|
367
|
+
}
|
368
|
+
|
369
|
+
/*********************************************************
|
370
|
+
NAME : RemoveClassFromTable
|
371
|
+
DESCRIPTION : Removes a class from the class hash table
|
372
|
+
INPUTS : The class
|
373
|
+
RETURNS : Nothing useful
|
374
|
+
SIDE EFFECTS : Class removed
|
375
|
+
NOTES : None
|
376
|
+
*********************************************************/
|
377
|
+
void RemoveClassFromTable(
|
378
|
+
Environment *theEnv,
|
379
|
+
Defclass *cls)
|
380
|
+
{
|
381
|
+
Defclass *prvhsh,*hshptr;
|
382
|
+
|
383
|
+
prvhsh = NULL;
|
384
|
+
hshptr = DefclassData(theEnv)->ClassTable[cls->hashTableIndex];
|
385
|
+
while (hshptr != cls)
|
386
|
+
{
|
387
|
+
prvhsh = hshptr;
|
388
|
+
hshptr = hshptr->nxtHash;
|
389
|
+
}
|
390
|
+
if (prvhsh == NULL)
|
391
|
+
DefclassData(theEnv)->ClassTable[cls->hashTableIndex] = cls->nxtHash;
|
392
|
+
else
|
393
|
+
prvhsh->nxtHash = cls->nxtHash;
|
394
|
+
}
|
395
|
+
|
396
|
+
/***************************************************
|
397
|
+
NAME : AddClassLink
|
398
|
+
DESCRIPTION : Adds a class link from one class to
|
399
|
+
another
|
400
|
+
INPUTS : 1) The packed links in which to
|
401
|
+
insert the new class
|
402
|
+
2) The subclass pointer
|
403
|
+
3) A flag indicating if the link
|
404
|
+
should be appended.
|
405
|
+
4) Index of where to place the
|
406
|
+
class if not appended
|
407
|
+
RETURNS : Nothing useful
|
408
|
+
SIDE EFFECTS : Link created and attached
|
409
|
+
NOTES : Assumes the pack structure belongs
|
410
|
+
to a class and does not need to
|
411
|
+
be deallocated
|
412
|
+
***************************************************/
|
413
|
+
void AddClassLink(
|
414
|
+
Environment *theEnv,
|
415
|
+
PACKED_CLASS_LINKS *src,
|
416
|
+
Defclass *cls,
|
417
|
+
bool append,
|
418
|
+
unsigned int posn)
|
419
|
+
{
|
420
|
+
PACKED_CLASS_LINKS dst;
|
421
|
+
|
422
|
+
dst.classArray = (Defclass **) gm2(theEnv,(sizeof(Defclass *) * (src->classCount + 1)));
|
423
|
+
|
424
|
+
if (append)
|
425
|
+
{
|
426
|
+
GenCopyMemory(Defclass *,src->classCount,dst.classArray,src->classArray);
|
427
|
+
dst.classArray[src->classCount] = cls;
|
428
|
+
}
|
429
|
+
else
|
430
|
+
{
|
431
|
+
if (posn != 0)
|
432
|
+
GenCopyMemory(Defclass *,posn,dst.classArray,src->classArray);
|
433
|
+
GenCopyMemory(Defclass *,src->classCount - posn,
|
434
|
+
dst.classArray + posn + 1,src->classArray + posn);
|
435
|
+
dst.classArray[posn] = cls;
|
436
|
+
}
|
437
|
+
dst.classCount = src->classCount + 1;
|
438
|
+
DeletePackedClassLinks(theEnv,src,false);
|
439
|
+
src->classCount = dst.classCount;
|
440
|
+
src->classArray = dst.classArray;
|
441
|
+
}
|
442
|
+
|
443
|
+
/***************************************************
|
444
|
+
NAME : DeleteSubclassLink
|
445
|
+
DESCRIPTION : Removes a class from another
|
446
|
+
class's subclass list
|
447
|
+
INPUTS : 1) The superclass whose subclass
|
448
|
+
list is to be modified
|
449
|
+
2) The subclass to be removed
|
450
|
+
RETURNS : Nothing useful
|
451
|
+
SIDE EFFECTS : The subclass list is changed
|
452
|
+
NOTES : None
|
453
|
+
***************************************************/
|
454
|
+
void DeleteSubclassLink(
|
455
|
+
Environment *theEnv,
|
456
|
+
Defclass *sclass,
|
457
|
+
Defclass *cls)
|
458
|
+
{
|
459
|
+
unsigned long deletedIndex;
|
460
|
+
PACKED_CLASS_LINKS *src,dst;
|
461
|
+
|
462
|
+
src = &sclass->directSubclasses;
|
463
|
+
|
464
|
+
for (deletedIndex = 0 ; deletedIndex < src->classCount ; deletedIndex++)
|
465
|
+
if (src->classArray[deletedIndex] == cls)
|
466
|
+
break;
|
467
|
+
if (deletedIndex == src->classCount)
|
468
|
+
return;
|
469
|
+
if (src->classCount > 1)
|
470
|
+
{
|
471
|
+
dst.classArray = (Defclass **) gm2(theEnv,(sizeof(Defclass *) * (src->classCount - 1)));
|
472
|
+
if (deletedIndex != 0)
|
473
|
+
GenCopyMemory(Defclass *,deletedIndex,dst.classArray,src->classArray);
|
474
|
+
GenCopyMemory(Defclass *,src->classCount - deletedIndex - 1,
|
475
|
+
dst.classArray + deletedIndex,src->classArray + deletedIndex + 1);
|
476
|
+
}
|
477
|
+
else
|
478
|
+
dst.classArray = NULL;
|
479
|
+
|
480
|
+
dst.classCount = src->classCount - 1;
|
481
|
+
DeletePackedClassLinks(theEnv,src,false);
|
482
|
+
src->classCount = dst.classCount;
|
483
|
+
src->classArray = dst.classArray;
|
484
|
+
}
|
485
|
+
|
486
|
+
|
487
|
+
/***************************************************
|
488
|
+
NAME : DeleteSuperclassLink
|
489
|
+
DESCRIPTION : Removes a class from another
|
490
|
+
class's superclass list
|
491
|
+
INPUTS : 1) The subclass whose superclass
|
492
|
+
list is to be modified
|
493
|
+
2) The superclass to be removed
|
494
|
+
RETURNS : Nothing useful
|
495
|
+
SIDE EFFECTS : The subclass list is changed
|
496
|
+
NOTES : None
|
497
|
+
***************************************************/
|
498
|
+
void DeleteSuperclassLink(
|
499
|
+
Environment *theEnv,
|
500
|
+
Defclass *sclass,
|
501
|
+
Defclass *cls)
|
502
|
+
{
|
503
|
+
unsigned long deletedIndex;
|
504
|
+
PACKED_CLASS_LINKS *src,dst;
|
505
|
+
|
506
|
+
src = &sclass->directSuperclasses;
|
507
|
+
|
508
|
+
for (deletedIndex = 0 ; deletedIndex < src->classCount ; deletedIndex++)
|
509
|
+
if (src->classArray[deletedIndex] == cls)
|
510
|
+
break;
|
511
|
+
if (deletedIndex == src->classCount)
|
512
|
+
return;
|
513
|
+
if (src->classCount > 1)
|
514
|
+
{
|
515
|
+
dst.classArray = (Defclass **) gm2(theEnv,(sizeof(Defclass *) * (src->classCount - 1)));
|
516
|
+
if (deletedIndex != 0)
|
517
|
+
GenCopyMemory(Defclass *,deletedIndex,dst.classArray,src->classArray);
|
518
|
+
GenCopyMemory(Defclass *,src->classCount - deletedIndex - 1,
|
519
|
+
dst.classArray + deletedIndex,src->classArray + deletedIndex + 1);
|
520
|
+
}
|
521
|
+
else
|
522
|
+
dst.classArray = NULL;
|
523
|
+
|
524
|
+
dst.classCount = src->classCount - 1;
|
525
|
+
DeletePackedClassLinks(theEnv,src,false);
|
526
|
+
src->classCount = dst.classCount;
|
527
|
+
src->classArray = dst.classArray;
|
528
|
+
}
|
529
|
+
|
530
|
+
/**************************************************************
|
531
|
+
NAME : NewClass
|
532
|
+
DESCRIPTION : Allocates and initalizes a new class structure
|
533
|
+
INPUTS : The symbolic name of the new class
|
534
|
+
RETURNS : The address of the new class
|
535
|
+
SIDE EFFECTS : None
|
536
|
+
NOTES : None
|
537
|
+
**************************************************************/
|
538
|
+
Defclass *NewClass(
|
539
|
+
Environment *theEnv,
|
540
|
+
CLIPSLexeme *className)
|
541
|
+
{
|
542
|
+
Defclass *cls;
|
543
|
+
|
544
|
+
cls = get_struct(theEnv,defclass);
|
545
|
+
InitializeConstructHeader(theEnv,"defclass",DEFCLASS,&cls->header,className);
|
546
|
+
|
547
|
+
cls->id = 0;
|
548
|
+
cls->installed = 0;
|
549
|
+
cls->busy = 0;
|
550
|
+
cls->system = 0;
|
551
|
+
cls->abstract = 0;
|
552
|
+
cls->reactive = 1;
|
553
|
+
#if DEBUGGING_FUNCTIONS
|
554
|
+
cls->traceInstances = DefclassData(theEnv)->WatchInstances;
|
555
|
+
cls->traceSlots = DefclassData(theEnv)->WatchSlots;
|
556
|
+
#endif
|
557
|
+
cls->hashTableIndex = 0;
|
558
|
+
cls->directSuperclasses.classCount = 0;
|
559
|
+
cls->directSuperclasses.classArray = NULL;
|
560
|
+
cls->directSubclasses.classCount = 0;
|
561
|
+
cls->directSubclasses.classArray = NULL;
|
562
|
+
cls->allSuperclasses.classCount = 0;
|
563
|
+
cls->allSuperclasses.classArray = NULL;
|
564
|
+
cls->slots = NULL;
|
565
|
+
cls->instanceTemplate = NULL;
|
566
|
+
cls->slotNameMap = NULL;
|
567
|
+
cls->instanceSlotCount = 0;
|
568
|
+
cls->localInstanceSlotCount = 0;
|
569
|
+
cls->slotCount = 0;
|
570
|
+
cls->maxSlotNameID = 0;
|
571
|
+
cls->handlers = NULL;
|
572
|
+
cls->handlerOrderMap = NULL;
|
573
|
+
cls->handlerCount = 0;
|
574
|
+
cls->instanceList = NULL;
|
575
|
+
cls->instanceListBottom = NULL;
|
576
|
+
cls->nxtHash = NULL;
|
577
|
+
cls->scopeMap = NULL;
|
578
|
+
ClearBitString(cls->traversalRecord,TRAVERSAL_BYTES);
|
579
|
+
#if DEFRULE_CONSTRUCT
|
580
|
+
cls->relevant_terminal_alpha_nodes = NULL;
|
581
|
+
#endif
|
582
|
+
return(cls);
|
583
|
+
}
|
584
|
+
|
585
|
+
/***************************************************
|
586
|
+
NAME : DeletePackedClassLinks
|
587
|
+
DESCRIPTION : Dealloacates a contiguous array
|
588
|
+
holding class links
|
589
|
+
INPUTS : 1) The class link segment
|
590
|
+
2) A flag indicating whether to
|
591
|
+
delete the top pack structure
|
592
|
+
RETURNS : Nothing useful
|
593
|
+
SIDE EFFECTS : Class links deallocated
|
594
|
+
NOTES : None
|
595
|
+
***************************************************/
|
596
|
+
void DeletePackedClassLinks(
|
597
|
+
Environment *theEnv,
|
598
|
+
PACKED_CLASS_LINKS *plp,
|
599
|
+
bool deleteTop)
|
600
|
+
{
|
601
|
+
if (plp->classCount > 0)
|
602
|
+
{
|
603
|
+
rm(theEnv,plp->classArray,(sizeof(Defclass *) * plp->classCount));
|
604
|
+
plp->classCount = 0;
|
605
|
+
plp->classArray = NULL;
|
606
|
+
}
|
607
|
+
if (deleteTop)
|
608
|
+
rtn_struct(theEnv,packedClassLinks,plp);
|
609
|
+
}
|
610
|
+
|
611
|
+
/***************************************************
|
612
|
+
NAME : AssignClassID
|
613
|
+
DESCRIPTION : Assigns a unique id to a class
|
614
|
+
and puts its address in the
|
615
|
+
id map
|
616
|
+
INPUTS : The class
|
617
|
+
RETURNS : Nothing useful
|
618
|
+
SIDE EFFECTS : Class id assigned and map set
|
619
|
+
NOTES : None
|
620
|
+
***************************************************/
|
621
|
+
void AssignClassID(
|
622
|
+
Environment *theEnv,
|
623
|
+
Defclass *cls)
|
624
|
+
{
|
625
|
+
unsigned short i;
|
626
|
+
|
627
|
+
if ((DefclassData(theEnv)->MaxClassID % CLASS_ID_MAP_CHUNK) == 0)
|
628
|
+
{
|
629
|
+
DefclassData(theEnv)->ClassIDMap =
|
630
|
+
(Defclass **) genrealloc(theEnv,DefclassData(theEnv)->ClassIDMap,
|
631
|
+
(DefclassData(theEnv)->MaxClassID * sizeof(Defclass *)),
|
632
|
+
((DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK) * sizeof(Defclass *)));
|
633
|
+
DefclassData(theEnv)->AvailClassID += CLASS_ID_MAP_CHUNK;
|
634
|
+
|
635
|
+
for (i = DefclassData(theEnv)->MaxClassID ; i < (DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK) ; i++)
|
636
|
+
DefclassData(theEnv)->ClassIDMap[i] = NULL;
|
637
|
+
}
|
638
|
+
DefclassData(theEnv)->ClassIDMap[DefclassData(theEnv)->MaxClassID] = cls;
|
639
|
+
cls->id = DefclassData(theEnv)->MaxClassID++;
|
640
|
+
}
|
641
|
+
|
642
|
+
/*********************************************************
|
643
|
+
NAME : AddSlotName
|
644
|
+
DESCRIPTION : Adds a new slot entry (or increments
|
645
|
+
the use count of an existing node).
|
646
|
+
INPUTS : 1) The slot name
|
647
|
+
2) The new canonical id for the slot name
|
648
|
+
3) A flag indicating whether the
|
649
|
+
given id must be used or not
|
650
|
+
RETURNS : The id of the (old) node
|
651
|
+
SIDE EFFECTS : Slot name entry added or use count
|
652
|
+
incremented
|
653
|
+
NOTES : None
|
654
|
+
*********************************************************/
|
655
|
+
SLOT_NAME *AddSlotName(
|
656
|
+
Environment *theEnv,
|
657
|
+
CLIPSLexeme *slotName,
|
658
|
+
unsigned short newid,
|
659
|
+
bool usenewid)
|
660
|
+
{
|
661
|
+
SLOT_NAME *snp;
|
662
|
+
unsigned hashTableIndex;
|
663
|
+
char *buf;
|
664
|
+
size_t bufsz;
|
665
|
+
|
666
|
+
hashTableIndex = HashSlotName(slotName);
|
667
|
+
snp = DefclassData(theEnv)->SlotNameTable[hashTableIndex];
|
668
|
+
while ((snp != NULL) ? (snp->name != slotName) : false)
|
669
|
+
snp = snp->nxt;
|
670
|
+
if (snp != NULL)
|
671
|
+
{
|
672
|
+
if (usenewid && (newid != snp->id))
|
673
|
+
{
|
674
|
+
SystemError(theEnv,"CLASSFUN",1);
|
675
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
676
|
+
}
|
677
|
+
snp->use++;
|
678
|
+
}
|
679
|
+
else
|
680
|
+
{
|
681
|
+
snp = get_struct(theEnv,slotName);
|
682
|
+
snp->name = slotName;
|
683
|
+
snp->hashTableIndex = hashTableIndex;
|
684
|
+
snp->use = 1;
|
685
|
+
snp->id = (unsigned short) (usenewid ? newid : DefclassData(theEnv)->newSlotID++);
|
686
|
+
snp->nxt = DefclassData(theEnv)->SlotNameTable[hashTableIndex];
|
687
|
+
DefclassData(theEnv)->SlotNameTable[hashTableIndex] = snp;
|
688
|
+
IncrementLexemeCount(slotName);
|
689
|
+
bufsz = (sizeof(char) *
|
690
|
+
(PUT_PREFIX_LENGTH + strlen(slotName->contents) + 1));
|
691
|
+
buf = (char *) gm2(theEnv,bufsz);
|
692
|
+
genstrcpy(buf,PUT_PREFIX);
|
693
|
+
genstrcat(buf,slotName->contents);
|
694
|
+
snp->putHandlerName = CreateSymbol(theEnv,buf);
|
695
|
+
IncrementLexemeCount(snp->putHandlerName);
|
696
|
+
rm(theEnv,buf,bufsz);
|
697
|
+
snp->bsaveIndex = 0L;
|
698
|
+
}
|
699
|
+
return(snp);
|
700
|
+
}
|
701
|
+
|
702
|
+
/***************************************************
|
703
|
+
NAME : DeleteSlotName
|
704
|
+
DESCRIPTION : Removes a slot name entry from
|
705
|
+
the table of all slot names if
|
706
|
+
no longer in use
|
707
|
+
INPUTS : The slot name hash node
|
708
|
+
RETURNS : Nothing useful
|
709
|
+
SIDE EFFECTS : Slot name entry deleted or use
|
710
|
+
count decremented
|
711
|
+
NOTES : None
|
712
|
+
***************************************************/
|
713
|
+
void DeleteSlotName(
|
714
|
+
Environment *theEnv,
|
715
|
+
SLOT_NAME *slotName)
|
716
|
+
{
|
717
|
+
SLOT_NAME *snp,*prv;
|
718
|
+
|
719
|
+
if (slotName == NULL)
|
720
|
+
return;
|
721
|
+
prv = NULL;
|
722
|
+
snp = DefclassData(theEnv)->SlotNameTable[slotName->hashTableIndex];
|
723
|
+
while (snp != slotName)
|
724
|
+
{
|
725
|
+
prv = snp;
|
726
|
+
snp = snp->nxt;
|
727
|
+
}
|
728
|
+
snp->use--;
|
729
|
+
if (snp->use != 0)
|
730
|
+
return;
|
731
|
+
if (prv == NULL)
|
732
|
+
DefclassData(theEnv)->SlotNameTable[snp->hashTableIndex] = snp->nxt;
|
733
|
+
else
|
734
|
+
prv->nxt = snp->nxt;
|
735
|
+
ReleaseLexeme(theEnv,snp->name);
|
736
|
+
ReleaseLexeme(theEnv,snp->putHandlerName);
|
737
|
+
rtn_struct(theEnv,slotName,snp);
|
738
|
+
}
|
739
|
+
|
740
|
+
/*******************************************************************
|
741
|
+
NAME : RemoveDefclass
|
742
|
+
DESCRIPTION : Deallocates a class structure and
|
743
|
+
all its fields - returns all symbols
|
744
|
+
in use by the class back to the symbol
|
745
|
+
manager for ephemeral removal
|
746
|
+
INPUTS : The address of the class
|
747
|
+
RETURNS : Nothing useful
|
748
|
+
SIDE EFFECTS : None
|
749
|
+
NOTES : Assumes class has no subclasses
|
750
|
+
IMPORTANT WARNING!! : Assumes class
|
751
|
+
busy count and all instances' busy
|
752
|
+
counts are 0 and all handlers' busy counts are 0!
|
753
|
+
*******************************************************************/
|
754
|
+
void RemoveDefclass(
|
755
|
+
Environment *theEnv,
|
756
|
+
Defclass *cls)
|
757
|
+
{
|
758
|
+
DefmessageHandler *hnd;
|
759
|
+
unsigned long i;
|
760
|
+
#if DEFRULE_CONSTRUCT
|
761
|
+
CLASS_ALPHA_LINK *currentAlphaLink;
|
762
|
+
CLASS_ALPHA_LINK *nextAlphaLink;
|
763
|
+
#endif
|
764
|
+
|
765
|
+
/* ====================================================
|
766
|
+
Remove all of this class's superclasses' links to it
|
767
|
+
==================================================== */
|
768
|
+
for (i = 0 ; i < cls->directSuperclasses.classCount ; i++)
|
769
|
+
DeleteSubclassLink(theEnv,cls->directSuperclasses.classArray[i],cls);
|
770
|
+
|
771
|
+
/* ====================================================
|
772
|
+
Remove all of this class's subclasses' links to it
|
773
|
+
==================================================== */
|
774
|
+
for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
|
775
|
+
DeleteSuperclassLink(theEnv,cls->directSubclasses.classArray[i],cls);
|
776
|
+
|
777
|
+
RemoveClassFromTable(theEnv,cls);
|
778
|
+
|
779
|
+
InstallClass(theEnv,cls,false);
|
780
|
+
|
781
|
+
DeletePackedClassLinks(theEnv,&cls->directSuperclasses,false);
|
782
|
+
DeletePackedClassLinks(theEnv,&cls->allSuperclasses,false);
|
783
|
+
DeletePackedClassLinks(theEnv,&cls->directSubclasses,false);
|
784
|
+
|
785
|
+
for (i = 0 ; i < cls->slotCount ; i++)
|
786
|
+
{
|
787
|
+
if (cls->slots[i].defaultValue != NULL)
|
788
|
+
{
|
789
|
+
if (cls->slots[i].dynamicDefault)
|
790
|
+
ReturnPackedExpression(theEnv,(Expression *) cls->slots[i].defaultValue);
|
791
|
+
else
|
792
|
+
{
|
793
|
+
UDFValue *theValue = (UDFValue *) cls->slots[i].defaultValue;
|
794
|
+
if (theValue->header->type == MULTIFIELD_TYPE)
|
795
|
+
{ ReturnMultifield(theEnv,theValue->multifieldValue); }
|
796
|
+
rtn_struct(theEnv,udfValue,theValue);
|
797
|
+
}
|
798
|
+
}
|
799
|
+
DeleteSlotName(theEnv,cls->slots[i].slotName);
|
800
|
+
RemoveConstraint(theEnv,cls->slots[i].constraint);
|
801
|
+
}
|
802
|
+
|
803
|
+
if (cls->instanceSlotCount != 0)
|
804
|
+
{
|
805
|
+
rm(theEnv,cls->instanceTemplate,
|
806
|
+
(sizeof(SlotDescriptor *) * cls->instanceSlotCount));
|
807
|
+
rm(theEnv,cls->slotNameMap,
|
808
|
+
(sizeof(unsigned) * (cls->maxSlotNameID + 1)));
|
809
|
+
}
|
810
|
+
if (cls->slotCount != 0)
|
811
|
+
rm(theEnv,cls->slots,(sizeof(SlotDescriptor) * cls->slotCount));
|
812
|
+
|
813
|
+
for (i = 0 ; i < cls->handlerCount ; i++)
|
814
|
+
{
|
815
|
+
hnd = &cls->handlers[i];
|
816
|
+
if (hnd->actions != NULL)
|
817
|
+
ReturnPackedExpression(theEnv,hnd->actions);
|
818
|
+
if (hnd->header.ppForm != NULL)
|
819
|
+
rm(theEnv,(void *) hnd->header.ppForm,(sizeof(char) * (strlen(hnd->header.ppForm)+1)));
|
820
|
+
if (hnd->header.usrData != NULL)
|
821
|
+
{ ClearUserDataList(theEnv,hnd->header.usrData); }
|
822
|
+
}
|
823
|
+
if (cls->handlerCount != 0)
|
824
|
+
{
|
825
|
+
rm(theEnv,cls->handlers,(sizeof(DefmessageHandler) * cls->handlerCount));
|
826
|
+
rm(theEnv,cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount));
|
827
|
+
}
|
828
|
+
|
829
|
+
#if DEFRULE_CONSTRUCT
|
830
|
+
currentAlphaLink = cls->relevant_terminal_alpha_nodes;
|
831
|
+
while (currentAlphaLink != NULL)
|
832
|
+
{
|
833
|
+
nextAlphaLink = currentAlphaLink->next;
|
834
|
+
rtn_struct(theEnv,classAlphaLink,currentAlphaLink);
|
835
|
+
currentAlphaLink = nextAlphaLink;
|
836
|
+
}
|
837
|
+
cls->relevant_terminal_alpha_nodes = NULL;
|
838
|
+
#endif
|
839
|
+
|
840
|
+
SetDefclassPPForm(theEnv,cls,NULL);
|
841
|
+
DeassignClassID(theEnv,cls->id);
|
842
|
+
rtn_struct(theEnv,defclass,cls);
|
843
|
+
}
|
844
|
+
|
845
|
+
#endif
|
846
|
+
|
847
|
+
/*******************************************************************
|
848
|
+
NAME : DestroyDefclass
|
849
|
+
DESCRIPTION : Deallocates a class structure and
|
850
|
+
all its fields.
|
851
|
+
INPUTS : The address of the class
|
852
|
+
RETURNS : Nothing useful
|
853
|
+
SIDE EFFECTS : None
|
854
|
+
NOTES :
|
855
|
+
*******************************************************************/
|
856
|
+
void DestroyDefclass(
|
857
|
+
Environment *theEnv,
|
858
|
+
Defclass *cls)
|
859
|
+
{
|
860
|
+
long i;
|
861
|
+
#if ! RUN_TIME
|
862
|
+
#if DEFRULE_CONSTRUCT
|
863
|
+
CLASS_ALPHA_LINK *currentAlphaLink;
|
864
|
+
CLASS_ALPHA_LINK *nextAlphaLink;
|
865
|
+
#endif
|
866
|
+
|
867
|
+
DefmessageHandler *hnd;
|
868
|
+
DeletePackedClassLinks(theEnv,&cls->directSuperclasses,false);
|
869
|
+
DeletePackedClassLinks(theEnv,&cls->allSuperclasses,false);
|
870
|
+
DeletePackedClassLinks(theEnv,&cls->directSubclasses,false);
|
871
|
+
#endif
|
872
|
+
for (i = 0 ; i < cls->slotCount ; i++)
|
873
|
+
{
|
874
|
+
if (cls->slots[i].defaultValue != NULL)
|
875
|
+
{
|
876
|
+
#if ! RUN_TIME
|
877
|
+
if (cls->slots[i].dynamicDefault)
|
878
|
+
ReturnPackedExpression(theEnv,(Expression *) cls->slots[i].defaultValue);
|
879
|
+
else
|
880
|
+
{
|
881
|
+
UDFValue *theValue = (UDFValue *) cls->slots[i].defaultValue;
|
882
|
+
if (theValue->header->type == MULTIFIELD_TYPE)
|
883
|
+
{ ReturnMultifield(theEnv,theValue->multifieldValue); }
|
884
|
+
rtn_struct(theEnv,udfValue,theValue);
|
885
|
+
}
|
886
|
+
#else
|
887
|
+
if (cls->slots[i].dynamicDefault == 0)
|
888
|
+
{
|
889
|
+
UDFValue *theValue = (UDFValue *) cls->slots[i].defaultValue;
|
890
|
+
if (theValue->header->type == MULTIFIELD_TYPE)
|
891
|
+
{ ReturnMultifield(theEnv,theValue->multifieldValue); }
|
892
|
+
rtn_struct(theEnv,udfValue,theValue);
|
893
|
+
}
|
894
|
+
#endif
|
895
|
+
}
|
896
|
+
}
|
897
|
+
|
898
|
+
#if ! RUN_TIME
|
899
|
+
if (cls->instanceSlotCount != 0)
|
900
|
+
{
|
901
|
+
rm(theEnv,cls->instanceTemplate,
|
902
|
+
(sizeof(SlotDescriptor *) * cls->instanceSlotCount));
|
903
|
+
rm(theEnv,cls->slotNameMap,
|
904
|
+
(sizeof(unsigned) * (cls->maxSlotNameID + 1)));
|
905
|
+
}
|
906
|
+
|
907
|
+
if (cls->slotCount != 0)
|
908
|
+
rm(theEnv,cls->slots,(sizeof(SlotDescriptor) * cls->slotCount));
|
909
|
+
|
910
|
+
for (i = 0 ; i < cls->handlerCount ; i++)
|
911
|
+
{
|
912
|
+
hnd = &cls->handlers[i];
|
913
|
+
if (hnd->actions != NULL)
|
914
|
+
ReturnPackedExpression(theEnv,hnd->actions);
|
915
|
+
|
916
|
+
if (hnd->header.ppForm != NULL)
|
917
|
+
rm(theEnv,(void *) hnd->header.ppForm,(sizeof(char) * (strlen(hnd->header.ppForm)+1)));
|
918
|
+
|
919
|
+
if (hnd->header.usrData != NULL)
|
920
|
+
{ ClearUserDataList(theEnv,hnd->header.usrData); }
|
921
|
+
}
|
922
|
+
|
923
|
+
if (cls->handlerCount != 0)
|
924
|
+
{
|
925
|
+
rm(theEnv,cls->handlers,(sizeof(DefmessageHandler) * cls->handlerCount));
|
926
|
+
rm(theEnv,cls->handlerOrderMap,(sizeof(unsigned) * cls->handlerCount));
|
927
|
+
}
|
928
|
+
|
929
|
+
#if DEFRULE_CONSTRUCT
|
930
|
+
currentAlphaLink = cls->relevant_terminal_alpha_nodes;
|
931
|
+
while (currentAlphaLink != NULL)
|
932
|
+
{
|
933
|
+
nextAlphaLink = currentAlphaLink->next;
|
934
|
+
rtn_struct(theEnv, classAlphaLink, currentAlphaLink);
|
935
|
+
currentAlphaLink = nextAlphaLink;
|
936
|
+
}
|
937
|
+
cls->relevant_terminal_alpha_nodes = NULL;
|
938
|
+
#endif
|
939
|
+
|
940
|
+
DestroyConstructHeader(theEnv,&cls->header);
|
941
|
+
|
942
|
+
rtn_struct(theEnv,defclass,cls);
|
943
|
+
#else
|
944
|
+
#if MAC_XCD
|
945
|
+
#pragma unused(hnd)
|
946
|
+
#endif
|
947
|
+
#endif
|
948
|
+
}
|
949
|
+
|
950
|
+
#if ! RUN_TIME
|
951
|
+
|
952
|
+
/***************************************************
|
953
|
+
NAME : InstallClass
|
954
|
+
DESCRIPTION : In(De)crements all symbol counts for
|
955
|
+
for symbols in use by class
|
956
|
+
Disallows (allows) symbols to become
|
957
|
+
ephemeral.
|
958
|
+
INPUTS : 1) The class address
|
959
|
+
2) 1 - install, 0 - deinstall
|
960
|
+
RETURNS : Nothing useful
|
961
|
+
SIDE EFFECTS : None
|
962
|
+
NOTES : None
|
963
|
+
***************************************************/
|
964
|
+
void InstallClass(
|
965
|
+
Environment *theEnv,
|
966
|
+
Defclass *cls,
|
967
|
+
bool set)
|
968
|
+
{
|
969
|
+
SlotDescriptor *slot;
|
970
|
+
DefmessageHandler *hnd;
|
971
|
+
long i;
|
972
|
+
|
973
|
+
if ((set && cls->installed) ||
|
974
|
+
((set == false) && (cls->installed == 0)))
|
975
|
+
return;
|
976
|
+
|
977
|
+
/* ==================================================================
|
978
|
+
Handler installation is handled when message-handlers are defined:
|
979
|
+
see ParseDefmessageHandler() in MSGCOM.C
|
980
|
+
|
981
|
+
Slot installation is handled by ParseSlot() in CLASSPSR.C
|
982
|
+
Scope map installation is handled by CreateClassScopeMap()
|
983
|
+
================================================================== */
|
984
|
+
if (set == false)
|
985
|
+
{
|
986
|
+
cls->installed = 0;
|
987
|
+
|
988
|
+
ReleaseLexeme(theEnv,cls->header.name);
|
989
|
+
|
990
|
+
#if DEFMODULE_CONSTRUCT
|
991
|
+
DecrementBitMapReferenceCount(theEnv,cls->scopeMap);
|
992
|
+
#endif
|
993
|
+
ClearUserDataList(theEnv,cls->header.usrData);
|
994
|
+
|
995
|
+
for (i = 0 ; i < cls->slotCount ; i++)
|
996
|
+
{
|
997
|
+
slot = &cls->slots[i];
|
998
|
+
ReleaseLexeme(theEnv,slot->overrideMessage);
|
999
|
+
if (slot->defaultValue != NULL)
|
1000
|
+
{
|
1001
|
+
if (slot->dynamicDefault)
|
1002
|
+
ExpressionDeinstall(theEnv,(Expression *) slot->defaultValue);
|
1003
|
+
else
|
1004
|
+
ReleaseUDFV(theEnv,(UDFValue *) slot->defaultValue);
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
for (i = 0 ; i < cls->handlerCount ; i++)
|
1008
|
+
{
|
1009
|
+
hnd = &cls->handlers[i];
|
1010
|
+
ReleaseLexeme(theEnv,hnd->header.name);
|
1011
|
+
if (hnd->actions != NULL)
|
1012
|
+
ExpressionDeinstall(theEnv,hnd->actions);
|
1013
|
+
}
|
1014
|
+
}
|
1015
|
+
else
|
1016
|
+
{
|
1017
|
+
cls->installed = 1;
|
1018
|
+
IncrementLexemeCount(cls->header.name);
|
1019
|
+
}
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
#endif
|
1023
|
+
|
1024
|
+
#if (! BLOAD_ONLY) && (! RUN_TIME)
|
1025
|
+
|
1026
|
+
/***************************************************
|
1027
|
+
NAME : IsClassBeingUsed
|
1028
|
+
DESCRIPTION : Checks the busy flag of a class
|
1029
|
+
and ALL classes that inherit from
|
1030
|
+
it to make sure that it is not
|
1031
|
+
in use before deletion
|
1032
|
+
INPUTS : The class
|
1033
|
+
RETURNS : True if in use, false otherwise
|
1034
|
+
SIDE EFFECTS : None
|
1035
|
+
NOTES : Recursively examines all subclasses
|
1036
|
+
***************************************************/
|
1037
|
+
bool IsClassBeingUsed(
|
1038
|
+
Defclass *cls)
|
1039
|
+
{
|
1040
|
+
unsigned long i;
|
1041
|
+
|
1042
|
+
if (cls->busy > 0)
|
1043
|
+
return true;
|
1044
|
+
for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
|
1045
|
+
if (IsClassBeingUsed(cls->directSubclasses.classArray[i]))
|
1046
|
+
return true;
|
1047
|
+
return false;
|
1048
|
+
}
|
1049
|
+
|
1050
|
+
/***************************************************
|
1051
|
+
NAME : RemoveAllUserClasses
|
1052
|
+
DESCRIPTION : Removes all classes
|
1053
|
+
INPUTS : None
|
1054
|
+
RETURNS : True if succesful, false otherwise
|
1055
|
+
SIDE EFFECTS : The class hash table is cleared
|
1056
|
+
NOTES : None
|
1057
|
+
***************************************************/
|
1058
|
+
bool RemoveAllUserClasses(
|
1059
|
+
Environment *theEnv)
|
1060
|
+
{
|
1061
|
+
Defclass *userClasses, *ctmp;
|
1062
|
+
bool success = true;
|
1063
|
+
|
1064
|
+
#if BLOAD || BLOAD_AND_BSAVE
|
1065
|
+
if (Bloaded(theEnv))
|
1066
|
+
return false;
|
1067
|
+
#endif
|
1068
|
+
/* ====================================================
|
1069
|
+
Don't delete built-in system classes at head of list
|
1070
|
+
==================================================== */
|
1071
|
+
userClasses = GetNextDefclass(theEnv,NULL);
|
1072
|
+
while (userClasses != NULL)
|
1073
|
+
{
|
1074
|
+
if (userClasses->system == 0)
|
1075
|
+
break;
|
1076
|
+
userClasses = GetNextDefclass(theEnv,userClasses);
|
1077
|
+
}
|
1078
|
+
while (userClasses != NULL)
|
1079
|
+
{
|
1080
|
+
ctmp = userClasses;
|
1081
|
+
userClasses = GetNextDefclass(theEnv,userClasses);
|
1082
|
+
if (DefclassIsDeletable(ctmp))
|
1083
|
+
{
|
1084
|
+
RemoveConstructFromModule(theEnv,&ctmp->header);
|
1085
|
+
RemoveDefclass(theEnv,ctmp);
|
1086
|
+
}
|
1087
|
+
else
|
1088
|
+
{
|
1089
|
+
success = false;
|
1090
|
+
CantDeleteItemErrorMessage(theEnv,"defclass",DefclassName(ctmp));
|
1091
|
+
}
|
1092
|
+
}
|
1093
|
+
return(success);
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
/****************************************************
|
1097
|
+
NAME : DeleteClassUAG
|
1098
|
+
DESCRIPTION : Deallocates a class and all its
|
1099
|
+
subclasses
|
1100
|
+
INPUTS : The address of the class
|
1101
|
+
RETURNS : 1 if successful, 0 otherwise
|
1102
|
+
SIDE EFFECTS : Removes the class from each of
|
1103
|
+
its superclasses' subclass lists
|
1104
|
+
NOTES : None
|
1105
|
+
****************************************************/
|
1106
|
+
bool DeleteClassUAG(
|
1107
|
+
Environment *theEnv,
|
1108
|
+
Defclass *cls)
|
1109
|
+
{
|
1110
|
+
unsigned long subCount;
|
1111
|
+
|
1112
|
+
while (cls->directSubclasses.classCount != 0)
|
1113
|
+
{
|
1114
|
+
subCount = cls->directSubclasses.classCount;
|
1115
|
+
DeleteClassUAG(theEnv,cls->directSubclasses.classArray[0]);
|
1116
|
+
if (cls->directSubclasses.classCount == subCount)
|
1117
|
+
return false;
|
1118
|
+
}
|
1119
|
+
if (DefclassIsDeletable(cls))
|
1120
|
+
{
|
1121
|
+
RemoveConstructFromModule(theEnv,&cls->header);
|
1122
|
+
RemoveDefclass(theEnv,cls);
|
1123
|
+
return true;
|
1124
|
+
}
|
1125
|
+
return false;
|
1126
|
+
}
|
1127
|
+
|
1128
|
+
/*********************************************************
|
1129
|
+
NAME : MarkBitMapSubclasses
|
1130
|
+
DESCRIPTION : Recursively marks the ids of a class
|
1131
|
+
and all its subclasses in a bitmap
|
1132
|
+
INPUTS : 1) The bitmap
|
1133
|
+
2) The class
|
1134
|
+
3) A code indicating whether to set
|
1135
|
+
or clear the bits of the map
|
1136
|
+
corresponding to the class ids
|
1137
|
+
RETURNS : Nothing useful
|
1138
|
+
SIDE EFFECTS : BitMap marked
|
1139
|
+
NOTES : IMPORTANT!!!! Assumes the bitmap is
|
1140
|
+
large enough to hold all ids encountered!
|
1141
|
+
*********************************************************/
|
1142
|
+
void MarkBitMapSubclasses(
|
1143
|
+
char *map,
|
1144
|
+
Defclass *cls,
|
1145
|
+
int set)
|
1146
|
+
{
|
1147
|
+
unsigned long i;
|
1148
|
+
|
1149
|
+
if (set)
|
1150
|
+
SetBitMap(map,cls->id);
|
1151
|
+
else
|
1152
|
+
ClearBitMap(map,cls->id);
|
1153
|
+
for (i = 0 ; i < cls->directSubclasses.classCount ; i++)
|
1154
|
+
MarkBitMapSubclasses(map,cls->directSubclasses.classArray[i],set);
|
1155
|
+
}
|
1156
|
+
|
1157
|
+
#endif
|
1158
|
+
|
1159
|
+
/***************************************************
|
1160
|
+
NAME : FindSlotNameID
|
1161
|
+
DESCRIPTION : Finds the id of a slot name
|
1162
|
+
INPUTS : The slot name
|
1163
|
+
RETURNS : The slot name id (-1 if not found)
|
1164
|
+
SIDE EFFECTS : None
|
1165
|
+
NOTES : A slot name always has the same
|
1166
|
+
id regardless of what class uses
|
1167
|
+
it. In this way, a slot can
|
1168
|
+
be referred to by index independent
|
1169
|
+
of class. Each class stores a
|
1170
|
+
map showing which slot name indices
|
1171
|
+
go to which slot. This provides
|
1172
|
+
for immediate lookup of slots
|
1173
|
+
given the index (object pattern
|
1174
|
+
matching uses this).
|
1175
|
+
***************************************************/
|
1176
|
+
unsigned short FindSlotNameID(
|
1177
|
+
Environment *theEnv,
|
1178
|
+
CLIPSLexeme *slotName)
|
1179
|
+
{
|
1180
|
+
SLOT_NAME *snp;
|
1181
|
+
|
1182
|
+
snp = DefclassData(theEnv)->SlotNameTable[HashSlotName(slotName)];
|
1183
|
+
|
1184
|
+
while ((snp != NULL) ? (snp->name != slotName) : false)
|
1185
|
+
{ snp = snp->nxt; }
|
1186
|
+
|
1187
|
+
return (snp != NULL) ? snp->id : SLOT_NAME_NOT_FOUND;
|
1188
|
+
}
|
1189
|
+
|
1190
|
+
/***************************************************
|
1191
|
+
NAME : FindIDSlotName
|
1192
|
+
DESCRIPTION : Finds the slot anme for an id
|
1193
|
+
INPUTS : The id
|
1194
|
+
RETURNS : The slot name (NULL if not found)
|
1195
|
+
SIDE EFFECTS : None
|
1196
|
+
NOTES : None
|
1197
|
+
***************************************************/
|
1198
|
+
CLIPSLexeme *FindIDSlotName(
|
1199
|
+
Environment *theEnv,
|
1200
|
+
unsigned short id)
|
1201
|
+
{
|
1202
|
+
SLOT_NAME *snp;
|
1203
|
+
|
1204
|
+
snp = FindIDSlotNameHash(theEnv,id);
|
1205
|
+
|
1206
|
+
return((snp != NULL) ? snp->name : NULL);
|
1207
|
+
}
|
1208
|
+
|
1209
|
+
/***************************************************
|
1210
|
+
NAME : FindIDSlotNameHash
|
1211
|
+
DESCRIPTION : Finds the slot anme for an id
|
1212
|
+
INPUTS : The id
|
1213
|
+
RETURNS : The slot name (NULL if not found)
|
1214
|
+
SIDE EFFECTS : None
|
1215
|
+
NOTES : None
|
1216
|
+
***************************************************/
|
1217
|
+
SLOT_NAME *FindIDSlotNameHash(
|
1218
|
+
Environment *theEnv,
|
1219
|
+
unsigned short id)
|
1220
|
+
{
|
1221
|
+
unsigned short i;
|
1222
|
+
SLOT_NAME *snp;
|
1223
|
+
|
1224
|
+
for (i = 0 ; i < SLOT_NAME_TABLE_HASH_SIZE ; i++)
|
1225
|
+
{
|
1226
|
+
snp = DefclassData(theEnv)->SlotNameTable[i];
|
1227
|
+
while (snp != NULL)
|
1228
|
+
{
|
1229
|
+
if (snp->id == id)
|
1230
|
+
return snp;
|
1231
|
+
snp = snp->nxt;
|
1232
|
+
}
|
1233
|
+
}
|
1234
|
+
return NULL;
|
1235
|
+
}
|
1236
|
+
|
1237
|
+
/***************************************************
|
1238
|
+
NAME : GetTraversalID
|
1239
|
+
DESCRIPTION : Returns a unique integer ID for a
|
1240
|
+
traversal into the class hierarchy
|
1241
|
+
INPUTS : None
|
1242
|
+
RETURNS : The id, or -1 if none available
|
1243
|
+
SIDE EFFECTS : EvaluationError set when no ids
|
1244
|
+
available
|
1245
|
+
NOTES : Used for recursive traversals of
|
1246
|
+
class hierarchy to assure that a
|
1247
|
+
class is only visited once
|
1248
|
+
***************************************************/
|
1249
|
+
int GetTraversalID(
|
1250
|
+
Environment *theEnv)
|
1251
|
+
{
|
1252
|
+
unsigned i;
|
1253
|
+
Defclass *cls;
|
1254
|
+
|
1255
|
+
if (DefclassData(theEnv)->CTID >= MAX_TRAVERSALS)
|
1256
|
+
{
|
1257
|
+
PrintErrorID(theEnv,"CLASSFUN",2,false);
|
1258
|
+
WriteString(theEnv,STDERR,"Maximum number of simultaneous class hierarchy\n traversals exceeded ");
|
1259
|
+
WriteInteger(theEnv,STDERR,MAX_TRAVERSALS);
|
1260
|
+
WriteString(theEnv,STDERR,".\n");
|
1261
|
+
SetEvaluationError(theEnv,true);
|
1262
|
+
return(-1);
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
for (i = 0 ; i < CLASS_TABLE_HASH_SIZE ; i++)
|
1266
|
+
for (cls = DefclassData(theEnv)->ClassTable[i] ; cls != NULL ; cls = cls->nxtHash)
|
1267
|
+
ClearTraversalID(cls->traversalRecord,DefclassData(theEnv)->CTID);
|
1268
|
+
return(DefclassData(theEnv)->CTID++);
|
1269
|
+
}
|
1270
|
+
|
1271
|
+
/***************************************************
|
1272
|
+
NAME : ReleaseTraversalID
|
1273
|
+
DESCRIPTION : Releases an ID for future use
|
1274
|
+
Also clears id from all classes
|
1275
|
+
INPUTS : None
|
1276
|
+
RETURNS : Nothing useful
|
1277
|
+
SIDE EFFECTS : Old ID released for later reuse
|
1278
|
+
NOTES : Releases ID returned by most recent
|
1279
|
+
call to GetTraversalID()
|
1280
|
+
***************************************************/
|
1281
|
+
void ReleaseTraversalID(
|
1282
|
+
Environment *theEnv)
|
1283
|
+
{
|
1284
|
+
DefclassData(theEnv)->CTID--;
|
1285
|
+
}
|
1286
|
+
|
1287
|
+
/*******************************************************
|
1288
|
+
NAME : HashClass
|
1289
|
+
DESCRIPTION : Generates a hash index for a given
|
1290
|
+
class name
|
1291
|
+
INPUTS : The address of the class name SYMBOL_HN
|
1292
|
+
RETURNS : The hash index value
|
1293
|
+
SIDE EFFECTS : None
|
1294
|
+
NOTES : Counts on the fact that the symbol
|
1295
|
+
has already been hashed into the
|
1296
|
+
symbol table - uses that hash value
|
1297
|
+
multiplied by a prime for a new hash
|
1298
|
+
*******************************************************/
|
1299
|
+
unsigned int HashClass(
|
1300
|
+
CLIPSLexeme *cname)
|
1301
|
+
{
|
1302
|
+
unsigned int tally;
|
1303
|
+
|
1304
|
+
tally = cname->bucket * BIG_PRIME;
|
1305
|
+
|
1306
|
+
return tally % CLASS_TABLE_HASH_SIZE;
|
1307
|
+
}
|
1308
|
+
|
1309
|
+
/* =========================================
|
1310
|
+
*****************************************
|
1311
|
+
INTERNALLY VISIBLE FUNCTIONS
|
1312
|
+
=========================================
|
1313
|
+
***************************************** */
|
1314
|
+
|
1315
|
+
/*******************************************************
|
1316
|
+
NAME : HashSlotName
|
1317
|
+
DESCRIPTION : Generates a hash index for a given
|
1318
|
+
slot name
|
1319
|
+
INPUTS : The address of the slot name SYMBOL_HN
|
1320
|
+
RETURNS : The hash index value
|
1321
|
+
SIDE EFFECTS : None
|
1322
|
+
NOTES : Counts on the fact that the symbol
|
1323
|
+
has already been hashed into the
|
1324
|
+
symbol table - uses that hash value
|
1325
|
+
multiplied by a prime for a new hash
|
1326
|
+
*******************************************************/
|
1327
|
+
static unsigned int HashSlotName(
|
1328
|
+
CLIPSLexeme *sname)
|
1329
|
+
{
|
1330
|
+
unsigned int tally;
|
1331
|
+
|
1332
|
+
tally = sname->bucket * BIG_PRIME;
|
1333
|
+
|
1334
|
+
return tally % SLOT_NAME_TABLE_HASH_SIZE;
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
#if (! RUN_TIME)
|
1338
|
+
|
1339
|
+
/***************************************************
|
1340
|
+
NAME : DeassignClassID
|
1341
|
+
DESCRIPTION : Reduces id map and MaxClassID if
|
1342
|
+
no ids in use above the one being
|
1343
|
+
released.
|
1344
|
+
INPUTS : The id
|
1345
|
+
RETURNS : Nothing useful
|
1346
|
+
SIDE EFFECTS : ID map and MaxClassID possibly
|
1347
|
+
reduced
|
1348
|
+
NOTES : None
|
1349
|
+
***************************************************/
|
1350
|
+
static void DeassignClassID(
|
1351
|
+
Environment *theEnv,
|
1352
|
+
unsigned short id)
|
1353
|
+
{
|
1354
|
+
unsigned short i;
|
1355
|
+
bool reallocReqd;
|
1356
|
+
unsigned short oldChunk = 0, newChunk = 0;
|
1357
|
+
|
1358
|
+
DefclassData(theEnv)->ClassIDMap[id] = NULL;
|
1359
|
+
for (i = id + 1 ; i < DefclassData(theEnv)->MaxClassID ; i++)
|
1360
|
+
if (DefclassData(theEnv)->ClassIDMap[i] != NULL)
|
1361
|
+
return;
|
1362
|
+
|
1363
|
+
reallocReqd = false;
|
1364
|
+
while (DefclassData(theEnv)->ClassIDMap[id] == NULL)
|
1365
|
+
{
|
1366
|
+
DefclassData(theEnv)->MaxClassID = id;
|
1367
|
+
if ((DefclassData(theEnv)->MaxClassID % CLASS_ID_MAP_CHUNK) == 0)
|
1368
|
+
{
|
1369
|
+
newChunk = DefclassData(theEnv)->MaxClassID;
|
1370
|
+
if (reallocReqd == false)
|
1371
|
+
{
|
1372
|
+
oldChunk = (DefclassData(theEnv)->MaxClassID + CLASS_ID_MAP_CHUNK);
|
1373
|
+
reallocReqd = true;
|
1374
|
+
}
|
1375
|
+
}
|
1376
|
+
if (id == 0)
|
1377
|
+
break;
|
1378
|
+
id--;
|
1379
|
+
}
|
1380
|
+
if (reallocReqd)
|
1381
|
+
{
|
1382
|
+
DefclassData(theEnv)->ClassIDMap = (Defclass **) genrealloc(theEnv,DefclassData(theEnv)->ClassIDMap,
|
1383
|
+
(oldChunk * sizeof(Defclass *)),
|
1384
|
+
(newChunk * sizeof(Defclass *)));
|
1385
|
+
|
1386
|
+
DefclassData(theEnv)->AvailClassID = newChunk;
|
1387
|
+
}
|
1388
|
+
}
|
1389
|
+
|
1390
|
+
#endif
|
1391
|
+
|
1392
|
+
#endif
|