Commit bd3b2f84 authored by Rob Pike's avatar Rob Pike

implement .alternates

R=rsc
OCL=27928
CL=27928
parent eb5eea9a
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
is executed for each element. If the array is nil or empty, is executed for each element. If the array is nil or empty,
YYY is executed instead. If the {.alternates with} marker YYY is executed instead. If the {.alternates with} marker
is present, ZZZ is executed between iterations of XXX. is present, ZZZ is executed between iterations of XXX.
(TODO(r): .alternates is not yet implemented)
{field} {field}
{field|formatter} {field|formatter}
...@@ -132,9 +131,11 @@ type sectionElement struct { ...@@ -132,9 +131,11 @@ type sectionElement struct {
end int; // one beyond last element 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 { 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. // Template is the type that represents a template definition.
...@@ -438,6 +439,8 @@ func (t *Template) parseRepeated(words []string) *repeatedElement { ...@@ -438,6 +439,8 @@ func (t *Template) parseRepeated(words []string) *repeatedElement {
// Scan section, collecting true and false (.or) blocks. // Scan section, collecting true and false (.or) blocks.
r.start = t.elems.Len(); r.start = t.elems.Len();
r.or = -1; r.or = -1;
r.altstart = -1;
r.altend = -1;
Loop: Loop:
for { for {
item := t.nextItem(); item := t.nextItem();
...@@ -455,17 +458,27 @@ Loop: ...@@ -455,17 +458,27 @@ Loop:
if r.or >= 0 { if r.or >= 0 {
t.parseError("extra .or in .repeated section"); t.parseError("extra .or in .repeated section");
} }
r.altend = t.elems.Len();
r.or = t.elems.Len(); r.or = t.elems.Len();
case tokSection: case tokSection:
t.parseSection(w); t.parseSection(w);
case tokRepeated: case tokRepeated:
t.parseRepeated(w); t.parseRepeated(w);
case tokAlternates: 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: default:
t.parseError("internal error: unknown repeated section item: %s", item); t.parseError("internal error: unknown repeated section item: %s", item);
} }
} }
if r.altend < 0 {
r.altend = t.elems.Len()
}
r.end = t.elems.Len(); r.end = t.elems.Len();
return r; return r;
} }
...@@ -693,6 +706,9 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) { ...@@ -693,6 +706,9 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
if end < 0 { if end < 0 {
end = r.end end = r.end
} }
if r.altstart >= 0 {
end = r.altstart
}
if field != nil { if field != nil {
array := field.(reflect.ArrayValue); array := field.(reflect.ArrayValue);
for j := 0; j < array.Len(); j++ { for j := 0; j < array.Len(); j++ {
...@@ -700,6 +716,12 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) { ...@@ -700,6 +716,12 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
for i := start; i < end; { for i := start; i < end; {
i = t.executeElement(i, newst) 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 { ...@@ -183,6 +183,20 @@ var tests = []*Test {
"this should appear: empty field\n" "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 // Formatters
&Test{ &Test{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment