el4r 1.0.4

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 (249) hide show
  1. data/BUGS +2 -0
  2. data/Changes +2412 -0
  3. data/bin/el4r +26 -0
  4. data/bin/el4r-instance +1105 -0
  5. data/bin/el4r-rctool +279 -0
  6. data/bin/el4r-runtest +26 -0
  7. data/data/emacs/site-lisp/el4r.el +441 -0
  8. data/doc/classes/El4r.html +200 -0
  9. data/doc/classes/El4r.src/M000004.html +25 -0
  10. data/doc/classes/El4r.src/M000005.html +25 -0
  11. data/doc/classes/El4r.src/M000006.html +18 -0
  12. data/doc/classes/El4r.src/M000008.html +25 -0
  13. data/doc/classes/El4r.src/M000009.html +18 -0
  14. data/doc/classes/El4r/ELConsCell.html +145 -0
  15. data/doc/classes/El4r/ELConsCell.src/M000044.html +16 -0
  16. data/doc/classes/El4r/ELConsCell.src/M000046.html +16 -0
  17. data/doc/classes/El4r/ELConsCell.src/M000050.html +16 -0
  18. data/doc/classes/El4r/ELInstance.html +755 -0
  19. data/doc/classes/El4r/ELInstance.src/M000046.html +36 -0
  20. data/doc/classes/El4r/ELInstance.src/M000047.html +41 -0
  21. data/doc/classes/El4r/ELInstance.src/M000048.html +31 -0
  22. data/doc/classes/El4r/ELInstance.src/M000049.html +22 -0
  23. data/doc/classes/El4r/ELInstance.src/M000050.html +25 -0
  24. data/doc/classes/El4r/ELInstance.src/M000051.html +35 -0
  25. data/doc/classes/El4r/ELInstance.src/M000052.html +31 -0
  26. data/doc/classes/El4r/ELInstance.src/M000053.html +23 -0
  27. data/doc/classes/El4r/ELInstance.src/M000054.html +41 -0
  28. data/doc/classes/El4r/ELInstance.src/M000055.html +31 -0
  29. data/doc/classes/El4r/ELInstance.src/M000056.html +43 -0
  30. data/doc/classes/El4r/ELInstance.src/M000057.html +31 -0
  31. data/doc/classes/El4r/ELInstance.src/M000058.html +22 -0
  32. data/doc/classes/El4r/ELInstance.src/M000059.html +25 -0
  33. data/doc/classes/El4r/ELInstance.src/M000060.html +43 -0
  34. data/doc/classes/El4r/ELInstance.src/M000061.html +31 -0
  35. data/doc/classes/El4r/ELInstance.src/M000062.html +22 -0
  36. data/doc/classes/El4r/ELInstance.src/M000063.html +25 -0
  37. data/doc/classes/El4r/ELInstance.src/M000064.html +35 -0
  38. data/doc/classes/El4r/ELInstance.src/M000065.html +23 -0
  39. data/doc/classes/El4r/ELInstance.src/M000066.html +23 -0
  40. data/doc/classes/El4r/ELInstance.src/M000067.html +19 -0
  41. data/doc/classes/El4r/ELInstance.src/M000068.html +18 -0
  42. data/doc/classes/El4r/ELInstance.src/M000069.html +20 -0
  43. data/doc/classes/El4r/ELInstance.src/M000070.html +18 -0
  44. data/doc/classes/El4r/ELInstance.src/M000071.html +19 -0
  45. data/doc/classes/El4r/ELInstance.src/M000072.html +30 -0
  46. data/doc/classes/El4r/ELInstance.src/M000073.html +20 -0
  47. data/doc/classes/El4r/ELInstance.src/M000074.html +20 -0
  48. data/doc/classes/El4r/ELInstance.src/M000075.html +17 -0
  49. data/doc/classes/El4r/ELInstance.src/M000076.html +18 -0
  50. data/doc/classes/El4r/ELInstance.src/M000077.html +21 -0
  51. data/doc/classes/El4r/ELInstance.src/M000078.html +18 -0
  52. data/doc/classes/El4r/ELInstance.src/M000079.html +18 -0
  53. data/doc/classes/El4r/ELInstance.src/M000080.html +35 -0
  54. data/doc/classes/El4r/ELInstance.src/M000081.html +24 -0
  55. data/doc/classes/El4r/ELInstance.src/M000082.html +22 -0
  56. data/doc/classes/El4r/ELInstance.src/M000083.html +21 -0
  57. data/doc/classes/El4r/ELInstance.src/M000084.html +19 -0
  58. data/doc/classes/El4r/ELInstance.src/M000085.html +18 -0
  59. data/doc/classes/El4r/ELInstance.src/M000086.html +21 -0
  60. data/doc/classes/El4r/ELInstance.src/M000087.html +18 -0
  61. data/doc/classes/El4r/ELInstance.src/M000088.html +24 -0
  62. data/doc/classes/El4r/ELInstance.src/M000089.html +23 -0
  63. data/doc/classes/El4r/ELInstance.src/M000090.html +18 -0
  64. data/doc/classes/El4r/ELInstance.src/M000091.html +20 -0
  65. data/doc/classes/El4r/ELInstance.src/M000092.html +18 -0
  66. data/doc/classes/El4r/ELInstance.src/M000093.html +19 -0
  67. data/doc/classes/El4r/ELListCell.html +163 -0
  68. data/doc/classes/El4r/ELListCell.src/M000026.html +16 -0
  69. data/doc/classes/El4r/ELListCell.src/M000027.html +16 -0
  70. data/doc/classes/El4r/ELListCell.src/M000028.html +23 -0
  71. data/doc/classes/El4r/ELListCell.src/M000031.html +16 -0
  72. data/doc/classes/El4r/ELListCell.src/M000032.html +23 -0
  73. data/doc/classes/El4r/ELListCell.src/M000033.html +16 -0
  74. data/doc/classes/El4r/ELListCell.src/M000034.html +23 -0
  75. data/doc/classes/El4r/ELListCell.src/M000037.html +16 -0
  76. data/doc/classes/El4r/ELListCell.src/M000038.html +23 -0
  77. data/doc/classes/El4r/ELMethodsMixin.html +648 -0
  78. data/doc/classes/El4r/ELMethodsMixin.src/M000006.html +27 -0
  79. data/doc/classes/El4r/ELMethodsMixin.src/M000007.html +27 -0
  80. data/doc/classes/El4r/ELMethodsMixin.src/M000008.html +18 -0
  81. data/doc/classes/El4r/ELMethodsMixin.src/M000009.html +18 -0
  82. data/doc/classes/El4r/ELMethodsMixin.src/M000010.html +27 -0
  83. data/doc/classes/El4r/ELMethodsMixin.src/M000011.html +19 -0
  84. data/doc/classes/El4r/ELMethodsMixin.src/M000012.html +18 -0
  85. data/doc/classes/El4r/ELMethodsMixin.src/M000013.html +19 -0
  86. data/doc/classes/El4r/ELMethodsMixin.src/M000014.html +19 -0
  87. data/doc/classes/El4r/ELMethodsMixin.src/M000015.html +18 -0
  88. data/doc/classes/El4r/ELMethodsMixin.src/M000016.html +21 -0
  89. data/doc/classes/El4r/ELMethodsMixin.src/M000017.html +18 -0
  90. data/doc/classes/El4r/ELMethodsMixin.src/M000018.html +23 -0
  91. data/doc/classes/El4r/ELMethodsMixin.src/M000019.html +18 -0
  92. data/doc/classes/El4r/ELMethodsMixin.src/M000020.html +46 -0
  93. data/doc/classes/El4r/ELMethodsMixin.src/M000021.html +18 -0
  94. data/doc/classes/El4r/ELMethodsMixin.src/M000022.html +23 -0
  95. data/doc/classes/El4r/ELMethodsMixin.src/M000023.html +28 -0
  96. data/doc/classes/El4r/ELMethodsMixin.src/M000024.html +46 -0
  97. data/doc/classes/El4r/ELMethodsMixin.src/M000025.html +18 -0
  98. data/doc/classes/El4r/ELMethodsMixin.src/M000026.html +18 -0
  99. data/doc/classes/El4r/ELMethodsMixin.src/M000027.html +28 -0
  100. data/doc/classes/El4r/ELMethodsMixin.src/M000028.html +31 -0
  101. data/doc/classes/El4r/ELMethodsMixin.src/M000029.html +24 -0
  102. data/doc/classes/El4r/ELMethodsMixin.src/M000030.html +18 -0
  103. data/doc/classes/El4r/ELMethodsMixin.src/M000031.html +18 -0
  104. data/doc/classes/El4r/ELMethodsMixin.src/M000032.html +18 -0
  105. data/doc/classes/El4r/ELMethodsMixin.src/M000033.html +18 -0
  106. data/doc/classes/El4r/ELMethodsMixin.src/M000034.html +18 -0
  107. data/doc/classes/El4r/ELMethodsMixin.src/M000035.html +18 -0
  108. data/doc/classes/El4r/ELMethodsMixin.src/M000036.html +25 -0
  109. data/doc/classes/El4r/ELObject.html +235 -0
  110. data/doc/classes/El4r/ELObject.src/M000078.html +19 -0
  111. data/doc/classes/El4r/ELObject.src/M000079.html +18 -0
  112. data/doc/classes/El4r/ELObject.src/M000080.html +19 -0
  113. data/doc/classes/El4r/ELObject.src/M000081.html +18 -0
  114. data/doc/classes/El4r/ELObject.src/M000082.html +19 -0
  115. data/doc/classes/El4r/ELObject.src/M000083.html +18 -0
  116. data/doc/classes/El4r/ELObject.src/M000084.html +18 -0
  117. data/doc/classes/El4r/ELObject.src/M000085.html +18 -0
  118. data/doc/classes/El4r/ELObject.src/M000086.html +20 -0
  119. data/doc/classes/El4r/ELObject.src/M000087.html +19 -0
  120. data/doc/classes/El4r/ELObject.src/M000088.html +20 -0
  121. data/doc/classes/El4r/ELObject.src/M000090.html +19 -0
  122. data/doc/classes/El4r/ELObject.src/M000091.html +19 -0
  123. data/doc/classes/El4r/ELObject.src/M000092.html +18 -0
  124. data/doc/classes/El4r/ELObject.src/M000093.html +19 -0
  125. data/doc/classes/El4r/ELObject.src/M000094.html +18 -0
  126. data/doc/classes/El4r/ELObject.src/M000095.html +18 -0
  127. data/doc/classes/El4r/ELObject.src/M000096.html +18 -0
  128. data/doc/classes/El4r/ELObject.src/M000097.html +19 -0
  129. data/doc/classes/El4r/ELObject.src/M000098.html +18 -0
  130. data/doc/classes/El4r/ELObject.src/M000099.html +18 -0
  131. data/doc/classes/El4r/ELObject.src/M000100.html +18 -0
  132. data/doc/classes/El4r/ELObject.src/M000102.html +19 -0
  133. data/doc/classes/El4r/ELObject.src/M000103.html +20 -0
  134. data/doc/classes/El4r/ELRubyObjectStock.html +283 -0
  135. data/doc/classes/El4r/ELRubyObjectStock.src/M000030.html +21 -0
  136. data/doc/classes/El4r/ELRubyObjectStock.src/M000031.html +22 -0
  137. data/doc/classes/El4r/ELRubyObjectStock.src/M000032.html +22 -0
  138. data/doc/classes/El4r/ELRubyObjectStock.src/M000033.html +42 -0
  139. data/doc/classes/El4r/ELRubyObjectStock.src/M000034.html +19 -0
  140. data/doc/classes/El4r/ELRubyObjectStock.src/M000035.html +22 -0
  141. data/doc/classes/El4r/ELRubyObjectStock.src/M000036.html +22 -0
  142. data/doc/classes/El4r/ELRubyObjectStock.src/M000037.html +22 -0
  143. data/doc/classes/El4r/ELRubyObjectStock.src/M000038.html +22 -0
  144. data/doc/classes/El4r/ELRubyObjectStock.src/M000039.html +17 -0
  145. data/doc/classes/El4r/ELRubyObjectStock.src/M000040.html +17 -0
  146. data/doc/classes/El4r/ELRubyObjectStock.src/M000041.html +22 -0
  147. data/doc/classes/El4r/ELRubyObjectStock.src/M000042.html +22 -0
  148. data/doc/classes/El4r/ELRubyObjectStock.src/M000043.html +17 -0
  149. data/doc/classes/El4r/ELRubyObjectStock.src/M000044.html +17 -0
  150. data/doc/classes/El4r/ELRubyObjectStock.src/M000045.html +46 -0
  151. data/doc/classes/El4r/ELRubyObjectStock.src/M000046.html +19 -0
  152. data/doc/classes/El4r/ELRubyObjectStock.src/M000047.html +21 -0
  153. data/doc/classes/El4r/ELRubyObjectStock.src/M000048.html +19 -0
  154. data/doc/classes/El4r/ELRubyObjectStock.src/M000049.html +18 -0
  155. data/doc/classes/El4r/ELSequence.html +221 -0
  156. data/doc/classes/El4r/ELSequence.src/M000040.html +18 -0
  157. data/doc/classes/El4r/ELSequence.src/M000041.html +18 -0
  158. data/doc/classes/El4r/ELSequence.src/M000042.html +20 -0
  159. data/doc/classes/El4r/ELSequence.src/M000043.html +19 -0
  160. data/doc/classes/El4r/ELSequence.src/M000044.html +18 -0
  161. data/doc/classes/El4r/ELSequence.src/M000045.html +19 -0
  162. data/doc/classes/El4r/ELSequence.src/M000048.html +18 -0
  163. data/doc/classes/El4r/ELSequence.src/M000049.html +20 -0
  164. data/doc/classes/El4r/ELSequence.src/M000050.html +18 -0
  165. data/doc/classes/El4r/ELSequence.src/M000051.html +20 -0
  166. data/doc/classes/El4r/ELSequence.src/M000052.html +19 -0
  167. data/doc/classes/El4r/ELSequence.src/M000053.html +18 -0
  168. data/doc/classes/El4r/ELSequence.src/M000054.html +18 -0
  169. data/doc/classes/El4r/ELSequence.src/M000055.html +20 -0
  170. data/doc/classes/El4r/ELSequence.src/M000056.html +19 -0
  171. data/doc/classes/El4r/ELSequence.src/M000057.html +18 -0
  172. data/doc/classes/El4r/ELSequence.src/M000058.html +19 -0
  173. data/doc/classes/El4r/ELVariables.html +173 -0
  174. data/doc/classes/El4r/ELVariables.src/M000037.html +18 -0
  175. data/doc/classes/El4r/ELVariables.src/M000038.html +18 -0
  176. data/doc/classes/El4r/ELVariables.src/M000039.html +18 -0
  177. data/doc/classes/El4r/ELVariables.src/M000040.html +23 -0
  178. data/doc/classes/El4r/ELVariables.src/M000045.html +18 -0
  179. data/doc/classes/El4r/ELVariables.src/M000046.html +18 -0
  180. data/doc/classes/El4r/ELVariables.src/M000047.html +18 -0
  181. data/doc/classes/El4r/ELVariables.src/M000048.html +18 -0
  182. data/doc/classes/El4r/ELVariables.src/M000049.html +23 -0
  183. data/doc/classes/El4r/ELVariables.src/M000051.html +18 -0
  184. data/doc/classes/El4r/ELVariables.src/M000052.html +18 -0
  185. data/doc/classes/El4r/ELVariables.src/M000053.html +23 -0
  186. data/doc/classes/El4r/ELVector.html +160 -0
  187. data/doc/classes/El4r/ELVector.src/M000028.html +22 -0
  188. data/doc/classes/El4r/ELVector.src/M000029.html +22 -0
  189. data/doc/classes/El4r/ELVector.src/M000030.html +16 -0
  190. data/doc/classes/El4r/ELVector.src/M000033.html +22 -0
  191. data/doc/classes/El4r/ELVector.src/M000034.html +16 -0
  192. data/doc/classes/El4r/ELVector.src/M000035.html +22 -0
  193. data/doc/classes/El4r/ELVector.src/M000036.html +16 -0
  194. data/doc/classes/El4r/ELVector.src/M000039.html +22 -0
  195. data/doc/classes/El4r/ELVector.src/M000040.html +16 -0
  196. data/doc/classes/El4r/El4rOutput.html +175 -0
  197. data/doc/classes/El4r/El4rOutput.src/M000080.html +18 -0
  198. data/doc/classes/El4r/El4rOutput.src/M000081.html +21 -0
  199. data/doc/classes/El4r/El4rOutput.src/M000088.html +18 -0
  200. data/doc/classes/El4r/El4rOutput.src/M000089.html +21 -0
  201. data/doc/classes/El4r/El4rOutput.src/M000090.html +18 -0
  202. data/doc/classes/El4r/El4rOutput.src/M000091.html +21 -0
  203. data/doc/classes/El4r/El4rOutput.src/M000092.html +18 -0
  204. data/doc/classes/El4r/El4rOutput.src/M000094.html +18 -0
  205. data/doc/classes/El4r/El4rOutput.src/M000095.html +21 -0
  206. data/doc/classes/El4r/El4rOutput.src/M000096.html +18 -0
  207. data/doc/classes/El4rAccessor.html +134 -0
  208. data/doc/classes/El4rAccessor.src/M000005.html +18 -0
  209. data/doc/classes/ElApp.html +211 -0
  210. data/doc/classes/ElApp.src/M000001.html +21 -0
  211. data/doc/classes/ElApp.src/M000002.html +17 -0
  212. data/doc/classes/ElApp.src/M000003.html +18 -0
  213. data/doc/classes/ElApp.src/M000004.html +18 -0
  214. data/doc/classes/ElMixin.html +163 -0
  215. data/doc/classes/ElMixin.src/M000001.html +19 -0
  216. data/doc/classes/ElMixin.src/M000002.html +19 -0
  217. data/doc/classes/ElMixin.src/M000003.html +18 -0
  218. data/doc/classes/ElMixin.src/M000004.html +18 -0
  219. data/doc/classes/ElMixin.src/M000006.html +19 -0
  220. data/doc/classes/ElMixin.src/M000007.html +18 -0
  221. data/doc/created.rid +1 -0
  222. data/doc/files/bin/el4r-instance.html +119 -0
  223. data/doc/fr_class_index.html +40 -0
  224. data/doc/fr_file_index.html +27 -0
  225. data/doc/fr_method_index.html +129 -0
  226. data/doc/index.html +24 -0
  227. data/doc/rdoc-style.css +208 -0
  228. data/el4r.en.html +468 -0
  229. data/el4r.ja.html +640 -0
  230. data/files +29 -0
  231. data/lib/el4r/el4r-sub.rb +1023 -0
  232. data/lib/el4r/emacsruby/autoload/70el4r-mode.rb +9 -0
  233. data/lib/el4r/emacsruby/el4r-mode.rb +35 -0
  234. data/lib/el4r/emacsruby/stdlib.rb +37 -0
  235. data/lib/el4r/exec-el4r.rb +182 -0
  236. data/man/el4r.1 +125 -0
  237. data/setup.rb +1551 -0
  238. data/testing/alltest.rb +5 -0
  239. data/testing/badcase.rb +50 -0
  240. data/testing/el4r.e +262 -0
  241. data/testing/euc.txt +1 -0
  242. data/testing/jis.txt +1 -0
  243. data/testing/sjis.txt +1 -0
  244. data/testing/test-el4r.rb +1053 -0
  245. data/testing/test-gc.rb +81 -0
  246. data/testing/test.el +16 -0
  247. data/testing/test.rb +97 -0
  248. data/testing/utf8.txt +1 -0
  249. metadata +311 -0
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # el4r - EmacsLisp for Ruby
3
+ # Copyright (C) 2005 rubikitch <rubikitch@ruby-lang.org>
4
+ # Version: $Id: el4r 852 2005-11-15 19:38:07Z rubikitch $
5
+
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+
20
+ require 'el4r/exec-el4r'
21
+ exec_el4r false
22
+
23
+
24
+ # Local Variables:
25
+ # modes: (ruby-mode emacs-lisp-mode)
26
+ # End:
@@ -0,0 +1,1105 @@
1
+ #!/usr/bin/env ruby
2
+ # el4r - EmacsLisp for Ruby
3
+ # Copyright (C) 2005 rubikitch <rubikitch@ruby-lang.org>
4
+ # Version: $Id: el4r-instance 1376 2006-09-21 05:50:24Z rubikitch $
5
+
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; either version 2 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # This program is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ # GNU General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU General Public License
17
+ # along with this program; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+
20
+ require 'forwardable'
21
+
22
+ if ENV["EL4R_RECORDIO"]
23
+ # Requires ucspi-tcp
24
+ exec("sh", "-c", '\
25
+ exec 2>"$EL4R_RECORDIO"
26
+ unset EL4R_RECORDIO
27
+ exec recordio "$@"', "--", $0, *ARGV)
28
+ end
29
+ # TODO: ENV['EL4R_RC']
30
+ load "~/.el4rrc.rb";
31
+ # The EmacsRuby engine
32
+ module El4r
33
+ ErrorUtils = Module.new
34
+ class << ErrorUtils
35
+ def error_description(exception = nil)
36
+ exception ||= $!
37
+ sprintf("%s (%s)", exception.to_s, exception.class)
38
+ end
39
+
40
+ def backtrace_message(backtrace = nil)
41
+ backtrace ||= caller(1)
42
+ lines = []
43
+ backtrace.each do |line|
44
+ lines << sprintf(" from %s", line)
45
+ end
46
+ lines.join("\n")
47
+ end
48
+
49
+ def stacktrace_message(exception = nil)
50
+ exception ||= $!
51
+ lines = []
52
+
53
+ lines << error_description(exception)
54
+ lines << backtrace_message(exception.backtrace)
55
+ lines.join("\n")
56
+ end
57
+ end #/<< ErrorUtils
58
+
59
+ El4rError = Class.new(StandardError)
60
+ ELError = Class.new(El4rError)
61
+
62
+ ELISP_INTEGER_RANGE = (-134217727..134217727)
63
+
64
+ class << self
65
+ def lisp_dump_string(string)
66
+ dumped = string.dup
67
+ # \ -> \\
68
+ dumped.gsub! %r"\\" do '\\\\' end
69
+ # " -> \"
70
+ dumped.gsub! %r'"' do '\\"' end
71
+ # (zero byte) -> \0
72
+ dumped.gsub! %r'\0' do "\\\0" end
73
+ %Q'"#{dumped}"'
74
+ end
75
+
76
+ def name_rb2el(rbname)
77
+ rbname.gsub(/_/, "-")
78
+ end
79
+ end #/<< self
80
+
81
+ ELExpression = Struct.new(:expression)
82
+
83
+ # Reference of an EmacsLisp object.
84
+ class ELObject < Struct.new(:instance, :object_id)
85
+ def initialize(*args)
86
+ ObjectSpace.define_finalizer(self, ELObject.finalizer_proc(*args))
87
+ super(*args)
88
+ end
89
+
90
+ def to_lisp
91
+ "(el4r-lisp-object-from-id #{object_id})"
92
+ end
93
+
94
+ def inspect
95
+ "#<#{self.class} id=#{object_id}>"
96
+ end
97
+
98
+ def to_s
99
+ instance.prin1_to_string(self)
100
+ end
101
+ alias :to_str :to_s
102
+
103
+ def ==(x)
104
+ ELObject === x or return false
105
+ object_id == x.object_id or instance.equal(self,x)
106
+ end
107
+
108
+ def self.finalizer_proc(instance, object_id)
109
+ proc {
110
+ instance.el4r_add_garbage_lispobj(object_id)
111
+ }
112
+ end
113
+ end #/ELObject
114
+
115
+ class ELSequence < ELObject
116
+ include Enumerable
117
+
118
+ def inspect
119
+ "#{self.class.to_s.split(/::/)[-1]}#{to_a.inspect}"
120
+ end
121
+
122
+ def check(x)
123
+ @length ||= to_a.length
124
+ Fixnum === x or raise TypeError, "must be Fixnum"
125
+ @length <= x and raise ArgumentError, "Args out of range #{inspect}[#{x}]"
126
+ end
127
+
128
+ def [](*args)
129
+ check args[0]
130
+ to_a[*args]
131
+ end
132
+
133
+ def each(&block)
134
+ to_a.each(&block)
135
+ end
136
+
137
+ def to_a
138
+ # subclass must define `to_a_func' method
139
+ @ary ||= instance.__send__(to_a_func, self)
140
+ end
141
+ alias :to_ary :to_a
142
+
143
+ end #/ELSequence
144
+
145
+ # An Array like object converted from a list object of EmacsLisp.
146
+ class ELListCell < ELSequence
147
+ def to_a_func () :el4r_list_to_rubyary end
148
+
149
+ # Convert alist -> Hash
150
+ def to_hash
151
+ hash = {}
152
+ each { |cell|
153
+ cell.kind_of?(ELListCell) or raise(TypeError, "Malformed assoc list.")
154
+ hash[instance.car(cell)] = instance.cdr(cell)
155
+ }
156
+ hash
157
+ end
158
+ end #/ELListCell
159
+
160
+ # An Array like object converted from a cons cell of EmacsLisp.
161
+ class ELConsCell < ELListCell
162
+ def to_a_func () :el4r_cons_to_rubyary end
163
+ end
164
+
165
+ # An Array like object converted from a vector object of EmacsLisp.
166
+ class ELVector < ELSequence
167
+ def []=(x,y)
168
+ check x
169
+ x < 0 and x = @length+x
170
+
171
+ @ary[x]=y
172
+ instance.aset(self, x, y)
173
+ end
174
+
175
+ def to_a_func () :el4r_vector_to_rubyary end
176
+ end #/ELVector
177
+
178
+
179
+ # EmacsLisp objects stock.
180
+ class ELRubyObjectStock
181
+ attr_accessor :gc_trigger_count, :gc_trigger_increment
182
+ def initialize(instance)
183
+ @instance = instance
184
+ conf = instance.conf
185
+ @oid_to_obj_hash = {}
186
+ @gc_trigger_count = conf.ruby_gc_trigger_count
187
+ @gc_trigger_increment = conf.ruby_gc_trigger_increment
188
+ end
189
+
190
+ def garbage_collect_if_required
191
+ if count_of_stocked_objects >= @gc_trigger_count
192
+ garbage_collect
193
+ @gc_trigger_count =
194
+ count_of_stocked_objects + @gc_trigger_increment
195
+ end
196
+ end
197
+
198
+ def pre_gc_hook
199
+ end
200
+
201
+ def post_gc_hook
202
+ end
203
+
204
+ def garbage_collect
205
+ pre_gc_hook
206
+ stock_ids = @oid_to_obj_hash.keys
207
+ stock_ids.sort!
208
+ @instance.el4r_debug { "(GC) 1" }
209
+ alive_ids = @instance.el4r_rubyobj_get_alive_ids.to_a # funcall
210
+ @instance.el4r_debug { "(GC) 2" }
211
+ alive_ids.collect! { |id| id.to_i; }
212
+ alive_ids.sort!
213
+
214
+ @instance.el4r_debug { "(GC) Stocked IDs: #{stock_ids.inspect}"; }
215
+ @instance.el4r_debug { "(GC) Alive IDs: #{alive_ids.inspect}"; }
216
+
217
+ freed_ids = []
218
+ while aid = alive_ids.pop
219
+ while true
220
+ sid = stock_ids.pop or raise(El4rError, "Can't happen!")
221
+ break if sid == aid
222
+ freed_ids << sid
223
+ end
224
+ end
225
+ freed_ids.concat(stock_ids)
226
+
227
+ @instance.el4r_debug { "(GC) IDs to free: #{freed_ids.inspect}"; }
228
+ freed_ids.each { |id|
229
+ @oid_to_obj_hash.delete(id)
230
+ }
231
+
232
+ @instance.el4r_debug { "(GC) Count of stocked object is reduced to #{count_of_stocked_objects}"; }
233
+ post_gc_hook
234
+ end
235
+
236
+ def obj2lisp(obj)
237
+ # NOTE: Ruby's object ID exceeds elisp's 28-bit integer limitation.
238
+ "(el4r-rubyobj-create \"#{obj2id(obj)}\")"
239
+ end
240
+
241
+ def obj2id(obj)
242
+ garbage_collect_if_required
243
+ oid = obj.__id__
244
+ @oid_to_obj_hash[oid] ||= obj
245
+ oid
246
+ end
247
+
248
+ def id2obj(oid)
249
+ @oid_to_obj_hash[oid] or
250
+ raise(El4rError, "No such object for ID: #{oid}")
251
+ end
252
+
253
+ def count_of_stocked_objects
254
+ @oid_to_obj_hash.size
255
+ end
256
+ end #/ELRubyObjectStock
257
+
258
+ # A Struct like object to handle EmacsLisp variables.
259
+ class ELVariables < Struct.new(:instance)
260
+ def [](name)
261
+ instance.getq(name)
262
+ end
263
+
264
+ def []=(name, value)
265
+ instance.setq(name, value)
266
+ end
267
+
268
+ def method_missing(name, value = nil)
269
+ name = name.to_s
270
+ if name[-1] == ?=
271
+ instance.setq(name[0..-2], value)
272
+ else
273
+ instance.getq(name)
274
+ end
275
+ end
276
+ end #/ELVariables
277
+
278
+ # EmacsLisp wrapper methods
279
+ module ELMethodsMixin
280
+ # Call an EmacsLisp function
281
+ def funcall(name_or_lambda, *args, &block)
282
+ func = case name_or_lambda
283
+ when Symbol, String
284
+ El4r.name_rb2el(name_or_lambda.to_s)
285
+ when ELObject, ELExpression
286
+ "funcall #{el4r_ruby2lisp(name_or_lambda)}"
287
+ else
288
+ raise(TypeError,
289
+ "Invalid 1st argument for funcall: #{name_or_lambda.inspect}")
290
+ end
291
+ funcall_internal(func, *args, &block)
292
+ end
293
+ alias method_missing funcall
294
+
295
+ def funcall_internal(funcexpr, *args, &block)
296
+ el4r_lisp_eval("(#{funcexpr} #{el4r_args_to_lispseq(*args, &block)})")
297
+ end
298
+
299
+ # Call (func FORMS...) type function
300
+ def with(name, *args, &block)
301
+ args << el("(funcall #{el4r_rubyproc_to_lambda(&block)})")
302
+ funcall(name, *args)
303
+ end
304
+
305
+ # EmacsLisp's defun.
306
+ #
307
+ # +attrs+ is a Hash.
308
+ # attrs[:interactive]:: If the function is interactive, set +true+ or String.
309
+ # attrs[:docstring]:: The docstring.
310
+ #
311
+ # The function arguments are block arguments.
312
+ def defun(name, attrs = nil, &block)
313
+ String === name and name = el("'#{name}")
314
+ funcall_internal("el4r-define-function", name, el_lambda(attrs, &block))
315
+ end
316
+
317
+ def defvar(name, value=nil, docstring="")
318
+ funcall_internal :defvar, el(name), value, docstring
319
+ end
320
+
321
+ # EmacsLisp's define-key.
322
+ #
323
+ # +map+ is a +Symbol+ or +ELObject+ refering to a keymap object.
324
+ # This method can be called with block.
325
+ def define_key(map, key, command = nil, &block)
326
+ map = el(map) unless map.kind_of?(ELObject)
327
+ key = el(%Q'"#{key}"') if key.kind_of?(String)
328
+ command = el_lambda(:interactive => true, &block) if block_given?
329
+ funcall_internal("define-key", map, key, command)
330
+ end
331
+
332
+ def symbol_value(name)
333
+ el4r_lisp_eval(El4r.name_rb2el(name.to_s))
334
+ end
335
+ alias getq symbol_value
336
+
337
+ def setq(name, value)
338
+ el4r_lisp_eval("(setq #{El4r.name_rb2el(name.to_s)} #{el4r_ruby2lisp(value)})")
339
+ end
340
+ alias set setq
341
+
342
+ def _init_eval_after_load
343
+ @eval_after_load_func = "el4r-eval-after-load-function-1"
344
+ end
345
+
346
+ # EmacsLisp's eval-after-load
347
+ def eval_after_load(lib, &block)
348
+ raise ArgumentError, "must have block" unless block
349
+ # el4r_lisp_eval "(eval-after-load #{el4r_ruby2lisp(lib)} '(funcall #{el4r_rubyproc_to_lambda(&block)}))" # '
350
+ defun(@eval_after_load_func, &block)
351
+ el4r_lisp_eval "(eval-after-load #{el4r_ruby2lisp(lib)} '(#{@eval_after_load_func}))" # '
352
+ @eval_after_load_func.succ!
353
+ nil
354
+ end
355
+
356
+ # EmacsLisp's let.
357
+ # +name_and_value_list+ is [variable_name, value, variable_name, value...].
358
+ # +name_and_value_list.length+ must be even.
359
+ # +variable_name+ is a Symbol.
360
+ def let(*name_and_value_list, &block)
361
+ (name_and_value_list.size % 2) == 0 or
362
+ raise(ArgumentError, "Invalid count of arguments.")
363
+
364
+ letexpr = "(let ("
365
+ until name_and_value_list.empty?
366
+ name = El4r.name_rb2el(name_and_value_list.shift.to_s)
367
+ value = el4r_ruby2lisp(name_and_value_list.shift)
368
+ letexpr << "(#{name} #{value}) "
369
+ end
370
+ letexpr << ") (funcall #{el4r_rubyproc_to_lambda(&block)}))"
371
+ el4r_lisp_eval(letexpr)
372
+ end
373
+
374
+ # Create a new buffer with some initialization.
375
+ # With block, newbuf execute it by the context of the generated buffer.
376
+ #
377
+ # A parameter is a Hash.
378
+ # :name :: buffer-name
379
+ # :file :: find-file-noselect / insert-file-contents [with :name]
380
+ # :contents :: buffer-string
381
+ # :line :: goto-line
382
+ # :point :: goto-char [default is (point-max)]
383
+ # :display :: :pop / :only / true
384
+ # :current :: set-buffer
385
+ # :read_only :: buffer-read-only
386
+ # :bury :: bury-buffer
387
+ def newbuf(x)
388
+ Hash === x or raise ArgumentError, "argument must be a hash!"
389
+ x[:name] || x[:file] or raise ArgumentError, "`:name' or `:file' key is mandatory!"
390
+ x[:name] and b = get_buffer_create(x[:name])
391
+ x[:file] && !x[:name] and b = find_file_noselect(x[:file])
392
+
393
+ check = lambda{|key, type| x[key] && (type===x[key] or raise ArgumentError) }
394
+ with(:with_current_buffer, b) {
395
+ elvar.buffer_read_only = nil
396
+ # TODO: coding-system
397
+ x[:name] and erase_buffer
398
+ x[:name] && x[:file] and insert_file_contents(x[:file])
399
+ x[:contents] and insert x[:contents].to_s
400
+ check[:line,Integer] and goto_line x[:line]
401
+ check[:point,Integer] and goto_char x[:point]
402
+ block_given? and yield
403
+ x[:read_only] and elvar.buffer_read_only = true
404
+ }
405
+
406
+ case x[:display]
407
+ when :pop; pop_to_buffer b
408
+ when :only; delete_other_windows; switch_to_buffer b
409
+ when true; display_buffer b
410
+ else
411
+ end
412
+
413
+ x[:bury] and bury_buffer b
414
+ x[:current] and set_buffer b
415
+
416
+ b
417
+ end
418
+
419
+ # Extended buffer-string.
420
+ # +buf+ is a buffer object.
421
+ def bufstr(buf=current_buffer)
422
+ with(:with_current_buffer, buf) { buffer_string }
423
+ end
424
+
425
+ def ad_do_it
426
+ el4r_lisp_eval("(funcall --defadvice-ad-do-it--)")
427
+ end
428
+
429
+ # EmacsLisp's defadvice.
430
+ # +func+ is Symbol or String refering to the function.
431
+ # +args+ is parameters to defadvice such as :before, :after, :around, :activate.
432
+ # In the block, you can call +ad_do_it+. [around advice]
433
+
434
+ def defadvice(func, *args, &block)
435
+ Hash === args[-1] and attrs = args.pop
436
+
437
+ param = args.map{|a| El4r.name_rb2el(a.to_s)}.join(' ')
438
+ forms = "#{El4r.name_rb2el(func.to_s)} (#{param})\n"
439
+
440
+ if attrs
441
+ _handle_attrs attrs, forms, false
442
+ end
443
+
444
+ forms << "(setq --defadvice-ad-do-it-- (lambda () ad-do-it))\n"
445
+ with(:defadvice, el(forms), &block)
446
+ end
447
+
448
+ def _handle_attrs(attrs, forms, quote)
449
+ docstring = attrs[:docstring]
450
+ forms << el4r_ruby2lisp(docstring) << "\n" if docstring
451
+ interactive = attrs[:interactive]
452
+ if interactive
453
+ forms << "'" if quote
454
+ case interactive
455
+ when Proc;
456
+ lmd = el4r_ruby2lisp(interactive)
457
+ el4r_lisp_eval %Q((el4r-register-lambda #{lmd}))
458
+ forms << "(interactive (eval (list #{lmd})))"
459
+ when true; forms << "(interactive)\n"
460
+ else; forms << "(interactive #{el4r_ruby2lisp(interactive)})\n"
461
+ end
462
+ end
463
+ end
464
+
465
+ # Call defun-type macro. `mode' is an EmacsLisp function to define.
466
+ # Most case the first argument is the function name.
467
+ #
468
+ # `define_derived_mode' and `define_minor_mode' are examples of this method's usage.
469
+ def with_preserved_block(funcexpr, mode, *args, &block)
470
+ mode = el(mode)
471
+ subfuncexpr = "#{mode.expression}--el4r-function"
472
+ block ||= lambda{}
473
+ defun(subfuncexpr, &block)
474
+ args << el("(#{subfuncexpr})")
475
+
476
+ funcall_internal(funcexpr, mode, *args)
477
+ end
478
+
479
+ # EmacsLisp's define-derived-mode.
480
+ def define_derived_mode(child, parent, name, docstring=nil, &block)
481
+ with_preserved_block "define-derived-mode", child, el(parent), name, docstring, &block
482
+ end
483
+
484
+ # EmacsLisp's define-minor-mode
485
+ def define_minor_mode(mode, doc, init_value=nil, lighter=nil, keymap=nil, &block)
486
+ with_preserved_block "define-minor-mode", mode, doc, init_value, lighter, keymap, &block
487
+ end
488
+
489
+ # Ruby's require.
490
+ def require(*args)
491
+ Kernel.require(*args)
492
+ end
493
+
494
+ # EmacsLisp's require.
495
+ def el_require(*args)
496
+ funcall_internal("require", *args)
497
+ end
498
+
499
+ # EmacsLisp's load.
500
+ def el_load(*args)
501
+ funcall_internal("load", *args)
502
+ end
503
+
504
+ # EmacsLisp's lambda.
505
+ def el_lambda(attr = nil, &block)
506
+ el(el4r_rubyproc_to_lambda(attr, &block))
507
+ end
508
+
509
+ # Bare EmacsLisp expression.
510
+ def el(expression)
511
+ case expression
512
+ when Symbol; ELExpression.new(El4r.name_rb2el(expression.to_s))
513
+ when String; ELExpression.new(expression)
514
+ when ELExpression; expression
515
+ else
516
+ raise(TypeError,
517
+ "Cannot treat as lisp expression: <#{expression.inspect}>")
518
+ end
519
+ end
520
+ end #/ELMethodsMixin
521
+
522
+ # Pseudo $stdout object for el4r.
523
+ # This object appends to *el4r output* buffer
524
+ class El4rOutput
525
+ def initialize(instance)
526
+ @instance = instance
527
+ end
528
+
529
+ def write(s)
530
+ @instance.instance_eval do
531
+ princ(s.to_s, get_buffer_create(conf.output_buffer))
532
+ end
533
+ nil
534
+ end
535
+
536
+ def flush
537
+ self
538
+ end
539
+ end
540
+
541
+ class ELInstance
542
+ include ELMethodsMixin
543
+ extend Forwardable
544
+
545
+ attr_accessor :outer # maybe thread-unsafe(no problem)
546
+ attr_reader :el4r_rubyobj_stock
547
+
548
+ # An Struct like object to handle EmacsLisp's variable.
549
+ attr_reader :elvar
550
+
551
+ # If +true+, verbose log output.
552
+ attr_accessor :el4r_is_debug
553
+
554
+ # el4r_load evals an EmacsRuby script from this directory.
555
+ attr_accessor :el4r_homedir
556
+
557
+ # settings by ~/.el4rrc.rb
558
+ attr_reader :conf
559
+
560
+ def_delegators :@conf, :el4r_load_path, :root_dir, :site_dir
561
+ def initialize(conf)
562
+ @conf = conf
563
+ @emacs_in = STDIN
564
+ @emacs_out = STDOUT
565
+ @call_level = 0
566
+ @last_error = nil
567
+ @el4r_is_debug = ENV["EL4R_DEBUG"]
568
+ @el4r_homedir = conf.home_dir
569
+ @elvar = ELVariables.new(self)
570
+ @el4r_rubyobj_stock = ELRubyObjectStock.new(self)
571
+ @el4r_garbage_elobj_ids = []
572
+
573
+ @el4r_output = El4rOutput.new self
574
+
575
+ log = ENV["EL4R_LOG"]
576
+ @log = case log
577
+ when "stderr"; STDERR
578
+ when /^\|/; File.popen($~.post_match, "w")
579
+ else; File.open(log || "/tmp/el4r-#{`whoami`.chomp}.#{Process.pid}.log", "w")
580
+ end
581
+
582
+ @el_backtrace_reset_threshold = 1 # very nasty hack!
583
+ @el_backtrace = []
584
+
585
+ _init_eval_after_load
586
+
587
+ $: << el4r_homedir
588
+ end
589
+
590
+ # --------------------------------
591
+ # Methods for user
592
+
593
+ # Load an EmacsRuby script.
594
+ #
595
+ # If +path_to_rb+'s dirname is omitted, searches a script from el4r_load_path.
596
+ # If +is_noerror+ is true and +path_to_rb+ is not found, returns false instead of raise LoadError.
597
+ # If success, returns true.
598
+ def el4r_load(path_to_rb, is_noerror = nil)
599
+ el4r_load_path.each do |dir|
600
+ full_path_to_rb = File.expand_path(path_to_rb, dir)
601
+ if File.exist?(full_path_to_rb)
602
+ source = el4r_readfile(full_path_to_rb)
603
+ instance_eval(source, full_path_to_rb)
604
+ return true
605
+ end
606
+ end
607
+
608
+ if is_noerror
609
+ false
610
+ else
611
+ raise LoadError, "el4r_load: cannot load #{path_to_rb}"
612
+ end
613
+ end
614
+
615
+ # Eval an EmacsLisp expression.
616
+ def el4r_lisp_eval(lispexpr)
617
+ el4r_interrupt if el4r_callback?
618
+ el4r_with_call {
619
+ el4r_send(lispexpr)
620
+ el4r_get
621
+ }
622
+ end
623
+
624
+ # Convert a Ruby Regexp into EmacsLisp.
625
+ def el4r_conv_regexp(re)
626
+ s = re.source.dup
627
+ s.gsub!(/[\|\(\)]/){'\\'+$&}
628
+ s.sub!(/\\A/){'\`'}
629
+ s.sub!(/\\Z/){'\\\''}
630
+ s.sub!(/\\w/, '[0-9A-Za-z_]')
631
+ s.sub!(/\\W/, '[^0-9A-Za-z_]')
632
+
633
+ s
634
+ end
635
+
636
+ # Convert a Ruby object into EmacsLisp.
637
+ def el4r_ruby2lisp(obj)
638
+ case obj
639
+ when nil, false; "nil"
640
+ when true; "t"
641
+ when String; El4r.lisp_dump_string(obj)
642
+ when Regexp; El4r.lisp_dump_string(el4r_conv_regexp(obj))
643
+ when Symbol; "'#{El4r.name_rb2el(obj.to_s)}"
644
+ when Proc; el4r_rubyproc_to_lambda(&obj)
645
+ when Integer
646
+ (ELISP_INTEGER_RANGE === obj) or
647
+ raise(RangeError,
648
+ "Integer #{obj} exceed elisp limitation (#{ELISP_INTEGER_RANGE})")
649
+ obj.to_s
650
+ when Numeric; obj.to_s
651
+ when Array; "(list #{el4r_args_to_lispseq(*obj)})"
652
+ when ELObject; obj.to_lisp
653
+ when ELExpression; obj.expression
654
+ else; el4r_rubyobj_stock.obj2lisp(obj)
655
+ end
656
+ end
657
+
658
+ # Convert a Ruby Proc into EmacsLisp
659
+ # +attrs+ is the same as that of +defun+.
660
+ def el4r_rubyproc_to_lambda(attrs = nil, &block)
661
+ forms =
662
+ ["el4r-lambda-for-rubyproc \"#{el4r_rubyobj_stock.obj2id(block)}\""]
663
+ if attrs
664
+ _handle_attrs attrs, forms, true
665
+ end
666
+ "(#{forms.join(' ')})"
667
+ end
668
+
669
+ def el4r_args_to_lispseq(*args, &block)
670
+ elargs = args
671
+ elargs << block if block_given?
672
+ elargs.collect! { |form|
673
+ el4r_ruby2lisp(form)
674
+ }
675
+ elargs.join(' ')
676
+ end
677
+
678
+ # Write a log message.
679
+ def el4r_log(msg)
680
+ @log.print(Time.now, ":")
681
+ @log.puts(msg); @log.flush
682
+ end
683
+
684
+ # String representation. obj.inspect and (prin1-to-string obj).
685
+ def el4r_prin1_to_string(obj)
686
+ "[ruby] #{obj.inspect} / [lisp] #{prin1_to_string(obj)}"
687
+ end
688
+
689
+ # Write string representation(both in Ruby and in EmacsLisp) of all the argument to the log.
690
+ def el4r_prin1(*objs)
691
+ objs.each { |obj|
692
+ el4r_log("el4r_prin1: #{el4r_prin1_to_string(obj)}")
693
+ }
694
+ end
695
+
696
+ # Write string representation(only in Ruby) of all the argument to the log.
697
+ def el4r_p(*objs)
698
+ el4r_log("el4r_p: #{objs.inspect}")
699
+ end
700
+
701
+ # Write a backtrace message to the log.
702
+ def el4r_backtrace(msg = nil)
703
+ msg ||= "*backtrace*"
704
+ el4r_log "#{msg}\n#{ErrorUtils.backtrace_message(caller(2))}"
705
+ end
706
+
707
+ # --------------------------------
708
+ # Methods for internal use
709
+
710
+ # Startup el4r without loading init.rb.
711
+ def el4r_boot__noinit
712
+ logbuf = get_buffer_create conf.log_buffer
713
+ elvar.el4r_log_path = el4r_log_io.path
714
+
715
+ el4r_lisp_eval('(defun el4r-show-log () (interactive)
716
+ (with-current-buffer (get-buffer-create el4r-log-buffer)
717
+ (setq buffer-read-only nil)
718
+ (erase-buffer)
719
+ (insert-file-contents el4r-log-path)
720
+ (setq buffer-read-only t)
721
+ (goto-char (point-max))
722
+ (pop-to-buffer (current-buffer))))')
723
+ el4r_install_builtin_functions
724
+ $> = @el4r_output
725
+ end
726
+
727
+ def el4r_process_autoloads(dir=conf.autoload_dir)
728
+ Dir["#{dir}/[0-9][0-9]*.rb"].sort.each do |rb|
729
+ el4r_load rb
730
+ end
731
+ end
732
+
733
+ # Startup el4r.
734
+ def el4r_boot
735
+ el4r_boot__noinit
736
+ el4r_process_autoloads
737
+ el4r_load(conf.init_script, true)
738
+ end
739
+
740
+ # Obsolete.
741
+ def el4r_shutdown
742
+ end
743
+
744
+ def el4r_add_garbage_lispobj(id)
745
+ @el4r_garbage_elobj_ids << id
746
+ end
747
+
748
+ def el4r_get_garbage_lispobj_ids
749
+ GC.start
750
+ ids = @el4r_garbage_elobj_ids
751
+ @el4r_garbage_elobj_ids = []
752
+ ids
753
+ end
754
+
755
+ def el4r_readfile(file)
756
+ File.open(file) { |io| io.read || ""; }
757
+ end
758
+
759
+ def el4r_wait_expr_loop
760
+ el4r_wait_expr until @emacs_in.eof?
761
+ end
762
+
763
+ def el4r_wait_expr
764
+ @last_error = nil
765
+ el4r_with_call {
766
+ lispexpr = nil
767
+ begin
768
+ result = el4r_get
769
+ el4r_debug { "Result: <#{result.inspect}>"; }
770
+ lispexpr = el4r_ruby2lisp(result)
771
+ rescue ELError
772
+ el4r_debug { "Passing lisp error: #{ErrorUtils.stacktrace_message($!)}"; }
773
+ lispexpr = "(el4r-signal-last-error)"
774
+ rescue StandardError, ScriptError
775
+ @last_error or
776
+ el4r_log("Error: #{ErrorUtils.stacktrace_message($!)}")
777
+ @last_error = $!
778
+ lispexpr = "(signal 'el4r-ruby-error nil)"
779
+ end
780
+ el4r_send(lispexpr)
781
+ }
782
+ end
783
+
784
+ def el4r_get
785
+ expr = el4r_recv
786
+ while expr.empty?
787
+ el4r_debug { "Received callback interrupt."; }
788
+ el4r_wait_expr
789
+ expr = el4r_recv
790
+ end
791
+ el4r_ruby_eval(expr)
792
+ end
793
+
794
+ def el4r_recv
795
+ el4r_debug { "Waiting for Ruby expression"; }
796
+ expr = @emacs_in.readline("\0\n")
797
+ expr.slice!(-2, 2)
798
+ el4r_debug { "Received Ruby expression: #{expr}"; }
799
+ expr
800
+ end
801
+
802
+ def el4r_send(lispexpr)
803
+ el4r_debug { "Sending Lisp expression: #{lispexpr}"; }
804
+ @emacs_out.print(lispexpr)
805
+ @emacs_out.print("\0")
806
+ @emacs_out.flush
807
+ end
808
+
809
+ def el4r_interrupt
810
+ el4r_debug { "Sending callback interrupt."; }
811
+ @emacs_out.print("\0")
812
+ end
813
+
814
+ # Create an ELObject.
815
+ def el4r_elobject_new(id, klass = nil)
816
+ (klass || ELObject).new(self, id)
817
+ end
818
+
819
+ # Write a log message if el4r is debug.
820
+ def el4r_debug(msg = nil, &block)
821
+ if @el4r_is_debug
822
+ msg ||= yield
823
+ el4r_log("[DEBUG] (#{@call_level}) #{msg}")
824
+ end
825
+ end
826
+
827
+ # Log IO object.
828
+ def el4r_log_io
829
+ @log
830
+ end
831
+
832
+ def el4r_with_call(&block)
833
+ @call_level += 1
834
+ begin
835
+ yield
836
+ ensure
837
+ @call_level -= 1
838
+ @call_level <= @el_backtrace_reset_threshold and @el_backtrace = []
839
+ end
840
+ end
841
+
842
+ # Eval +source.
843
+ # When an Exception is raised, write a stacktrace message to the log.
844
+ def el4r_ruby_eval(source)
845
+ begin
846
+ instance_eval(source)
847
+ rescue Exception
848
+ el4r_debug { "Error in evaluating '#{source}': #{ErrorUtils.stacktrace_message($!)}"; }
849
+ raise
850
+ end
851
+ end
852
+
853
+ def el4r_reraise_last_error
854
+ raise @last_error
855
+ end
856
+
857
+ def el4r_raise_lisp_error
858
+ msg = el4r_lisp_eval("(prin1-to-string el4r-last-error-desc)")
859
+ @el_backtrace << el4r_lisp_eval("(prin1-to-string el4r-error-lisp-expression)")
860
+ raise(ELError, "Error in lisp code.:#{msg}\n#{@el_backtrace.join("\n")}")
861
+ end
862
+
863
+ def el4r_callback?
864
+ @call_level != 0
865
+ end
866
+
867
+ # Treat EmacsLisp strings containing C-c, C-d, C-q, C-s, C-v, C-w, C-z
868
+ def el4r_treat_ctrl_codes(&block)
869
+ #File.unlink conf.temp_file if File.exist? conf.temp_file
870
+ let(:el4r_treat_ctrl_codes, true, &block)
871
+ end
872
+
873
+ private
874
+ # Install the built in functions.
875
+ def el4r_install_builtin_functions
876
+ el4r_load "stdlib.rb"
877
+ el4r_install_unittest_stuff
878
+ el4r_install_xemacs_workaround
879
+ end
880
+
881
+ def el4r_install_unittest_stuff
882
+ el4r_install_test_unit_testrunner
883
+ el4r_install_run_unittest
884
+ end
885
+
886
+ # Install el4r version of Test::Unit.
887
+ def el4r_install_test_unit_testrunner
888
+ require 'test/unit'
889
+ require 'test/unit/ui/console/testrunner'
890
+ require 'stringio'
891
+
892
+ eval <<-EOS
893
+ module ::Test
894
+ module Unit
895
+ module UI
896
+ module Console
897
+ class El4rTestRunner < TestRunner
898
+ OUTPUT = StringIO.new
899
+
900
+ def initialize(*args)
901
+ super
902
+ @io = OUTPUT
903
+ end
904
+ end
905
+ end
906
+ end
907
+
908
+ class TestCase
909
+ include ElMixin
910
+ extend ElMixin
911
+ end
912
+ end
913
+ end
914
+ EOS
915
+ end
916
+
917
+
918
+ # Install el4r-run-unittest.
919
+ def el4r_install_run_unittest
920
+ elvar.el4r_unittest_strip_instance_error = true
921
+ defun(:el4r_run_unittest, :interactive=>true) do
922
+ el4r_unittest_tweak_gc
923
+ save_some_buffers
924
+ load(elvar.el4r_unittest_file_name)
925
+ begin
926
+ runner_class = ::Test::Unit::UI::Console::El4rTestRunner
927
+ el4r_unittest_run_internal(runner_class)
928
+ ensure
929
+ out = runner_class::OUTPUT
930
+ display = el4r_make_unittest_output(out)
931
+ el4r_unittest_display_result(display)
932
+ @el_backtrace_reset_threshold = 2
933
+ out.string = ""
934
+ end
935
+ end #/defun
936
+ end
937
+
938
+ def el4r_unittest_tweak_gc
939
+ el4r_rubyobj_stock.gc_trigger_count = conf.unittest_ruby_gc_trigger_count
940
+ el4r_rubyobj_stock.gc_trigger_increment = conf.unittest_ruby_gc_trigger_increment
941
+ elvar.el4r_lisp_object_gc_trigger_count = conf.unittest_lisp_object_gc_trigger_count
942
+ elvar.el4r_lisp_object_gc_trigger_increment = conf.unittest_lisp_object_gc_trigger_increment
943
+ end
944
+
945
+ def el4r_unittest_run_internal(runner_class)
946
+ r = ::Test::Unit::AutoRunner.new(nil)
947
+ r.process_args(elvar.el4r_unittest_args.to_a)
948
+ r.runner = proc{|r| runner_class}
949
+ r.run
950
+ end
951
+
952
+ def el4r_make_unittest_output(out)
953
+ display = format("ruby %s (%s) [%s]\n", RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM)
954
+ display << "#{emacs_version}\n\n"
955
+ display << out.string
956
+ display.gsub!(/^ +.+el4r-instance:\d+.*\n/,'') if elvar.el4r_unittest_strip_instance_error
957
+ display
958
+ end
959
+
960
+ def el4r_unittest_display_result(display)
961
+ let(:ee_buffer_name, "*el4r:unittest*"){
962
+ if elvar.noninteractive
963
+ princ(display)
964
+ else
965
+ switch_to_buffer "*Result*"
966
+ unittest_mode
967
+ elvar.buffer_read_only = nil
968
+ erase_buffer
969
+ insert display
970
+ elvar.buffer_read_only = true
971
+ goto_char 1
972
+ fundamental_mode
973
+ delete_other_windows
974
+ end
975
+ }
976
+ end
977
+
978
+ # Install an xemacs workaround.
979
+ def el4r_install_xemacs_workaround
980
+ # delete-other-windows at xemacs workaround! very nasty hack!
981
+ if elvar.noninteractive and featurep(:xemacs)
982
+ defun(:delete_other_windows) do
983
+ windows = []
984
+ walk_windows{|w| windows << w}
985
+
986
+ curwin = selected_window
987
+ windows.each do |w|
988
+ delete_window w unless eq(w,curwin)
989
+ end
990
+ select_window curwin
991
+ nil
992
+ end #/defun
993
+ end #/if
994
+
995
+ end #/def
996
+
997
+ end #/ELInstance
998
+ end #/El4r
999
+
1000
+ module El4rAccessor
1001
+ # The el4r object.
1002
+ def el4r
1003
+ $el
1004
+ end
1005
+
1006
+ end
1007
+
1008
+ # A mix-in to add EmacsRuby features.
1009
+ module ElMixin
1010
+ include El4rAccessor
1011
+ # Eval the block in the el4r context.
1012
+ # +outer+ is the caller of this method.
1013
+ def elisp(&block)
1014
+ el4r.outer = self
1015
+ el4r.instance_eval(&block)
1016
+ end
1017
+
1018
+ def method_missing(func, *args, &block)
1019
+ el4r.__send__(func, *args, &block)
1020
+ end
1021
+
1022
+ end
1023
+
1024
+ # A class with EmacsRuby features.
1025
+ class ElApp
1026
+ include ElMixin
1027
+ extend El4rAccessor
1028
+ @@instances = {}
1029
+
1030
+ # Run the application.
1031
+ def self.run(params={})
1032
+ obj = new(params)
1033
+ (@@instances[self] ||= []) << obj # preserve from GC
1034
+ process_defun(obj)
1035
+ obj
1036
+ end
1037
+
1038
+ def self._change_receiver_of(orgblock, obj, name)
1039
+ ## HACK Yuck!
1040
+ defunmeth = "#{name}__defun__"
1041
+ define_method(defunmeth, orgblock)
1042
+ private defunmeth
1043
+
1044
+ obj.instance_eval{ lambda{|*args| __send__(defunmeth, *args)}}
1045
+ end
1046
+ private_class_method :_change_receiver_of
1047
+
1048
+ def self.process_defun(obj)
1049
+ (@defuns || []).each do |name, attrs, block|
1050
+ block = _change_receiver_of(block, obj, name)
1051
+ obj.defun(name, attrs, &block)
1052
+ end
1053
+ end
1054
+ private_class_method :process_defun
1055
+
1056
+ def initialize(params)
1057
+ end
1058
+
1059
+ # EmacsLisp's defun. See El4r::ELMethodsMixin#defun.
1060
+ #
1061
+ # It is a convenient defun. Note that +block+ is evaluated within a
1062
+ # context of INSTANCE.
1063
+ def self.defun(name, attrs=nil, &block)
1064
+ (@defuns ||= []) << [name, attrs, block]
1065
+ end
1066
+
1067
+ extend SingleForwardable
1068
+
1069
+ # Import EmacsLisp (and El4r::ELMethodsMixin) functions within class definition.
1070
+
1071
+ def self.import_function(*funcs)
1072
+ def_delegators :el4r, *funcs
1073
+ end
1074
+ import_function :defvar, :el4r_lisp_eval
1075
+
1076
+ end
1077
+
1078
+ if __FILE__ == $0
1079
+ el4r = El4r::ELInstance.new __conf__
1080
+ $el = el4r # backward compatibility
1081
+ STDERR.reopen(el4r.el4r_log_io)
1082
+
1083
+ finalizer = lambda {
1084
+ el4r.el4r_log "Caught SIGTERM, exiting."
1085
+ logfile = el4r.el4r_log_io.path
1086
+ File.unlink logfile if !ENV["EL4R_PRESERVE_LOG"] and logfile and File.exist? logfile
1087
+ exit 0
1088
+ }
1089
+ trap(:TERM, &finalizer)
1090
+ trap(:HUP, &finalizer) rescue nil # for windows
1091
+
1092
+ el4r.el4r_log "Starting, waiting for expression."
1093
+ begin
1094
+ el4r.el4r_wait_expr_loop
1095
+ rescue Exception
1096
+ el4r.el4r_log El4r::ErrorUtils.stacktrace_message($!)
1097
+ ensure
1098
+ el4r.el4r_log "Exiting."
1099
+ end
1100
+ end
1101
+
1102
+ # Local Variables:
1103
+ # mode: ruby
1104
+ # test-script: "../testing/test-el4r.rb"
1105
+ # End: