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 it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
25 #if defined (HAVE_UNISTD_H)
29 #if defined (HAVE_LIMITS_H)
41 #include <chartypes.h>
52 #define x_digs "0123456789abcdef"
53 #define X_digs "0123456789ABCDEF"
55 /* XXX -- assumes uppercase letters, lowercase letters, and digits are
58 ((x) < 10) ? (x) + '0' \
59 : (((x) < 36) ? (x) - 10 + 'a' \
60 : (((x) < 62) ? (x) - 36 + 'A' \
61 : (((x) == 62) ? '@' : '_')))
64 # define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
65 # define FL_ADDBASE 0x02 /* add base# prefix to converted value */
66 # define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
67 # define FL_UNSIGNED 0x08 /* don't add any sign */
72 # define UNSIGNED_LONG unsigned long
75 /* `unsigned long' (or unsigned long long) to string conversion for a given
76 base. The caller passes the output buffer and the size. This should
77 check for buffer underflow, but currently does not. */
79 fmtulong (ui, base, buf, len, flags)
93 if (base < 2 || base > 64)
96 strncpy (buf, "invalid base", len - 1);
106 if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0)
115 /* handle common cases explicitly */
124 /* Favor signed arithmetic over unsigned arithmetic; it is faster on
128 *p-- = TOCHAR (ui % 10);
134 *p-- = TOCHAR (si % 10);
140 *p-- = TOCHAR (ui & 7);
146 *p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15];
152 *p-- = TOCHAR (ui & 1);
158 *p-- = FMTCHAR (ui % base);
163 if ((flags & FL_PREFIX) && (base == 8 || base == 16))
167 *p-- = (flags & FL_HEXUPPER) ? 'X' : 'x';
170 else if (p[1] != '0')
173 else if ((flags & FL_ADDBASE) && base != 10)
176 *p-- = TOCHAR (base % 10);
178 *p-- = TOCHAR (base / 10);