New wreaddir function, wide character version of readdir

darcs-hash:20060208145847-ac50b-0e250edb67dd095e90054ed55f88a2638ba9b02a.gz
This commit is contained in:
axel 2006-02-09 00:58:47 +10:00
parent 824f4ee566
commit 133b682793
5 changed files with 91 additions and 70 deletions

View file

@ -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) &&

View file

@ -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

View file

@ -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 );

87
wutil.c
View file

@ -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];

View file

@ -16,6 +16,13 @@
#include <sys/types.h>
#include <stdarg.h>
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