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