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
|
227
|
|
|
|
|
|
iftag.value=1; |
269
|
|
|
|
|
|
|
/* state->is_visible is not touched */ |
270
|
|
|
|
|
|
|
} else { |
271
|
275
|
|
|
|
|
|
iftag.value=0; |
272
|
275
|
|
|
|
|
|
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
|
185
|
|
|
|
|
|
state->is_visible=0; |
376
|
221
|
100
|
|
|
|
|
} else if (1==iftag->vcontext) { |
377
|
195
|
|
|
|
|
|
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
|
|
|
|
|
|
|
*/ |