tfmt changes from Google - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 85231fd8cdf32d861e196d7dfa827b7239157817
 (DIR) parent 8d7133308db580d2356d5d1dd30f0b9a1f0a7417
 (HTM) Author: rsc <devnull@localhost>
       Date:   Sun, 21 May 2006 20:49:16 +0000
       
       fmt changes from Google
       
       Diffstat:
         M include/fmt.h                       |      17 ++++++++++++++++-
         M src/lib9/fmt/LICENSE                |      11 ++++++-----
         M src/lib9/fmt/charstod.c             |      14 +-------------
         M src/lib9/fmt/dofmt.c                |      97 ++++++++++++++++++++++---------
         M src/lib9/fmt/dorfmt.c               |      25 +++++++------------------
         M src/lib9/fmt/errfmt.c               |      14 +-------------
         M src/lib9/fmt/fltfmt.c               |      14 +-------------
         M src/lib9/fmt/fmt.c                  |      17 +++--------------
         M src/lib9/fmt/fmtdef.h               |      26 +++++++-------------------
         M src/lib9/fmt/fmtfd.c                |      16 +++-------------
         M src/lib9/fmt/fmtfdflush.c           |      14 +-------------
         A src/lib9/fmt/fmtlocale.c            |      56 +++++++++++++++++++++++++++++++
         M src/lib9/fmt/fmtlock.c              |      14 +-------------
         M src/lib9/fmt/fmtprint.c             |      14 +-------------
         M src/lib9/fmt/fmtquote.c             |      18 ++++--------------
         M src/lib9/fmt/fmtrune.c              |      14 +-------------
         M src/lib9/fmt/fmtstr.c               |      15 ++-------------
         M src/lib9/fmt/fmtvprint.c            |      14 +-------------
         M src/lib9/fmt/fprint.c               |      14 +-------------
         M src/lib9/fmt/pow10.c                |      14 +-------------
         M src/lib9/fmt/print.c                |      14 +-------------
         M src/lib9/fmt/runefmtstr.c           |      15 ++-------------
         M src/lib9/fmt/runeseprint.c          |      14 +-------------
         M src/lib9/fmt/runesmprint.c          |      14 +-------------
         M src/lib9/fmt/runesnprint.c          |      14 +-------------
         M src/lib9/fmt/runesprint.c           |      14 +-------------
         M src/lib9/fmt/runevseprint.c         |      14 +-------------
         M src/lib9/fmt/runevsmprint.c         |      15 ++-------------
         M src/lib9/fmt/runevsnprint.c         |      15 ++-------------
         M src/lib9/fmt/seprint.c              |      14 +-------------
         M src/lib9/fmt/smprint.c              |      14 +-------------
         M src/lib9/fmt/snprint.c              |      14 +-------------
         M src/lib9/fmt/sprint.c               |      14 +-------------
         M src/lib9/fmt/strtod.c               |      18 +++---------------
         M src/lib9/fmt/test.c                 |      33 +++++++++++++++++++------------
         M src/lib9/fmt/vfprint.c              |      14 +-------------
         M src/lib9/fmt/vseprint.c             |      14 +-------------
         M src/lib9/fmt/vsmprint.c             |      15 ++-------------
         M src/lib9/fmt/vsnprint.c             |      15 ++-------------
         A src/lib9/testfltfmt.c               |     166 +++++++++++++++++++++++++++++++
         A src/lib9/testfmt.c                  |     114 +++++++++++++++++++++++++++++++
       
       41 files changed, 507 insertions(+), 505 deletions(-)
       ---
 (DIR) diff --git a/include/fmt.h b/include/fmt.h
       t@@ -34,6 +34,18 @@ struct Fmt{
                int        width;
                int        prec;
                unsigned long        flags;
       +        char        *decimal;        /* decimal point; cannot be "" */
       +
       +        /* For %'d */
       +        char *thousands;        /* separator for thousands */
       +        
       +        /* 
       +         * Each char is an integer indicating #digits before next separator. Values:
       +         *        \xFF: no more grouping (or \x7F; defined to be CHAR_MAX in POSIX)
       +         *        \x00: repeat previous indefinitely
       +         *        \x**: count that many
       +         */
       +        char        *grouping;                /* descriptor of separator placement */
        };
        
        enum{
       t@@ -43,7 +55,8 @@ enum{
                FmtSharp        = FmtPrec << 1,
                FmtSpace        = FmtSharp << 1,
                FmtSign                = FmtSpace << 1,
       -        FmtZero                = FmtSign << 1,
       +        FmtApost                = FmtSign << 1,
       +        FmtZero                = FmtApost << 1,
                FmtUnsigned        = FmtZero << 1,
                FmtShort        = FmtUnsigned << 1,
                FmtLong                = FmtShort << 1,
       t@@ -64,6 +77,8 @@ double                fmtcharstod(int(*f)(void*), void *vp);
        int                fmtfdflush(Fmt *f);
        int                fmtfdinit(Fmt *f, int fd, char *buf, int size);
        int                fmtinstall(int c, int (*f)(Fmt*));
       +int                fmtnullinit(Fmt*);
       +void                fmtlocaleinit(Fmt*, char*, char*, char*);
        int                fmtprint(Fmt *f, char *fmt, ...);
        int                fmtrune(Fmt *f, int r);
        int                fmtrunestrcpy(Fmt *f, Rune *s);
 (DIR) diff --git a/src/lib9/fmt/LICENSE b/src/lib9/fmt/LICENSE
       t@@ -1,6 +1,8 @@
        /*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *                Copyright (c) 2002 by Lucent Technologies.
       + * The authors of this software are Rob Pike and Ken Thompson,
       + * with contributions from Mike Burrows and Sean Dorward.
       + *
       + *              Copyright (c) 2002-2006 by Lucent Technologies.
         * Permission to use, copy, modify, and distribute this software for any
         * purpose without fee is hereby granted, provided that this entire notice
         * is included in all copies of any software which is or includes a copy
       t@@ -10,10 +12,9 @@
         * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
         * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
         * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       -*/
       + */
        
        This is a Unix port of the Plan 9 formatted I/O package.
        
       -Please send comments about the packaging
       -to Russ Cox <rsc@post.harvard.edu>.
       +Please send comments about the packaging to Russ Cox <rsc@swtch.com>.
        
 (DIR) diff --git a/src/lib9/fmt/charstod.c b/src/lib9/fmt/charstod.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/dofmt.c b/src/lib9/fmt/dofmt.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
       t@@ -97,7 +85,7 @@ __fmtflush(Fmt *f, void *t, int len)
        
        /*
         * put a formatted block of memory sz bytes long of n runes into the output buffer,
       - * left/right justified in a field of at least f->width charactes
       + * left/right justified in a field of at least f->width characters (if FmtWidth is set)
         */
        int
        __fmtpad(Fmt *f, int n)
       t@@ -139,8 +127,10 @@ __fmtcpy(Fmt *f, const void *vm, int n, int sz)
        
                m = (char*)vm;
                me = m + sz;
       -        w = f->width;
                fl = f->flags;
       +        w = 0;
       +        if(fl & FmtWidth)
       +                w = f->width;
                if((fl & FmtPrec) && n > f->prec)
                        n = f->prec;
                if(f->runes){
       t@@ -194,8 +184,10 @@ __fmtrcpy(Fmt *f, const void *vm, int n)
                int w;
        
                m = (Rune*)vm;
       -        w = f->width;
                fl = f->flags;
       +        w = 0;
       +        if(fl & FmtWidth)
       +                w = f->width;
                if((fl & FmtPrec) && n > f->prec)
                        n = f->prec;
                if(f->runes){
       t@@ -324,10 +316,14 @@ __percentfmt(Fmt *f)
        int
        __ifmt(Fmt *f)
        {
       -        char buf[70], *p, *conv;
       +        char buf[140], *p, *conv;
       +        /* 140: for 64 bits of binary + 3-byte sep every 4 digits */
                uvlong vu;
                ulong u;
                int neg, base, i, n, fl, w, isv;
       +        int ndig, len, excess, bytelen;
       +        char *grouping;
       +        char *thousands;
        
                neg = 0;
                fl = f->flags;
       t@@ -339,11 +335,11 @@ __ifmt(Fmt *f)
                 * Unsigned verbs for ANSI C
                 */
                switch(f->r){
       -        case 'x':
       -        case 'X':
                case 'o':
       -        case 'u':
                case 'p':
       +        case 'u':
       +        case 'x':
       +        case 'X':
                        fl |= FmtUnsigned;
                        fl &= ~(FmtSign|FmtSpace);
                        break;
       t@@ -381,21 +377,25 @@ __ifmt(Fmt *f)
                                u = va_arg(f->args, int);
                }
                conv = "0123456789abcdef";
       +        grouping = "\4";        /* for hex, octal etc. (undefined by spec but nice) */
       +        thousands = f->thousands;
                switch(f->r){
                case 'd':
                case 'i':
                case 'u':
                        base = 10;
       -                break;
       -        case 'x':
       -                base = 16;
       +                grouping = f->grouping;
                        break;
                case 'X':
       -                base = 16;
                        conv = "0123456789ABCDEF";
       +                /* fall through */
       +        case 'x':
       +                base = 16;
       +                thousands = ":";
                        break;
                case 'b':
                        base = 2;
       +                thousands = ":";
                        break;
                case 'o':
                        base = 8;
       t@@ -413,7 +413,11 @@ __ifmt(Fmt *f)
                        }
                }
                p = buf + sizeof buf - 1;
       -        n = 0;
       +        n = 0;        /* in runes */
       +        excess = 0;        /* number of bytes > number runes */
       +        ndig = 0;
       +        len = utflen(thousands);
       +        bytelen = strlen(thousands);
                if(isv){
                        while(vu){
                                i = vu % base;
       t@@ -422,6 +426,12 @@ __ifmt(Fmt *f)
                                        *p-- = ',';
                                        n++;
                                }
       +                        if((fl & FmtApost) && __needsep(&ndig, &grouping)){
       +                                n += len;
       +                                excess += bytelen - len;
       +                                p -= bytelen;
       +                                memmove(p+1, thousands, bytelen);
       +                        }
                                *p-- = conv[i];
                                n++;
                        }
       t@@ -433,6 +443,12 @@ __ifmt(Fmt *f)
                                        *p-- = ',';
                                        n++;
                                }
       +                        if((fl & FmtApost) && __needsep(&ndig, &grouping)){
       +                                n += len;
       +                                excess += bytelen - len;
       +                                p -= bytelen;
       +                                memmove(p+1, thousands, bytelen);
       +                        }
                                *p-- = conv[i];
                                n++;
                        }
       t@@ -440,9 +456,19 @@ __ifmt(Fmt *f)
                if(n == 0){
                        *p-- = '0';
                        n = 1;
       +                if(fl & FmtApost)
       +                        __needsep(&ndig, &grouping);
       +                fl &= ~FmtSharp;        /* ??? */
                }
       -        for(w = f->prec; n < w && p > buf+3; n++)
       +        for(w = f->prec; n < w && p > buf+3; n++){
       +                if((fl & FmtApost) && __needsep(&ndig, &grouping)){
       +                        n += len;
       +                        excess += bytelen - len;
       +                        p -= bytelen;
       +                        memmove(p+1, thousands, bytelen);
       +                }
                        *p-- = '0';
       +        }
                if(neg || (fl & (FmtSign|FmtSpace)))
                        n++;
                if(fl & FmtSharp){
       t@@ -456,9 +482,19 @@ __ifmt(Fmt *f)
                        }
                }
                if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
       -                for(w = f->width; n < w && p > buf+3; n++)
       +                w = 0;
       +                if(fl & FmtWidth)
       +                        w = f->width;
       +                for(; n < w && p > buf+3; n++){
       +                        if((fl & FmtApost) && __needsep(&ndig, &grouping)){
       +                                n += len;
       +                                excess += bytelen - len;
       +                                p -= bytelen;
       +                                memmove(p+1, thousands, bytelen);
       +                        }
                                *p-- = '0';
       -                f->width = 0;
       +                }
       +                f->flags &= ~FmtWidth;
                }
                if(fl & FmtSharp){
                        if(base == 16)
       t@@ -473,7 +509,7 @@ __ifmt(Fmt *f)
                else if(fl & FmtSpace)
                        *p-- = ' ';
                f->flags &= ~FmtPrec;
       -        return __fmtcpy(f, p + 1, n, n);
       +        return __fmtcpy(f, p + 1, n, n + excess);
        }
        
        int
       t@@ -514,6 +550,9 @@ __flagfmt(Fmt *f)
                case '#':
                        f->flags |= FmtSharp;
                        break;
       +        case '\'':
       +                f->flags |= FmtApost;
       +                break;
                case ' ':
                        f->flags |= FmtSpace;
                        break;
 (DIR) diff --git a/src/lib9/fmt/dorfmt.c b/src/lib9/fmt/dorfmt.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
       t@@ -19,6 +7,7 @@
        
        /* format the output into f->to and return the number of characters fmted  */
        
       +/* BUG: THIS FILE IS NOT UPDATED TO THE  NEW SPEC */
        int
        dorfmt(Fmt *f, const Rune *fmt)
        {
       t@@ -30,8 +19,8 @@ dorfmt(Fmt *f, const Rune *fmt)
                nfmt = f->nfmt;
                for(;;){
                        if(f->runes){
       -                        rt = f->to;
       -                        rs = f->stop;
       +                        rt = (Rune*)f->to;
       +                        rs = (Rune*)f->stop;
                                while((r = *fmt++) && r != '%'){
                                        FMTRCHAR(f, rt, rs, r);
                                }
       t@@ -41,8 +30,8 @@ dorfmt(Fmt *f, const Rune *fmt)
                                        return f->nfmt - nfmt;
                                f->stop = rs;
                        }else{
       -                        t = f->to;
       -                        s = f->stop;
       +                        t = (char*)f->to;
       +                        s = (char*)f->stop;
                                while((r = *fmt++) && r != '%'){
                                        FMTRUNE(f, t, f->stop, r);
                                }
       t@@ -53,7 +42,7 @@ dorfmt(Fmt *f, const Rune *fmt)
                                f->stop = s;
                        }
        
       -                fmt = __fmtdispatch(f, (Rune*)fmt, 1);
       +                fmt = (Rune*)__fmtdispatch(f, (Rune*)fmt, 1);
                        if(fmt == nil)
                                return -1;
                }
 (DIR) diff --git a/src/lib9/fmt/errfmt.c b/src/lib9/fmt/errfmt.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <errno.h>
        #include <string.h>
 (DIR) diff --git a/src/lib9/fmt/fltfmt.c b/src/lib9/fmt/fltfmt.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdio.h>
        #include <math.h>
        #include <float.h>
 (DIR) diff --git a/src/lib9/fmt/fmt.c b/src/lib9/fmt/fmt.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
       t@@ -29,7 +17,7 @@ struct Convfmt
                volatile        Fmts        fmt;        /* for spin lock in fmtfmt; avoids race due to write order */
        };
        
       -struct
       +static struct
        {
                /* lock by calling __fmtlock, __fmtunlock */
                int        nfmt;
       t@@ -40,6 +28,7 @@ static Convfmt knownfmt[] = {
                ' ',        __flagfmt,
                '#',        __flagfmt,
                '%',        __percentfmt,
       +        '\'',        __flagfmt,
                '+',        __flagfmt,
                ',',        __flagfmt,
                '-',        __flagfmt,
 (DIR) diff --git a/src/lib9/fmt/fmtdef.h b/src/lib9/fmt/fmtdef.h
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
       - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        
        /*
         * dofmt -- format to a buffer
       t@@ -66,9 +54,9 @@ int          __strfmt(Fmt *f);
        #define FMTCHAR(f, t, s, c)\
                do{\
                if(t + 1 > (char*)s){\
       -                t = __fmtflush(f, t, 1);\
       +                t = (char*)__fmtflush(f, t, 1);\
                        if(t != nil)\
       -                        s = f->stop;\
       +                        s = (char*)f->stop;\
                        else\
                                return -1;\
                }\
       t@@ -78,9 +66,9 @@ int          __strfmt(Fmt *f);
        #define FMTRCHAR(f, t, s, c)\
                do{\
                if(t + 1 > (Rune*)s){\
       -                t = __fmtflush(f, t, sizeof(Rune));\
       +                t = (Rune*)__fmtflush(f, t, sizeof(Rune));\
                        if(t != nil)\
       -                        s = f->stop;\
       +                        s = (Rune*)f->stop;\
                        else\
                                return -1;\
                }\
       t@@ -92,9 +80,9 @@ int          __strfmt(Fmt *f);
                Rune _rune;\
                int _runelen;\
                if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\
       -                t = __fmtflush(f, t, _runelen);\
       +                t = (char*)__fmtflush(f, t, _runelen);\
                        if(t != nil)\
       -                        s = f->stop;\
       +                        s = (char*)f->stop;\
                        else\
                                return -1;\
                }\
 (DIR) diff --git a/src/lib9/fmt/fmtfd.c b/src/lib9/fmt/fmtfd.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
       t@@ -41,6 +29,8 @@ fmtfdinit(Fmt *f, int fd, char *buf, int size)
                f->stop = buf + size;
                f->flush = __fmtFdFlush;
                f->farg = (void*)(uintptr_t)fd;
       +        f->flags = 0;
                f->nfmt = 0;
       +        fmtlocaleinit(f, nil, nil, nil);
                return 0;
        }
 (DIR) diff --git a/src/lib9/fmt/fmtfdflush.c b/src/lib9/fmt/fmtfdflush.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <unistd.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/fmtlocale.c b/src/lib9/fmt/fmtlocale.c
       t@@ -0,0 +1,56 @@
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
       +#include <stdarg.h>
       +#include <string.h>
       +#include "plan9.h"
       +#include "fmt.h"
       +#include "fmtdef.h"
       +
       +/* XXX GOOGLE COPYRIGHT */
       +
       +/*
       + * Fill in the internationalization stuff in the State structure.
       + * For nil arguments, provide the sensible defaults:
       + *        decimal is a period
       + *        thousands separator is a comma
       + *        thousands are marked every three digits
       + */
       +void
       +fmtlocaleinit(Fmt *f, char *decimal, char *thousands, char *grouping)
       +{
       +        if(decimal == nil || decimal[0] == '\0')
       +                decimal = ".";
       +        if(thousands == nil)
       +                thousands = ",";
       +        if(grouping == nil)
       +                grouping = "\3";
       +        f->decimal = decimal;
       +        f->thousands = thousands;
       +        f->grouping = grouping;
       +}
       +
       +/*
       + * We are about to emit a digit in e.g. %'d.  If that digit would
       + * overflow a thousands (e.g.) grouping, tell the caller to emit
       + * the thousands separator.  Always advance the digit counter
       + * and pointer into the grouping descriptor.
       + */
       +int
       +__needsep(int *ndig, const char **grouping)
       +{
       +        int group;
       +        
       +        (*ndig)++;
       +        group = *(unsigned char*)*grouping;
       +        /* CHAR_MAX means no further grouping. \0 means we got the empty string */
       +        if(group == 0xFF || group == 0x7f || group == 0x00)
       +                return 0;
       +        if(*ndig > group){
       +                /* if we're at end of string, continue with this grouping; else advance */
       +                if((*grouping)[1] != '\0')
       +                        (*grouping)++;
       +                *ndig = 1;
       +                return 1;
       +        }
       +        return 0;
       +}
       +
 (DIR) diff --git a/src/lib9/fmt/fmtlock.c b/src/lib9/fmt/fmtlock.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/fmtprint.c b/src/lib9/fmt/fmtprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/fmtquote.c b/src/lib9/fmt/fmtquote.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
       t@@ -120,8 +108,10 @@ qstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f)
                rm = rin;
                rme = rm + q->nrunesin;
        
       -        w = f->width;
                fl = f->flags;
       +        w = 0;
       +        if(fl & FmtWidth)
       +                w = f->width;
                if(f->runes){
                        if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)
                                return -1;
 (DIR) diff --git a/src/lib9/fmt/fmtrune.c b/src/lib9/fmt/fmtrune.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/fmtstr.c b/src/lib9/fmt/fmtstr.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdlib.h>
        #include <stdarg.h>
        #include "plan9.h"
       t@@ -23,5 +11,6 @@ fmtstrflush(Fmt *f)
                if(f->start == nil)
                        return nil;
                *(char*)f->to = '\0';
       +        f->to = f->start;
                return (char*)f->start;
        }
 (DIR) diff --git a/src/lib9/fmt/fmtvprint.c b/src/lib9/fmt/fmtvprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/fprint.c b/src/lib9/fmt/fprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/pow10.c b/src/lib9/fmt/pow10.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/print.c b/src/lib9/fmt/print.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/runefmtstr.c b/src/lib9/fmt/runefmtstr.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <stdlib.h>
        #include "plan9.h"
       t@@ -23,5 +11,6 @@ runefmtstrflush(Fmt *f)
                if(f->start == nil)
                        return nil;
                *(Rune*)f->to = '\0';
       +        f->to = f->start;
                return f->start;
        }
 (DIR) diff --git a/src/lib9/fmt/runeseprint.c b/src/lib9/fmt/runeseprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/runesmprint.c b/src/lib9/fmt/runesmprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/runesnprint.c b/src/lib9/fmt/runesnprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/runesprint.c b/src/lib9/fmt/runesprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/runevseprint.c b/src/lib9/fmt/runevseprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/runevsmprint.c b/src/lib9/fmt/runevsmprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        /*
         * Plan 9 port version must include libc.h in order to 
         * get Plan 9 debugging malloc, which sometimes returns
       t@@ -69,6 +57,7 @@ runefmtstrinit(Fmt *f)
                f->flush = runeFmtStrFlush;
                f->farg = (void*)(uintptr)n;
                f->nfmt = 0;
       +        fmtlocaleinit(f, nil, nil, nil);
                return 0;
        }
        
 (DIR) diff --git a/src/lib9/fmt/runevsnprint.c b/src/lib9/fmt/runevsnprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <string.h>
        #include "plan9.h"
       t@@ -32,6 +20,7 @@ runevsnprint(Rune *buf, int len, char *fmt, va_list args)
                f.farg = nil;
                f.nfmt = 0;
                VA_COPY(f.args,args);
       +        fmtlocaleinit(&f, nil, nil, nil);
                dofmt(&f, fmt);
                VA_END(f.args);
                *(Rune*)f.to = '\0';
 (DIR) diff --git a/src/lib9/fmt/seprint.c b/src/lib9/fmt/seprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/smprint.c b/src/lib9/fmt/smprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/snprint.c b/src/lib9/fmt/snprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/sprint.c b/src/lib9/fmt/sprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include <fmt.h>
        #include "plan9.h"
 (DIR) diff --git a/src/lib9/fmt/strtod.c b/src/lib9/fmt/strtod.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdlib.h>
        #include <math.h>
        #include <ctype.h>
       t@@ -239,7 +227,7 @@ fmtstrtod(const char *as, char **aas)
                /* close approx by naive conversion */
                mid[0] = 0;
                mid[1] = 1;
       -        for(i=0; c=a[i]; i++) {
       +        for(i=0; (c=a[i]) != '\0'; i++) {
                        mid[0] = mid[0]*10 + (c-'0');
                        mid[1] = mid[1]*10;
                        if(i >= 8)
       t@@ -521,7 +509,7 @@ xcmp(char *a, char *b)
        {
                int c1, c2;
        
       -        while(c1 = *b++) {
       +        while((c1 = *b++) != '\0') {
                        c2 = *a++;
                        if(isupper(c2))
                                c2 = tolower(c2);
 (DIR) diff --git a/src/lib9/fmt/test.c b/src/lib9/fmt/test.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdio.h>
        #include <stdarg.h>
        #include <utf.h>
       t@@ -40,5 +28,24 @@ main(int argc, char *argv[])
                print("%d\n", 23);
                print("%i\n", 23);
                print("%0.10d\n", 12345);
       +
       +        /* test %4$d formats */
       +        print("%3$d %4$06d %2$d %1$d\n", 444, 333, 111, 222);
       +        print("%3$d %4$06d %2$d %1$d\n", 444, 333, 111, 222);
       +        print("%3$d %4$*5$06d %2$d %1$d\n", 444, 333, 111, 222, 20);
       +        print("%3$hd %4$*5$06d %2$d %1$d\n", 444, 333, (short)111, 222, 20);
       +        print("%3$lld %4$*5$06d %2$d %1$d\n", 444, 333, 111LL, 222, 20);
       +
       +        /* test %'d formats */
       +        print("%'d %'d %'d\n", 1, 2222, 33333333);
       +        print("%'019d\n", 0);
       +        print("%08d %08d %08d\n", 1, 2222, 33333333);
       +        print("%'08d %'08d %'08d\n", 1, 2222, 33333333);
       +        print("%'x %'X %'b\n", 0x11111111, 0xabcd1234, 12345);
       +        print("%'lld %'lld %'lld\n", 1LL, 222222222LL, 3333333333333LL);
       +        print("%019lld %019lld %019lld\n", 1LL, 222222222LL, 3333333333333LL);
       +        print("%'019lld %'019lld %'019lld\n", 1LL, 222222222LL, 3333333333333LL);
       +        print("%'020lld %'020lld %'020lld\n", 1LL, 222222222LL, 3333333333333LL);
       +        print("%'llx %'llX %'llb\n", 0x111111111111LL, 0xabcd12345678LL, 112342345LL);
                return 0;
        }
 (DIR) diff --git a/src/lib9/fmt/vfprint.c b/src/lib9/fmt/vfprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/vseprint.c b/src/lib9/fmt/vseprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdarg.h>
        #include "plan9.h"
        #include "fmt.h"
 (DIR) diff --git a/src/lib9/fmt/vsmprint.c b/src/lib9/fmt/vsmprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        /*
         * Plan 9 port version must include libc.h in order to 
         * get Plan 9 debugging malloc, which sometimes returns
       t@@ -69,6 +57,7 @@ fmtstrinit(Fmt *f)
                f->flush = fmtStrFlush;
                f->farg = (void*)(uintptr)n;
                f->nfmt = 0;
       +        fmtlocaleinit(f, nil, nil, nil);
                return 0;
        }
        
 (DIR) diff --git a/src/lib9/fmt/vsnprint.c b/src/lib9/fmt/vsnprint.c
       t@@ -1,16 +1,4 @@
       -/*
       - * The authors of this software are Rob Pike and Ken Thompson.
       - *              Copyright (c) 2002 by Lucent Technologies.
       - * Permission to use, copy, modify, and distribute this software for any
       - * purpose without fee is hereby granted, provided that this entire notice
       - * is included in all copies of any software which is or includes a copy
       - * or modification of this software and in all copies of the supporting
       - * documentation for such software.
       - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
       - * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
       - * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
       - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
       - */
       +/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
        #include <stdlib.h>
        #include <stdarg.h>
        #include "plan9.h"
       t@@ -32,6 +20,7 @@ vsnprint(char *buf, int len, char *fmt, va_list args)
                f.farg = nil;
                f.nfmt = 0;
                VA_COPY(f.args,args);
       +        fmtlocaleinit(&f, nil, nil, nil);
                dofmt(&f, fmt);
                VA_END(f.args);
                *(char*)f.to = '\0';
 (DIR) diff --git a/src/lib9/testfltfmt.c b/src/lib9/testfltfmt.c
       t@@ -0,0 +1,166 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <stdio.h>
       +
       +/*
       + * try all combination of flags and float conversions
       + * with some different widths & precisions
       + */
       +
       +#define Njust 2
       +#define Nplus 3
       +#define Nalt 2
       +#define Nzero 2
       +#define Nspec 5
       +#define Nwidth 5
       +#define Nprec 5
       +
       +static double fmtvals[] = {
       +        3.1415925535897932e15,
       +        3.1415925535897932e14,
       +        3.1415925535897932e13,
       +        3.1415925535897932e12,
       +        3.1415925535897932e11,
       +        3.1415925535897932e10,
       +        3.1415925535897932e9,
       +        3.1415925535897932e8,
       +        3.1415925535897932e7,
       +        3.1415925535897932e6,
       +        3.1415925535897932e5,
       +        3.1415925535897932e4,
       +        3.1415925535897932e3,
       +        3.1415925535897932e2,
       +        3.1415925535897932e1,
       +        3.1415925535897932e0,
       +        3.1415925535897932e-1,
       +        3.1415925535897932e-2,
       +        3.1415925535897932e-3,
       +        3.1415925535897932e-4,
       +        3.1415925535897932e-5,
       +        3.1415925535897932e-6,
       +        3.1415925535897932e-7,
       +        3.1415925535897932e-8,
       +        3.1415925535897932e-9,
       +        3.1415925535897932e-10,
       +        3.1415925535897932e-11,
       +        3.1415925535897932e-12,
       +        3.1415925535897932e-13,
       +        3.1415925535897932e-14,
       +        3.1415925535897932e-15,
       +};
       +
       +/*
       + * are the numbers close?
       + * used to compare long numbers where the last few digits are garbage
       + * due to precision problems
       + */
       +static int
       +numclose(char *num1, char *num2)
       +{
       +        int ndig;
       +        enum { MAXDIG = 15 };
       +
       +        ndig = 0;
       +        while (*num1) {
       +                if (*num1 >= '0' && *num1 <= '9') {
       +                        ndig++;
       +                        if (ndig > MAXDIG) {
       +                                if (!(*num2 >= '0' && *num2 <= '9')) {
       +                                        return 0;
       +                                }
       +                        } else if (*num1 != *num2) {
       +                                return 0;
       +                        }
       +                } else if (*num1 != *num2) {
       +                        return 0;
       +                } else if (*num1 == 'e' || *num1 == 'E') {
       +                        ndig = 0;
       +                }
       +                num1++;
       +                num2++;
       +        }
       +        if (*num1 || !num2)
       +                return 0;
       +        return 1;
       +}
       +
       +static void
       +doit(int just, int plus, int alt, int zero, int width, int prec, int spec)
       +{
       +        char format[256];
       +        char *p;
       +        const char *s;
       +        int i;
       +
       +        p = format;
       +        *p++ = '%';
       +        if (just > 0)
       +                *p++ = "-"[just - 1];
       +        if (plus > 0)
       +                *p++ = "+ "[plus - 1];
       +        if (alt > 0)
       +                *p++ = "#"[alt - 1];
       +        if (zero > 0)
       +                *p++ = "0"[zero - 1];
       +
       +        s = "";
       +        switch (width) {
       +        case 1: s = "1"; break;
       +        case 2: s = "5"; break;
       +        case 3: s = "10"; break;
       +        case 4: s = "15"; break;
       +        }
       +        strcpy(p, s);
       +
       +        s = "";
       +        switch (prec) {
       +        case 1: s = ".0"; break;
       +        case 2: s = ".2"; break;
       +        case 3: s = ".5"; break;
       +        case 4: s = ".15"; break;
       +        }
       +        strcat(p, s);
       +
       +        p = strchr(p, '\0');
       +        *p++ = "efgEG"[spec];
       +        *p = '\0';
       +
       +        for (i = 0; i < sizeof(fmtvals) / sizeof(fmtvals[0]); i++) {
       +                char ref[256], buf[256];
       +                Rune rbuf[256];
       +
       +                sprintf(ref, format, fmtvals[i]);
       +                snprint(buf, sizeof(buf), format, fmtvals[i]);
       +                if (strcmp(ref, buf) != 0
       +                && !numclose(ref, buf)) {
       +                        fprintf(stderr, "%s: ref='%s' fmt='%s'\n", format, ref, buf);
       +                        exit(1);
       +                }
       +
       +                /* Check again with output to rune string */
       +                runesnprint(rbuf, 256, format, fmtvals[i]);
       +                snprint(buf, sizeof(buf), "%S", rbuf);
       +                if (strcmp(ref, buf) != 0
       +                && !numclose(ref, buf)) {
       +                        fprintf(stderr, "%s: rune ref='%s' fmt='%s'\n", format, ref, buf);
       +                        exits("oops");
       +                }
       +        }
       +}
       +
       +void
       +main(int argc, char **argv)
       +{
       +        int just, plus, alt, zero, width, prec, spec;
       +
       +        for (just = 0; just < Njust; just++)
       +        for (plus = 0; plus < Nplus; plus++)
       +        for (alt = 0; alt < Nalt; alt++)
       +        for (zero = 0; zero < Nzero; zero++)
       +        for (width = 0; width < Nwidth; width++)
       +        for (prec = 0; prec < Nprec; prec++)
       +        for (spec = 0; spec < Nspec; spec++)
       +                doit(just, plus, alt, zero, width, prec, spec);
       +
       +        exits(0);
       +}
 (DIR) diff --git a/src/lib9/testfmt.c b/src/lib9/testfmt.c
       t@@ -0,0 +1,114 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <stdio.h>
       +
       +int failed;
       +
       +/* Consume argument and ignore it */
       +int
       +Zflag(Fmt* f)
       +{
       +        if(va_arg(f->args, int))
       +                ;
       +        return 1;        /* it's a flag */
       +}
       +
       +void
       +verify(char *s, char *t)
       +{
       +        if(strcmp(s, t) != 0){
       +                failed = 1;
       +                fprintf(stderr, "error: (%s) != (%s)\n", s, t);
       +        }
       +        free(s);
       +}
       +
       +Rune lightsmiley = 0x263a;
       +Rune darksmiley = 0x263b;
       +
       +/* Test printer that loads unusual decimal point and separator */
       +char*
       +mysmprint(char *fmt, ...)
       +{
       +        Fmt f;
       +
       +        if(fmtstrinit(&f) < 0)
       +                return 0;
       +        va_start(f.args, fmt);
       +        f.decimal = smprint("%C", lightsmiley);
       +        f.thousands = smprint("%C", darksmiley);
       +        f.grouping = "\1\2\3\4";
       +        if(dofmt(&f, fmt) < 0)
       +                return 0;
       +        va_end(f.args);
       +        return fmtstrflush(&f);
       +}
       +
       +
       +void
       +main(int argc, char **argv)
       +{
       +        quotefmtinstall();
       +        fmtinstall('Z', Zflag);
       +        fmtinstall(L'\x263a', Zflag);
       +
       +        verify(smprint("hello world"), "hello world");
       +#ifdef PLAN9PORT
       +        verify(smprint("x: %ux", 0x87654321), "x: 87654321");
       +#else
       +        verify(smprint("x: %x", 0x87654321), "x: 87654321");
       +#endif
       +        verify(smprint("d: %d", 0x87654321), "d: -2023406815");
       +        verify(smprint("s: %s", "hi there"), "s: hi there");
       +        verify(smprint("q: %q", "hi i'm here"), "q: 'hi i''m here'");
       +        verify(smprint("c: %c", '!'), "c: !");
       +        verify(smprint("g: %g %g %g", 3.14159, 3.14159e10, 3.14159e-10), "g: 3.14159 3.14159e+10 3.14159e-10");
       +        verify(smprint("e: %e %e %e", 3.14159, 3.14159e10, 3.14159e-10), "e: 3.141590e+00 3.141590e+10 3.141590e-10");
       +        verify(smprint("f: %f %f %f", 3.14159, 3.14159e10, 3.14159e-10), "f: 3.141590 31415900000.000000 0.000000");
       +        verify(smprint("smiley: %C", (Rune)0x263a), "smiley: \xe2\x98\xba");
       +        verify(smprint("%g %.18g", 2e25, 2e25), "2e+25 2e+25");
       +        verify(smprint("%2.18g", 1.0), " 1");
       +        verify(smprint("%f", 3.1415927/4), "0.785398");
       +        verify(smprint("%d", 23), "23");
       +        verify(smprint("%i", 23), "23");
       +        verify(smprint("%Zi", 1234, 23), "23");
       +
       +        /* test $ reorderings */
       +        verify(smprint("%3$d %4$06d %2$d %1$d", 444, 333, 111, 222), "111 000222 333 444");
       +        verify(smprint("%3$Zd %5$06d %2$d %1$d", 444, 333, 555, 111, 222), "111 000222 333 444");
       +        verify(smprint("%3$d %4$*5$06d %2$d %1$d", 444, 333, 111, 222, 20), "111               000222 333 444");
       +        verify(smprint("%3$hd %4$*5$06d %2$d %1$d", 444, 333, (short)111, 222, 20), "111               000222 333 444");
       +        verify(smprint("%3$\xe2\x98\xba""d %5$06d %2$d %1$d", 444, 333, 555, 111, 222), "111 000222 333 444");
       +        
       +        /* test %'d formats */
       +        verify(smprint("%'d %'d %'d", 1, 2222, 33333333), "1 2,222 33,333,333");
       +        verify(smprint("%'019d", 0), "000,000,000,000,000");
       +        verify(smprint("%'08d %'08d %'08d", 1, 2222, 33333333), "0,000,001 0,002,222 33,333,333");
       +#ifdef PLAN9PORT
       +        verify(smprint("%'ux %'uX %'ub", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001");
       +#else
       +        verify(smprint("%'x %'X %'b", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001");
       +#endif
       +        verify(smprint("%'lld %'lld %'lld", 1LL, 222222222LL, 3333333333333LL), "1 222,222,222 3,333,333,333,333");
       +        verify(smprint("%'019lld %'019lld %'019lld", 1LL, 222222222LL, 3333333333333LL), "000,000,000,000,001 000,000,222,222,222 003,333,333,333,333");
       +#ifdef PLAN9PORT
       +        verify(smprint("%'llux %'lluX %'llub", 0x111111111111LL, 0xabcd12345678LL, 112342345LL), "1111:1111:1111 ABCD:1234:5678 110:1011:0010:0011:0101:0100:1001");
       +#else
       +        verify(smprint("%'llx %'llX %'llb", 0x111111111111LL, 0xabcd12345678LL, 112342345LL), "1111:1111:1111 ABCD:1234:5678 110:1011:0010:0011:0101:0100:1001");
       +#endif
       +
       +        /* test %'d with custom (utf-8!) separators */
       +        /* x and b still use : */
       +        verify(mysmprint("%'d %'d %'d", 1, 2222, 33333333), "1 2\xe2\x98\xbb""22\xe2\x98\xbb""2 33\xe2\x98\xbb""333\xe2\x98\xbb""33\xe2\x98\xbb""3");
       +#ifdef PLAN9PORT
       +        verify(mysmprint("%'ux %'uX %'ub", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001");
       +#else
       +        verify(mysmprint("%'x %'X %'b", 0x11111111, 0xabcd1234, 12345), "1111:1111 ABCD:1234 11:0000:0011:1001");
       +#endif
       +        verify(mysmprint("%'lld %'lld %'lld", 1LL, 222222222LL, 3333333333333LL), "1 222\xe2\x98\xbb""222\xe2\x98\xbb""22\xe2\x98\xbb""2 333\xe2\x98\xbb""3333\xe2\x98\xbb""333\xe2\x98\xbb""33\xe2\x98\xbb""3");
       +        verify(mysmprint("%'llx %'llX %'llb", 0x111111111111LL, 0xabcd12345678LL, 112342345LL), "1111:1111:1111 ABCD:1234:5678 110:1011:0010:0011:0101:0100:1001");
       +
       +        if(failed)
       +                sysfatal("tests failed");
       +        exits(0);
       +}