clipsruby 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/ext/clipsruby/agenda.c +1373 -0
  3. data/ext/clipsruby/agenda.h +169 -0
  4. data/ext/clipsruby/analysis.c +1142 -0
  5. data/ext/clipsruby/analysis.h +61 -0
  6. data/ext/clipsruby/argacces.c +526 -0
  7. data/ext/clipsruby/argacces.h +77 -0
  8. data/ext/clipsruby/bload.c +884 -0
  9. data/ext/clipsruby/bload.h +94 -0
  10. data/ext/clipsruby/bmathfun.c +557 -0
  11. data/ext/clipsruby/bmathfun.h +66 -0
  12. data/ext/clipsruby/bsave.c +634 -0
  13. data/ext/clipsruby/bsave.h +130 -0
  14. data/ext/clipsruby/classcom.c +976 -0
  15. data/ext/clipsruby/classcom.h +115 -0
  16. data/ext/clipsruby/classexm.c +1376 -0
  17. data/ext/clipsruby/classexm.h +97 -0
  18. data/ext/clipsruby/classfun.c +1392 -0
  19. data/ext/clipsruby/classfun.h +164 -0
  20. data/ext/clipsruby/classinf.c +1245 -0
  21. data/ext/clipsruby/classinf.h +94 -0
  22. data/ext/clipsruby/classini.c +843 -0
  23. data/ext/clipsruby/classini.h +75 -0
  24. data/ext/clipsruby/classpsr.c +957 -0
  25. data/ext/clipsruby/classpsr.h +73 -0
  26. data/ext/clipsruby/clips.h +133 -0
  27. data/ext/clipsruby/clipsruby.c +619 -0
  28. data/ext/clipsruby/clsltpsr.c +931 -0
  29. data/ext/clipsruby/clsltpsr.h +72 -0
  30. data/ext/clipsruby/commline.c +1217 -0
  31. data/ext/clipsruby/commline.h +131 -0
  32. data/ext/clipsruby/conscomp.c +1593 -0
  33. data/ext/clipsruby/conscomp.h +150 -0
  34. data/ext/clipsruby/constant.h +264 -0
  35. data/ext/clipsruby/constrct.c +1090 -0
  36. data/ext/clipsruby/constrct.h +216 -0
  37. data/ext/clipsruby/constrnt.c +554 -0
  38. data/ext/clipsruby/constrnt.h +132 -0
  39. data/ext/clipsruby/crstrtgy.c +1088 -0
  40. data/ext/clipsruby/crstrtgy.h +85 -0
  41. data/ext/clipsruby/cstrcbin.c +185 -0
  42. data/ext/clipsruby/cstrcbin.h +61 -0
  43. data/ext/clipsruby/cstrccmp.h +43 -0
  44. data/ext/clipsruby/cstrccom.c +1791 -0
  45. data/ext/clipsruby/cstrccom.h +115 -0
  46. data/ext/clipsruby/cstrcpsr.c +835 -0
  47. data/ext/clipsruby/cstrcpsr.h +97 -0
  48. data/ext/clipsruby/cstrnbin.c +282 -0
  49. data/ext/clipsruby/cstrnbin.h +55 -0
  50. data/ext/clipsruby/cstrnchk.c +826 -0
  51. data/ext/clipsruby/cstrnchk.h +91 -0
  52. data/ext/clipsruby/cstrncmp.c +238 -0
  53. data/ext/clipsruby/cstrncmp.h +57 -0
  54. data/ext/clipsruby/cstrnops.c +1176 -0
  55. data/ext/clipsruby/cstrnops.h +47 -0
  56. data/ext/clipsruby/cstrnpsr.c +1394 -0
  57. data/ext/clipsruby/cstrnpsr.h +88 -0
  58. data/ext/clipsruby/cstrnutl.c +564 -0
  59. data/ext/clipsruby/cstrnutl.h +54 -0
  60. data/ext/clipsruby/default.c +454 -0
  61. data/ext/clipsruby/default.h +57 -0
  62. data/ext/clipsruby/defins.c +971 -0
  63. data/ext/clipsruby/defins.h +127 -0
  64. data/ext/clipsruby/developr.c +677 -0
  65. data/ext/clipsruby/developr.h +69 -0
  66. data/ext/clipsruby/dffctbin.c +477 -0
  67. data/ext/clipsruby/dffctbin.h +76 -0
  68. data/ext/clipsruby/dffctbsc.c +308 -0
  69. data/ext/clipsruby/dffctbsc.h +72 -0
  70. data/ext/clipsruby/dffctcmp.c +297 -0
  71. data/ext/clipsruby/dffctcmp.h +44 -0
  72. data/ext/clipsruby/dffctdef.c +364 -0
  73. data/ext/clipsruby/dffctdef.h +104 -0
  74. data/ext/clipsruby/dffctpsr.c +179 -0
  75. data/ext/clipsruby/dffctpsr.h +49 -0
  76. data/ext/clipsruby/dffnxbin.c +520 -0
  77. data/ext/clipsruby/dffnxbin.h +67 -0
  78. data/ext/clipsruby/dffnxcmp.c +378 -0
  79. data/ext/clipsruby/dffnxcmp.h +54 -0
  80. data/ext/clipsruby/dffnxexe.c +241 -0
  81. data/ext/clipsruby/dffnxexe.h +58 -0
  82. data/ext/clipsruby/dffnxfun.c +1192 -0
  83. data/ext/clipsruby/dffnxfun.h +155 -0
  84. data/ext/clipsruby/dffnxpsr.c +514 -0
  85. data/ext/clipsruby/dffnxpsr.h +57 -0
  86. data/ext/clipsruby/dfinsbin.c +509 -0
  87. data/ext/clipsruby/dfinsbin.h +66 -0
  88. data/ext/clipsruby/dfinscmp.c +345 -0
  89. data/ext/clipsruby/dfinscmp.h +48 -0
  90. data/ext/clipsruby/drive.c +1191 -0
  91. data/ext/clipsruby/drive.h +65 -0
  92. data/ext/clipsruby/emathfun.c +1213 -0
  93. data/ext/clipsruby/emathfun.h +99 -0
  94. data/ext/clipsruby/engine.c +1568 -0
  95. data/ext/clipsruby/engine.h +203 -0
  96. data/ext/clipsruby/entities.h +276 -0
  97. data/ext/clipsruby/envrnbld.c +514 -0
  98. data/ext/clipsruby/envrnbld.h +40 -0
  99. data/ext/clipsruby/envrnmnt.c +257 -0
  100. data/ext/clipsruby/envrnmnt.h +112 -0
  101. data/ext/clipsruby/evaluatn.c +1736 -0
  102. data/ext/clipsruby/evaluatn.h +211 -0
  103. data/ext/clipsruby/expressn.c +494 -0
  104. data/ext/clipsruby/expressn.h +154 -0
  105. data/ext/clipsruby/exprnbin.c +538 -0
  106. data/ext/clipsruby/exprnbin.h +60 -0
  107. data/ext/clipsruby/exprnops.c +564 -0
  108. data/ext/clipsruby/exprnops.h +67 -0
  109. data/ext/clipsruby/exprnpsr.c +1112 -0
  110. data/ext/clipsruby/exprnpsr.h +98 -0
  111. data/ext/clipsruby/extconf.rb +2 -0
  112. data/ext/clipsruby/extnfunc.c +1015 -0
  113. data/ext/clipsruby/extnfunc.h +157 -0
  114. data/ext/clipsruby/factbin.c +447 -0
  115. data/ext/clipsruby/factbin.h +56 -0
  116. data/ext/clipsruby/factbld.c +1035 -0
  117. data/ext/clipsruby/factbld.h +63 -0
  118. data/ext/clipsruby/factcmp.c +386 -0
  119. data/ext/clipsruby/factcmp.h +46 -0
  120. data/ext/clipsruby/factcom.c +759 -0
  121. data/ext/clipsruby/factcom.h +80 -0
  122. data/ext/clipsruby/factfile.c +1761 -0
  123. data/ext/clipsruby/factfile.h +54 -0
  124. data/ext/clipsruby/factfun.c +682 -0
  125. data/ext/clipsruby/factfun.h +77 -0
  126. data/ext/clipsruby/factgen.c +1305 -0
  127. data/ext/clipsruby/factgen.h +229 -0
  128. data/ext/clipsruby/facthsh.c +438 -0
  129. data/ext/clipsruby/facthsh.h +81 -0
  130. data/ext/clipsruby/factlhs.c +250 -0
  131. data/ext/clipsruby/factlhs.h +54 -0
  132. data/ext/clipsruby/factmch.c +905 -0
  133. data/ext/clipsruby/factmch.h +68 -0
  134. data/ext/clipsruby/factmngr.c +3373 -0
  135. data/ext/clipsruby/factmngr.h +325 -0
  136. data/ext/clipsruby/factprt.c +498 -0
  137. data/ext/clipsruby/factprt.h +60 -0
  138. data/ext/clipsruby/factqpsr.c +796 -0
  139. data/ext/clipsruby/factqpsr.h +61 -0
  140. data/ext/clipsruby/factqury.c +1267 -0
  141. data/ext/clipsruby/factqury.h +112 -0
  142. data/ext/clipsruby/factrete.c +978 -0
  143. data/ext/clipsruby/factrete.h +70 -0
  144. data/ext/clipsruby/factrhs.c +667 -0
  145. data/ext/clipsruby/factrhs.h +55 -0
  146. data/ext/clipsruby/filecom.c +353 -0
  147. data/ext/clipsruby/filecom.h +137 -0
  148. data/ext/clipsruby/filertr.c +481 -0
  149. data/ext/clipsruby/filertr.h +94 -0
  150. data/ext/clipsruby/fileutil.c +1020 -0
  151. data/ext/clipsruby/fileutil.h +50 -0
  152. data/ext/clipsruby/generate.c +1079 -0
  153. data/ext/clipsruby/generate.h +57 -0
  154. data/ext/clipsruby/genrcbin.c +902 -0
  155. data/ext/clipsruby/genrcbin.h +69 -0
  156. data/ext/clipsruby/genrccmp.c +640 -0
  157. data/ext/clipsruby/genrccmp.h +59 -0
  158. data/ext/clipsruby/genrccom.c +2017 -0
  159. data/ext/clipsruby/genrccom.h +119 -0
  160. data/ext/clipsruby/genrcexe.c +737 -0
  161. data/ext/clipsruby/genrcexe.h +73 -0
  162. data/ext/clipsruby/genrcfun.c +890 -0
  163. data/ext/clipsruby/genrcfun.h +185 -0
  164. data/ext/clipsruby/genrcpsr.c +1618 -0
  165. data/ext/clipsruby/genrcpsr.h +80 -0
  166. data/ext/clipsruby/globlbin.c +458 -0
  167. data/ext/clipsruby/globlbin.h +71 -0
  168. data/ext/clipsruby/globlbsc.c +361 -0
  169. data/ext/clipsruby/globlbsc.h +83 -0
  170. data/ext/clipsruby/globlcmp.c +330 -0
  171. data/ext/clipsruby/globlcmp.h +52 -0
  172. data/ext/clipsruby/globlcom.c +289 -0
  173. data/ext/clipsruby/globlcom.h +63 -0
  174. data/ext/clipsruby/globldef.c +1087 -0
  175. data/ext/clipsruby/globldef.h +151 -0
  176. data/ext/clipsruby/globlpsr.c +530 -0
  177. data/ext/clipsruby/globlpsr.h +59 -0
  178. data/ext/clipsruby/immthpsr.c +431 -0
  179. data/ext/clipsruby/immthpsr.h +55 -0
  180. data/ext/clipsruby/incrrset.c +530 -0
  181. data/ext/clipsruby/incrrset.h +73 -0
  182. data/ext/clipsruby/inherpsr.c +850 -0
  183. data/ext/clipsruby/inherpsr.h +52 -0
  184. data/ext/clipsruby/inscom.c +2076 -0
  185. data/ext/clipsruby/inscom.h +182 -0
  186. data/ext/clipsruby/insfile.c +1764 -0
  187. data/ext/clipsruby/insfile.h +96 -0
  188. data/ext/clipsruby/insfun.c +1451 -0
  189. data/ext/clipsruby/insfun.h +134 -0
  190. data/ext/clipsruby/insmngr.c +2550 -0
  191. data/ext/clipsruby/insmngr.h +125 -0
  192. data/ext/clipsruby/insmoddp.c +1041 -0
  193. data/ext/clipsruby/insmoddp.h +91 -0
  194. data/ext/clipsruby/insmult.c +804 -0
  195. data/ext/clipsruby/insmult.h +62 -0
  196. data/ext/clipsruby/inspsr.c +602 -0
  197. data/ext/clipsruby/inspsr.h +60 -0
  198. data/ext/clipsruby/insquery.c +1278 -0
  199. data/ext/clipsruby/insquery.h +115 -0
  200. data/ext/clipsruby/insqypsr.c +729 -0
  201. data/ext/clipsruby/insqypsr.h +63 -0
  202. data/ext/clipsruby/iofun.c +2045 -0
  203. data/ext/clipsruby/iofun.h +116 -0
  204. data/ext/clipsruby/lgcldpnd.c +644 -0
  205. data/ext/clipsruby/lgcldpnd.h +75 -0
  206. data/ext/clipsruby/main.c +112 -0
  207. data/ext/clipsruby/match.h +142 -0
  208. data/ext/clipsruby/memalloc.c +481 -0
  209. data/ext/clipsruby/memalloc.h +197 -0
  210. data/ext/clipsruby/miscfun.c +1801 -0
  211. data/ext/clipsruby/miscfun.h +132 -0
  212. data/ext/clipsruby/modulbin.c +607 -0
  213. data/ext/clipsruby/modulbin.h +84 -0
  214. data/ext/clipsruby/modulbsc.c +347 -0
  215. data/ext/clipsruby/modulbsc.h +67 -0
  216. data/ext/clipsruby/modulcmp.c +499 -0
  217. data/ext/clipsruby/modulcmp.h +54 -0
  218. data/ext/clipsruby/moduldef.c +817 -0
  219. data/ext/clipsruby/moduldef.h +271 -0
  220. data/ext/clipsruby/modulpsr.c +1150 -0
  221. data/ext/clipsruby/modulpsr.h +69 -0
  222. data/ext/clipsruby/modulutl.c +1036 -0
  223. data/ext/clipsruby/modulutl.h +84 -0
  224. data/ext/clipsruby/msgcom.c +1221 -0
  225. data/ext/clipsruby/msgcom.h +125 -0
  226. data/ext/clipsruby/msgfun.c +1076 -0
  227. data/ext/clipsruby/msgfun.h +118 -0
  228. data/ext/clipsruby/msgpass.c +1441 -0
  229. data/ext/clipsruby/msgpass.h +103 -0
  230. data/ext/clipsruby/msgpsr.c +698 -0
  231. data/ext/clipsruby/msgpsr.h +73 -0
  232. data/ext/clipsruby/multifld.c +1404 -0
  233. data/ext/clipsruby/multifld.h +130 -0
  234. data/ext/clipsruby/multifun.c +2182 -0
  235. data/ext/clipsruby/multifun.h +102 -0
  236. data/ext/clipsruby/network.h +142 -0
  237. data/ext/clipsruby/objbin.c +1522 -0
  238. data/ext/clipsruby/objbin.h +79 -0
  239. data/ext/clipsruby/objcmp.c +1507 -0
  240. data/ext/clipsruby/objcmp.h +71 -0
  241. data/ext/clipsruby/object.h +260 -0
  242. data/ext/clipsruby/objrtbin.c +701 -0
  243. data/ext/clipsruby/objrtbin.h +79 -0
  244. data/ext/clipsruby/objrtbld.c +2393 -0
  245. data/ext/clipsruby/objrtbld.h +66 -0
  246. data/ext/clipsruby/objrtcmp.c +734 -0
  247. data/ext/clipsruby/objrtcmp.h +66 -0
  248. data/ext/clipsruby/objrtfnx.c +1330 -0
  249. data/ext/clipsruby/objrtfnx.h +222 -0
  250. data/ext/clipsruby/objrtgen.c +736 -0
  251. data/ext/clipsruby/objrtgen.h +63 -0
  252. data/ext/clipsruby/objrtmch.c +1524 -0
  253. data/ext/clipsruby/objrtmch.h +160 -0
  254. data/ext/clipsruby/parsefun.c +415 -0
  255. data/ext/clipsruby/parsefun.h +67 -0
  256. data/ext/clipsruby/pattern.c +1265 -0
  257. data/ext/clipsruby/pattern.h +163 -0
  258. data/ext/clipsruby/pprint.c +328 -0
  259. data/ext/clipsruby/pprint.h +79 -0
  260. data/ext/clipsruby/prccode.c +1478 -0
  261. data/ext/clipsruby/prccode.h +145 -0
  262. data/ext/clipsruby/prcdrfun.c +640 -0
  263. data/ext/clipsruby/prcdrfun.h +95 -0
  264. data/ext/clipsruby/prcdrpsr.c +1068 -0
  265. data/ext/clipsruby/prcdrpsr.h +79 -0
  266. data/ext/clipsruby/prdctfun.c +869 -0
  267. data/ext/clipsruby/prdctfun.h +77 -0
  268. data/ext/clipsruby/prntutil.c +878 -0
  269. data/ext/clipsruby/prntutil.h +125 -0
  270. data/ext/clipsruby/proflfun.c +827 -0
  271. data/ext/clipsruby/proflfun.h +118 -0
  272. data/ext/clipsruby/reorder.c +2082 -0
  273. data/ext/clipsruby/reorder.h +172 -0
  274. data/ext/clipsruby/reteutil.c +1732 -0
  275. data/ext/clipsruby/reteutil.h +111 -0
  276. data/ext/clipsruby/retract.c +710 -0
  277. data/ext/clipsruby/retract.h +74 -0
  278. data/ext/clipsruby/router.c +737 -0
  279. data/ext/clipsruby/router.h +147 -0
  280. data/ext/clipsruby/rulebin.c +1136 -0
  281. data/ext/clipsruby/rulebin.h +153 -0
  282. data/ext/clipsruby/rulebld.c +1328 -0
  283. data/ext/clipsruby/rulebld.h +62 -0
  284. data/ext/clipsruby/rulebsc.c +517 -0
  285. data/ext/clipsruby/rulebsc.h +91 -0
  286. data/ext/clipsruby/rulecmp.c +733 -0
  287. data/ext/clipsruby/rulecmp.h +63 -0
  288. data/ext/clipsruby/rulecom.c +1583 -0
  289. data/ext/clipsruby/rulecom.h +116 -0
  290. data/ext/clipsruby/rulecstr.c +892 -0
  291. data/ext/clipsruby/rulecstr.h +53 -0
  292. data/ext/clipsruby/ruledef.c +559 -0
  293. data/ext/clipsruby/ruledef.h +179 -0
  294. data/ext/clipsruby/ruledlt.c +599 -0
  295. data/ext/clipsruby/ruledlt.h +58 -0
  296. data/ext/clipsruby/rulelhs.c +1216 -0
  297. data/ext/clipsruby/rulelhs.h +52 -0
  298. data/ext/clipsruby/rulepsr.c +1073 -0
  299. data/ext/clipsruby/rulepsr.h +61 -0
  300. data/ext/clipsruby/scanner.c +856 -0
  301. data/ext/clipsruby/scanner.h +112 -0
  302. data/ext/clipsruby/setup.h +488 -0
  303. data/ext/clipsruby/sortfun.c +433 -0
  304. data/ext/clipsruby/sortfun.h +55 -0
  305. data/ext/clipsruby/strngfun.c +1173 -0
  306. data/ext/clipsruby/strngfun.h +96 -0
  307. data/ext/clipsruby/strngrtr.c +523 -0
  308. data/ext/clipsruby/strngrtr.h +97 -0
  309. data/ext/clipsruby/symblbin.c +648 -0
  310. data/ext/clipsruby/symblbin.h +64 -0
  311. data/ext/clipsruby/symblcmp.c +893 -0
  312. data/ext/clipsruby/symblcmp.h +61 -0
  313. data/ext/clipsruby/symbol.c +1961 -0
  314. data/ext/clipsruby/symbol.h +243 -0
  315. data/ext/clipsruby/sysdep.c +894 -0
  316. data/ext/clipsruby/sysdep.h +164 -0
  317. data/ext/clipsruby/textpro.c +1388 -0
  318. data/ext/clipsruby/textpro.h +77 -0
  319. data/ext/clipsruby/tmpltbin.c +609 -0
  320. data/ext/clipsruby/tmpltbin.h +108 -0
  321. data/ext/clipsruby/tmpltbsc.c +327 -0
  322. data/ext/clipsruby/tmpltbsc.h +87 -0
  323. data/ext/clipsruby/tmpltcmp.c +450 -0
  324. data/ext/clipsruby/tmpltcmp.h +57 -0
  325. data/ext/clipsruby/tmpltdef.c +584 -0
  326. data/ext/clipsruby/tmpltdef.h +155 -0
  327. data/ext/clipsruby/tmpltfun.c +2477 -0
  328. data/ext/clipsruby/tmpltfun.h +122 -0
  329. data/ext/clipsruby/tmpltlhs.c +379 -0
  330. data/ext/clipsruby/tmpltlhs.h +50 -0
  331. data/ext/clipsruby/tmpltpsr.c +819 -0
  332. data/ext/clipsruby/tmpltpsr.h +59 -0
  333. data/ext/clipsruby/tmpltrhs.c +595 -0
  334. data/ext/clipsruby/tmpltrhs.h +55 -0
  335. data/ext/clipsruby/tmpltutl.c +637 -0
  336. data/ext/clipsruby/tmpltutl.h +82 -0
  337. data/ext/clipsruby/userdata.c +156 -0
  338. data/ext/clipsruby/userdata.h +72 -0
  339. data/ext/clipsruby/userfunctions.c +70 -0
  340. data/ext/clipsruby/usrsetup.h +7 -0
  341. data/ext/clipsruby/utility.c +1594 -0
  342. data/ext/clipsruby/utility.h +250 -0
  343. data/ext/clipsruby/watch.c +865 -0
  344. data/ext/clipsruby/watch.h +124 -0
  345. data/lib/clipsruby.rb +1 -0
  346. metadata +388 -0
