html-template-pro 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. data/.autotest +9 -0
  2. data/ARTISTIC +131 -0
  3. data/History.txt +4 -0
  4. data/LGPL +504 -0
  5. data/Manifest.txt +221 -0
  6. data/README.rdoc +52 -0
  7. data/Rakefile +18 -0
  8. data/benchmark.rb +136 -0
  9. data/config/website.yml +2 -0
  10. data/ext/html/template/internal/Pro.xs +679 -0
  11. data/ext/html/template/internal/builtin_findfile.inc +361 -0
  12. data/ext/html/template/internal/calc.h +26 -0
  13. data/ext/html/template/internal/calc.inc +120 -0
  14. data/ext/html/template/internal/callback_stubs.inc +63 -0
  15. data/ext/html/template/internal/expr.c +2267 -0
  16. data/ext/html/template/internal/expr.y +476 -0
  17. data/ext/html/template/internal/expr_iface.c +94 -0
  18. data/ext/html/template/internal/exprpstr.h +36 -0
  19. data/ext/html/template/internal/exprpstr.inc +144 -0
  20. data/ext/html/template/internal/exprtool.h +99 -0
  21. data/ext/html/template/internal/exprtool.inc +289 -0
  22. data/ext/html/template/internal/exprtype.h +62 -0
  23. data/ext/html/template/internal/exprval.h +30 -0
  24. data/ext/html/template/internal/extconf.rb +6 -0
  25. data/ext/html/template/internal/internal.c +449 -0
  26. data/ext/html/template/internal/loadfile.h +11 -0
  27. data/ext/html/template/internal/loadfile.inc +171 -0
  28. data/ext/html/template/internal/pabidecl.h +54 -0
  29. data/ext/html/template/internal/pabstract.h +426 -0
  30. data/ext/html/template/internal/parse_expr.h +15 -0
  31. data/ext/html/template/internal/pbuffer.c +76 -0
  32. data/ext/html/template/internal/pbuffer.h +31 -0
  33. data/ext/html/template/internal/pmiscdef.h +54 -0
  34. data/ext/html/template/internal/pparam.h +101 -0
  35. data/ext/html/template/internal/ppport.h +1098 -0
  36. data/ext/html/template/internal/procore.c +1189 -0
  37. data/ext/html/template/internal/procore.h +18 -0
  38. data/ext/html/template/internal/proparam.c +443 -0
  39. data/ext/html/template/internal/proparam.h +571 -0
  40. data/ext/html/template/internal/proscope.h +32 -0
  41. data/ext/html/template/internal/proscope.inc +107 -0
  42. data/ext/html/template/internal/prostate.h +49 -0
  43. data/ext/html/template/internal/prostate.inc +24 -0
  44. data/ext/html/template/internal/provalue.h +14 -0
  45. data/ext/html/template/internal/pstring.h +60 -0
  46. data/ext/html/template/internal/pstrutils.h +25 -0
  47. data/ext/html/template/internal/pstrutils.inc +150 -0
  48. data/ext/html/template/internal/tagstack.h +30 -0
  49. data/ext/html/template/internal/tagstack.inc +65 -0
  50. data/ext/html/template/internal/tmpllog.c +62 -0
  51. data/ext/html/template/internal/tmpllog.h +27 -0
  52. data/ext/html/template/internal/tmplpro.h +218 -0
  53. data/ext/html/template/internal/tmplpro_version.c +35 -0
  54. data/lib/html/template/pro.rb +225 -0
  55. data/script/console +10 -0
  56. data/script/destroy +14 -0
  57. data/script/generate +14 -0
  58. data/script/txt2html +71 -0
  59. data/tasks/extconf.rake +13 -0
  60. data/tasks/extconf/tmplpro.rake +43 -0
  61. data/templates-Pro/a.incl +1 -0
  62. data/templates-Pro/empty.incl +0 -0
  63. data/templates-Pro/include/1/a.incl +1 -0
  64. data/templates-Pro/include/2.out +3 -0
  65. data/templates-Pro/include/2.tmpl +1 -0
  66. data/templates-Pro/include/2/a.incl +1 -0
  67. data/templates-Pro/include/3.tmpl +1 -0
  68. data/templates-Pro/include/4.tmpl +1 -0
  69. data/templates-Pro/include/a.incl +1 -0
  70. data/templates-Pro/test_broken.tmpl +25 -0
  71. data/templates-Pro/test_broken1.out +1 -0
  72. data/templates-Pro/test_broken1.tmpl +1 -0
  73. data/templates-Pro/test_esc1.out +4 -0
  74. data/templates-Pro/test_esc1.tmpl +4 -0
  75. data/templates-Pro/test_esc2.out +5 -0
  76. data/templates-Pro/test_esc2.tmpl +6 -0
  77. data/templates-Pro/test_esc3.out +4 -0
  78. data/templates-Pro/test_esc3.tmpl +4 -0
  79. data/templates-Pro/test_esc4.out +3 -0
  80. data/templates-Pro/test_esc4.tmpl +4 -0
  81. data/templates-Pro/test_expr1.out +26 -0
  82. data/templates-Pro/test_expr1.tmpl +26 -0
  83. data/templates-Pro/test_expr2.out +34 -0
  84. data/templates-Pro/test_expr2.tmpl +34 -0
  85. data/templates-Pro/test_expr3.out +6 -0
  86. data/templates-Pro/test_expr3.tmpl +6 -0
  87. data/templates-Pro/test_expr4.out +4 -0
  88. data/templates-Pro/test_expr4.tmpl +4 -0
  89. data/templates-Pro/test_expr5.out +18 -0
  90. data/templates-Pro/test_expr5.tmpl +18 -0
  91. data/templates-Pro/test_expr6.out +18 -0
  92. data/templates-Pro/test_expr6.tmpl +18 -0
  93. data/templates-Pro/test_expr7.out +44 -0
  94. data/templates-Pro/test_expr7.tmpl +20 -0
  95. data/templates-Pro/test_expr8.out +15 -0
  96. data/templates-Pro/test_expr8.tmpl +15 -0
  97. data/templates-Pro/test_if1.out +25 -0
  98. data/templates-Pro/test_if1.tmpl +28 -0
  99. data/templates-Pro/test_if2.out +17 -0
  100. data/templates-Pro/test_if2.tmpl +25 -0
  101. data/templates-Pro/test_if3.out +12 -0
  102. data/templates-Pro/test_if3.tmpl +14 -0
  103. data/templates-Pro/test_if4.out +15 -0
  104. data/templates-Pro/test_if4.tmpl +31 -0
  105. data/templates-Pro/test_if5.out +16 -0
  106. data/templates-Pro/test_if5.tmpl +16 -0
  107. data/templates-Pro/test_if6.out +15 -0
  108. data/templates-Pro/test_if6.tmpl +31 -0
  109. data/templates-Pro/test_if7.out +14 -0
  110. data/templates-Pro/test_if7.tmpl +18 -0
  111. data/templates-Pro/test_include1.out +23 -0
  112. data/templates-Pro/test_include1.tmpl +7 -0
  113. data/templates-Pro/test_include2.out +120 -0
  114. data/templates-Pro/test_include2.tmpl +10 -0
  115. data/templates-Pro/test_include3.out +8 -0
  116. data/templates-Pro/test_include3.tmpl +8 -0
  117. data/templates-Pro/test_include4.out +7 -0
  118. data/templates-Pro/test_include4.tmpl +6 -0
  119. data/templates-Pro/test_include5.out +7 -0
  120. data/templates-Pro/test_include5.tmpl +6 -0
  121. data/templates-Pro/test_loop1.erb +17 -0
  122. data/templates-Pro/test_loop1.out +12 -0
  123. data/templates-Pro/test_loop1.tmpl +16 -0
  124. data/templates-Pro/test_loop2.erb +19 -0
  125. data/templates-Pro/test_loop2.out +40 -0
  126. data/templates-Pro/test_loop2.tmpl +19 -0
  127. data/templates-Pro/test_loop3.out +38 -0
  128. data/templates-Pro/test_loop3.tmpl +40 -0
  129. data/templates-Pro/test_loop4.out +44 -0
  130. data/templates-Pro/test_loop4.tmpl +20 -0
  131. data/templates-Pro/test_loop5.out +9 -0
  132. data/templates-Pro/test_loop5.tmpl +11 -0
  133. data/templates-Pro/test_loop6.out +33 -0
  134. data/templates-Pro/test_loop6.tmpl +15 -0
  135. data/templates-Pro/test_malloc.tmpl +1 -0
  136. data/templates-Pro/test_userfunc1.out +14 -0
  137. data/templates-Pro/test_userfunc1.tmpl +14 -0
  138. data/templates-Pro/test_userfunc2.out +35 -0
  139. data/templates-Pro/test_userfunc2.tmpl +5 -0
  140. data/templates-Pro/test_userfunc3.out +5 -0
  141. data/templates-Pro/test_userfunc3.tmpl +5 -0
  142. data/templates-Pro/test_userfunc4.out +10 -0
  143. data/templates-Pro/test_userfunc4.tmpl +10 -0
  144. data/templates-Pro/test_userfunc5.out +4 -0
  145. data/templates-Pro/test_userfunc5.tmpl +4 -0
  146. data/templates-Pro/test_userfunc6.out +4 -0
  147. data/templates-Pro/test_userfunc6.tmpl +4 -0
  148. data/templates-Pro/test_var1.erb +23 -0
  149. data/templates-Pro/test_var1.out +20 -0
  150. data/templates-Pro/test_var1.tmpl +23 -0
  151. data/templates-Pro/test_var2.erb +7 -0
  152. data/templates-Pro/test_var2.out +6 -0
  153. data/templates-Pro/test_var2.tmpl +7 -0
  154. data/templates-Pro/test_var3.out +14 -0
  155. data/templates-Pro/test_var3.tmpl +16 -0
  156. data/templates/case_loop.tmpl +3 -0
  157. data/templates/context.tmpl +3 -0
  158. data/templates/counter.tmpl +2 -0
  159. data/templates/default.tmpl +1 -0
  160. data/templates/default_escape.tmpl +4 -0
  161. data/templates/double_loop.tmpl +7 -0
  162. data/templates/escape.tmpl +5 -0
  163. data/templates/global-loops.tmpl +9 -0
  164. data/templates/globals.tmpl +11 -0
  165. data/templates/if.tmpl +7 -0
  166. data/templates/ifelse.tmpl +6 -0
  167. data/templates/include.tmpl +14 -0
  168. data/templates/include_path/a.tmpl +2 -0
  169. data/templates/include_path/b.tmpl +1 -0
  170. data/templates/include_path/inner.tmpl +1 -0
  171. data/templates/include_path/one.tmpl +2 -0
  172. data/templates/include_path2/inner.tmpl +1 -0
  173. data/templates/included.tmpl +4 -0
  174. data/templates/included2.tmpl +3 -0
  175. data/templates/js.tmpl +1 -0
  176. data/templates/long_loops.tmpl +307 -0
  177. data/templates/loop-context.tmpl +2 -0
  178. data/templates/loop-if.tmpl +9 -0
  179. data/templates/medium.tmpl +217 -0
  180. data/templates/multiline_tags.tmpl +7 -0
  181. data/templates/newline_test1.tmpl +1 -0
  182. data/templates/newline_test2.tmpl +1 -0
  183. data/templates/other-loop.tmpl +7 -0
  184. data/templates/outer.tmpl +3 -0
  185. data/templates/query-test.tmpl +21 -0
  186. data/templates/query-test2.tmpl +12 -0
  187. data/templates/recursive.tmpl +2 -0
  188. data/templates/searchpath/included.tmpl +4 -0
  189. data/templates/searchpath/three.tmpl +1 -0
  190. data/templates/searchpath/two.tmpl +2 -0
  191. data/templates/simple-loop-nonames.tmpl +13 -0
  192. data/templates/simple-loop.tmpl +12 -0
  193. data/templates/simple.tmpl +9 -0
  194. data/templates/unless.tmpl +5 -0
  195. data/templates/urlescape.tmpl +3 -0
  196. data/templates/vanguard1.tmpl +2 -0
  197. data/templates/vanguard2.tmpl +3 -0
  198. data/test/templates/complex.tmpl +24 -0
  199. data/test/templates/foo.tmpl +6 -0
  200. data/test/templates/func.tmpl +2 -0
  201. data/test/templates/loop.tmpl +14 -0
  202. data/test/templates/negative.tmpl +1 -0
  203. data/test/templates/numerics.tmpl +6 -0
  204. data/test/templates/register.tmpl +2 -0
  205. data/test/test_basic.rb +23 -0
  206. data/test/test_coderefs.rb +16 -0
  207. data/test/test_complex.rb +106 -0
  208. data/test/test_helper.rb +3 -0
  209. data/test/test_html_template.rb +583 -0
  210. data/test/test_html_template_internal_extn.rb +10 -0
  211. data/test/test_html_template_pro.rb +177 -0
  212. data/test/test_path_like_variable_scope.rb +59 -0
  213. data/test/test_random.rb +21 -0
  214. data/test/test_realloc.rb +16 -0
  215. data/test/test_register.rb +25 -0
  216. data/test/test_tmplpro.rb +9 -0
  217. data/test/tests.rb +9 -0
  218. data/website/index.txt +57 -0
  219. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  220. data/website/stylesheets/screen.css +159 -0
  221. data/website/template.html.erb +50 -0
  222. metadata +303 -0
