Commit 23553955 authored by Rob Pike's avatar Rob Pike

handle nils safely

R=rsc
DELTA=38  (14 added, 10 deleted, 14 changed)
OCL=19242
CL=19242
parent 22e0e1b0
...@@ -11,16 +11,13 @@ package fmt ...@@ -11,16 +11,13 @@ package fmt
import ( import (
"fmt"; "fmt";
"io";
"reflect"; "reflect";
"os"; "os";
) )
export type Writer interface {
Write(b *[]byte) (ret int, err *os.Error);
}
// Representation of printer state passed to custom formatters. // Representation of printer state passed to custom formatters.
// Provides access to the Writer interface plus information about // Provides access to the io.Write interface plus information about
// the active formatting verb. // the active formatting verb.
export type Formatter interface { export type Formatter interface {
Write(b *[]byte) (ret int, err *os.Error); Write(b *[]byte) (ret int, err *os.Error);
...@@ -119,7 +116,7 @@ func (p *P) doprint(v reflect.StructValue, addspace, addnewline bool); ...@@ -119,7 +116,7 @@ func (p *P) doprint(v reflect.StructValue, addspace, addnewline bool);
// These routines end in 'f' and take a format string. // These routines end in 'f' and take a format string.
export func fprintf(w Writer, format string, a ...) (n int, error *os.Error) { export func fprintf(w io.Write, format string, a ...) (n int, error *os.Error) {
v := reflect.NewValue(a).(reflect.PtrValue).Sub().(reflect.StructValue); v := reflect.NewValue(a).(reflect.PtrValue).Sub().(reflect.StructValue);
p := Printer(); p := Printer();
p.doprintf(format, v); p.doprintf(format, v);
...@@ -143,7 +140,7 @@ export func sprintf(format string, a ...) string { ...@@ -143,7 +140,7 @@ export func sprintf(format string, a ...) string {
// These routines do not take a format string and add spaces only // These routines do not take a format string and add spaces only
// when the operand on neither side is a string. // when the operand on neither side is a string.
export func fprint(w Writer, a ...) (n int, error *os.Error) { export func fprint(w io.Write, a ...) (n int, error *os.Error) {
v := reflect.NewValue(a).(reflect.PtrValue).Sub().(reflect.StructValue); v := reflect.NewValue(a).(reflect.PtrValue).Sub().(reflect.StructValue);
p := Printer(); p := Printer();
p.doprint(v, false, false); p.doprint(v, false, false);
...@@ -168,7 +165,7 @@ export func sprint(a ...) string { ...@@ -168,7 +165,7 @@ export func sprint(a ...) string {
// always add spaces between operands, and add a newline // always add spaces between operands, and add a newline
// after the last operand. // after the last operand.
export func fprintln(w Writer, a ...) (n int, error *os.Error) { export func fprintln(w io.Write, a ...) (n int, error *os.Error) {
v := reflect.NewValue(a).(reflect.PtrValue).Sub().(reflect.StructValue); v := reflect.NewValue(a).(reflect.PtrValue).Sub().(reflect.StructValue);
p := Printer(); p := Printer();
p.doprint(v, true, true); p.doprint(v, true, true);
...@@ -310,22 +307,25 @@ func (p *P) printField(field reflect.Value) (was_string bool) { ...@@ -310,22 +307,25 @@ func (p *P) printField(field reflect.Value) (was_string bool) {
s = p.fmt.s(v).str(); s = p.fmt.s(v).str();
was_string = true; was_string = true;
case reflect.PtrKind: case reflect.PtrKind:
// pointer to array? if v, ok := getPtr(field); v == 0 {
if v, ok := getArrayPtr(field); ok { s = "<nil>"
p.addstr("&["); } else {
for i := 0; i < v.Len(); i++ { // pointer to array?
if i > 0 { if a, ok := getArrayPtr(field); ok {
p.addstr(" "); p.addstr("&[");
for i := 0; i < a.Len(); i++ {
if i > 0 {
p.addstr(" ");
}
p.printField(a.Elem(i));
} }
p.printField(v.Elem(i)); p.addstr("]");
} else {
p.add('0');
p.add('x');
s = p.fmt.uX64(v).str();
} }
p.addstr("]");
break;
} }
v, ok := getPtr(field);
p.add('0');
p.add('x');
s = p.fmt.uX64(v).str();
case reflect.StructKind: case reflect.StructKind:
p.add('{'); p.add('{');
p.doprint(field, true, false); p.doprint(field, true, false);
...@@ -471,7 +471,11 @@ func (p *P) doprintf(format string, v reflect.StructValue) { ...@@ -471,7 +471,11 @@ func (p *P) doprintf(format string, v reflect.StructValue) {
// pointer // pointer
case 'p': case 'p':
if v, ok := getPtr(field); ok { if v, ok := getPtr(field); ok {
s = "0x" + p.fmt.uX64(v).str() if v == nil {
s = "<nil>"
} else {
s = "0x" + p.fmt.uX64(v).str()
}
} else { } else {
goto badtype goto badtype
} }
......
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