| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
static |
|
2
|
1141
|
|
|
|
|
|
int get_escape_option(struct tmplpro_state *state, PSTRING OptEscape) |
|
3
|
|
|
|
|
|
|
{ |
|
4
|
|
|
|
|
|
|
/* int escape = HTML_TEMPLATE_OPT_ESCAPE_NO; */ |
|
5
|
1141
|
|
|
|
|
|
int escape = state->param->default_escape; |
|
6
|
1141
|
100
|
|
|
|
|
if (OptEscape.begin
|
|
7
|
90
|
|
|
|
|
|
switch (*OptEscape.begin) { |
|
8
|
|
|
|
|
|
|
case '1': case 'H': case 'h': /* HTML*/ |
|
9
|
60
|
|
|
|
|
|
escape = HTML_TEMPLATE_OPT_ESCAPE_HTML; |
|
10
|
60
|
|
|
|
|
|
break; |
|
11
|
|
|
|
|
|
|
case 'U': case 'u': /* URL */ |
|
12
|
13
|
|
|
|
|
|
escape = HTML_TEMPLATE_OPT_ESCAPE_URL; |
|
13
|
13
|
|
|
|
|
|
break; |
|
14
|
|
|
|
|
|
|
case 'J': case 'j': /* JS */ |
|
15
|
9
|
|
|
|
|
|
escape = HTML_TEMPLATE_OPT_ESCAPE_JS; |
|
16
|
9
|
|
|
|
|
|
break; |
|
17
|
|
|
|
|
|
|
case '0': case 'N': case 'n': /* 0 or NONE */ |
|
18
|
8
|
|
|
|
|
|
escape = HTML_TEMPLATE_OPT_ESCAPE_NO; |
|
19
|
8
|
|
|
|
|
|
break; |
|
20
|
|
|
|
|
|
|
default: |
|
21
|
0
|
|
|
|
|
|
state->param->found_syntax_error=1; |
|
22
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR, " unsupported value of ESCAPE=%.*s\n",(int)(OptEscape.endnext-OptEscape.begin),OptEscape.begin); |
|
23
|
|
|
|
|
|
|
} |
|
24
|
|
|
|
|
|
|
} |
|
25
|
1141
|
|
|
|
|
|
return escape; |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
static |
|
29
|
1394
|
|
|
|
|
|
void init_tmpl_var_case_buffers (struct tmplpro_param *param) { |
|
30
|
1394
|
|
|
|
|
|
param->lowercase_varname.begin = NULL; |
|
31
|
1394
|
|
|
|
|
|
param->lowercase_varname.endnext = NULL; |
|
32
|
1394
|
|
|
|
|
|
param->uppercase_varname.begin = NULL; |
|
33
|
1394
|
|
|
|
|
|
param->uppercase_varname.endnext = NULL; |
|
34
|
1394
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
static |
|
37
|
1446
|
|
|
|
|
|
ABSTRACT_VALUE* get_abstract_value (struct tmplpro_param *param, int scope_level, PSTRING name) { |
|
38
|
1446
|
|
|
|
|
|
ABSTRACT_VALUE* retval = NULL; |
|
39
|
1446
|
|
|
|
|
|
ABSTRACT_MAP* param_HV = getScope(¶m->var_scope_stack, scope_level)->param_HV; |
|
40
|
1446
|
|
|
|
|
|
ABSTRACT_DATASTATE* data_state = param->ext_data_state; |
|
41
|
1446
|
|
|
|
|
|
get_ABSTRACT_VALUE_functype getval_func = param->GetAbstractValFuncPtr; |
|
42
|
1446
|
|
|
|
|
|
int tmpl_var_case = param->tmpl_var_case; |
|
43
|
1446
|
100
|
|
|
|
|
if ((tmpl_var_case & ASK_NAME_MASK) == ASK_NAME_DEFAULT |
|
44
|
1427
|
100
|
|
|
|
|
|| tmpl_var_case & ASK_NAME_AS_IS) { |
|
45
|
63
|
|
|
|
|
|
retval = getval_func(data_state, param_HV, name); |
|
46
|
63
|
100
|
|
|
|
|
if (retval != NULL) return retval; |
|
47
|
|
|
|
|
|
|
} |
|
48
|
1413
|
100
|
|
|
|
|
if (tmpl_var_case & ASK_NAME_LOWERCASE) { |
|
49
|
987
|
100
|
|
|
|
|
if (param->lowercase_varname.begin == NULL) { |
|
50
|
935
|
|
|
|
|
|
param->lowercase_varname=lowercase_pstring(¶m->lowercase_varname_buffer, name); |
|
51
|
|
|
|
|
|
|
} |
|
52
|
987
|
|
|
|
|
|
retval = getval_func(data_state, param_HV, param->lowercase_varname); |
|
53
|
987
|
100
|
|
|
|
|
if (retval != NULL) return retval; |
|
54
|
|
|
|
|
|
|
} |
|
55
|
624
|
100
|
|
|
|
|
if (tmpl_var_case & ASK_NAME_UPPERCASE) { |
|
56
|
426
|
50
|
|
|
|
|
if (param->uppercase_varname.begin == NULL) { |
|
57
|
426
|
|
|
|
|
|
param->uppercase_varname=uppercase_pstring(¶m->uppercase_varname_buffer, name); |
|
58
|
|
|
|
|
|
|
} |
|
59
|
426
|
|
|
|
|
|
retval = getval_func(data_state, param_HV, param->uppercase_varname); |
|
60
|
426
|
100
|
|
|
|
|
if (retval != NULL) return retval; |
|
61
|
|
|
|
|
|
|
} |
|
62
|
336
|
|
|
|
|
|
return retval; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
static |
|
66
|
1394
|
|
|
|
|
|
ABSTRACT_VALUE* walk_through_nested_loops (struct tmplpro_param *param, PSTRING name) { |
|
67
|
|
|
|
|
|
|
int CurLevel; |
|
68
|
|
|
|
|
|
|
ABSTRACT_VALUE* valptr; |
|
69
|
1394
|
|
|
|
|
|
init_tmpl_var_case_buffers (param); |
|
70
|
|
|
|
|
|
|
/* Shigeki Morimoto path_like_variable_scope extension */ |
|
71
|
1394
|
100
|
|
|
|
|
if (param->path_like_variable_scope) { |
|
72
|
13
|
100
|
|
|
|
|
if(*(name.begin) == '/' || strncmp(name.begin, "../", 3) == 0){ |
|
|
|
100
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
PSTRING tmp_name; |
|
74
|
|
|
|
|
|
|
int GoalHash; |
|
75
|
6
|
100
|
|
|
|
|
if(*(name.begin) == '/'){ |
|
76
|
4
|
|
|
|
|
|
tmp_name.begin = name.begin+1; // skip '/' |
|
77
|
4
|
|
|
|
|
|
tmp_name.endnext = name.endnext; |
|
78
|
4
|
|
|
|
|
|
GoalHash = 0; |
|
79
|
|
|
|
|
|
|
}else{ |
|
80
|
2
|
|
|
|
|
|
tmp_name.begin = name.begin; |
|
81
|
2
|
|
|
|
|
|
tmp_name.endnext = name.endnext; |
|
82
|
2
|
|
|
|
|
|
GoalHash = curScopeLevel(¶m->var_scope_stack); |
|
83
|
4
|
100
|
|
|
|
|
while(strncmp(tmp_name.begin, "../", 3) == 0){ |
|
84
|
2
|
|
|
|
|
|
tmp_name.begin = tmp_name.begin + 3; // skip '../' |
|
85
|
2
|
|
|
|
|
|
GoalHash --; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
} |
|
88
|
6
|
|
|
|
|
|
return get_abstract_value(param, GoalHash, tmp_name); |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
/* end Shigeki Morimoto path_like_variable_scope extension */ |
|
92
|
|
|
|
|
|
|
|
|
93
|
1388
|
|
|
|
|
|
CurLevel = curScopeLevel(¶m->var_scope_stack); |
|
94
|
1388
|
|
|
|
|
|
valptr = get_abstract_value(param, CurLevel, name); |
|
95
|
1388
|
100
|
|
|
|
|
if (valptr) return valptr; |
|
96
|
|
|
|
|
|
|
/* optional strict scoping; does it have much sence? |
|
97
|
|
|
|
|
|
|
if ((STRICT_SCOPING==param->global_vars)) return NULL; |
|
98
|
|
|
|
|
|
|
*/ |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
/* loop-bounded scoping; */ |
|
101
|
322
|
100
|
|
|
|
|
if (0==param->global_vars) { |
|
102
|
286
|
100
|
|
|
|
|
while (isScopeMap(getScope(¶m->var_scope_stack,CurLevel)) && --CurLevel>=0) { |
|
|
|
100
|
|
|
|
|
|
|
103
|
2
|
|
|
|
|
|
valptr = get_abstract_value(param, CurLevel, name); |
|
104
|
2
|
50
|
|
|
|
|
if (valptr!=NULL) return valptr; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
284
|
|
|
|
|
|
return NULL; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
50
|
50
|
|
|
|
|
while (--CurLevel>=0) { |
|
110
|
50
|
|
|
|
|
|
valptr = get_abstract_value(param, CurLevel, name); |
|
111
|
50
|
100
|
|
|
|
|
if (valptr!=NULL) return valptr; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
0
|
|
|
|
|
|
return NULL; |
|
114
|
|
|
|
|
|
|
} |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
TMPLPRO_LOCAL |
|
117
|
1028
|
|
|
|
|
|
PSTRING _get_variable_value (struct tmplpro_param *param, PSTRING name) { |
|
118
|
1028
|
|
|
|
|
|
PSTRING varvalue ={NULL, NULL}; |
|
119
|
|
|
|
|
|
|
ABSTRACT_VALUE* abstrval; |
|
120
|
1028
|
100
|
|
|
|
|
if (param->loop_context_vars) { |
|
121
|
768
|
|
|
|
|
|
varvalue=get_loop_context_vars_value(param, name); |
|
122
|
|
|
|
|
|
|
} |
|
123
|
1028
|
100
|
|
|
|
|
if (varvalue.begin==NULL) { |
|
124
|
857
|
|
|
|
|
|
abstrval=walk_through_nested_loops(param, name); |
|
125
|
857
|
100
|
|
|
|
|
if (abstrval!=NULL) varvalue=(param->AbstractVal2pstringFuncPtr)(param->ext_data_state, abstrval); |
|
126
|
|
|
|
|
|
|
} |
|
127
|
1028
|
50
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) { |
|
128
|
0
|
0
|
|
|
|
|
if (name.begin!=NULL) { |
|
129
|
0
|
|
|
|
|
|
tmpl_log(TMPL_LOG_DEBUG2,"_get_variable_value: name = %.*s ",(int)(name.endnext-name.begin),name.begin); |
|
130
|
|
|
|
|
|
|
} else { |
|
131
|
0
|
|
|
|
|
|
tmpl_log(TMPL_LOG_DEBUG2,"_get_variable_value: name = NULL "); |
|
132
|
|
|
|
|
|
|
} |
|
133
|
0
|
0
|
|
|
|
|
if (varvalue.begin!=NULL) { |
|
134
|
0
|
|
|
|
|
|
tmpl_log(TMPL_LOG_DEBUG2,"value = %.*s\n",(int)(varvalue.endnext-varvalue.begin),varvalue.begin); |
|
135
|
|
|
|
|
|
|
} else { |
|
136
|
0
|
|
|
|
|
|
tmpl_log(TMPL_LOG_DEBUG2,"value = UNDEF\n"); |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
} |
|
139
|
1028
|
|
|
|
|
|
return varvalue; |
|
140
|
|
|
|
|
|
|
} |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
static |
|
143
|
1141
|
|
|
|
|
|
PSTRING get_variable_option (struct tmplpro_state *state, const PSTRING* const TagOptVal) { |
|
144
|
1141
|
|
|
|
|
|
PSTRING varvalue ={NULL, NULL}; |
|
145
|
1141
|
|
|
|
|
|
PSTRING defvalue = TagOptVal[TAG_OPT_DEFAULT]; |
|
146
|
1141
|
100
|
|
|
|
|
if (TagOptVal[TAG_OPT_EXPR].begin!=NULL) { |
|
147
|
477
|
|
|
|
|
|
varvalue=parse_expr(TagOptVal[TAG_OPT_EXPR], state); |
|
148
|
|
|
|
|
|
|
} else { |
|
149
|
664
|
|
|
|
|
|
varvalue=_get_variable_value(state->param, TagOptVal[TAG_OPT_NAME]); |
|
150
|
|
|
|
|
|
|
} |
|
151
|
1141
|
100
|
|
|
|
|
if (varvalue.begin==NULL) { |
|
152
|
120
|
100
|
|
|
|
|
if (defvalue.begin!=defvalue.endnext) { |
|
153
|
27
|
|
|
|
|
|
varvalue=defvalue; |
|
154
|
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
} |
|
156
|
1141
|
|
|
|
|
|
return varvalue; |
|
157
|
|
|
|
|
|
|
} |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
static |
|
161
|
|
|
|
|
|
|
void |
|
162
|
1422
|
|
|
|
|
|
tag_handler_var (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
163
|
|
|
|
|
|
|
{ |
|
164
|
|
|
|
|
|
|
PSTRING varvalue; |
|
165
|
|
|
|
|
|
|
int escapeopt; |
|
166
|
|
|
|
|
|
|
/* |
|
167
|
|
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) { |
|
168
|
|
|
|
|
|
|
log_state(state,TMPL_LOG_DEBUG2,"Entered tag_handler_var\n"); |
|
169
|
|
|
|
|
|
|
}*/ |
|
170
|
1515
|
100
|
|
|
|
|
if (! state->is_visible) return; |
|
171
|
1141
|
|
|
|
|
|
varvalue = get_variable_option(state, TagOptVal); |
|
172
|
1141
|
|
|
|
|
|
escapeopt = get_escape_option(state,TagOptVal[TAG_OPT_ESCAPE]); |
|
173
|
1141
|
100
|
|
|
|
|
if (varvalue.begin==NULL) return; |
|
174
|
|
|
|
|
|
|
|
|
175
|
1048
|
100
|
|
|
|
|
if (escapeopt!=HTML_TEMPLATE_OPT_ESCAPE_NO) { |
|
176
|
94
|
|
|
|
|
|
varvalue=escape_pstring(&state->param->escape_pstring_buffer, varvalue, escapeopt); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
1048
|
|
|
|
|
|
(state->param->WriterFuncPtr)(state->param->ext_writer_state,varvalue.begin,varvalue.endnext); |
|
179
|
|
|
|
|
|
|
} |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
static |
|
182
|
|
|
|
|
|
|
void |
|
183
|
83
|
|
|
|
|
|
tag_handler_include (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
184
|
|
|
|
|
|
|
{ |
|
185
|
|
|
|
|
|
|
struct tmplpro_param* param; |
|
186
|
|
|
|
|
|
|
char* filename; |
|
187
|
|
|
|
|
|
|
int x; |
|
188
|
|
|
|
|
|
|
PSTRING varvalue; |
|
189
|
|
|
|
|
|
|
PSTRING defvalue; |
|
190
|
|
|
|
|
|
|
|
|
191
|
83
|
100
|
|
|
|
|
if (! state->is_visible) return; |
|
192
|
79
|
|
|
|
|
|
param=state->param; |
|
193
|
79
|
50
|
|
|
|
|
if (param->no_includes) { |
|
194
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR, "HTML::Template::Pro : Illegal attempt to use TMPL_INCLUDE in template file : (no_includes => 1)\n"); |
|
195
|
0
|
|
|
|
|
|
return; |
|
196
|
|
|
|
|
|
|
} |
|
197
|
79
|
50
|
|
|
|
|
if (param->max_includes && param->max_includes < param->cur_includes) { |
|
|
|
100
|
|
|
|
|
|
|
198
|
2
|
|
|
|
|
|
log_state(state,TMPL_LOG_INFO, "HTML::Template::Pro : TMPL_INCLUDE: max_includes exceeded.\n"); |
|
199
|
2
|
|
|
|
|
|
return; |
|
200
|
|
|
|
|
|
|
} |
|
201
|
77
|
|
|
|
|
|
param->cur_includes++; |
|
202
|
|
|
|
|
|
|
|
|
203
|
77
|
|
|
|
|
|
varvalue=TagOptVal[TAG_OPT_NAME]; |
|
204
|
77
|
|
|
|
|
|
defvalue = TagOptVal[TAG_OPT_DEFAULT]; |
|
205
|
|
|
|
|
|
|
|
|
206
|
77
|
100
|
|
|
|
|
if (TagOptVal[TAG_OPT_EXPR].begin!=NULL) { |
|
207
|
4
|
|
|
|
|
|
varvalue=parse_expr(TagOptVal[TAG_OPT_EXPR], state); |
|
208
|
|
|
|
|
|
|
}; |
|
209
|
77
|
50
|
|
|
|
|
if (varvalue.begin==varvalue.endnext && defvalue.begin!=defvalue.endnext) varvalue=defvalue; |
|
|
|
0
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
/* pstrdup */ |
|
211
|
|
|
|
|
|
|
{ |
|
212
|
77
|
|
|
|
|
|
const long len = varvalue.endnext-varvalue.begin; |
|
213
|
77
|
|
|
|
|
|
filename =(char*) malloc(len+1); |
|
214
|
1138
|
100
|
|
|
|
|
for (x=0;x
|
|
215
|
1061
|
|
|
|
|
|
*(filename+x)=*(varvalue.begin+x); |
|
216
|
|
|
|
|
|
|
} |
|
217
|
77
|
|
|
|
|
|
*(filename+len)=0; |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
/* end pstrdup */ |
|
220
|
77
|
|
|
|
|
|
tmplpro_exec_tmpl_filename (param,filename); |
|
221
|
77
|
|
|
|
|
|
free (filename); |
|
222
|
77
|
|
|
|
|
|
param->cur_includes--; |
|
223
|
83
|
|
|
|
|
|
return; |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
static |
|
227
|
|
|
|
|
|
|
int |
|
228
|
506
|
|
|
|
|
|
is_var_true(struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
229
|
|
|
|
|
|
|
{ |
|
230
|
506
|
|
|
|
|
|
register int ifval=-1; /*not yet defined*/ |
|
231
|
506
|
100
|
|
|
|
|
if (TagOptVal[TAG_OPT_EXPR].begin!=NULL) { |
|
232
|
|
|
|
|
|
|
/* |
|
233
|
|
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) { |
|
234
|
|
|
|
|
|
|
tmpl_log(TMPL_LOG_DEBUG2,"is_var_true: expr = %.*s\n",(int)(TagOptVal[TAG_OPT_EXPR].endnext-TagOptVal[TAG_OPT_EXPR].begin),TagOptVal[TAG_OPT_EXPR].begin); |
|
235
|
|
|
|
|
|
|
}*/ |
|
236
|
70
|
|
|
|
|
|
ifval=is_pstring_true(parse_expr(TagOptVal[TAG_OPT_EXPR], state)); |
|
237
|
|
|
|
|
|
|
} else |
|
238
|
436
|
100
|
|
|
|
|
if (state->param->loop_context_vars) { |
|
239
|
220
|
|
|
|
|
|
PSTRING loop_var=get_loop_context_vars_value(state->param, TagOptVal[TAG_OPT_NAME]); |
|
240
|
220
|
100
|
|
|
|
|
if (loop_var.begin!=NULL) { |
|
241
|
220
|
|
|
|
|
|
ifval=is_pstring_true(loop_var); |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
} |
|
244
|
506
|
100
|
|
|
|
|
if (ifval==-1) { |
|
245
|
|
|
|
|
|
|
is_ABSTRACT_VALUE_true_functype userSuppliedIsTrueFunc; |
|
246
|
416
|
|
|
|
|
|
ABSTRACT_VALUE* abstrval=walk_through_nested_loops(state->param, TagOptVal[TAG_OPT_NAME]); |
|
247
|
416
|
100
|
|
|
|
|
if (abstrval==NULL) return 0; |
|
248
|
304
|
|
|
|
|
|
userSuppliedIsTrueFunc = state->param->IsAbstractValTrueFuncPtr; |
|
249
|
304
|
50
|
|
|
|
|
if (userSuppliedIsTrueFunc!=NULL) { |
|
250
|
304
|
|
|
|
|
|
ifval=(userSuppliedIsTrueFunc)(state->param->ext_data_state, abstrval); |
|
251
|
|
|
|
|
|
|
} else { |
|
252
|
0
|
|
|
|
|
|
ifval=is_pstring_true((state->param->AbstractVal2pstringFuncPtr)(state->param->ext_data_state, abstrval)); |
|
253
|
|
|
|
|
|
|
} |
|
254
|
|
|
|
|
|
|
} |
|
255
|
394
|
|
|
|
|
|
return ifval; |
|
256
|
|
|
|
|
|
|
} |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
static |
|
259
|
|
|
|
|
|
|
void |
|
260
|
502
|
|
|
|
|
|
tag_handler_if (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
261
|
|
|
|
|
|
|
{ |
|
262
|
|
|
|
|
|
|
struct tagstack_entry iftag; |
|
263
|
502
|
|
|
|
|
|
iftag.tag=HTML_TEMPLATE_TAG_IF; |
|
264
|
502
|
|
|
|
|
|
iftag.vcontext=state->is_visible; |
|
265
|
502
|
|
|
|
|
|
iftag.position=state->cur_pos; /* unused */ |
|
266
|
|
|
|
|
|
|
/* state->is_visible && means that we do not evaluate variable in shadow */ |
|
267
|
502
|
100
|
|
|
|
|
if (state->is_visible && is_var_true(state,TagOptVal)) { |
|
|
|
100
|
|
|
|
|
|
|
268
|
230
|
|
|
|
|
|
iftag.value=1; |
|
269
|
|
|
|
|
|
|
/* state->is_visible is not touched */ |
|
270
|
|
|
|
|
|
|
} else { |
|
271
|
272
|
|
|
|
|
|
iftag.value=0; |
|
272
|
272
|
|
|
|
|
|
state->is_visible=0; |
|
273
|
|
|
|
|
|
|
} |
|
274
|
502
|
|
|
|
|
|
tagstack_push(&(state->tag_stack), iftag); |
|
275
|
502
|
50
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"tag_handler_if:visible context =%d value=%d ",iftag.vcontext,iftag.value); |
|
276
|
502
|
|
|
|
|
|
} |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
static |
|
279
|
|
|
|
|
|
|
void |
|
280
|
50
|
|
|
|
|
|
tag_handler_unless (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
281
|
|
|
|
|
|
|
{ |
|
282
|
|
|
|
|
|
|
struct tagstack_entry iftag; |
|
283
|
50
|
|
|
|
|
|
iftag.tag=HTML_TEMPLATE_TAG_UNLESS; |
|
284
|
50
|
|
|
|
|
|
iftag.vcontext=state->is_visible; |
|
285
|
50
|
|
|
|
|
|
iftag.position=state->cur_pos; /* unused */ |
|
286
|
|
|
|
|
|
|
/* state->is_visible && means that we do not evaluate variable in shadow */ |
|
287
|
50
|
100
|
|
|
|
|
if (state->is_visible && !is_var_true(state,TagOptVal)) { |
|
|
|
100
|
|
|
|
|
|
|
288
|
29
|
|
|
|
|
|
iftag.value=1; |
|
289
|
|
|
|
|
|
|
/* state->is_visible is not touched */ |
|
290
|
|
|
|
|
|
|
} else { |
|
291
|
21
|
|
|
|
|
|
iftag.value=0; |
|
292
|
21
|
|
|
|
|
|
state->is_visible=0; |
|
293
|
|
|
|
|
|
|
} |
|
294
|
50
|
|
|
|
|
|
tagstack_push(&(state->tag_stack), iftag); |
|
295
|
50
|
50
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"tag_handler_unless:visible context =%d value=%d ",iftag.vcontext,iftag.value); |
|
296
|
50
|
|
|
|
|
|
} |
|
297
|
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
static |
|
299
|
|
|
|
|
|
|
INLINE |
|
300
|
|
|
|
|
|
|
int |
|
301
|
1212
|
|
|
|
|
|
test_stack (int tag) |
|
302
|
|
|
|
|
|
|
{ |
|
303
|
|
|
|
|
|
|
// return (tagstack_notempty(&(state->tag_stack)) && (tagstack_top(&(state->tag_stack))->tag==tag)); |
|
304
|
1212
|
|
|
|
|
|
return 1; |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
static |
|
308
|
|
|
|
|
|
|
void |
|
309
|
0
|
|
|
|
|
|
tag_stack_debug (struct tmplpro_state *state, int stack_tag_type) |
|
310
|
|
|
|
|
|
|
{ |
|
311
|
0
|
0
|
|
|
|
|
if (stack_tag_type) { |
|
312
|
0
|
0
|
|
|
|
|
if (tagstack_notempty(&(state->tag_stack))) { |
|
313
|
0
|
|
|
|
|
|
struct tagstack_entry* iftag=tagstack_top(&(state->tag_stack)); |
|
314
|
0
|
0
|
|
|
|
|
if (iftag->tag!=stack_tag_type) { |
|
315
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR, "ERROR: tag mismatch with %s\n",TAGNAME[iftag->tag]); |
|
316
|
|
|
|
|
|
|
} |
|
317
|
|
|
|
|
|
|
} else { |
|
318
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR, "ERROR: opening tag %s not found\n",TAGNAME[stack_tag_type]); |
|
319
|
|
|
|
|
|
|
} |
|
320
|
|
|
|
|
|
|
} |
|
321
|
0
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
static |
|
324
|
678
|
|
|
|
|
|
struct tagstack_entry tagstack_smart_pop(struct tmplpro_state *state) |
|
325
|
|
|
|
|
|
|
{ |
|
326
|
678
|
|
|
|
|
|
int is_underflow=0; |
|
327
|
678
|
|
|
|
|
|
struct tagstack_entry curtag=tagstack_pop(&(state->tag_stack), &is_underflow); |
|
328
|
678
|
100
|
|
|
|
|
if (is_underflow) { |
|
329
|
1
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR,"stack underflow:tag stack is empty. Cased by closing tag w/o matching opening tag.\n"); |
|
330
|
|
|
|
|
|
|
} |
|
331
|
678
|
|
|
|
|
|
return curtag; |
|
332
|
|
|
|
|
|
|
} |
|
333
|
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
static |
|
335
|
|
|
|
|
|
|
void |
|
336
|
506
|
|
|
|
|
|
tag_handler_closeif (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
337
|
|
|
|
|
|
|
{ |
|
338
|
|
|
|
|
|
|
struct tagstack_entry iftag; |
|
339
|
506
|
50
|
|
|
|
|
if (! test_stack(HTML_TEMPLATE_TAG_IF)) { |
|
340
|
0
|
|
|
|
|
|
tag_stack_debug(state,HTML_TEMPLATE_TAG_IF); |
|
341
|
0
|
|
|
|
|
|
return; |
|
342
|
|
|
|
|
|
|
} |
|
343
|
506
|
|
|
|
|
|
iftag=tagstack_smart_pop(state); |
|
344
|
506
|
100
|
|
|
|
|
if (0==state->is_visible) state->last_processed_pos=state->cur_pos; |
|
345
|
506
|
|
|
|
|
|
state->is_visible=iftag.vcontext; |
|
346
|
|
|
|
|
|
|
} |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
static |
|
349
|
|
|
|
|
|
|
void |
|
350
|
46
|
|
|
|
|
|
tag_handler_closeunless (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
351
|
|
|
|
|
|
|
{ |
|
352
|
|
|
|
|
|
|
struct tagstack_entry iftag; |
|
353
|
46
|
50
|
|
|
|
|
if (! test_stack(HTML_TEMPLATE_TAG_UNLESS)) { |
|
354
|
0
|
|
|
|
|
|
tag_stack_debug(state,HTML_TEMPLATE_TAG_UNLESS); |
|
355
|
0
|
|
|
|
|
|
return; |
|
356
|
|
|
|
|
|
|
} |
|
357
|
46
|
|
|
|
|
|
iftag=tagstack_smart_pop(state); |
|
358
|
46
|
100
|
|
|
|
|
if (0==state->is_visible) state->last_processed_pos=state->cur_pos; |
|
359
|
46
|
|
|
|
|
|
state->is_visible=iftag.vcontext; |
|
360
|
|
|
|
|
|
|
} |
|
361
|
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
static |
|
363
|
|
|
|
|
|
|
void |
|
364
|
406
|
|
|
|
|
|
tag_handler_else (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
365
|
|
|
|
|
|
|
{ |
|
366
|
|
|
|
|
|
|
struct tagstack_entry* iftag; |
|
367
|
406
|
|
|
|
|
|
if (! test_stack(HTML_TEMPLATE_TAG_IF) && |
|
368
|
0
|
|
|
|
|
|
! test_stack(HTML_TEMPLATE_TAG_UNLESS)) { |
|
369
|
0
|
|
|
|
|
|
tag_stack_debug(state,HTML_TEMPLATE_TAG_ELSE); |
|
370
|
0
|
|
|
|
|
|
return; |
|
371
|
|
|
|
|
|
|
} |
|
372
|
406
|
|
|
|
|
|
iftag=tagstack_top(&(state->tag_stack)); |
|
373
|
406
|
100
|
|
|
|
|
if (0==state->is_visible) state->last_processed_pos=state->cur_pos; |
|
374
|
406
|
100
|
|
|
|
|
if (iftag->value) { |
|
375
|
188
|
|
|
|
|
|
state->is_visible=0; |
|
376
|
218
|
100
|
|
|
|
|
} else if (1==iftag->vcontext) { |
|
377
|
192
|
|
|
|
|
|
state->is_visible=1; |
|
378
|
|
|
|
|
|
|
} |
|
379
|
406
|
50
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"else:(pos " MOD_TD ") visible:context =%d, set to %d ", |
|
380
|
0
|
|
|
|
|
|
TO_PTRDIFF_T(iftag->position - state->top),iftag->vcontext,state->is_visible); |
|
381
|
|
|
|
|
|
|
} |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
static |
|
384
|
|
|
|
|
|
|
void |
|
385
|
8
|
|
|
|
|
|
tag_handler_elsif (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
386
|
|
|
|
|
|
|
{ |
|
387
|
|
|
|
|
|
|
struct tagstack_entry *iftag; |
|
388
|
8
|
|
|
|
|
|
if (! test_stack(HTML_TEMPLATE_TAG_IF) && |
|
389
|
0
|
|
|
|
|
|
! test_stack(HTML_TEMPLATE_TAG_UNLESS)) { |
|
390
|
0
|
|
|
|
|
|
tag_stack_debug(state,HTML_TEMPLATE_TAG_ELSIF); |
|
391
|
0
|
|
|
|
|
|
return; |
|
392
|
|
|
|
|
|
|
} |
|
393
|
8
|
|
|
|
|
|
iftag=tagstack_top(&(state->tag_stack)); |
|
394
|
8
|
100
|
|
|
|
|
if (0==state->is_visible) state->last_processed_pos=state->cur_pos; |
|
395
|
8
|
100
|
|
|
|
|
if (iftag->value) { |
|
396
|
4
|
|
|
|
|
|
state->is_visible=0; |
|
397
|
4
|
50
|
|
|
|
|
} else if (1==iftag->vcontext) { |
|
398
|
|
|
|
|
|
|
/* test only if vcontext==true; if the whole tag if..endif itself is invisible, skip the is_var_true test */ |
|
399
|
|
|
|
|
|
|
/*TODO: it is reasonable to skip is_var_true test in if/unless too */ |
|
400
|
4
|
50
|
|
|
|
|
if (is_var_true(state,TagOptVal)) { |
|
401
|
4
|
|
|
|
|
|
iftag->value=1; |
|
402
|
4
|
|
|
|
|
|
state->is_visible=1; |
|
403
|
|
|
|
|
|
|
} else { |
|
404
|
0
|
|
|
|
|
|
iftag->value=0; |
|
405
|
0
|
|
|
|
|
|
state->is_visible=0; |
|
406
|
|
|
|
|
|
|
} |
|
407
|
|
|
|
|
|
|
} |
|
408
|
8
|
50
|
|
|
|
|
if (debuglevel>=TMPL_LOG_DEBUG2) log_state(state,TMPL_LOG_DEBUG2,"elsif:(pos " MOD_TD ") visible:context =%d, set to %d ", |
|
409
|
0
|
|
|
|
|
|
TO_PTRDIFF_T(iftag->position - state->top), iftag->vcontext, state->is_visible); |
|
410
|
|
|
|
|
|
|
} |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
static |
|
413
|
|
|
|
|
|
|
int |
|
414
|
254
|
|
|
|
|
|
next_loop (struct tmplpro_state* state) { |
|
415
|
|
|
|
|
|
|
#ifdef DEBUG |
|
416
|
|
|
|
|
|
|
log_state(state,TMPL_LOG_DEBUG2,"next_loop:before NextLoopFuncPtr\n"); |
|
417
|
|
|
|
|
|
|
#endif |
|
418
|
254
|
|
|
|
|
|
struct ProScopeEntry* currentScope = getCurrentScope(&state->param->var_scope_stack); |
|
419
|
254
|
50
|
|
|
|
|
if (!isScopeLoop(currentScope)) { |
|
420
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR, "next_loop:at scope level %d: internal error - loop is null\n", curScopeLevel(&state->param->var_scope_stack)); |
|
421
|
0
|
|
|
|
|
|
return 0; |
|
422
|
|
|
|
|
|
|
} |
|
423
|
254
|
100
|
|
|
|
|
if (++currentScope->loop < currentScope->loop_count || currentScope->loop_count< 0) { |
|
|
|
50
|
|
|
|
|
|
|
424
|
187
|
|
|
|
|
|
ABSTRACT_MAP* arrayvalptr=(state->param->GetAbstractMapFuncPtr)(state->param->ext_data_state, currentScope->loops_AV,currentScope->loop); |
|
425
|
187
|
50
|
|
|
|
|
if ((arrayvalptr!=NULL)) { |
|
426
|
187
|
|
|
|
|
|
currentScope->param_HV=arrayvalptr; |
|
427
|
187
|
|
|
|
|
|
return 1; |
|
428
|
|
|
|
|
|
|
} else { |
|
429
|
|
|
|
|
|
|
/* either undefined loop ended normally or defined loop ended ubnormally */ |
|
430
|
0
|
0
|
|
|
|
|
if (currentScope->loop_count>0) log_state(state,TMPL_LOG_ERROR, "PARAM:LOOP:next_loop(%d): callback returned null scope\n", currentScope->loop); |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
} |
|
433
|
67
|
50
|
|
|
|
|
if (state->param->ExitLoopScopeFuncPtr) state->param->ExitLoopScopeFuncPtr(state->param->ext_data_state, currentScope->loops_AV); |
|
434
|
67
|
|
|
|
|
|
popScope(&state->param->var_scope_stack); |
|
435
|
67
|
|
|
|
|
|
return 0; |
|
436
|
|
|
|
|
|
|
} |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
static |
|
439
|
121
|
|
|
|
|
|
int init_loop (struct tmplpro_state *state, const PSTRING* const TagOptVal) { |
|
440
|
|
|
|
|
|
|
int loop_count; |
|
441
|
121
|
|
|
|
|
|
ABSTRACT_ARRAY* loopptr=(ABSTRACT_ARRAY*) walk_through_nested_loops(state->param,TagOptVal[TAG_OPT_NAME]); |
|
442
|
121
|
100
|
|
|
|
|
if (loopptr==NULL) { |
|
443
|
46
|
|
|
|
|
|
return 0; |
|
444
|
|
|
|
|
|
|
} else { |
|
445
|
|
|
|
|
|
|
/* set loop array */ |
|
446
|
75
|
|
|
|
|
|
loopptr = (*state->param->AbstractVal2abstractArrayFuncPtr)(state->param->ext_data_state, loopptr); |
|
447
|
75
|
50
|
|
|
|
|
if (loopptr == NULL) |
|
448
|
|
|
|
|
|
|
{ |
|
449
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR, "PARAM:LOOP:loop argument:loop was expected but not found.\n"); |
|
450
|
0
|
|
|
|
|
|
return 0; |
|
451
|
|
|
|
|
|
|
} |
|
452
|
75
|
|
|
|
|
|
loop_count = (*state->param->GetAbstractArrayLengthFuncPtr)(state->param->ext_data_state, loopptr); |
|
453
|
|
|
|
|
|
|
/* 0 is an empty array; <0 is an undefined array (iterated until next_loop==NULL */ |
|
454
|
75
|
100
|
|
|
|
|
if (0==loop_count) return 0; |
|
455
|
67
|
|
|
|
|
|
pushScopeLoop(&state->param->var_scope_stack, loop_count, loopptr); |
|
456
|
67
|
|
|
|
|
|
return 1; |
|
457
|
|
|
|
|
|
|
} |
|
458
|
|
|
|
|
|
|
} |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
static |
|
461
|
|
|
|
|
|
|
void |
|
462
|
126
|
|
|
|
|
|
tag_handler_loop (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
463
|
|
|
|
|
|
|
{ |
|
464
|
|
|
|
|
|
|
struct tagstack_entry iftag; |
|
465
|
126
|
|
|
|
|
|
iftag.tag=HTML_TEMPLATE_TAG_LOOP; |
|
466
|
126
|
|
|
|
|
|
iftag.vcontext=state->is_visible; |
|
467
|
126
|
|
|
|
|
|
iftag.value=0; |
|
468
|
126
|
|
|
|
|
|
iftag.position=state->cur_pos; /* loop start - to restore in */ |
|
469
|
|
|
|
|
|
|
#ifdef DEBUG |
|
470
|
|
|
|
|
|
|
log_state(state,TMPL_LOG_DEBUG2,"tag_handler_loop:before InitLoopFuncPtr\n"); |
|
471
|
|
|
|
|
|
|
#endif |
|
472
|
126
|
100
|
|
|
|
|
if (state->is_visible && init_loop(state,TagOptVal) && next_loop(state)) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
473
|
67
|
|
|
|
|
|
iftag.value=1; /* the loop is non - empty */ |
|
474
|
|
|
|
|
|
|
} else { |
|
475
|
|
|
|
|
|
|
/* empty loop is equal to ... */ |
|
476
|
59
|
|
|
|
|
|
state->is_visible=0; |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
#ifdef DEBUG |
|
479
|
|
|
|
|
|
|
log_state(state,TMPL_LOG_DEBUG2,"tag_handler_loop:after InitLoopFuncPtr\n"); |
|
480
|
|
|
|
|
|
|
#endif |
|
481
|
126
|
|
|
|
|
|
tagstack_push(&(state->tag_stack), iftag); |
|
482
|
126
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
static |
|
485
|
|
|
|
|
|
|
void |
|
486
|
246
|
|
|
|
|
|
tag_handler_closeloop (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
487
|
|
|
|
|
|
|
{ |
|
488
|
|
|
|
|
|
|
struct tagstack_entry* iftag_ptr; |
|
489
|
246
|
50
|
|
|
|
|
if (! test_stack(HTML_TEMPLATE_TAG_LOOP)) { |
|
490
|
0
|
|
|
|
|
|
tag_stack_debug(state,HTML_TEMPLATE_TAG_LOOP); |
|
491
|
0
|
|
|
|
|
|
return; |
|
492
|
|
|
|
|
|
|
} |
|
493
|
246
|
|
|
|
|
|
iftag_ptr=tagstack_top(&(state->tag_stack)); |
|
494
|
246
|
100
|
|
|
|
|
if (iftag_ptr->value==1 && next_loop(state)) { |
|
|
|
100
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
/* continue loop */ |
|
496
|
120
|
|
|
|
|
|
state->cur_pos=iftag_ptr->position; |
|
497
|
120
|
|
|
|
|
|
state->last_processed_pos=iftag_ptr->position; |
|
498
|
120
|
|
|
|
|
|
return; |
|
499
|
|
|
|
|
|
|
} else { |
|
500
|
|
|
|
|
|
|
/* finish loop */ |
|
501
|
|
|
|
|
|
|
struct tagstack_entry iftag; |
|
502
|
126
|
|
|
|
|
|
iftag=tagstack_smart_pop(state); |
|
503
|
126
|
|
|
|
|
|
state->is_visible=iftag.vcontext; |
|
504
|
126
|
|
|
|
|
|
state->last_processed_pos=state->cur_pos; |
|
505
|
|
|
|
|
|
|
} |
|
506
|
|
|
|
|
|
|
} |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
static |
|
509
|
|
|
|
|
|
|
void |
|
510
|
0
|
|
|
|
|
|
tag_handler_unknown (struct tmplpro_state *state, const PSTRING* const TagOptVal) |
|
511
|
|
|
|
|
|
|
{ |
|
512
|
0
|
|
|
|
|
|
log_state(state,TMPL_LOG_ERROR,"tag_handler_unknown: unknown tag\n"); |
|
513
|
0
|
|
|
|
|
|
} |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
/* |
|
516
|
|
|
|
|
|
|
* Local Variables: |
|
517
|
|
|
|
|
|
|
* mode: c |
|
518
|
|
|
|
|
|
|
* End: |
|
519
|
|
|
|
|
|
|
*/ |