Re: [Libclc-developers] contribution(?): string function ultostr()
Status: Planning
Brought to you by:
augestad
|
From: <bo...@me...> - 2003-03-17 16:46:51
|
Jan Engelhardt wrote:
> Hi,
>
> copied this from my personal lib as I thought
> this might be worth sharing, no?
Thanks for the code, Jan. Here are my comments.
>
> /*=============================================================================
> ultostr
> by Jan "Hirogen2" Engelhardt <hirogen2 at gmx de>, 2003
> -- distributed under the Frontier Artistic License and GNU General Public
> -- License. See doc/FAL1.txt and doc/GPL2.txt for details.
The license must be changed to BSD.
> -------------------------------------------------------------------------------
> NAME
> ultostr - convert an unsigned long integer to a string
The name must be prefixed with clc_ .
>
> SYNOPSIS
> unsigned char *ultostr(unsigned long num, unsigned long base,
> unsigned char *ptr, size_t size);
unsigned long base is pretty long for the range 2..36 :-) strtoul uses
int for base.
Unsigned char* are very uncommon in C libraries, and its buddy function
strtoul uses char*.
>
> DESCRIPTION
> The ultostr() function converts the number NUM to a string, in
> base BASE notation. BASE must be between 2 and 36 inclusive. To
> summarize it, this function does (nearly) exactly the opposite
> of strtoul().
>
> The output is written to the location pointed to by PTR, whose
> length is passed in SIZE. SIZE is the number of bytes, including
> space for a trailing '\0'. No more bytes than (SIZE - 1) are
> written. The output is null-padded in front.
>
> RETURN VALUE
> ultostr() returns PTR on success, or NULL on error. ERANGE is
> returned if BASE is < 2 or > 36. EFAULT is returned if PTR is
> NULL.
I assume that you mean that errno is set to ERANGE? I guess we won't
have to test for legal base. strtoul sets errno to EINVAL if base is out
of range according to my man page. That page also says that C99 does
*not* set errno if base is out of range, so we shouldn't do it either?
EFAULT does not exist in ANSI C and the libclc doesn't require that we
test for NULL args in release versions. The debug version should have an
clc_assert_not_null(function_name, ptr);
It should also have a
clc_assert_arg(function_name, base >= 2 && base <= 36);
>
> EXAMPLE
> unsigned char buf[12];
> memset(buf, 0, 12);
> printf("%s\n", ultostr(170, 2, 12));
>
> Prints 00010101010 (11 chars).
> =============================================================================*/
> #include <errno.h>
> #include <stdio.h>
>
> unsigned char *ultostr(unsigned long num, unsigned long base,
> unsigned char *ptr, size_t size) {
> unsigned char *sym = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
> *startp = ptr + size - 2;
> if(base < 2 || base > 36) { errno = ERANGE; return NULL; }
> if(ptr == NULL) { errno = EFAULT; return NULL; }
> while(--size > 0) {
> *ptr = sym[num % base];
> num /= base;
> --ptr;
> }
> return ptr;
> }
>
/* Proper libclc format guidelines (unpublished :-)) applied */
unsigned char *ultostr(
unsigned long num,
unsigned long base,
unsigned char *ptr,
size_t size)
{
unsigned char *sym = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
clc_assert_not_null(ultostr, ptr);
clc_assert_arg(ultostr, base >= 2 && base <= 36);
*startp = ptr + size - 2;
if(base < 2 || base > 36) {
errno = ERANGE;
return NULL;
}
while(--size > 0) {
*ptr = sym[num % base];
num /= base;
--ptr;
}
return ptr;
}
I fail to see where startp is defined.
Very good documentation!
I think we need a function like this, especially if it converts numbers
to bit patterns. Lots of people wants to convert integers to bit patterns.
If we add this function, should we add ltostr, lltostr and ulltostr as well?
--
boa
Please join the libclc-developers list
at http://lists.sourceforge.net/lists/listinfo/libclc-developers
|