1 /* fmtulong.c -- Convert unsigned long int to string. */
3 /* Copyright (C) 1998-2002 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
25 #if defined (HAVE_UNISTD_H)
29 #if defined (HAVE_LIMITS_H)
41 #ifdef HAVE_INTTYPES_H
42 # include <inttypes.h>
44 #include <chartypes.h>
57 #define x_digs "0123456789abcdef"
58 #define X_digs "0123456789ABCDEF"
60 /* XXX -- assumes uppercase letters, lowercase letters, and digits are
63 ((x) < 10) ? (x) + '0' \
64 : (((x) < 36) ? (x) - 10 + 'a' \
65 : (((x) < 62) ? (x) - 36 + 'A' \
66 : (((x) == 62) ? '@' : '_')))
69 # define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
70 # define FL_ADDBASE 0x02 /* add base# prefix to converted value */
71 # define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
72 # define FL_UNSIGNED 0x08 /* don't add any sign */
77 # define UNSIGNED_LONG unsigned long
80 /* `unsigned long' (or unsigned long long) to string conversion for a given
81 base. The caller passes the output buffer and the size. This should
82 check for buffer underflow, but currently does not. */
84 fmtulong (ui, base, buf, len, flags)
98 if (base < 2 || base > 64)
101 strncpy (buf, _("invalid base"), len - 1);
111 if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0)
120 /* handle common cases explicitly */
129 /* Favor signed arithmetic over unsigned arithmetic; it is faster on
133 *p-- = TOCHAR (ui % 10);
139 *p-- = TOCHAR (si % 10);
145 *p-- = TOCHAR (ui & 7);
151 *p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15];
157 *p-- = TOCHAR (ui & 1);
163 *p-- = FMTCHAR (ui % base);
168 if ((flags & FL_PREFIX) && (base == 8 || base == 16))
172 *p-- = (flags & FL_HEXUPPER) ? 'X' : 'x';
175 else if (p[1] != '0')
178 else if ((flags & FL_ADDBASE) && base != 10)
181 *p-- = TOCHAR (base % 10);
183 *p-- = TOCHAR (base / 10);