@@ -0,0 +1,2182 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.41 11/04/22 */
5
+ /* */
6
+ /* MULTIFIELD FUNCTIONS MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Contains the code for several multifield */
11
+ /* functions including first$, rest$, subseq$, delete$, */
12
+ /* delete-member$, replace-member$, replace$, insert$, */
13
+ /* explode$, implode$, nth$, member$, subsetp and progn$. */
14
+ /* */
15
+ /* Principal Programmer(s): */
16
+ /* Gary D. Riley */
17
+ /* Brian Dantes */
18
+ /* Barry Cameron */
19
+ /* */
20
+ /* Contributing Programmer(s): */
21
+ /* */
22
+ /* Revision History: */
23
+ /* */
24
+ /* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
25
+ /* */
26
+ /* Changed name of variable exp to theExp */
27
+ /* because of Unix compiler warnings of shadowed */
28
+ /* definitions. */
29
+ /* */
30
+ /* 6.24: Renamed BOOLEAN macro type to intBool. */
31
+ /* */
32
+ /* Moved ImplodeMultifield to multifld.c. */
33
+ /* */
34
+ /* 6.30: Changed integer type/precision. */
35
+ /* */
36
+ /* Support for long long integers. */
37
+ /* */
38
+ /* Changed garbage collection algorithm. */
39
+ /* */
40
+ /* Fixed memory leaks when error occurred. */
41
+ /* */
42
+ /* Added const qualifiers to remove C++ */
43
+ /* deprecation warnings. */
44
+ /* */
45
+ /* Fixed linkage issue when DEFMODULE_CONSTRUCT */
46
+ /* compiler flag is set to 0. */
47
+ /* */
48
+ /* 6.32: Rebinding of field index variable in progn$ */
49
+ /* and foreach now generates an error. */
50
+ /* */
51
+ /* 6.40: Added Env prefix to GetEvaluationError and */
52
+ /* SetEvaluationError functions. */
53
+ /* */
54
+ /* Added Env prefix to GetHaltExecution and */
55
+ /* SetHaltExecution functions. */
56
+ /* */
57
+ /* Pragma once and other inclusion changes. */
58
+ /* */
59
+ /* Added support for booleans with <stdbool.h>. */
60
+ /* */
61
+ /* Removed use of void pointers for specific */
62
+ /* data structures. */
63
+ /* */
64
+ /* Removed member, mv-replace, mv-subseq, */
65
+ /* mv-delete, str-implode, str-explode, subset, */
66
+ /* and nth functions. */
67
+ /* */
68
+ /* UDF redesign. */
69
+ /* */
70
+ /* Added GCBlockStart and GCBlockEnd functions */
71
+ /* for garbage collection blocks. */
72
+ /* */
73
+ /* Eval support for run time and bload only. */
74
+ /* */
75
+ /* The explode$ function via StringToMultifield */
76
+ /* now converts non-primitive value tokens */
77
+ /* (such as parentheses) to symbols rather than */
78
+ /* strings. */
79
+ /* */
80
+ /* 6.41: Added intersection$, union$, and difference$ */
81
+ /* functions. */
82
+ /* */
83
+ /*************************************************************/
84
+
85
+ #include "setup.h"
86
+
87
+ #if MULTIFIELD_FUNCTIONS || OBJECT_SYSTEM
88
+
89
+ #include <stdio.h>
90
+ #include <string.h>
91
+
92
+ #include "argacces.h"
93
+ #include "envrnmnt.h"
94
+ #include "exprnpsr.h"
95
+ #include "memalloc.h"
96
+ #include "multifld.h"
97
+ #include "multifun.h"
98
+ #if OBJECT_SYSTEM
99
+ #include "object.h"
100
+ #endif
101
+ #include "pprint.h"
102
+ #include "prcdrpsr.h"
103
+ #include "prcdrfun.h"
104
+ #include "prntutil.h"
105
+ #include "router.h"
106
+ #if (! BLOAD_ONLY) && (! RUN_TIME)
107
+ #include "scanner.h"
108
+ #endif
109
+ #include "utility.h"
110
+
111
+ /**************/
112
+ /* STRUCTURES */
113
+ /**************/
114
+
115
+ typedef struct fieldVarStack
116
+ {
117
+ unsigned short type;
118
+ void *value;
119
+ size_t index;
120
+ struct fieldVarStack *nxt;
121
+ } FIELD_VAR_STACK;
122
+
123
+ /***************************************/
124
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
125
+ /***************************************/
126
+
127
+ #if MULTIFIELD_FUNCTIONS
128
+ static bool MVRangeCheck(size_t,size_t,size_t *,unsigned int);
129
+ static void MultifieldPrognDriver(UDFContext *,UDFValue *,const char *);
130
+ #if (! BLOAD_ONLY)
131
+ static struct expr *MultifieldPrognParser(Environment *,struct expr *,const char *);
132
+ static struct expr *ForeachParser(Environment *,struct expr *,const char *);
133
+ static void ReplaceMvPrognFieldVars(Environment *,CLIPSLexeme *,struct expr *,int);
134
+ #endif /* (! BLOAD_ONLY) && (! RUN_TIME) */
135
+ #endif /* MULTIFIELD_FUNCTIONS */
136
+ static void MVRangeErrorSizet(Environment *,size_t,size_t,size_t,const char *);
137
+ #endif /* MULTIFIELD_FUNCTIONS || OBJECT_SYSTEM */
138
+
139
+ /***************************************/
140
+ /* LOCAL INTERNAL VARIABLE DEFINITIONS */
141
+ /***************************************/
142
+
143
+ #if MULTIFIELD_FUNCTIONS
144
+
145
+ #define MULTIFUN_DATA 10
146
+
147
+ struct multiFunctionData
148
+ {
149
+ FIELD_VAR_STACK *FieldVarStack;
150
+ };
151
+
152
+ #define MultiFunctionData(theEnv) ((struct multiFunctionData *) GetEnvironmentData(theEnv,MULTIFUN_DATA))
153
+
154
+ /**********************************************/
155
+ /* MultifieldFunctionDefinitions: Initializes */
156
+ /* the multifield functions. */
157
+ /**********************************************/
158
+ void MultifieldFunctionDefinitions(
159
+ Environment *theEnv)
160
+ {
161
+ AllocateEnvironmentData(theEnv,MULTIFUN_DATA,sizeof(struct multiFunctionData),NULL);
162
+
163
+ #if ! RUN_TIME
164
+ AddUDF(theEnv,"first$","m",1,1,"m",FirstFunction,"FirstFunction",NULL);
165
+ AddUDF(theEnv,"rest$","m",1,1,"m",RestFunction,"RestFunction",NULL);
166
+ AddUDF(theEnv,"subseq$","m",3,3,"l;m",SubseqFunction,"SubseqFunction",NULL);
167
+ AddUDF(theEnv,"delete-member$","m",2,UNBOUNDED,"*;m",DeleteMemberFunction,"DeleteMemberFunction",NULL);
168
+ AddUDF(theEnv,"replace-member$","m",3,UNBOUNDED,"*;m",ReplaceMemberFunction,"ReplaceMemberFunction",NULL);
169
+ AddUDF(theEnv,"delete$","m",3,3,"l;m",DeleteFunction,"DeleteFunction",NULL);
170
+ AddUDF(theEnv,"replace$","m",4,UNBOUNDED,"*;m;l;l",ReplaceFunction,"ReplaceFunction",NULL);
171
+ AddUDF(theEnv,"insert$","m",3,UNBOUNDED,"*;m;l",InsertFunction,"InsertFunction",NULL);
172
+ AddUDF(theEnv,"explode$","m",1,1,"s",ExplodeFunction,"ExplodeFunction",NULL);
173
+ AddUDF(theEnv,"implode$","s",1,1,"m",ImplodeFunction,"ImplodeFunction",NULL);
174
+ AddUDF(theEnv,"nth$","synldife",2,2,";l;m",NthFunction,"NthFunction",NULL);
175
+ AddUDF(theEnv,"member$","blm",2,2,";*;m",MemberFunction,"MemberFunction",NULL);
176
+ AddUDF(theEnv,"subsetp","b",2,2,";m;m",SubsetpFunction,"SubsetpFunction",NULL);
177
+ AddUDF(theEnv,"intersection$","m",0,UNBOUNDED,"m",IntersectionFunction,"IntersectionFunction",NULL);
178
+ AddUDF(theEnv,"union$","m",0,UNBOUNDED,"m",UnionFunction,"UnionFunction",NULL);
179
+ AddUDF(theEnv,"difference$","m",1,UNBOUNDED,"m",DifferenceFunction,"DifferenceFunction",NULL);
180
+ AddUDF(theEnv,"progn$","*",0,UNBOUNDED,NULL,MultifieldPrognFunction,"MultifieldPrognFunction",NULL);
181
+ AddUDF(theEnv,"foreach","*",0,UNBOUNDED,NULL,ForeachFunction,"ForeachFunction",NULL);
182
+ FuncSeqOvlFlags(theEnv,"progn$",false,false);
183
+ FuncSeqOvlFlags(theEnv,"foreach",false,false);
184
+ AddUDF(theEnv,"(get-progn$-field)","*",0,0,NULL,GetMvPrognField,"GetMvPrognField",NULL);
185
+ AddUDF(theEnv,"(get-progn$-index)","l",0,0,NULL,GetMvPrognIndex,"GetMvPrognIndex",NULL);
186
+ #endif
187
+
188
+ #if ! BLOAD_ONLY
189
+ AddFunctionParser(theEnv,"progn$",MultifieldPrognParser);
190
+ AddFunctionParser(theEnv,"foreach",ForeachParser);
191
+ #endif
192
+ }
193
+
194
+ /****************************************/
195
+ /* DeleteFunction: H/L access routine */
196
+ /* for the delete$ function. */
197
+ /****************************************/
198
+ void DeleteFunction(
199
+ Environment *theEnv,
200
+ UDFContext *context,
201
+ UDFValue *returnValue)
202
+ {
203
+ UDFValue value1, value2, value3;
204
+ long long start, end;
205
+ size_t rs, re, srcLen, dstLen, i, j;
206
+
207
+ /*=======================================*/
208
+ /* Check for the correct argument types. */
209
+ /*=======================================*/
210
+
211
+ if ((! UDFFirstArgument(context,MULTIFIELD_BIT,&value1)) ||
212
+ (! UDFNextArgument(context,INTEGER_BIT,&value2)) ||
213
+ (! UDFNextArgument(context,INTEGER_BIT,&value3)))
214
+ { return; }
215
+
216
+ /*===========================================*/
217
+ /* Verify the start and end index arguments. */
218
+ /*===========================================*/
219
+
220
+ start = value2.integerValue->contents;
221
+ end = value3.integerValue->contents;
222
+
223
+ if ((end < start) || (start < 1) || (end < 1) ||
224
+ (((long long) ((size_t) start)) != start) ||
225
+ (((long long) ((size_t) end)) != end))
226
+ {
227
+ MVRangeError(theEnv,start,end,value1.range,"delete$");
228
+ SetEvaluationError(theEnv,true);
229
+ SetMultifieldErrorValue(theEnv,returnValue);
230
+ return;
231
+ }
232
+
233
+ /*============================================*/
234
+ /* Convert the indices to unsigned zero-based */
235
+ /* values including the begin value. */
236
+ /*============================================*/
237
+
238
+ rs = (size_t) start;
239
+ re = (size_t) end;
240
+ srcLen = value1.range;
241
+
242
+ if ((rs > srcLen) || (re > srcLen))
243
+ {
244
+ MVRangeError(theEnv,start,end,value1.range,"delete$");
245
+ SetEvaluationError(theEnv,true);
246
+ SetMultifieldErrorValue(theEnv,returnValue);
247
+ return;
248
+ }
249
+
250
+ rs--;
251
+ re--;
252
+ rs += value1.begin;
253
+ re += value1.begin;
254
+
255
+ /*=================================================*/
256
+ /* Delete the section out of the multifield value. */
257
+ /*=================================================*/
258
+
259
+ dstLen = srcLen - (re - rs + 1);
260
+ returnValue->begin = 0;
261
+ returnValue->range = dstLen;
262
+ returnValue->multifieldValue = CreateMultifield(theEnv,dstLen);
263
+
264
+ for (i = value1.begin, j = 0; i < (value1.begin + value1.range); i++)
265
+ {
266
+ if ((i >= rs) && (i <= re)) continue;
267
+
268
+ returnValue->multifieldValue->contents[j++].value = value1.multifieldValue->contents[i].value;
269
+ }
270
+ }
271
+
272
+ /*****************************************/
273
+ /* ReplaceFunction: H/L access routine */
274
+ /* for the replace$ function. */
275
+ /*****************************************/
276
+ void ReplaceFunction(
277
+ Environment *theEnv,
278
+ UDFContext *context,
279
+ UDFValue *returnValue)
280
+ {
281
+ UDFValue value1, value2, value3, value4;
282
+ Expression *fieldarg;
283
+ long long start, end;
284
+ size_t rs, re, srcLen, dstLen;
285
+ size_t i, j, k;
286
+
287
+ /*=======================================*/
288
+ /* Check for the correct argument types. */
289
+ /*=======================================*/
290
+
291
+ if ((! UDFFirstArgument(context,MULTIFIELD_BIT,&value1)) ||
292
+ (! UDFNextArgument(context,INTEGER_BIT,&value2)) ||
293
+ (! UDFNextArgument(context,INTEGER_BIT,&value3)))
294
+ { return; }
295
+
296
+ /*===============================*/
297
+ /* Create the replacement value. */
298
+ /*===============================*/
299
+
300
+ fieldarg = GetFirstArgument()->nextArg->nextArg->nextArg;
301
+ if (fieldarg->nextArg != NULL)
302
+ { StoreInMultifield(theEnv,&value4,fieldarg,true); }
303
+ else
304
+ { EvaluateExpression(theEnv,fieldarg,&value4); }
305
+
306
+ /*===========================================*/
307
+ /* Verify the start and end index arguments. */
308
+ /*===========================================*/
309
+
310
+ start = value2.integerValue->contents; // TBD Refactor
311
+ end = value3.integerValue->contents;
312
+
313
+ if ((end < start) || (start < 1) || (end < 1) ||
314
+ (((long long) ((size_t) start)) != start) ||
315
+ (((long long) ((size_t) end)) != end))
316
+ {
317
+ MVRangeError(theEnv,start,end,value1.range,"replace$");
318
+ SetEvaluationError(theEnv,true);
319
+ SetMultifieldErrorValue(theEnv,returnValue);
320
+ return;
321
+ }
322
+
323
+ /*============================================*/
324
+ /* Convert the indices to unsigned zero-based */
325
+ /* values including the begin value. */
326
+ /*============================================*/
327
+
328
+ rs = (size_t) start;
329
+ re = (size_t) end;
330
+ srcLen = value1.range;
331
+
332
+ if ((rs > srcLen) || (re > srcLen))
333
+ {
334
+ MVRangeError(theEnv,start,end,value1.range,"replace$");
335
+ SetEvaluationError(theEnv,true);
336
+ SetMultifieldErrorValue(theEnv,returnValue);
337
+ return;
338
+ }
339
+
340
+ rs--;
341
+ re--;
342
+ rs += value1.begin;
343
+ re += value1.begin;
344
+
345
+ /*=================================================*/
346
+ /* Delete the section out of the multifield value. */
347
+ /*=================================================*/
348
+
349
+ if (value4.header->type == MULTIFIELD_TYPE) // TBD Refactor
350
+ { dstLen = srcLen - (re - rs + 1) + value4.range; }
351
+ else
352
+ { dstLen = srcLen - (re - rs); }
353
+
354
+ returnValue->begin = 0;
355
+ returnValue->range = dstLen;
356
+ returnValue->multifieldValue = CreateMultifield(theEnv,dstLen);
357
+
358
+ for (i = value1.begin, j = 0; i < (value1.begin + value1.range); i++)
359
+ {
360
+ if (i == rs)
361
+ {
362
+ if (value4.header->type == MULTIFIELD_TYPE)
363
+ {
364
+ for (k = value4.begin; k < (value4.begin + value4.range); k++)
365
+ { returnValue->multifieldValue->contents[j++].value = value4.multifieldValue->contents[k].value; }
366
+ }
367
+ else
368
+ { returnValue->multifieldValue->contents[j++].value = value4.value; }
369
+
370
+ continue;
371
+ }
372
+ else if ((i > rs) && (i <= re))
373
+ { continue; }
374
+
375
+ returnValue->multifieldValue->contents[j++].value = value1.multifieldValue->contents[i].value;
376
+ }
377
+ }
378
+
379
+ /**********************************************/
380
+ /* DeleteMemberFunction: H/L access routine */
381
+ /* for the delete-member$ function. */
382
+ /**********************************************/
383
+ void DeleteMemberFunction(
384
+ Environment *theEnv,
385
+ UDFContext *context,
386
+ UDFValue *returnValue)
387
+ {
388
+ UDFValue resultValue, valueSought;
389
+ unsigned int argCnt;
390
+ size_t i, j, k, valueSoughtLength;
391
+ size_t rs, re;
392
+ Multifield *update;
393
+
394
+ /*============================================*/
395
+ /* Check for the correct number of arguments. */
396
+ /*============================================*/
397
+
398
+ argCnt = UDFArgumentCount(context);
399
+
400
+ /*=======================================*/
401
+ /* Check for the correct argument types. */
402
+ /*=======================================*/
403
+
404
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&resultValue))
405
+ { return; }
406
+
407
+ /*===================================================*/
408
+ /* For every value specified, delete all occurrences */
409
+ /* of those values from the multifield. */
410
+ /*===================================================*/
411
+
412
+ for (i = 2 ; i <= argCnt ; i++)
413
+ {
414
+ if (! UDFNextArgument(context,ANY_TYPE_BITS,&valueSought))
415
+ {
416
+ SetEvaluationError(theEnv,true);
417
+ SetMultifieldErrorValue(theEnv,returnValue);
418
+ return;
419
+ }
420
+
421
+ if (valueSought.header->type == MULTIFIELD_TYPE)
422
+ {
423
+ valueSoughtLength = valueSought.range;
424
+ if (valueSoughtLength == 0) continue;
425
+ }
426
+ else
427
+ { valueSoughtLength = 1; }
428
+
429
+ while ((rs = FindValueInMultifield(&valueSought,&resultValue)) != VALUE_NOT_FOUND) // TBD Refactor
430
+ {
431
+ update = CreateMultifield(theEnv,resultValue.range - valueSoughtLength);
432
+ re = rs + valueSoughtLength - 1;
433
+
434
+ for (j = resultValue.begin, k = 0; j < (resultValue.begin + resultValue.range); j++)
435
+ {
436
+ if ((j >= rs) && (j <= re)) continue;
437
+
438
+ update->contents[k++].value = resultValue.multifieldValue->contents[j].value;
439
+ }
440
+
441
+ resultValue.multifieldValue = update;
442
+ resultValue.begin = 0;
443
+ resultValue.range = resultValue.range - valueSoughtLength;
444
+ }
445
+ }
446
+
447
+ returnValue->multifieldValue = resultValue.multifieldValue;
448
+ returnValue->begin = resultValue.begin;
449
+ returnValue->range = resultValue.range;
450
+ }
451
+
452
+ /***********************************************/
453
+ /* ReplaceMemberFunction: H/L access routine */
454
+ /* for the replace-member$ function. */
455
+ /***********************************************/
456
+ void ReplaceMemberFunction(
457
+ Environment *theEnv,
458
+ UDFContext *context,
459
+ UDFValue *returnValue)
460
+ {
461
+ UDFValue resultValue,replVal,*delVals,tmpVal;
462
+ unsigned int i, argCnt;
463
+ unsigned delSize;
464
+ size_t j, k;
465
+ size_t mink[2], *minkp;
466
+ size_t replLen = 1;
467
+
468
+ /*============================================*/
469
+ /* Check for the correct number of arguments. */
470
+ /*============================================*/
471
+
472
+ argCnt = UDFArgumentCount(context);
473
+
474
+ /*=======================================*/
475
+ /* Check for the correct argument types. */
476
+ /*=======================================*/
477
+
478
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&resultValue))
479
+ { return; }
480
+
481
+ if (! UDFNextArgument(context,ANY_TYPE_BITS,&replVal))
482
+ { return; }
483
+
484
+ if (replVal.header->type == MULTIFIELD_TYPE)
485
+ replLen = replVal.range;
486
+
487
+ /*======================================================*/
488
+ /* For the value (or values from multifield) specified, */
489
+ /* replace all occurrences of those values with all */
490
+ /* values specified. */
491
+ /*======================================================*/
492
+
493
+ delSize = (sizeof(UDFValue) * (argCnt-2));
494
+ delVals = (UDFValue *) gm2(theEnv,delSize);
495
+
496
+ for (i = 3 ; i <= argCnt ; i++)
497
+ {
498
+ if (! UDFNthArgument(context,i,ANY_TYPE_BITS,&delVals[i-3]))
499
+ {
500
+ rm(theEnv,delVals,delSize);
501
+ return;
502
+ }
503
+ }
504
+ minkp = NULL;
505
+ while (FindDOsInSegment(delVals,argCnt-2,&resultValue,&j,&k,minkp,minkp ? 1 : 0))
506
+ {
507
+ if (ReplaceMultiValueFieldSizet(theEnv,&tmpVal,&resultValue,j,k,
508
+ &replVal,"replace-member$") == false)
509
+ {
510
+ rm(theEnv,delVals,delSize);
511
+ SetEvaluationError(theEnv,true);
512
+ SetMultifieldErrorValue(theEnv,returnValue);
513
+ return;
514
+ }
515
+ GenCopyMemory(UDFValue,1,&resultValue,&tmpVal);
516
+ mink[0] = 1;
517
+ mink[1] = j + replLen - 1;
518
+ minkp = mink;
519
+ }
520
+ rm(theEnv,delVals,delSize);
521
+ GenCopyMemory(UDFValue,1,returnValue,&resultValue);
522
+ }
523
+
524
+ /****************************************/
525
+ /* InsertFunction: H/L access routine */
526
+ /* for the insert$ function. */
527
+ /****************************************/
528
+ void InsertFunction(
529
+ Environment *theEnv,
530
+ UDFContext *context,
531
+ UDFValue *returnValue)
532
+ {
533
+ UDFValue value1, value2, value3;
534
+ Expression *fieldarg;
535
+ long long theIndex;
536
+ size_t uindex;
537
+
538
+ /*=======================================*/
539
+ /* Check for the correct argument types. */
540
+ /*=======================================*/
541
+
542
+ if ((! UDFFirstArgument(context,MULTIFIELD_BIT,&value1)) ||
543
+ (! UDFNextArgument(context,INTEGER_BIT,&value2)))
544
+ { return; }
545
+
546
+ /*=============================*/
547
+ /* Create the insertion value. */
548
+ /*=============================*/
549
+
550
+ fieldarg = GetFirstArgument()->nextArg->nextArg;
551
+ if (fieldarg->nextArg != NULL)
552
+ StoreInMultifield(theEnv,&value3,fieldarg,true);
553
+ else
554
+ EvaluateExpression(theEnv,fieldarg,&value3);
555
+
556
+ /*============================*/
557
+ /* Coerce the index argument. */
558
+ /*============================*/
559
+
560
+ theIndex = value2.integerValue->contents;
561
+
562
+ if ((((long long) ((size_t) theIndex)) != theIndex) ||
563
+ (theIndex < 1))
564
+ {
565
+ MVRangeError(theEnv,theIndex,theIndex,value1.range,"insert$");
566
+ return;
567
+ }
568
+
569
+ uindex = (size_t) theIndex;
570
+
571
+ /*===========================================*/
572
+ /* Insert the value in the multifield value. */
573
+ /*===========================================*/
574
+
575
+ if (InsertMultiValueField(theEnv,returnValue,&value1,uindex,
576
+ &value3,"insert$") == false)
577
+ {
578
+ SetEvaluationError(theEnv,true);
579
+ SetMultifieldErrorValue(theEnv,returnValue);
580
+ }
581
+ }
582
+
583
+ /*****************************************/
584
+ /* ExplodeFunction: H/L access routine */
585
+ /* for the explode$ function. */
586
+ /*****************************************/
587
+ void ExplodeFunction(
588
+ Environment *theEnv,
589
+ UDFContext *context,
590
+ UDFValue *returnValue)
591
+ {
592
+ UDFValue value;
593
+ Multifield *theMultifield;
594
+ size_t end;
595
+
596
+ /*==================================*/
597
+ /* The argument should be a string. */
598
+ /*==================================*/
599
+
600
+ if (! UDFFirstArgument(context,STRING_BIT,&value))
601
+ { return; }
602
+
603
+ /*=====================================*/
604
+ /* Convert the string to a multifield. */
605
+ /*=====================================*/
606
+
607
+ theMultifield = StringToMultifield(theEnv,value.lexemeValue->contents);
608
+ if (theMultifield == NULL)
609
+ {
610
+ theMultifield = CreateMultifield(theEnv,0L);
611
+ end = 0;
612
+ }
613
+ else
614
+ { end = theMultifield->length; }
615
+
616
+ /*========================*/
617
+ /* Return the multifield. */
618
+ /*========================*/
619
+
620
+ returnValue->begin = 0;
621
+ returnValue->range = end;
622
+ returnValue->value = theMultifield;
623
+ }
624
+
625
+ /*****************************************/
626
+ /* ImplodeFunction: H/L access routine */
627
+ /* for the implode$ function. */
628
+ /*****************************************/
629
+ void ImplodeFunction(
630
+ Environment *theEnv,
631
+ UDFContext *context,
632
+ UDFValue *returnValue)
633
+ {
634
+ UDFValue theArg;
635
+
636
+ /*======================================*/
637
+ /* The argument should be a multifield. */
638
+ /*======================================*/
639
+
640
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&theArg))
641
+ { return; }
642
+
643
+ /*====================*/
644
+ /* Return the string. */
645
+ /*====================*/
646
+
647
+ returnValue->value = ImplodeMultifield(theEnv,&theArg);
648
+ }
649
+
650
+ /****************************************/
651
+ /* SubseqFunction: H/L access routine */
652
+ /* for the subseq$ function. */
653
+ /****************************************/
654
+ void SubseqFunction(
655
+ Environment *theEnv,
656
+ UDFContext *context,
657
+ UDFValue *returnValue)
658
+ {
659
+ UDFValue theArg;
660
+ Multifield *theList;
661
+ long long start, end; /* 6.04 Bug Fix */
662
+ size_t offset, length;
663
+ size_t ustart, uend;
664
+
665
+ /*===================================*/
666
+ /* Get the segment to be subdivided. */
667
+ /*===================================*/
668
+
669
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&theArg))
670
+ { return; }
671
+
672
+ theList = theArg.multifieldValue;
673
+ offset = theArg.begin;
674
+ length = theArg.range;
675
+
676
+ /*=============================================*/
677
+ /* Get range arguments. If they are not within */
678
+ /* appropriate ranges, return a null segment. */
679
+ /*=============================================*/
680
+
681
+ if (! UDFNextArgument(context,INTEGER_BIT,&theArg))
682
+ { return; }
683
+
684
+ start = theArg.integerValue->contents;
685
+
686
+ if (! UDFNextArgument(context,INTEGER_BIT,&theArg))
687
+ { return; }
688
+
689
+ end = theArg.integerValue->contents;
690
+
691
+ if ((end < 1) || (end < start))
692
+ {
693
+ SetMultifieldErrorValue(theEnv,returnValue);
694
+ return;
695
+ }
696
+
697
+ /*==================================================*/
698
+ /* Adjust lengths to conform to segment boundaries. */
699
+ /*==================================================*/
700
+
701
+ if (start < 1) start = 1;
702
+
703
+ if (((long long) ((size_t) start)) == start)
704
+ { ustart = (size_t) start; }
705
+ else
706
+ { ustart = SIZE_MAX; }
707
+
708
+ if (ustart > length)
709
+ {
710
+ SetMultifieldErrorValue(theEnv,returnValue);
711
+ return;
712
+ }
713
+
714
+ if (((long long) ((size_t) end)) == end)
715
+ { uend = (size_t) end; }
716
+ else
717
+ { uend = SIZE_MAX; }
718
+
719
+ if (uend > length) uend = length;
720
+
721
+ /*=========================*/
722
+ /* Return the new segment. */
723
+ /*=========================*/
724
+
725
+ returnValue->value = theList;
726
+ returnValue->range = ((uend - ustart) + 1);
727
+ returnValue->begin = (offset + ustart - 1);
728
+ }
729
+
730
+ /***************************************/
731
+ /* FirstFunction: H/L access routine */
732
+ /* for the first$ function. */
733
+ /***************************************/
734
+ void FirstFunction(
735
+ Environment *theEnv,
736
+ UDFContext *context,
737
+ UDFValue *returnValue)
738
+ {
739
+ UDFValue theArg;
740
+ Multifield *theList;
741
+
742
+ /*===================================*/
743
+ /* Get the segment to be subdivided. */
744
+ /*===================================*/
745
+
746
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&theArg)) return;
747
+
748
+ theList = theArg.multifieldValue;
749
+
750
+ /*=========================*/
751
+ /* Return the new segment. */
752
+ /*=========================*/
753
+
754
+ returnValue->value = theList;
755
+ if (theArg.range >= 1)
756
+ { returnValue->range = 1; }
757
+ else
758
+ { returnValue->range = 0; }
759
+ returnValue->begin = theArg.begin;
760
+ }
761
+
762
+ /**************************************/
763
+ /* RestFunction: H/L access routine */
764
+ /* for the rest$ function. */
765
+ /**************************************/
766
+ void RestFunction(
767
+ Environment *theEnv,
768
+ UDFContext *context,
769
+ UDFValue *returnValue)
770
+ {
771
+ UDFValue theArg;
772
+ Multifield *theList;
773
+
774
+ /*===================================*/
775
+ /* Get the segment to be subdivided. */
776
+ /*===================================*/
777
+
778
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&theArg)) return;
779
+
780
+ theList = theArg.multifieldValue;
781
+
782
+ /*=========================*/
783
+ /* Return the new segment. */
784
+ /*=========================*/
785
+
786
+ returnValue->value = theList;
787
+
788
+ if (theArg.range > 0)
789
+ {
790
+ returnValue->begin = theArg.begin + 1;
791
+ returnValue->range = theArg.range - 1;
792
+ }
793
+ else
794
+ {
795
+ returnValue->begin = theArg.begin;
796
+ returnValue->range = theArg.range;
797
+ }
798
+ }
799
+
800
+ /*************************************/
801
+ /* NthFunction: H/L access routine */
802
+ /* for the nth$ function. */
803
+ /*************************************/
804
+ void NthFunction(
805
+ Environment *theEnv,
806
+ UDFContext *context,
807
+ UDFValue *returnValue)
808
+ {
809
+ UDFValue value1, value2;
810
+ Multifield *elm_ptr;
811
+ long long n; /* 6.04 Bug Fix */
812
+ size_t un;
813
+
814
+ if ((! UDFFirstArgument(context,INTEGER_BIT,&value1)) ||
815
+ (! UDFNextArgument(context,MULTIFIELD_BIT,&value2)))
816
+ { return; }
817
+
818
+ n = value1.integerValue->contents; /* 6.04 Bug Fix */
819
+
820
+ if (((long long) ((size_t) n)) != n)
821
+ {
822
+ returnValue->lexemeValue = CreateSymbol(theEnv,"nil");
823
+ return;
824
+ }
825
+ un = (size_t) n;
826
+
827
+ if ((un > value2.range) || (un < 1))
828
+ {
829
+ returnValue->lexemeValue = CreateSymbol(theEnv,"nil");
830
+ return;
831
+ }
832
+
833
+ elm_ptr = value2.multifieldValue;
834
+ returnValue->value = elm_ptr->contents[value2.begin + un - 1].value;
835
+ }
836
+
837
+ /* ------------------------------------------------------------------
838
+ * SubsetFunction:
839
+ * This function compares two multi-field variables
840
+ * to see if the first is a subset of the second. It
841
+ * does not consider order.
842
+ *
843
+ * INPUTS: Two arguments via argument stack. First is the sublist
844
+ * multi-field variable, the second is the list to be
845
+ * compared to. Both should be of type MULTIFIELD_TYPE.
846
+ *
847
+ * OUTPUTS: True if the first list is a subset of the
848
+ * second, else false
849
+ *
850
+ * NOTES: This function is called from H/L with the subset
851
+ * command. Repeated values in the sublist must also
852
+ * be repeated in the main list.
853
+ * ------------------------------------------------------------------
854
+ */
855
+
856
+ void SubsetpFunction(
857
+ Environment *theEnv,
858
+ UDFContext *context,
859
+ UDFValue *returnValue)
860
+ {
861
+ UDFValue item1, item2;
862
+ size_t i, j;
863
+ bool found;
864
+
865
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&item1))
866
+ { return; }
867
+
868
+ if (! UDFNextArgument(context,MULTIFIELD_BIT,&item2))
869
+ { return; }
870
+
871
+ if (item1.range == 0)
872
+ {
873
+ returnValue->lexemeValue = TrueSymbol(theEnv);
874
+ return;
875
+ }
876
+
877
+ if (item2.range == 0)
878
+ {
879
+ returnValue->lexemeValue = FalseSymbol(theEnv);
880
+ return;
881
+ }
882
+
883
+ for (i = item1.begin; i < (item1.begin + item1.range); i++)
884
+ {
885
+ found = false;
886
+
887
+ for (j = item2.begin; j < (item2.begin + item2.range); j++)
888
+ {
889
+ if (item1.multifieldValue->contents[i].value == item2.multifieldValue->contents[j].value)
890
+ {
891
+ found = true;
892
+ break;
893
+ }
894
+ }
895
+
896
+ if (! found)
897
+ {
898
+ returnValue->lexemeValue = FalseSymbol(theEnv);
899
+ return;
900
+ }
901
+ }
902
+
903
+ returnValue->lexemeValue = TrueSymbol(theEnv);
904
+ }
905
+
906
+ /**************************************/
907
+ /* MemberFunction: H/L access routine */
908
+ /* for the member$ function. */
909
+ /**************************************/
910
+ void MemberFunction(
911
+ Environment *theEnv,
912
+ UDFContext *context,
913
+ UDFValue *returnValue)
914
+ {
915
+ UDFValue item1, item2;
916
+ size_t i, pos;
917
+
918
+ returnValue->lexemeValue = FalseSymbol(theEnv);
919
+
920
+ if (! UDFFirstArgument(context,ANY_TYPE_BITS,&item1)) return;
921
+
922
+ if (! UDFNextArgument(context,MULTIFIELD_BIT,&item2)) return;
923
+
924
+ /*==========================================*/
925
+ /* Member sought is not a multifield value. */
926
+ /*==========================================*/
927
+
928
+ if (item1.header->type != MULTIFIELD_TYPE)
929
+ {
930
+ for (i = item2.begin; i < (item2.begin + item2.range); i++)
931
+ {
932
+ if (item1.value == item2.multifieldValue->contents[i].value)
933
+ {
934
+ returnValue->integerValue = CreateInteger(theEnv,(long long) (i + 1));
935
+ return;
936
+ }
937
+ }
938
+ return;
939
+ }
940
+
941
+ /*=====================================*/
942
+ /* Multifield sought can not be larger */
943
+ /* than the multifield being searched. */
944
+ /*=====================================*/
945
+
946
+ if (item1.range > item2.range) return;
947
+
948
+ /*================================================*/
949
+ /* Search for the first multifield in the second. */
950
+ /*================================================*/
951
+
952
+ pos = FindValueInMultifield(&item1,&item2);
953
+
954
+ if (pos == VALUE_NOT_FOUND) return;
955
+
956
+ if (item1.range == 1)
957
+ { returnValue->integerValue = CreateInteger(theEnv,(long long) (pos + 1)); }
958
+ else
959
+ {
960
+ returnValue->value = CreateMultifield(theEnv,2);
961
+ returnValue->multifieldValue->contents[0].integerValue = CreateInteger(theEnv,(long long) (pos + 1));
962
+ returnValue->multifieldValue->contents[1].integerValue = CreateInteger(theEnv,(long long) (pos + item1.range));
963
+ returnValue->begin = 0;
964
+ returnValue->range = 2;
965
+ }
966
+ }
967
+
968
+ /********************************************/
969
+ /* IntersectionFunction: H/L access routine */
970
+ /* for the intersection$ function. */
971
+ /********************************************/
972
+ /*
973
+ void IntersectionFunction2(
974
+ Environment *theEnv,
975
+ UDFContext *context,
976
+ UDFValue *returnValue)
977
+ {
978
+ CLIPSValue *valueArray;
979
+ UDFValue item1, item2;
980
+ size_t i, j, maxElements, actualElements = 0;
981
+ bool found;
982
+
983
+ // TBD Use HashMap to determine intersection
984
+
985
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&item1))
986
+ { return; }
987
+
988
+ if (! UDFNextArgument(context,MULTIFIELD_BIT,&item2))
989
+ { return; }
990
+
991
+ if ((item1.range == 0) ||
992
+ (item2.range == 0))
993
+ {
994
+ SetMultifieldErrorValue(theEnv,returnValue);
995
+ return;
996
+ }
997
+
998
+ if (item1.range >= item2.range)
999
+ { maxElements = item1.range; }
1000
+ else
1001
+ { maxElements = item2.range; }
1002
+
1003
+ valueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * maxElements);
1004
+
1005
+ for (i = item1.begin; i < (item1.begin + item1.range); i++)
1006
+ {
1007
+ found = false;
1008
+
1009
+ for (j = item2.begin; j < (item2.begin + item2.range); j++)
1010
+ {
1011
+ if (item1.multifieldValue->contents[i].value == item2.multifieldValue->contents[j].value)
1012
+ {
1013
+ found = true;
1014
+ break;
1015
+ }
1016
+ }
1017
+
1018
+ if (! found) continue;
1019
+
1020
+ found = false;
1021
+
1022
+ for (j = 0; j < actualElements; j++)
1023
+ {
1024
+ if (item1.multifieldValue->contents[i].value == valueArray[j].value)
1025
+ {
1026
+ found = true;
1027
+ break;
1028
+ }
1029
+ }
1030
+
1031
+ if (! found)
1032
+ {
1033
+ valueArray[actualElements].value = item1.multifieldValue->contents[i].value;
1034
+ actualElements++;
1035
+ }
1036
+
1037
+ if (actualElements == maxElements) break;
1038
+ }
1039
+
1040
+ returnValue->begin = 0;
1041
+ returnValue->range = actualElements;
1042
+ returnValue->multifieldValue = CreateMultifield(theEnv,actualElements);
1043
+
1044
+ for (i = 0; i < actualElements; i++)
1045
+ { returnValue->multifieldValue->contents[i].value = valueArray[i].value; }
1046
+
1047
+ rm(theEnv,valueArray,sizeof(CLIPSValue) * maxElements);
1048
+ }
1049
+ */
1050
+ /********************************************/
1051
+ /* IntersectionFunction: H/L access routine */
1052
+ /* for the intersection$ function. */
1053
+ /********************************************/
1054
+ void IntersectionFunction(
1055
+ Environment *theEnv,
1056
+ UDFContext *context,
1057
+ UDFValue *returnValue)
1058
+ {
1059
+ unsigned int numArgs, argIndex;
1060
+ UDFValue *theArgs;
1061
+ size_t i, j, maxElements = 0, actualElements = 0;
1062
+ CLIPSValue *valueArray;
1063
+ bool found;
1064
+
1065
+ /*====================================*/
1066
+ /* Determine the number of arguments. */
1067
+ /*====================================*/
1068
+
1069
+ numArgs = UDFArgumentCount(context);
1070
+
1071
+ /*==============================================*/
1072
+ /* If no arguments, return an empty multifield. */
1073
+ /*==============================================*/
1074
+
1075
+ if (numArgs == 0)
1076
+ {
1077
+ SetMultifieldErrorValue(theEnv,returnValue);
1078
+ return;
1079
+ }
1080
+
1081
+ /*===========================================*/
1082
+ /* Evaluate all of the multifield arguments. */
1083
+ /*===========================================*/
1084
+
1085
+ theArgs = (UDFValue *) gm1(theEnv,sizeof(UDFValue) * numArgs);
1086
+ for (argIndex = 0; argIndex < numArgs; argIndex++)
1087
+ {
1088
+ if (! UDFNthArgument(context,argIndex+1,MULTIFIELD_BIT,&theArgs[argIndex]))
1089
+ {
1090
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1091
+ SetMultifieldErrorValue(theEnv,returnValue);
1092
+ return;
1093
+ }
1094
+ }
1095
+
1096
+ /*=================================*/
1097
+ /* Determine the maximum number of */
1098
+ /* elements in the intersection. */
1099
+ /*=================================*/
1100
+
1101
+ maxElements = theArgs[0].range;
1102
+ for (argIndex = 0; argIndex < numArgs; argIndex++)
1103
+ {
1104
+ if (theArgs[argIndex].range < maxElements)
1105
+ { maxElements = theArgs[argIndex].range; }
1106
+ }
1107
+
1108
+ /*=========================================*/
1109
+ /* If any argument is an empty multifield, */
1110
+ /* return an empty multifield. */
1111
+ /*=========================================*/
1112
+
1113
+ if (maxElements == 0)
1114
+ {
1115
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1116
+ SetMultifieldErrorValue(theEnv,returnValue);
1117
+ return;
1118
+ }
1119
+
1120
+ /*===========================================================*/
1121
+ /* Allocate an array large enough to hold all of the values. */
1122
+ /*===========================================================*/
1123
+
1124
+ valueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * maxElements);
1125
+
1126
+ /*=====================================*/
1127
+ /* Copy values to the temporary array. */
1128
+ /*=====================================*/
1129
+
1130
+ for (i = theArgs[0].begin; i < (theArgs[0].begin + theArgs[0].range); i++)
1131
+ {
1132
+ found = true;
1133
+
1134
+ for (argIndex = 1; argIndex < numArgs; argIndex++)
1135
+ {
1136
+ found = false;
1137
+ for (j = theArgs[argIndex].begin; j < (theArgs[argIndex].begin + theArgs[argIndex].range); j++)
1138
+ {
1139
+ if (theArgs[0].multifieldValue->contents[i].value == theArgs[argIndex].multifieldValue->contents[j].value)
1140
+ {
1141
+ found = true;
1142
+ break;
1143
+ }
1144
+ }
1145
+
1146
+ if (! found) break;
1147
+ }
1148
+
1149
+ if (! found) continue;
1150
+
1151
+ found = false;
1152
+
1153
+ for (j = 0; j < actualElements; j++)
1154
+ {
1155
+ if (theArgs[0].multifieldValue->contents[i].value == valueArray[j].value)
1156
+ {
1157
+ found = true;
1158
+ break;
1159
+ }
1160
+ }
1161
+
1162
+ if (! found)
1163
+ {
1164
+ valueArray[actualElements].value = theArgs[0].multifieldValue->contents[i].value;
1165
+ actualElements++;
1166
+ }
1167
+ }
1168
+
1169
+ /*================================*/
1170
+ /* Create the final return value. */
1171
+ /*================================*/
1172
+
1173
+ returnValue->begin = 0;
1174
+ returnValue->range = actualElements;
1175
+ returnValue->multifieldValue = CreateMultifield(theEnv,actualElements);
1176
+
1177
+ for (i = 0; i < actualElements; i++)
1178
+ { returnValue->multifieldValue->contents[i].value = valueArray[i].value; }
1179
+
1180
+ /*==================================*/
1181
+ /* Deallocate the temporary arrays. */
1182
+ /*==================================*/
1183
+
1184
+ rm(theEnv,valueArray,sizeof(CLIPSValue) * maxElements);
1185
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1186
+ }
1187
+
1188
+ /*************************************/
1189
+ /* UnionFunction: H/L access routine */
1190
+ /* for the union$ function. */
1191
+ /*************************************/
1192
+ void UnionFunction(
1193
+ Environment *theEnv,
1194
+ UDFContext *context,
1195
+ UDFValue *returnValue)
1196
+ {
1197
+ unsigned int numArgs, argIndex;
1198
+ UDFValue *theArgs;
1199
+ size_t i, j, maxElements = 0, actualElements = 0;
1200
+ CLIPSValue *valueArray;
1201
+ bool found;
1202
+
1203
+ /*====================================*/
1204
+ /* Determine the number of arguments. */
1205
+ /*====================================*/
1206
+
1207
+ numArgs = UDFArgumentCount(context);
1208
+
1209
+ /*==============================================*/
1210
+ /* If no arguments, return an empty multifield. */
1211
+ /*==============================================*/
1212
+
1213
+ if (numArgs == 0)
1214
+ {
1215
+ SetMultifieldErrorValue(theEnv,returnValue);
1216
+ return;
1217
+ }
1218
+
1219
+ /*===========================================*/
1220
+ /* Evaluate all of the multifield arguments. */
1221
+ /*===========================================*/
1222
+
1223
+ theArgs = (UDFValue *) gm1(theEnv,sizeof(UDFValue) * numArgs);
1224
+ for (argIndex = 0; argIndex < numArgs; argIndex++)
1225
+ {
1226
+ if (! UDFNthArgument(context,argIndex+1,MULTIFIELD_BIT,&theArgs[argIndex]))
1227
+ {
1228
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1229
+ SetMultifieldErrorValue(theEnv,returnValue);
1230
+ return;
1231
+ }
1232
+
1233
+ maxElements += theArgs[argIndex].range;
1234
+ }
1235
+
1236
+ /*=========================================*/
1237
+ /* If all the multifield values contain no */
1238
+ /* elements, return an empty multifield. */
1239
+ /*=========================================*/
1240
+
1241
+ if (maxElements == 0)
1242
+ {
1243
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1244
+ SetMultifieldErrorValue(theEnv,returnValue);
1245
+ return;
1246
+ }
1247
+
1248
+ /*===========================================================*/
1249
+ /* Allocate an array large enough to hold all of the values. */
1250
+ /*===========================================================*/
1251
+
1252
+ valueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * maxElements);
1253
+
1254
+ /*=====================================*/
1255
+ /* Copy values to the temporary array. */
1256
+ /*=====================================*/
1257
+
1258
+ for (argIndex = 0; argIndex < numArgs; argIndex++)
1259
+ {
1260
+ for (i = theArgs[argIndex].begin; i < (theArgs[argIndex].begin + theArgs[argIndex].range); i++)
1261
+ {
1262
+ found = false;
1263
+
1264
+ for (j = 0; j < actualElements; j++)
1265
+ {
1266
+ if (theArgs[argIndex].multifieldValue->contents[i].value == valueArray[j].value)
1267
+ {
1268
+ found = true;
1269
+ break;
1270
+ }
1271
+ }
1272
+
1273
+ if (! found)
1274
+ {
1275
+ valueArray[actualElements].value = theArgs[argIndex].multifieldValue->contents[i].value;
1276
+ actualElements++;
1277
+ }
1278
+ }
1279
+ }
1280
+
1281
+ /*================================*/
1282
+ /* Create the final return value. */
1283
+ /*================================*/
1284
+
1285
+ returnValue->begin = 0;
1286
+ returnValue->range = actualElements;
1287
+ returnValue->multifieldValue = CreateMultifield(theEnv,actualElements);
1288
+
1289
+ for (i = 0; i < actualElements; i++)
1290
+ { returnValue->multifieldValue->contents[i].value = valueArray[i].value; }
1291
+
1292
+ /*==================================*/
1293
+ /* Deallocate the temporary arrays. */
1294
+ /*==================================*/
1295
+
1296
+ rm(theEnv,valueArray,sizeof(CLIPSValue) * maxElements);
1297
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1298
+ }
1299
+
1300
+ /******************************************/
1301
+ /* DifferenceFunction: H/L access routine */
1302
+ /* for the difference$ function. */
1303
+ /******************************************/
1304
+ void DifferenceFunction(
1305
+ Environment *theEnv,
1306
+ UDFContext *context,
1307
+ UDFValue *returnValue)
1308
+ {
1309
+ unsigned int numArgs, argIndex;
1310
+ UDFValue *theArgs;
1311
+ size_t i, j, maxElements = 0, actualElements = 0;
1312
+ CLIPSValue *valueArray;
1313
+ bool found;
1314
+
1315
+ /*====================================*/
1316
+ /* Determine the number of arguments. */
1317
+ /*====================================*/
1318
+
1319
+ numArgs = UDFArgumentCount(context);
1320
+
1321
+ /*===========================================*/
1322
+ /* Evaluate all of the multifield arguments. */
1323
+ /*===========================================*/
1324
+
1325
+ theArgs = (UDFValue *) gm1(theEnv,sizeof(UDFValue) * numArgs);
1326
+ for (argIndex = 0; argIndex < numArgs; argIndex++)
1327
+ {
1328
+ if (! UDFNthArgument(context,argIndex+1,MULTIFIELD_BIT,&theArgs[argIndex]))
1329
+ {
1330
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1331
+ SetMultifieldErrorValue(theEnv,returnValue);
1332
+ return;
1333
+ }
1334
+ }
1335
+
1336
+ maxElements = theArgs[0].range;
1337
+
1338
+ /*=========================================*/
1339
+ /* If the first multifield values contains */
1340
+ /* no elements, return an empty multifield. */
1341
+ /*=========================================*/
1342
+
1343
+ if (maxElements == 0)
1344
+ {
1345
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1346
+ SetMultifieldErrorValue(theEnv,returnValue);
1347
+ return;
1348
+ }
1349
+
1350
+ /*===========================================================*/
1351
+ /* Allocate an array large enough to hold all of the values. */
1352
+ /*===========================================================*/
1353
+
1354
+ valueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * maxElements);
1355
+
1356
+ /*=====================================*/
1357
+ /* Copy values to the temporary array. */
1358
+ /*=====================================*/
1359
+
1360
+ for (i = theArgs[0].begin; i < (theArgs[0].begin + theArgs[0].range); i++)
1361
+ {
1362
+ found = false;
1363
+ for (argIndex = 1; argIndex < numArgs; argIndex++)
1364
+ {
1365
+ for (j = theArgs[argIndex].begin; j < (theArgs[argIndex].begin + theArgs[argIndex].range); j++)
1366
+ {
1367
+ if (theArgs[0].multifieldValue->contents[i].value == theArgs[argIndex].multifieldValue->contents[j].value)
1368
+ {
1369
+ found = true;
1370
+ break;
1371
+ }
1372
+ }
1373
+
1374
+ if (found) break;
1375
+ }
1376
+
1377
+ if (found) continue;
1378
+
1379
+ found = false;
1380
+
1381
+ for (j = 0; j < actualElements; j++)
1382
+ {
1383
+ if (theArgs[0].multifieldValue->contents[i].value == valueArray[j].value)
1384
+ {
1385
+ found = true;
1386
+ break;
1387
+ }
1388
+ }
1389
+
1390
+ if (! found)
1391
+ {
1392
+ valueArray[actualElements].value = theArgs[0].multifieldValue->contents[i].value;
1393
+ actualElements++;
1394
+ }
1395
+ }
1396
+
1397
+ /*================================*/
1398
+ /* Create the final return value. */
1399
+ /*================================*/
1400
+
1401
+ returnValue->begin = 0;
1402
+ returnValue->range = actualElements;
1403
+ returnValue->multifieldValue = CreateMultifield(theEnv,actualElements);
1404
+
1405
+ for (i = 0; i < actualElements; i++)
1406
+ { returnValue->multifieldValue->contents[i].value = valueArray[i].value; }
1407
+
1408
+ /*==================================*/
1409
+ /* Deallocate the temporary arrays. */
1410
+ /*==================================*/
1411
+
1412
+ rm(theEnv,valueArray,sizeof(CLIPSValue) * maxElements);
1413
+ rm(theEnv,theArgs,sizeof(UDFValue) * numArgs);
1414
+ }
1415
+
1416
+ /**************************/
1417
+ /* FindValueInMultifield: */
1418
+ /**************************/
1419
+ size_t FindValueInMultifield(
1420
+ UDFValue *valueSought,
1421
+ UDFValue *multifieldToSearch)
1422
+ {
1423
+ size_t i, j;
1424
+ bool found;
1425
+
1426
+ /*==========================================*/
1427
+ /* Member sought is not a multifield value. */
1428
+ /*==========================================*/
1429
+
1430
+ if (valueSought->header->type != MULTIFIELD_TYPE)
1431
+ {
1432
+ for (i = multifieldToSearch->begin; i < (multifieldToSearch->begin + multifieldToSearch->range); i++)
1433
+ {
1434
+ if (valueSought->value == multifieldToSearch->multifieldValue->contents[i].value)
1435
+ { return i; }
1436
+ }
1437
+
1438
+ return VALUE_NOT_FOUND;
1439
+ }
1440
+
1441
+ /*=====================================*/
1442
+ /* Multifield sought can not be larger */
1443
+ /* than the multifield being searched. */
1444
+ /*=====================================*/
1445
+
1446
+ if (valueSought->range > multifieldToSearch->range) return VALUE_NOT_FOUND;
1447
+
1448
+ /*================================================*/
1449
+ /* Search for the first multifield in the second. */
1450
+ /*================================================*/
1451
+
1452
+ for (i = 0; i <= (multifieldToSearch->range - valueSought->range); i++)
1453
+ {
1454
+ found = true;
1455
+ for (j = 0; j < valueSought->range; j++)
1456
+ {
1457
+ if (valueSought->multifieldValue->contents[valueSought->begin+j].value !=
1458
+ multifieldToSearch->multifieldValue->contents[multifieldToSearch->begin+i+j].value)
1459
+ {
1460
+ found = false;
1461
+ break;
1462
+ }
1463
+ }
1464
+
1465
+ if (found)
1466
+ { return i; }
1467
+ }
1468
+
1469
+ return VALUE_NOT_FOUND;
1470
+ }
1471
+
1472
+ /*********************/
1473
+ /* FindDOsInSegment: */
1474
+ /*********************/
1475
+ /* 6.05 Bug Fix */
1476
+ bool FindDOsInSegment(
1477
+ UDFValue *searchDOs,
1478
+ unsigned int scnt,
1479
+ UDFValue *value,
1480
+ size_t *si,
1481
+ size_t *ei,
1482
+ size_t *excludes,
1483
+ unsigned int epaircnt)
1484
+ {
1485
+ size_t slen;
1486
+ unsigned int j;
1487
+ size_t i, k, mul_length;
1488
+
1489
+ mul_length = value->range;
1490
+ for (i = 0 ; i < mul_length ; i++)
1491
+ {
1492
+ for (j = 0 ; j < scnt ; j++)
1493
+ {
1494
+ if (searchDOs[j].header->type == MULTIFIELD_TYPE)
1495
+ {
1496
+ slen = searchDOs[j].range;
1497
+
1498
+ if (MVRangeCheck(i+1,i+slen,excludes,epaircnt))
1499
+ {
1500
+ for (k = 0L ; (k < slen) && ((k + i) < mul_length) ; k++)
1501
+ if (searchDOs[j].multifieldValue->contents[k+searchDOs[j].begin].value !=
1502
+ value->multifieldValue->contents[k+i+value->begin].value)
1503
+ break;
1504
+ if (k >= slen)
1505
+ {
1506
+ *si = i + 1;
1507
+ *ei = i + slen;
1508
+ return true;
1509
+ }
1510
+ }
1511
+ }
1512
+ else if ((searchDOs[j].value == value->multifieldValue->contents[i + value->begin].value) &&
1513
+ MVRangeCheck(i+1L,i+1L,excludes,epaircnt))
1514
+ {
1515
+ *si = *ei = i + 1;
1516
+ return true;
1517
+ }
1518
+ }
1519
+ }
1520
+
1521
+ return false;
1522
+ }
1523
+
1524
+ /*****************/
1525
+ /* MVRangeCheck: */
1526
+ /*****************/
1527
+ static bool MVRangeCheck(
1528
+ size_t si,
1529
+ size_t ei,
1530
+ size_t *elist,
1531
+ unsigned int epaircnt)
1532
+ {
1533
+ unsigned int i;
1534
+
1535
+ if (!elist || !epaircnt)
1536
+ return true;
1537
+ for (i = 0 ; i < epaircnt ; i++)
1538
+ if (((si >= elist[i*2]) && (si <= elist[i*2+1])) ||
1539
+ ((ei >= elist[i*2]) && (ei <= elist[i*2+1])))
1540
+ return false;
1541
+
1542
+ return true;
1543
+ }
1544
+
1545
+ #if (! BLOAD_ONLY)
1546
+
1547
+ /******************************************************/
1548
+ /* MultifieldPrognParser: Parses the progn$ function. */
1549
+ /******************************************************/
1550
+ static struct expr *MultifieldPrognParser(
1551
+ Environment *theEnv,
1552
+ struct expr *top,
1553
+ const char *infile)
1554
+ {
1555
+ struct BindInfo *oldBindList, *newBindList, *prev;
1556
+ struct token tkn;
1557
+ struct expr *tmp;
1558
+ CLIPSLexeme *fieldVar = NULL;
1559
+ size_t flen = 0;
1560
+
1561
+ SavePPBuffer(theEnv," ");
1562
+ GetToken(theEnv,infile,&tkn);
1563
+
1564
+ /* ================================
1565
+ Simple form: progn$ <mf-exp> ...
1566
+ ================================ */
1567
+ if (tkn.tknType != LEFT_PARENTHESIS_TOKEN)
1568
+ {
1569
+ top->argList = ParseAtomOrExpression(theEnv,infile,&tkn);
1570
+ if (top->argList == NULL)
1571
+ {
1572
+ ReturnExpression(theEnv,top);
1573
+ return NULL;
1574
+ }
1575
+ }
1576
+ else
1577
+ {
1578
+ GetToken(theEnv,infile,&tkn);
1579
+ if (tkn.tknType != SF_VARIABLE_TOKEN)
1580
+ {
1581
+ if (tkn.tknType != SYMBOL_TOKEN)
1582
+ goto MvPrognParseError;
1583
+ top->argList = Function2Parse(theEnv,infile,tkn.lexemeValue->contents);
1584
+ if (top->argList == NULL)
1585
+ {
1586
+ ReturnExpression(theEnv,top);
1587
+ return NULL;
1588
+ }
1589
+ }
1590
+
1591
+ /* =========================================
1592
+ Complex form: progn$ (<var> <mf-exp>) ...
1593
+ ========================================= */
1594
+ else
1595
+ {
1596
+ fieldVar = tkn.lexemeValue;
1597
+ SavePPBuffer(theEnv," ");
1598
+ top->argList = ParseAtomOrExpression(theEnv,infile,NULL);
1599
+ if (top->argList == NULL)
1600
+ {
1601
+ ReturnExpression(theEnv,top);
1602
+ return NULL;
1603
+ }
1604
+ GetToken(theEnv,infile,&tkn);
1605
+ if (tkn.tknType != RIGHT_PARENTHESIS_TOKEN)
1606
+ goto MvPrognParseError;
1607
+ PPBackup(theEnv);
1608
+ /* PPBackup(theEnv); */
1609
+ SavePPBuffer(theEnv,tkn.printForm);
1610
+ SavePPBuffer(theEnv," ");
1611
+ }
1612
+ }
1613
+
1614
+ if (CheckArgumentAgainstRestriction(theEnv,top->argList,MULTIFIELD_BIT))
1615
+ goto MvPrognParseError;
1616
+
1617
+ oldBindList = GetParsedBindNames(theEnv);
1618
+ SetParsedBindNames(theEnv,NULL);
1619
+ IncrementIndentDepth(theEnv,3);
1620
+ ExpressionData(theEnv)->BreakContext = true;
1621
+ ExpressionData(theEnv)->ReturnContext = ExpressionData(theEnv)->svContexts->rtn;
1622
+ PPCRAndIndent(theEnv);
1623
+ top->argList->nextArg = GroupActions(theEnv,infile,&tkn,true,NULL,false);
1624
+ DecrementIndentDepth(theEnv,3);
1625
+ PPBackup(theEnv);
1626
+ PPBackup(theEnv);
1627
+ SavePPBuffer(theEnv,tkn.printForm);
1628
+ if (top->argList->nextArg == NULL)
1629
+ {
1630
+ ClearParsedBindNames(theEnv);
1631
+ SetParsedBindNames(theEnv,oldBindList);
1632
+ ReturnExpression(theEnv,top);
1633
+ return NULL;
1634
+ }
1635
+ tmp = top->argList->nextArg;
1636
+ top->argList->nextArg = tmp->argList;
1637
+ tmp->argList = NULL;
1638
+ ReturnExpression(theEnv,tmp);
1639
+ newBindList = GetParsedBindNames(theEnv);
1640
+ prev = NULL;
1641
+ if (fieldVar != NULL)
1642
+ { flen = strlen(fieldVar->contents); }
1643
+
1644
+ while (newBindList != NULL)
1645
+ {
1646
+ if ((fieldVar == NULL) ? false :
1647
+ (((strncmp(newBindList->name->contents,fieldVar->contents,flen) == 0) &&
1648
+ (strcmp(newBindList->name->contents+flen,"-index") == 0)) ||
1649
+ (strcmp(newBindList->name->contents,fieldVar->contents) == 0)))
1650
+ {
1651
+ ClearParsedBindNames(theEnv);
1652
+ SetParsedBindNames(theEnv,oldBindList);
1653
+ PrintErrorID(theEnv,"MULTIFUN",2,false);
1654
+ WriteString(theEnv,STDERR,"Cannot rebind field variable in function 'progn$'.\n");
1655
+ ReturnExpression(theEnv,top);
1656
+ return NULL;
1657
+ }
1658
+ prev = newBindList;
1659
+ newBindList = newBindList->next;
1660
+ }
1661
+ if (prev == NULL)
1662
+ SetParsedBindNames(theEnv,oldBindList);
1663
+ else
1664
+ prev->next = oldBindList;
1665
+ if (fieldVar != NULL)
1666
+ ReplaceMvPrognFieldVars(theEnv,fieldVar,top->argList->nextArg,0);
1667
+ return(top);
1668
+
1669
+ MvPrognParseError:
1670
+ SyntaxErrorMessage(theEnv,"progn$");
1671
+ ReturnExpression(theEnv,top);
1672
+ return NULL;
1673
+ }
1674
+
1675
+ /***********************************************/
1676
+ /* ForeachParser: Parses the foreach function. */
1677
+ /***********************************************/
1678
+ static struct expr *ForeachParser(
1679
+ Environment *theEnv,
1680
+ struct expr *top,
1681
+ const char *infile)
1682
+ {
1683
+ struct BindInfo *oldBindList,*newBindList,*prev;
1684
+ struct token tkn;
1685
+ struct expr *tmp;
1686
+ CLIPSLexeme *fieldVar;
1687
+ size_t flen = 0;
1688
+
1689
+ SavePPBuffer(theEnv," ");
1690
+ GetToken(theEnv,infile,&tkn);
1691
+
1692
+ if (tkn.tknType != SF_VARIABLE_TOKEN)
1693
+ { goto ForeachParseError; }
1694
+
1695
+ fieldVar = tkn.lexemeValue;
1696
+ SavePPBuffer(theEnv," ");
1697
+ top->argList = ParseAtomOrExpression(theEnv,infile,NULL);
1698
+ if (top->argList == NULL)
1699
+ {
1700
+ ReturnExpression(theEnv,top);
1701
+ return NULL;
1702
+ }
1703
+
1704
+ if (CheckArgumentAgainstRestriction(theEnv,top->argList,MULTIFIELD_BIT))
1705
+ goto ForeachParseError;
1706
+
1707
+ oldBindList = GetParsedBindNames(theEnv);
1708
+ SetParsedBindNames(theEnv,NULL);
1709
+ IncrementIndentDepth(theEnv,3);
1710
+ ExpressionData(theEnv)->BreakContext = true;
1711
+ ExpressionData(theEnv)->ReturnContext = ExpressionData(theEnv)->svContexts->rtn;
1712
+ PPCRAndIndent(theEnv);
1713
+ top->argList->nextArg = GroupActions(theEnv,infile,&tkn,true,NULL,false);
1714
+ DecrementIndentDepth(theEnv,3);
1715
+ PPBackup(theEnv);
1716
+ PPBackup(theEnv);
1717
+ SavePPBuffer(theEnv,tkn.printForm);
1718
+ if (top->argList->nextArg == NULL)
1719
+ {
1720
+ ClearParsedBindNames(theEnv);
1721
+ SetParsedBindNames(theEnv,oldBindList);
1722
+ ReturnExpression(theEnv,top);
1723
+ return NULL;
1724
+ }
1725
+ tmp = top->argList->nextArg;
1726
+ top->argList->nextArg = tmp->argList;
1727
+ tmp->argList = NULL;
1728
+ ReturnExpression(theEnv,tmp);
1729
+ newBindList = GetParsedBindNames(theEnv);
1730
+ prev = NULL;
1731
+ if (fieldVar != NULL)
1732
+ { flen = strlen(fieldVar->contents); }
1733
+
1734
+ while (newBindList != NULL)
1735
+ {
1736
+ if ((fieldVar == NULL) ? false :
1737
+ (((strncmp(newBindList->name->contents,fieldVar->contents,flen) == 0) &&
1738
+ (strcmp(newBindList->name->contents+flen,"-index") == 0)) ||
1739
+ (strcmp(newBindList->name->contents,fieldVar->contents) == 0)))
1740
+ {
1741
+ ClearParsedBindNames(theEnv);
1742
+ SetParsedBindNames(theEnv,oldBindList);
1743
+ PrintErrorID(theEnv,"MULTIFUN",2,false);
1744
+ WriteString(theEnv,STDERR,"Cannot rebind field variable in function 'foreach'.\n");
1745
+ ReturnExpression(theEnv,top);
1746
+ return NULL;
1747
+ }
1748
+ prev = newBindList;
1749
+ newBindList = newBindList->next;
1750
+ }
1751
+ if (prev == NULL)
1752
+ SetParsedBindNames(theEnv,oldBindList);
1753
+ else
1754
+ prev->next = oldBindList;
1755
+ if (fieldVar != NULL)
1756
+ ReplaceMvPrognFieldVars(theEnv,fieldVar,top->argList->nextArg,0);
1757
+ return(top);
1758
+
1759
+ ForeachParseError:
1760
+ SyntaxErrorMessage(theEnv,"foreach");
1761
+ ReturnExpression(theEnv,top);
1762
+ return NULL;
1763
+ }
1764
+
1765
+ /**********************************************/
1766
+ /* ReplaceMvPrognFieldVars: Replaces variable */
1767
+ /* references found in the progn$ function. */
1768
+ /**********************************************/
1769
+ static void ReplaceMvPrognFieldVars(
1770
+ Environment *theEnv,
1771
+ CLIPSLexeme *fieldVar,
1772
+ struct expr *theExp,
1773
+ int depth)
1774
+ {
1775
+ size_t flen;
1776
+
1777
+ flen = strlen(fieldVar->contents);
1778
+ while (theExp != NULL)
1779
+ {
1780
+ if ((theExp->type != SF_VARIABLE) ? false :
1781
+ (strncmp(theExp->lexemeValue->contents,fieldVar->contents,
1782
+ (STD_SIZE) flen) == 0))
1783
+ {
1784
+ if (theExp->lexemeValue->contents[flen] == '\0')
1785
+ {
1786
+ theExp->type = FCALL;
1787
+ theExp->value = FindFunction(theEnv,"(get-progn$-field)");
1788
+ theExp->argList = GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,depth));
1789
+ }
1790
+ else if (strcmp(theExp->lexemeValue->contents + flen,"-index") == 0)
1791
+ {
1792
+ theExp->type = FCALL;
1793
+ theExp->value = FindFunction(theEnv,"(get-progn$-index)");
1794
+ theExp->argList = GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,depth));
1795
+ }
1796
+ }
1797
+ else if (theExp->argList != NULL)
1798
+ {
1799
+ if ((theExp->type == FCALL) && ((theExp->value == (void *) FindFunction(theEnv,"progn$")) ||
1800
+ (theExp->value == (void *) FindFunction(theEnv,"foreach")) ))
1801
+ ReplaceMvPrognFieldVars(theEnv,fieldVar,theExp->argList,depth+1);
1802
+ else
1803
+ ReplaceMvPrognFieldVars(theEnv,fieldVar,theExp->argList,depth);
1804
+ }
1805
+ theExp = theExp->nextArg;
1806
+ }
1807
+ }
1808
+
1809
+ #endif /* (! BLOAD_ONLY) */
1810
+
1811
+ /*****************************************/
1812
+ /* MultifieldPrognFunction: H/L access */
1813
+ /* routine for the progn$ function. */
1814
+ /*****************************************/
1815
+ void MultifieldPrognFunction(
1816
+ Environment *theEnv,
1817
+ UDFContext *context,
1818
+ UDFValue *returnValue)
1819
+ {
1820
+ MultifieldPrognDriver(context,returnValue,"progn$");
1821
+ }
1822
+
1823
+ /***************************************/
1824
+ /* ForeachFunction: H/L access routine */
1825
+ /* for the foreach function. */
1826
+ /***************************************/
1827
+ void ForeachFunction(
1828
+ Environment *theEnv,
1829
+ UDFContext *context,
1830
+ UDFValue *returnValue)
1831
+ {
1832
+ MultifieldPrognDriver(context,returnValue,"foreach");
1833
+ }
1834
+
1835
+ /*******************************************/
1836
+ /* MultifieldPrognDriver: Driver routine */
1837
+ /* for the progn$ and foreach functions. */
1838
+ /******************************************/
1839
+ static void MultifieldPrognDriver(
1840
+ UDFContext *context,
1841
+ UDFValue *returnValue,
1842
+ const char *functionName)
1843
+ {
1844
+ Expression *theExp;
1845
+ UDFValue argval;
1846
+ size_t i, end;
1847
+ FIELD_VAR_STACK *tmpField;
1848
+ GCBlock gcb;
1849
+ Environment *theEnv = context->environment;
1850
+
1851
+ tmpField = get_struct(theEnv,fieldVarStack);
1852
+ tmpField->type = SYMBOL_TYPE;
1853
+ tmpField->value = FalseSymbol(theEnv);
1854
+ tmpField->nxt = MultiFunctionData(theEnv)->FieldVarStack;
1855
+ MultiFunctionData(theEnv)->FieldVarStack = tmpField;
1856
+ returnValue->value = FalseSymbol(theEnv);
1857
+
1858
+ if (! UDFFirstArgument(context,MULTIFIELD_BIT,&argval))
1859
+ {
1860
+ MultiFunctionData(theEnv)->FieldVarStack = tmpField->nxt;
1861
+ rtn_struct(theEnv,fieldVarStack,tmpField);
1862
+ returnValue->value = FalseSymbol(theEnv);
1863
+ return;
1864
+ }
1865
+
1866
+ GCBlockStart(theEnv,&gcb);
1867
+
1868
+ end = argval.begin + argval.range;
1869
+ for (i = argval.begin; i < end; i++)
1870
+ {
1871
+ tmpField->type = argval.multifieldValue->contents[i].header->type;
1872
+ tmpField->value = argval.multifieldValue->contents[i].value;
1873
+ tmpField->index = 1 + i - argval.begin;
1874
+ for (theExp = GetFirstArgument()->nextArg ; theExp != NULL ; theExp = theExp->nextArg)
1875
+ {
1876
+ EvaluateExpression(theEnv,theExp,returnValue);
1877
+
1878
+ if (EvaluationData(theEnv)->HaltExecution || ProcedureFunctionData(theEnv)->BreakFlag || ProcedureFunctionData(theEnv)->ReturnFlag)
1879
+ {
1880
+ ProcedureFunctionData(theEnv)->BreakFlag = false;
1881
+ if (EvaluationData(theEnv)->HaltExecution)
1882
+ {
1883
+ returnValue->value = FalseSymbol(theEnv);
1884
+ }
1885
+ MultiFunctionData(theEnv)->FieldVarStack = tmpField->nxt;
1886
+ rtn_struct(theEnv,fieldVarStack,tmpField);
1887
+ GCBlockEndUDF(theEnv,&gcb,returnValue);
1888
+ return;
1889
+ }
1890
+
1891
+ /*===================================*/
1892
+ /* Garbage collect if this isn't the */
1893
+ /* last evaluation of the progn$. */
1894
+ /*===================================*/
1895
+
1896
+ if (((i + 1) < end) || (theExp->nextArg != NULL))
1897
+ {
1898
+ CleanCurrentGarbageFrame(theEnv,NULL);
1899
+ CallPeriodicTasks(theEnv);
1900
+ }
1901
+ }
1902
+ }
1903
+
1904
+ ProcedureFunctionData(theEnv)->BreakFlag = false;
1905
+ MultiFunctionData(theEnv)->FieldVarStack = tmpField->nxt;
1906
+ rtn_struct(theEnv,fieldVarStack,tmpField);
1907
+
1908
+ GCBlockEndUDF(theEnv,&gcb,returnValue);
1909
+ CallPeriodicTasks(theEnv);
1910
+ }
1911
+
1912
+ /*******************/
1913
+ /* GetMvPrognField */
1914
+ /*******************/
1915
+ void GetMvPrognField(
1916
+ Environment *theEnv,
1917
+ UDFContext *context,
1918
+ UDFValue *returnValue)
1919
+ {
1920
+ long long depth;
1921
+ FIELD_VAR_STACK *tmpField;
1922
+
1923
+ depth = GetFirstArgument()->integerValue->contents;
1924
+ tmpField = MultiFunctionData(theEnv)->FieldVarStack;
1925
+ while (depth > 0)
1926
+ {
1927
+ tmpField = tmpField->nxt;
1928
+ depth--;
1929
+ }
1930
+ returnValue->value = tmpField->value;
1931
+ }
1932
+
1933
+ /*******************/
1934
+ /* GetMvPrognIndex */
1935
+ /*******************/
1936
+ void GetMvPrognIndex(
1937
+ Environment *theEnv,
1938
+ UDFContext *context,
1939
+ UDFValue *returnValue)
1940
+ {
1941
+ long long depth;
1942
+ FIELD_VAR_STACK *tmpField;
1943
+
1944
+ depth = GetFirstArgument()->integerValue->contents;
1945
+ tmpField = MultiFunctionData(theEnv)->FieldVarStack;
1946
+ while (depth > 0)
1947
+ {
1948
+ tmpField = tmpField->nxt;
1949
+ depth--;
1950
+ }
1951
+
1952
+ returnValue->integerValue = CreateInteger(theEnv,(long long) tmpField->index);
1953
+ }
1954
+
1955
+ #endif /* MULTIFIELD_FUNCTIONS */
1956
+
1957
+ #if OBJECT_SYSTEM || MULTIFIELD_FUNCTIONS
1958
+
1959
+ bool ReplaceMultiValueFieldSizet(
1960
+ Environment *theEnv,
1961
+ UDFValue *dst,
1962
+ UDFValue *src,
1963
+ size_t rb,
1964
+ size_t re,
1965
+ UDFValue *field,
1966
+ const char *funcName)
1967
+ {
1968
+ size_t i, j, k;
1969
+ CLIPSValue *deptr;
1970
+ CLIPSValue *septr;
1971
+ size_t srclen, dstlen;
1972
+ size_t urb, ure;
1973
+
1974
+ srclen = ((src != NULL) ? src->range : 0);
1975
+ if ((re < rb) ||
1976
+ (rb < 1) || (re < 1) ||
1977
+ (rb > srclen) || (re > srclen))
1978
+ {
1979
+ MVRangeErrorSizet(theEnv,rb,re,srclen,funcName);
1980
+ return false;
1981
+ }
1982
+
1983
+ rb = src->begin + rb - 1;
1984
+ re = src->begin + re - 1;
1985
+
1986
+ if (field->header->type == MULTIFIELD_TYPE)
1987
+ dstlen = (size_t) (srclen + field->range - (re-rb+1));
1988
+ else
1989
+ dstlen = (size_t) (srclen + 1 - (re-rb+1));
1990
+ dst->begin = 0;
1991
+ dst->value = CreateMultifield(theEnv,dstlen);
1992
+ dst->range = dstlen;
1993
+
1994
+ urb = (size_t) rb;
1995
+ ure = (size_t) re;
1996
+
1997
+ for (i = 0 , j = src->begin ; j < urb ; i++ , j++)
1998
+ {
1999
+ deptr = &dst->multifieldValue->contents[i];
2000
+ septr = &src->multifieldValue->contents[j];
2001
+ deptr->value = septr->value;
2002
+ }
2003
+ if (field->header->type != MULTIFIELD_TYPE)
2004
+ {
2005
+ deptr = &dst->multifieldValue->contents[i++];
2006
+ deptr->value = field->value;
2007
+ }
2008
+ else
2009
+ {
2010
+ for (k = field->begin ; k < (field->begin + field->range) ; k++ , i++)
2011
+ {
2012
+ deptr = &dst->multifieldValue->contents[i];
2013
+ septr = &field->multifieldValue->contents[k];
2014
+ deptr->value = septr->value;
2015
+ }
2016
+ }
2017
+ while (j < ure)
2018
+ j++;
2019
+ for (j++ ; i < dstlen ; i++ , j++)
2020
+ {
2021
+ deptr = &dst->multifieldValue->contents[i];
2022
+ septr = &src->multifieldValue->contents[j];
2023
+ deptr->value = septr->value;
2024
+ }
2025
+ return true;
2026
+ }
2027
+
2028
+ /**************************************************************************
2029
+ NAME : InsertMultiValueField
2030
+ DESCRIPTION : Performs an insert on the src multi-field value
2031
+ storing the results in the dst multi-field value
2032
+ INPUTS : 1) The destination value buffer
2033
+ 2) The source value (can be NULL)
2034
+ 3) The index for the change
2035
+ 4) The new field value
2036
+ RETURNS : True if successful, false otherwise
2037
+ SIDE EFFECTS : Allocates and sets a ephemeral segment (even if new
2038
+ number of fields is 0)
2039
+ Src value segment is not changed
2040
+ NOTES : index is NOT guaranteed to be valid
2041
+ src is guaranteed to be a multi-field variable or NULL
2042
+ **************************************************************************/
2043
+ bool InsertMultiValueField(
2044
+ Environment *theEnv,
2045
+ UDFValue *dst,
2046
+ UDFValue *src,
2047
+ size_t theIndex,
2048
+ UDFValue *field,
2049
+ const char *funcName)
2050
+ {
2051
+ size_t i, j, k;
2052
+ CLIPSValue *deptr, *septr;
2053
+ size_t srclen, dstlen;
2054
+
2055
+ srclen = ((src != NULL) ? src->range : 0);
2056
+
2057
+ if (theIndex > (srclen + 1))
2058
+ { theIndex = (srclen + 1); }
2059
+
2060
+ dst->begin = 0;
2061
+ if (src == NULL)
2062
+ {
2063
+ if (field->header->type == MULTIFIELD_TYPE)
2064
+ {
2065
+ DuplicateMultifield(theEnv,dst,field);
2066
+ AddToMultifieldList(theEnv,dst->multifieldValue);
2067
+ }
2068
+ else
2069
+ {
2070
+ dst->value = CreateMultifield(theEnv,0L);
2071
+ dst->range = 1;
2072
+ deptr = &dst->multifieldValue->contents[0];
2073
+ deptr->value = field->value;
2074
+ }
2075
+ return true;
2076
+ }
2077
+ dstlen = (field->header->type == MULTIFIELD_TYPE) ? field->range + srclen : srclen + 1;
2078
+ dst->value = CreateMultifield(theEnv,dstlen);
2079
+ dst->range = dstlen;
2080
+ theIndex--;
2081
+ for (i = 0 , j = src->begin ; i < (size_t) theIndex ; i++ , j++)
2082
+ {
2083
+ deptr = &dst->multifieldValue->contents[i];
2084
+ septr = &src->multifieldValue->contents[j];
2085
+ deptr->value = septr->value;
2086
+ }
2087
+ if (field->header->type != MULTIFIELD_TYPE)
2088
+ {
2089
+ deptr = &dst->multifieldValue->contents[theIndex];
2090
+ deptr->value = field->value;
2091
+ i++;
2092
+ }
2093
+ else
2094
+ {
2095
+ for (k = field->begin ; k < (field->begin + field->range) ; k++ , i++)
2096
+ {
2097
+ deptr = &dst->multifieldValue->contents[i];
2098
+ septr = &field->multifieldValue->contents[k];
2099
+ deptr->value = septr->value;
2100
+ }
2101
+ }
2102
+ for ( ; j < (src->begin + src->range) ; i++ , j++)
2103
+ {
2104
+ deptr = &dst->multifieldValue->contents[i];
2105
+ septr = &src->multifieldValue->contents[j];
2106
+ deptr->value = septr->value;
2107
+ }
2108
+ return true;
2109
+ }
2110
+
2111
+ /*******************************************************
2112
+ NAME : MVRangeError
2113
+ DESCRIPTION : Prints out an error messages for index
2114
+ out-of-range errors in multi-field
2115
+ access functions
2116
+ INPUTS : 1) The bad range start
2117
+ 2) The bad range end
2118
+ 3) The max end of the range (min is
2119
+ assumed to be 1)
2120
+ RETURNS : Nothing useful
2121
+ SIDE EFFECTS : None
2122
+ NOTES : None
2123
+ ******************************************************/
2124
+ void MVRangeError(
2125
+ Environment *theEnv,
2126
+ long long brb,
2127
+ long long bre,
2128
+ size_t max,
2129
+ const char *funcName)
2130
+ {
2131
+ PrintErrorID(theEnv,"MULTIFUN",1,false);
2132
+ WriteString(theEnv,STDERR,"Multifield index ");
2133
+ if (brb == bre)
2134
+ WriteInteger(theEnv,STDERR,brb);
2135
+ else
2136
+ {
2137
+ WriteString(theEnv,STDERR,"range ");
2138
+ WriteInteger(theEnv,STDERR,brb);
2139
+ WriteString(theEnv,STDERR,"..");
2140
+ WriteInteger(theEnv,STDERR,bre);
2141
+ }
2142
+ WriteString(theEnv,STDERR," out of range 1..");
2143
+ PrintUnsignedInteger(theEnv,STDERR,max);
2144
+ if (funcName != NULL)
2145
+ {
2146
+ WriteString(theEnv,STDERR," in function '");
2147
+ WriteString(theEnv,STDERR,funcName);
2148
+ WriteString(theEnv,STDERR,"'");
2149
+ }
2150
+ WriteString(theEnv,STDERR,".\n");
2151
+ }
2152
+
2153
+ static void MVRangeErrorSizet(
2154
+ Environment *theEnv,
2155
+ size_t brb,
2156
+ size_t bre,
2157
+ size_t max,
2158
+ const char *funcName)
2159
+ {
2160
+ PrintErrorID(theEnv,"MULTIFUN",1,false);
2161
+ WriteString(theEnv,STDERR,"Multifield index ");
2162
+ if (brb == bre)
2163
+ PrintUnsignedInteger(theEnv,STDERR,brb);
2164
+ else
2165
+ {
2166
+ WriteString(theEnv,STDERR,"range ");
2167
+ PrintUnsignedInteger(theEnv,STDERR,brb);
2168
+ WriteString(theEnv,STDERR,"..");
2169
+ PrintUnsignedInteger(theEnv,STDERR,bre);
2170
+ }
2171
+ WriteString(theEnv,STDERR," out of range 1..");
2172
+ PrintUnsignedInteger(theEnv,STDERR,max);
2173
+ if (funcName != NULL)
2174
+ {
2175
+ WriteString(theEnv,STDERR," in function '");
2176
+ WriteString(theEnv,STDERR,funcName);
2177
+ WriteString(theEnv,STDERR,"'");
2178
+ }
2179
+ WriteString(theEnv,STDERR,".\n");
2180
+ }
2181
+
2182
+ #endif /* OBJECT_SYSTEM || MULTIFIELD_FUNCTIONS */