summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrhodes <trhodes@FreeBSD.org>2005-12-24 22:37:59 +0000
committertrhodes <trhodes@FreeBSD.org>2005-12-24 22:37:59 +0000
commit8190ceb049ac4ab6148966f67d239e0618b7114b (patch)
tree7e59823292e97167e21df1524210e5c0d4ccf3c0
parent412f766852e2da36b4f178232cadb20dda832f61 (diff)
downloadFreeBSD-src-8190ceb049ac4ab6148966f67d239e0618b7114b.zip
FreeBSD-src-8190ceb049ac4ab6148966f67d239e0618b7114b.tar.gz
Add a64l(), l64a(), and l64a_r() XSI extentions. These functions convert
between a 32-bit integer and a radix-64 ASCII string. The l64a_r() function is a NetBSD addition. PR: 51209 (based on submission, but very different) Reviewed by: bde, ru
-rw-r--r--include/stdlib.h5
-rw-r--r--lib/libc/stdlib/Makefile.inc11
-rw-r--r--lib/libc/stdlib/a64l.3186
-rw-r--r--lib/libc/stdlib/a64l.c46
-rw-r--r--lib/libc/stdlib/l64a.c52
5 files changed, 293 insertions, 7 deletions
diff --git a/include/stdlib.h b/include/stdlib.h
index 1cc6c37..1fa4328 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -172,7 +172,7 @@ void unsetenv(const char *);
*/
#if __XSI_VISIBLE
/* XXX XSI requires pollution from <sys/wait.h> here. We'd rather not. */
-/* long a64l(const char *); */
+long a64l(const char *);
double drand48(void);
/* char *ecvt(double, int, int * __restrict, int * __restrict); */
double erand48(unsigned short[3]);
@@ -182,7 +182,7 @@ int getsubopt(char **, char *const *, char **);
int grantpt(int);
char *initstate(unsigned long /* XSI requires u_int */, char *, long);
long jrand48(unsigned short[3]);
-/* char *l64a(long); */
+char *l64a(long);
void lcong48(unsigned short[7]);
long lrand48(void);
#ifndef _MKSTEMP_DECLARED
@@ -258,6 +258,7 @@ __const char *
getprogname(void);
int heapsort(void *, size_t, size_t, int (*)(const void *, const void *));
+int l64a_r(long, char *, int);
int mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
void qsort_r(void *, size_t, size_t, void *,
int (*)(void *, const void *, const void *));
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index bebbc63..7883e96 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -4,12 +4,12 @@
# machine-independent stdlib sources
.PATH: ${.CURDIR}/${MACHINE_ARCH}/stdlib ${.CURDIR}/stdlib
-MISRCS+=_Exit.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
+MISRCS+=_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
bsearch.c calloc.c div.c exit.c getenv.c getopt.c getopt_long.c \
getsubopt.c grantpt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c \
- insque.c labs.c ldiv.c llabs.c lldiv.c lsearch.c malloc.c merge.c \
- putenv.c qsort.c qsort_r.c radixsort.c rand.c random.c reallocf.c \
- realpath.c remque.c setenv.c strfmon.c strtoimax.c \
+ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c malloc.c \
+ merge.c putenv.c qsort.c qsort_r.c radixsort.c rand.c random.c \
+ reallocf.c realpath.c remque.c setenv.c strfmon.c strtoimax.c \
strtol.c strtoll.c strtoq.c strtoul.c strtoull.c strtoumax.c strtouq.c \
system.c tdelete.c tfind.c tsearch.c twalk.c
@@ -18,12 +18,13 @@ MISRCS+=_Exit.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
.include "${.CURDIR}/${MACHINE_ARCH}/stdlib/Makefile.inc"
.endif
-MAN+= abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
+MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 atoi.3 atol.3 bsearch.3 \
div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 grantpt.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
lsearch.3 malloc.3 memory.3 qsort.3 radixsort.3 rand.3 random.3 \
realpath.3 strfmon.3 strtod.3 strtol.3 strtoul.3 system.3 tsearch.3
+MLINKS+=a64l.3 l64a.3 a64l.3 l64a_r.3
MLINKS+=atol.3 atoll.3
MLINKS+=exit.3 _Exit.3
MLINKS+=getenv.3 putenv.3 getenv.3 setenv.3 getenv.3 unsetenv.3
diff --git a/lib/libc/stdlib/a64l.3 b/lib/libc/stdlib/a64l.3
new file mode 100644
index 0000000..97545e9
--- /dev/null
+++ b/lib/libc/stdlib/a64l.3
@@ -0,0 +1,186 @@
+.\" Copyright (c) 2005 Tom Rhodes
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Portions of this text are reprinted and reproduced in electronic form
+.\" from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology --
+.\" Portable Operating System Interface (POSIX), The Open Group Base
+.\" Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of
+.\" Electrical and Electronics Engineers, Inc and The Open Group. In the
+.\" event of any discrepancy between this version and the original IEEE and
+.\" The Open Group Standard, the original IEEE and The Open Group Standard is
+.\" the referee document. The original Standard can be obtained online at
+.\" http://www.opengroup.org/unix/online.html.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd November 20, 2005
+.Dt A64L 3
+.Os
+.Sh NAME
+.Nm a64l ,
+.Nm l64a ,
+.Nm l64a_r
+.Nd "convert between a long integer and a base-64 ASCII string"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft long
+.Fn a64l "const char *s"
+.Ft char *
+.Fn l64a "long int l"
+.Ft int
+.Fn l64a_r "long int l" "char *buffer" "int buflen"
+.Sh DESCRIPTION
+These functions are used to maintain numbers stored in radix-64
+.Tn ASCII
+characters.
+This is a notation by which 32-bit integers can be represented by
+up to six characters; each character represents a digit in
+radix-64 notation.
+If the type long contains more than 32 bits, only the low-order
+32 bits are used for these operations.
+.Pp
+The characters used to represent
+.Dq digits
+are
+.Ql .\&
+for 0,
+.Ql /\&
+for 1,
+.Ql 0\&
+.Fl
+.Ql 9\&
+for 2
+.Fl
+11,
+.Ql A\&
+.Fl
+.Ql Z\&
+for 12
+.Fl
+37, and
+.Ql a\&
+.Fl
+.Ql z\&
+for 38
+.Fl
+63.
+.Pp
+The
+.Fn a64l
+function takes a pointer to a radix-64 representation, in which the first
+digit is the least significant, and returns a corresponding
+.Ft long
+value.
+If the string pointed to by
+.Fa s
+contains more than six characters,
+.Fn a64l
+uses the first six.
+If the first six characters of the string contain a null terminator,
+.Fn a64l
+uses only characters preceding the null terminator.
+The
+.Fn a64l
+function scans the character string from left to right with the least
+significant digit on the left, decoding each character as a 6-bit
+radix-64 number.
+If the type long contains more than 32 bits, the resulting value is
+sign-extended.
+The behavior of
+.Fn a64l
+is unspecified if
+.Fa s
+is a null pointer or the string pointed to by
+.Fa s
+was not generated by a previous call to
+.Fn l64a .
+.Pp
+The
+.Fn l64a
+function takes a long argument and returns a pointer to the corresponding
+radix-64 representation.
+The behavior of
+.Fn l64a
+is unspecified if value is negative.
+.Pp
+The value returned by
+.Fn l64a
+is a pointer into a static buffer.
+Subsequent calls to
+.Fn l64a
+may overwrite the buffer.
+.Pp
+The
+.Fn l64a_r
+function performs a conversion identical to that of
+.Fn l64a
+and stores the resulting representation in the memory area pointed to by
+.Fa buffer ,
+consuming at most
+.Fa buflen
+characters including the terminating NUL character.
+.Sh RETURN VALUES
+On successful completion,
+.Fn a64l
+returns the
+.Ft long
+value resulting from conversion of the input string.
+If a string pointed to by s is an empty string,
+.Fn a64l
+returns 0.
+.Pp
+The
+l64a
+function returns a pointer to the radix-64 representation.
+If value is 0,
+.Fn l64a
+returns a pointer to an empty string.
+.Sh SEE ALSO
+.Xr stroul 3
+.Sh HISTORY
+The
+.Fn a64l ,
+.Fn l64a ,
+and
+.Fn l64a_r
+functions are derived from
+.Nx
+with modifications.
+They were added to
+.Fx 6.1 .
+.Sh AUTHORS
+The
+.Fn a64l ,
+.Fn l64a ,
+and
+.Fn l64a_r
+were added to
+.Fx
+by
+.An Tom Rhodes Aq trhodes@FreeBSD.org .
+Almost all of this manual page came from the
+.Tn POSIX
+standard.
diff --git a/lib/libc/stdlib/a64l.c b/lib/libc/stdlib/a64l.c
new file mode 100644
index 0000000..6d175ef
--- /dev/null
+++ b/lib/libc/stdlib/a64l.c
@@ -0,0 +1,46 @@
+/*-
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: a64l.c,v 1.8 2000/01/22 22:19:19 mycroft Exp $");
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#define ADOT 46 /* ASCII '.' */
+#define ASLASH ADOT + 1 /* ASCII '/' */
+#define A0 48 /* ASCII '0' */
+#define AA 65 /* ASCII 'A' */
+#define Aa 97 /* ASCII 'a' */
+
+long
+a64l(const char *s)
+{
+ long shift;
+ int digit, i, value;
+
+ value = 0;
+ shift = 0;
+ for (i = 0; *s != '\0' && i < 6; i++, s++) {
+ if (*s <= ASLASH)
+ digit = *s - ASLASH + 1;
+ else if (*s <= A0 + 9)
+ digit = *s - A0 + 2;
+ else if (*s <= AA + 25)
+ digit = *s - AA + 12;
+ else
+ digit = *s - Aa + 38;
+
+ value |= digit << shift;
+ shift += 6;
+ }
+ return (value);
+}
diff --git a/lib/libc/stdlib/l64a.c b/lib/libc/stdlib/l64a.c
new file mode 100644
index 0000000..bc10553
--- /dev/null
+++ b/lib/libc/stdlib/l64a.c
@@ -0,0 +1,52 @@
+/*
+ * Written by J.T. Conklin <jtc@NetBSD.org>.
+ * Public domain.
+ */
+
+#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: l64a.c,v 1.13 2003/07/26 19:24:54 salo Exp $");
+#endif /* not lint */
+#endif
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdlib.h>
+
+#define ADOT 46 /* ASCII '.' */
+#define ASLASH ADOT + 1 /* ASCII '/' */
+#define A0 48 /* ASCII '0' */
+#define AA 65 /* ASCII 'A' */
+#define Aa 97 /* ASCII 'a' */
+
+char *
+l64a(long value)
+{
+ static char buf[8];
+
+ (void)l64a_r(value, buf, sizeof(buf));
+ return (buf);
+}
+
+int
+l64a_r(long value, char *buffer, int buflen)
+{
+ long v;
+ int digit;
+
+ v = value & (long)0xffffffff;
+ for (; v != 0 && buflen > 1; buffer++, buflen--) {
+ digit = v & 0x3f;
+ if (digit < 2)
+ *buffer = digit + ADOT;
+ else if (digit < 12)
+ *buffer = digit + A0 - 2;
+ else if (digit < 38)
+ *buffer = digit + AA - 12;
+ else
+ *buffer = digit + Aa - 38;
+ v >>= 6;
+ }
+ return (v == 0 ? 0 : -1);
+}
OpenPOWER on IntegriCloud