aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2006-02-09 00:58:47 +1000
committerGravatar axel <axel@liljencrantz.se>2006-02-09 00:58:47 +1000
commit133b682793fdbc0d86d207c6afe774b26af84d3a (patch)
tree041bcc8297048ba2c4abfe189ed740b8c05c2d9a
parent824f4ee566f0454515810c4df5f602e28fbb7c60 (diff)
New wreaddir function, wide character version of readdir
darcs-hash:20060208145847-ac50b-0e250edb67dd095e90054ed55f88a2638ba9b02a.gz
-rw-r--r--common.c28
-rw-r--r--common.h3
-rw-r--r--wildcard.c34
-rw-r--r--wutil.c75
-rw-r--r--wutil.h9
5 files changed, 85 insertions, 64 deletions
diff --git a/common.c b/common.c
index 103c5bea..751c1ffd 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 04766587..f18f391d 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 d1f7386f..278a7f24 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 d66fee81..97b5d764 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;
}
+
+ 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++;
- while( in[in_pos] )
+ new_sz = sizeof(wchar_t)*(strlen(in)+1);
+ if( tmp2_len < new_sz )
{
- if( ( in[in_pos] >= ENCODE_DIRECT_BASE) &&
- ( in[in_pos] < ENCODE_DIRECT_BASE+256) )
- {
- tmp[out_pos++] = in[in_pos]- ENCODE_DIRECT_BASE;
- }
- else
+ new_sz = maxi( new_sz, TMP_LEN_MIN );
+ tmp2 = realloc( tmp2, new_sz );
+ if( !tmp2 )
{
- 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;
- }
- }
+ die_mem();
}
- in_pos++;
+ tmp2_len = new_sz;
}
- tmp[out_pos] = 0;
+
+ 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;
- return tmp;
}
+
wchar_t *wgetcwd( wchar_t *buff, size_t sz )
{
char buffc[sz*MAX_UTF8_BYTES];
diff --git a/wutil.h b/wutil.h
index 4230e629..b88c7822 100644
--- a/wutil.h
+++ b/wutil.h
@@ -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