html-template-pro 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. data/.autotest +9 -0
  2. data/ARTISTIC +131 -0
  3. data/History.txt +4 -0
  4. data/LGPL +504 -0
  5. data/Manifest.txt +221 -0
  6. data/README.rdoc +52 -0
  7. data/Rakefile +18 -0
  8. data/benchmark.rb +136 -0
  9. data/config/website.yml +2 -0
  10. data/ext/html/template/internal/Pro.xs +679 -0
  11. data/ext/html/template/internal/builtin_findfile.inc +361 -0
  12. data/ext/html/template/internal/calc.h +26 -0
  13. data/ext/html/template/internal/calc.inc +120 -0
  14. data/ext/html/template/internal/callback_stubs.inc +63 -0
  15. data/ext/html/template/internal/expr.c +2267 -0
  16. data/ext/html/template/internal/expr.y +476 -0
  17. data/ext/html/template/internal/expr_iface.c +94 -0
  18. data/ext/html/template/internal/exprpstr.h +36 -0
  19. data/ext/html/template/internal/exprpstr.inc +144 -0
  20. data/ext/html/template/internal/exprtool.h +99 -0
  21. data/ext/html/template/internal/exprtool.inc +289 -0
  22. data/ext/html/template/internal/exprtype.h +62 -0
  23. data/ext/html/template/internal/exprval.h +30 -0
  24. data/ext/html/template/internal/extconf.rb +6 -0
  25. data/ext/html/template/internal/internal.c +449 -0
  26. data/ext/html/template/internal/loadfile.h +11 -0
  27. data/ext/html/template/internal/loadfile.inc +171 -0
  28. data/ext/html/template/internal/pabidecl.h +54 -0
  29. data/ext/html/template/internal/pabstract.h +426 -0
  30. data/ext/html/template/internal/parse_expr.h +15 -0
  31. data/ext/html/template/internal/pbuffer.c +76 -0
  32. data/ext/html/template/internal/pbuffer.h +31 -0
  33. data/ext/html/template/internal/pmiscdef.h +54 -0
  34. data/ext/html/template/internal/pparam.h +101 -0
  35. data/ext/html/template/internal/ppport.h +1098 -0
  36. data/ext/html/template/internal/procore.c +1189 -0
  37. data/ext/html/template/internal/procore.h +18 -0
  38. data/ext/html/template/internal/proparam.c +443 -0
  39. data/ext/html/template/internal/proparam.h +571 -0
  40. data/ext/html/template/internal/proscope.h +32 -0
  41. data/ext/html/template/internal/proscope.inc +107 -0
  42. data/ext/html/template/internal/prostate.h +49 -0
  43. data/ext/html/template/internal/prostate.inc +24 -0
  44. data/ext/html/template/internal/provalue.h +14 -0
  45. data/ext/html/template/internal/pstring.h +60 -0
  46. data/ext/html/template/internal/pstrutils.h +25 -0
  47. data/ext/html/template/internal/pstrutils.inc +150 -0
  48. data/ext/html/template/internal/tagstack.h +30 -0
  49. data/ext/html/template/internal/tagstack.inc +65 -0
  50. data/ext/html/template/internal/tmpllog.c +62 -0
  51. data/ext/html/template/internal/tmpllog.h +27 -0
  52. data/ext/html/template/internal/tmplpro.h +218 -0
  53. data/ext/html/template/internal/tmplpro_version.c +35 -0
  54. data/lib/html/template/pro.rb +225 -0
  55. data/script/console +10 -0
  56. data/script/destroy +14 -0
  57. data/script/generate +14 -0
  58. data/script/txt2html +71 -0
  59. data/tasks/extconf.rake +13 -0
  60. data/tasks/extconf/tmplpro.rake +43 -0
  61. data/templates-Pro/a.incl +1 -0
  62. data/templates-Pro/empty.incl +0 -0
  63. data/templates-Pro/include/1/a.incl +1 -0
  64. data/templates-Pro/include/2.out +3 -0
  65. data/templates-Pro/include/2.tmpl +1 -0
  66. data/templates-Pro/include/2/a.incl +1 -0
  67. data/templates-Pro/include/3.tmpl +1 -0
  68. data/templates-Pro/include/4.tmpl +1 -0
  69. data/templates-Pro/include/a.incl +1 -0
  70. data/templates-Pro/test_broken.tmpl +25 -0
  71. data/templates-Pro/test_broken1.out +1 -0
  72. data/templates-Pro/test_broken1.tmpl +1 -0
  73. data/templates-Pro/test_esc1.out +4 -0
  74. data/templates-Pro/test_esc1.tmpl +4 -0
  75. data/templates-Pro/test_esc2.out +5 -0
  76. data/templates-Pro/test_esc2.tmpl +6 -0
  77. data/templates-Pro/test_esc3.out +4 -0
  78. data/templates-Pro/test_esc3.tmpl +4 -0
  79. data/templates-Pro/test_esc4.out +3 -0
  80. data/templates-Pro/test_esc4.tmpl +4 -0
  81. data/templates-Pro/test_expr1.out +26 -0
  82. data/templates-Pro/test_expr1.tmpl +26 -0
  83. data/templates-Pro/test_expr2.out +34 -0
  84. data/templates-Pro/test_expr2.tmpl +34 -0
  85. data/templates-Pro/test_expr3.out +6 -0
  86. data/templates-Pro/test_expr3.tmpl +6 -0
  87. data/templates-Pro/test_expr4.out +4 -0
  88. data/templates-Pro/test_expr4.tmpl +4 -0
  89. data/templates-Pro/test_expr5.out +18 -0
  90. data/templates-Pro/test_expr5.tmpl +18 -0
  91. data/templates-Pro/test_expr6.out +18 -0
  92. data/templates-Pro/test_expr6.tmpl +18 -0
  93. data/templates-Pro/test_expr7.out +44 -0
  94. data/templates-Pro/test_expr7.tmpl +20 -0
  95. data/templates-Pro/test_expr8.out +15 -0
  96. data/templates-Pro/test_expr8.tmpl +15 -0
  97. data/templates-Pro/test_if1.out +25 -0
  98. data/templates-Pro/test_if1.tmpl +28 -0
  99. data/templates-Pro/test_if2.out +17 -0
  100. data/templates-Pro/test_if2.tmpl +25 -0
  101. data/templates-Pro/test_if3.out +12 -0
  102. data/templates-Pro/test_if3.tmpl +14 -0
  103. data/templates-Pro/test_if4.out +15 -0
  104. data/templates-Pro/test_if4.tmpl +31 -0
  105. data/templates-Pro/test_if5.out +16 -0
  106. data/templates-Pro/test_if5.tmpl +16 -0
  107. data/templates-Pro/test_if6.out +15 -0
  108. data/templates-Pro/test_if6.tmpl +31 -0
  109. data/templates-Pro/test_if7.out +14 -0
  110. data/templates-Pro/test_if7.tmpl +18 -0
  111. data/templates-Pro/test_include1.out +23 -0
  112. data/templates-Pro/test_include1.tmpl +7 -0
  113. data/templates-Pro/test_include2.out +120 -0
  114. data/templates-Pro/test_include2.tmpl +10 -0
  115. data/templates-Pro/test_include3.out +8 -0
  116. data/templates-Pro/test_include3.tmpl +8 -0
  117. data/templates-Pro/test_include4.out +7 -0
  118. data/templates-Pro/test_include4.tmpl +6 -0
  119. data/templates-Pro/test_include5.out +7 -0
  120. data/templates-Pro/test_include5.tmpl +6 -0
  121. data/templates-Pro/test_loop1.erb +17 -0
  122. data/templates-Pro/test_loop1.out +12 -0
  123. data/templates-Pro/test_loop1.tmpl +16 -0
  124. data/templates-Pro/test_loop2.erb +19 -0
  125. data/templates-Pro/test_loop2.out +40 -0
  126. data/templates-Pro/test_loop2.tmpl +19 -0
  127. data/templates-Pro/test_loop3.out +38 -0
  128. data/templates-Pro/test_loop3.tmpl +40 -0
  129. data/templates-Pro/test_loop4.out +44 -0
  130. data/templates-Pro/test_loop4.tmpl +20 -0
  131. data/templates-Pro/test_loop5.out +9 -0
  132. data/templates-Pro/test_loop5.tmpl +11 -0
  133. data/templates-Pro/test_loop6.out +33 -0
  134. data/templates-Pro/test_loop6.tmpl +15 -0
  135. data/templates-Pro/test_malloc.tmpl +1 -0
  136. data/templates-Pro/test_userfunc1.out +14 -0
  137. data/templates-Pro/test_userfunc1.tmpl +14 -0
  138. data/templates-Pro/test_userfunc2.out +35 -0
  139. data/templates-Pro/test_userfunc2.tmpl +5 -0
  140. data/templates-Pro/test_userfunc3.out +5 -0
  141. data/templates-Pro/test_userfunc3.tmpl +5 -0
  142. data/templates-Pro/test_userfunc4.out +10 -0
  143. data/templates-Pro/test_userfunc4.tmpl +10 -0
  144. data/templates-Pro/test_userfunc5.out +4 -0
  145. data/templates-Pro/test_userfunc5.tmpl +4 -0
  146. data/templates-Pro/test_userfunc6.out +4 -0
  147. data/templates-Pro/test_userfunc6.tmpl +4 -0
  148. data/templates-Pro/test_var1.erb +23 -0
  149. data/templates-Pro/test_var1.out +20 -0
  150. data/templates-Pro/test_var1.tmpl +23 -0
  151. data/templates-Pro/test_var2.erb +7 -0
  152. data/templates-Pro/test_var2.out +6 -0
  153. data/templates-Pro/test_var2.tmpl +7 -0
  154. data/templates-Pro/test_var3.out +14 -0
  155. data/templates-Pro/test_var3.tmpl +16 -0
  156. data/templates/case_loop.tmpl +3 -0
  157. data/templates/context.tmpl +3 -0
  158. data/templates/counter.tmpl +2 -0
  159. data/templates/default.tmpl +1 -0
  160. data/templates/default_escape.tmpl +4 -0
  161. data/templates/double_loop.tmpl +7 -0
  162. data/templates/escape.tmpl +5 -0
  163. data/templates/global-loops.tmpl +9 -0
  164. data/templates/globals.tmpl +11 -0
  165. data/templates/if.tmpl +7 -0
  166. data/templates/ifelse.tmpl +6 -0
  167. data/templates/include.tmpl +14 -0
  168. data/templates/include_path/a.tmpl +2 -0
  169. data/templates/include_path/b.tmpl +1 -0
  170. data/templates/include_path/inner.tmpl +1 -0
  171. data/templates/include_path/one.tmpl +2 -0
  172. data/templates/include_path2/inner.tmpl +1 -0
  173. data/templates/included.tmpl +4 -0
  174. data/templates/included2.tmpl +3 -0
  175. data/templates/js.tmpl +1 -0
  176. data/templates/long_loops.tmpl +307 -0
  177. data/templates/loop-context.tmpl +2 -0
  178. data/templates/loop-if.tmpl +9 -0
  179. data/templates/medium.tmpl +217 -0
  180. data/templates/multiline_tags.tmpl +7 -0
  181. data/templates/newline_test1.tmpl +1 -0
  182. data/templates/newline_test2.tmpl +1 -0
  183. data/templates/other-loop.tmpl +7 -0
  184. data/templates/outer.tmpl +3 -0
  185. data/templates/query-test.tmpl +21 -0
  186. data/templates/query-test2.tmpl +12 -0
  187. data/templates/recursive.tmpl +2 -0
  188. data/templates/searchpath/included.tmpl +4 -0
  189. data/templates/searchpath/three.tmpl +1 -0
  190. data/templates/searchpath/two.tmpl +2 -0
  191. data/templates/simple-loop-nonames.tmpl +13 -0
  192. data/templates/simple-loop.tmpl +12 -0
  193. data/templates/simple.tmpl +9 -0
  194. data/templates/unless.tmpl +5 -0
  195. data/templates/urlescape.tmpl +3 -0
  196. data/templates/vanguard1.tmpl +2 -0
  197. data/templates/vanguard2.tmpl +3 -0
  198. data/test/templates/complex.tmpl +24 -0
  199. data/test/templates/foo.tmpl +6 -0
  200. data/test/templates/func.tmpl +2 -0
  201. data/test/templates/loop.tmpl +14 -0
  202. data/test/templates/negative.tmpl +1 -0
  203. data/test/templates/numerics.tmpl +6 -0
  204. data/test/templates/register.tmpl +2 -0
  205. data/test/test_basic.rb +23 -0
  206. data/test/test_coderefs.rb +16 -0
  207. data/test/test_complex.rb +106 -0
  208. data/test/test_helper.rb +3 -0
  209. data/test/test_html_template.rb +583 -0
  210. data/test/test_html_template_internal_extn.rb +10 -0
  211. data/test/test_html_template_pro.rb +177 -0
  212. data/test/test_path_like_variable_scope.rb +59 -0
  213. data/test/test_random.rb +21 -0
  214. data/test/test_realloc.rb +16 -0
  215. data/test/test_register.rb +25 -0
  216. data/test/test_tmplpro.rb +9 -0
  217. data/test/tests.rb +9 -0
  218. data/website/index.txt +57 -0
  219. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  220. data/website/stylesheets/screen.css +159 -0
  221. data/website/template.html.erb +50 -0
  222. metadata +303 -0
