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,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
+ }