html-template-pro 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +9 -0
- data/ARTISTIC +131 -0
- data/History.txt +4 -0
- data/LGPL +504 -0
- data/Manifest.txt +221 -0
- data/README.rdoc +52 -0
- data/Rakefile +18 -0
- data/benchmark.rb +136 -0
- data/config/website.yml +2 -0
- data/ext/html/template/internal/Pro.xs +679 -0
- data/ext/html/template/internal/builtin_findfile.inc +361 -0
- data/ext/html/template/internal/calc.h +26 -0
- data/ext/html/template/internal/calc.inc +120 -0
- data/ext/html/template/internal/callback_stubs.inc +63 -0
- data/ext/html/template/internal/expr.c +2267 -0
- data/ext/html/template/internal/expr.y +476 -0
- data/ext/html/template/internal/expr_iface.c +94 -0
- data/ext/html/template/internal/exprpstr.h +36 -0
- data/ext/html/template/internal/exprpstr.inc +144 -0
- data/ext/html/template/internal/exprtool.h +99 -0
- data/ext/html/template/internal/exprtool.inc +289 -0
- data/ext/html/template/internal/exprtype.h +62 -0
- data/ext/html/template/internal/exprval.h +30 -0
- data/ext/html/template/internal/extconf.rb +6 -0
- data/ext/html/template/internal/internal.c +449 -0
- data/ext/html/template/internal/loadfile.h +11 -0
- data/ext/html/template/internal/loadfile.inc +171 -0
- data/ext/html/template/internal/pabidecl.h +54 -0
- data/ext/html/template/internal/pabstract.h +426 -0
- data/ext/html/template/internal/parse_expr.h +15 -0
- data/ext/html/template/internal/pbuffer.c +76 -0
- data/ext/html/template/internal/pbuffer.h +31 -0
- data/ext/html/template/internal/pmiscdef.h +54 -0
- data/ext/html/template/internal/pparam.h +101 -0
- data/ext/html/template/internal/ppport.h +1098 -0
- data/ext/html/template/internal/procore.c +1189 -0
- data/ext/html/template/internal/procore.h +18 -0
- data/ext/html/template/internal/proparam.c +443 -0
- data/ext/html/template/internal/proparam.h +571 -0
- data/ext/html/template/internal/proscope.h +32 -0
- data/ext/html/template/internal/proscope.inc +107 -0
- data/ext/html/template/internal/prostate.h +49 -0
- data/ext/html/template/internal/prostate.inc +24 -0
- data/ext/html/template/internal/provalue.h +14 -0
- data/ext/html/template/internal/pstring.h +60 -0
- data/ext/html/template/internal/pstrutils.h +25 -0
- data/ext/html/template/internal/pstrutils.inc +150 -0
- data/ext/html/template/internal/tagstack.h +30 -0
- data/ext/html/template/internal/tagstack.inc +65 -0
- data/ext/html/template/internal/tmpllog.c +62 -0
- data/ext/html/template/internal/tmpllog.h +27 -0
- data/ext/html/template/internal/tmplpro.h +218 -0
- data/ext/html/template/internal/tmplpro_version.c +35 -0
- data/lib/html/template/pro.rb +225 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/tasks/extconf.rake +13 -0
- data/tasks/extconf/tmplpro.rake +43 -0
- data/templates-Pro/a.incl +1 -0
- data/templates-Pro/empty.incl +0 -0
- data/templates-Pro/include/1/a.incl +1 -0
- data/templates-Pro/include/2.out +3 -0
- data/templates-Pro/include/2.tmpl +1 -0
- data/templates-Pro/include/2/a.incl +1 -0
- data/templates-Pro/include/3.tmpl +1 -0
- data/templates-Pro/include/4.tmpl +1 -0
- data/templates-Pro/include/a.incl +1 -0
- data/templates-Pro/test_broken.tmpl +25 -0
- data/templates-Pro/test_broken1.out +1 -0
- data/templates-Pro/test_broken1.tmpl +1 -0
- data/templates-Pro/test_esc1.out +4 -0
- data/templates-Pro/test_esc1.tmpl +4 -0
- data/templates-Pro/test_esc2.out +5 -0
- data/templates-Pro/test_esc2.tmpl +6 -0
- data/templates-Pro/test_esc3.out +4 -0
- data/templates-Pro/test_esc3.tmpl +4 -0
- data/templates-Pro/test_esc4.out +3 -0
- data/templates-Pro/test_esc4.tmpl +4 -0
- data/templates-Pro/test_expr1.out +26 -0
- data/templates-Pro/test_expr1.tmpl +26 -0
- data/templates-Pro/test_expr2.out +34 -0
- data/templates-Pro/test_expr2.tmpl +34 -0
- data/templates-Pro/test_expr3.out +6 -0
- data/templates-Pro/test_expr3.tmpl +6 -0
- data/templates-Pro/test_expr4.out +4 -0
- data/templates-Pro/test_expr4.tmpl +4 -0
- data/templates-Pro/test_expr5.out +18 -0
- data/templates-Pro/test_expr5.tmpl +18 -0
- data/templates-Pro/test_expr6.out +18 -0
- data/templates-Pro/test_expr6.tmpl +18 -0
- data/templates-Pro/test_expr7.out +44 -0
- data/templates-Pro/test_expr7.tmpl +20 -0
- data/templates-Pro/test_expr8.out +15 -0
- data/templates-Pro/test_expr8.tmpl +15 -0
- data/templates-Pro/test_if1.out +25 -0
- data/templates-Pro/test_if1.tmpl +28 -0
- data/templates-Pro/test_if2.out +17 -0
- data/templates-Pro/test_if2.tmpl +25 -0
- data/templates-Pro/test_if3.out +12 -0
- data/templates-Pro/test_if3.tmpl +14 -0
- data/templates-Pro/test_if4.out +15 -0
- data/templates-Pro/test_if4.tmpl +31 -0
- data/templates-Pro/test_if5.out +16 -0
- data/templates-Pro/test_if5.tmpl +16 -0
- data/templates-Pro/test_if6.out +15 -0
- data/templates-Pro/test_if6.tmpl +31 -0
- data/templates-Pro/test_if7.out +14 -0
- data/templates-Pro/test_if7.tmpl +18 -0
- data/templates-Pro/test_include1.out +23 -0
- data/templates-Pro/test_include1.tmpl +7 -0
- data/templates-Pro/test_include2.out +120 -0
- data/templates-Pro/test_include2.tmpl +10 -0
- data/templates-Pro/test_include3.out +8 -0
- data/templates-Pro/test_include3.tmpl +8 -0
- data/templates-Pro/test_include4.out +7 -0
- data/templates-Pro/test_include4.tmpl +6 -0
- data/templates-Pro/test_include5.out +7 -0
- data/templates-Pro/test_include5.tmpl +6 -0
- data/templates-Pro/test_loop1.erb +17 -0
- data/templates-Pro/test_loop1.out +12 -0
- data/templates-Pro/test_loop1.tmpl +16 -0
- data/templates-Pro/test_loop2.erb +19 -0
- data/templates-Pro/test_loop2.out +40 -0
- data/templates-Pro/test_loop2.tmpl +19 -0
- data/templates-Pro/test_loop3.out +38 -0
- data/templates-Pro/test_loop3.tmpl +40 -0
- data/templates-Pro/test_loop4.out +44 -0
- data/templates-Pro/test_loop4.tmpl +20 -0
- data/templates-Pro/test_loop5.out +9 -0
- data/templates-Pro/test_loop5.tmpl +11 -0
- data/templates-Pro/test_loop6.out +33 -0
- data/templates-Pro/test_loop6.tmpl +15 -0
- data/templates-Pro/test_malloc.tmpl +1 -0
- data/templates-Pro/test_userfunc1.out +14 -0
- data/templates-Pro/test_userfunc1.tmpl +14 -0
- data/templates-Pro/test_userfunc2.out +35 -0
- data/templates-Pro/test_userfunc2.tmpl +5 -0
- data/templates-Pro/test_userfunc3.out +5 -0
- data/templates-Pro/test_userfunc3.tmpl +5 -0
- data/templates-Pro/test_userfunc4.out +10 -0
- data/templates-Pro/test_userfunc4.tmpl +10 -0
- data/templates-Pro/test_userfunc5.out +4 -0
- data/templates-Pro/test_userfunc5.tmpl +4 -0
- data/templates-Pro/test_userfunc6.out +4 -0
- data/templates-Pro/test_userfunc6.tmpl +4 -0
- data/templates-Pro/test_var1.erb +23 -0
- data/templates-Pro/test_var1.out +20 -0
- data/templates-Pro/test_var1.tmpl +23 -0
- data/templates-Pro/test_var2.erb +7 -0
- data/templates-Pro/test_var2.out +6 -0
- data/templates-Pro/test_var2.tmpl +7 -0
- data/templates-Pro/test_var3.out +14 -0
- data/templates-Pro/test_var3.tmpl +16 -0
- data/templates/case_loop.tmpl +3 -0
- data/templates/context.tmpl +3 -0
- data/templates/counter.tmpl +2 -0
- data/templates/default.tmpl +1 -0
- data/templates/default_escape.tmpl +4 -0
- data/templates/double_loop.tmpl +7 -0
- data/templates/escape.tmpl +5 -0
- data/templates/global-loops.tmpl +9 -0
- data/templates/globals.tmpl +11 -0
- data/templates/if.tmpl +7 -0
- data/templates/ifelse.tmpl +6 -0
- data/templates/include.tmpl +14 -0
- data/templates/include_path/a.tmpl +2 -0
- data/templates/include_path/b.tmpl +1 -0
- data/templates/include_path/inner.tmpl +1 -0
- data/templates/include_path/one.tmpl +2 -0
- data/templates/include_path2/inner.tmpl +1 -0
- data/templates/included.tmpl +4 -0
- data/templates/included2.tmpl +3 -0
- data/templates/js.tmpl +1 -0
- data/templates/long_loops.tmpl +307 -0
- data/templates/loop-context.tmpl +2 -0
- data/templates/loop-if.tmpl +9 -0
- data/templates/medium.tmpl +217 -0
- data/templates/multiline_tags.tmpl +7 -0
- data/templates/newline_test1.tmpl +1 -0
- data/templates/newline_test2.tmpl +1 -0
- data/templates/other-loop.tmpl +7 -0
- data/templates/outer.tmpl +3 -0
- data/templates/query-test.tmpl +21 -0
- data/templates/query-test2.tmpl +12 -0
- data/templates/recursive.tmpl +2 -0
- data/templates/searchpath/included.tmpl +4 -0
- data/templates/searchpath/three.tmpl +1 -0
- data/templates/searchpath/two.tmpl +2 -0
- data/templates/simple-loop-nonames.tmpl +13 -0
- data/templates/simple-loop.tmpl +12 -0
- data/templates/simple.tmpl +9 -0
- data/templates/unless.tmpl +5 -0
- data/templates/urlescape.tmpl +3 -0
- data/templates/vanguard1.tmpl +2 -0
- data/templates/vanguard2.tmpl +3 -0
- data/test/templates/complex.tmpl +24 -0
- data/test/templates/foo.tmpl +6 -0
- data/test/templates/func.tmpl +2 -0
- data/test/templates/loop.tmpl +14 -0
- data/test/templates/negative.tmpl +1 -0
- data/test/templates/numerics.tmpl +6 -0
- data/test/templates/register.tmpl +2 -0
- data/test/test_basic.rb +23 -0
- data/test/test_coderefs.rb +16 -0
- data/test/test_complex.rb +106 -0
- data/test/test_helper.rb +3 -0
- data/test/test_html_template.rb +583 -0
- data/test/test_html_template_internal_extn.rb +10 -0
- data/test/test_html_template_pro.rb +177 -0
- data/test/test_path_like_variable_scope.rb +59 -0
- data/test/test_random.rb +21 -0
- data/test/test_realloc.rb +16 -0
- data/test/test_register.rb +25 -0
- data/test/test_tmplpro.rb +9 -0
- data/test/tests.rb +9 -0
- data/website/index.txt +57 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +159 -0
- data/website/template.html.erb +50 -0
- metadata +303 -0
data/Manifest.txt
ADDED
@@ -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
|
data/README.rdoc
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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 }
|
data/benchmark.rb
ADDED
@@ -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);
|
data/config/website.yml
ADDED
@@ -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
|
+
|