html-template-pro 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,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
|
+
}
|