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,32 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: proscope.h
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Thu May 26 15:13:10 2005
|
|
5
|
+
*
|
|
6
|
+
* $Id$
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef _PROSCOPE_H
|
|
10
|
+
#define _PROSCOPE_H 1
|
|
11
|
+
|
|
12
|
+
#include "pabstract.h"
|
|
13
|
+
|
|
14
|
+
struct scope_stack {
|
|
15
|
+
int level;
|
|
16
|
+
int max;
|
|
17
|
+
struct ProScopeEntry* root;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
struct ProScopeEntry {
|
|
21
|
+
int flags; /* type of scope */
|
|
22
|
+
int loop; /* current loop */
|
|
23
|
+
int loop_count; /* total number of loops or negative value if unknown */
|
|
24
|
+
/* objects are wrapper-specific so pointer is void */
|
|
25
|
+
ABSTRACT_ARRAY* loops_AV; /* pointer to array of loop's dictionaries */
|
|
26
|
+
ABSTRACT_MAP* param_HV; /* pointer to dictionary of current loop */
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
#define isScopeLoop(X) ((X)->loops_AV!=NULL)
|
|
30
|
+
#define isScopeMap(X) ((X)->loops_AV==NULL)
|
|
31
|
+
|
|
32
|
+
#endif /* _PROSCOPE_H */
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: proscope.c
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Thu May 26 15:25:57 2005
|
|
5
|
+
*
|
|
6
|
+
* $Id$
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include "proscope.h"
|
|
11
|
+
#include "tmpllog.h"
|
|
12
|
+
|
|
13
|
+
#define START_NUMBER_OF_NESTED_LOOPS 64
|
|
14
|
+
|
|
15
|
+
static
|
|
16
|
+
void
|
|
17
|
+
Scope_init(struct scope_stack* scopestack) {
|
|
18
|
+
scopestack->max=START_NUMBER_OF_NESTED_LOOPS;
|
|
19
|
+
scopestack->root=(struct ProScopeEntry*) malloc ((scopestack->max) * sizeof(struct ProScopeEntry));
|
|
20
|
+
if (NULL==scopestack->root) tmpl_log(TMPL_LOG_ERROR, "DIE:_Scope_init:internal error:not enough memory\n");
|
|
21
|
+
scopestack->level=-1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static
|
|
25
|
+
void
|
|
26
|
+
Scope_free(struct scope_stack* scopestack) {
|
|
27
|
+
free(scopestack->root);
|
|
28
|
+
scopestack->max=-1;
|
|
29
|
+
scopestack->level=-1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static
|
|
33
|
+
int curScopeLevel(struct scope_stack* scopestack) {
|
|
34
|
+
return scopestack->level;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static
|
|
38
|
+
struct ProScopeEntry* getCurrentScope(struct scope_stack* scopestack) {
|
|
39
|
+
return scopestack->root+scopestack->level;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static
|
|
43
|
+
struct ProScopeEntry*
|
|
44
|
+
getScope(struct scope_stack* scopestack, int depth) {
|
|
45
|
+
return &(scopestack->root)[depth];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static
|
|
49
|
+
void
|
|
50
|
+
popScope(struct scope_stack* scopestack) {
|
|
51
|
+
if (scopestack->level>0) scopestack->level--;
|
|
52
|
+
else tmpl_log(TMPL_LOG_ERROR, "WARN:PopScope:internal error:scope is exhausted\n");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static
|
|
56
|
+
void
|
|
57
|
+
_pushScope(struct scope_stack* scopestack) {
|
|
58
|
+
if (scopestack->max<0) {
|
|
59
|
+
tmpl_log(TMPL_LOG_ERROR, "WARN:PushScope:internal warning:why scope is empty?\n");
|
|
60
|
+
Scope_init(scopestack);
|
|
61
|
+
}
|
|
62
|
+
++scopestack->level;
|
|
63
|
+
if (scopestack->level>scopestack->max)
|
|
64
|
+
{
|
|
65
|
+
if (scopestack->max<START_NUMBER_OF_NESTED_LOOPS) scopestack->max=START_NUMBER_OF_NESTED_LOOPS;
|
|
66
|
+
scopestack->max*=2;
|
|
67
|
+
scopestack->root=(struct ProScopeEntry*) realloc (scopestack->root, (scopestack->max) * sizeof(struct ProScopeEntry));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static
|
|
72
|
+
void
|
|
73
|
+
pushScopeLoop(struct scope_stack* scopestack, int loop_count, void *loops_AV) {
|
|
74
|
+
struct ProScopeEntry* CurrentScope;
|
|
75
|
+
_pushScope(scopestack);
|
|
76
|
+
CurrentScope=scopestack->root+scopestack->level;
|
|
77
|
+
CurrentScope->loop=-1;
|
|
78
|
+
CurrentScope->loop_count = loop_count;
|
|
79
|
+
CurrentScope->flags=0;
|
|
80
|
+
CurrentScope->loops_AV=loops_AV;
|
|
81
|
+
CurrentScope->param_HV=NULL;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static
|
|
85
|
+
void
|
|
86
|
+
pushScopeMap(struct scope_stack* scopestack, void *param_HV, int flags) {
|
|
87
|
+
struct ProScopeEntry* CurrentScope;
|
|
88
|
+
_pushScope(scopestack);
|
|
89
|
+
CurrentScope=scopestack->root+scopestack->level;
|
|
90
|
+
CurrentScope->flags=flags;
|
|
91
|
+
CurrentScope->loops_AV=NULL;
|
|
92
|
+
CurrentScope->param_HV=param_HV;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static
|
|
96
|
+
void
|
|
97
|
+
Scope_reset(struct scope_stack* scopestack, int keep_count) {
|
|
98
|
+
int init_level=-1;
|
|
99
|
+
// TODO; find out scope level
|
|
100
|
+
if (scopestack->max<0) {
|
|
101
|
+
tmpl_log(TMPL_LOG_ERROR, "ERROR:Scope_reset:internal error:scope is empty.\n");
|
|
102
|
+
Scope_init(scopestack);
|
|
103
|
+
scopestack->level=init_level;
|
|
104
|
+
} else {
|
|
105
|
+
scopestack->level=keep_count+init_level;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#ifndef _PROSTATE_H
|
|
2
|
+
#define _PROSTATE_H 1
|
|
3
|
+
|
|
4
|
+
#include "pbuffer.h"
|
|
5
|
+
|
|
6
|
+
struct tagstack {
|
|
7
|
+
struct tagstack_entry* entry;
|
|
8
|
+
int pos;
|
|
9
|
+
int depth;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
struct tmplpro_param;
|
|
13
|
+
|
|
14
|
+
typedef int boolval;
|
|
15
|
+
|
|
16
|
+
struct tmplpro_state {
|
|
17
|
+
boolval is_visible;
|
|
18
|
+
const char* top;
|
|
19
|
+
const char* next_to_end;
|
|
20
|
+
const char* last_processed_pos;
|
|
21
|
+
const char* cur_pos;
|
|
22
|
+
struct tmplpro_param* param;
|
|
23
|
+
/* current tag */
|
|
24
|
+
int tag;
|
|
25
|
+
boolval is_tag_closed;
|
|
26
|
+
boolval is_tag_commented;
|
|
27
|
+
boolval is_expr;
|
|
28
|
+
const char* tag_start;
|
|
29
|
+
|
|
30
|
+
/* internal buffers */
|
|
31
|
+
/* main string buffer */
|
|
32
|
+
pbuffer str_buffer;
|
|
33
|
+
/* tag stack */
|
|
34
|
+
struct tagstack tag_stack;
|
|
35
|
+
|
|
36
|
+
/* expr string buffers; used to unescape pstring args and for num -> string */
|
|
37
|
+
pbuffer expr_left_pbuffer;
|
|
38
|
+
pbuffer expr_right_pbuffer;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
extern TMPLPRO_LOCAL void log_state(struct tmplpro_state*, int level, const char *fmt, ...) FORMAT_PRINTF(3,4);
|
|
42
|
+
|
|
43
|
+
#endif /* prostate.h */
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* Local Variables:
|
|
47
|
+
* mode: c
|
|
48
|
+
* End:
|
|
49
|
+
*/
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#include "prostate.h"
|
|
2
|
+
#include "tmpllog.h"
|
|
3
|
+
|
|
4
|
+
TMPLPRO_LOCAL void log_state(struct tmplpro_state* state, int level, const char *fmt, ...)
|
|
5
|
+
{
|
|
6
|
+
va_list vl;
|
|
7
|
+
va_start(vl, fmt);
|
|
8
|
+
if (state->tag ==HTML_TEMPLATE_NO_TAG) {
|
|
9
|
+
tmpl_log(level, "HTML::Template::Pro:");
|
|
10
|
+
} else {
|
|
11
|
+
tmpl_log(level, "HTML::Template::Pro:in %sTMPL_%s at pos " MOD_TD ": ",
|
|
12
|
+
(state->is_tag_closed ? "/" : ""),
|
|
13
|
+
(state->tag>HTML_TEMPLATE_BAD_TAG && state->tag <=HTML_TEMPLATE_LAST_TAG_USED) ? TAGNAME[state->tag] : "",
|
|
14
|
+
TO_PTRDIFF_T(state->tag_start - state->top));
|
|
15
|
+
}
|
|
16
|
+
tmpl_vlog(level, fmt, vl);
|
|
17
|
+
va_end(vl);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* Local Variables:
|
|
22
|
+
* mode: c
|
|
23
|
+
* End:
|
|
24
|
+
*/
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/*! \file pstring.h
|
|
2
|
+
* \brief string type.
|
|
3
|
+
*
|
|
4
|
+
* \author Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
5
|
+
* \warning This header file should never be included directly.
|
|
6
|
+
* Include <tmplpro.h> instead.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef _PSTRING_H
|
|
10
|
+
#define _PSTRING_H 1
|
|
11
|
+
|
|
12
|
+
/** \struct PSTRING
|
|
13
|
+
|
|
14
|
+
\brief string type used in htmltmplpro.
|
|
15
|
+
|
|
16
|
+
\code
|
|
17
|
+
typedef struct PSTRING {
|
|
18
|
+
const char* begin;
|
|
19
|
+
const char* endnext;
|
|
20
|
+
} PSTRING;
|
|
21
|
+
\endcode
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
The string is delimited by two pointers, begin and endnext.
|
|
25
|
+
The length of the string is calculated as endnext - begin.
|
|
26
|
+
The empty string has begin == endnext.
|
|
27
|
+
|
|
28
|
+
\warning It is possible for empty string to have begin == endnext == NULL.
|
|
29
|
+
\warning Contents of the memory area, passed as PSTRING, should always be treated as const.
|
|
30
|
+
\warning Contents of the memory area, passed as PSTRING, can be destroyed after the callback function
|
|
31
|
+
completed. To be used afterwards the string content should be copied.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
typedef struct PSTRING {
|
|
35
|
+
const char* begin; /*!< pointer to begin of the string. */
|
|
36
|
+
const char* endnext; /*!< pointer to the byte next to the last char of the string. */
|
|
37
|
+
} PSTRING;
|
|
38
|
+
|
|
39
|
+
/** \struct MPSTRING
|
|
40
|
+
|
|
41
|
+
\brief Modifiable PSTRING.
|
|
42
|
+
|
|
43
|
+
\code
|
|
44
|
+
typedef struct MPSTRING {
|
|
45
|
+
char* begin;
|
|
46
|
+
char* endnext;
|
|
47
|
+
} PSTRING;
|
|
48
|
+
\endcode
|
|
49
|
+
|
|
50
|
+
The same as PSTING, but in non-constant memory.
|
|
51
|
+
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
typedef struct MPSTRING {
|
|
56
|
+
char* begin; /*!< pointer to begin of the string. */
|
|
57
|
+
char* endnext; /*!< pointer to the byte next to the last char of the string. */
|
|
58
|
+
} MPSTRING;
|
|
59
|
+
|
|
60
|
+
#endif /* pstring.h */
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: pstring.h
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Fri Jul 1 20:11:51 2005
|
|
5
|
+
*
|
|
6
|
+
* $Id$
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef _PSTRUTILS_H
|
|
10
|
+
#define _PSTRUTILS_H 1
|
|
11
|
+
|
|
12
|
+
#include "pbuffer.h"
|
|
13
|
+
|
|
14
|
+
static
|
|
15
|
+
PSTRING lowercase_pstring (pbuffer*, PSTRING);
|
|
16
|
+
static
|
|
17
|
+
int is_pstring_true (PSTRING s);
|
|
18
|
+
static
|
|
19
|
+
PSTRING escape_pstring (pbuffer* StrBuffer, PSTRING pstring, int escapeopt);
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
static
|
|
23
|
+
void lowercase_pstring_inplace (PSTRING pstring);
|
|
24
|
+
*/
|
|
25
|
+
#endif /* pstrutils.h */
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* -*- c -*-
|
|
2
|
+
* File: pstring.h
|
|
3
|
+
* Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
|
|
4
|
+
* Created: Fri Jul 1 20:11:51 2005
|
|
5
|
+
*
|
|
6
|
+
* $Id$
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
#include <ctype.h>
|
|
12
|
+
#include "pbuffer.h"
|
|
13
|
+
#include "pstring.h"
|
|
14
|
+
|
|
15
|
+
static
|
|
16
|
+
PSTRING
|
|
17
|
+
lowercase_pstring (pbuffer* pBuffer ,PSTRING pstring) {
|
|
18
|
+
size_t size=pstring.endnext-pstring.begin;
|
|
19
|
+
char* buf=pbuffer_resize(pBuffer, size+1);
|
|
20
|
+
char* inbuf=buf;
|
|
21
|
+
const char* i=pstring.begin;
|
|
22
|
+
PSTRING retval;
|
|
23
|
+
while (i<pstring.endnext) {
|
|
24
|
+
*inbuf++=tolower((unsigned char) *i++);
|
|
25
|
+
}
|
|
26
|
+
*inbuf=0;
|
|
27
|
+
retval.begin=buf;
|
|
28
|
+
retval.endnext=buf+size;
|
|
29
|
+
return retval;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
static
|
|
34
|
+
void
|
|
35
|
+
lowercase_pstring_inplace (PSTRING pstring) {
|
|
36
|
+
char* i=pstring.begin;
|
|
37
|
+
while (i<pstring.endnext) {
|
|
38
|
+
*i=tolower(*i);
|
|
39
|
+
i++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
static
|
|
45
|
+
PSTRING
|
|
46
|
+
uppercase_pstring (pbuffer* pBuffer ,PSTRING pstring) {
|
|
47
|
+
size_t size=pstring.endnext-pstring.begin;
|
|
48
|
+
char* buf=pbuffer_resize(pBuffer, size+1);
|
|
49
|
+
char* inbuf=buf;
|
|
50
|
+
const char* i=pstring.begin;
|
|
51
|
+
PSTRING retval;
|
|
52
|
+
while (i<pstring.endnext) {
|
|
53
|
+
*inbuf++=toupper((unsigned char) *i++);
|
|
54
|
+
}
|
|
55
|
+
*inbuf=0;
|
|
56
|
+
retval.begin=buf;
|
|
57
|
+
retval.endnext=buf+size;
|
|
58
|
+
return retval;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
static
|
|
63
|
+
int
|
|
64
|
+
is_pstring_true (PSTRING s) {
|
|
65
|
+
if (s.begin == NULL || s.begin == s.endnext) return 0;
|
|
66
|
+
if (1==s.endnext-s.begin) {
|
|
67
|
+
if (*(s.begin)=='0') return 0; else return 1;
|
|
68
|
+
} else if (3==s.endnext-s.begin) {
|
|
69
|
+
if ('0'==*(s.begin) && '.'==*(s.begin+1) && '0'==*(s.begin+2)) return 0; else return 1;
|
|
70
|
+
} else return 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static
|
|
74
|
+
PSTRING
|
|
75
|
+
escape_pstring (pbuffer* StrBuffer, PSTRING pstring, int escapeopt) {
|
|
76
|
+
char* buf=pbuffer_resize(StrBuffer, 2*(pstring.endnext-pstring.begin+1));
|
|
77
|
+
const char* curpos=pstring.begin;
|
|
78
|
+
size_t offset=0;
|
|
79
|
+
size_t buflen=pbuffer_size(StrBuffer);
|
|
80
|
+
PSTRING retval;
|
|
81
|
+
switch (escapeopt) {
|
|
82
|
+
case HTML_TEMPLATE_OPT_ESCAPE_HTML:
|
|
83
|
+
while (curpos<pstring.endnext) {
|
|
84
|
+
unsigned char curchar=*curpos++;
|
|
85
|
+
int bufdelta=1;
|
|
86
|
+
if (offset>=buflen) {
|
|
87
|
+
buf=pbuffer_resize(StrBuffer, 2*offset);
|
|
88
|
+
buflen=pbuffer_size(StrBuffer);
|
|
89
|
+
}
|
|
90
|
+
switch (curchar) {
|
|
91
|
+
/* straight from the CGI.pm bible. (HTML::Template) */
|
|
92
|
+
case '&' : bufdelta=5; strncpy(buf+offset, "&", bufdelta);break;
|
|
93
|
+
case '"' : bufdelta=6; strncpy(buf+offset, """,bufdelta);break;
|
|
94
|
+
case '>' : bufdelta=4; strncpy(buf+offset, ">", bufdelta);break;
|
|
95
|
+
case '<' : bufdelta=4; strncpy(buf+offset, "<", bufdelta);break;
|
|
96
|
+
case '\'': bufdelta=5; strncpy(buf+offset, "'", bufdelta);break;
|
|
97
|
+
default: *(buf+offset)=curchar;
|
|
98
|
+
}
|
|
99
|
+
offset+=bufdelta;
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
case HTML_TEMPLATE_OPT_ESCAPE_JS:
|
|
103
|
+
while (curpos<pstring.endnext) {
|
|
104
|
+
unsigned char curchar=*curpos++;
|
|
105
|
+
int bufdelta=1;
|
|
106
|
+
if (offset>=buflen) {
|
|
107
|
+
buf=pbuffer_resize(StrBuffer, 2*offset);
|
|
108
|
+
buflen=pbuffer_size(StrBuffer);
|
|
109
|
+
}
|
|
110
|
+
switch (curchar) {
|
|
111
|
+
case '\\' : bufdelta=2; strncpy(buf+offset, "\\\\", bufdelta);break;
|
|
112
|
+
case '"' : bufdelta=2; strncpy(buf+offset, "\\\"",bufdelta);break;
|
|
113
|
+
case '\'' : bufdelta=2; strncpy(buf+offset, "\\'",bufdelta);break;
|
|
114
|
+
case '\n' : bufdelta=2; strncpy(buf+offset, "\\n",bufdelta);break;
|
|
115
|
+
case '\r' : bufdelta=2; strncpy(buf+offset, "\\r",bufdelta);break;
|
|
116
|
+
default: *(buf+offset)=curchar;
|
|
117
|
+
}
|
|
118
|
+
offset+=bufdelta;
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
case HTML_TEMPLATE_OPT_ESCAPE_URL:
|
|
122
|
+
while (curpos<pstring.endnext) {
|
|
123
|
+
unsigned char curchar=*curpos++;
|
|
124
|
+
int bufdelta=1;
|
|
125
|
+
if (offset>=buflen) {
|
|
126
|
+
buf=pbuffer_resize(StrBuffer, 2*offset);
|
|
127
|
+
buflen=pbuffer_size(StrBuffer);
|
|
128
|
+
}
|
|
129
|
+
/*
|
|
130
|
+
* # do the translation (RFC 2396 ^uric)
|
|
131
|
+
* s!([^a-zA-Z0-9_.\-])!sprintf('%%%02X', $_)
|
|
132
|
+
*/
|
|
133
|
+
if ((curchar>='a' && curchar<='z') ||
|
|
134
|
+
(curchar>='A' && curchar<='Z') ||
|
|
135
|
+
(curchar>='0' && curchar<='9') ||
|
|
136
|
+
curchar=='_' || curchar=='.' || curchar=='\\' || curchar=='-'
|
|
137
|
+
)
|
|
138
|
+
*(buf+offset)=curchar;
|
|
139
|
+
else {
|
|
140
|
+
bufdelta=3; sprintf(buf+offset,"%%%.2X",(int) curchar);
|
|
141
|
+
}
|
|
142
|
+
offset+=bufdelta;
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
default : return pstring;
|
|
146
|
+
}
|
|
147
|
+
retval.begin=buf;
|
|
148
|
+
retval.endnext=buf+offset;
|
|
149
|
+
return retval;
|
|
150
|
+
}
|