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,62 @@
|
|
1
|
+
/*! \file exprtype.h
|
2
|
+
\brief description of EXPR variable type.
|
3
|
+
|
4
|
+
EXPR variable type is passed to and from user-supplied functions.
|
5
|
+
|
6
|
+
\author Igor Vlasenko <vlasenko@imath.kiev.ua>
|
7
|
+
\warning This header file should never be included directly.
|
8
|
+
Include <tmplpro.h> instead.
|
9
|
+
*/
|
10
|
+
|
11
|
+
#ifndef _EXPRTYPE_H
|
12
|
+
#define _EXPRTYPE_H 1
|
13
|
+
|
14
|
+
#ifdef HAVE_CONFIG_H
|
15
|
+
#include "config.h"
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#if HAVE_INTTYPES_H
|
19
|
+
# include <inttypes.h>
|
20
|
+
#else
|
21
|
+
# if HAVE_STDINT_H
|
22
|
+
# include <stdint.h>
|
23
|
+
# endif
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#define EXPR_TYPE_INT 'i'
|
27
|
+
#define EXPR_TYPE_DBL 'd'
|
28
|
+
#define EXPR_TYPE_PSTR 'p'
|
29
|
+
/* NULL is for interface only, internally NULL pstring is used. */
|
30
|
+
#define EXPR_TYPE_NULL '\0'
|
31
|
+
/* UPSTR is for internal use only. it is never passed to user functions. */
|
32
|
+
#define EXPR_TYPE_UPSTR 'u'
|
33
|
+
|
34
|
+
#if defined INT64_MAX || defined int64_t
|
35
|
+
typedef int64_t EXPR_int64;
|
36
|
+
#elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8
|
37
|
+
typedef long long int EXPR_int64;
|
38
|
+
#elif defined INT64_NAME
|
39
|
+
typedef INT64_NAME EXPR_int64;
|
40
|
+
#else
|
41
|
+
typedef long int EXPR_int64;
|
42
|
+
#endif
|
43
|
+
|
44
|
+
#if defined PRId64
|
45
|
+
# define EXPR_PRId64 PRId64
|
46
|
+
#elif defined SIZEOF_LONG_LONG && SIZEOF_LONG_LONG == 8
|
47
|
+
# define EXPR_PRId64 "lld"
|
48
|
+
#elif defined _MSC_VER
|
49
|
+
# define EXPR_PRId64 "I64d"
|
50
|
+
#else
|
51
|
+
# define EXPR_PRId64 "ld"
|
52
|
+
#endif
|
53
|
+
|
54
|
+
struct exprval;
|
55
|
+
|
56
|
+
#endif /* exprtype.h */
|
57
|
+
|
58
|
+
/*
|
59
|
+
* Local Variables:
|
60
|
+
* mode: c
|
61
|
+
* End:
|
62
|
+
*/
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/* -*- c -*-
|
2
|
+
* File: exprval.h
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
4
|
+
* Created: Mon Jul 20 21:10:57 2009
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef _EXPRVAL_H
|
8
|
+
#define _EXPRVAL_H 1
|
9
|
+
|
10
|
+
#include "exprtype.h"
|
11
|
+
|
12
|
+
typedef char EXPR_char;
|
13
|
+
struct exprval {
|
14
|
+
EXPR_char type;
|
15
|
+
union uval {
|
16
|
+
EXPR_int64 intval; /* integer */
|
17
|
+
double dblval; /* double */
|
18
|
+
PSTRING strval;
|
19
|
+
} val;
|
20
|
+
};
|
21
|
+
|
22
|
+
#define NEW_EXPRVAL(X) { X }
|
23
|
+
|
24
|
+
#endif /* exprval.h */
|
25
|
+
|
26
|
+
/*
|
27
|
+
* Local Variables:
|
28
|
+
* mode: c
|
29
|
+
* End:
|
30
|
+
*/
|
@@ -0,0 +1,449 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "tmplpro.h"
|
3
|
+
|
4
|
+
static int debuglevel = 0;
|
5
|
+
|
6
|
+
struct internal_state {
|
7
|
+
char **pathlist;
|
8
|
+
};
|
9
|
+
|
10
|
+
static struct internal_state *new_internal_state() {
|
11
|
+
struct internal_state *state = (struct internal_state*)malloc(sizeof(struct internal_state));
|
12
|
+
state->pathlist = NULL;
|
13
|
+
return state;
|
14
|
+
}
|
15
|
+
|
16
|
+
static void free_internal_state(struct internal_state *state) {
|
17
|
+
free(state->pathlist);
|
18
|
+
free(state);
|
19
|
+
}
|
20
|
+
|
21
|
+
static void write_chars_to_file (ABSTRACT_WRITER* OutputFile, const char* begin, const char* endnext) {
|
22
|
+
rb_io_write((VALUE)OutputFile, rb_str_new(begin, endnext - begin));
|
23
|
+
}
|
24
|
+
|
25
|
+
static void write_chars_to_string (ABSTRACT_WRITER* OutputString, const char* begin, const char* endnext) {
|
26
|
+
rb_str_cat((VALUE)OutputString, begin, endnext - begin);
|
27
|
+
}
|
28
|
+
|
29
|
+
static ABSTRACT_VALUE* get_ABSTRACT_VALUE_impl (ABSTRACT_DATASTATE *none, ABSTRACT_MAP* hashPtr, PSTRING name) {
|
30
|
+
VALUE key = ID2SYM(rb_intern2(name.begin, name.endnext - name.begin));
|
31
|
+
VALUE val = rb_hash_aref((VALUE)hashPtr, key);
|
32
|
+
if (NIL_P(val)) {
|
33
|
+
key = rb_str_new(name.begin, name.endnext - name.begin);
|
34
|
+
val = rb_hash_aref((VALUE)hashPtr, key);
|
35
|
+
}
|
36
|
+
return NIL_P(val) ? NULL : (ABSTRACT_VALUE*)val;
|
37
|
+
}
|
38
|
+
|
39
|
+
static
|
40
|
+
PSTRING ABSTRACT_VALUE2PSTRING_impl (ABSTRACT_DATASTATE *none, ABSTRACT_VALUE* valptr) {
|
41
|
+
VALUE val = (VALUE)valptr;
|
42
|
+
PSTRING retval = {NULL,NULL};
|
43
|
+
|
44
|
+
if (valptr == NULL) return retval;
|
45
|
+
|
46
|
+
if (rb_obj_is_kind_of(val, rb_cProc)) {
|
47
|
+
val = rb_proc_call(val, rb_ary_new());
|
48
|
+
}
|
49
|
+
|
50
|
+
if (TYPE(val) != T_STRING) {
|
51
|
+
ID to_s = rb_intern("to_s");
|
52
|
+
val = rb_funcall(val, to_s, 0);
|
53
|
+
}
|
54
|
+
retval.begin = RSTRING_PTR(val);
|
55
|
+
retval.endnext = retval.begin + RSTRING_LEN(val);
|
56
|
+
return retval;
|
57
|
+
}
|
58
|
+
|
59
|
+
static
|
60
|
+
int is_ABSTRACT_VALUE_true_impl (ABSTRACT_DATASTATE *none, ABSTRACT_VALUE* valptr) {
|
61
|
+
VALUE val = (VALUE)valptr;
|
62
|
+
|
63
|
+
if (NIL_P(val)) return 0;
|
64
|
+
|
65
|
+
if (rb_obj_is_kind_of(val, rb_cProc)) {
|
66
|
+
val = rb_proc_call(val, rb_ary_new());
|
67
|
+
}
|
68
|
+
|
69
|
+
if (NIL_P(val) || TYPE(val) == T_FALSE) return 0;
|
70
|
+
|
71
|
+
return 1;
|
72
|
+
}
|
73
|
+
|
74
|
+
static
|
75
|
+
ABSTRACT_ARRAY* ABSTRACT_VALUE2ABSTRACT_ARRAY_impl (ABSTRACT_DATASTATE *none, ABSTRACT_VALUE* abstrvalptr) {
|
76
|
+
if (TYPE(abstrvalptr) != T_ARRAY) return 0;
|
77
|
+
return (ABSTRACT_ARRAY*)abstrvalptr;
|
78
|
+
}
|
79
|
+
|
80
|
+
static
|
81
|
+
int get_ABSTRACT_ARRAY_length_impl (ABSTRACT_DATASTATE *none, ABSTRACT_ARRAY* loops) {
|
82
|
+
if (TYPE(loops) != T_ARRAY) return 0;
|
83
|
+
return RARRAY_LEN((VALUE)loops);
|
84
|
+
}
|
85
|
+
|
86
|
+
static
|
87
|
+
ABSTRACT_MAP* get_ABSTRACT_MAP_impl (ABSTRACT_DATASTATE *none, ABSTRACT_ARRAY* loops_ary, int loop) {
|
88
|
+
return (ABSTRACT_MAP *)rb_ary_entry((VALUE)loops_ary, loop);
|
89
|
+
}
|
90
|
+
|
91
|
+
typedef void (*set_int_option_functype) (struct tmplpro_param*, int);
|
92
|
+
|
93
|
+
static
|
94
|
+
void set_integer_from_hash(VALUE option_hash, char* key, struct tmplpro_param* param, set_int_option_functype setfunc) {
|
95
|
+
VALUE option_key = ID2SYM(rb_intern(key));
|
96
|
+
VALUE option_val = rb_hash_aref(option_hash, option_key);
|
97
|
+
if (NIL_P(option_val)) return;
|
98
|
+
setfunc(param, NUM2INT(option_val));
|
99
|
+
}
|
100
|
+
|
101
|
+
static
|
102
|
+
void set_boolean_from_hash(VALUE option_hash, char* key, struct tmplpro_param* param, set_int_option_functype setfunc) {
|
103
|
+
VALUE option_key = ID2SYM(rb_intern(key));
|
104
|
+
VALUE option_val = rb_hash_aref(option_hash, option_key);
|
105
|
+
int val = NIL_P(option_val) || TYPE(option_val) == T_FALSE ? 0 : 1;
|
106
|
+
setfunc(param, val);
|
107
|
+
}
|
108
|
+
|
109
|
+
static
|
110
|
+
PSTRING get_string_from_value(VALUE self, char* key) {
|
111
|
+
ID key_id = rb_intern(key);
|
112
|
+
VALUE strval = rb_ivar_get(self, key_id);
|
113
|
+
PSTRING retval={NULL,NULL};
|
114
|
+
if (NIL_P(strval)) return retval;
|
115
|
+
retval.begin = StringValuePtr(strval);
|
116
|
+
retval.endnext = retval.begin + RSTRING_LEN(strval);
|
117
|
+
return retval;
|
118
|
+
}
|
119
|
+
|
120
|
+
static
|
121
|
+
PSTRING get_string_from_hash(VALUE hash, char* key_string) {
|
122
|
+
VALUE key = ID2SYM(rb_intern(key_string));
|
123
|
+
VALUE val = rb_hash_aref(hash, key);
|
124
|
+
PSTRING retval={NULL,NULL};
|
125
|
+
if (NIL_P(val)) return retval;
|
126
|
+
retval.begin = StringValuePtr(val);
|
127
|
+
retval.endnext = retval.begin + RSTRING_LEN(val);
|
128
|
+
return retval;
|
129
|
+
}
|
130
|
+
|
131
|
+
static
|
132
|
+
int get_boolean_from_hash(VALUE options, char* keystr) {
|
133
|
+
VALUE key = ID2SYM(rb_intern(keystr));
|
134
|
+
VALUE val = rb_hash_aref(options, key);
|
135
|
+
return NIL_P(val) || TYPE(val) == T_FALSE ? 0 : 1;
|
136
|
+
}
|
137
|
+
|
138
|
+
static
|
139
|
+
PSTRING load_file (ABSTRACT_FILTER* callback_state, const char* filepath) {
|
140
|
+
PSTRING tmpl;
|
141
|
+
VALUE self = (VALUE)callback_state;
|
142
|
+
VALUE path = rb_str_new_cstr(filepath);
|
143
|
+
VALUE result = rb_funcall(self, rb_intern("load_template"), 1, path);
|
144
|
+
if (!NIL_P(result) && TYPE(result) == T_STRING) {
|
145
|
+
tmpl.begin = StringValuePtr(result);
|
146
|
+
tmpl.endnext = tmpl.begin + RSTRING_LEN(result);
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
rb_raise(rb_eRuntimeError, "Big trouble! load_template internal fatal error\n") ;
|
150
|
+
}
|
151
|
+
return tmpl;
|
152
|
+
}
|
153
|
+
|
154
|
+
static
|
155
|
+
int unload_file(ABSTRACT_FILTER* callback_state, PSTRING memarea) {
|
156
|
+
return 0;
|
157
|
+
}
|
158
|
+
|
159
|
+
static
|
160
|
+
ABSTRACT_USERFUNC* is_expr_userfnc (ABSTRACT_FUNCMAP* FuncHash, PSTRING name) {
|
161
|
+
VALUE key = ID2SYM(rb_intern2(name.begin, name.endnext - name.begin));
|
162
|
+
VALUE val = rb_hash_aref((VALUE)FuncHash, key);
|
163
|
+
if (NIL_P(val)) return NULL;
|
164
|
+
return (ABSTRACT_USERFUNC *)val;
|
165
|
+
}
|
166
|
+
|
167
|
+
static
|
168
|
+
void free_expr_arglist(ABSTRACT_ARGLIST* arglist) {
|
169
|
+
VALUE args = (VALUE)arglist;
|
170
|
+
VALUE registory = rb_ary_shift(args);
|
171
|
+
rb_hash_delete(registory, rb_obj_id(args));
|
172
|
+
return;
|
173
|
+
}
|
174
|
+
|
175
|
+
static
|
176
|
+
ABSTRACT_ARGLIST* init_expr_arglist(ABSTRACT_CALLER* callback_state)
|
177
|
+
{
|
178
|
+
VALUE self = (VALUE)callback_state;
|
179
|
+
VALUE registory = rb_ivar_get(self, rb_intern("@internal_expr_args"));
|
180
|
+
VALUE args = rb_ary_new();
|
181
|
+
rb_ary_push(args, registory);
|
182
|
+
rb_hash_aset(registory, rb_obj_id(args), args);
|
183
|
+
return (ABSTRACT_ARGLIST*)args;
|
184
|
+
}
|
185
|
+
|
186
|
+
static
|
187
|
+
void push_expr_arglist(ABSTRACT_ARGLIST* arglist, ABSTRACT_EXPRVAL* exprval)
|
188
|
+
{
|
189
|
+
VALUE val = Qnil;
|
190
|
+
int exprval_type = tmplpro_get_expr_type(exprval);
|
191
|
+
PSTRING parg;
|
192
|
+
switch (exprval_type) {
|
193
|
+
case EXPR_TYPE_NULL: val = Qnil; break;
|
194
|
+
case EXPR_TYPE_INT: val = INT2NUM(tmplpro_get_expr_as_int64(exprval)); break;
|
195
|
+
case EXPR_TYPE_DBL: val = rb_float_new(tmplpro_get_expr_as_double(exprval)); break;
|
196
|
+
case EXPR_TYPE_PSTR:
|
197
|
+
parg = tmplpro_get_expr_as_pstring(exprval);
|
198
|
+
val = rb_str_new(parg.begin, parg.endnext - parg.begin);
|
199
|
+
break;
|
200
|
+
default:
|
201
|
+
rb_raise(rb_eRuntimeError, "Ruby wrapper: FATAL INTERNAL ERROR:Unsupported type %d in exprval", exprval_type);
|
202
|
+
}
|
203
|
+
rb_ary_push((VALUE)arglist, val);
|
204
|
+
}
|
205
|
+
|
206
|
+
static
|
207
|
+
void call_expr_userfnc (ABSTRACT_CALLER* callback_state, ABSTRACT_ARGLIST* arglist, ABSTRACT_USERFUNC* hashvalptr, ABSTRACT_EXPRVAL* exprval) {
|
208
|
+
char* empty = "";
|
209
|
+
VALUE self = (VALUE)callback_state;
|
210
|
+
VALUE func = (VALUE)hashvalptr;
|
211
|
+
VALUE args = (VALUE)arglist;
|
212
|
+
PSTRING retvalpstr = { empty, empty };
|
213
|
+
|
214
|
+
if (hashvalptr==NULL) {
|
215
|
+
rb_raise(rb_eRuntimeError, "FATAL INTERNAL ERROR:Call_EXPR:function called but not exists");
|
216
|
+
tmplpro_set_expr_as_pstring(exprval, retvalpstr);
|
217
|
+
return;
|
218
|
+
} else if (NIL_P(func) || !rb_obj_is_kind_of(func, rb_cProc)) {
|
219
|
+
rb_raise(rb_eRuntimeError, "FATAL INTERNAL ERROR:Call_EXPR:not a Proc object");
|
220
|
+
tmplpro_set_expr_as_pstring(exprval, retvalpstr);
|
221
|
+
return;
|
222
|
+
}
|
223
|
+
|
224
|
+
/* head of args is not a true aruguments(it is a regisotry of args). */
|
225
|
+
VALUE tmp = rb_ary_shift(args);
|
226
|
+
VALUE retval = rb_proc_call(func, args);
|
227
|
+
rb_ary_unshift(args, tmp);
|
228
|
+
|
229
|
+
VALUE registory = Qnil;
|
230
|
+
|
231
|
+
switch (TYPE(retval)) {
|
232
|
+
case T_FIXNUM:
|
233
|
+
tmplpro_set_expr_as_int64(exprval, FIX2LONG(retval));
|
234
|
+
break;
|
235
|
+
case T_TRUE:
|
236
|
+
tmplpro_set_expr_as_int64(exprval, 1);
|
237
|
+
break;
|
238
|
+
case T_FALSE:
|
239
|
+
tmplpro_set_expr_as_int64(exprval, 0);
|
240
|
+
break;
|
241
|
+
case T_FLOAT:
|
242
|
+
tmplpro_set_expr_as_double(exprval, NUM2DBL(retval));
|
243
|
+
break;
|
244
|
+
case T_NIL:
|
245
|
+
tmplpro_set_expr_as_null(exprval);
|
246
|
+
break;
|
247
|
+
default:
|
248
|
+
registory = rb_ivar_get(self, rb_intern("@internal_expr_results"));
|
249
|
+
rb_ary_push(registory, retval);
|
250
|
+
retvalpstr.begin = StringValuePtr(retval);
|
251
|
+
retvalpstr.endnext = retvalpstr.begin + RSTRING_LEN(retval);
|
252
|
+
tmplpro_set_expr_as_pstring(exprval, retvalpstr);
|
253
|
+
}
|
254
|
+
|
255
|
+
return;
|
256
|
+
}
|
257
|
+
|
258
|
+
static
|
259
|
+
char** set_pathlist(VALUE self, VALUE options, char* param_name) {
|
260
|
+
long i, len;
|
261
|
+
struct internal_state *state;
|
262
|
+
VALUE key = ID2SYM(rb_intern(param_name));
|
263
|
+
VALUE paths = rb_hash_aref(options, key);
|
264
|
+
VALUE callback_state = rb_ivar_get(self, rb_intern("@internal_state"));
|
265
|
+
if (NIL_P(paths) || NIL_P(callback_state)) return NULL;
|
266
|
+
Data_Get_Struct(callback_state, struct internal_state, state);
|
267
|
+
if (TYPE(paths) != T_ARRAY) rb_raise(rb_eRuntimeError, "path param is not array");
|
268
|
+
len = RARRAY_LEN(paths);
|
269
|
+
if (len < 0) return NULL;
|
270
|
+
state->pathlist = (char **)malloc(sizeof(char*) * (len + 1));
|
271
|
+
for (i=0;i<len;i++) {
|
272
|
+
VALUE elem = rb_ary_entry(paths, i);
|
273
|
+
state->pathlist[i] = StringValueCStr(elem);
|
274
|
+
}
|
275
|
+
state->pathlist[len] = NULL;
|
276
|
+
return state->pathlist;
|
277
|
+
}
|
278
|
+
|
279
|
+
static struct tmplpro_param*
|
280
|
+
process_tmplpro_options(VALUE self)
|
281
|
+
{
|
282
|
+
struct tmplpro_param* param = tmplpro_param_init();
|
283
|
+
const char* tmpstring;
|
284
|
+
int default_escape=HTML_TEMPLATE_OPT_ESCAPE_NO;
|
285
|
+
|
286
|
+
tmplpro_set_option_WriterFuncPtr(param, &write_chars_to_string);
|
287
|
+
tmplpro_set_option_GetAbstractValFuncPtr(param, &get_ABSTRACT_VALUE_impl);
|
288
|
+
tmplpro_set_option_AbstractVal2pstringFuncPtr(param, &ABSTRACT_VALUE2PSTRING_impl);
|
289
|
+
tmplpro_set_option_AbstractVal2abstractArrayFuncPtr(param, &ABSTRACT_VALUE2ABSTRACT_ARRAY_impl);
|
290
|
+
tmplpro_set_option_GetAbstractArrayLengthFuncPtr(param, &get_ABSTRACT_ARRAY_length_impl);
|
291
|
+
tmplpro_set_option_IsAbstractValTrueFuncPtr(param, &is_ABSTRACT_VALUE_true_impl);
|
292
|
+
tmplpro_set_option_GetAbstractMapFuncPtr(param, &get_ABSTRACT_MAP_impl);
|
293
|
+
tmplpro_set_option_LoadFileFuncPtr(param, &load_file);
|
294
|
+
tmplpro_set_option_UnloadFileFuncPtr(param, &unload_file);
|
295
|
+
|
296
|
+
/* setting initial Expr hooks */
|
297
|
+
tmplpro_set_option_InitExprArglistFuncPtr(param, &init_expr_arglist);
|
298
|
+
tmplpro_set_option_FreeExprArglistFuncPtr(param, &free_expr_arglist);
|
299
|
+
tmplpro_set_option_PushExprArglistFuncPtr(param, &push_expr_arglist);
|
300
|
+
tmplpro_set_option_CallExprUserfncFuncPtr(param, &call_expr_userfnc);
|
301
|
+
tmplpro_set_option_IsExprUserfncFuncPtr(param, &is_expr_userfnc);
|
302
|
+
/* end setting initial hooks */
|
303
|
+
|
304
|
+
/* setting ruby globals */
|
305
|
+
tmplpro_set_option_ext_findfile_state(param, (ABSTRACT_FINDFILE *)self);
|
306
|
+
tmplpro_set_option_ext_filter_state(param, (ABSTRACT_FILTER *)self);
|
307
|
+
tmplpro_set_option_ext_calluserfunc_state(param, (ABSTRACT_CALLER *)self);
|
308
|
+
tmplpro_set_option_ext_data_state(param, (ABSTRACT_DATASTATE *)self);
|
309
|
+
/* end setting ruby globals */
|
310
|
+
|
311
|
+
if ((void*)self == NULL) {
|
312
|
+
rb_raise(rb_eRuntimeError, "FATAL:SELF:self was expected but not found");
|
313
|
+
}
|
314
|
+
Check_Type(self, T_OBJECT);
|
315
|
+
|
316
|
+
/* checking main arguments */
|
317
|
+
PSTRING filename = get_string_from_value(self, "@filename");
|
318
|
+
PSTRING scalarref = get_string_from_value(self, "@scalarref");
|
319
|
+
tmplpro_set_option_filename(param, filename.begin);
|
320
|
+
tmplpro_set_option_scalarref(param, scalarref);
|
321
|
+
if (filename.begin==NULL && scalarref.begin==NULL) {
|
322
|
+
rb_raise(rb_eRuntimeError, "bad arguments: expected filename or scalarref");
|
323
|
+
}
|
324
|
+
|
325
|
+
VALUE options = rb_ivar_get(self, rb_intern("@options"));
|
326
|
+
Check_Type(options, T_HASH);
|
327
|
+
|
328
|
+
/* setting expr_func */
|
329
|
+
VALUE expr_key = ID2SYM(rb_intern("expr_func"));
|
330
|
+
VALUE expr = rb_hash_aref(options, expr_key);
|
331
|
+
if (!expr || NIL_P(expr) || TYPE(expr) != T_HASH) {
|
332
|
+
rb_raise(rb_eRuntimeError, "FATAL:output:EXPR user functions not found");
|
333
|
+
}
|
334
|
+
tmplpro_set_option_expr_func_map(param, (ABSTRACT_FUNCMAP *)expr);
|
335
|
+
/* end setting expr_func */
|
336
|
+
|
337
|
+
/* setting param_map */
|
338
|
+
tmplpro_clear_option_param_map(param);
|
339
|
+
VALUE map = rb_ivar_get(self, rb_intern("@params"));
|
340
|
+
Check_Type(map, T_HASH);
|
341
|
+
tmplpro_push_option_param_map(param, (ABSTRACT_MAP*)map, 0);
|
342
|
+
/* end setting param_map */
|
343
|
+
|
344
|
+
/* setting filter */
|
345
|
+
VALUE filter_key = ID2SYM(rb_intern("filter"));
|
346
|
+
VALUE filter = rb_hash_aref(options, filter_key);
|
347
|
+
Check_Type(filter, T_ARRAY);
|
348
|
+
if (RARRAY_LEN(filter) >= 0) tmplpro_set_option_filters(param, 1);
|
349
|
+
/* end setting filter */
|
350
|
+
|
351
|
+
if (!get_boolean_from_hash(options, "case_sensitive")) {
|
352
|
+
tmplpro_set_option_tmpl_var_case(param, ASK_NAME_LOWERCASE);
|
353
|
+
}
|
354
|
+
|
355
|
+
set_integer_from_hash(options,"tmpl_var_case",param,tmplpro_set_option_tmpl_var_case);
|
356
|
+
set_integer_from_hash(options,"max_includes",param,tmplpro_set_option_max_includes);
|
357
|
+
set_boolean_from_hash(options,"no_includes",param,tmplpro_set_option_no_includes);
|
358
|
+
set_boolean_from_hash(options,"search_path_on_include",param,tmplpro_set_option_search_path_on_include);
|
359
|
+
set_boolean_from_hash(options,"global_vars",param,tmplpro_set_option_global_vars);
|
360
|
+
set_integer_from_hash(options,"debug",param,tmplpro_set_option_debug);
|
361
|
+
debuglevel = tmplpro_get_option_debug(param);
|
362
|
+
set_boolean_from_hash(options,"loop_context_vars",param,tmplpro_set_option_loop_context_vars);
|
363
|
+
set_boolean_from_hash(options,"path_like_variable_scope",param,tmplpro_set_option_path_like_variable_scope);
|
364
|
+
/* still unsupported */
|
365
|
+
set_boolean_from_hash(options,"strict",param,tmplpro_set_option_strict);
|
366
|
+
|
367
|
+
tmpstring = get_string_from_hash(options, "default_escape").begin;
|
368
|
+
if (tmpstring && *tmpstring) {
|
369
|
+
switch (*tmpstring) {
|
370
|
+
case '1': case 'H': case 'h': /* HTML*/
|
371
|
+
default_escape = HTML_TEMPLATE_OPT_ESCAPE_HTML;
|
372
|
+
break;
|
373
|
+
case 'U': case 'u': /* URL */
|
374
|
+
default_escape = HTML_TEMPLATE_OPT_ESCAPE_URL;
|
375
|
+
break;
|
376
|
+
case 'J': case 'j': /* JS */
|
377
|
+
default_escape = HTML_TEMPLATE_OPT_ESCAPE_JS;
|
378
|
+
break;
|
379
|
+
case '0': case 'N': case 'n': /* 0 or NONE */
|
380
|
+
default_escape = HTML_TEMPLATE_OPT_ESCAPE_NO;
|
381
|
+
break;
|
382
|
+
default:
|
383
|
+
rb_warn("unsupported value of default_escape=%s. Valid values are HTML, URL or JS.\n",tmpstring);
|
384
|
+
}
|
385
|
+
tmplpro_set_option_default_escape(param, default_escape);
|
386
|
+
}
|
387
|
+
|
388
|
+
/* set path */
|
389
|
+
tmplpro_set_option_path(param, set_pathlist(self, options, "path"));
|
390
|
+
tmplpro_set_option_FindFileFuncPtr(param, NULL);
|
391
|
+
|
392
|
+
return param;
|
393
|
+
}
|
394
|
+
|
395
|
+
static void
|
396
|
+
release_tmplpro_options(struct tmplpro_param* param)
|
397
|
+
{
|
398
|
+
tmplpro_param_free(param);
|
399
|
+
}
|
400
|
+
|
401
|
+
VALUE mHtml;
|
402
|
+
VALUE mHtmlTemplate;
|
403
|
+
VALUE mHtmlTemplateInternal;
|
404
|
+
VALUE cHtmlTemplateInternalState;
|
405
|
+
|
406
|
+
static void setup_internal(VALUE self)
|
407
|
+
{
|
408
|
+
struct internal_state *state = new_internal_state();
|
409
|
+
VALUE internal_state = Data_Wrap_Struct(cHtmlTemplateInternalState, 0,
|
410
|
+
&free_internal_state, state);
|
411
|
+
rb_ivar_set(self, rb_intern("@internal_state"), internal_state);
|
412
|
+
rb_ivar_set(self, rb_intern("@internal_expr_args"), rb_hash_new());
|
413
|
+
rb_ivar_set(self, rb_intern("@internal_expr_results"), rb_ary_new());
|
414
|
+
}
|
415
|
+
|
416
|
+
static VALUE exec_tmpl(VALUE self, VALUE output)
|
417
|
+
{
|
418
|
+
writer_functype writer;
|
419
|
+
struct tmplpro_param* proparam;
|
420
|
+
setup_internal(self);
|
421
|
+
proparam = process_tmplpro_options(self);
|
422
|
+
|
423
|
+
switch (TYPE(output)) {
|
424
|
+
case T_STRING:
|
425
|
+
writer = &write_chars_to_string;
|
426
|
+
break;
|
427
|
+
case T_FILE:
|
428
|
+
writer = &write_chars_to_file;
|
429
|
+
break;
|
430
|
+
default:
|
431
|
+
rb_warning("bad file descriptor. Use output=stdout\n");
|
432
|
+
writer = &write_chars_to_file;
|
433
|
+
output = rb_stdout;
|
434
|
+
}
|
435
|
+
tmplpro_set_option_WriterFuncPtr(proparam, writer);
|
436
|
+
tmplpro_set_option_ext_writer_state(proparam, (ABSTRACT_WRITER *)output);
|
437
|
+
int retval = tmplpro_exec_tmpl(proparam);
|
438
|
+
release_tmplpro_options(proparam);
|
439
|
+
return INT2FIX(retval);
|
440
|
+
}
|
441
|
+
|
442
|
+
void Init_internal(void)
|
443
|
+
{
|
444
|
+
mHtml = rb_define_module("HTML");
|
445
|
+
mHtmlTemplate = rb_define_module_under(mHtml, "Template");
|
446
|
+
mHtmlTemplateInternal = rb_define_module_under(mHtmlTemplate, "Internal");
|
447
|
+
rb_define_module_function(mHtmlTemplateInternal, "exec_tmpl", &exec_tmpl, 1);
|
448
|
+
cHtmlTemplateInternalState = rb_define_class_under(mHtmlTemplateInternal, "State", rb_cObject);
|
449
|
+
}
|