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