Mail Archives: djgpp-workers/2001/06/04/13:29:59
> > I've had problems before where patches couldn't be applied due to line
> > breaks added by the mail agent, so I've taken to sending diffs as
> > attachments if they're meant to be applied, instead of just reviewed.
>
> I was talking from the point of view of someone who needs to review the
> patches, not apply them (don't you have write access to the CVS?)
I see your point. And no, I do not have write access.
> > > I'd think that interpreting the argument as an unsigned long would
> > > produce reasonable results.
> > I was talking about possibly changing the signatures to use unsigned
> > long, but I suppose that simply treating them as such would be OK.
>
> Given that glibc does that as well, it sounds plausible.
I've made that change.
> > > > + printf ("a64l(\"EliRules!\") -> %ld\n",
> a64l("EliRules!"));
> > >
> > > This line has a bug in it.
> >
> > Hmmm - where exactly? I see nothing wrong with it :-)
>
> The missing smiley.
>
Changed it to "Rhubarb!" instead - that needs no smiley and also tests the
overflow case :-)
Third draft follows:
diff -rN emptydir/a64l.c src/libc/posix/stdlib/a64l.c
0a1,38
> /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
>
> #include <limits.h>
> #include <stdlib.h>
> #include <string.h>
>
> long
> a64l(const char* s)
> {
> int i = 0;
> unsigned long value = 0;
>
> if (s == NULL || *s == '\0')
> return 0L;
>
> for (i = 0; i < 6; ++i, ++s)
> {
> if (*s == '\0')
> break;
> /* Detect overflow; return the conversion of '/2BIG/' */
> if (value > (ULONG_MAX >> 6))
> return 1144341633L;
> value <<= 6;
> if (*s == '.') /* 0 */
> value += 0;
> else if (*s == '/') /* 1 */
> ++value;
> else if (*s >= '0' && *s <= '9') /* 2-11 */
> value += (*s - '0') + 2;
> else if (*s >= 'A' && *s <= 'Z') /* 12-37 */
> value += (*s - 'A') + 12;
> else if (*s >= 'a' && *s <= 'z') /* 38-63 */
> value += (*s - 'a') + 38;
> else /* invalid digit */
> return 0L;
> }
> return (long) value;
> }
diff -rN emptydir/a64l.txh src/libc/posix/stdlib/a64l.txh
0a1,36
> @node a64l, string
> @subheading Syntax
>
> @example
> #include <stdlib.h>
>
> long a64l(const char *s);
> @end example
>
> @subheading Description
>
> This function takes a pointer to a radix-64 representation, with the
> first digit the least significant, and returns the corresponding
> @code{long} value.
>
> If @var{s} contains more than six characters, only the first six are
> used. If the first six characters of @var{s} contain a null terminator,
> only those characters before the null terminator are used.
> @code{a64l()} will scan the string from left to right, with the least
> significant digit on the left, decoding each character as a 6-bit radix-64
> number.
>
> For a description of the radix-64 representation, @ref{l64a}.
>
> @subheading Return Value
>
> Returns the @code{long} value resulting from the conversion of the
contents
> of @var{s}, or 0L if @var{s} is NULL, points to an empty string, or points
> to an invalid string (i.e. one not generated by a previous call to
> @code{l64a()}). If the result would overflow a signed long, the
> conversion of @samp{/2BIG/} (1144341633L) is returned.
>
> @subheading Portability
>
> @portability !ansi, posix
> @port-note Posix 1003.1-200x, not POSIX-1:1996
diff -rN emptydir/l64a.c src/libc/posix/stdlib/l64a.c
0a1,36
> /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
>
> #include <limits.h>
> #include <stdlib.h>
> #include <string.h>
>
> char*
> l64a(long _value)
> {
> static char radix64[7] = { "" };
> char *s = radix64 + 5;
> unsigned long value = (unsigned long) _value;
>
> memset (radix64, 0, sizeof radix64);
>
> if (value == 0)
> return radix64;
>
> while (value && s >= radix64)
> {
> int digit = value & 0x3f;
> value >>= 6;
>
> if (digit == 0)
> *s-- = '.';
> else if (digit == 1)
> *s-- = '/';
> else if (digit < 12)
> *s-- = '0' + (digit - 2);
> else if (digit < 38)
> *s-- = 'A' + (digit - 12);
> else
> *s-- = 'a' + (digit - 38);
> }
> return ++s;
> }
diff -rN emptydir/l64a.txh src/libc/posix/stdlib/l64a.txh
0a1,42
> @node l64a, string
> @subheading Syntax
>
> @example
> #include <stdlib.h>
>
> char *l64a(long value);
> @end example
>
> @subheading Description
>
> This function takes a @code{long} argument and returns a pointer to its
> radix-64 representation. Negative numbers are not supported.
> @c FIXME: Supporting negative values (or at least unsigned longs) seems
> @c more logical; should we be POSIX-compliant here?
>
> @subheading Return Value
>
> A pointer to a static buffer containing the radix-64 representation of
> @var{value}. Subsequent calls will overwrite the contents of this buffer.
> If @var{value} is 0L, this function returns an empty string.
>
> @subheading Radix-64
> @cindex radix-64
>
> The radix-64 @sc{ascii} representation is a notation whereby 32-bit
integers
> are represented by up to 6 @sc{ascii} characters; each character
represents
> a single radix-64 digit. Radix-64 refers to the fact that each digit in
this
> representation can take 64 different values.
> If the @code{long} type is more than 32 bits in size, only the low-order
> 32 bits are used.
> The characters used to represent digits are @samp{.} (dot) for 0, @samp{/}
> for 1, @samp{0} through @samp{9} for 2 to 11, @samp{A} through @samp{Z}
for
> 12 to 37, and @samp{a} through @samp{z} for 38 to 63.
>
> Note that this is @emph{not} the same encoding used by either uuencode or
the
> MIME base64 encoding.
>
> @subheading Portability
>
> @portability !ansi, posix
> @port-note Posix 1003.1-200x, not POSIX-1:1996
diff -rN emptydir/makefile src/libc/posix/stdlib/makefile
0a1,7
> # Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details
>
> TOP=../..
>
> SRC += a64l.c l64a.c
>
> include $(TOP)/../makefile.inc
diff -rN emptydir/makefile tests/libc/posix/stdlib/makefile
0a1,5
> TOP=../..
>
> SRC += radix64.c
>
> include $(TOP)/../makefile.inc
diff -rN emptydir/radix64.c tests/libc/posix/stdlib/radix64.c
0a1,39
> #include <stdio.h>
> #include <stdlib.h>
>
> int
> main(void)
> {
> printf ("a64l(\"/.\") -> %ld\n", a64l("/."));
> printf ("a64l(\"DJGPP\") -> %ld\n", a64l("DJGPP"));
> printf ("a64l(\"/.Rules!\") -> %ld\n", a64l("/.Rules!"));
> printf ("a64l(\"Rhubarb!\") -> %ld\n", a64l("Rhubarb!"));
> printf ("a64l(NULL) -> %ld\n", a64l(NULL));
> printf ("a64l(\"\") -> %ld\n", a64l(""));
> printf ("a64l(\"Not Radix64\") -> %ld\n", a64l("Not Radix64"));
>
> printf ("a64l(l64a(1234)) -> %ld\n", a64l(l64a(1234)));
> printf ("a64l(l64a(64)) -> %ld\n", a64l(l64a(64)));
> printf ("a64l(l64a(7)) -> %ld\n", a64l(l64a(7)));
> printf ("a64l(l64a(0)) -> %ld\n", a64l(l64a(0)));
> printf ("a64l(l64a(-88)) -> %ld\n", a64l(l64a(-88)));
> /* 0x54534554 is the binary representation of 'TEST' */
> printf ("a64l(l64a(0x54534554)) -> 0x%lx\n", a64l(l64a(0x54534554)));
>
> printf ("l64a(1234) -> '%s'\n", l64a(1234));
> printf ("l64a(64) -> '%s'\n", l64a(64));
> printf ("l64a(7) -> '%s'\n", l64a(7));
> printf ("l64a(0) -> '%s'\n", l64a(0));
> printf ("l64a(-88) -> '%s'\n", l64a(-88));
> printf ("l64a(0x54534554) -> '%s'\n", l64a(0x54534554));
>
> printf ("l64a(a64l(\"/.\")) -> '%s'\n", l64a(a64l("/.")));
> printf ("l64a(a64l(\"DJGPP\")) -> '%s'\n", l64a(a64l("DJGPP")));
> printf ("l64a(a64l(\"/.Rules!\")) -> '%s'\n",
l64a(a64l("/.Rules!")));
> printf ("l64a(a64l(\"Rhubarb!\")) -> '%s'\n",
l64a(a64l("Rhubarb!")));
> printf ("l64a(a64l(NULL)) -> '%s'\n", l64a(a64l(NULL)));
> printf ("l64a(a64l(\"\")) -> '%s'\n", l64a(a64l("")));
> printf ("l64a(a64l(\"Not Radix64\")) -> '%s'\n", l64a(a64l("Not
Radix64")));
>
> return 0;
> }
- Raw text -