From 133b682793fdbc0d86d207c6afe774b26af84d3a Mon Sep 17 00:00:00 2001 From: axel Date: Thu, 9 Feb 2006 00:58:47 +1000 Subject: [PATCH] New wreaddir function, wide character version of readdir darcs-hash:20060208145847-ac50b-0e250edb67dd095e90054ed55f88a2638ba9b02a.gz --- common.c | 28 +++++++++++++----- common.h | 3 ++ wildcard.c | 34 ++++++--------------- wutil.c | 87 ++++++++++++++++++++++++++++++------------------------ wutil.h | 9 ++++++ 5 files changed, 91 insertions(+), 70 deletions(-) diff --git a/common.c b/common.c index 103c5beac..751c1ffd9 100644 --- a/common.c +++ b/common.c @@ -254,13 +254,21 @@ void sort_list( array_list_t *comp ) wchar_t *str2wcs( const char *in ) { wchar_t *out; + size_t len = strlen(in); + + out = malloc( sizeof(wchar_t)*(len+1) ); + return str2wcs_internal( in, out ); + +} + +wchar_t *str2wcs_internal( const char *in, wchar_t *out ) +{ size_t res=0; int in_pos=0; int out_pos = 0; - size_t len = strlen(in); mbstate_t state; + size_t len = strlen(in); - out = malloc( sizeof(wchar_t)*(len+1) ); memset( &state, 0, sizeof(state) ); if( !out ) @@ -309,19 +317,25 @@ void error_reset() char *wcs2str( const wchar_t *in ) { char *out; - size_t res=0; - int in_pos=0; - int out_pos = 0; - mbstate_t state; out = malloc( MAX_UTF8_BYTES*wcslen(in)+1 ); - memset( &state, 0, sizeof(state) ); if( !out ) { die_mem(); } + return wcs2str_internal( in, out ); +} + +char *wcs2str_internal( const wchar_t *in, char *out ) +{ + size_t res=0; + int in_pos=0; + int out_pos = 0; + mbstate_t state; + memset( &state, 0, sizeof(state) ); + while( in[in_pos] ) { if( ( in[in_pos] >= ENCODE_DIRECT_BASE) && diff --git a/common.h b/common.h index 047665877..f18f391dc 100644 --- a/common.h +++ b/common.h @@ -114,6 +114,7 @@ void sort_list( array_list_t *comp ); specified multibyte character string */ wchar_t *str2wcs( const char *in ); +wchar_t *str2wcs_internal( const char *in, wchar_t *out ); /** Returns a newly allocated multibyte character string equivalent of @@ -121,6 +122,8 @@ wchar_t *str2wcs( const char *in ); */ char *wcs2str( const wchar_t *in ); +char *wcs2str_internal( const wchar_t *in, char *out ); + /** Returns a newly allocated wide character string array equivalent of the specified multibyte character string array diff --git a/wildcard.c b/wildcard.c index d1f7386f4..278a7f248 100644 --- a/wildcard.c +++ b/wildcard.c @@ -363,7 +363,7 @@ int wildcard_expand( const wchar_t *wc, wchar_t *wc_end; /* Variables for traversing a directory */ - struct dirent *next; + struct wdirent *next; DIR *dir; /* The result returned */ @@ -454,15 +454,11 @@ int wildcard_expand( const wchar_t *wc, */ if( flags & ACCEPT_INCOMPLETE ) { - while( (next=readdir(dir))!=0 ) + while( (next=wreaddir(dir))!=0 ) { - if( next->d_name[0] != '.' ) + if( next->d_name[0] != L'.' ) { - wchar_t *name = str2wcs(next->d_name); - if( name == 0 ) - { - continue; - } + wchar_t *name = next->d_name; wchar_t *long_name = make_path( base_dir, name ); if( test_flags( long_name, flags ) ) @@ -474,8 +470,6 @@ int wildcard_expand( const wchar_t *wc, wcsdupcat(name, (wchar_t *)sb_desc.buff) ); } - free(name); - free( long_name ); } } @@ -491,13 +485,9 @@ int wildcard_expand( const wchar_t *wc, /* This is the last wildcard segment, and it is not empty. Match files/directories. */ - while( (next=readdir(dir))!=0 ) + while( (next=wreaddir(dir))!=0 ) { - wchar_t *name = str2wcs(next->d_name); - if( name == 0 ) - { - continue; - } + wchar_t *name = next->d_name; if( flags & ACCEPT_INCOMPLETE ) { @@ -540,7 +530,6 @@ int wildcard_expand( const wchar_t *wc, res = 1; } } - free( name ); } } } @@ -595,14 +584,10 @@ int wildcard_expand( const wchar_t *wc, wcscpy( new_dir, base_dir ); - while( (next=readdir(dir))!=0 ) + while( (next=wreaddir(dir))!=0 ) { - wchar_t *name = str2wcs(next->d_name); - if( name == 0 ) - { - continue; - } - + wchar_t *name = next->d_name; + /* Test if the file/directory name matches the whole wildcard element, i.e. regular matching. @@ -673,7 +658,6 @@ int wildcard_expand( const wchar_t *wc, } } } - free(name); } free( wc_str ); diff --git a/wutil.c b/wutil.c index d66fee811..97b5d764f 100644 --- a/wutil.c +++ b/wutil.c @@ -39,16 +39,20 @@ the \c wutil_wcs2str() function. */ static char *tmp=0; +static wchar_t *tmp2=0; /** Length of the \c tmp buffer. */ static size_t tmp_len=0; +static size_t tmp2_len=0; /** Counts the number of calls to the wutil wrapper functions */ static int wutil_calls = 0; +static struct wdirent my_wdirent; + void wutil_init() { } @@ -56,6 +60,7 @@ void wutil_init() void wutil_destroy() { free( tmp ); + free( tmp2 ); tmp=0; tmp_len=0; debug( 3, L"wutil functions called %d times", wutil_calls ); @@ -68,14 +73,9 @@ void wutil_destroy() */ static char *wutil_wcs2str( const wchar_t *in ) { - size_t res=0; - int in_pos=0; - int out_pos = 0; - mbstate_t state; size_t new_sz; - + wutil_calls++; - memset( &state, 0, sizeof(state) ); new_sz =MAX_UTF8_BYTES*wcslen(in)+1; if( tmp_len < new_sz ) @@ -88,40 +88,51 @@ static char *wutil_wcs2str( const wchar_t *in ) } tmp_len = new_sz; } - - while( in[in_pos] ) - { - if( ( in[in_pos] >= ENCODE_DIRECT_BASE) && - ( in[in_pos] < ENCODE_DIRECT_BASE+256) ) - { - tmp[out_pos++] = in[in_pos]- ENCODE_DIRECT_BASE; - } - else - { - res = wcrtomb( &tmp[out_pos], in[in_pos], &state ); - - switch( res ) - { - case (size_t)(-1): - { - debug( 1, L"Wide character has no narrow representation" ); - memset( &state, 0, sizeof(state) ); - break; - } - default: - { - out_pos += res; - break; - } - } - } - in_pos++; - } - tmp[out_pos] = 0; - - return tmp; + + return wcs2str_internal( in, tmp ); } + +/** + Convert the specified wide character string to a narrow character + string. This function uses an internal temporary buffer for storing + the result so subsequent results will overwrite previous results. +*/ +static wchar_t *wutil_str2wcs( const char *in ) +{ + size_t new_sz; + + wutil_calls++; + + new_sz = sizeof(wchar_t)*(strlen(in)+1); + if( tmp2_len < new_sz ) + { + new_sz = maxi( new_sz, TMP_LEN_MIN ); + tmp2 = realloc( tmp2, new_sz ); + if( !tmp2 ) + { + die_mem(); + } + tmp2_len = new_sz; + } + + return str2wcs_internal( in, tmp2 ); +} + + + +struct wdirent *wreaddir(DIR *dir ) +{ + struct dirent *d = readdir( dir ); + if( !d ) + return 0; + + my_wdirent.d_name = wutil_str2wcs( d->d_name ); + return &my_wdirent; + +} + + wchar_t *wgetcwd( wchar_t *buff, size_t sz ) { char buffc[sz*MAX_UTF8_BYTES]; diff --git a/wutil.h b/wutil.h index 4230e6298..b88c7822d 100644 --- a/wutil.h +++ b/wutil.h @@ -16,6 +16,13 @@ #include #include +struct wdirent +{ + wchar_t *d_name; +} + ; + + /** Call this function on startup to create internal wutil resources. This function doesn't do anything. @@ -91,6 +98,8 @@ int wchdir( const wchar_t * dir ); */ wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path); +struct wdirent *wreaddir(DIR *dir ); + /* Here follows the prototypes for fallback implementations of various standarcs libc functions relating to wide character support. Some of