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,361 @@
1
+ /*
2
+ * File: builtin_findfile.c
3
+ * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4
+ * Created: Tue Jul 14 22:47:11 2009
5
+ */
6
+
7
+ #include <ctype.h> /* for isalpha */
8
+
9
+ /* TODO: support CYGWIN
10
+ * see
11
+ * http://sourceware.org/autobook/autobook/autobook_249.html
12
+ */
13
+ #if defined __CYGWIN32__ && !defined __CYGWIN__
14
+ /* For backwards compatibility with Cygwin b19 and
15
+ earlier, we define __CYGWIN__ here, so that
16
+ we can rely on checking just for that macro. */
17
+ # define __CYGWIN__ __CYGWIN32__
18
+ #endif
19
+
20
+ #if defined _WIN32 && !defined __CYGWIN__
21
+ /* Use Windows separators on all _WIN32 defining
22
+ environments, except Cygwin. */
23
+ # define DIR_SEPARATOR_CHAR '\\'
24
+ #endif
25
+
26
+ #if defined (DIR_SEPARATOR_CHAR)
27
+ # define IS_FILE_SEP(X) ((X=='/') || (X==DIR_SEPARATOR_CHAR))
28
+ #else
29
+ # define IS_FILE_SEP(X) (X=='/')
30
+ #endif
31
+
32
+ static int _ff_exists(const char* path) {
33
+ FILE *file_p = fopen(path, "r");
34
+ if (file_p) {
35
+ fclose(file_p);
36
+ if (debuglevel>=TMPL_LOG_DEBUG2) tmpl_log(TMPL_LOG_DEBUG2,"_ff_exists: found [%s]\n",path);
37
+ return 1;
38
+ }
39
+ if (debuglevel>=TMPL_LOG_DEBUG2) tmpl_log(TMPL_LOG_ERROR,"_ff_exists: not found [%s]\n",path);
40
+ return 0;
41
+ }
42
+
43
+ /* lame dirname implementation */
44
+ static PSTRING _ff_dirname(const char* path) {
45
+ PSTRING retval={(char*)path,(char*)path};
46
+ char c=0;
47
+ if (path!=NULL) retval.endnext += strlen(path);
48
+ else return retval;
49
+ while (retval.endnext > retval.begin && (c=*(--retval.endnext)) && ! IS_FILE_SEP(c));
50
+ return retval;
51
+ }
52
+ /*
53
+ Windows Relative Paths
54
+
55
+ For functions that manipulate files, the file names can be relative to the current directory. A file name is relative to the current directory if it does not begin with one of the following:
56
+
57
+ * A UNC name of any format.
58
+ * A disk designator with a backslash, for example "C:\".
59
+ * A backslash, for example, "\directory").
60
+ */
61
+
62
+ /* remember about \\?\ and \\?\UNC\ prefixes on WIN platform.
63
+ * see "File Names, Paths, and Namespaces"
64
+ * http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx
65
+ */
66
+ int _ff_is_absolute(const char * filename) {
67
+ unsigned char c0 = *filename;
68
+ #if defined _WIN32 || defined __CYGWIN__
69
+ unsigned char c1;
70
+ #endif
71
+ if ('\0' == c0) return 0;
72
+ /* \\?\ and \\?\UNC\ prefixes are included too */
73
+ if (IS_FILE_SEP(c0)) return 1;
74
+ #if defined _WIN32 || defined __CYGWIN__
75
+ c1 = *(++filename);
76
+ if ('\0' == c1) return 0;
77
+ if (isalpha(c0) && ':'==c1 && IS_FILE_SEP(*filename)) return 1;
78
+ #endif
79
+ return 0;
80
+ }
81
+
82
+ #if defined _WIN32 || defined __CYGWIN__
83
+ int _ff_is_win_fully_qualified_path(const char * filename) {
84
+ unsigned char c0 = *filename;
85
+ unsigned char c1;
86
+ unsigned char c2;
87
+ if ('\0' == c0) return 0;
88
+ c1 = *(++filename);
89
+ if ('\0' == c1) return 0;
90
+ c2 = *(++filename);
91
+ /* \\?\ and \\?\UNC\ prefixes are included too */
92
+ if (isalpha(c0) && ':'==c1 && IS_FILE_SEP(c2)) return 1;
93
+ if ('\\'==c0 && '\\'==c1 && '?'==c2 && '\\'==*filename) return 1;
94
+ return 0;
95
+ }
96
+ #endif
97
+
98
+ #define _ff_canonical_path(X) (X)
99
+
100
+ static MPSTRING _shift_back_pstring_at(MPSTRING buf, char* pos, long shift) {
101
+ if (pos >= buf.begin && (pos+shift) <=buf.endnext) {
102
+ buf.endnext -= shift;
103
+ while (pos<buf.endnext) {
104
+ *pos=*(pos+shift);
105
+ pos++;
106
+ }
107
+ }
108
+ *buf.endnext='\0';
109
+ return buf;
110
+ }
111
+
112
+ static MPSTRING _filepath_remove_multiple_slashes(MPSTRING buf) {
113
+ char* pos = buf.begin;
114
+ #if defined _WIN32
115
+ /* due to \\?\ and \\?\UNC\ prefixes on WIN platform.
116
+ * see "File Names, Paths, and Namespaces"
117
+ * http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx
118
+ * we skip first 2 bytes of path
119
+ */
120
+ if (((buf.endnext-pos)>1) && ('\\'==*pos && '\\'==*(pos+1))) pos += 2;
121
+ #endif
122
+ while (pos<buf.endnext-1) {
123
+ if (IS_FILE_SEP(*pos) && IS_FILE_SEP(*(pos+1))) buf=_shift_back_pstring_at(buf, pos, 1);
124
+ else pos++;
125
+ }
126
+ return buf;
127
+ }
128
+
129
+ static const char* _ff_canonical_path_from_buf(MPSTRING buf) {
130
+ char* pos;
131
+ char* prev_slash_next;
132
+ char* slash_begin;
133
+ /* /./ <-- shift -2 */
134
+ pos = buf.begin;
135
+ while (pos<buf.endnext-2) {
136
+ if (IS_FILE_SEP(*pos) && ('.'==*(pos+1)) && IS_FILE_SEP(*(pos+2))) buf=_shift_back_pstring_at(buf, pos, 2);
137
+ pos++;
138
+ }
139
+
140
+ /* // <-- shift -1 */
141
+ buf=_filepath_remove_multiple_slashes(buf);
142
+
143
+ /* /.* /../ shift (scan from prevslash to slash back) */
144
+ pos = buf.begin;
145
+ slash_begin = buf.begin;
146
+ #if defined _WIN32
147
+ /* check for C: */
148
+ if (((buf.endnext-pos)>1) && isalpha((unsigned char) *pos) && ':'==*(pos+1)) {
149
+ pos += 2;
150
+ slash_begin += 2;
151
+ }
152
+ #endif
153
+ prev_slash_next = slash_begin;
154
+ while (pos<buf.endnext-3) {
155
+ /*printf("debug: %s pos=%c[%ld] fsn=%c[%ld]\n",buf.begin,*pos, pos-buf.begin, *prev_slash_next,prev_slash_next-buf.begin);*/
156
+ if (IS_FILE_SEP(*pos)) {
157
+ if (('.'==*(pos+1)) && ('.'==*(pos+2)) && IS_FILE_SEP(*(pos+3))) {
158
+ /*printf("debug: do shift pos=%ld fsn=%ld shift=%ld\n", pos-buf.begin, prev_slash_next-buf.begin, pos-prev_slash_next+4);*/
159
+ if (pos == prev_slash_next && prev_slash_next==slash_begin) {
160
+ /* begining of the string ("/../") -> leave one slash */
161
+ buf=_shift_back_pstring_at(buf, prev_slash_next, pos-prev_slash_next+3);
162
+ pos=prev_slash_next-1;/* 1 to compensate pos++ */
163
+ } else {
164
+ buf=_shift_back_pstring_at(buf, prev_slash_next, pos-prev_slash_next+4);
165
+ pos=prev_slash_next-2;/* 2 to compensate / and pos++ */
166
+ /* 2 to step back slashnext char and 'slash' char, if any */
167
+ if (prev_slash_next>slash_begin) prev_slash_next--;
168
+ if (prev_slash_next>slash_begin) prev_slash_next--;
169
+ }
170
+ /* old prev_slash_next now current, so we need to recalculate it */
171
+ /* first find a 'slash' char */
172
+ while (!IS_FILE_SEP(*prev_slash_next) && prev_slash_next>=slash_begin) prev_slash_next--;
173
+ if (prev_slash_next>slash_begin) prev_slash_next++;/* step next to slash */
174
+ } else {
175
+ prev_slash_next=pos+1;
176
+ }
177
+ }
178
+ pos++;
179
+ }
180
+
181
+ /* // <-- shift -1 */
182
+ buf=_filepath_remove_multiple_slashes(buf);
183
+
184
+ /* offset 0: if ./ shift -2 */
185
+ if ((buf.endnext-buf.begin)<2) return buf.begin;
186
+ pos = buf.begin;
187
+ if (('.'==*pos) && IS_FILE_SEP(*(pos+1))) buf=_shift_back_pstring_at(buf, pos, 2);
188
+ return buf.begin;
189
+ }
190
+
191
+ static MPSTRING _ff_add_pstr_to_buffer(MPSTRING buf, PSTRING pstr) {
192
+ MPSTRING ret = buf;
193
+ const char* s;
194
+ //tmpl_log(TMPL_LOG_ERROR,"_ff_add_pstr_to_buffer: called as [%p,%p]+[%p,%p]\n",buf.begin,buf.endnext, pstr.begin,pstr.endnext);
195
+ for (s=pstr.begin;s<pstr.endnext;s++) {*(ret.endnext++)=*s;}
196
+ //tmpl_log(TMPL_LOG_ERROR,"_ff_add_pstr_to_buffer: ret = [%p,%p]\n",ret.begin,ret.endnext);
197
+ return ret;
198
+ }
199
+ static MPSTRING _ff_add_str_to_buffer(MPSTRING buf, const char* str) {
200
+ MPSTRING ret = buf;
201
+ const char* s=str;
202
+ //tmpl_log(TMPL_LOG_ERROR,"_ff_add_str_to_buffer: called as [%p,%p]+[%s]\n",buf.begin,buf.endnext, str);
203
+ while ('\0'!=*s) {*(ret.endnext++)=*s++;}
204
+ //tmpl_log(TMPL_LOG_ERROR,"_ff_add_str_to_buffer: ret = [%p,%p]\n",ret.begin,ret.endnext);
205
+ return ret;
206
+ }
207
+ static MPSTRING _ff_add_sep_to_buffer(MPSTRING buf) {
208
+ MPSTRING ret = buf;
209
+ if (ret.endnext>ret.begin && IS_FILE_SEP(*(ret.endnext-1))) return ret;
210
+ #ifdef DIR_SEPARATOR_CHAR
211
+ *(ret.endnext++)=DIR_SEPARATOR_CHAR;
212
+ #else
213
+ *(ret.endnext++)='/';
214
+ #endif
215
+ return ret;
216
+ }
217
+ static MPSTRING _ff_add_0_to_buffer(MPSTRING buf) {
218
+ *(buf.endnext++)='\0';
219
+ return buf;
220
+ }
221
+ static const char* _find_file (struct tmplpro_param* param, const char* filename, PSTRING extra_dir) {
222
+ // TODO: finish it
223
+ const char* HTML_TEMPLATE_ROOT = getenv("HTML_TEMPLATE_ROOT");
224
+ size_t HTML_TEMPLATE_ROOT_length=0;
225
+ size_t buffsize=0;
226
+ char** pathlist=param->path;
227
+ MPSTRING pbuf_begin, filepath;
228
+
229
+ if (param->debug >= TMPL_LOG_DEBUG2) {
230
+ tmpl_log(TMPL_LOG_DEBUG2,"built-in _find_file: looking for %s extra dir = %.*s\n",filename, (int)(extra_dir.endnext-extra_dir.begin),extra_dir.begin);
231
+ }
232
+
233
+ /* first check for a full path */
234
+ if (_ff_is_absolute(filename) && _ff_exists(filename)) return _ff_canonical_path(filename);
235
+
236
+ #if defined _WIN32 || defined __CYGWIN__
237
+ /* no sense of prefixing C:\ or \\?\ */
238
+ if (_ff_is_win_fully_qualified_path(filename)) return NULL;
239
+ #endif
240
+
241
+ if (HTML_TEMPLATE_ROOT!=NULL) HTML_TEMPLATE_ROOT_length=strlen(HTML_TEMPLATE_ROOT);
242
+ if (pathlist!=NULL) {
243
+ while (NULL!=*pathlist) {
244
+ size_t pathentrylen=strlen(*pathlist);
245
+ if (buffsize<pathentrylen) buffsize=pathentrylen;
246
+ pathlist++;
247
+ }
248
+ }
249
+ /* bufsize is max possible length path of path considered
250
+ * min is max_len(foreach pathlist)+HTML_TEMPLATE_ROOT_length+strlen(filename)+len(extra_dir)+1)
251
+ * but we malloc an extra space to avoid frequent reallocing
252
+ */
253
+ buffsize+=HTML_TEMPLATE_ROOT_length+strlen(filename)+(extra_dir.endnext-extra_dir.begin)+4+1; /* 4 - for slashes */
254
+ if (0==pbuffer_size(&param->builtin_findfile_buffer)) {
255
+ pbuffer_init_as(&param->builtin_findfile_buffer, 3*buffsize);
256
+ } else {
257
+ pbuffer_resize(&param->builtin_findfile_buffer, buffsize);
258
+ }
259
+ pbuf_begin.begin=pbuffer_string(&param->builtin_findfile_buffer);
260
+ pbuf_begin.endnext=pbuf_begin.begin;
261
+
262
+ /* try the extra_path if one was specified */
263
+ if (extra_dir.begin!=NULL) {
264
+ filepath=_ff_add_pstr_to_buffer(pbuf_begin,extra_dir);
265
+ if (extra_dir.endnext-extra_dir.begin >0)
266
+ filepath=_ff_add_sep_to_buffer(filepath);
267
+ filepath=_ff_add_str_to_buffer(filepath,filename);
268
+ filepath=_ff_add_0_to_buffer(filepath);
269
+ if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath);
270
+ }
271
+
272
+ /* try pre-prending HTML_Template_Root */
273
+ if (HTML_TEMPLATE_ROOT!=NULL) {
274
+ filepath=_ff_add_str_to_buffer(pbuf_begin,HTML_TEMPLATE_ROOT);
275
+ if (HTML_TEMPLATE_ROOT_length >0)
276
+ filepath=_ff_add_sep_to_buffer(filepath);
277
+ filepath=_ff_add_str_to_buffer(filepath,filename);
278
+ filepath=_ff_add_0_to_buffer(filepath);
279
+ if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath);
280
+ }
281
+
282
+ /* try "path" option list.. */
283
+ pathlist=param->path;
284
+ if (pathlist!=NULL) {
285
+ while (NULL!=*pathlist) {
286
+ //tmpl_log(TMPL_LOG_ERROR,"try 'path' option list..: looking in [%s]\n",*pathlist);
287
+ filepath=_ff_add_str_to_buffer(pbuf_begin,*pathlist);
288
+ /* TODO: check *pathlist length */
289
+ filepath=_ff_add_sep_to_buffer(filepath);
290
+ filepath=_ff_add_str_to_buffer(filepath,filename);
291
+ filepath=_ff_add_0_to_buffer(filepath);
292
+ if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath);
293
+ pathlist++;
294
+ }
295
+ }
296
+
297
+ /* try even a relative path from the current directory...*/
298
+ if (_ff_exists(filename)) return _ff_canonical_path(filename);
299
+
300
+ /* try "path" option list with HTML_TEMPLATE_ROOT prepended... */
301
+ if (HTML_TEMPLATE_ROOT!=NULL) {
302
+ pathlist=param->path;
303
+ if (pathlist!=NULL) {
304
+ while (NULL!=*pathlist) {
305
+ filepath=_ff_add_str_to_buffer(pbuf_begin,HTML_TEMPLATE_ROOT);
306
+ if (HTML_TEMPLATE_ROOT_length >0)
307
+ filepath=_ff_add_sep_to_buffer(filepath);
308
+ filepath=_ff_add_str_to_buffer(filepath,*pathlist);
309
+ /* TODO: check *pathlist length */
310
+ filepath=_ff_add_sep_to_buffer(filepath);
311
+ filepath=_ff_add_str_to_buffer(filepath,filename);
312
+ filepath=_ff_add_0_to_buffer(filepath);
313
+ if (_ff_exists(filepath.begin)) return _ff_canonical_path_from_buf(filepath);
314
+ pathlist++;
315
+ }
316
+ }
317
+ }
318
+
319
+ return NULL;
320
+ }
321
+
322
+ static const char* BACKCALL stub_find_file_func(ABSTRACT_FINDFILE* param,const char* filename, const char* last_visited_file) {
323
+ const char* filepath;
324
+ PSTRING extra_path ={NULL,NULL};
325
+
326
+ if (filename == last_visited_file) tmpl_log(TMPL_LOG_ERROR,"built-in find_file: internal error: buffer clash for %s\n",filename);
327
+
328
+ if (((struct tmplpro_param*)param)->debug>= TMPL_LOG_DEBUG)
329
+ tmpl_log(TMPL_LOG_DEBUG,"built-in find_file: looking for %s last_visited_file = %s\n",filename, last_visited_file);
330
+
331
+ // look for the included file...
332
+ if (last_visited_file!=NULL && ! ((struct tmplpro_param*) param)->search_path_on_include) {
333
+ extra_path = _ff_dirname(last_visited_file);
334
+ }
335
+ filepath = _find_file((struct tmplpro_param*)param,filename,extra_path);
336
+ if (filepath==NULL) {
337
+ char** path=((struct tmplpro_param*)param)->path;
338
+ tmpl_log(TMPL_LOG_ERROR,"built-in find_file: can't find file %s", filename);
339
+ if (NULL!=last_visited_file) tmpl_log(TMPL_LOG_ERROR," (included from %s)", last_visited_file);
340
+ if (NULL!=path) {
341
+ tmpl_log(TMPL_LOG_ERROR," with path = [");
342
+ while (NULL!=*path) {
343
+ tmpl_log(TMPL_LOG_ERROR," '%s'",*path);
344
+ path++;
345
+ }
346
+ tmpl_log(TMPL_LOG_ERROR," ]");
347
+ } else {
348
+ tmpl_log(TMPL_LOG_ERROR," with empty path list");
349
+ }
350
+ tmpl_log(TMPL_LOG_ERROR,"\n");
351
+ return NULL;
352
+ } else {
353
+ return filepath;
354
+ }
355
+ }
356
+
357
+ /*
358
+ * Local Variables:
359
+ * mode: c
360
+ * End:
361
+ */
@@ -0,0 +1,26 @@
1
+ #include <string.h>
2
+ #include "exprtype.h"
3
+
4
+ struct expr_parser;
5
+
6
+ /* Function types */
7
+ typedef double (*func_t_dd) (double);
8
+ typedef double (*func_t_ddd) (double,double);
9
+ typedef struct exprval (*func_t_ee) (struct expr_parser* exprobj, struct exprval);
10
+
11
+ /* memory is allocated at compile time. it is also thread safe */
12
+ struct symrec_const
13
+ {
14
+ char *name; /* name of symbol */
15
+ int type; /* type of symbol: either VAR or FNCT */
16
+ double var; /* value of a VAR */
17
+ void* fnctptr; /* value of a FNCT */
18
+ };
19
+
20
+ typedef struct symrec_const symrec_const;
21
+
22
+ /*
23
+ Local Variables:
24
+ mode: c
25
+ End:
26
+ */
@@ -0,0 +1,120 @@
1
+ /* -*- c -*-
2
+ * File: calc.c
3
+ * $Id$
4
+ */
5
+
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <time.h>
9
+ #include "pmiscdef.h"
10
+ #include "tmplpro.h" /* for tmplpro_version */
11
+
12
+ #ifdef HAVE_CONFIG_H
13
+ #include "config.h"
14
+ #endif
15
+
16
+ #ifndef HAVE_DRAND48
17
+ #define drand48() (((float) rand())/((float) RAND_MAX))
18
+ #define srand48(x) (srand((x)))
19
+ #endif
20
+
21
+
22
+ static
23
+ const symrec_const *
24
+ getsym (const symrec_const symrec_array[], PSTRING sym_name)
25
+ {
26
+ const symrec_const* ptr;
27
+ for (ptr=symrec_array; ptr->name!=NULL; ptr++)
28
+ if (strncmp (ptr->name,sym_name.begin,sym_name.endnext-sym_name.begin) == 0)
29
+ return ptr;
30
+ return 0;
31
+ }
32
+
33
+ #define ABS(X) (((X)<0)? (-X) : (X))
34
+
35
+ static
36
+ struct exprval builtin_int (struct expr_parser* exprobj, struct exprval e) {
37
+ expr_to_int1(exprobj, &e);
38
+ return e;
39
+ }
40
+
41
+ static
42
+ struct exprval builtin_abs (struct expr_parser* exprobj, struct exprval e) {
43
+ expr_to_int_or_dbl1(exprobj, &e);
44
+ if (e.type==EXPR_TYPE_DBL) e.val.dblval = ABS(e.val.dblval);
45
+ else if (e.type==EXPR_TYPE_INT) e.val.intval = ABS(e.val.intval);
46
+ return e;
47
+ }
48
+
49
+ static
50
+ struct exprval builtin_defined (struct expr_parser* exprobj, struct exprval e) {
51
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT);
52
+ if (e.type==EXPR_TYPE_NULL ||
53
+ (e.type==EXPR_TYPE_PSTR && e.val.strval.begin == NULL)) retval.val.intval = 0;
54
+ else retval.val.intval = 1;
55
+ return retval;
56
+ }
57
+
58
+ static
59
+ struct exprval builtin_length (struct expr_parser* exprobj, struct exprval e) {
60
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT);
61
+ expr_to_str1(exprobj->state, &e);
62
+ retval.val.intval = (EXPR_int64) (e.val.strval.endnext - e.val.strval.begin);
63
+ return retval;
64
+ }
65
+
66
+ static
67
+ struct exprval builtin_hex (struct expr_parser* exprobj, struct exprval e) {
68
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT);
69
+ unsigned int scan = 0;
70
+ expr_to_str1(exprobj->state, &e);
71
+ if (e.val.strval.begin!=NULL) sscanf(e.val.strval.begin, "%x", &scan);
72
+ retval.val.intval = scan;
73
+ return retval;
74
+ }
75
+
76
+ static
77
+ struct exprval builtin_oct (struct expr_parser* exprobj, struct exprval e) {
78
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_INT);
79
+ unsigned int scan = 0;
80
+ expr_to_str1(exprobj->state, &e);
81
+ if (e.val.strval.begin!=NULL) sscanf(e.val.strval.begin, "%o", &scan);
82
+ retval.val.intval = scan;
83
+ return retval;
84
+ }
85
+
86
+ static int _srand_called = 0;
87
+
88
+ static
89
+ struct exprval builtin_srand (struct expr_parser* exprobj, struct exprval e) {
90
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_DBL);
91
+ expr_to_int1(exprobj, &e);
92
+ if (e.val.intval == 0) {
93
+ e.val.intval=clock();
94
+ }
95
+ srand48(e.val.intval);
96
+ _srand_called = 1;
97
+ retval.val.dblval = 0;
98
+ return retval;
99
+ }
100
+
101
+ static
102
+ struct exprval builtin_rand (struct expr_parser* exprobj, struct exprval e) {
103
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_DBL);
104
+ if (EXPR_TYPE_PSTR == e.type && NULL == e.val.strval.begin) {
105
+ e.type = EXPR_TYPE_DBL;
106
+ e.val.dblval = 1.0;
107
+ }
108
+ expr_to_dbl1(exprobj, &e);
109
+ if (!_srand_called) srand48(clock());
110
+ retval.val.dblval = drand48() * e.val.dblval;
111
+ return retval;
112
+ }
113
+
114
+ static
115
+ struct exprval builtin_version (struct expr_parser* exprobj, struct exprval e) {
116
+ struct exprval retval = NEW_EXPRVAL(EXPR_TYPE_PSTR);
117
+ retval.val.strval.begin = tmplpro_version();
118
+ retval.val.strval.endnext = retval.val.strval.begin + strlen(retval.val.strval.begin);
119
+ return retval;
120
+ }