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,30 @@
|
|
|
1
|
+
#ifndef _TAGSTACK_H
|
|
2
|
+
#define _TAGSTACK_H 1
|
|
3
|
+
|
|
4
|
+
struct tagstack_entry {
|
|
5
|
+
int tag; /* code of tag */
|
|
6
|
+
int value; /* if (true/false) - used in else */
|
|
7
|
+
int vcontext; /* visibility context of the tag (visible/unvisible) */
|
|
8
|
+
const char* position; /* start of tag; useful for loops */
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
static
|
|
12
|
+
void tagstack_init(struct tagstack* tagstack);
|
|
13
|
+
static
|
|
14
|
+
void tagstack_free(struct tagstack* tagstack);
|
|
15
|
+
static
|
|
16
|
+
void tagstack_push(struct tagstack* tagstack, struct tagstack_entry);
|
|
17
|
+
static
|
|
18
|
+
struct tagstack_entry tagstack_pop(struct tagstack* tagstack);
|
|
19
|
+
static
|
|
20
|
+
struct tagstack_entry* tagstack_top(struct tagstack* tagstack);
|
|
21
|
+
static
|
|
22
|
+
int tagstack_notempty(struct tagstack* tagstack);
|
|
23
|
+
|
|
24
|
+
#endif /* tagstack.h */
|
|
25
|
+
|
|
26
|
+
/*
|
|
27
|
+
* Local Variables:
|
|
28
|
+
* mode: c
|
|
29
|
+
* End:
|
|
30
|
+
*/
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#include <stdlib.h>
|
|
2
|
+
#include <assert.h>
|
|
3
|
+
|
|
4
|
+
#define INIT_ENV_DEPTH 256
|
|
5
|
+
|
|
6
|
+
static
|
|
7
|
+
void tagstack_init(struct tagstack* tagstack) {
|
|
8
|
+
tagstack->depth=INIT_ENV_DEPTH;
|
|
9
|
+
tagstack->pos=-1;
|
|
10
|
+
tagstack->entry=(struct tagstack_entry*) malloc (tagstack->depth * sizeof(struct tagstack_entry));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
static
|
|
14
|
+
void tagstack_free(struct tagstack* tagstack) {
|
|
15
|
+
tagstack->depth=-1;
|
|
16
|
+
tagstack->pos=-1;
|
|
17
|
+
free(tagstack->entry);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static
|
|
21
|
+
int tagstack_notempty(struct tagstack* tagstack) {
|
|
22
|
+
return tagstack->pos>=0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
static
|
|
27
|
+
void tagstack_entry_debug(struct tagstack_entry item) {
|
|
28
|
+
tmpl_log(TMPL_LOG_DEBUG,"vcontext = %d value=%d\n",item.vcontext,item.value);
|
|
29
|
+
}
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
static
|
|
33
|
+
struct tagstack_entry* tagstack_top(struct tagstack* tagstack) {
|
|
34
|
+
return tagstack->entry+tagstack->pos;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static
|
|
38
|
+
struct tagstack_entry tagstack_pop(struct tagstack* tagstack) {
|
|
39
|
+
if (tagstack->pos<0) {
|
|
40
|
+
tmpl_log(TMPL_LOG_ERROR,"stack underflow:tags stack is empty\n");
|
|
41
|
+
tagstack->pos=0;
|
|
42
|
+
if (tagstack->depth<0) {
|
|
43
|
+
tmpl_log(TMPL_LOG_ERROR,"FATAL:stack error:tags stack is uninitialized\n");
|
|
44
|
+
tagstack_init(tagstack);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return *(tagstack->entry+ tagstack->pos--);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static
|
|
51
|
+
void tagstack_push(struct tagstack* tagstack, struct tagstack_entry item) {
|
|
52
|
+
/* overflow check */
|
|
53
|
+
if (++(tagstack->pos)>=tagstack->depth) {
|
|
54
|
+
if (tagstack->depth<INIT_ENV_DEPTH) tagstack->depth=INIT_ENV_DEPTH;
|
|
55
|
+
tagstack->depth*=2;
|
|
56
|
+
tagstack->entry=(struct tagstack_entry*) realloc (tagstack->entry, tagstack->depth * sizeof(struct tagstack_entry));
|
|
57
|
+
}
|
|
58
|
+
*(tagstack->entry+tagstack->pos)=item;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* Local Variables:
|
|
63
|
+
* mode: c
|
|
64
|
+
* End:
|
|
65
|
+
*/
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: log.c
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Thu Sep 1 17:18:16 2005
|
|
5
|
+
*
|
|
6
|
+
* $Id$
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* based on FFmpeg av_log API */
|
|
10
|
+
|
|
11
|
+
#include <stdio.h>
|
|
12
|
+
#include <string.h>
|
|
13
|
+
#include "tmpllog.h"
|
|
14
|
+
|
|
15
|
+
static int tmpl_log_level = TMPL_LOG_ERROR;
|
|
16
|
+
|
|
17
|
+
static void
|
|
18
|
+
tmpl_log_default_callback(int level, const char* fmt, va_list vl)
|
|
19
|
+
{
|
|
20
|
+
if(level>tmpl_log_level) return;
|
|
21
|
+
vfprintf(stderr, fmt, vl);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static void (*tmpl_log_callback)(int, const char*, va_list) = tmpl_log_default_callback;
|
|
25
|
+
|
|
26
|
+
TMPLPRO_LOCAL
|
|
27
|
+
void
|
|
28
|
+
tmpl_log(int level, const char *fmt, ...)
|
|
29
|
+
{
|
|
30
|
+
va_list vl;
|
|
31
|
+
va_start(vl, fmt);
|
|
32
|
+
tmpl_vlog(level, fmt, vl);
|
|
33
|
+
va_end(vl);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
TMPLPRO_LOCAL
|
|
37
|
+
void
|
|
38
|
+
tmpl_vlog(int level, const char *fmt, va_list vl)
|
|
39
|
+
{
|
|
40
|
+
tmpl_log_callback(level, fmt, vl);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
TMPLPRO_LOCAL
|
|
44
|
+
int
|
|
45
|
+
tmpl_log_get_level(void)
|
|
46
|
+
{
|
|
47
|
+
return tmpl_log_level;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
TMPLPRO_LOCAL
|
|
51
|
+
void
|
|
52
|
+
tmpl_log_set_level(int level)
|
|
53
|
+
{
|
|
54
|
+
tmpl_log_level = level;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
TMPLPRO_LOCAL
|
|
58
|
+
void
|
|
59
|
+
tmpl_log_set_callback(void (*callback)(int, const char*, va_list))
|
|
60
|
+
{
|
|
61
|
+
tmpl_log_callback = callback;
|
|
62
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: log.h
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Thu Sep 1 17:17:37 2005
|
|
5
|
+
*
|
|
6
|
+
* $Id$
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* based on FFmpeg av_log API */
|
|
10
|
+
|
|
11
|
+
#include "pabidecl.h"
|
|
12
|
+
#include "pmiscdef.h"
|
|
13
|
+
#include <stdarg.h>
|
|
14
|
+
|
|
15
|
+
#define TMPL_LOG_QUIET -1
|
|
16
|
+
#define TMPL_LOG_ERROR 0
|
|
17
|
+
#define TMPL_LOG_INFO 1
|
|
18
|
+
#define TMPL_LOG_DEBUG 2
|
|
19
|
+
#define TMPL_LOG_DEBUG2 3
|
|
20
|
+
|
|
21
|
+
extern TMPLPRO_LOCAL void tmpl_log(int level, const char *fmt, ...) FORMAT_PRINTF(2,3);
|
|
22
|
+
|
|
23
|
+
extern TMPLPRO_LOCAL void tmpl_vlog(int level, const char *fmt, va_list);
|
|
24
|
+
extern TMPLPRO_LOCAL int tmpl_log_get_level(void);
|
|
25
|
+
extern TMPLPRO_LOCAL void tmpl_log_set_level(int);
|
|
26
|
+
extern TMPLPRO_LOCAL void tmpl_log_set_callback(void (*)(int, const char*, va_list));
|
|
27
|
+
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/*! \file tmplpro.h
|
|
2
|
+
\brief libhtmltmplpro API header.
|
|
3
|
+
|
|
4
|
+
An official libhtmltmplpro API header.
|
|
5
|
+
|
|
6
|
+
\author Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef _TMPLPRO_H
|
|
10
|
+
#define _TMPLPRO_H 1
|
|
11
|
+
|
|
12
|
+
#include "pabidecl.h"
|
|
13
|
+
#include "pstring.h"
|
|
14
|
+
#include "exprtype.h"
|
|
15
|
+
#include "pabstract.h"
|
|
16
|
+
#include "proparam.h"
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* generic load/first use library and unload/last use library hooks.
|
|
20
|
+
*/
|
|
21
|
+
TMPLPRO_API void APICALL tmplpro_procore_init(void);
|
|
22
|
+
TMPLPRO_API void APICALL tmplpro_procore_done(void);
|
|
23
|
+
|
|
24
|
+
TMPLPRO_API const char* APICALL tmplpro_version(void);
|
|
25
|
+
|
|
26
|
+
struct tmplpro_param;
|
|
27
|
+
/*
|
|
28
|
+
* Constructor and destructor of tmplpro_param.
|
|
29
|
+
* Note that struct tmplpro_param is not part of the interface
|
|
30
|
+
* and is subject to change without notice.
|
|
31
|
+
*/
|
|
32
|
+
TMPLPRO_API struct tmplpro_param* APICALL tmplpro_param_init(void);
|
|
33
|
+
TMPLPRO_API void APICALL tmplpro_param_free(struct tmplpro_param*);
|
|
34
|
+
|
|
35
|
+
TMPLPRO_API int APICALL tmplpro_exec_tmpl (struct tmplpro_param*);
|
|
36
|
+
TMPLPRO_API MPSTRING APICALL tmplpro_tmpl2pstring (struct tmplpro_param *param, int *exitcode);
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
TMPLPRO_API void APICALL tmplpro_clear_option_param_map(struct tmplpro_param *param);
|
|
40
|
+
TMPLPRO_API int APICALL tmplpro_count_option_param_map(struct tmplpro_param *param);
|
|
41
|
+
TMPLPRO_API int APICALL tmplpro_push_option_param_map(struct tmplpro_param *param, ABSTRACT_MAP* map, EXPR_int64 flags);
|
|
42
|
+
|
|
43
|
+
struct exprval;
|
|
44
|
+
TMPLPRO_API void APICALL tmplpro_set_expr_as_int64 (ABSTRACT_EXPRVAL*,EXPR_int64);
|
|
45
|
+
TMPLPRO_API void APICALL tmplpro_set_expr_as_double (ABSTRACT_EXPRVAL*,double);
|
|
46
|
+
TMPLPRO_API void APICALL tmplpro_set_expr_as_string (ABSTRACT_EXPRVAL*, const char*);
|
|
47
|
+
TMPLPRO_API void APICALL tmplpro_set_expr_as_pstring (ABSTRACT_EXPRVAL*,PSTRING);
|
|
48
|
+
TMPLPRO_API void APICALL tmplpro_set_expr_as_null (ABSTRACT_EXPRVAL*);
|
|
49
|
+
|
|
50
|
+
TMPLPRO_API int APICALL tmplpro_get_expr_type (ABSTRACT_EXPRVAL*);
|
|
51
|
+
TMPLPRO_API EXPR_int64 APICALL tmplpro_get_expr_as_int64 (ABSTRACT_EXPRVAL*);
|
|
52
|
+
TMPLPRO_API double APICALL tmplpro_get_expr_as_double (ABSTRACT_EXPRVAL*);
|
|
53
|
+
TMPLPRO_API PSTRING APICALL tmplpro_get_expr_as_pstring (ABSTRACT_EXPRVAL*);
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
#define ASK_NAME_DEFAULT 0
|
|
57
|
+
#define ASK_NAME_AS_IS 1
|
|
58
|
+
#define ASK_NAME_LOWERCASE 2
|
|
59
|
+
#define ASK_NAME_UPPERCASE 4
|
|
60
|
+
#define ASK_NAME_MASK (ASK_NAME_AS_IS|ASK_NAME_LOWERCASE|ASK_NAME_UPPERCASE)
|
|
61
|
+
/* future compatibility: not yet implemented */
|
|
62
|
+
#define ASK_NAME_CAPITALIZED 8
|
|
63
|
+
#define ASK_NAME_LCFIRST 16
|
|
64
|
+
#define ASK_NAME_UCFIRST 32
|
|
65
|
+
/* define ASK_NAME_MASK (ASK_NAME_AS_IS|ASK_NAME_LOWERCASE|ASK_NAME_UPPERCASE|ASK_NAME_CAPITALIZED|ASK_NAME_LCFIRST|ASK_NAME_UCFIRST) */
|
|
66
|
+
|
|
67
|
+
#endif /* tmplpro.h */
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/*! \fn void tmplpro_procore_init(void);
|
|
72
|
+
\brief generic load library/first use initializer.
|
|
73
|
+
|
|
74
|
+
Initializer of global internal structures.
|
|
75
|
+
Should be called before first use of the library.
|
|
76
|
+
|
|
77
|
+
\warning May not be thread safe. Should be called once.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/*! \fn void tmplpro_procore_done(void);
|
|
81
|
+
\brief generic load/first use library and unload/last use library hooks.
|
|
82
|
+
|
|
83
|
+
Deinitializer of global internal structures.
|
|
84
|
+
Should be called before unloading the library.
|
|
85
|
+
|
|
86
|
+
\warning May not be thread safe. Should be called once.
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/*! \fn const char* tmplpro_version(void);
|
|
90
|
+
\brief version of the library
|
|
91
|
+
\return version string.
|
|
92
|
+
*/
|
|
93
|
+
|
|
94
|
+
/*! \fn struct tmplpro_param* tmplpro_param_init(void);
|
|
95
|
+
\brief Constructor of tmplpro_param.
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
/*! \fn void tmplpro_param_free(struct tmplpro_param*);
|
|
99
|
+
\brief Destructor of tmplpro_param.
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
/*! \fn int tmplpro_exec_tmpl (struct tmplpro_param*);
|
|
103
|
+
\brief main method of libhtmltmplpro.
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
/*! \fn MPSTRING tmplpro_tmpl2pstring (struct tmplpro_param*, int* exitcode);
|
|
107
|
+
\brief main method of libhtmltmplpro. Returns processed template as a C string.
|
|
108
|
+
|
|
109
|
+
Note that caller's responsibility is to free the returned memory.
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/*! \fn void tmplpro_set_expr_as_int64 (ABSTRACT_EXPRVAL*,EXPR_int64);
|
|
113
|
+
\brief method to return int64 value from callback of call_expr_userfnc_functype.
|
|
114
|
+
|
|
115
|
+
It should only be used in a callback of call_expr_userfnc_functype.
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/*! \fn void tmplpro_set_expr_as_double (ABSTRACT_EXPRVAL*,double);
|
|
119
|
+
\brief method to return double value from callback of call_expr_userfnc_functype.
|
|
120
|
+
|
|
121
|
+
It should only be used in a callback of call_expr_userfnc_functype.
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
/*! \fn void tmplpro_set_expr_as_string (ABSTRACT_EXPRVAL*,char*);
|
|
125
|
+
\brief method to return C string value from callback of call_expr_userfnc_functype.
|
|
126
|
+
|
|
127
|
+
It should only be used in a callback of call_expr_userfnc_functype.
|
|
128
|
+
*/
|
|
129
|
+
|
|
130
|
+
/*! \fn void tmplpro_set_expr_as_pstring (ABSTRACT_EXPRVAL*,PSTRING);
|
|
131
|
+
\brief method to return PSTRING value from callback of call_expr_userfnc_functype.
|
|
132
|
+
|
|
133
|
+
It should only be used in a callback of call_expr_userfnc_functype.
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
/*! \fn void tmplpro_set_expr_as_null (ABSTRACT_EXPRVAL*);
|
|
137
|
+
\brief method to return null from callback of call_expr_userfnc_functype.
|
|
138
|
+
|
|
139
|
+
It should only be used in a callback of call_expr_userfnc_functype.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
/*! \fn EXPR_int64 tmplpro_get_expr_as_int64 (ABSTRACT_EXPRVAL*);
|
|
143
|
+
\brief method for callback of push_expr_arglist_functype to retrieve a value as int64.
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
/*! \fn double tmplpro_get_expr_as_double (ABSTRACT_EXPRVAL*);
|
|
147
|
+
\brief method for callback of push_expr_arglist_functype to retrieve a value as double.
|
|
148
|
+
|
|
149
|
+
It should only be used in a callback of push_expr_arglist_functype.
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
/*! \fn PSTRING tmplpro_get_expr_as_pstring (ABSTRACT_EXPRVAL*);
|
|
153
|
+
\brief method for callback of push_expr_arglist_functype to retrieve a value as PSTRING.
|
|
154
|
+
|
|
155
|
+
It should only be used in a callback of push_expr_arglist_functype.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/*! \fn int tmplpro_get_expr_type (ABSTRACT_EXPRVAL*);
|
|
159
|
+
\brief method for callback of push_expr_arglist_functype to determine the type of a value.
|
|
160
|
+
|
|
161
|
+
It should only be used in a callback of push_expr_arglist_functype.
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
/** \struct tmplpro_param
|
|
165
|
+
|
|
166
|
+
\brief main htmltmplpro class.
|
|
167
|
+
|
|
168
|
+
Main htmltmplpro class. Passed by reference.
|
|
169
|
+
Its internal structure is hidden and is not part of the API.
|
|
170
|
+
|
|
171
|
+
Constructor is tmplpro_param_init()
|
|
172
|
+
|
|
173
|
+
Destructor is tmplpro_param_free()
|
|
174
|
+
|
|
175
|
+
Main methods are tmplpro_exec_tmpl(), tmplpro_tmpl2pstring()
|
|
176
|
+
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
/** \struct exprval
|
|
180
|
+
|
|
181
|
+
\brief EXPR="..." variable class.
|
|
182
|
+
|
|
183
|
+
EXPR="..." expression variable class. Passed by reference.
|
|
184
|
+
Its internal structure is hidden and is not part of the API.
|
|
185
|
+
It can contain string, 64-bit integer or double.
|
|
186
|
+
|
|
187
|
+
Methods:
|
|
188
|
+
\li tmplpro_set_expr_as_null(ABSTRACT_EXPRVAL*)
|
|
189
|
+
\li tmplpro_set_expr_as_int64(ABSTRACT_EXPRVAL*,EXPR_int64)
|
|
190
|
+
\li tmplpro_set_expr_as_double(ABSTRACT_EXPRVAL*,double)
|
|
191
|
+
\li tmplpro_set_expr_as_string(ABSTRACT_EXPRVAL*,const char*)
|
|
192
|
+
\li tmplpro_set_expr_as_pstring(ABSTRACT_EXPRVAL*,PSTRING)
|
|
193
|
+
|
|
194
|
+
\li tmplpro_get_expr_type(ABSTRACT_EXPRVAL*)
|
|
195
|
+
\li tmplpro_get_expr_as_int64(ABSTRACT_EXPRVAL*)
|
|
196
|
+
\li tmplpro_get_expr_as_double(ABSTRACT_EXPRVAL*)
|
|
197
|
+
\li tmplpro_get_expr_as_pstring(ABSTRACT_EXPRVAL*)
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
/*! \mainpage
|
|
202
|
+
*
|
|
203
|
+
* \section intro_sec Introduction
|
|
204
|
+
*
|
|
205
|
+
* \include README
|
|
206
|
+
*
|
|
207
|
+
* \section compile_sec Compilation
|
|
208
|
+
*
|
|
209
|
+
* \subsection autoconf
|
|
210
|
+
*
|
|
211
|
+
* \subsection CMake
|
|
212
|
+
* etc...
|
|
213
|
+
*
|
|
214
|
+
* \section api_sec History of API and ABI changes
|
|
215
|
+
*
|
|
216
|
+
* \include API
|
|
217
|
+
*
|
|
218
|
+
*/
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: tmplpro_version.c
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Mon Jul 13 21:24:55 2009
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#ifdef HAVE_CONFIG_H
|
|
8
|
+
#include "config.h"
|
|
9
|
+
#endif
|
|
10
|
+
|
|
11
|
+
#ifndef PACKAGE_VERSION
|
|
12
|
+
#define PACKAGE_VERSION "0.0(not defined)"
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
/*************************************************
|
|
16
|
+
* Return version string *
|
|
17
|
+
*************************************************/
|
|
18
|
+
|
|
19
|
+
/* These macros are the standard way of turning unquoted text into C strings.
|
|
20
|
+
They allow macros like PCRE_MAJOR to be defined without quotes, which is
|
|
21
|
+
convenient for user programs that want to test its value. */
|
|
22
|
+
|
|
23
|
+
#define STRING(a) # a
|
|
24
|
+
#define XSTRING(s) STRING(s)
|
|
25
|
+
|
|
26
|
+
const char* tmplpro_version(void) {
|
|
27
|
+
//return "" XSTRING(PACKAGE_VERSION) ;
|
|
28
|
+
return "" PACKAGE_VERSION ;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* Local Variables:
|
|
33
|
+
* mode: c
|
|
34
|
+
* End:
|
|
35
|
+
*/
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
require 'html_template_internal'
|
|
2
|
+
|
|
3
|
+
module HTML
|
|
4
|
+
module Template
|
|
5
|
+
|
|
6
|
+
def Internal.register_functions_impl(registory, func_spec, &block)
|
|
7
|
+
if block && func_spec.kind_of?(Symbol)
|
|
8
|
+
registory[func_spec] = block
|
|
9
|
+
elsif func_spec.kind_of? Hash
|
|
10
|
+
unless func_spec.values.all?{|e| e.kind_of? Proc}
|
|
11
|
+
raise ArgumentError, "functions must be kind_of Proc"
|
|
12
|
+
end
|
|
13
|
+
registory.update(func_spec)
|
|
14
|
+
else
|
|
15
|
+
raise ArgumentError, "first argument must be symbol or hash contains functions"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Pro
|
|
20
|
+
|
|
21
|
+
VERSION = "0.0.1"
|
|
22
|
+
|
|
23
|
+
include HTML::Template::Internal
|
|
24
|
+
|
|
25
|
+
INPUTS = [:filename, :filehandle, :arrayref, :scalarref, :source]
|
|
26
|
+
|
|
27
|
+
ASK_NAME_DEFAULT = 0
|
|
28
|
+
ASK_NAME_AS_IS = 1
|
|
29
|
+
ASK_NAME_LOWERCASE = 2
|
|
30
|
+
ASK_NAME_UPPERCASE = 4
|
|
31
|
+
ASK_NAME_MASK = ASK_NAME_AS_IS | ASK_NAME_LOWERCASE | ASK_NAME_UPPERCASE
|
|
32
|
+
|
|
33
|
+
@@func = {
|
|
34
|
+
# note that length,defined,sin,cos,log,tan,... are built-in
|
|
35
|
+
:sprintf => lambda { |*args| sprintf(*args) },
|
|
36
|
+
:substr => lambda { |str, *args| args.size == 2 ? str[*args] : str[args[0]..-1] },
|
|
37
|
+
:lc => lambda { |str| str.downcase },
|
|
38
|
+
:lcfirst => lambda { |str| str[0,1].downcase + str[1..-1] },
|
|
39
|
+
:uc => lambda { |str| str.upcase },
|
|
40
|
+
:ucfirst => lambda { |str| str.capitalize },
|
|
41
|
+
# :length => lambda { |str| str.length },
|
|
42
|
+
# :defined => lambda { |obj| obj.nil? },
|
|
43
|
+
# :abs => lambda { |num| num.abs },
|
|
44
|
+
# :hex => lambda { |obj| obj.to_s.hex },
|
|
45
|
+
# :oct => lambda { |obj| obj.to_s.oct },
|
|
46
|
+
:rand => lambda { |num| rand num },
|
|
47
|
+
:srand => lambda { |seed| srand seed },
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
def initialize(args={})
|
|
51
|
+
@options = default_options.merge(args)
|
|
52
|
+
if args.keys.count(&INPUTS.method(:include?)) != 1
|
|
53
|
+
raise ArgumentError, "HTML::Template::Pro.new called with multiple (or no) template sources specified!"
|
|
54
|
+
end
|
|
55
|
+
@params = @options[:param_map]
|
|
56
|
+
[:path, :associate, :filter].each do |opt|
|
|
57
|
+
unless @options[opt].kind_of? Array
|
|
58
|
+
@options[opt] = [ @options[opt] ]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
@options[:expr_func] = @@func.merge(@options[:functions] || {})
|
|
62
|
+
initialize_tmpl_source args
|
|
63
|
+
if @scalarref and @options[:filter]
|
|
64
|
+
@scalarref = call_filters @scalarref
|
|
65
|
+
end
|
|
66
|
+
@filtered_template = {}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def param(args=nil, &block)
|
|
70
|
+
return @params.keys if args.nil?
|
|
71
|
+
if !(args.kind_of? Hash)
|
|
72
|
+
key = @options[:case_sensitive] ? args : args.downcase
|
|
73
|
+
if block
|
|
74
|
+
return @params[key] = block
|
|
75
|
+
else
|
|
76
|
+
return @params[key] || @params[args]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
merge_params(args)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def clear_params
|
|
83
|
+
@params.clear
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def output(options={})
|
|
87
|
+
|
|
88
|
+
@options[:associate].reverse.each do |assoc|
|
|
89
|
+
assoc.param.each do |key|
|
|
90
|
+
param(key => assoc.param(key)) unless @params[key]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if (options.include? :print_to)
|
|
95
|
+
exec_tmpl(options[:print_to])
|
|
96
|
+
else
|
|
97
|
+
output_string = String.new
|
|
98
|
+
exec_tmpl(output_string)
|
|
99
|
+
return output_string
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.new_filehandle(file)
|
|
104
|
+
self.new(:filehandle => file)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def self.register_function(func_spec, &block)
|
|
108
|
+
HTML::Template::Internal.register_functions_impl(@@func, func_spec, &block)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def register_function(func_spec, &block)
|
|
112
|
+
HTML::Template::Internal.register_functions_impl(@options[:expr_func], func_spec, &block)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def default_options
|
|
118
|
+
return {
|
|
119
|
+
:param_map => {},
|
|
120
|
+
:filter => [],
|
|
121
|
+
:debug => 0,
|
|
122
|
+
:max_includes => 10,
|
|
123
|
+
:global_vars => false,
|
|
124
|
+
:no_includes => false,
|
|
125
|
+
:search_path_on_include => false,
|
|
126
|
+
:loop_context_vars => false,
|
|
127
|
+
:path_like_variable_scope => false,
|
|
128
|
+
:path => [],
|
|
129
|
+
:associate => [],
|
|
130
|
+
:case_sensitive => false,
|
|
131
|
+
:__strict_compatibility => true,
|
|
132
|
+
:strict => false,
|
|
133
|
+
:die_on_bad_params => false,
|
|
134
|
+
}
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def initialize_tmpl_source(args)
|
|
138
|
+
if args.include? :filename
|
|
139
|
+
@filename = args[:filename]
|
|
140
|
+
@scalarref = nil
|
|
141
|
+
return
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
@filename = nil
|
|
145
|
+
if args.include? :source
|
|
146
|
+
source = args[:source]
|
|
147
|
+
@scalarref = case source
|
|
148
|
+
when IO then source.read
|
|
149
|
+
when Array then source.join('')
|
|
150
|
+
when String then source
|
|
151
|
+
else
|
|
152
|
+
if source.respond_to? :to_str
|
|
153
|
+
source.to_str
|
|
154
|
+
else
|
|
155
|
+
raise "unknown source type"
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
elsif args.include? :scalarref
|
|
159
|
+
@scalarref = args[:scalarref]
|
|
160
|
+
elsif args.include? :arrayref
|
|
161
|
+
@scalarref = args[:arrayref].join('')
|
|
162
|
+
elsif args.include? :filehandle
|
|
163
|
+
@scalarref = args[:filehandle].read
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def merge_params(params)
|
|
168
|
+
unless @options[:case_sensitive]
|
|
169
|
+
params = lowercase_keys params
|
|
170
|
+
end
|
|
171
|
+
@params.update(params)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def lowercase_keys(orighash)
|
|
175
|
+
Hash[
|
|
176
|
+
orighash.map do |key, val|
|
|
177
|
+
case val
|
|
178
|
+
when Array then [key.downcase, val.map(&(method :lowercase_keys))]
|
|
179
|
+
when Proc then [key.downcase, val]
|
|
180
|
+
else [key.downcase, val]
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
]
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def load_template(filepath)
|
|
187
|
+
File.open(filepath, 'r') do |file|
|
|
188
|
+
# filtered template is used in internal. we store it to `self'
|
|
189
|
+
# to prevent gc.
|
|
190
|
+
@filtered_template[filepath] = call_filters file.read
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def call_filters(template)
|
|
195
|
+
@options[:filter].each do |filter|
|
|
196
|
+
format, sub = case filter
|
|
197
|
+
when Hash then filter.values_at(:format, :sub)
|
|
198
|
+
when Proc then ['scalar', filter]
|
|
199
|
+
else raise "bad value set for filter parameter - must be a Proc or a Hash object."
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
unless format and sub
|
|
203
|
+
raise "bad value set for filter parameter - hash must contain \"format\" key and \"sub\" key."
|
|
204
|
+
end
|
|
205
|
+
unless format == 'array' or format == 'scalar'
|
|
206
|
+
raise "bad value set for filter parameter - \"format\" must be either 'array' or 'scalar'"
|
|
207
|
+
end
|
|
208
|
+
unless sub.kind_of? Proc
|
|
209
|
+
raise "bad value set for filter parameter - \"sub\" must be a code ref"
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
if format == 'scalar'
|
|
213
|
+
template = sub.call(template)
|
|
214
|
+
else
|
|
215
|
+
template = sub.call(template.split("\n").map {|str| str + "\n"}).join('')
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
return template
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# alias
|
|
223
|
+
Expr = Pro
|
|
224
|
+
end
|
|
225
|
+
end
|