[patch] Add wcstol, wcstoul, wcstoll, wcstoull

Duane Ellis duane@duaneellis.com
Tue Jul 10 01:45:00 GMT 2007


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 ....
}




	






More information about the Newlib mailing list