trim tags from type strings for structure fields.

R=rsc
DELTA=28  (14 added, 4 deleted, 10 changed)
OCL=18561
CL=18563
diff --git a/src/lib/reflect/test.go b/src/lib/reflect/test.go
index a260a8a..fa55c92 100644
--- a/src/lib/reflect/test.go
+++ b/src/lib/reflect/test.go
@@ -250,4 +250,10 @@
 	assert(t.String(), "chan<-string");
 	ct = t.(reflect.ChanType);
 	assert(ct.Elem().String(), "string");
+
+	// make sure tag strings are not part of element type
+	t = reflect.ParseTypeString("", "struct{d *[]uint32 \"TAG\"}");
+	st = t.(reflect.StructType);
+	name, typ, tag, offset = st.Field(0);
+	assert(typ.String(), "*[]uint32");
 }
diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go
index 2c05901..8b5e88f 100644
--- a/src/lib/reflect/type.go
+++ b/src/lib/reflect/type.go
@@ -557,11 +557,19 @@
 	str	string;	// string being parsed
 	token	string;	// the token being parsed now
 	tokstart	int;	// starting position of token
+	prevend	int;	// (one after) ending position of previous token
 	index	int;	// next character position in str
 }
 
+// Return typestring starting at position i.
+// Trim trailing blanks.
+func (p *Parser) TypeString(i int) string {
+	return p.str[i:p.prevend];
+}
+
 // Load next token into p.token
 func (p *Parser) Next() {
+	p.prevend = p.index;
 	token := "";
 	for ; p.index < len(p.str) && p.str[p.index] == ' '; p.index++ {
 	}
@@ -643,7 +651,7 @@
 	}
 	p.Next();
 	elemtype := p.Type("");
-	return NewStubType(name, NewArrayTypeStruct(name, p.str[tokstart:p.index], open, size, elemtype));
+	return NewStubType(name, NewArrayTypeStruct(name, p.TypeString(tokstart), open, size, elemtype));
 }
 
 func (p *Parser) Map(name string, tokstart int) *StubType {
@@ -657,7 +665,7 @@
 	}
 	p.Next();
 	elemtype := p.Type("");
-	return NewStubType(name, NewMapTypeStruct(name, p.str[tokstart:p.index], keytype, elemtype));
+	return NewStubType(name, NewMapTypeStruct(name, p.TypeString(tokstart), keytype, elemtype));
 }
 
 func (p *Parser) Chan(name string, tokstart, dir int) *StubType {
@@ -669,7 +677,7 @@
 		dir = SendDir;
 	}
 	elemtype := p.Type("");
-	return NewStubType(name, NewChanTypeStruct(name, p.str[tokstart:p.index], dir, elemtype));
+	return NewStubType(name, NewChanTypeStruct(name, p.TypeString(tokstart), dir, elemtype));
 }
 
 // Parse array of fields for struct, interface, and func arguments
@@ -713,9 +721,8 @@
 	if p.token != "}" {
 		return MissingStub;
 	}
-	ts := p.str[tokstart:p.index];
 	p.Next();
-	return NewStubType(name, NewStructTypeStruct(name, ts, f));
+	return NewStubType(name, NewStructTypeStruct(name, p.TypeString(tokstart), f));
 }
 
 func (p *Parser) Interface(name string, tokstart int) *StubType {
@@ -723,9 +730,8 @@
 	if p.token != "}" {
 		return MissingStub;
 	}
-	ts := p.str[tokstart:p.index];
 	p.Next();
-	return NewStubType(name, NewInterfaceTypeStruct(name, ts, f));
+	return NewStubType(name, NewInterfaceTypeStruct(name, p.TypeString(tokstart), f));
 }
 
 func (p *Parser) Func(name string, tokstart int) *StubType {
@@ -734,16 +740,15 @@
 	if p.token != ")" {
 		return MissingStub;
 	}
-	end := p.index;
 	p.Next();
 	if p.token != "(" {
 		// 1 list: the in parameters are a list.  Is there a single out parameter?
 		if p.token == "" || p.token == "}" || p.token == "," || p.token == ";" {
-			return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, nil));
+			return NewStubType(name, NewFuncTypeStruct(name, p.TypeString(tokstart), f1, nil));
 		}
 		// A single out parameter.
 		f2 := NewStructTypeStruct("", "", p.OneField());
-		return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, f2));
+		return NewStubType(name, NewFuncTypeStruct(name, p.TypeString(tokstart), f1, f2));
 	} else {
 		p.Next();
 	}
@@ -751,10 +756,9 @@
 	if p.token != ")" {
 		return MissingStub;
 	}
-	end = p.index;
 	p.Next();
 	// 2 lists: the in and out parameters are present
-	return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, f2));
+	return NewStubType(name, NewFuncTypeStruct(name, p.TypeString(tokstart), f1, f2));
 }
 
 func (p *Parser) Type(name string) *StubType {
@@ -766,7 +770,7 @@
 	case p.token == "*":
 		p.Next();
 		sub := p.Type("");
-		return NewStubType(name, NewPtrTypeStruct(name, p.str[tokstart:p.index], sub));
+		return NewStubType(name, NewPtrTypeStruct(name, p.TypeString(tokstart), sub));
 	case p.token == "[":
 		p.Next();
 		return p.Array(name, tokstart);