This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: [patch] Add wcstol, wcstoul, wcstoll, wcstoull
corinna> Any idea how we could implement wcstof, wcstod and wcstold without
corinna> too much overhead?
I've dealt with this before. Below is how I handled it.
--Duane.
The simplest solution is to:
1) create a common function that does the real work.
2) create a 'helper structure' to manage the char/wchar_t IO operation.
In a way, it's a lot like the callback functions in the FILE structure.
I've had others describe this technique as "C++" virtual functions in C.
You only need to add a putch() function for output routines routines and you
can use the same technique for printf() - and strtime() and so forth - at
first - it is a big jump - but - in the end - you get identical implementations
and fewer missing features issues - ie: Feature XX is has-a-bug/not-supported
in wchar mode, and ease of creating wcs versions of anything.
Sort of like this - a structure in "strwcs_helpers.h"
struct strwcs_xxx_helper {
/* IO funcs */
int (*putch_func)( struct wcs_xxx_helper *p, int ch );
int (*getch_func)( struct wcs_xxx_helper *p );
int (*unget_func)( struct wcs_xxx_helper *p, int ch );
/* is_xxx performs <ctype.h> operations */
int (*is_xxx_func)( struct wcs_xxx_helper *p, int opcode, int ch );
int is_wchar_mode;
/* params for access funcs */
void *ptr1, *ptr2, *ptr3;
int i1, i2, i3;
};
If you look closely at the string IO functions they are very common
and could easily be reused. ie: strtol() would use the same string
IO functions as strtod() - and - sscanf() and strftime() and strptime()
I'll bet - the IO functions could be compartmentalized and standardized
into just two pre-defined structures, and thus become a pointer to a
method wanna-be-c++ base class like thing.
To continue my example: wcstof() and strtof() becomes:
#if CONFIG_ENABLE_WCHAR
double
wcstod( const wchar_t *nptr, wchar_t **endptr )
{
struct strwcs_xxx_helper x;
double d;
x.is_wchar_mode = 1;
x.ptr1 = nptr;
x.ptr2 = endptr;
x.getch_func = wcs_getch_helper;
x.unget_func = wcs_unget_helper;
x.is_xxx_func = wcs_is_xxx_helper;
d = __strtod_common( &x );
if( endptr ){
*endptr = x.ptr1;
}
return d;
}
#endif
double
strtod( const char *ntpr, char **endptr )
{
struct strwcs_xxx_helper x;
double d;
x.is_wchar_mode = 0;
x.ptr1 = nptr;
x.ptr2 = endptr;
x.getch_func = str_getch_helper;
x.unget_func = str_unget_helper;
x.is_xxx_func = str_is_xxx_helper;
d = __strtod_common( &x );
if( endptr ){
*endptr = x.ptr1;
}
return d;
|
static double
__strtod_common( struct strwcs_xxx_helper *p )
{
.... existing implementation ....
}