If a value implements String(), use that in fmt.print (not fmt.printf)

R=rsc
DELTA=13  (9 added, 0 deleted, 4 changed)
OCL=18682
CL=18684
diff --git a/src/lib/fmt/print.go b/src/lib/fmt/print.go
index 3c237f5..3516b19 100644
--- a/src/lib/fmt/print.go
+++ b/src/lib/fmt/print.go
@@ -22,14 +22,18 @@
 // Representation of printer state passed to custom formatters.
 // Provides access to the Writer interface plus information about
 // the active formatting verb.
-export type FormatHelper interface {
+export type Formatter interface {
 	Write(b *[]byte) (ret int, err *os.Error);
 	Width()	(wid int, ok bool);
 	Precision()	(prec int, ok bool);
 }
 
-export type Formatter interface {
-	Format(f FormatHelper, c int);
+export type Format interface {
+	Format(f Formatter, c int);
+}
+
+export type String interface {
+	String() string
 }
 
 const Runeself = 0x80
@@ -303,7 +307,7 @@
 		}
 		field := v.Field(fieldnum);
 		fieldnum++;
-		if formatter, ok := field.Interface().(Formatter); ok {
+		if formatter, ok := field.Interface().(Format); ok {
 			formatter.Format(p, c);
 			continue;
 		}
@@ -439,6 +443,11 @@
 				p.add(' ')
 			}
 		}
+		if stringer, ok := field.Interface().(String); ok {
+			p.addstr(stringer.String());
+			prev_string = false;	// this value is not a string
+			continue;
+		}
 		switch field.Kind() {
 		case reflect.BoolKind:
 			s = p.fmt.boolean(field.(reflect.BoolValue).Get()).str();