// This function never executes, but it serves as a simple test for the program. // Test with make test. public static void PrintfTests() { bool b = default; long i = default; int r = default; @string s = default; double x = default; ptr <long> p; map <long, long> imap = default; slice <double> fslice = default; complex64 c = default; // Some good format/argtypes fmt.Printf(""); fmt.Printf("%b %b %b", 3L, i, x); fmt.Printf("%c %c %c %c", 3L, i, 'x', r); fmt.Printf("%d %d %d", 3L, i, imap); fmt.Printf("%e %e %e %e", 3e9F, x, fslice, c); fmt.Printf("%E %E %E %E", 3e9F, x, fslice, c); fmt.Printf("%f %f %f %f", 3e9F, x, fslice, c); fmt.Printf("%F %F %F %F", 3e9F, x, fslice, c); fmt.Printf("%g %g %g %g", 3e9F, x, fslice, c); fmt.Printf("%G %G %G %G", 3e9F, x, fslice, c); fmt.Printf("%b %b %b %b", 3e9F, x, fslice, c); fmt.Printf("%o %o", 3L, i); fmt.Printf("%p", p); fmt.Printf("%q %q %q %q", 3L, i, 'x', r); fmt.Printf("%s %s %s", "hi", s, new slice <byte>(new byte[] { 65 })); fmt.Printf("%t %t", true, b); fmt.Printf("%T %T", 3L, i); fmt.Printf("%U %U", 3L, i); fmt.Printf("%v %v", 3L, i); fmt.Printf("%x %x %x %x %x %x %x", 3L, i, "hi", s, x, c, fslice); fmt.Printf("%X %X %X %X %X %X %X", 3L, i, "hi", s, x, c, fslice); fmt.Printf("%.*s %d %g", 3L, "hi", 23L, 2.3F); fmt.Printf("%s", _addr_stringerv); fmt.Printf("%v", _addr_stringerv); fmt.Printf("%T", _addr_stringerv); fmt.Printf("%s", _addr_embeddedStringerv); fmt.Printf("%v", _addr_embeddedStringerv); fmt.Printf("%T", _addr_embeddedStringerv); fmt.Printf("%v", notstringerv); fmt.Printf("%T", notstringerv); fmt.Printf("%q", stringerarrayv); fmt.Printf("%v", stringerarrayv); fmt.Printf("%s", stringerarrayv); fmt.Printf("%v", notstringerarrayv); fmt.Printf("%T", notstringerarrayv); fmt.Printf("%d", @new <fmt.Formatter>()); fmt.Printf("%*%", 2L); // Ridiculous but allowed. fmt.Printf("%s"); // Nothing useful we can say. fmt.Printf("%g", 1L + 2iUL); fmt.Printf("%#e %#E %#f %#F %#g %#G", 1.2F, 1.2F, 1.2F, 1.2F, 1.2F, 1.2F); // OK since Go 1.9 // Some bad format/argTypes fmt.Printf("%b", "hi"); // ERROR "Printf format %b has arg \x22hi\x22 of wrong type string" fmt.Printf("%t", c); // ERROR "Printf format %t has arg c of wrong type complex64" fmt.Printf("%t", 1L + 2iUL); // ERROR "Printf format %t has arg 1 \+ 2i of wrong type complex128" fmt.Printf("%c", 2.3F); // ERROR "Printf format %c has arg 2.3 of wrong type float64" fmt.Printf("%d", 2.3F); // ERROR "Printf format %d has arg 2.3 of wrong type float64" fmt.Printf("%e", "hi"); // ERROR "Printf format %e has arg \x22hi\x22 of wrong type string" fmt.Printf("%E", true); // ERROR "Printf format %E has arg true of wrong type bool" fmt.Printf("%f", "hi"); // ERROR "Printf format %f has arg \x22hi\x22 of wrong type string" fmt.Printf("%F", 'x'); // ERROR "Printf format %F has arg 'x' of wrong type rune" fmt.Printf("%g", "hi"); // ERROR "Printf format %g has arg \x22hi\x22 of wrong type string" fmt.Printf("%g", imap); // ERROR "Printf format %g has arg imap of wrong type map\[int\]int" fmt.Printf("%G", i); // ERROR "Printf format %G has arg i of wrong type int" fmt.Printf("%o", x); // ERROR "Printf format %o has arg x of wrong type float64" fmt.Printf("%p", null); // ERROR "Printf format %p has arg nil of wrong type untyped nil" fmt.Printf("%p", 23L); // ERROR "Printf format %p has arg 23 of wrong type int" fmt.Printf("%q", x); // ERROR "Printf format %q has arg x of wrong type float64" fmt.Printf("%s", b); // ERROR "Printf format %s has arg b of wrong type bool" fmt.Printf("%s", byte(65L)); // ERROR "Printf format %s has arg byte\(65\) of wrong type byte" fmt.Printf("%t", 23L); // ERROR "Printf format %t has arg 23 of wrong type int" fmt.Printf("%U", x); // ERROR "Printf format %U has arg x of wrong type float64" fmt.Printf("%x", null); // ERROR "Printf format %x has arg nil of wrong type untyped nil" fmt.Printf("%s", stringerv); // ERROR "Printf format %s has arg stringerv of wrong type .*print.ptrStringer" fmt.Printf("%t", stringerv); // ERROR "Printf format %t has arg stringerv of wrong type .*print.ptrStringer" fmt.Printf("%s", embeddedStringerv); // ERROR "Printf format %s has arg embeddedStringerv of wrong type .*print.embeddedStringer" fmt.Printf("%t", embeddedStringerv); // ERROR "Printf format %t has arg embeddedStringerv of wrong type .*print.embeddedStringer" fmt.Printf("%q", notstringerv); // ERROR "Printf format %q has arg notstringerv of wrong type .*print.notstringer" fmt.Printf("%t", notstringerv); // ERROR "Printf format %t has arg notstringerv of wrong type .*print.notstringer" fmt.Printf("%t", stringerarrayv); // ERROR "Printf format %t has arg stringerarrayv of wrong type .*print.stringerarray" fmt.Printf("%t", notstringerarrayv); // ERROR "Printf format %t has arg notstringerarrayv of wrong type .*print.notstringerarray" fmt.Printf("%q", notstringerarrayv); // ERROR "Printf format %q has arg notstringerarrayv of wrong type .*print.notstringerarray" fmt.Printf("%d", BoolFormatter(true)); // ERROR "Printf format %d has arg BoolFormatter\(true\) of wrong type .*print.BoolFormatter" fmt.Printf("%z", FormatterVal(true)); // correct (the type is responsible for formatting) fmt.Printf("%d", FormatterVal(true)); // correct (the type is responsible for formatting) fmt.Printf("%s", nonemptyinterface); // correct (the type is responsible for formatting) fmt.Printf("%.*s %d %6g", 3L, "hi", 23L, 'x'); // ERROR "Printf format %6g has arg 'x' of wrong type rune" fmt.Println(); // not an error fmt.Println("%s", "hi"); // ERROR "Println call has possible formatting directive %s" fmt.Println("%v", "hi"); // ERROR "Println call has possible formatting directive %v" fmt.Println("%T", "hi"); // ERROR "Println call has possible formatting directive %T" fmt.Println("0.0%"); // correct (trailing % couldn't be a formatting directive) fmt.Printf("%s", "hi", 3L); // ERROR "Printf call needs 1 arg but has 2 args" _ = fmt.Sprintf("%" + ("s"), "hi", 3L); // ERROR "Sprintf call needs 1 arg but has 2 args" fmt.Printf("%s%%%d", "hi", 3L); // correct fmt.Printf("%08s", "woo"); // correct fmt.Printf("% 8s", "woo"); // correct fmt.Printf("%.*d", 3L, 3L); // correct fmt.Printf("%.*d x", 3L, 3L, 3L, 3L); // ERROR "Printf call needs 2 args but has 4 args" fmt.Printf("%.*d x", "hi", 3L); // ERROR "Printf format %.*d uses non-int \x22hi\x22 as argument of \*" fmt.Printf("%.*d x", i, 3L); // correct fmt.Printf("%.*d x", s, 3L); // ERROR "Printf format %.\*d uses non-int s as argument of \*" fmt.Printf("%*% x", 0.22F); // ERROR "Printf format %\*% uses non-int 0.22 as argument of \*" fmt.Printf("%q %q", multi()); // ok fmt.Printf("%#q", "blah"); // ok // printf("now is the time", "buddy") // no error "printf call has arguments but no formatting directives" Printf("now is the time", "buddy"); // ERROR "Printf call has arguments but no formatting directives" Printf("hi"); // ok const @string format = (@string)"%s %s\n"; Printf(format, "hi", "there"); Printf(format, "hi"); // ERROR "Printf format %s reads arg #2, but call has 1 arg$" Printf("%s %d %.3v %q", "str", 4L); // ERROR "Printf format %.3v reads arg #3, but call has 2 args" ptr <object> f = @new <ptrStringer>(); f.Warn(0L, "%s", "hello", 3L); // ERROR "Warn call has possible formatting directive %s" f.Warnf(0L, "%s", "hello", 3L); // ERROR "Warnf call needs 1 arg but has 2 args" f.Warnf(0L, "%r", "hello"); // ERROR "Warnf format %r has unknown verb r" f.Warnf(0L, "%#s", "hello"); // ERROR "Warnf format %#s has unrecognized flag #" f.Warn2(0L, "%s", "hello", 3L); // ERROR "Warn2 call has possible formatting directive %s" f.Warnf2(0L, "%s", "hello", 3L); // ERROR "Warnf2 call needs 1 arg but has 2 args" f.Warnf2(0L, "%r", "hello"); // ERROR "Warnf2 format %r has unknown verb r" f.Warnf2(0L, "%#s", "hello"); // ERROR "Warnf2 format %#s has unrecognized flag #" f.Wrap(0L, "%s", "hello", 3L); // ERROR "Wrap call has possible formatting directive %s" f.Wrapf(0L, "%s", "hello", 3L); // ERROR "Wrapf call needs 1 arg but has 2 args" f.Wrapf(0L, "%r", "hello"); // ERROR "Wrapf format %r has unknown verb r" f.Wrapf(0L, "%#s", "hello"); // ERROR "Wrapf format %#s has unrecognized flag #" f.Wrap2(0L, "%s", "hello", 3L); // ERROR "Wrap2 call has possible formatting directive %s" f.Wrapf2(0L, "%s", "hello", 3L); // ERROR "Wrapf2 call needs 1 arg but has 2 args" f.Wrapf2(0L, "%r", "hello"); // ERROR "Wrapf2 format %r has unknown verb r" f.Wrapf2(0L, "%#s", "hello"); // ERROR "Wrapf2 format %#s has unrecognized flag #" fmt.Printf("%#s", FormatterVal(true)); // correct (the type is responsible for formatting) Printf("d%", 2L); // ERROR "Printf format % is missing verb at end of string" Printf("%d", percentDV); Printf("%d", _addr_percentDV); Printf("%d", notPercentDV); // ERROR "Printf format %d has arg notPercentDV of wrong type .*print.notPercentDStruct" Printf("%d", _addr_notPercentDV); // ERROR "Printf format %d has arg ¬PercentDV of wrong type \*.*print.notPercentDStruct" Printf("%p", _addr_notPercentDV); // Works regardless: we print it as a pointer. Printf("%q", _addr_percentDV); // ERROR "Printf format %q has arg &percentDV of wrong type \*.*print.percentDStruct" Printf("%s", percentSV); Printf("%s", _addr_percentSV); // Good argument reorderings. Printf("%[1]d", 3L); Printf("%[1]*d", 3L, 1L); Printf("%[2]*[1]d", 1L, 3L); Printf("%[2]*.[1]*[3]d", 2L, 3L, 4L); fmt.Fprintf(os.Stderr, "%[2]*.[1]*[3]d", 2L, 3L, 4L); // Use Fprintf to make sure we count arguments correctly. // Bad argument reorderings. Printf("%[xd", 3L); // ERROR "Printf format %\[xd is missing closing \]" Printf("%[x]d x", 3L); // ERROR "Printf format has invalid argument index \[x\]" Printf("%[3]*s x", "hi", 2L); // ERROR "Printf format has invalid argument index \[3\]" _ = fmt.Sprintf("%[3]d x", 2L); // ERROR "Sprintf format has invalid argument index \[3\]" Printf("%[2]*.[1]*[3]d x", 2L, "hi", 4L); // ERROR "Printf format %\[2]\*\.\[1\]\*\[3\]d uses non-int \x22hi\x22 as argument of \*" Printf("%[0]s x", "arg1"); // ERROR "Printf format has invalid argument index \[0\]" Printf("%[0]d x", 1L); // ERROR "Printf format has invalid argument index \[0\]" // Something that satisfies the error interface. error e = default !;