diff options
author | Danny Smith <dannysmith@users.sourceforge.net> | 2002-04-23 05:59:06 +0400 |
---|---|---|
committer | Danny Smith <dannysmith@users.sourceforge.net> | 2002-04-23 05:59:06 +0400 |
commit | 1d401c02afb3f6b96350a39997763427da752355 (patch) | |
tree | 4047e765b60cdaf368e18f79bbb01c683b66326f | |
parent | 68fe11a37bb61de094870ed8cc377f907d32c2f7 (diff) |
Make wide char versions of opendir and friends.
* include/dirent.h (_wdirent, _WDIR): Define wide versions of
struct dirent, DIR.
(_wopendir,_wreaddir,_wclosedir,_wrewinddir,_wtelldir,
_wseekdir): Add prototypes for wide versions of corresponding
standard functions.
* include/tchar.h; Add _UNICODE mappings for dirent.h
structures and functions.
* mingwex/dirent.c: Make _UNICODE neutral.
* mingwex/wdirent.c: New file to define _UNICODE before
including dirent.c.
* mingwex/Makefile.in (DISTFILES): Add wdirent.c/
(POSIX_OBJS): Add wdirent.o.
(wdirent.o): Specify dependency on dirent.c as well as
wdirent.c.
* samples/dirent/wtest.c: New file, wide version of test.c.
-rw-r--r-- | winsup/mingw/ChangeLog | 19 | ||||
-rw-r--r-- | winsup/mingw/include/dirent.h | 53 | ||||
-rw-r--r-- | winsup/mingw/include/tchar.h | 19 | ||||
-rw-r--r-- | winsup/mingw/mingwex/Makefile.in | 9 | ||||
-rw-r--r-- | winsup/mingw/mingwex/dirent.c | 74 | ||||
-rw-r--r-- | winsup/mingw/mingwex/wdirent.c | 3 | ||||
-rw-r--r-- | winsup/mingw/samples/dirent/wtest.c | 98 |
7 files changed, 237 insertions, 38 deletions
diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog index 344b6063d..0df3c5885 100644 --- a/winsup/mingw/ChangeLog +++ b/winsup/mingw/ChangeLog @@ -1,3 +1,22 @@ +2002-04-23 Danny Smith <dannysmith@users.sourceforge.net> + + Make wide char versions of opendir and friends. + * include/dirent.h (_wdirent, _WDIR): Define wide versions of + struct dirent, DIR. + (_wopendir,_wreaddir,_wclosedir,_wrewinddir,_wtelldir, + _wseekdir): Add prototypes for wide versions of corresponding + standard functions. + * include/tchar.h; Add _UNICODE mappings for dirent.h + structures and functions. + * mingwex/dirent.c: Make _UNICODE neutral. + * mingwex/wdirent.c: New file to define _UNICODE before + including dirent.c. + * mingwex/Makefile.in (DISTFILES): Add wdirent.c/ + (POSIX_OBJS): Add wdirent.o. + (wdirent.o): Specify dependency on dirent.c as well as + wdirent.c. + * samples/dirent/wtest.c: New file, wide version of test.c. + 2002-04-20 Danny Smith <dannysmith@users.sourceforge.net> * include/mbstring.h: New file. diff --git a/winsup/mingw/include/dirent.h b/winsup/mingw/include/dirent.h index 92ec6b587..3d7fae827 100644 --- a/winsup/mingw/include/dirent.h +++ b/winsup/mingw/include/dirent.h @@ -77,6 +77,7 @@ typedef struct } DIR; + DIR* opendir (const char*); struct dirent* readdir (DIR*); int closedir (DIR*); @@ -84,6 +85,58 @@ void rewinddir (DIR*); long telldir (DIR*); void seekdir (DIR*, long); + +/* wide char versions */ + +struct _wdirent +{ + long d_ino; /* Always zero. */ + unsigned short d_reclen; /* Always zero. */ + unsigned short d_namlen; /* Length of name in d_name. */ + wchar_t* d_name; /* File name. */ + /* NOTE: The name in the dirent structure points to the name in the + * wfinddata_t structure in the _WDIR. */ +}; + +/* + * This is an internal data structure. Good programmers will not use it + * except as an argument to one of the functions below. + */ +typedef struct +{ + /* disk transfer area for this dir */ + struct _wfinddata_t dd_dta; + + /* dirent struct to return from dir (NOTE: this makes this thread + * safe as long as only one thread uses a particular DIR struct at + * a time) */ + struct _wdirent dd_dir; + + /* _findnext handle */ + long dd_handle; + + /* + * Status of search: + * 0 = not started yet (next entry to read is first entry) + * -1 = off the end + * positive = 0 based index of next entry + */ + short dd_stat; + + /* given path for dir with search pattern (struct is extended) */ + wchar_t dd_name[1]; +} _WDIR; + + + +_WDIR* _wopendir (const wchar_t*); +struct _wdirent* _wreaddir (_WDIR*); +int _wclosedir (_WDIR*); +void _wrewinddir (_WDIR*); +long _wtelldir (_WDIR*); +void _wseekdir (_WDIR*, long); + + #ifdef __cplusplus } #endif diff --git a/winsup/mingw/include/tchar.h b/winsup/mingw/include/tchar.h index 2b19c16a7..bc6f28f5c 100644 --- a/winsup/mingw/include/tchar.h +++ b/winsup/mingw/include/tchar.h @@ -207,6 +207,15 @@ typedef wchar_t _TCHAR; #define _tfinddatai64_t _wfinddatai64_t #endif /* __MSVCRT__ */ +/* dirent structures and functions */ +#define _tdirent _wdirent +#define _TDIR _WDIR +#define _topendir _wopendir +#define _tclosedir _wclosedir +#define _treaddir _wreaddir +#define _trewinddir _wrewinddir +#define _ttelldir _wtelldir +#define _tseekdir _wseekdir #else /* Not _UNICODE */ /* @@ -364,6 +373,16 @@ typedef char _TCHAR; #define _tfinddatai64_t _finddatai64_t #endif /* __MSVCRT__ */ +/* dirent structures and functions */ +#define _tdirent dirent +#define _TDIR DIR +#define _topendir opendir +#define _tclosedir closedir +#define _treaddir readdir +#define _trewinddir rewinddir +#define _ttelldir telldir +#define _tseekdir seekdir + #endif /* Not _UNICODE */ /* diff --git a/winsup/mingw/mingwex/Makefile.in b/winsup/mingw/mingwex/Makefile.in index ea79fbabc..61f596847 100644 --- a/winsup/mingw/mingwex/Makefile.in +++ b/winsup/mingw/mingwex/Makefile.in @@ -75,6 +75,7 @@ DISTFILES = Makefile.in configure configure.in \ wcstof.c \ wcstoimax.c \ wcstoumax.c \ + wdirent.c \ wmemchr.c \ wmemcmp.c \ wmemcpy.c \ @@ -140,7 +141,7 @@ FENV_OBJS = fesetround.o fegetround.o \ feclearexcept.o feholdexcept.o fegetexceptflag.o \ feraiseexcept.o fetestexcept.o fesetexceptflag.o POSIX_OBJS = \ - dirent.o + dirent.o wdirent.o REPLACE_OBJS = \ mingw-fseek.o @@ -191,6 +192,12 @@ distclean: $(CC) -c $< -o $@ +# +# Dependancies +# +wdirent.o: $(srcdir)/dirent.c $(srcdir)/wdirent.c + + dist: mkdir $(distdir)/mingwex chmod 755 $(distdir)/mingwex diff --git a/winsup/mingw/mingwex/dirent.c b/winsup/mingw/mingwex/dirent.c index 9eb1a502c..91c170619 100644 --- a/winsup/mingw/mingwex/dirent.c +++ b/winsup/mingw/mingwex/dirent.c @@ -20,14 +20,14 @@ #include <string.h> #include <io.h> #include <direct.h> - #include <dirent.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> /* for GetFileAttributes */ -#define SUFFIX "*" -#define SLASH "\\" +#include <tchar.h> +#define SUFFIX _T("*") +#define SLASH _T("\\") /* * opendir @@ -35,25 +35,25 @@ * Returns a pointer to a DIR structure appropriately filled in to begin * searching a directory. */ -DIR * -opendir (const char *szPath) +_TDIR * +_topendir (const _TCHAR *szPath) { - DIR *nd; + _TDIR *nd; unsigned int rc; - char szFullPath[MAX_PATH]; + _TCHAR szFullPath[MAX_PATH]; errno = 0; if (!szPath) { errno = EFAULT; - return (DIR *) 0; + return (_TDIR *) 0; } - if (szPath[0] == '\0') + if (szPath[0] == _T('\0')) { errno = ENOTDIR; - return (DIR *) 0; + return (_TDIR *) 0; } /* Attempt to determine if the given path really is a directory. */ @@ -62,43 +62,43 @@ opendir (const char *szPath) { /* call GetLastError for more error info */ errno = ENOENT; - return (DIR *) 0; + return (_TDIR *) 0; } if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) { /* Error, entry exists but not a directory. */ errno = ENOTDIR; - return (DIR *) 0; + return (_TDIR *) 0; } /* Make an absolute pathname. */ - _fullpath (szFullPath, szPath, MAX_PATH); + _tfullpath (szFullPath, szPath, MAX_PATH); /* Allocate enough space to store DIR structure and the complete * directory path given. */ - nd = (DIR *) malloc (sizeof (DIR) + strlen (szFullPath) + strlen (SLASH) + - strlen (SUFFIX)); + nd = (_TDIR *) malloc (sizeof (_TDIR) + _tcslen (szFullPath) + _tcslen (SLASH) + + _tcslen (SUFFIX)); if (!nd) { /* Error, out of memory. */ errno = ENOMEM; - return (DIR *) 0; + return (_TDIR *) 0; } /* Create the search expression. */ - strcpy (nd->dd_name, szFullPath); + _tcscpy (nd->dd_name, szFullPath); /* Add on a slash if the path does not end with one. */ - if (nd->dd_name[0] != '\0' && - nd->dd_name[strlen (nd->dd_name) - 1] != '/' && - nd->dd_name[strlen (nd->dd_name) - 1] != '\\') + if (nd->dd_name[0] != _T('\0') && + nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('/') && + nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('\\')) { - strcat (nd->dd_name, SLASH); + _tcscat (nd->dd_name, SLASH); } /* Add on the search pattern */ - strcat (nd->dd_name, SUFFIX); + _tcscat (nd->dd_name, SUFFIX); /* Initialize handle to -1 so that a premature closedir doesn't try * to call _findclose on it. */ @@ -125,8 +125,8 @@ opendir (const char *szPath) * Return a pointer to a dirent structure filled with the information on the * next entry in the directory. */ -struct dirent * -readdir (DIR * dirp) +struct _tdirent * +_treaddir (_TDIR * dirp) { errno = 0; @@ -134,27 +134,27 @@ readdir (DIR * dirp) if (!dirp) { errno = EFAULT; - return (struct dirent *) 0; + return (struct _tdirent *) 0; } if (dirp->dd_dir.d_name != dirp->dd_dta.name) { /* The structure does not seem to be set up correctly. */ errno = EINVAL; - return (struct dirent *) 0; + return (struct _tdirent *) 0; } if (dirp->dd_stat < 0) { /* We have already returned all files in the directory * (or the structure has an invalid dd_stat). */ - return (struct dirent *) 0; + return (struct _tdirent *) 0; } else if (dirp->dd_stat == 0) { /* We haven't started the search yet. */ /* Start the search */ - dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta)); + dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta)); if (dirp->dd_handle == -1) { @@ -170,7 +170,7 @@ readdir (DIR * dirp) else { /* Get the next search entry. */ - if (_findnext (dirp->dd_handle, &(dirp->dd_dta))) + if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta))) { /* We are off the end or otherwise error. */ _findclose (dirp->dd_handle); @@ -190,11 +190,11 @@ readdir (DIR * dirp) /* Successfully got an entry. Everything about the file is * already appropriately filled in except the length of the * file name. */ - dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name); + dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dir.d_name); return &dirp->dd_dir; } - return (struct dirent *) 0; + return (struct _tdirent *) 0; } @@ -204,7 +204,7 @@ readdir (DIR * dirp) * Frees up resources allocated by opendir. */ int -closedir (DIR * dirp) +_tclosedir (_TDIR * dirp) { int rc; @@ -235,7 +235,7 @@ closedir (DIR * dirp) * and then reset things like an opendir. */ void -rewinddir (DIR * dirp) +_trewinddir (_TDIR * dirp) { errno = 0; @@ -261,7 +261,7 @@ rewinddir (DIR * dirp) * seekdir to go back to an old entry. We simply return the value in stat. */ long -telldir (DIR * dirp) +_ttelldir (_TDIR * dirp) { errno = 0; @@ -283,7 +283,7 @@ telldir (DIR * dirp) * any such system. */ void -seekdir (DIR * dirp, long lPos) +_tseekdir (_TDIR * dirp, long lPos) { errno = 0; @@ -312,9 +312,9 @@ seekdir (DIR * dirp, long lPos) else { /* Rewind and read forward to the appropriate index. */ - rewinddir (dirp); + _trewinddir (dirp); - while ((dirp->dd_stat < lPos) && readdir (dirp)) + while ((dirp->dd_stat < lPos) && _treaddir (dirp)) ; } } diff --git a/winsup/mingw/mingwex/wdirent.c b/winsup/mingw/mingwex/wdirent.c new file mode 100644 index 000000000..4b8cc5054 --- /dev/null +++ b/winsup/mingw/mingwex/wdirent.c @@ -0,0 +1,3 @@ +#define _UNICODE 1 +#define UNICODE 1 +#include "dirent.c" diff --git a/winsup/mingw/samples/dirent/wtest.c b/winsup/mingw/samples/dirent/wtest.c new file mode 100644 index 000000000..798544374 --- /dev/null +++ b/winsup/mingw/samples/dirent/wtest.c @@ -0,0 +1,98 @@ +/* + * A test which demonstrates the use of _wopendir and related + * wide char functions declared in dirent.h. + * + * TODO: Make this _UNICODE neutral using tchar.h mappings. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <dirent.h> + +int +main (int argc, char* argv[]) +{ + int i; + struct _wdirent* de; + _WDIR* dir; + long lPos; + + if (argc == 2) + { + size_t len = strlen(argv[1]) + 1; + wchar_t* wpath = (wchar_t*) malloc(len *sizeof(wchar_t)); + mbstowcs(wpath, argv[1], len); + wprintf (L"Opening directory \"%s\"\n", wpath); + dir = _wopendir(wpath); + free (wpath); + } + else + { + wprintf (L"Opening \".\"\n"); + dir = _wopendir(L"."); + } + + if (!dir) + { + wprintf (L"Directory open failed!\n"); + if (errno) + { + wprintf (L"Error : %S\n", strerror(errno)); + } + return 1; + } + + i = 0; + lPos = -1; + + while ((de = _wreaddir (dir))) + { + i++; + wprintf (L"%d : \"%s\" (tell %ld)\n", i, de->d_name, + _wtelldir(dir)); + + if (i == 3) + { + wprintf (L"We will seek here later.\n"); + lPos = _wtelldir (dir); + } + } + + printf ("Rewind directory.\n"); + _wrewinddir (dir); + + if ((de = _wreaddir (dir))) + { + wprintf (L"First entry : \"%s\"\n", de->d_name); + } + else + { + wprintf (L"Empty directory.\n"); + } + + if (lPos != -1) + { + wprintf (L"Seeking to fourth entry.\n"); + _wseekdir (dir, lPos); + + if ((de = _wreaddir (dir))) + { + wprintf (L"Fourth entry : \"%s\"\n", de->d_name); + } + else + { + wprintf (L"No fourth entry.\n"); + } + } + else + { + wprintf (L"Seek position is past end of directory.\n"); + } + + wprintf (L"Closing directory.\n"); + _wclosedir (dir); +return 0; +} + |