mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Add bash 5.2 to third_party
This commit is contained in:
parent
e1f65d5f2b
commit
f4a2a65cc8
237 changed files with 120739 additions and 1 deletions
191
third_party/bash/fmtulong.c
vendored
Normal file
191
third_party/bash/fmtulong.c
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
/* fmtulong.c -- Convert unsigned long int to string. */
|
||||
|
||||
/* Copyright (C) 1998-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LIMITS_H)
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
#ifdef HAVE_STDDEF_H
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include "chartypes.h"
|
||||
#include <errno.h>
|
||||
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
#include "typemax.h"
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#define x_digs "0123456789abcdef"
|
||||
#define X_digs "0123456789ABCDEF"
|
||||
|
||||
/* XXX -- assumes uppercase letters, lowercase letters, and digits are
|
||||
contiguous */
|
||||
#define FMTCHAR(x) \
|
||||
((x) < 10) ? (x) + '0' \
|
||||
: (((x) < 36) ? (x) - 10 + 'a' \
|
||||
: (((x) < 62) ? (x) - 36 + 'A' \
|
||||
: (((x) == 62) ? '@' : '_')))
|
||||
|
||||
#ifndef FL_PREFIX
|
||||
# define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
|
||||
# define FL_ADDBASE 0x02 /* add base# prefix to converted value */
|
||||
# define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
|
||||
# define FL_UNSIGNED 0x08 /* don't add any sign */
|
||||
#endif
|
||||
|
||||
#ifndef LONG
|
||||
# define LONG long
|
||||
# define UNSIGNED_LONG unsigned long
|
||||
#endif
|
||||
|
||||
/* `unsigned long' (or unsigned long long) to string conversion for a given
|
||||
base. The caller passes the output buffer and the size. This should
|
||||
check for buffer underflow, but currently does not. */
|
||||
char *
|
||||
fmtulong (ui, base, buf, len, flags)
|
||||
UNSIGNED_LONG ui;
|
||||
int base;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
{
|
||||
char *p;
|
||||
int sign;
|
||||
LONG si;
|
||||
|
||||
if (base == 0)
|
||||
base = 10;
|
||||
|
||||
if (base < 2 || base > 64)
|
||||
{
|
||||
#if 1
|
||||
/* XXX - truncation possible with long translation */
|
||||
strncpy (buf, _("invalid base"), len - 1);
|
||||
buf[len-1] = '\0';
|
||||
errno = EINVAL;
|
||||
return (p = buf);
|
||||
#else
|
||||
base = 10;
|
||||
#endif
|
||||
}
|
||||
|
||||
sign = 0;
|
||||
if ((flags & FL_UNSIGNED) == 0 && (LONG)ui < 0)
|
||||
{
|
||||
ui = -ui;
|
||||
sign = '-';
|
||||
}
|
||||
|
||||
p = buf + len - 2;
|
||||
p[1] = '\0';
|
||||
|
||||
/* handle common cases explicitly */
|
||||
switch (base)
|
||||
{
|
||||
case 10:
|
||||
if (ui < 10)
|
||||
{
|
||||
*p-- = TOCHAR (ui);
|
||||
break;
|
||||
}
|
||||
/* Favor signed arithmetic over unsigned arithmetic; it is faster on
|
||||
many machines. */
|
||||
if ((LONG)ui < 0)
|
||||
{
|
||||
*p-- = TOCHAR (ui % 10);
|
||||
si = ui / 10;
|
||||
}
|
||||
else
|
||||
si = ui;
|
||||
do
|
||||
*p-- = TOCHAR (si % 10);
|
||||
while (si /= 10);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
do
|
||||
*p-- = TOCHAR (ui & 7);
|
||||
while (ui >>= 3);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
do
|
||||
*p-- = (flags & FL_HEXUPPER) ? X_digs[ui & 15] : x_digs[ui & 15];
|
||||
while (ui >>= 4);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
do
|
||||
*p-- = TOCHAR (ui & 1);
|
||||
while (ui >>= 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
do
|
||||
*p-- = FMTCHAR (ui % base);
|
||||
while (ui /= base);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((flags & FL_PREFIX) && (base == 8 || base == 16))
|
||||
{
|
||||
if (base == 16)
|
||||
{
|
||||
*p-- = (flags & FL_HEXUPPER) ? 'X' : 'x';
|
||||
*p-- = '0';
|
||||
}
|
||||
else if (p[1] != '0')
|
||||
*p-- = '0';
|
||||
}
|
||||
else if ((flags & FL_ADDBASE) && base != 10)
|
||||
{
|
||||
*p-- = '#';
|
||||
*p-- = TOCHAR (base % 10);
|
||||
if (base > 10)
|
||||
*p-- = TOCHAR (base / 10);
|
||||
}
|
||||
|
||||
if (sign)
|
||||
*p-- = '-';
|
||||
|
||||
return (p + 1);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue