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,94 @@
1
+ /*
2
+ * File: expr_iface.c
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Sat Apr 15 21:15:24 2006
5
+ */
6
+
7
+ #include <string.h>
8
+ #include "tmplpro.h"
9
+ #include "exprval.h"
10
+ #include "pparam.h"
11
+
12
+ API_IMPL
13
+ void
14
+ APICALL
15
+ tmplpro_set_expr_as_int64 (struct exprval* p,EXPR_int64 ival) {
16
+ p->type=EXPR_TYPE_INT;
17
+ p->val.intval=ival;
18
+ }
19
+
20
+ API_IMPL
21
+ void
22
+ APICALL
23
+ tmplpro_set_expr_as_double (struct exprval* p,double dval) {
24
+ p->type=EXPR_TYPE_DBL;
25
+ p->val.dblval=dval;
26
+ }
27
+
28
+ API_IMPL
29
+ void
30
+ APICALL
31
+ tmplpro_set_expr_as_string (struct exprval* p, const char* sval) {
32
+ p->type=EXPR_TYPE_PSTR;
33
+ p->val.strval.begin=sval;
34
+ p->val.strval.endnext=sval;
35
+ if (NULL!=sval) p->val.strval.endnext+=strlen(sval);
36
+ }
37
+
38
+ API_IMPL
39
+ void
40
+ APICALL
41
+ tmplpro_set_expr_as_pstring (struct exprval* p,PSTRING pval) {
42
+ p->type=EXPR_TYPE_PSTR;
43
+ p->val.strval=pval;
44
+ }
45
+
46
+ API_IMPL
47
+ void
48
+ APICALL
49
+ tmplpro_set_expr_as_null (struct exprval* p) {
50
+ p->type=EXPR_TYPE_PSTR;
51
+ p->val.strval.begin=NULL;
52
+ p->val.strval.endnext=NULL;
53
+ }
54
+
55
+ API_IMPL
56
+ int
57
+ APICALL
58
+ tmplpro_get_expr_type (struct exprval* p) {
59
+ if (p->type == EXPR_TYPE_PSTR) {
60
+ if (NULL==p->val.strval.begin) {
61
+ p->val.strval.endnext=NULL;
62
+ p->type = EXPR_TYPE_NULL;
63
+ } else if (NULL==p->val.strval.endnext) {
64
+ /* should never happen */
65
+ p->val.strval.endnext=p->val.strval.begin+strlen(p->val.strval.begin);
66
+ }
67
+ /* never happen; but let it be for future compatibility */
68
+ } else if (p->type == EXPR_TYPE_NULL) {
69
+ p->val.strval.begin=NULL;
70
+ p->val.strval.endnext=NULL;
71
+ }
72
+ return (int) p->type;
73
+ }
74
+
75
+ API_IMPL
76
+ EXPR_int64
77
+ APICALL
78
+ tmplpro_get_expr_as_int64 (struct exprval* p) {
79
+ return p->val.intval;
80
+ }
81
+
82
+ API_IMPL
83
+ double
84
+ APICALL
85
+ tmplpro_get_expr_as_double (struct exprval* p) {
86
+ return p->val.dblval;
87
+ }
88
+
89
+ API_IMPL
90
+ PSTRING
91
+ APICALL
92
+ tmplpro_get_expr_as_pstring (struct exprval* p) {
93
+ return p->val.strval;
94
+ }
@@ -0,0 +1,36 @@
1
+ /* -*- c -*-
2
+ * File: pstring.h
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Fri Jul 1 20:11:51 2005
5
+ *
6
+ * $Id$
7
+ */
8
+
9
+ #ifndef _EXPR_TYPE_PSTR_H
10
+ #define _EXPR_TYPE_PSTR_H 1
11
+
12
+ #include "exprval.h"
13
+
14
+ static
15
+ PSTRING double_to_pstring (double, char* buf, size_t bufsize);
16
+ static
17
+ PSTRING int_to_pstring (EXPR_int64, char* buf, size_t bufsize);
18
+ static
19
+ int pstring_ge(PSTRING, PSTRING);
20
+ static
21
+ int pstring_le(PSTRING, PSTRING);
22
+ static
23
+ int pstring_ne(PSTRING, PSTRING);
24
+ static
25
+ int pstring_eq(PSTRING, PSTRING);
26
+ static
27
+ int pstring_gt(PSTRING, PSTRING);
28
+ static
29
+ int pstring_lt(PSTRING, PSTRING);
30
+
31
+ static
32
+ int re_like(PSTRING, PSTRING);
33
+ static
34
+ int re_notlike(PSTRING, PSTRING);
35
+
36
+ #endif /* exprpstr.h */
@@ -0,0 +1,144 @@
1
+ /* -*- c -*-
2
+ * File: pstring.h
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Fri Jul 1 20:11:51 2005
5
+ *
6
+ * $Id$
7
+ */
8
+
9
+ #ifdef HAVE_CONFIG_H
10
+ #include "config.h"
11
+ #endif
12
+ #include <stdio.h>
13
+ #include <string.h>
14
+ #include "pstring.h"
15
+ #include "tmpllog.h"
16
+ #include "exprval.h"
17
+ #include "pmiscdef.h" /*for snprintf */
18
+
19
+ static
20
+ PSTRING
21
+ double_to_pstring (double number, char buffer[], size_t bufsize) {
22
+ size_t len=0;
23
+ size_t tmplen=0;
24
+ PSTRING retval;
25
+ snprintf(buffer,bufsize,"%f",number);
26
+ len=strlen(buffer);
27
+ tmplen=len;
28
+ /* removing trailing 0 as 2.00000... */
29
+ while (buffer[tmplen-1]=='0' && tmplen-->0);
30
+ if (buffer[tmplen-1]=='.') {
31
+ tmplen--;
32
+ len=tmplen;
33
+ }
34
+ retval.begin=buffer;
35
+ retval.endnext=buffer+len;
36
+ return retval;
37
+ }
38
+
39
+ static
40
+ PSTRING
41
+ int_to_pstring (EXPR_int64 number, char buffer[], size_t bufsize) {
42
+ size_t len=0;
43
+ PSTRING retval;
44
+ snprintf(buffer, bufsize,"%" EXPR_PRId64 , number);
45
+ len=strlen(buffer);
46
+ retval.begin=buffer;
47
+ retval.endnext=buffer+len;
48
+ return retval;
49
+ }
50
+
51
+ static
52
+ int
53
+ pstring_ge(PSTRING a, PSTRING b) {
54
+ const char* in_a=a.begin;
55
+ const char* in_b=b.begin;
56
+ while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
57
+ if ((in_a==a.endnext && in_b==b.endnext) || *(--in_a) >= *(--in_b) ) return 1; else return 0;
58
+ }
59
+
60
+ static
61
+ int
62
+ pstring_le(PSTRING a, PSTRING b) {
63
+ const char* in_a=a.begin;
64
+ const char* in_b=b.begin;
65
+ while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
66
+ if ((in_a==a.endnext && in_b==b.endnext) || *(--in_a) <= *(--in_b) ) return 1; else return 0;
67
+ }
68
+
69
+ static
70
+ int
71
+ pstring_ne(PSTRING a, PSTRING b) {
72
+ const char* in_a=a.begin;
73
+ const char* in_b=b.begin;
74
+ while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
75
+ if (in_a==a.endnext && in_b==b.endnext && *(--in_a) == *(--in_b)) return 0; else return 1;
76
+ }
77
+
78
+ static
79
+ int
80
+ pstring_eq(PSTRING a, PSTRING b) {
81
+ const char* in_a=a.begin;
82
+ const char* in_b=b.begin;
83
+ while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
84
+ if (in_a==a.endnext && in_b==b.endnext && *(--in_a) == *(--in_b)) return 1; else return 0;
85
+ }
86
+
87
+ static
88
+ int
89
+ pstring_gt(PSTRING a, PSTRING b) {
90
+ const char* in_a=a.begin;
91
+ const char* in_b=b.begin;
92
+ while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
93
+ if ((in_b==b.endnext && in_a!=a.endnext)
94
+ || (*(--in_a) > *(--in_b)) ) return 1; else return 0;
95
+ }
96
+
97
+ static
98
+ int
99
+ pstring_lt(PSTRING a, PSTRING b) {
100
+ const char* in_a=a.begin;
101
+ const char* in_b=b.begin;
102
+ while (in_a<a.endnext && in_b < b.endnext && *in_a++==*in_b++);
103
+ if ((in_b!=b.endnext && in_a==a.endnext)
104
+ || *(--in_a) < *(--in_b) ) return 1; else return 0;
105
+ }
106
+
107
+ static
108
+ int
109
+ re_notlike(PSTRING a, PSTRING b) {
110
+ return ! re_like(a,b);
111
+ }
112
+
113
+ #ifndef HAVE_PCRE
114
+ static
115
+ int
116
+ re_like(PSTRING a, PSTRING b) {
117
+ tmpl_log(TMPL_LOG_ERROR," (sorry, Stanislav Yadykin regexp extension is disabled at compile time) \n");
118
+ return 0;
119
+ }
120
+ #else
121
+ #include <pcre.h>
122
+ static
123
+ int
124
+ re_like(PSTRING a, PSTRING b) {
125
+ pcre* re;
126
+ int ovector[30];
127
+ int rc, erroffset;
128
+ const char* error;
129
+ const char* subject=a.begin;
130
+ int subject_length=(int)(a.endnext-a.begin);
131
+ char* pattern=(char*)malloc(b.endnext-b.begin);
132
+ strncpy(pattern, b.begin, (b.endnext-b.begin));
133
+ *(pattern+(b.endnext-b.begin))=0;
134
+ re = pcre_compile(pattern, 0, &error, &erroffset, NULL); /* default character set */
135
+ free(pattern);
136
+ if (re==NULL) {
137
+ tmpl_log(TMPL_LOG_ERROR, "PCRE compilation failed at offset %d: %s\n",
138
+ erroffset, error);
139
+ return 0;
140
+ }
141
+ rc=pcre_exec(re, NULL, subject, subject_length, 0, 0, ovector, 30);
142
+ return (rc<0)?0:1;
143
+ }
144
+ #endif
@@ -0,0 +1,99 @@
1
+ /* -*- c -*-
2
+ * File: exprtool.h
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Mon Jul 25 15:29:04 2005
5
+ *
6
+ * $Id$
7
+ */
8
+
9
+ #ifndef _EXPRTOOL_H
10
+ #define _EXPRTOOL_H 1
11
+
12
+ #include "pstring.h"
13
+ #include "exprval.h"
14
+
15
+ struct expr_parser {
16
+ struct tmplpro_state* state;
17
+ PSTRING exprarea;
18
+ const char* expr_curpos;
19
+ /* for callbacks */
20
+ struct exprval userfunc_call;
21
+ /*
22
+ * is_expect_quote_like allows recognization of quotelike.
23
+ * if not is_expect_quote_like we look only for 'str' and, possibly, "str"
24
+ * if is_expect_quote_like we also look for /str/.
25
+ */
26
+ int is_expect_quote_like;
27
+ };
28
+
29
+ #define DO_MATHOP(exprobj, z,op,x,y) switch (z.type=expr_to_int_or_dbl(exprobj, &x,&y)) { \
30
+ case EXPR_TYPE_INT: z.val.intval=x.val.intval op y.val.intval;break; \
31
+ case EXPR_TYPE_DBL: z.val.dblval=x.val.dblval op y.val.dblval;break; \
32
+ }
33
+
34
+ #define DO_LOGOP(exprobj, z,op,x,y) z.type=EXPR_TYPE_INT; switch (expr_to_int_or_dbl_logop(exprobj, &x,&y)) { \
35
+ case EXPR_TYPE_INT: z.val.intval=x.val.intval op y.val.intval;break; \
36
+ case EXPR_TYPE_DBL: z.val.intval=x.val.dblval op y.val.dblval;break; \
37
+ }
38
+
39
+ #define DO_LOGOP1(exprobj,z,op,x) z.type=EXPR_TYPE_INT; switch (expr_to_int_or_dbl_logop1(exprobj, &x)) { \
40
+ case EXPR_TYPE_INT: z.val.intval= op x.val.intval;break; \
41
+ case EXPR_TYPE_DBL: z.val.intval= op x.val.dblval;break; \
42
+ }
43
+
44
+ #define DO_CMPOP(exprobj, z,op,x,y) switch (expr_to_int_or_dbl(exprobj, &x,&y)) { \
45
+ case EXPR_TYPE_INT: z.val.intval=x.val.intval op y.val.intval;break; \
46
+ case EXPR_TYPE_DBL: z.val.intval=x.val.dblval op y.val.dblval;break; \
47
+ }; z.type=EXPR_TYPE_INT;
48
+
49
+ #define DO_TXTOP(z,op,x,y,buf) expr_to_str(buf, &x,&y); z.type=EXPR_TYPE_INT; z.val.intval = op (x.val.strval,y.val.strval);
50
+
51
+ static
52
+ EXPR_char expr_to_int_or_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2);
53
+ static
54
+ EXPR_char expr_to_int_or_dbl1 (struct expr_parser* exprobj, struct exprval* val1);
55
+ static
56
+ EXPR_char expr_to_int_or_dbl_logop (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2);
57
+ static
58
+ EXPR_char expr_to_int_or_dbl_logop1 (struct expr_parser* exprobj, struct exprval* val1);
59
+ static
60
+ void expr_to_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2);
61
+ static
62
+ void expr_to_int (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2);
63
+ static
64
+ void expr_to_dbl1 (struct expr_parser* exprobj, struct exprval* val);
65
+ static
66
+ void expr_to_int1 (struct expr_parser* exprobj, struct exprval* val1);
67
+ static
68
+ void expr_to_str (struct tmplpro_state* state, struct exprval* val1, struct exprval* val2);
69
+ static
70
+ void expr_to_str1 (struct tmplpro_state* state, struct exprval* val1);
71
+ static
72
+ void expr_to_num (struct expr_parser* exprobj, struct exprval* val1);
73
+ static
74
+ void expr_to_bool (struct expr_parser* exprobj, struct exprval* val1);
75
+ static
76
+ struct exprval exp_read_number (struct expr_parser* exprobj, const char* *curposptr, const char* endchars);
77
+
78
+ /* this stuff is defined or used in expr.y */
79
+ static
80
+ void log_expr(struct expr_parser* exprobj, int loglevel, const char* fmt, ...) FORMAT_PRINTF(3,4);
81
+
82
+ static
83
+ PSTRING expr_unescape_pstring_val(pbuffer* pbuff, PSTRING val);
84
+
85
+ static
86
+ void _tmplpro_expnum_debug (struct exprval val, char* msg);
87
+
88
+
89
+ struct user_func_call {
90
+ ABSTRACT_USERFUNC* func; /* for user-defined function name */
91
+ ABSTRACT_ARGLIST* arglist;
92
+ };
93
+
94
+ static
95
+ struct exprval call_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call extfunc);
96
+ static
97
+ void pusharg_expr_userfunc(struct expr_parser* exprobj, struct tmplpro_param* param, struct user_func_call extfunc, struct exprval arg);
98
+
99
+ #endif /* exprtool.h */
@@ -0,0 +1,289 @@
1
+ /* -*- c -*-
2
+ * File: exprtool.c
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Mon Jul 25 15:29:17 2005
5
+ *
6
+ * $Id$
7
+ */
8
+
9
+ /*
10
+ #include "exprtool.h"
11
+ #include <ctype.h> // for yylex alnum
12
+ #include <stdio.h> // for printf
13
+ */
14
+
15
+ #define EXPR_CHECK_NUMBER(exprobj, ptr) switch (ptr->type) { \
16
+ case EXPR_TYPE_INT: case EXPR_TYPE_DBL: break; \
17
+ case EXPR_TYPE_UPSTR: case EXPR_TYPE_PSTR: expr_to_num(exprobj, ptr); break; \
18
+ default: _tmplpro_expnum_debug(*ptr, "FATAL:internal expr type error. please report\n"); \
19
+ ptr->type = EXPR_TYPE_INT; \
20
+ }
21
+
22
+ #define EXPR_CHECK_LOGICAL(exprobj, ptr) switch (ptr->type) { \
23
+ case EXPR_TYPE_INT: case EXPR_TYPE_DBL: break; \
24
+ case EXPR_TYPE_UPSTR: case EXPR_TYPE_PSTR: expr_to_bool(exprobj, ptr); break; \
25
+ default: _tmplpro_expnum_debug(*ptr, "FATAL:internal expr type error. please report\n"); \
26
+ ptr->type = EXPR_TYPE_INT; \
27
+ }
28
+
29
+ static
30
+ EXPR_char
31
+ expr_to_int_or_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) {
32
+ EXPR_CHECK_NUMBER(exprobj, val1);
33
+ EXPR_CHECK_NUMBER(exprobj, val2);
34
+ if ((val1->type == EXPR_TYPE_INT) && (val2->type == EXPR_TYPE_INT))
35
+ return EXPR_TYPE_INT;
36
+ if ((val1->type == EXPR_TYPE_DBL) && (val2->type == EXPR_TYPE_DBL))
37
+ return EXPR_TYPE_DBL;
38
+ if (val1->type == EXPR_TYPE_INT) {
39
+ val1->type=EXPR_TYPE_DBL;
40
+ val1->val.dblval=(double) val1->val.intval;
41
+ }
42
+ if (val2->type == EXPR_TYPE_INT) {
43
+ val1->type=EXPR_TYPE_DBL;
44
+ val2->val.dblval=(double) val2->val.intval;
45
+ }
46
+ return EXPR_TYPE_DBL;
47
+ }
48
+
49
+ static
50
+ EXPR_char
51
+ expr_to_int_or_dbl_logop (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) {
52
+ EXPR_CHECK_LOGICAL(exprobj, val1);
53
+ EXPR_CHECK_LOGICAL(exprobj, val2);
54
+ if (val1->type == EXPR_TYPE_INT && val2->type == EXPR_TYPE_INT)
55
+ return EXPR_TYPE_INT;
56
+ if (val1->type == EXPR_TYPE_DBL && val2->type == EXPR_TYPE_DBL)
57
+ return EXPR_TYPE_DBL;
58
+ if (val1->type == EXPR_TYPE_INT) {
59
+ val1->type=EXPR_TYPE_DBL;
60
+ val1->val.dblval=(double) val1->val.intval;
61
+ }
62
+ if (val2->type == EXPR_TYPE_INT) {
63
+ val1->type=EXPR_TYPE_DBL;
64
+ val2->val.dblval=(double) val2->val.intval;
65
+ }
66
+ return EXPR_TYPE_DBL;
67
+ }
68
+
69
+ static
70
+ EXPR_char
71
+ expr_to_int_or_dbl_logop1 (struct expr_parser* exprobj, struct exprval* val1) {
72
+ EXPR_CHECK_LOGICAL(exprobj, val1);
73
+ return val1->type;
74
+ }
75
+
76
+ static
77
+ EXPR_char
78
+ expr_to_int_or_dbl1 (struct expr_parser* exprobj, struct exprval* val1) {
79
+ EXPR_CHECK_NUMBER(exprobj, val1);
80
+ return val1->type;
81
+ }
82
+
83
+ static
84
+ void
85
+ expr_to_dbl1 (struct expr_parser* exprobj, struct exprval* val1) {
86
+ EXPR_CHECK_NUMBER(exprobj, val1);
87
+ if (val1->type == EXPR_TYPE_INT) {
88
+ val1->type=EXPR_TYPE_DBL;
89
+ val1->val.dblval=(double) val1->val.intval;
90
+ }
91
+ }
92
+
93
+ static
94
+ void
95
+ expr_to_int1 (struct expr_parser* exprobj, struct exprval* val1) {
96
+ EXPR_CHECK_NUMBER(exprobj, val1);
97
+ if (val1->type == EXPR_TYPE_DBL) {
98
+ val1->type=EXPR_TYPE_INT;
99
+ val1->val.intval=(EXPR_int64) val1->val.dblval;
100
+ /* _tmplpro_expnum_debug(*val1, "WARN:converting to `int' from `double'"); */
101
+ }
102
+ }
103
+
104
+ static
105
+ void
106
+ expr_to_dbl (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) {
107
+ expr_to_dbl1(exprobj, val1);
108
+ expr_to_dbl1(exprobj, val2);
109
+ }
110
+
111
+ static
112
+ void
113
+ expr_to_int (struct expr_parser* exprobj, struct exprval* val1, struct exprval* val2) {
114
+ expr_to_int1(exprobj, val1);
115
+ expr_to_int1(exprobj, val2);
116
+ }
117
+
118
+ #define EXPR_CHECK_STRING(pbuff, ptr) switch (ptr->type) { \
119
+ case EXPR_TYPE_PSTR: break; \
120
+ case EXPR_TYPE_UPSTR: ptr->val.strval=expr_unescape_pstring_val(pbuff,ptr->val.strval); break; \
121
+ case EXPR_TYPE_INT: ptr->val.strval=int_to_pstring(ptr->val.intval,pbuffer_string(pbuff),pbuffer_size(pbuff)); break; \
122
+ case EXPR_TYPE_DBL: ptr->val.strval=double_to_pstring(ptr->val.dblval,pbuffer_string(pbuff),pbuffer_size(pbuff)); break; \
123
+ default: _tmplpro_expnum_debug(*ptr, "FATAL:internal expr string error. please report\n"); \
124
+ } \
125
+ ptr->type = EXPR_TYPE_PSTR;
126
+
127
+ static
128
+ void
129
+ expr_to_str (struct tmplpro_state* state, struct exprval* val1, struct exprval* val2) {
130
+ EXPR_CHECK_STRING(&(state->expr_left_pbuffer), val1);
131
+ EXPR_CHECK_STRING(&(state->expr_right_pbuffer), val2);
132
+ }
133
+
134
+ static
135
+ void
136
+ expr_to_str1 (struct tmplpro_state* state, struct exprval* val1) {
137
+ EXPR_CHECK_STRING(&(state->expr_left_pbuffer), val1);
138
+ }
139
+
140
+ static
141
+ int
142
+ is_float_lex (char c)
143
+ {
144
+ return (c == '.' || isdigit (c));
145
+ }
146
+
147
+ static
148
+ struct exprval
149
+ exp_read_number (struct expr_parser* exprobj, const char* *curposptr, const char* endchars) {
150
+ char c = **curposptr;
151
+ struct exprval retval;
152
+ EXPR_int64 iretval=0;
153
+ double dretval=0;
154
+ EXPR_int64 offset=0;
155
+ int sign=1;
156
+ retval.type=EXPR_TYPE_INT;
157
+ retval.val.intval=0;
158
+ if ((*curposptr)<endchars && '-' == c) {
159
+ sign=-1;
160
+ c = *(++(*curposptr));
161
+ }
162
+ if (! (c == '.' || isdigit (c))) return retval;
163
+ /* double reader
164
+ yylval.dblval=atof(fill_symbuf(is_float_lex).begin);
165
+ return dblNUM;
166
+ */
167
+ while ((*curposptr)<endchars && is_float_lex(c)) {
168
+ if (c == '.') {
169
+ if (retval.type == EXPR_TYPE_INT) {
170
+ retval.type = EXPR_TYPE_DBL;
171
+ dretval=iretval;
172
+ offset=1;
173
+ } else {
174
+ /* (*curposptr)--; ??? */
175
+ log_expr(exprobj, TMPL_LOG_ERROR, "while reading number: %s\n", "uninspected declimal point");
176
+ retval.val.dblval=dretval*sign;
177
+ retval.type=EXPR_TYPE_DBL;
178
+ return retval;
179
+ }
180
+ } else {
181
+ offset*=10;
182
+ if (retval.type == EXPR_TYPE_INT) {
183
+ iretval=iretval*10+c-'0';
184
+ } else {
185
+ dretval=dretval*10+c-'0';
186
+ }
187
+ }
188
+ c = *(++(*curposptr));
189
+ }
190
+ if (retval.type == EXPR_TYPE_INT) {
191
+ retval.val.intval=iretval*sign;
192
+ } else {
193
+ if (offset) dretval/=offset;
194
+ retval.val.dblval=dretval*sign;
195
+ }
196
+ return retval;
197
+ }
198
+
199
+ static
200
+ void
201
+ expr_to_num (struct expr_parser* exprobj, struct exprval* val1)
202
+ {
203
+ const char* curpos=val1->val.strval.begin;
204
+ EXPR_char type = val1->type;
205
+ if (type == EXPR_TYPE_PSTR || type == EXPR_TYPE_UPSTR) {
206
+ if (NULL==curpos) {
207
+ val1->type = EXPR_TYPE_INT;
208
+ val1->val.intval = 0;
209
+ } else {
210
+ /* escaped string can't be read properly anyway */
211
+ *val1=exp_read_number (exprobj, &curpos, val1->val.strval.endnext);
212
+ }
213
+ }
214
+ }
215
+
216
+ static
217
+ void
218
+ expr_to_bool (struct expr_parser* exprobj, struct exprval* val1)
219
+ {
220
+ if (val1->type == EXPR_TYPE_PSTR || val1->type == EXPR_TYPE_UPSTR) {
221
+ const char* begin=val1->val.strval.begin;
222
+ const char* end=val1->val.strval.endnext;
223
+ const char* curpos=begin;
224
+ if (begin==end) {
225
+ val1->type = EXPR_TYPE_INT;
226
+ val1->val.intval = 0;
227
+ } else {
228
+ *val1=exp_read_number (exprobj, &curpos, end);
229
+ if (val1->type == EXPR_TYPE_INT) {
230
+ if (val1->val.intval || (curpos == end)) return;
231
+ else val1->val.intval=1; /* strings are true in perl */
232
+ }
233
+ else
234
+ if (val1->type == EXPR_TYPE_DBL) {
235
+ if (val1->val.dblval || (curpos == end)) return;
236
+ else val1->val.dblval=1.0; /* strings are true in perl */
237
+ }
238
+ }
239
+ }
240
+ }
241
+
242
+ static
243
+ void
244
+ _tmplpro_expnum_debug (struct exprval val, char* msg)
245
+ {
246
+ tmpl_log(TMPL_LOG_DEBUG,"--> debug %s:type %c ",msg,val.type);
247
+ if (val.type == EXPR_TYPE_INT)
248
+ tmpl_log(TMPL_LOG_DEBUG,"ival=%" EXPR_PRId64 "\n",val.val.intval);
249
+ else if (val.type == EXPR_TYPE_DBL)
250
+ tmpl_log(TMPL_LOG_DEBUG,"dval=%f\n",val.val.dblval);
251
+ else if (val.type == EXPR_TYPE_PSTR) {
252
+ tmpl_log(TMPL_LOG_DEBUG,"pstr(%c):",(int) val.type);
253
+ if (NULL==val.val.strval.begin) tmpl_log(TMPL_LOG_DEBUG,"{begin=NULL}");
254
+ if (NULL==val.val.strval.endnext) tmpl_log(TMPL_LOG_DEBUG,"{endnext=NULL}");
255
+ tmpl_log(TMPL_LOG_DEBUG,"sval=%.*s\n",(int)(val.val.strval.endnext-val.val.strval.begin),val.val.strval.begin);
256
+ } else if (val.type == EXPR_TYPE_NULL) {
257
+ tmpl_log(TMPL_LOG_DEBUG,"NULL\n");
258
+ if (NULL!=val.val.strval.begin) tmpl_log(TMPL_LOG_DEBUG,"{begin!=NULL}");
259
+ if (NULL!=val.val.strval.endnext) tmpl_log(TMPL_LOG_DEBUG,"{endnext!=NULL}");
260
+ } else {
261
+ tmpl_log(TMPL_LOG_DEBUG,"unknown(%c) as ival=%" EXPR_PRId64 "\n",(int) val.type,val.val.intval);
262
+ }
263
+ }
264
+
265
+ /*
266
+ * checks if it is stringval and unescape it (copies to the buffer).
267
+ * it implies that only one string at a time can use buffer.
268
+ */
269
+ static
270
+ PSTRING
271
+ expr_unescape_pstring_val(pbuffer* pbuff, PSTRING val) {
272
+ PSTRING retval;
273
+ const char* curpos = val.begin;
274
+ const char* endnext= val.endnext;
275
+ char* buf=pbuffer_resize(pbuff, endnext-curpos+1);
276
+ char* bufpos = buf;
277
+ while (curpos < endnext) {
278
+ if (*curpos == '\\') {
279
+ *bufpos=*(++curpos);
280
+ } else {
281
+ *bufpos=*curpos;
282
+ }
283
+ curpos++;
284
+ bufpos++;
285
+ }
286
+ retval.begin = buf;
287
+ retval.endnext = bufpos;
288
+ return retval;
289
+ }