html-template-pro 0.0.1

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 (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
+