~ubuntu-branches/ubuntu/lucid/9base/lucid

« back to all changes in this revision

Viewing changes to lib9/fmt/dofmt.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-08-20 17:34:06 UTC
  • mfrom: (6.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090820173406-xpwqa9ruyevvc0ut
Tags: 1:3-3
* Updating maintainer field.
* Updating vcs fields.
* Updating package to standards version 3.8.3.
* Updatin variables writing in rules to consistent style.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * The authors of this software are Rob Pike and Ken Thompson.
3
 
 *              Copyright (c) 2002 by Lucent Technologies.
4
 
 * Permission to use, copy, modify, and distribute this software for any
5
 
 * purpose without fee is hereby granted, provided that this entire notice
6
 
 * is included in all copies of any software which is or includes a copy
7
 
 * or modification of this software and in all copies of the supporting
8
 
 * documentation for such software.
9
 
 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
10
 
 * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE
11
 
 * ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
12
 
 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
13
 
 */
 
1
/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
 
2
/* Copyright (c) 2004 Google Inc.; see LICENSE */
 
3
 
14
4
#include <stdarg.h>
15
5
#include <string.h>
16
6
#include "plan9.h"
97
87
 
98
88
/*
99
89
 * put a formatted block of memory sz bytes long of n runes into the output buffer,
100
 
 * left/right justified in a field of at least f->width charactes
 
90
 * left/right justified in a field of at least f->width characters (if FmtWidth is set)
101
91
 */
102
92
int
103
93
__fmtpad(Fmt *f, int n)
139
129
 
140
130
        m = (char*)vm;
141
131
        me = m + sz;
142
 
        w = f->width;
143
132
        fl = f->flags;
 
133
        w = 0;
 
134
        if(fl & FmtWidth)
 
135
                w = f->width;
144
136
        if((fl & FmtPrec) && n > f->prec)
145
137
                n = f->prec;
146
138
        if(f->runes){
194
186
        int w;
195
187
 
196
188
        m = (Rune*)vm;
197
 
        w = f->width;
198
189
        fl = f->flags;
 
190
        w = 0;
 
191
        if(fl & FmtWidth)
 
192
                w = f->width;
199
193
        if((fl & FmtPrec) && n > f->prec)
200
194
                n = f->prec;
201
195
        if(f->runes){
252
246
fmtstrcpy(Fmt *f, char *s)
253
247
{
254
248
        int i, j;
255
 
        Rune r;
256
249
 
257
250
        if(!s)
258
251
                return __fmtcpy(f, "<nil>", 5, 5);
259
252
        /* if precision is specified, make sure we don't wander off the end */
260
253
        if(f->flags & FmtPrec){
 
254
#ifdef PLAN9PORT
 
255
                Rune r;
261
256
                i = 0;
262
257
                for(j=0; j<f->prec && s[i]; j++)
263
258
                        i += chartorune(&r, s+i);
 
259
#else
 
260
                /* ANSI requires precision in bytes, not Runes */
 
261
                for(i=0; i<f->prec; i++)
 
262
                        if(s[i] == 0)
 
263
                                break;
 
264
                j = utfnlen(s, i);      /* won't print partial at end */
 
265
#endif
264
266
                return __fmtcpy(f, s, j, i);
265
267
        }
266
268
        return __fmtcpy(f, s, utflen(s), strlen(s));
324
326
int
325
327
__ifmt(Fmt *f)
326
328
{
327
 
        char buf[70], *p, *conv;
 
329
        char buf[140], *p, *conv;
 
330
        /* 140: for 64 bits of binary + 3-byte sep every 4 digits */
328
331
        uvlong vu;
329
332
        ulong u;
330
333
        int neg, base, i, n, fl, w, isv;
 
334
        int ndig, len, excess, bytelen;
 
335
        char *grouping;
 
336
        char *thousands;
331
337
 
332
338
        neg = 0;
333
339
        fl = f->flags;
339
345
         * Unsigned verbs for ANSI C
340
346
         */
341
347
        switch(f->r){
342
 
        case 'x':
343
 
        case 'X':
344
348
        case 'o':
345
 
        case 'u':
346
349
        case 'p':
 
350
        case 'u':
 
351
        case 'x':
 
352
        case 'X':
347
353
                fl |= FmtUnsigned;
348
354
                fl &= ~(FmtSign|FmtSpace);
349
355
                break;
381
387
                        u = va_arg(f->args, int);
382
388
        }
383
389
        conv = "0123456789abcdef";
 
390
        grouping = "\4";        /* for hex, octal etc. (undefined by spec but nice) */
 
391
        thousands = f->thousands;
384
392
        switch(f->r){
385
393
        case 'd':
386
394
        case 'i':
387
395
        case 'u':
388
396
                base = 10;
389
 
                break;
390
 
        case 'x':
391
 
                base = 16;
 
397
                grouping = f->grouping;
392
398
                break;
393
399
        case 'X':
394
 
                base = 16;
395
400
                conv = "0123456789ABCDEF";
 
401
                /* fall through */
 
402
        case 'x':
 
403
                base = 16;
 
404
                thousands = ":";
396
405
                break;
397
406
        case 'b':
398
407
                base = 2;
 
408
                thousands = ":";
399
409
                break;
400
410
        case 'o':
401
411
                base = 8;
413
423
                }
414
424
        }
415
425
        p = buf + sizeof buf - 1;
416
 
        n = 0;
 
426
        n = 0;  /* in runes */
 
427
        excess = 0;     /* number of bytes > number runes */
 
428
        ndig = 0;
 
429
        len = utflen(thousands);
 
430
        bytelen = strlen(thousands);
417
431
        if(isv){
418
432
                while(vu){
419
433
                        i = vu % base;
422
436
                                *p-- = ',';
423
437
                                n++;
424
438
                        }
 
439
                        if((fl & FmtApost) && __needsep(&ndig, &grouping)){
 
440
                                n += len;
 
441
                                excess += bytelen - len;
 
442
                                p -= bytelen;
 
443
                                memmove(p+1, thousands, bytelen);
 
444
                        }
425
445
                        *p-- = conv[i];
426
446
                        n++;
427
447
                }
433
453
                                *p-- = ',';
434
454
                                n++;
435
455
                        }
 
456
                        if((fl & FmtApost) && __needsep(&ndig, &grouping)){
 
457
                                n += len;
 
458
                                excess += bytelen - len;
 
459
                                p -= bytelen;
 
460
                                memmove(p+1, thousands, bytelen);
 
461
                        }
436
462
                        *p-- = conv[i];
437
463
                        n++;
438
464
                }
439
465
        }
440
466
        if(n == 0){
441
 
                *p-- = '0';
442
 
                n = 1;
443
 
        }
444
 
        for(w = f->prec; n < w && p > buf+3; n++)
445
 
                *p-- = '0';
 
467
                /*
 
468
                 * "The result of converting a zero value with
 
469
                 * a precision of zero is no characters."  - ANSI
 
470
                 *
 
471
                 * "For o conversion, # increases the precision, if and only if
 
472
                 * necessary, to force the first digit of the result to be a zero
 
473
                 * (if the value and precision are both 0, a single 0 is printed)." - ANSI
 
474
                 */
 
475
                if(!(fl & FmtPrec) || f->prec != 0 || (f->r == 'o' && (fl & FmtSharp))){
 
476
                        *p-- = '0';
 
477
                        n = 1;
 
478
                        if(fl & FmtApost)
 
479
                                __needsep(&ndig, &grouping);
 
480
                }
 
481
                
 
482
                /*
 
483
                 * Zero values don't get 0x.
 
484
                 */
 
485
                if(f->r == 'x' || f->r == 'X')
 
486
                        fl &= ~FmtSharp;
 
487
        }
 
