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.
- data/.autotest +9 -0
- data/ARTISTIC +131 -0
- data/History.txt +4 -0
- data/LGPL +504 -0
- data/Manifest.txt +221 -0
- data/README.rdoc +52 -0
- data/Rakefile +18 -0
- data/benchmark.rb +136 -0
- data/config/website.yml +2 -0
- data/ext/html/template/internal/Pro.xs +679 -0
- data/ext/html/template/internal/builtin_findfile.inc +361 -0
- data/ext/html/template/internal/calc.h +26 -0
- data/ext/html/template/internal/calc.inc +120 -0
- data/ext/html/template/internal/callback_stubs.inc +63 -0
- data/ext/html/template/internal/expr.c +2267 -0
- data/ext/html/template/internal/expr.y +476 -0
- data/ext/html/template/internal/expr_iface.c +94 -0
- data/ext/html/template/internal/exprpstr.h +36 -0
- data/ext/html/template/internal/exprpstr.inc +144 -0
- data/ext/html/template/internal/exprtool.h +99 -0
- data/ext/html/template/internal/exprtool.inc +289 -0
- data/ext/html/template/internal/exprtype.h +62 -0
- data/ext/html/template/internal/exprval.h +30 -0
- data/ext/html/template/internal/extconf.rb +6 -0
- data/ext/html/template/internal/internal.c +449 -0
- data/ext/html/template/internal/loadfile.h +11 -0
- data/ext/html/template/internal/loadfile.inc +171 -0
- data/ext/html/template/internal/pabidecl.h +54 -0
- data/ext/html/template/internal/pabstract.h +426 -0
- data/ext/html/template/internal/parse_expr.h +15 -0
- data/ext/html/template/internal/pbuffer.c +76 -0
- data/ext/html/template/internal/pbuffer.h +31 -0
- data/ext/html/template/internal/pmiscdef.h +54 -0
- data/ext/html/template/internal/pparam.h +101 -0
- data/ext/html/template/internal/ppport.h +1098 -0
- data/ext/html/template/internal/procore.c +1189 -0
- data/ext/html/template/internal/procore.h +18 -0
- data/ext/html/template/internal/proparam.c +443 -0
- data/ext/html/template/internal/proparam.h +571 -0
- data/ext/html/template/internal/proscope.h +32 -0
- data/ext/html/template/internal/proscope.inc +107 -0
- data/ext/html/template/internal/prostate.h +49 -0
- data/ext/html/template/internal/prostate.inc +24 -0
- data/ext/html/template/internal/provalue.h +14 -0
- data/ext/html/template/internal/pstring.h +60 -0
- data/ext/html/template/internal/pstrutils.h +25 -0
- data/ext/html/template/internal/pstrutils.inc +150 -0
- data/ext/html/template/internal/tagstack.h +30 -0
- data/ext/html/template/internal/tagstack.inc +65 -0
- data/ext/html/template/internal/tmpllog.c +62 -0
- data/ext/html/template/internal/tmpllog.h +27 -0
- data/ext/html/template/internal/tmplpro.h +218 -0
- data/ext/html/template/internal/tmplpro_version.c +35 -0
- data/lib/html/template/pro.rb +225 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/tasks/extconf.rake +13 -0
- data/tasks/extconf/tmplpro.rake +43 -0
- data/templates-Pro/a.incl +1 -0
- data/templates-Pro/empty.incl +0 -0
- data/templates-Pro/include/1/a.incl +1 -0
- data/templates-Pro/include/2.out +3 -0
- data/templates-Pro/include/2.tmpl +1 -0
- data/templates-Pro/include/2/a.incl +1 -0
- data/templates-Pro/include/3.tmpl +1 -0
- data/templates-Pro/include/4.tmpl +1 -0
- data/templates-Pro/include/a.incl +1 -0
- data/templates-Pro/test_broken.tmpl +25 -0
- data/templates-Pro/test_broken1.out +1 -0
- data/templates-Pro/test_broken1.tmpl +1 -0
- data/templates-Pro/test_esc1.out +4 -0
- data/templates-Pro/test_esc1.tmpl +4 -0
- data/templates-Pro/test_esc2.out +5 -0
- data/templates-Pro/test_esc2.tmpl +6 -0
- data/templates-Pro/test_esc3.out +4 -0
- data/templates-Pro/test_esc3.tmpl +4 -0
- data/templates-Pro/test_esc4.out +3 -0
- data/templates-Pro/test_esc4.tmpl +4 -0
- data/templates-Pro/test_expr1.out +26 -0
- data/templates-Pro/test_expr1.tmpl +26 -0
- data/templates-Pro/test_expr2.out +34 -0
- data/templates-Pro/test_expr2.tmpl +34 -0
- data/templates-Pro/test_expr3.out +6 -0
- data/templates-Pro/test_expr3.tmpl +6 -0
- data/templates-Pro/test_expr4.out +4 -0
- data/templates-Pro/test_expr4.tmpl +4 -0
- data/templates-Pro/test_expr5.out +18 -0
- data/templates-Pro/test_expr5.tmpl +18 -0
- data/templates-Pro/test_expr6.out +18 -0
- data/templates-Pro/test_expr6.tmpl +18 -0
- data/templates-Pro/test_expr7.out +44 -0
- data/templates-Pro/test_expr7.tmpl +20 -0
- data/templates-Pro/test_expr8.out +15 -0
- data/templates-Pro/test_expr8.tmpl +15 -0
- data/templates-Pro/test_if1.out +25 -0
- data/templates-Pro/test_if1.tmpl +28 -0
- data/templates-Pro/test_if2.out +17 -0
- data/templates-Pro/test_if2.tmpl +25 -0
- data/templates-Pro/test_if3.out +12 -0
- data/templates-Pro/test_if3.tmpl +14 -0
- data/templates-Pro/test_if4.out +15 -0
- data/templates-Pro/test_if4.tmpl +31 -0
- data/templates-Pro/test_if5.out +16 -0
- data/templates-Pro/test_if5.tmpl +16 -0
- data/templates-Pro/test_if6.out +15 -0
- data/templates-Pro/test_if6.tmpl +31 -0
- data/templates-Pro/test_if7.out +14 -0
- data/templates-Pro/test_if7.tmpl +18 -0
- data/templates-Pro/test_include1.out +23 -0
- data/templates-Pro/test_include1.tmpl +7 -0
- data/templates-Pro/test_include2.out +120 -0
- data/templates-Pro/test_include2.tmpl +10 -0
- data/templates-Pro/test_include3.out +8 -0
- data/templates-Pro/test_include3.tmpl +8 -0
- data/templates-Pro/test_include4.out +7 -0
- data/templates-Pro/test_include4.tmpl +6 -0
- data/templates-Pro/test_include5.out +7 -0
- data/templates-Pro/test_include5.tmpl +6 -0
- data/templates-Pro/test_loop1.erb +17 -0
- data/templates-Pro/test_loop1.out +12 -0
- data/templates-Pro/test_loop1.tmpl +16 -0
- data/templates-Pro/test_loop2.erb +19 -0
- data/templates-Pro/test_loop2.out +40 -0
- data/templates-Pro/test_loop2.tmpl +19 -0
- data/templates-Pro/test_loop3.out +38 -0
- data/templates-Pro/test_loop3.tmpl +40 -0
- data/templates-Pro/test_loop4.out +44 -0
- data/templates-Pro/test_loop4.tmpl +20 -0
- data/templates-Pro/test_loop5.out +9 -0
- data/templates-Pro/test_loop5.tmpl +11 -0
- data/templates-Pro/test_loop6.out +33 -0
- data/templates-Pro/test_loop6.tmpl +15 -0
- data/templates-Pro/test_malloc.tmpl +1 -0
- data/templates-Pro/test_userfunc1.out +14 -0
- data/templates-Pro/test_userfunc1.tmpl +14 -0
- data/templates-Pro/test_userfunc2.out +35 -0
- data/templates-Pro/test_userfunc2.tmpl +5 -0
- data/templates-Pro/test_userfunc3.out +5 -0
- data/templates-Pro/test_userfunc3.tmpl +5 -0
- data/templates-Pro/test_userfunc4.out +10 -0
- data/templates-Pro/test_userfunc4.tmpl +10 -0
- data/templates-Pro/test_userfunc5.out +4 -0
- data/templates-Pro/test_userfunc5.tmpl +4 -0
- data/templates-Pro/test_userfunc6.out +4 -0
- data/templates-Pro/test_userfunc6.tmpl +4 -0
- data/templates-Pro/test_var1.erb +23 -0
- data/templates-Pro/test_var1.out +20 -0
- data/templates-Pro/test_var1.tmpl +23 -0
- data/templates-Pro/test_var2.erb +7 -0
- data/templates-Pro/test_var2.out +6 -0
- data/templates-Pro/test_var2.tmpl +7 -0
- data/templates-Pro/test_var3.out +14 -0
- data/templates-Pro/test_var3.tmpl +16 -0
- data/templates/case_loop.tmpl +3 -0
- data/templates/context.tmpl +3 -0
- data/templates/counter.tmpl +2 -0
- data/templates/default.tmpl +1 -0
- data/templates/default_escape.tmpl +4 -0
- data/templates/double_loop.tmpl +7 -0
- data/templates/escape.tmpl +5 -0
- data/templates/global-loops.tmpl +9 -0
- data/templates/globals.tmpl +11 -0
- data/templates/if.tmpl +7 -0
- data/templates/ifelse.tmpl +6 -0
- data/templates/include.tmpl +14 -0
- data/templates/include_path/a.tmpl +2 -0
- data/templates/include_path/b.tmpl +1 -0
- data/templates/include_path/inner.tmpl +1 -0
- data/templates/include_path/one.tmpl +2 -0
- data/templates/include_path2/inner.tmpl +1 -0
- data/templates/included.tmpl +4 -0
- data/templates/included2.tmpl +3 -0
- data/templates/js.tmpl +1 -0
- data/templates/long_loops.tmpl +307 -0
- data/templates/loop-context.tmpl +2 -0
- data/templates/loop-if.tmpl +9 -0
- data/templates/medium.tmpl +217 -0
- data/templates/multiline_tags.tmpl +7 -0
- data/templates/newline_test1.tmpl +1 -0
- data/templates/newline_test2.tmpl +1 -0
- data/templates/other-loop.tmpl +7 -0
- data/templates/outer.tmpl +3 -0
- data/templates/query-test.tmpl +21 -0
- data/templates/query-test2.tmpl +12 -0
- data/templates/recursive.tmpl +2 -0
- data/templates/searchpath/included.tmpl +4 -0
- data/templates/searchpath/three.tmpl +1 -0
- data/templates/searchpath/two.tmpl +2 -0
- data/templates/simple-loop-nonames.tmpl +13 -0
- data/templates/simple-loop.tmpl +12 -0
- data/templates/simple.tmpl +9 -0
- data/templates/unless.tmpl +5 -0
- data/templates/urlescape.tmpl +3 -0
- data/templates/vanguard1.tmpl +2 -0
- data/templates/vanguard2.tmpl +3 -0
- data/test/templates/complex.tmpl +24 -0
- data/test/templates/foo.tmpl +6 -0
- data/test/templates/func.tmpl +2 -0
- data/test/templates/loop.tmpl +14 -0
- data/test/templates/negative.tmpl +1 -0
- data/test/templates/numerics.tmpl +6 -0
- data/test/templates/register.tmpl +2 -0
- data/test/test_basic.rb +23 -0
- data/test/test_coderefs.rb +16 -0
- data/test/test_complex.rb +106 -0
- data/test/test_helper.rb +3 -0
- data/test/test_html_template.rb +583 -0
- data/test/test_html_template_internal_extn.rb +10 -0
- data/test/test_html_template_pro.rb +177 -0
- data/test/test_path_like_variable_scope.rb +59 -0
- data/test/test_random.rb +21 -0
- data/test/test_realloc.rb +16 -0
- data/test/test_register.rb +25 -0
- data/test/test_tmplpro.rb +9 -0
- data/test/tests.rb +9 -0
- data/website/index.txt +57 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +159 -0
- data/website/template.html.erb +50 -0
- 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(¶m->builtin_findfile_buffer)) {
|
|
255
|
+
pbuffer_init_as(¶m->builtin_findfile_buffer, 3*buffsize);
|
|
256
|
+
} else {
|
|
257
|
+
pbuffer_resize(¶m->builtin_findfile_buffer, buffsize);
|
|
258
|
+
}
|
|
259
|
+
pbuf_begin.begin=pbuffer_string(¶m->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
|
+
}
|