@@ -0,0 +1,221 @@
1
+ .autotest
2
+ ARTISTIC
3
+ History.txt
4
+ LGPL
5
+ Manifest.txt
6
+ README.rdoc
7
+ Rakefile
8
+ benchmark.rb
9
+ config/website.yml
10
+ ext/html/template/internal/Pro.xs
11
+ ext/html/template/internal/builtin_findfile.inc
12
+ ext/html/template/internal/calc.h
13
+ ext/html/template/internal/calc.inc
14
+ ext/html/template/internal/callback_stubs.inc
15
+ ext/html/template/internal/expr.c
16
+ ext/html/template/internal/expr.y
17
+ ext/html/template/internal/expr_iface.c
18
+ ext/html/template/internal/exprpstr.h
19
+ ext/html/template/internal/exprpstr.inc
20
+ ext/html/template/internal/exprtool.h
21
+ ext/html/template/internal/exprtool.inc
22
+ ext/html/template/internal/exprtype.h
23
+ ext/html/template/internal/exprval.h
24
+ ext/html/template/internal/extconf.rb
25
+ ext/html/template/internal/internal.c
26
+ ext/html/template/internal/loadfile.h
27
+ ext/html/template/internal/loadfile.inc
28
+ ext/html/template/internal/pabidecl.h
29
+ ext/html/template/internal/pabstract.h
30
+ ext/html/template/internal/parse_expr.h
31
+ ext/html/template/internal/pbuffer.c
32
+ ext/html/template/internal/pbuffer.h
33
+ ext/html/template/internal/pmiscdef.h
34
+ ext/html/template/internal/pparam.h
35
+ ext/html/template/internal/ppport.h
36
+ ext/html/template/internal/procore.c
37
+ ext/html/template/internal/procore.h
38
+ ext/html/template/internal/proparam.c
39
+ ext/html/template/internal/proparam.h
40
+ ext/html/template/internal/proscope.h
41
+ ext/html/template/internal/proscope.inc
42
+ ext/html/template/internal/prostate.h
43
+ ext/html/template/internal/prostate.inc
44
+ ext/html/template/internal/provalue.h
45
+ ext/html/template/internal/pstring.h
46
+ ext/html/template/internal/pstrutils.h
47
+ ext/html/template/internal/pstrutils.inc
48
+ ext/html/template/internal/tagstack.h
49
+ ext/html/template/internal/tagstack.inc
50
+ ext/html/template/internal/tmpllog.c
51
+ ext/html/template/internal/tmpllog.h
52
+ ext/html/template/internal/tmplpro.h
53
+ ext/html/template/internal/tmplpro_version.c
54
+ lib/html/template/pro.rb
55
+ script/console
56
+ script/destroy
57
+ script/generate
58
+ script/txt2html
59
+ tasks/extconf.rake
60
+ tasks/extconf/tmplpro.rake
61
+ templates-Pro/a.incl
62
+ templates-Pro/empty.incl
63
+ templates-Pro/include/1/a.incl
64
+ templates-Pro/include/2.out
65
+ templates-Pro/include/2.tmpl
66
+ templates-Pro/include/2/a.incl
67
+ templates-Pro/include/3.tmpl
68
+ templates-Pro/include/4.tmpl
69
+ templates-Pro/include/a.incl
70
+ templates-Pro/test_broken.tmpl
71
+ templates-Pro/test_broken1.out
72
+ templates-Pro/test_broken1.tmpl
73
+ templates-Pro/test_esc1.out
74
+ templates-Pro/test_esc1.tmpl
75
+ templates-Pro/test_esc2.out
76
+ templates-Pro/test_esc2.tmpl
77
+ templates-Pro/test_esc3.out
78
+ templates-Pro/test_esc3.tmpl
79
+ templates-Pro/test_esc4.out
80
+ templates-Pro/test_esc4.tmpl
81
+ templates-Pro/test_expr1.out
82
+ templates-Pro/test_expr1.tmpl
83
+ templates-Pro/test_expr2.out
84
+ templates-Pro/test_expr2.tmpl
85
+ templates-Pro/test_expr3.out
86
+ templates-Pro/test_expr3.tmpl
87
+ templates-Pro/test_expr4.out
88
+ templates-Pro/test_expr4.tmpl
89
+ templates-Pro/test_expr5.out
90
+ templates-Pro/test_expr5.tmpl
91
+ templates-Pro/test_expr6.out
92
+ templates-Pro/test_expr6.tmpl
93
+ templates-Pro/test_expr7.out
94
+ templates-Pro/test_expr7.tmpl
95
+ templates-Pro/test_expr8.out
96
+ templates-Pro/test_expr8.tmpl
97
+ templates-Pro/test_if1.out
98
+ templates-Pro/test_if1.tmpl
99
+ templates-Pro/test_if2.out
100
+ templates-Pro/test_if2.tmpl
101
+ templates-Pro/test_if3.out
102
+ templates-Pro/test_if3.tmpl
103
+ templates-Pro/test_if4.out
104
+ templates-Pro/test_if4.tmpl
105
+ templates-Pro/test_if5.out
106
+ templates-Pro/test_if5.tmpl
107
+ templates-Pro/test_if6.out
108
+ templates-Pro/test_if6.tmpl
109
+ templates-Pro/test_if7.out
110
+ templates-Pro/test_if7.tmpl
111
+ templates-Pro/test_include1.out
112
+ templates-Pro/test_include1.tmpl
113
+ templates-Pro/test_include2.out
114
+ templates-Pro/test_include2.tmpl
115
+ templates-Pro/test_include3.out
116
+ templates-Pro/test_include3.tmpl
117
+ templates-Pro/test_include4.out
118
+ templates-Pro/test_include4.tmpl
119
+ templates-Pro/test_include5.out
120
+ templates-Pro/test_include5.tmpl
121
+ templates-Pro/test_loop1.erb
122
+ templates-Pro/test_loop1.out
123
+ templates-Pro/test_loop1.tmpl
124
+ templates-Pro/test_loop2.erb
125
+ templates-Pro/test_loop2.out
126
+ templates-Pro/test_loop2.tmpl
127
+ templates-Pro/test_loop3.out
128
+ templates-Pro/test_loop3.tmpl
129
+ templates-Pro/test_loop4.out
130
+ templates-Pro/test_loop4.tmpl
131
+ templates-Pro/test_loop5.out
132
+ templates-Pro/test_loop5.tmpl
133
+ templates-Pro/test_loop6.out
134
+ templates-Pro/test_loop6.tmpl
135
+ templates-Pro/test_malloc.tmpl
136
+ templates-Pro/test_userfunc1.out
137
+ templates-Pro/test_userfunc1.tmpl
138
+ templates-Pro/test_userfunc2.out
139
+ templates-Pro/test_userfunc2.tmpl
140
+ templates-Pro/test_userfunc3.out
141
+ templates-Pro/test_userfunc3.tmpl
142
+ templates-Pro/test_userfunc4.out
143
+ templates-Pro/test_userfunc4.tmpl
144
+ templates-Pro/test_userfunc5.out
145
+ templates-Pro/test_userfunc5.tmpl
146
+ templates-Pro/test_userfunc6.out
147
+ templates-Pro/test_userfunc6.tmpl
148
+ templates-Pro/test_var1.erb
149
+ templates-Pro/test_var1.out
150
+ templates-Pro/test_var1.tmpl
151
+ templates-Pro/test_var2.erb
152
+ templates-Pro/test_var2.out
153
+ templates-Pro/test_var2.tmpl
154
+ templates-Pro/test_var3.out
155
+ templates-Pro/test_var3.tmpl
156
+ templates/case_loop.tmpl
157
+ templates/context.tmpl
158
+ templates/counter.tmpl
159
+ templates/default.tmpl
160
+ templates/default_escape.tmpl
161
+ templates/double_loop.tmpl
162
+ templates/escape.tmpl
163
+ templates/global-loops.tmpl
164
+ templates/globals.tmpl
165
+ templates/if.tmpl
166
+ templates/ifelse.tmpl
167
+ templates/include.tmpl
168
+ templates/include_path/a.tmpl
169
+ templates/include_path/b.tmpl
170
+ templates/include_path/inner.tmpl
171
+ templates/include_path/one.tmpl
172
+ templates/include_path2/inner.tmpl
173
+ templates/included.tmpl
174
+ templates/included2.tmpl
175
+ templates/js.tmpl
176
+ templates/long_loops.tmpl
177
+ templates/loop-context.tmpl
178
+ templates/loop-if.tmpl
179
+ templates/medium.tmpl
180
+ templates/multiline_tags.tmpl
181
+ templates/newline_test1.tmpl
182
+ templates/newline_test2.tmpl
183
+ templates/other-loop.tmpl
184
+ templates/outer.tmpl
185
+ templates/query-test.tmpl
186
+ templates/query-test2.tmpl
187
+ templates/recursive.tmpl
188
+ templates/searchpath/included.tmpl
189
+ templates/searchpath/three.tmpl
190
+ templates/searchpath/two.tmpl
191
+ templates/simple-loop-nonames.tmpl
192
+ templates/simple-loop.tmpl
193
+ templates/simple.tmpl
194
+ templates/unless.tmpl
195
+ templates/urlescape.tmpl
196
+ templates/vanguard1.tmpl
197
+ templates/vanguard2.tmpl
198
+ test/templates/complex.tmpl
199
+ test/templates/foo.tmpl
200
+ test/templates/func.tmpl
201
+ test/templates/loop.tmpl
202
+ test/templates/negative.tmpl
203
+ test/templates/numerics.tmpl
204
+ test/templates/register.tmpl
205
+ test/test_basic.rb
206
+ test/test_coderefs.rb
207
+ test/test_complex.rb
208
+ test/test_helper.rb
209
+ test/test_html_template.rb
210
+ test/test_html_template_internal_extn.rb
211
+ test/test_html_template_pro.rb
212
+ test/test_path_like_variable_scope.rb
213
+ test/test_random.rb
214
+ test/test_realloc.rb
215
+ test/test_register.rb
216
+ test/test_tmplpro.rb
217
+ test/tests.rb
218
+ website/index.txt
219
+ website/javascripts/rounded_corners_lite.inc.js
220
+ website/stylesheets/screen.css
221
+ website/template.html.erb
@@ -0,0 +1,52 @@
1
+ = tmplpro
2
+
3
+ * http://github.com/tom-lpsd/ruby-html-template-pro
4
+
5
+ == DESCRIPTION:
6
+
7
+ A Ruby port of HTML::Template::Pro (template engine originally written
8
+ in Perl and XS).
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Fast. (Main part is written in C.)
13
+ * Simple. (It avoids mixing up complex logic in View.)
14
+
15
+ == SYNOPSIS:
16
+
17
+ # foo.rb
18
+ require 'html/template/pro'
19
+
20
+ template = HTML::Template::Pro.new(:filename => 'foo.tmpl')
21
+ template.param(:param1 => 100)
22
+ puts template.output
23
+
24
+ # foo.tmpl
25
+ <html>
26
+ <head></head>
27
+ <body>
28
+ <h1><TMPL_VAR NAME="param1"></h1>
29
+ </body>
30
+ </html>
31
+
32
+ # results
33
+ $ ruby foo.rb
34
+ <html>
35
+ <head></head>
36
+ <body>
37
+ <h1>100</h1>
38
+ </body>
39
+ </html>
40
+
41
+
42
+ == REQUIREMENTS:
43
+
44
+ * C99 C compiler.
45
+
46
+ == INSTALL:
47
+
48
+ * sudo gem install html-template-pro
49
+
50
+ == LICENSE:
51
+
52
+ LGPL
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+
6
+ Hoe.plugin :newgem
7
+ Hoe.plugin :website
8
+
9
+ $hoe = Hoe.spec 'html-template-pro' do
10
+ self.developer 'Tsuruhara Tom', 'tom.lpsd@gmail.com'
11
+ self.rubyforge_name = 'tmplpro'
12
+ self.version = "0.0.1"
13
+ self.summary = 'A Ruby port of HTML::Template::Pro'
14
+ self.extra_rdoc_files = ['README.rdoc']
15
+ end
16
+
17
+ require 'newgem/tasks'
18
+ Dir['tasks/**/*.rake'].each { |t| load t }
@@ -0,0 +1,136 @@
1
+ require 'benchmark'
2
+ require 'erb'
3
+ require 'erubis'
4
+ require 'html/template/pro'
5
+
6
+ varset1 = { :VAR1 => 'VAR1', :VAR2 => 'VAR2', :VAR3 => 'VAR3', :VAR10 => 'VAR10' }
7
+ varset2 = { :STUFF1 => '<>"; %FA' }
8
+
9
+ refset1 = {
10
+ :HASHREF0=>[],
11
+ :HASHREF2=>[{},{}],
12
+ :HASHREF1=>[
13
+ {:LOOPVAR1=>'LOOP1-VAR1',:LOOPVAR2=>'LOOP1-VAR2',:LOOPVAR3=>'LOOP1-VAR3',:LOOPVAR10=>'LOOP1-VAR10'},
14
+ {:LOOPVAR1=>'LOOP2-VAR1',:LOOPVAR2=>'LOOP2-VAR2',:LOOPVAR3=>'LOOP2-VAR3',:LOOPVAR10=>'LOOP2-VAR10'},
15
+ {:LOOPVAR1=>'LOOP3-VAR1',:LOOPVAR2=>'LOOP3-VAR2',:LOOPVAR3=>'LOOP3-VAR3',:LOOPVAR10=>'LOOP3-VAR10'},
16
+ {:LOOPVAR1=>'LOOP4-VAR1',:LOOPVAR2=>'LOOP4-VAR2',:LOOPVAR3=>'LOOP4-VAR3',:LOOPVAR10=>'LOOP4-VAR10'},
17
+ ]
18
+ }
19
+
20
+ # -------------------------
21
+
22
+ def test_tmpl(file, *args)
23
+ params = args.inject({}) do |result, item|
24
+ result.update(item)
25
+ end
26
+ testname = file
27
+ test_tmpl_complete(testname, params)
28
+ test_tmpl_output(testname, params)
29
+ end
30
+
31
+ def test_tmpl_output(testname, params)
32
+ Dir.chdir 'templates-Pro'
33
+ file = testname
34
+ count = 1000
35
+
36
+ tmplo = HTML::Template::Pro.new(:filename => file + '.tmpl',
37
+ :die_on_bad_params => false,
38
+ :strict => false,
39
+ :case_sensitive => false,
40
+ :loop_context_vars => true
41
+ )
42
+ tmplo.param(params);
43
+
44
+ File.open('/dev/null', 'w') do |file|
45
+ puts "Template::Pro " + '-' * 40
46
+ puts Benchmark::CAPTION
47
+ puts Benchmark.measure{
48
+ count.times do
49
+ tmplo.output(:print_to => file)
50
+ end
51
+ }
52
+ end
53
+
54
+ erb = ERB.new(File.read(file + '.erb'))
55
+ File.open('/dev/null', 'w') do |file|
56
+ puts "ERB " + '-' * 40
57
+ puts Benchmark::CAPTION
58
+ puts Benchmark.measure{
59
+ count.times do
60
+ file.puts erb.result(binding)
61
+ end
62
+ }
63
+ end
64
+
65
+ erubis = Erubis::FastEruby.new(File.read(file + '.erb'))
66
+ File.open('/dev/null', 'w') do |file|
67
+ puts "Erubis " + '-' * 40
68
+ puts Benchmark::CAPTION
69
+ puts Benchmark.measure{
70
+ count.times do
71
+ file.puts erubis.result(binding)
72
+ end
73
+ }
74
+ end
75
+
76
+ Dir.chdir '..'
77
+ end
78
+
79
+ def test_tmpl_complete(testname, params)
80
+ Dir.chdir 'templates-Pro';
81
+ file = testname
82
+ count = 1000
83
+
84
+ File.open('/dev/null', 'w') do |file|
85
+ puts "Template::Pro " + '-' * 40
86
+ puts Benchmark::CAPTION
87
+ puts Benchmark.measure{
88
+ count.times do
89
+ tmpl = HTML::Template::Pro.new(:filename => testname + '.tmpl',
90
+ :loop_context_vars => true,
91
+ :case_sensitive => false,
92
+ :die_on_bad_params => false)
93
+ tmpl.param(params)
94
+ tmpl.output(:print_to => file)
95
+ end
96
+ }
97
+ end
98
+
99
+ File.open('/dev/null', 'w') do |file|
100
+ puts "ERB " + '-' * 40
101
+ puts Benchmark::CAPTION
102
+ puts Benchmark.measure{
103
+ count.times do
104
+ erb = ERB.new(File.read(testname + '.erb'))
105
+ file.puts erb.result(binding)
106
+ end
107
+ }
108
+ end
109
+
110
+ File.open('/dev/null', 'w') do |file|
111
+ puts "Erubis " + '-' * 40
112
+ puts Benchmark::CAPTION
113
+ puts Benchmark.measure{
114
+ count.times do
115
+ erubis = Erubis::FastEruby.new(File.read(testname + '.erb'))
116
+ file.puts erubis.result(binding)
117
+ end
118
+ }
119
+ end
120
+
121
+ Dir.chdir '..'
122
+ end
123
+
124
+ test_tmpl('test_var1', varset1);
125
+ test_tmpl('test_var2', varset1);
126
+ test_tmpl('test_loop1', varset1, refset1);
127
+ test_tmpl('test_loop2', varset1, refset1);
128
+
129
+ __END__
130
+ test_tmpl('test_var3', varset1, varset2);
131
+ test_tmpl('test_if1', varset1);
132
+ test_tmpl('test_if2', varset1);
133
+ test_tmpl('test_if3', refset1);
134
+ test_tmpl('test_loop3', varset1, refset1);
135
+ test_tmpl('test_loop4', varset1, refset1);
136
+ test_tmpl('test_loop5', varset1, refset1);
@@ -0,0 +1,2 @@
1
+ host: tom-lpsd@rubyforge.org
2
+ remote_dir: /var/www/gforge-projects/tmplpro
@@ -0,0 +1,679 @@
1
+ #define PERLIO_NOT_STDIO 0 /* For co-existence with stdio only */
2
+ #define PERL_NO_GET_CONTEXT /* we want efficiency */
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+ #include "EXTERN.h"
8
+ #include "perl.h"
9
+ #include "XSUB.h"
10
+ #ifdef __cplusplus
11
+ }
12
+ #endif
13
+
14
+ #include <string.h>
15
+ #include <stdio.h>
16
+
17
+ #include "ppport.h"
18
+
19
+ #ifdef USE_SYSTEM_HTP_HEADER
20
+ #include <tmplpro.h>
21
+ #else
22
+ #include "tmplpro.h"
23
+ #endif
24
+
25
+ typedef PerlIO * OutputStream;
26
+
27
+ struct perl_callback_state {
28
+ SV* perl_obj_self_ptr;
29
+ AV* filtered_tmpl_array;
30
+ AV* pool_for_perl_vars;
31
+ int force_untaint;
32
+ };
33
+
34
+ static
35
+ int debuglevel=0;
36
+
37
+ /* endnext points on next character to end of interval as in c++ */
38
+ static void write_chars_to_file (ABSTRACT_WRITER* OutputFile, const char* begin, const char* endnext) {
39
+ dTHX; /* fetch context */
40
+ PerlIO_write((PerlIO*)OutputFile,begin, endnext-begin);
41
+ }
42
+
43
+ /* endnext points on next to end character of the interval */
44
+ static void write_chars_to_string (ABSTRACT_WRITER* OutputString, const char* begin, const char* endnext) {
45
+ dTHX; /* fetch context */
46
+ sv_catpvn((SV*)OutputString, begin, endnext-begin);
47
+ }
48
+
49
+ static
50
+ ABSTRACT_VALUE* get_ABSTRACT_VALUE_impl (ABSTRACT_DATASTATE* none, ABSTRACT_MAP* ptr_HV, PSTRING name) {
51
+ dTHX; /* fetch context */
52
+ return hv_fetch((HV*) ptr_HV,name.begin, name.endnext-name.begin, 0);
53
+ }
54
+
55
+ static
56
+ SV*
57
+ call_coderef (SV* coderef) {
58
+ SV* SVretval;
59
+ I32 count;
60
+ dTHX; /* fetch context */
61
+ /* TODO: G_EVAL and error handler */
62
+ dSP;
63
+
64
+ /* let perl clean up mortals after the end of output() call
65
+ ENTER;
66
+ SAVETMPS;*/
67
+
68
+ PUSHMARK(SP);
69
+ PUTBACK; /* in fact, isn't needed -- nothing is pushed and G_NOARGS is used */
70
+
71
+ count = call_sv(coderef, G_EVAL|G_SCALAR|G_NOARGS);
72
+ SPAGAIN;
73
+
74
+ /* Check the eval first */
75
+ if (SvTRUE(ERRSV))
76
+ {
77
+ STRLEN n_a;
78
+ printf ("Pro.xs: param tree code reference exited abnormally - %s\n", SvPV(ERRSV, n_a));
79
+ SVretval=POPs; /* undef */
80
+ }
81
+ else
82
+ {
83
+ if (count != 1)
84
+ croak("Pro.xs: internal context error (got %d) while calling CODE reference\n", count);
85
+ SVretval=POPs;
86
+ }
87
+
88
+ PUTBACK;
89
+ /* let perl clean up mortals after the end of output() call
90
+ FREETMPS;
91
+ LEAVE;*/
92
+ return SVretval;
93
+ }
94
+
95
+ static
96
+ PSTRING ABSTRACT_VALUE2PSTRING_impl (ABSTRACT_DATASTATE* callback_state, ABSTRACT_VALUE* valptr) {
97
+ STRLEN len=0;
98
+ PSTRING retval={NULL,NULL};
99
+ SV* SVval;
100
+ dTHX; /* fetch context */
101
+ if (valptr==NULL) return retval;
102
+ SVval = *((SV**) valptr);
103
+ SvGETMAGIC(SVval);
104
+ if (SvOK(SVval) && SvROK(SVval)) {
105
+ if (SvTYPE(SvRV(SVval))==SVt_PVCV) {
106
+ SVval = call_coderef(SVval);
107
+ } else {
108
+ SVval = SvRV(SVval);
109
+ }
110
+ SvGETMAGIC(SVval);
111
+ }
112
+ if (!SvOK(SVval)) return retval;
113
+ /* TODO param resource deallocation */
114
+ if (((struct perl_callback_state*) callback_state)->force_untaint && SVval && SvTAINTED(SVval))
115
+ croak("force_untaint: got tainted value %" SVf, SVval);
116
+
117
+ retval.begin=SvPV(SVval, len);
118
+ retval.endnext=retval.begin+len;
119
+ return retval;
120
+ }
121
+
122
+ static
123
+ int is_ABSTRACT_VALUE_true_impl (ABSTRACT_DATASTATE* none, ABSTRACT_VALUE* valptr) {
124
+ SV* SVval;
125
+ dTHX; /* fetch context */
126
+ if (valptr==NULL) return 0;
127
+ SVval = *((SV**) valptr);
128
+ if (SvROK(SVval)) {
129
+ if ((SvTYPE(SvRV(SVval)) == SVt_PVCV)) {
130
+ SVval = call_coderef(SVval);
131
+ } else
132
+ /* arrayptr : in HTML::Template, true if len(array)>0 */
133
+ if ((SvTYPE(SvRV(SVval)) == SVt_PVAV)
134
+ && (av_len((AV *)SvRV(SVval))<0)) {
135
+ return 0;
136
+ } else return 1;
137
+ }
138
+ /* in any place where I receive a value of which I don't know the origin,
139
+ I should call SvGETMAGIC first. */
140
+ SvGETMAGIC(SVval);
141
+ if(SvTRUE(SVval)) return 1;
142
+ return 0;
143
+ }
144
+
145
+ static
146
+ ABSTRACT_ARRAY* ABSTRACT_VALUE2ABSTRACT_ARRAY_impl (ABSTRACT_DATASTATE* none, ABSTRACT_VALUE* abstrvalptr) {
147
+ SV* val = *((SV**) abstrvalptr);
148
+ dTHX; /* fetch context */
149
+ SvGETMAGIC(val);
150
+ if ((!SvROK(val)) || (SvTYPE(SvRV(val)) != SVt_PVAV)) return 0;
151
+ return (ABSTRACT_ARRAY*) SvRV(val);
152
+ }
153
+
154
+ static
155
+ int get_ABSTRACT_ARRAY_length_impl (ABSTRACT_DATASTATE* none, ABSTRACT_ARRAY* loops_AV) {
156
+ dTHX; /* fetch context */
157
+ SvGETMAGIC((SV *)loops_AV);
158
+ return av_len((AV *)loops_AV)+1;
159
+ }
160
+
161
+ static
162
+ ABSTRACT_MAP* get_ABSTRACT_MAP_impl (ABSTRACT_DATASTATE* none, ABSTRACT_ARRAY* loops_AV, int loop) {
163
+ dTHX; /* fetch context */
164
+ SV* val;
165
+ SV** arrayvalptr = av_fetch((AV*)loops_AV, loop, 0);
166
+ if (arrayvalptr==NULL) return NULL;
167
+ val = *arrayvalptr;
168
+ SvGETMAGIC(val);
169
+ if ((!SvROK(val)) || (SvTYPE(SvRV(val)) != SVt_PVHV)) {
170
+ return NULL;
171
+ } else {
172
+ return (ABSTRACT_MAP *)SvRV(*arrayvalptr);
173
+ }
174
+ }
175
+
176
+ static
177
+ const char* get_filepath (ABSTRACT_FINDFILE* callback_state, const char* filename, const char* prevfilename) {
178
+ dTHX; /* fetch context */
179
+ dSP ;
180
+ int count ;
181
+ STRLEN len;
182
+ char* filepath;
183
+ SV* perlprevfile;
184
+ SV* PerlSelfHTMLTemplatePro = ((struct perl_callback_state*)callback_state)->perl_obj_self_ptr;
185
+ SV* perlretval = sv_2mortal(newSVpv(filename,0));
186
+ if (prevfilename) {
187
+ perlprevfile=sv_2mortal(newSVpv(prevfilename,0));
188
+ } else {
189
+ perlprevfile=sv_2mortal(newSV(0));
190
+ }
191
+ ENTER ;
192
+ SAVETMPS;
193
+ PUSHMARK(SP) ;
194
+ XPUSHs((SV*)PerlSelfHTMLTemplatePro);
195
+ XPUSHs(perlretval);
196
+ XPUSHs(perlprevfile);
197
+ PUTBACK ;
198
+ count = call_pv("_get_filepath", G_SCALAR);
199
+ SPAGAIN ;
200
+ if (count != 1) croak("Big troublen") ;
201
+ perlretval=POPs;
202
+ /* any memory leaks??? */
203
+ if (SvOK(perlretval)) {
204
+ filepath = SvPV(perlretval, len);
205
+ av_push(((struct perl_callback_state*)callback_state)->pool_for_perl_vars,perlretval);
206
+ SvREFCNT_inc(perlretval);
207
+ } else {
208
+ filepath = NULL;
209
+ }
210
+ PUTBACK ;
211
+ FREETMPS ;
212
+ LEAVE ;
213
+ return filepath;
214
+ }
215
+
216
+ static
217
+ PSTRING load_file (ABSTRACT_FILTER* callback_state, const char* filepath) {
218
+ dTHX; /* fetch context */
219
+ dSP ;
220
+ int count ;
221
+ STRLEN len;
222
+ PSTRING tmpl;
223
+ SV* templateptr;
224
+ SV* perlretval = sv_2mortal(newSVpv(filepath,0));
225
+ ENTER ;
226
+ SAVETMPS;
227
+ PUSHMARK(SP) ;
228
+ XPUSHs(((struct perl_callback_state*)callback_state)->perl_obj_self_ptr);
229
+ XPUSHs(perlretval);
230
+ PUTBACK ;
231
+ count = call_pv("_load_template", G_SCALAR);
232
+ SPAGAIN ;
233
+ if (count != 1) croak("Big troublen") ;
234
+ templateptr=POPs;
235
+ /* any memory leaks??? */
236
+ if (SvOK(templateptr) && SvROK(templateptr)) {
237
+ tmpl.begin = SvPV(SvRV(templateptr), len);
238
+ tmpl.endnext=tmpl.begin+len;
239
+ av_push(((struct perl_callback_state*)callback_state)->filtered_tmpl_array,templateptr);
240
+ SvREFCNT_inc(SvRV(templateptr));
241
+ } else {
242
+ croak("Big trouble! _load_template internal fatal error\n") ;
243
+ }
244
+ PUTBACK ;
245
+ FREETMPS ;
246
+ LEAVE ;
247
+ return tmpl;
248
+ }
249
+
250
+ static
251
+ int unload_file(ABSTRACT_FILTER* callback_state, PSTRING memarea) {
252
+ dTHX; /* fetch context */
253
+ /*
254
+ * scalar is already mortal so we don't need to dereference it
255
+ * SvREFCNT_dec(SvRV(av_pop(((struct perl_callback_state*)callback_state)->filtered_tmpl_array)));
256
+ */
257
+ av_pop(((struct perl_callback_state*)callback_state)->filtered_tmpl_array);
258
+ return 0;
259
+ }
260
+
261
+ static
262
+ ABSTRACT_USERFUNC* is_expr_userfnc (ABSTRACT_FUNCMAP* FuncHash, PSTRING name) {
263
+ dTHX; /* fetch context */
264
+ SV** hashvalptr=hv_fetch((HV *) FuncHash, name.begin, name.endnext-name.begin, 0);
265
+ return hashvalptr;
266
+ }
267
+
268
+ static
269
+ void free_expr_arglist(ABSTRACT_ARGLIST* arglist)
270
+ {
271
+ dTHX; /* fetch context */
272
+ if (NULL!=arglist) {
273
+ av_undef((AV*) arglist);
274
+ SvREFCNT_dec(arglist);
275
+ }
276
+ }
277
+
278
+ static
279
+ ABSTRACT_ARGLIST* init_expr_arglist(ABSTRACT_CALLER* none)
280
+ {
281
+ dTHX; /* fetch context */
282
+ return newAV();
283
+ }
284
+
285
+ static
286
+ void push_expr_arglist(ABSTRACT_ARGLIST* arglist, ABSTRACT_EXPRVAL* exprval)
287
+ {
288
+ dTHX; /* fetch context */
289
+ SV* val=NULL;
290
+ int exprval_type=tmplpro_get_expr_type(exprval);
291
+ PSTRING parg;
292
+ switch (exprval_type) {
293
+ case EXPR_TYPE_NULL: val=newSV(0);break;
294
+ case EXPR_TYPE_INT: val=newSViv(tmplpro_get_expr_as_int64(exprval));break;
295
+ case EXPR_TYPE_DBL: val=newSVnv(tmplpro_get_expr_as_double(exprval));break;
296
+ case EXPR_TYPE_PSTR: parg=tmplpro_get_expr_as_pstring(exprval);
297
+ val=newSVpvn(parg.begin, parg.endnext-parg.begin);break;
298
+ default: die ("Perl wrapper: FATAL INTERNAL ERROR:Unsupported type %d in exprval", exprval_type);
299
+ }
300
+ av_push ((AV*) arglist, val);
301
+ }
302
+
303
+ static
304
+ void call_expr_userfnc (ABSTRACT_CALLER* callback_state, ABSTRACT_ARGLIST* arglist, ABSTRACT_USERFUNC* hashvalptr, ABSTRACT_EXPRVAL* exprval) {
305
+ dTHX; /* fetch context */
306
+ dSP ;
307
+ char* empty="";
308
+ char* strval;
309
+ SV ** arrval;
310
+ SV * svretval;
311
+ I32 i;
312
+ I32 numretval;
313
+ I32 arrlen=av_len((AV *) arglist);
314
+ PSTRING retvalpstr = { empty, empty };
315
+ retvalpstr.begin=empty;
316
+ retvalpstr.endnext=empty;
317
+ if (hashvalptr==NULL) {
318
+ die ("FATAL INTERNAL ERROR:Call_EXPR:function called but not exists");
319
+ tmplpro_set_expr_as_pstring(exprval,retvalpstr);
320
+ return;
321
+ } else if (! SvROK(*((SV**) hashvalptr)) || (SvTYPE(SvRV(*((SV**) hashvalptr))) != SVt_PVCV)) {
322
+ die ("FATAL INTERNAL ERROR:Call_EXPR:not a function reference");
323
+ tmplpro_set_expr_as_pstring(exprval,retvalpstr);
324
+ return;
325
+ }
326
+
327
+ ENTER ;
328
+ SAVETMPS ;
329
+
330
+ PUSHMARK(SP) ;
331
+ for (i=0;i<=arrlen;i++) {
332
+ arrval=av_fetch((AV *) arglist,i,0);
333
+ if (arrval) XPUSHs(*arrval);
334
+ else warn("INTERNAL: call: strange arrval");
335
+ }
336
+ PUTBACK ;
337
+ numretval=call_sv(*((SV**) hashvalptr), G_SCALAR);
338
+ SPAGAIN ;
339
+ if (numretval) {
340
+ svretval=POPs;
341
+ SvGETMAGIC(svretval);
342
+ if (SvOK(svretval)) {
343
+ if (SvIOK(svretval)) {
344
+ tmplpro_set_expr_as_int64(exprval,SvIV(svretval));
345
+ } else if (SvNOK(svretval)) {
346
+ tmplpro_set_expr_as_double(exprval,SvNV(svretval));
347
+ } else {
348
+ STRLEN len=0;
349
+ strval =SvPV(svretval, len);
350
+ /* hack !!! */
351
+ av_push(((struct perl_callback_state*)callback_state)->pool_for_perl_vars,svretval);
352
+ SvREFCNT_inc(svretval);
353
+ retvalpstr.begin=strval;
354
+ retvalpstr.endnext=strval +len;
355
+ tmplpro_set_expr_as_pstring(exprval,retvalpstr);
356
+ }
357
+ } else {
358
+ if (debuglevel>1) warn ("user defined function returned undef\n");
359
+ }
360
+ } else {
361
+ if (debuglevel) warn ("user defined function returned nothing\n");
362
+ }
363
+
364
+ FREETMPS ;
365
+ LEAVE ;
366
+
367
+ return;
368
+ }
369
+
370
+ typedef void (*set_int_option_functype) (struct tmplpro_param*, int);
371
+
372
+ static
373
+ void set_integer_from_hash(pTHX_ HV* TheHash, char* key, struct tmplpro_param* param, set_int_option_functype setfunc) {
374
+ SV** hashvalptr=hv_fetch(TheHash, key, strlen(key), 0);
375
+ if (hashvalptr==NULL) return;
376
+ setfunc(param,SvIV(*hashvalptr));
377
+ }
378
+
379
+ static
380
+ int get_integer_from_hash(pTHX_ HV* TheHash, char* key) {
381
+ SV** hashvalptr=hv_fetch(TheHash, key, strlen(key), 0);
382
+ if (hashvalptr==NULL) return 0;
383
+ return SvIV(*hashvalptr);
384
+ }
385
+
386
+ static
387
+ PSTRING get_string_from_hash(pTHX_ HV* TheHash, char* key) {
388
+ SV** hashvalptr=hv_fetch(TheHash, key, strlen(key), 0);
389
+ STRLEN len=0;
390
+ char * begin;
391
+ PSTRING retval={NULL,NULL};
392
+ if (hashvalptr==NULL) return retval;
393
+ if (SvROK(*hashvalptr)) {
394
+ /* if (SvTYPE(SvRV(*hashvalptr))!=SVt_PV) return (PSTRING) {NULL,NULL}; */
395
+ begin=SvPV(SvRV(*hashvalptr),len);
396
+ } else {
397
+ if (! SvPOK(*hashvalptr)) return retval;
398
+ begin=SvPV(*hashvalptr,len);
399
+ }
400
+ retval.begin=begin;
401
+ retval.endnext=begin+len;
402
+ return retval;
403
+ }
404
+
405
+
406
+ static
407
+ char** get_array_of_strings_from_hash(pTHX_ HV* TheHash, char* key, struct perl_callback_state* callback_state) {
408
+ SV** valptr=hv_fetch(TheHash, key, strlen(key), 0);
409
+ int amax;
410
+ char** path=NULL;
411
+ AV* pathAV;
412
+ int i =0;
413
+ char** j;
414
+ SV* store;
415
+ if (valptr!=NULL && SvROK(*valptr) && (SvTYPE(SvRV(*valptr)) == SVt_PVAV) ) {
416
+ pathAV=(AV *)SvRV(*valptr);
417
+ amax=av_len(pathAV);
418
+ if (amax<0) {
419
+ return NULL;
420
+ } else {
421
+ store = newSV(sizeof(char*)*(amax+2));
422
+ path = (char**) SvGROW(store, sizeof(char*)*(amax+2));
423
+ av_push(((struct perl_callback_state*)callback_state)->pool_for_perl_vars,store);
424
+ SvREFCNT_inc(store);
425
+ //path=(char**) malloc(sizeof(char*)*(amax+2));
426
+ j=path;
427
+ for (i=0; i<=amax;i++) {
428
+ valptr = av_fetch(pathAV,i,0);
429
+ if (valptr!=NULL) {
430
+ *j=SvPV_nolen(*valptr);
431
+ j++;
432
+ }
433
+ *j=NULL;
434
+ }
435
+ }
436
+ } else {
437
+ warn ("get_array_of_strings:option %s not found :(\n", key);
438
+ }
439
+ return path;
440
+ }
441
+
442
+ static
443
+ struct tmplpro_param* process_tmplpro_options (struct perl_callback_state* callback_state) {
444
+ dTHX; /* fetch context */
445
+ HV* SelfHash;
446
+ SV** hashvalptr;
447
+ const char* tmpstring;
448
+ SV* PerlSelfPtr=callback_state->perl_obj_self_ptr;
449
+ int default_escape=HTML_TEMPLATE_OPT_ESCAPE_NO;
450
+
451
+ /* main arguments */
452
+ PSTRING filename;
453
+ PSTRING scalarref;
454
+
455
+ /* internal initialization */
456
+ struct tmplpro_param* param=tmplpro_param_init();
457
+
458
+ /* setting initial hooks */
459
+ tmplpro_set_option_WriterFuncPtr(param, &write_chars_to_string);
460
+ tmplpro_set_option_GetAbstractValFuncPtr(param, &get_ABSTRACT_VALUE_impl);
461
+ tmplpro_set_option_AbstractVal2pstringFuncPtr(param, &ABSTRACT_VALUE2PSTRING_impl);
462
+ tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(param, &ABSTRACT_VALUE2ABSTRACT_ARRAY_impl);
463
+ tmplpro_set_option_GetAbstractArrayLengthFuncPtr(param, &get_ABSTRACT_ARRAY_length_impl);
464
+ tmplpro_set_option_IsAbstractValTrueFuncPtr(param, &is_ABSTRACT_VALUE_true_impl);
465
+ tmplpro_set_option_GetAbstractMapFuncPtr(param, &get_ABSTRACT_MAP_impl);
466
+ tmplpro_set_option_LoadFileFuncPtr(param, &load_file);
467
+ tmplpro_set_option_UnloadFileFuncPtr(param, &unload_file);
468
+
469
+ /* setting initial Expr hooks */
470
+ tmplpro_set_option_InitExprArglistFuncPtr(param, &init_expr_arglist);
471
+ tmplpro_set_option_FreeExprArglistFuncPtr(param, &free_expr_arglist);
472
+ tmplpro_set_option_PushExprArglistFuncPtr(param, &push_expr_arglist);
473
+ tmplpro_set_option_CallExprUserfncFuncPtr(param, &call_expr_userfnc);
474
+ tmplpro_set_option_IsExprUserfncFuncPtr(param, &is_expr_userfnc);
475
+ /* end setting initial hooks */
476
+
477
+ /* setting perl globals */
478
+ tmplpro_set_option_ext_findfile_state(param,callback_state);
479
+ tmplpro_set_option_ext_filter_state(param,callback_state);
480
+ tmplpro_set_option_ext_calluserfunc_state(param,callback_state);
481
+ tmplpro_set_option_ext_data_state(param,callback_state);
482
+ /* end setting perl globals */
483
+
484
+ if ((!SvROK(PerlSelfPtr)) || (SvTYPE(SvRV(PerlSelfPtr)) != SVt_PVHV))
485
+ {
486
+ die("FATAL:SELF:hash pointer was expected but not found");
487
+ }
488
+ SelfHash=(HV *)SvRV(PerlSelfPtr);
489
+
490
+ /* checking main arguments */
491
+ filename=get_string_from_hash(aTHX_ SelfHash,"filename");
492
+ scalarref=get_string_from_hash(aTHX_ SelfHash,"scalarref");
493
+ tmplpro_set_option_filename(param, filename.begin);
494
+ tmplpro_set_option_scalarref(param, scalarref);
495
+ if (filename.begin==NULL && scalarref.begin==NULL) {
496
+ die ("bad arguments: expected filename or scalarref");
497
+ }
498
+
499
+ /* setting expr_func */
500
+ hashvalptr=hv_fetch(SelfHash, "expr_func", 9, 0); /* 9=strlen("expr_func") */
501
+ if (!hashvalptr || !SvROK(*hashvalptr) || (SvTYPE(SvRV(*hashvalptr)) != SVt_PVHV))
502
+ die("FATAL:output:EXPR user functions not found");
503
+ tmplpro_set_option_expr_func_map(param, (HV *) SvRV(*hashvalptr));
504
+ /* end setting expr_func */
505
+
506
+ /* setting param_map */
507
+ tmplpro_clear_option_param_map(param);
508
+ hashvalptr=hv_fetch(SelfHash, "associate", 9, 0); /* 9=strlen("associate") */
509
+ if (hashvalptr!=NULL && SvROK(*hashvalptr) && (SvTYPE(SvRV(*hashvalptr)) == SVt_PVAV)) {
510
+ AV* associate = (AV*) SvRV(*hashvalptr);
511
+ I32 i = av_len(associate);
512
+ SV** arrayvalptr;
513
+ while (i>=0) {
514
+ arrayvalptr = av_fetch(associate, i, 0);
515
+ if (arrayvalptr!=NULL && SvROK(*arrayvalptr))
516
+ tmplpro_push_option_param_map(param, (ABSTRACT_MAP *)SvRV(*arrayvalptr), 0);
517
+ i--;
518
+ }
519
+ }
520
+ hashvalptr=hv_fetch(SelfHash, "param_map", 9, 0); /* 9=strlen("param_map") */
521
+ /* TODO param deallocation on warn/die */
522
+ if (!hashvalptr || !SvROK(*hashvalptr) || (SvTYPE(SvRV(*hashvalptr)) != SVt_PVHV))
523
+ die("FATAL:output:param_map not found");
524
+ tmplpro_push_option_param_map(param, (ABSTRACT_MAP *)SvRV(*hashvalptr), 0);
525
+ /* end setting param_map */
526
+
527
+ /* setting filter */
528
+ hashvalptr=hv_fetch(SelfHash, "filter", 6, 0); /* 6=strlen("filter") */
529
+ if (!hashvalptr || !SvROK(*hashvalptr) || (SvTYPE(SvRV(*hashvalptr)) != SVt_PVAV))
530
+ die("FATAL:output:filter not found");
531
+ if (av_len((AV*)SvRV(*hashvalptr))>=0) tmplpro_set_option_filters(param, 1);
532
+ /* end setting param_map */
533
+
534
+ if (!get_integer_from_hash(aTHX_ SelfHash,"case_sensitive")) {
535
+ tmplpro_set_option_tmpl_var_case(param, ASK_NAME_LOWERCASE);
536
+ }
537
+
538
+ set_integer_from_hash(aTHX_ SelfHash,"tmpl_var_case",param,tmplpro_set_option_tmpl_var_case);
539
+ set_integer_from_hash(aTHX_ SelfHash,"max_includes",param,tmplpro_set_option_max_includes);
540
+ set_integer_from_hash(aTHX_ SelfHash,"no_includes",param,tmplpro_set_option_no_includes);
541
+ set_integer_from_hash(aTHX_ SelfHash,"search_path_on_include",param,tmplpro_set_option_search_path_on_include);
542
+ set_integer_from_hash(aTHX_ SelfHash,"global_vars",param,tmplpro_set_option_global_vars);
543
+ set_integer_from_hash(aTHX_ SelfHash,"debug",param,tmplpro_set_option_debug);
544
+ debuglevel = tmplpro_get_option_debug(param);
545
+ set_integer_from_hash(aTHX_ SelfHash,"loop_context_vars",param,tmplpro_set_option_loop_context_vars);
546
+ set_integer_from_hash(aTHX_ SelfHash,"path_like_variable_scope",param,tmplpro_set_option_path_like_variable_scope);
547
+ /* still unsupported */
548
+ set_integer_from_hash(aTHX_ SelfHash,"strict",param,tmplpro_set_option_strict);
549
+
550
+ tmpstring=get_string_from_hash(aTHX_ SelfHash,"default_escape").begin;
551
+ if (tmpstring && *tmpstring) {
552
+ switch (*tmpstring) {
553
+ case '1': case 'H': case 'h': /* HTML*/
554
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_HTML;
555
+ break;
556
+ case 'U': case 'u': /* URL */
557
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_URL;
558
+ break;
559
+ case 'J': case 'j': /* JS */
560
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_JS;
561
+ break;
562
+ case '0': case 'N': case 'n': /* 0 or NONE */
563
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_NO;
564
+ break;
565
+ default:
566
+ warn("unsupported value of default_escape=%s. Valid values are HTML, URL or JS.\n",tmpstring);
567
+ }
568
+ tmplpro_set_option_default_escape(param, default_escape);
569
+
570
+ }
571
+
572
+ /* setting callback_state */
573
+ callback_state->force_untaint=get_integer_from_hash(aTHX_ SelfHash,"force_untaint");
574
+ /* end setting callback_state */
575
+
576
+ if (get_integer_from_hash(aTHX_ SelfHash,"__use_perl_find_file")) {
577
+ tmplpro_set_option_FindFileFuncPtr(param, &get_filepath);
578
+ } else {
579
+ tmplpro_set_option_path(param, get_array_of_strings_from_hash(aTHX_ SelfHash, "path", callback_state));
580
+ tmplpro_set_option_FindFileFuncPtr(param, NULL);
581
+ }
582
+ return param;
583
+ }
584
+
585
+ static void
586
+ release_tmplpro_options(struct tmplpro_param* param, struct perl_callback_state callback_state)
587
+ {
588
+ dTHX; /* fetch context */
589
+ av_undef(callback_state.filtered_tmpl_array);
590
+ av_undef(callback_state.pool_for_perl_vars);
591
+ tmplpro_param_free(param);
592
+ }
593
+
594
+
595
+
596
+ MODULE = HTML::Template::Pro PACKAGE = HTML::Template::Pro
597
+
598
+ void
599
+ _init()
600
+ CODE:
601
+ tmplpro_procore_init();
602
+
603
+ void
604
+ _done()
605
+ CODE:
606
+ tmplpro_procore_done();
607
+
608
+
609
+ int
610
+ exec_tmpl(self_ptr,possible_output)
611
+ SV* self_ptr;
612
+ SV* possible_output;
613
+ PREINIT:
614
+ struct perl_callback_state callback_state = {self_ptr,newAV(),newAV(),0};
615
+ struct tmplpro_param* proparam=process_tmplpro_options(&callback_state);
616
+ CODE:
617
+ OutputStream output_stream;
618
+ SvGETMAGIC(possible_output);
619
+ if (!SvOK(possible_output)) {
620
+ tmplpro_set_option_WriterFuncPtr(proparam,NULL);
621
+ } else {
622
+ output_stream = IoOFP(sv_2io(possible_output));
623
+ if (output_stream == NULL){
624
+ warn("Pro.xs:output: bad file descriptor in print_to option. Use stdout\n");
625
+ tmplpro_set_option_WriterFuncPtr(proparam,NULL);
626
+ } else {
627
+ tmplpro_set_option_ext_writer_state(proparam,output_stream);
628
+ tmplpro_set_option_WriterFuncPtr(proparam,&write_chars_to_file);
629
+ }
630
+ }
631
+ RETVAL = tmplpro_exec_tmpl(proparam);
632
+ release_tmplpro_options(proparam,callback_state);
633
+ if (RETVAL!=0) warn ("Pro.xs: non-zero exit code %d",RETVAL);
634
+ OUTPUT:
635
+ RETVAL
636
+
637
+
638
+ SV*
639
+ exec_tmpl_string(self_ptr)
640
+ SV* self_ptr;
641
+ PREINIT:
642
+ int retstate;
643
+ /* made mortal automatically */
644
+ SV* outputString;
645
+ struct perl_callback_state callback_state = {self_ptr,newAV(),newAV(),0};
646
+ struct tmplpro_param* proparam=process_tmplpro_options(&callback_state);
647
+ CODE:
648
+ outputString=newSV(4000); /* 4000 allocated bytes -- should be approx. filesize*/
649
+ sv_setpvn(outputString, "", 0);
650
+ tmplpro_set_option_WriterFuncPtr(proparam,&write_chars_to_string);
651
+ tmplpro_set_option_ext_writer_state(proparam,outputString);
652
+ retstate = tmplpro_exec_tmpl(proparam);
653
+ release_tmplpro_options(proparam,callback_state);
654
+ if (retstate!=0) warn ("Pro.xs: non-zero exit code %d",retstate);
655
+ RETVAL = outputString;
656
+ OUTPUT:
657
+ RETVAL
658
+
659
+
660
+ SV*
661
+ exec_tmpl_string_builtin(self_ptr)
662
+ SV* self_ptr;
663
+ PREINIT:
664
+ int retstate;
665
+ SV* outputString;
666
+ MPSTRING inString;
667
+ struct perl_callback_state callback_state = {self_ptr,newAV(),newAV(),0};
668
+ struct tmplpro_param* proparam=process_tmplpro_options(&callback_state);
669
+ CODE:
670
+ inString = tmplpro_tmpl2pstring(proparam, &retstate);
671
+ outputString=newSV(inString.endnext-inString.begin+2);
672
+ sv_setpvn(outputString, inString.begin, inString.endnext-inString.begin);
673
+ free(inString.begin);
674
+ release_tmplpro_options(proparam,callback_state);
675
+ if (retstate!=0) warn ("Pro.xs: non-zero exit code %d",retstate);
676
+ RETVAL = outputString;
677
+ OUTPUT:
678
+ RETVAL
679
+