@@ -0,0 +1,62 @@
1
+ /*! \file exprtype.h
2
+ \brief description of EXPR variable type.
3
+
4
+ EXPR variable type is passed to and from user-supplied functions.
5
+
6
+ \author Igor Vlasenko <vlasenko@imath.kiev.ua>
7
+ \warning This header file should never be included directly.
8
+ Include <tmplpro.h> instead.
9
+ */
10
+
11
+ #ifndef _EXPRTYPE_H
12
+ #define _EXPRTYPE_H 1
13
+
14
+ #ifdef HAVE_CONFIG_H
15
+ #include "config.h"
16
+ #endif
17
+
18
+ #if HAVE_INTTYPES_H
19
+ # include <inttypes.h>
20
+ #else
21
+ # if HAVE_STDINT_H
22
+ # include <stdint.h>
23
+ # endif
24
+ #endif
25
+
26
+ #define EXPR_TYPE_INT 'i'
27
+ #define EXPR_TYPE_DBL 'd'
28
+ #define EXPR_TYPE_PSTR 'p'
29
+ /* NULL is for interface only, internally NULL pstring is used. */
30
+ #define EXPR_TYPE_NULL '\0'
31
+ /* UPSTR is for internal use only. it is never passed to user functions. */
32
+ #define EXPR_TYPE_UPSTR 'u'
33
+
34
+ #if defined INT64_MAX || defined int64_t
35
+ typedef int64_t EXPR_int64;
36
+ #elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8
37
+ typedef long long int EXPR_int64;
38
+ #elif defined INT64_NAME
39
+ typedef INT64_NAME EXPR_int64;
40
+ #else
41
+ typedef long int EXPR_int64;
42
+ #endif
43
+
44
+ #if defined PRId64
45
+ # define EXPR_PRId64 PRId64
46
+ #elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8
47
+ # define EXPR_PRId64 "lld"
48
+ #elif defined _MSC_VER
49
+ # define EXPR_PRId64 "I64d"
50
+ #else
51
+ # define EXPR_PRId64 "ld"
52
+ #endif
53
+
54
+ struct exprval;
55
+
56
+ #endif /* exprtype.h */
57
+
58
+ /*
59
+ * Local Variables:
60
+ * mode: c
61
+ * End:
62
+ */
@@ -0,0 +1,30 @@
1
+ /* -*- c -*-
2
+ * File: exprval.h
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Mon Jul 20 21:10:57 2009
5
+ */
6
+
7
+ #ifndef _EXPRVAL_H
8
+ #define _EXPRVAL_H 1
9
+
10
+ #include "exprtype.h"
11
+
12
+ typedef char EXPR_char;
13
+ struct exprval {
14
+ EXPR_char type;
15
+ union uval {
16
+ EXPR_int64 intval; /* integer */
17
+ double dblval; /* double */
18
+ PSTRING strval;
19
+ } val;
20
+ };
21
+
22
+ #define NEW_EXPRVAL(X) { X }
23
+
24
+ #endif /* exprval.h */
25
+
26
+ /*
27
+ * Local Variables:
28
+ * mode: c
29
+ * End:
30
+ */
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ dir_config("html/template/internal")
4
+
5
+ create_makefile("html/template/internal")
6
+
@@ -0,0 +1,449 @@
1
+ #include "ruby.h"
2
+ #include "tmplpro.h"
3
+
4
+ static int debuglevel = 0;
5
+
6
+ struct internal_state {
7
+ char **pathlist;
8
+ };
9
+
10
+ static struct internal_state *new_internal_state() {
11
+ struct internal_state *state = (struct internal_state*)malloc(sizeof(struct internal_state));
12
+ state->pathlist = NULL;
13
+ return state;
14
+ }
15
+
16
+ static void free_internal_state(struct internal_state *state) {
17
+ free(state->pathlist);
18
+ free(state);
19
+ }
20
+
21
+ static void write_chars_to_file (ABSTRACT_WRITER* OutputFile, const char* begin, const char* endnext) {
22
+ rb_io_write((VALUE)OutputFile, rb_str_new(begin, endnext - begin));
23
+ }
24
+
25
+ static void write_chars_to_string (ABSTRACT_WRITER* OutputString, const char* begin, const char* endnext) {
26
+ rb_str_cat((VALUE)OutputString, begin, endnext - begin);
27
+ }
28
+
29
+ static ABSTRACT_VALUE* get_ABSTRACT_VALUE_impl (ABSTRACT_DATASTATE *none, ABSTRACT_MAP* hashPtr, PSTRING name) {
30
+ VALUE key = ID2SYM(rb_intern2(name.begin, name.endnext - name.begin));
31
+ VALUE val = rb_hash_aref((VALUE)hashPtr, key);
32
+ if (NIL_P(val)) {
33
+ key = rb_str_new(name.begin, name.endnext - name.begin);
34
+ val = rb_hash_aref((VALUE)hashPtr, key);
35
+ }
36
+ return NIL_P(val) ? NULL : (ABSTRACT_VALUE*)val;
37
+ }
38
+
39
+ static
40
+ PSTRING ABSTRACT_VALUE2PSTRING_impl (ABSTRACT_DATASTATE *none, ABSTRACT_VALUE* valptr) {
41
+ VALUE val = (VALUE)valptr;
42
+ PSTRING retval = {NULL,NULL};
43
+
44
+ if (valptr == NULL) return retval;
45
+
46
+ if (rb_obj_is_kind_of(val, rb_cProc)) {
47
+ val = rb_proc_call(val, rb_ary_new());
48
+ }
49
+
50
+ if (TYPE(val) != T_STRING) {
51
+ ID to_s = rb_intern("to_s");
52
+ val = rb_funcall(val, to_s, 0);
53
+ }
54
+ retval.begin = RSTRING_PTR(val);
55
+ retval.endnext = retval.begin + RSTRING_LEN(val);
56
+ return retval;
57
+ }
58
+
59
+ static
60
+ int is_ABSTRACT_VALUE_true_impl (ABSTRACT_DATASTATE *none, ABSTRACT_VALUE* valptr) {
61
+ VALUE val = (VALUE)valptr;
62
+
63
+ if (NIL_P(val)) return 0;
64
+
65
+ if (rb_obj_is_kind_of(val, rb_cProc)) {
66
+ val = rb_proc_call(val, rb_ary_new());
67
+ }
68
+
69
+ if (NIL_P(val) || TYPE(val) == T_FALSE) return 0;
70
+
71
+ return 1;
72
+ }
73
+
74
+ static
75
+ ABSTRACT_ARRAY* ABSTRACT_VALUE2ABSTRACT_ARRAY_impl (ABSTRACT_DATASTATE *none, ABSTRACT_VALUE* abstrvalptr) {
76
+ if (TYPE(abstrvalptr) != T_ARRAY) return 0;
77
+ return (ABSTRACT_ARRAY*)abstrvalptr;
78
+ }
79
+
80
+ static
81
+ int get_ABSTRACT_ARRAY_length_impl (ABSTRACT_DATASTATE *none, ABSTRACT_ARRAY* loops) {
82
+ if (TYPE(loops) != T_ARRAY) return 0;
83
+ return RARRAY_LEN((VALUE)loops);
84
+ }
85
+
86
+ static
87
+ ABSTRACT_MAP* get_ABSTRACT_MAP_impl (ABSTRACT_DATASTATE *none, ABSTRACT_ARRAY* loops_ary, int loop) {
88
+ return (ABSTRACT_MAP *)rb_ary_entry((VALUE)loops_ary, loop);
89
+ }
90
+
91
+ typedef void (*set_int_option_functype) (struct tmplpro_param*, int);
92
+
93
+ static
94
+ void set_integer_from_hash(VALUE option_hash, char* key, struct tmplpro_param* param, set_int_option_functype setfunc) {
95
+ VALUE option_key = ID2SYM(rb_intern(key));
96
+ VALUE option_val = rb_hash_aref(option_hash, option_key);
97
+ if (NIL_P(option_val)) return;
98
+ setfunc(param, NUM2INT(option_val));
99
+ }
100
+
101
+ static
102
+ void set_boolean_from_hash(VALUE option_hash, char* key, struct tmplpro_param* param, set_int_option_functype setfunc) {
103
+ VALUE option_key = ID2SYM(rb_intern(key));
104
+ VALUE option_val = rb_hash_aref(option_hash, option_key);
105
+ int val = NIL_P(option_val) || TYPE(option_val) == T_FALSE ? 0 : 1;
106
+ setfunc(param, val);
107
+ }
108
+
109
+ static
110
+ PSTRING get_string_from_value(VALUE self, char* key) {
111
+ ID key_id = rb_intern(key);
112
+ VALUE strval = rb_ivar_get(self, key_id);
113
+ PSTRING retval={NULL,NULL};
114
+ if (NIL_P(strval)) return retval;
115
+ retval.begin = StringValuePtr(strval);
116
+ retval.endnext = retval.begin + RSTRING_LEN(strval);
117
+ return retval;
118
+ }
119
+
120
+ static
121
+ PSTRING get_string_from_hash(VALUE hash, char* key_string) {
122
+ VALUE key = ID2SYM(rb_intern(key_string));
123
+ VALUE val = rb_hash_aref(hash, key);
124
+ PSTRING retval={NULL,NULL};
125
+ if (NIL_P(val)) return retval;
126
+ retval.begin = StringValuePtr(val);
127
+ retval.endnext = retval.begin + RSTRING_LEN(val);
128
+ return retval;
129
+ }
130
+
131
+ static
132
+ int get_boolean_from_hash(VALUE options, char* keystr) {
133
+ VALUE key = ID2SYM(rb_intern(keystr));
134
+ VALUE val = rb_hash_aref(options, key);
135
+ return NIL_P(val) || TYPE(val) == T_FALSE ? 0 : 1;
136
+ }
137
+
138
+ static
139
+ PSTRING load_file (ABSTRACT_FILTER* callback_state, const char* filepath) {
140
+ PSTRING tmpl;
141
+ VALUE self = (VALUE)callback_state;
142
+ VALUE path = rb_str_new_cstr(filepath);
143
+ VALUE result = rb_funcall(self, rb_intern("load_template"), 1, path);
144
+ if (!NIL_P(result) && TYPE(result) == T_STRING) {
145
+ tmpl.begin = StringValuePtr(result);
146
+ tmpl.endnext = tmpl.begin + RSTRING_LEN(result);
147
+ }
148
+ else {
149
+ rb_raise(rb_eRuntimeError, "Big trouble! load_template internal fatal error\n") ;
150
+ }
151
+ return tmpl;
152
+ }
153
+
154
+ static
155
+ int unload_file(ABSTRACT_FILTER* callback_state, PSTRING memarea) {
156
+ return 0;
157
+ }
158
+
159
+ static
160
+ ABSTRACT_USERFUNC* is_expr_userfnc (ABSTRACT_FUNCMAP* FuncHash, PSTRING name) {
161
+ VALUE key = ID2SYM(rb_intern2(name.begin, name.endnext - name.begin));
162
+ VALUE val = rb_hash_aref((VALUE)FuncHash, key);
163
+ if (NIL_P(val)) return NULL;
164
+ return (ABSTRACT_USERFUNC *)val;
165
+ }
166
+
167
+ static
168
+ void free_expr_arglist(ABSTRACT_ARGLIST* arglist) {
169
+ VALUE args = (VALUE)arglist;
170
+ VALUE registory = rb_ary_shift(args);
171
+ rb_hash_delete(registory, rb_obj_id(args));
172
+ return;
173
+ }
174
+
175
+ static
176
+ ABSTRACT_ARGLIST* init_expr_arglist(ABSTRACT_CALLER* callback_state)
177
+ {
178
+ VALUE self = (VALUE)callback_state;
179
+ VALUE registory = rb_ivar_get(self, rb_intern("@internal_expr_args"));
180
+ VALUE args = rb_ary_new();
181
+ rb_ary_push(args, registory);
182
+ rb_hash_aset(registory, rb_obj_id(args), args);
183
+ return (ABSTRACT_ARGLIST*)args;
184
+ }
185
+
186
+ static
187
+ void push_expr_arglist(ABSTRACT_ARGLIST* arglist, ABSTRACT_EXPRVAL* exprval)
188
+ {
189
+ VALUE val = Qnil;
190
+ int exprval_type = tmplpro_get_expr_type(exprval);
191
+ PSTRING parg;
192
+ switch (exprval_type) {
193
+ case EXPR_TYPE_NULL: val = Qnil; break;
194
+ case EXPR_TYPE_INT: val = INT2NUM(tmplpro_get_expr_as_int64(exprval)); break;
195
+ case EXPR_TYPE_DBL: val = rb_float_new(tmplpro_get_expr_as_double(exprval)); break;
196
+ case EXPR_TYPE_PSTR:
197
+ parg = tmplpro_get_expr_as_pstring(exprval);
198
+ val = rb_str_new(parg.begin, parg.endnext - parg.begin);
199
+ break;
200
+ default:
201
+ rb_raise(rb_eRuntimeError, "Ruby wrapper: FATAL INTERNAL ERROR:Unsupported type %d in exprval", exprval_type);
202
+ }
203
+ rb_ary_push((VALUE)arglist, val);
204
+ }
205
+
206
+ static
207
+ void call_expr_userfnc (ABSTRACT_CALLER* callback_state, ABSTRACT_ARGLIST* arglist, ABSTRACT_USERFUNC* hashvalptr, ABSTRACT_EXPRVAL* exprval) {
208
+ char* empty = "";
209
+ VALUE self = (VALUE)callback_state;
210
+ VALUE func = (VALUE)hashvalptr;
211
+ VALUE args = (VALUE)arglist;
212
+ PSTRING retvalpstr = { empty, empty };
213
+
214
+ if (hashvalptr==NULL) {
215
+ rb_raise(rb_eRuntimeError, "FATAL INTERNAL ERROR:Call_EXPR:function called but not exists");
216
+ tmplpro_set_expr_as_pstring(exprval, retvalpstr);
217
+ return;
218
+ } else if (NIL_P(func) || !rb_obj_is_kind_of(func, rb_cProc)) {
219
+ rb_raise(rb_eRuntimeError, "FATAL INTERNAL ERROR:Call_EXPR:not a Proc object");
220
+ tmplpro_set_expr_as_pstring(exprval, retvalpstr);
221
+ return;
222
+ }
223
+
224
+ /* head of args is not a true aruguments(it is a regisotry of args). */
225
+ VALUE tmp = rb_ary_shift(args);
226
+ VALUE retval = rb_proc_call(func, args);
227
+ rb_ary_unshift(args, tmp);
228
+
229
+ VALUE registory = Qnil;
230
+
231
+ switch (TYPE(retval)) {
232
+ case T_FIXNUM:
233
+ tmplpro_set_expr_as_int64(exprval, FIX2LONG(retval));
234
+ break;
235
+ case T_TRUE:
236
+ tmplpro_set_expr_as_int64(exprval, 1);
237
+ break;
238
+ case T_FALSE:
239
+ tmplpro_set_expr_as_int64(exprval, 0);
240
+ break;
241
+ case T_FLOAT:
242
+ tmplpro_set_expr_as_double(exprval, NUM2DBL(retval));
243
+ break;
244
+ case T_NIL:
245
+ tmplpro_set_expr_as_null(exprval);
246
+ break;
247
+ default:
248
+ registory = rb_ivar_get(self, rb_intern("@internal_expr_results"));
249
+ rb_ary_push(registory, retval);
250
+ retvalpstr.begin = StringValuePtr(retval);
251
+ retvalpstr.endnext = retvalpstr.begin + RSTRING_LEN(retval);
252
+ tmplpro_set_expr_as_pstring(exprval, retvalpstr);
253
+ }
254
+
255
+ return;
256
+ }
257
+
258
+ static
259
+ char** set_pathlist(VALUE self, VALUE options, char* param_name) {
260
+ long i, len;
261
+ struct internal_state *state;
262
+ VALUE key = ID2SYM(rb_intern(param_name));
263
+ VALUE paths = rb_hash_aref(options, key);
264
+ VALUE callback_state = rb_ivar_get(self, rb_intern("@internal_state"));
265
+ if (NIL_P(paths) || NIL_P(callback_state)) return NULL;
266
+ Data_Get_Struct(callback_state, struct internal_state, state);
267
+ if (TYPE(paths) != T_ARRAY) rb_raise(rb_eRuntimeError, "path param is not array");
268
+ len = RARRAY_LEN(paths);
269
+ if (len < 0) return NULL;
270
+ state->pathlist = (char **)malloc(sizeof(char*) * (len + 1));
271
+ for (i=0;i<len;i++) {
272
+ VALUE elem = rb_ary_entry(paths, i);
273
+ state->pathlist[i] = StringValueCStr(elem);
274
+ }
275
+ state->pathlist[len] = NULL;
276
+ return state->pathlist;
277
+ }
278
+
279
+ static struct tmplpro_param*
280
+ process_tmplpro_options(VALUE self)
281
+ {
282
+ struct tmplpro_param* param = tmplpro_param_init();
283
+ const char* tmpstring;
284
+ int default_escape=HTML_TEMPLATE_OPT_ESCAPE_NO;
285
+
286
+ tmplpro_set_option_WriterFuncPtr(param, &write_chars_to_string);
287
+ tmplpro_set_option_GetAbstractValFuncPtr(param, &get_ABSTRACT_VALUE_impl);
288
+ tmplpro_set_option_AbstractVal2pstringFuncPtr(param, &ABSTRACT_VALUE2PSTRING_impl);
289
+ tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(param, &ABSTRACT_VALUE2ABSTRACT_ARRAY_impl);
290
+ tmplpro_set_option_GetAbstractArrayLengthFuncPtr(param, &get_ABSTRACT_ARRAY_length_impl);
291
+ tmplpro_set_option_IsAbstractValTrueFuncPtr(param, &is_ABSTRACT_VALUE_true_impl);
292
+ tmplpro_set_option_GetAbstractMapFuncPtr(param, &get_ABSTRACT_MAP_impl);
293
+ tmplpro_set_option_LoadFileFuncPtr(param, &load_file);
294
+ tmplpro_set_option_UnloadFileFuncPtr(param, &unload_file);
295
+
296
+ /* setting initial Expr hooks */
297
+ tmplpro_set_option_InitExprArglistFuncPtr(param, &init_expr_arglist);
298
+ tmplpro_set_option_FreeExprArglistFuncPtr(param, &free_expr_arglist);
299
+ tmplpro_set_option_PushExprArglistFuncPtr(param, &push_expr_arglist);
300
+ tmplpro_set_option_CallExprUserfncFuncPtr(param, &call_expr_userfnc);
301
+ tmplpro_set_option_IsExprUserfncFuncPtr(param, &is_expr_userfnc);
302
+ /* end setting initial hooks */
303
+
304
+ /* setting ruby globals */
305
+ tmplpro_set_option_ext_findfile_state(param, (ABSTRACT_FINDFILE *)self);
306
+ tmplpro_set_option_ext_filter_state(param, (ABSTRACT_FILTER *)self);
307
+ tmplpro_set_option_ext_calluserfunc_state(param, (ABSTRACT_CALLER *)self);
308
+ tmplpro_set_option_ext_data_state(param, (ABSTRACT_DATASTATE *)self);
309
+ /* end setting ruby globals */
310
+
311
+ if ((void*)self == NULL) {
312
+ rb_raise(rb_eRuntimeError, "FATAL:SELF:self was expected but not found");
313
+ }
314
+ Check_Type(self, T_OBJECT);
315
+
316
+ /* checking main arguments */
317
+ PSTRING filename = get_string_from_value(self, "@filename");
318
+ PSTRING scalarref = get_string_from_value(self, "@scalarref");
319
+ tmplpro_set_option_filename(param, filename.begin);
320
+ tmplpro_set_option_scalarref(param, scalarref);
321
+ if (filename.begin==NULL && scalarref.begin==NULL) {
322
+ rb_raise(rb_eRuntimeError, "bad arguments: expected filename or scalarref");
323
+ }
324
+
325
+ VALUE options = rb_ivar_get(self, rb_intern("@options"));
326
+ Check_Type(options, T_HASH);
327
+
328
+ /* setting expr_func */
329
+ VALUE expr_key = ID2SYM(rb_intern("expr_func"));
330
+ VALUE expr = rb_hash_aref(options, expr_key);
331
+ if (!expr || NIL_P(expr) || TYPE(expr) != T_HASH) {
332
+ rb_raise(rb_eRuntimeError, "FATAL:output:EXPR user functions not found");
333
+ }
334
+ tmplpro_set_option_expr_func_map(param, (ABSTRACT_FUNCMAP *)expr);
335
+ /* end setting expr_func */
336
+
337
+ /* setting param_map */
338
+ tmplpro_clear_option_param_map(param);
339
+ VALUE map = rb_ivar_get(self, rb_intern("@params"));
340
+ Check_Type(map, T_HASH);
341
+ tmplpro_push_option_param_map(param, (ABSTRACT_MAP*)map, 0);
342
+ /* end setting param_map */
343
+
344
+ /* setting filter */
345
+ VALUE filter_key = ID2SYM(rb_intern("filter"));
346
+ VALUE filter = rb_hash_aref(options, filter_key);
347
+ Check_Type(filter, T_ARRAY);
348
+ if (RARRAY_LEN(filter) >= 0) tmplpro_set_option_filters(param, 1);
349
+ /* end setting filter */
350
+
351
+ if (!get_boolean_from_hash(options, "case_sensitive")) {
352
+ tmplpro_set_option_tmpl_var_case(param, ASK_NAME_LOWERCASE);
353
+ }
354
+
355
+ set_integer_from_hash(options,"tmpl_var_case",param,tmplpro_set_option_tmpl_var_case);
356
+ set_integer_from_hash(options,"max_includes",param,tmplpro_set_option_max_includes);
357
+ set_boolean_from_hash(options,"no_includes",param,tmplpro_set_option_no_includes);
358
+ set_boolean_from_hash(options,"search_path_on_include",param,tmplpro_set_option_search_path_on_include);
359
+ set_boolean_from_hash(options,"global_vars",param,tmplpro_set_option_global_vars);
360
+ set_integer_from_hash(options,"debug",param,tmplpro_set_option_debug);
361
+ debuglevel = tmplpro_get_option_debug(param);
362
+ set_boolean_from_hash(options,"loop_context_vars",param,tmplpro_set_option_loop_context_vars);
363
+ set_boolean_from_hash(options,"path_like_variable_scope",param,tmplpro_set_option_path_like_variable_scope);
364
+ /* still unsupported */
365
+ set_boolean_from_hash(options,"strict",param,tmplpro_set_option_strict);
366
+
367
+ tmpstring = get_string_from_hash(options, "default_escape").begin;
368
+ if (tmpstring && *tmpstring) {
369
+ switch (*tmpstring) {
370
+ case '1': case 'H': case 'h': /* HTML*/
371
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_HTML;
372
+ break;
373
+ case 'U': case 'u': /* URL */
374
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_URL;
375
+ break;
376
+ case 'J': case 'j': /* JS */
377
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_JS;
378
+ break;
379
+ case '0': case 'N': case 'n': /* 0 or NONE */
380
+ default_escape = HTML_TEMPLATE_OPT_ESCAPE_NO;
381
+ break;
382
+ default:
383
+ rb_warn("unsupported value of default_escape=%s. Valid values are HTML, URL or JS.\n",tmpstring);
384
+ }
385
+ tmplpro_set_option_default_escape(param, default_escape);
386
+ }
387
+
388
+ /* set path */
389
+ tmplpro_set_option_path(param, set_pathlist(self, options, "path"));
390
+ tmplpro_set_option_FindFileFuncPtr(param, NULL);
391
+
392
+ return param;
393
+ }
394
+
395
+ static void
396
+ release_tmplpro_options(struct tmplpro_param* param)
397
+ {
398
+ tmplpro_param_free(param);
399
+ }
400
+
401
+ VALUE mHtml;
402
+ VALUE mHtmlTemplate;
403
+ VALUE mHtmlTemplateInternal;
404
+ VALUE cHtmlTemplateInternalState;
405
+
406
+ static void setup_internal(VALUE self)
407
+ {
408
+ struct internal_state *state = new_internal_state();
409
+ VALUE internal_state = Data_Wrap_Struct(cHtmlTemplateInternalState, 0,
410
+ &free_internal_state, state);
411
+ rb_ivar_set(self, rb_intern("@internal_state"), internal_state);
412
+ rb_ivar_set(self, rb_intern("@internal_expr_args"), rb_hash_new());
413
+ rb_ivar_set(self, rb_intern("@internal_expr_results"), rb_ary_new());
414
+ }
415
+
416
+ static VALUE exec_tmpl(VALUE self, VALUE output)
417
+ {
418
+ writer_functype writer;
419
+ struct tmplpro_param* proparam;
420
+ setup_internal(self);
421
+ proparam = process_tmplpro_options(self);
422
+
423
+ switch (TYPE(output)) {
424
+ case T_STRING:
425
+ writer = &write_chars_to_string;
426
+ break;
427
+ case T_FILE:
428
+ writer = &write_chars_to_file;
429
+ break;
430
+ default:
431
+ rb_warning("bad file descriptor. Use output=stdout\n");
432
+ writer = &write_chars_to_file;
433
+ output = rb_stdout;
434
+ }
435
+ tmplpro_set_option_WriterFuncPtr(proparam, writer);
436
+ tmplpro_set_option_ext_writer_state(proparam, (ABSTRACT_WRITER *)output);
437
+ int retval = tmplpro_exec_tmpl(proparam);
438
+ release_tmplpro_options(proparam);
439
+ return INT2FIX(retval);
440
+ }
441
+
442
+ void Init_internal(void)
443
+ {
444
+ mHtml = rb_define_module("HTML");
445
+ mHtmlTemplate = rb_define_module_under(mHtml, "Template");
446
+ mHtmlTemplateInternal = rb_define_module_under(mHtmlTemplate, "Internal");
447
+ rb_define_module_function(mHtmlTemplateInternal, "exec_tmpl", &exec_tmpl, 1);
448
+ cHtmlTemplateInternalState = rb_define_class_under(mHtmlTemplateInternal, "State", rb_cObject);
449
+ }