static
const char* const innerloopname[]={
"", "first__", "last__", "inner__", "odd__", "counter__"
};
static
const char* const INNERLOOPNAME[]={
"", "FIRST__", "LAST__", "INNER__", "ODD__", "COUNTER__"
};
#define HTML_TEMPLATE_INNER_LOOP_VAR_FIRST 1
#define HTML_TEMPLATE_INNER_LOOP_VAR_LAST 2
#define HTML_TEMPLATE_INNER_LOOP_VAR_INNER 3
#define HTML_TEMPLATE_INNER_LOOP_VAR_ODD 4
#define HTML_TEMPLATE_INNER_LOOP_VAR_COUNTER 5
#define HTML_TEMPLATE_FIRST_INNER_LOOP 1
#define HTML_TEMPLATE_LAST_INNER_LOOP 5
static
int
try_inner_loop_variable (PSTRING name)
{
int i;
const char* cur_pos;
const char* pattern;
const char* PATTERN;
for (i=HTML_TEMPLATE_FIRST_INNER_LOOP; i<=HTML_TEMPLATE_LAST_INNER_LOOP; i++) {
cur_pos=name.begin;
pattern=innerloopname[i];
PATTERN=INNERLOOPNAME[i];
while (*pattern && cur_pos<name.endnext) {
if (*pattern == *cur_pos || *PATTERN == *cur_pos) {
pattern++;
PATTERN++;
cur_pos++;
} else {
break;
}
}
if (cur_pos==name.endnext) {
return i;
}
}
return 0;
}
static
PSTRING
get_loop_context_vars_value (struct tmplpro_param *param, PSTRING name) {
static const char* const FalseString="0";
static const char* const TrueString ="1";
int loop;
PSTRING retval={NULL,NULL};
const struct ProScopeEntry* const currentScope = getCurrentScope(¶m->var_scope_stack);
if (isScopeLoop(currentScope)
&& name.endnext-name.begin>4
&& '_'==*(name.begin)
&& '_'==*(name.begin+1)
) {
/* we can meet loop variables here -- try it first */
/* length of its name >4 */
/* __first__ __last__ __inner__ __odd__ __counter__ */
PSTRING shiftedname; /* (PSTRING) {name.begin+2,name.endnext} */
shiftedname.begin=name.begin+2;
shiftedname.endnext=name.endnext;
switch (try_inner_loop_variable(shiftedname)) {
case 0: break;
case HTML_TEMPLATE_INNER_LOOP_VAR_FIRST:
if (currentScope->loop==0) { /* first__ */
retval.begin=TrueString; retval.endnext=TrueString+1;
} else {
retval.begin=FalseString; retval.endnext=FalseString+1;
}; break;
case HTML_TEMPLATE_INNER_LOOP_VAR_LAST:
if (currentScope->loop==(currentScope->loop_count-1)) {
retval.begin=TrueString; retval.endnext=TrueString+1;
} else {
retval.begin=FalseString; retval.endnext=FalseString+1;
}; break;
case HTML_TEMPLATE_INNER_LOOP_VAR_ODD:
if ((currentScope->loop%2)==0) {
retval.begin=TrueString; retval.endnext=TrueString+1;
} else {
retval.begin=FalseString; retval.endnext=FalseString+1;
}; break;
case HTML_TEMPLATE_INNER_LOOP_VAR_INNER:
if (currentScope->loop>0 &&
(currentScope->loop_count<0 /* loop_count < 0 if number of loops is unknown/undefined */
|| currentScope->loop < (currentScope->loop_count-1))) {
retval.begin=TrueString; retval.endnext=TrueString+1;
} else {
retval.begin=FalseString; retval.endnext=FalseString+1;
}; break;
case HTML_TEMPLATE_INNER_LOOP_VAR_COUNTER:
{
char* const buffer = param->loopvarbuf;
loop=currentScope->loop+1;
snprintf(buffer,sizeof(param->loopvarbuf),"%d",loop);
retval.begin=buffer; retval.endnext=buffer+strlen(buffer);
}
break;
}
}
return retval;
}
/*
* Local Variables:
* mode: c
* End:
*/