mirror of
https://github.com/golang/go.git
synced 2025-05-16 12:54:37 +00:00
implement .alternates
R=rsc OCL=27928 CL=27928
This commit is contained in:
parent
eb5eea9a8f
commit
bd3b2f843f
@ -36,7 +36,6 @@
|
||||
is executed for each element. If the array is nil or empty,
|
||||
YYY is executed instead. If the {.alternates with} marker
|
||||
is present, ZZZ is executed between iterations of XXX.
|
||||
(TODO(r): .alternates is not yet implemented)
|
||||
|
||||
{field}
|
||||
{field|formatter}
|
||||
@ -132,9 +131,11 @@ type sectionElement struct {
|
||||
end int; // one beyond last element
|
||||
}
|
||||
|
||||
// A .repeated block, possibly with a .or. TODO(r): .alternates
|
||||
// A .repeated block, possibly with a .or and a .alternates
|
||||
type repeatedElement struct {
|
||||
sectionElement; // It has the same structure!
|
||||
sectionElement; // It has the same structure...
|
||||
altstart int; // ... except for alternates
|
||||
altend int;
|
||||
}
|
||||
|
||||
// Template is the type that represents a template definition.
|
||||
@ -438,6 +439,8 @@ func (t *Template) parseRepeated(words []string) *repeatedElement {
|
||||
// Scan section, collecting true and false (.or) blocks.
|
||||
r.start = t.elems.Len();
|
||||
r.or = -1;
|
||||
r.altstart = -1;
|
||||
r.altend = -1;
|
||||
Loop:
|
||||
for {
|
||||
item := t.nextItem();
|
||||
@ -455,17 +458,27 @@ Loop:
|
||||
if r.or >= 0 {
|
||||
t.parseError("extra .or in .repeated section");
|
||||
}
|
||||
r.altend = t.elems.Len();
|
||||
r.or = t.elems.Len();
|
||||
case tokSection:
|
||||
t.parseSection(w);
|
||||
case tokRepeated:
|
||||
t.parseRepeated(w);
|
||||
case tokAlternates:
|
||||
t.parseError("internal error: .alternates not implemented");
|
||||
if r.altstart >= 0 {
|
||||
t.parseError("extra .alternates in .repeated section");
|
||||
}
|
||||
if r.or >= 0 {
|
||||
t.parseError(".alternates inside .or block in .repeated section");
|
||||
}
|
||||
r.altstart = t.elems.Len();
|
||||
default:
|
||||
t.parseError("internal error: unknown repeated section item: %s", item);
|
||||
}
|
||||
}
|
||||
if r.altend < 0 {
|
||||
r.altend = t.elems.Len()
|
||||
}
|
||||
r.end = t.elems.Len();
|
||||
return r;
|
||||
}
|
||||
@ -693,6 +706,9 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
|
||||
if end < 0 {
|
||||
end = r.end
|
||||
}
|
||||
if r.altstart >= 0 {
|
||||
end = r.altstart
|
||||
}
|
||||
if field != nil {
|
||||
array := field.(reflect.ArrayValue);
|
||||
for j := 0; j < array.Len(); j++ {
|
||||
@ -700,6 +716,12 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
|
||||
for i := start; i < end; {
|
||||
i = t.executeElement(i, newst)
|
||||
}
|
||||
// If appropriate, do .alternates between elements
|
||||
if j < array.Len() - 1 && r.altstart >= 0 {
|
||||
for i := r.altstart; i < r.altend; i++ {
|
||||
i = t.executeElement(i, newst)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,6 +183,20 @@ var tests = []*Test {
|
||||
|
||||
"this should appear: empty field\n"
|
||||
},
|
||||
&Test{
|
||||
"{.section pdata }\n"
|
||||
"{.repeated section @ }\n"
|
||||
"{item}={value}\n"
|
||||
"{.alternates with}DIVIDER\n"
|
||||
"{.or}\n"
|
||||
"this should not appear\n"
|
||||
"{.end}\n"
|
||||
"{.end}\n",
|
||||
|
||||
"ItemNumber1=ValueNumber1\n"
|
||||
"DIVIDER\n"
|
||||
"ItemNumber2=ValueNumber2\n"
|
||||
},
|
||||
|
||||
// Formatters
|
||||
&Test{
|
||||
|
Loading…
x
Reference in New Issue
Block a user