1 /* fmt/sllnum.c - Format a signed long long integer.
2 * Copyright (C) 2004,2005 Bruce Guenter <bruce@untroubled.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #include "fmt.h"
19
rec(char * buffer,long long num,int sign,unsigned width,char pad,unsigned base,const char * digits)20 static unsigned rec(char* buffer, long long num, int sign,
21 unsigned width, char pad,
22 unsigned base, const char* digits)
23 {
24 char* s = buffer;
25 if (width) --width;
26 if (num >= (long long)base)
27 s += rec(s, num/base, sign, width, pad, base, digits);
28 else
29 s += fmt_sign_pad(s, sign, width, pad);
30 *s++ = digits[num % base];
31 return s - buffer;
32 }
33
34 /** Format a signed long long integer of arbitrary base with optional
35 padding. */
fmt_sllnumw(char * buffer,long long num,unsigned width,char pad,unsigned base,const char * digits)36 unsigned fmt_sllnumw(char* buffer, long long num, unsigned width, char pad,
37 unsigned base, const char* digits)
38 {
39 char* s = buffer;
40 int sign;
41
42 sign = 0;
43 if (num < 0) {
44 sign = 1;
45 num = -num;
46 if (width) -- width;
47 }
48 if (buffer == 0) {
49 unsigned len;
50 for (len = 1; num >= base; ++len)
51 num /= base;
52 return ((width > len) ? width : len) + sign;
53 }
54 if (num < (long long)base) {
55 s += fmt_sign_pad(s, sign, width-1, pad);
56 *s++ = digits[num];
57 }
58 else
59 s += rec(s, num, sign, width, pad, base, digits);
60 return s - buffer;
61 }
62
63 #ifdef SELFTEST_MAIN
test(long long num,unsigned width,char pad)64 void test(long long num, unsigned width, char pad)
65 {
66 char buf[FMT_ULONG_LEN];
67 obuf_putu(&outbuf, fmt_slldecw(0, num, width, pad));
68 obuf_putc(&outbuf, ':');
69 buf[fmt_sdecw(buf, num, width, pad)] = 0;
70 obuf_puts(&outbuf, buf);
71 NL();
72 }
73
74 MAIN
75 {
76 test( 0, 0, 0);
77 test( 10, 0, 0);
78 test(-10, 0, 0);
79 test( 10, 1, '0');
80 test(-10, 1, '0');
81 test( 10, 5, ' ');
82 test( 10, 5, '0');
83 test(-10, 5, ' ');
84 test(-10, 5, '0');
85 }
86 #endif
87 #ifdef SELFTEST_EXP
88 1:0
89 2:10
90 3:-10
91 2:10
92 3:-10
93 5: 10
94 5:00010
95 5: -10
96 5:-0010
97 #endif
98