Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
12a34358
Commit
12a34358
authored
Oct 31, 2008
by
Rob Pike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reflection support for tag strings
R=rsc DELTA=86 (77 added, 0 deleted, 9 changed) OCL=18201 CL=18203
parent
57804f1d
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
9 deletions
+86
-9
test.go
src/lib/reflect/test.go
+2
-0
tostring.go
src/lib/reflect/tostring.go
+28
-2
type.go
src/lib/reflect/type.go
+55
-6
value.go
src/lib/reflect/value.go
+1
-1
No files found.
src/lib/reflect/test.go
View file @
12a34358
...
@@ -118,6 +118,8 @@ func main() {
...
@@ -118,6 +118,8 @@ func main() {
typedump
(
"struct {a int8; b int8; c int8; b int32}"
,
"struct{a int8; b int8; c int8; b int32}"
);
typedump
(
"struct {a int8; b int8; c int8; b int32}"
,
"struct{a int8; b int8; c int8; b int32}"
);
typedump
(
"struct {a int8; b int8; c int8; d int8; b int32}"
,
"struct{a int8; b int8; c int8; d int8; b int32}"
);
typedump
(
"struct {a int8; b int8; c int8; d int8; b int32}"
,
"struct{a int8; b int8; c int8; d int8; b int32}"
);
typedump
(
"struct {a int8; b int8; c int8; d int8; e int8; b int32}"
,
"struct{a int8; b int8; c int8; d int8; e int8; b int32}"
);
typedump
(
"struct {a int8; b int8; c int8; d int8; e int8; b int32}"
,
"struct{a int8; b int8; c int8; d int8; e int8; b int32}"
);
typedump
(
"struct {a int8
\"
hi there
\"
; }"
,
"struct{a int8
\"
hi there
\"
}"
);
typedump
(
"struct {a int8
\"
hi
\\
0there
\\
t
\\
n
\\\"\\\\\"
; }"
,
"struct{a int8
\"
hi
\\
0there
\\
t
\\
n
\\\"\\\\\"
}"
);
valuedump
(
"int8"
,
"8"
);
valuedump
(
"int8"
,
"8"
);
valuedump
(
"int16"
,
"16"
);
valuedump
(
"int16"
,
"16"
);
...
...
src/lib/reflect/tostring.go
View file @
12a34358
...
@@ -15,16 +15,42 @@ import (
...
@@ -15,16 +15,42 @@ import (
export
func
TypeToString
(
typ
Type
,
expand
bool
)
string
export
func
TypeToString
(
typ
Type
,
expand
bool
)
string
export
func
ValueToString
(
val
Value
)
string
export
func
ValueToString
(
val
Value
)
string
func
DoubleQuote
(
s
string
)
string
{
out
:=
"
\"
"
;
for
i
:=
0
;
i
<
len
(
s
);
i
++
{
c
:=
s
[
i
];
switch
c
{
case
'\n'
:
out
+=
`\n`
;
case
'\t'
:
out
+=
`\t`
;
case
'\x00'
:
out
+=
`\0`
;
case
'"'
:
out
+=
`\"`
;
case
'\\'
:
out
+=
`\\`
;
default
:
out
+=
string
(
c
);
}
}
out
+=
"
\"
"
;
return
out
;
}
type
HasFields
interface
{
type
HasFields
interface
{
Field
(
i
int
)
(
name
string
,
typ
Type
,
offset
uint64
);
Field
(
i
int
)
(
name
string
,
typ
Type
,
tag
string
,
offset
uint64
);
Len
()
int
;
Len
()
int
;
}
}
func
TypeFieldsToString
(
t
HasFields
,
sep
string
)
string
{
func
TypeFieldsToString
(
t
HasFields
,
sep
string
)
string
{
var
str
string
;
var
str
string
;
for
i
:=
0
;
i
<
t
.
Len
();
i
++
{
for
i
:=
0
;
i
<
t
.
Len
();
i
++
{
str1
,
typ
,
offset
:=
t
.
Field
(
i
);
str1
,
typ
,
tag
,
offset
:=
t
.
Field
(
i
);
str1
+=
" "
+
TypeToString
(
typ
,
false
);
str1
+=
" "
+
TypeToString
(
typ
,
false
);
if
tag
!=
""
{
str1
+=
" "
+
DoubleQuote
(
tag
);
}
if
i
<
t
.
Len
()
-
1
{
if
i
<
t
.
Len
()
-
1
{
str1
+=
sep
+
" "
;
str1
+=
sep
+
" "
;
}
}
...
...
src/lib/reflect/type.go
View file @
12a34358
...
@@ -245,13 +245,14 @@ func (t *ChanTypeStruct) Elem() Type {
...
@@ -245,13 +245,14 @@ func (t *ChanTypeStruct) Elem() Type {
// -- Struct
// -- Struct
export
type
StructType
interface
{
export
type
StructType
interface
{
Field
(
int
)
(
name
string
,
typ
Type
,
offset
uint64
);
Field
(
int
)
(
name
string
,
typ
Type
,
tag
string
,
offset
uint64
);
Len
()
int
;
Len
()
int
;
}
}
type
Field
struct
{
type
Field
struct
{
name
string
;
name
string
;
typ
*
StubType
;
typ
*
StubType
;
tag
string
;
size
uint64
;
size
uint64
;
offset
uint64
;
offset
uint64
;
}
}
...
@@ -289,11 +290,11 @@ func (t *StructTypeStruct) Size() uint64 {
...
@@ -289,11 +290,11 @@ func (t *StructTypeStruct) Size() uint64 {
return
size
;
return
size
;
}
}
func
(
t
*
StructTypeStruct
)
Field
(
i
int
)
(
name
string
,
typ
Type
,
offset
uint64
)
{
func
(
t
*
StructTypeStruct
)
Field
(
i
int
)
(
name
string
,
typ
Type
,
tag
string
,
offset
uint64
)
{
if
t
.
field
[
i
]
.
offset
==
0
{
if
t
.
field
[
i
]
.
offset
==
0
{
t
.
Size
();
// will compute offsets
t
.
Size
();
// will compute offsets
}
}
return
t
.
field
[
i
]
.
name
,
t
.
field
[
i
]
.
typ
.
Get
(),
t
.
field
[
i
]
.
offset
return
t
.
field
[
i
]
.
name
,
t
.
field
[
i
]
.
typ
.
Get
(),
t
.
field
[
i
]
.
tag
,
t
.
field
[
i
]
.
offset
}
}
func
(
t
*
StructTypeStruct
)
Len
()
int
{
func
(
t
*
StructTypeStruct
)
Len
()
int
{
...
@@ -303,7 +304,7 @@ func (t *StructTypeStruct) Len() int {
...
@@ -303,7 +304,7 @@ func (t *StructTypeStruct) Len() int {
// -- Interface
// -- Interface
export
type
InterfaceType
interface
{
export
type
InterfaceType
interface
{
Field
(
int
)
(
name
string
,
typ
Type
,
offset
uint64
);
Field
(
int
)
(
name
string
,
typ
Type
,
tag
string
,
offset
uint64
);
Len
()
int
;
Len
()
int
;
}
}
...
@@ -316,8 +317,8 @@ func NewInterfaceTypeStruct(name string, field *[]Field) *InterfaceTypeStruct {
...
@@ -316,8 +317,8 @@ func NewInterfaceTypeStruct(name string, field *[]Field) *InterfaceTypeStruct {
return
&
InterfaceTypeStruct
{
Common
{
InterfaceKind
,
name
,
interfacesize
},
field
}
return
&
InterfaceTypeStruct
{
Common
{
InterfaceKind
,
name
,
interfacesize
},
field
}
}
}
func
(
t
*
InterfaceTypeStruct
)
Field
(
i
int
)
(
name
string
,
typ
Type
,
offset
uint64
)
{
func
(
t
*
InterfaceTypeStruct
)
Field
(
i
int
)
(
name
string
,
typ
Type
,
tag
string
,
offset
uint64
)
{
return
t
.
field
[
i
]
.
name
,
t
.
field
[
i
]
.
typ
.
Get
(),
0
return
t
.
field
[
i
]
.
name
,
t
.
field
[
i
]
.
typ
.
Get
(),
""
,
0
}
}
func
(
t
*
InterfaceTypeStruct
)
Len
()
int
{
func
(
t
*
InterfaceTypeStruct
)
Len
()
int
{
...
@@ -489,6 +490,33 @@ func special(c uint8) bool {
...
@@ -489,6 +490,33 @@ func special(c uint8) bool {
return
false
;
return
false
;
}
}
// Process backslashes. String known to be well-formed.
// Initial double-quote is left in, as an indication this token is a string.
func
unescape
(
s
string
,
backslash
bool
)
string
{
if
!
backslash
{
return
s
}
out
:=
"
\"
"
;
for
i
:=
1
;
i
<
len
(
s
);
i
++
{
c
:=
s
[
i
];
if
c
==
'\\'
{
i
++
;
c
=
s
[
i
];
switch
c
{
case
'n'
:
c
=
'\n'
;
case
't'
:
c
=
'\t'
;
case
'0'
:
// it's not a legal go string but \0 means NUL
c
=
'\x00'
;
// default is correct already; \\ is \; \" is "
}
}
out
+=
string
(
c
);
}
return
out
;
}
// Simple parser for type strings
// Simple parser for type strings
type
Parser
struct
{
type
Parser
struct
{
str
string
;
// string being parsed
str
string
;
// string being parsed
...
@@ -525,6 +553,23 @@ func (p *Parser) Next() {
...
@@ -525,6 +553,23 @@ func (p *Parser) Next() {
}
}
p
.
token
=
p
.
str
[
start
:
p
.
index
];
p
.
token
=
p
.
str
[
start
:
p
.
index
];
return
;
return
;
case
c
==
'"'
:
// double-quoted string for struct field annotation
backslash
:=
false
;
for
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
]
!=
'"'
{
if
p
.
str
[
p
.
index
]
==
'\\'
{
if
p
.
index
+
1
==
len
(
p
.
str
)
{
// bad final backslash
break
;
}
p
.
index
++
;
// skip (and accept) backslash
backslash
=
true
;
}
p
.
index
++
}
p
.
token
=
unescape
(
p
.
str
[
start
:
p
.
index
],
backslash
);
if
p
.
index
<
len
(
p
.
str
)
{
// properly terminated string
p
.
index
++
;
// skip the terminating double-quote
}
return
;
}
}
for
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
]
!=
' '
&&
!
special
(
p
.
str
[
p
.
index
])
{
for
p
.
index
<
len
(
p
.
str
)
&&
p
.
str
[
p
.
index
]
!=
' '
&&
!
special
(
p
.
str
[
p
.
index
])
{
p
.
index
++
p
.
index
++
...
@@ -598,6 +643,10 @@ func (p *Parser) Fields(sep string) *[]Field {
...
@@ -598,6 +643,10 @@ func (p *Parser) Fields(sep string) *[]Field {
a
[
nf
]
.
name
=
p
.
token
;
a
[
nf
]
.
name
=
p
.
token
;
p
.
Next
();
p
.
Next
();
a
[
nf
]
.
typ
=
p
.
Type
(
""
);
a
[
nf
]
.
typ
=
p
.
Type
(
""
);
if
p
.
token
!=
""
&&
p
.
token
[
0
]
==
'"'
{
a
[
nf
]
.
tag
=
p
.
token
[
1
:
len
(
p
.
token
)];
p
.
Next
();
}
nf
++
;
nf
++
;
if
p
.
token
!=
sep
{
if
p
.
token
!=
sep
{
break
;
break
;
...
...
src/lib/reflect/value.go
View file @
12a34358
...
@@ -609,7 +609,7 @@ func StructCreator(typ Type, addr Addr) Value {
...
@@ -609,7 +609,7 @@ func StructCreator(typ Type, addr Addr) Value {
nfield
:=
t
.
Len
();
nfield
:=
t
.
Len
();
v
:=
&
StructValueStruct
{
CommonV
{
StructKind
,
typ
,
addr
},
new
([]
Value
,
nfield
)
};
v
:=
&
StructValueStruct
{
CommonV
{
StructKind
,
typ
,
addr
},
new
([]
Value
,
nfield
)
};
for
i
:=
0
;
i
<
nfield
;
i
++
{
for
i
:=
0
;
i
<
nfield
;
i
++
{
name
,
ftype
,
offset
:=
t
.
Field
(
i
);
name
,
ftype
,
str
,
offset
:=
t
.
Field
(
i
);
v
.
field
[
i
]
=
NewValueAddr
(
ftype
,
addr
+
offset
);
v
.
field
[
i
]
=
NewValueAddr
(
ftype
,
addr
+
offset
);
}
}
v
.
typ
=
typ
;
v
.
typ
=
typ
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment