Commit d9c914e9 authored by Rob Pike's avatar Rob Pike

dotted names

R=rsc
DELTA=28  (19 added, 0 deleted, 9 changed)
OCL=32550
CL=32554
parent 90e6656c
...@@ -33,8 +33,8 @@ const debugText = ...@@ -33,8 +33,8 @@ const debugText =
<th align=center>Method</th><th align=center>Calls</th> <th align=center>Method</th><th align=center>Calls</th>
{.repeated section meth} {.repeated section meth}
<tr> <tr>
<td align=left font=fixed>{name}({.section m}{argType}, {replyType}) os.Error</td> <td align=left font=fixed>{name}({m.argType}, {m.replyType}) os.Error</td>
<td align=center>{numCalls}</td>{.end} <td align=center>{m.numCalls}</td>
</tr> </tr>
{.end} {.end}
</table> </table>
......
...@@ -563,19 +563,27 @@ func (t *Template) parse() { ...@@ -563,19 +563,27 @@ func (t *Template) parse() {
// -- Execution // -- Execution
// If the data for this template is a struct, find the named variable. // If the data for this template is a struct, find the named variable.
// Names of the form a.b.c are walked down the data tree.
// The special name "@" (the "cursor") denotes the current data. // The special name "@" (the "cursor") denotes the current data.
func (st *state) findVar(s string) reflect.Value { func (st *state) findVar(s string) reflect.Value {
if s == "@" { if s == "@" {
return st.data return st.data
} }
data := reflect.Indirect(st.data); data := reflect.Indirect(st.data);
typ, ok := data.Type().(*reflect.StructType); elems := strings.Split(s, ".", 0);
if ok { for i := 0; i < len(elems); i++ {
if field, ok := typ.FieldByName(s); ok { // Look up field; data must be a struct.
return data.(*reflect.StructValue).Field(field.Index) typ, ok := data.Type().(*reflect.StructType);
if !ok {
return nil
} }
field, ok := typ.FieldByName(elems[i]);
if !ok {
return nil
}
data = reflect.Indirect(data.(*reflect.StructValue).Field(field.Index));
} }
return nil return data
} }
// Is there no data to look at? // Is there no data to look at?
......
...@@ -27,6 +27,7 @@ type S struct { ...@@ -27,6 +27,7 @@ type S struct {
header string; header string;
integer int; integer int;
raw string; raw string;
innerT T;
data []T; data []T;
pdata []*T; pdata []*T;
empty []*T; empty []*T;
...@@ -199,6 +200,15 @@ var tests = []*Test { ...@@ -199,6 +200,15 @@ var tests = []*Test {
"ItemNumber2=ValueNumber2\n" "ItemNumber2=ValueNumber2\n"
}, },
// Nested names
&Test{
"{.section @ }\n"
"{innerT.item}={innerT.value}\n"
"{.end}",
"ItemNumber1=ValueNumber1\n"
},
// Formatters // Formatters
&Test{ &Test{
"{.section pdata }\n" "{.section pdata }\n"
...@@ -232,6 +242,7 @@ func TestAll(t *testing.T) { ...@@ -232,6 +242,7 @@ func TestAll(t *testing.T) {
s.header = "Header"; s.header = "Header";
s.integer = 77; s.integer = 77;
s.raw = "&<>!@ #$%^"; s.raw = "&<>!@ #$%^";
s.innerT = t1;
s.data = []T{ t1, t2 }; s.data = []T{ t1, t2 };
s.pdata = []*T{ &t1, &t2 }; s.pdata = []*T{ &t1, &t2 };
s.empty = []*T{ }; s.empty = []*T{ };
......
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