488
        for(w = f->prec; n < w && p > buf+3; n++){
 
489
                if((fl & FmtApost) && __needsep(&ndig, &grouping)){
 
490
                        n += len;
 
491
                        excess += bytelen - len;
 
492
                        p -= bytelen;
 
493
                        memmove(p+1, thousands, bytelen);
 
494
                }
 
495
                *p-- = '0';
 
496
        }
446
497
        if(neg || (fl & (FmtSign|FmtSpace)))
447
498
                n++;
448
499
        if(fl & FmtSharp){
456
507
                }
457
508
        }
458
509
        if((fl & FmtZero) && !(fl & (FmtLeft|FmtPrec))){
459
 
                for(w = f->width; n < w && p > buf+3; n++)
 
510
                w = 0;
 
511
                if(fl & FmtWidth)
 
512
                        w = f->width;
 
513
                for(; n < w && p > buf+3; n++){
 
514
                        if((fl & FmtApost) && __needsep(&ndig, &grouping)){
 
515
                                n += len;
 
516
                                excess += bytelen - len;
 
517
                                p -= bytelen;
 
518
                                memmove(p+1, thousands, bytelen);
 
519
                        }
460
520
                        *p-- = '0';
461
 
                f->width = 0;
 
521
                }
 
522
                f->flags &= ~FmtWidth;
462
523
        }
463
524
        if(fl & FmtSharp){
464
525
                if(base == 16)
473
534
        else if(fl & FmtSpace)
474
535
                *p-- = ' ';
475
536
        f->flags &= ~FmtPrec;
476
 
        return __fmtcpy(f, p + 1, n, n);
 
537
        return __fmtcpy(f, p + 1, n, n + excess);
477
538
}
478
539
 
479
540
int
514
575
        case '#':
515
576
                f->flags |= FmtSharp;
516
577
                break;
 
578
        case '\'':
 
579
                f->flags |= FmtApost;
 
580
                break;
517
581
        case ' ':
518
582
                f->flags |= FmtSpace;
519
583
                break;