From 74b5914a220b9ea0ed4abf4f7e7b448d4a9894e5 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Mon, 20 Apr 2009 16:40:08 -0500 Subject: [PATCH] add extra files for WIN32. --- packages/PLStream/pl-mswchar.h | 39 ++ packages/PLStream/uxnt/README | 8 + packages/PLStream/uxnt/dirent.h | 51 ++ packages/PLStream/uxnt/utf8.c | 101 ++++ packages/PLStream/uxnt/utf8.h | 58 +++ packages/PLStream/uxnt/uxnt.c | 883 ++++++++++++++++++++++++++++++++ packages/PLStream/uxnt/uxnt.h | 154 ++++++ 7 files changed, 1294 insertions(+) create mode 100644 packages/PLStream/pl-mswchar.h create mode 100644 packages/PLStream/uxnt/README create mode 100644 packages/PLStream/uxnt/dirent.h create mode 100644 packages/PLStream/uxnt/utf8.c create mode 100644 packages/PLStream/uxnt/utf8.h create mode 100644 packages/PLStream/uxnt/uxnt.c create mode 100644 packages/PLStream/uxnt/uxnt.h diff --git a/packages/PLStream/pl-mswchar.h b/packages/PLStream/pl-mswchar.h new file mode 100644 index 000000000..bac2c7d95 --- /dev/null +++ b/packages/PLStream/pl-mswchar.h @@ -0,0 +1,39 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: wielemak@science.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2005, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +See pl-mswchar.cpp for the motivation for this nonsense. Used in +pl-fli.c and pl-text.c. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#if defined(__WINDOWS__) && !defined(__MINGW32__) + +#define wcrtomb(s, wc, ps) ms_wcrtomb(s, wc, ps) +#define mbrtowc(pwc, s, n, ps) ms_mbrtowc(pwc, s, n, ps) + +extern size_t ms_wcrtomb(char *s, wchar_t wc, mbstate_t *ps); +extern size_t ms_mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps); +#endif diff --git a/packages/PLStream/uxnt/README b/packages/PLStream/uxnt/README new file mode 100644 index 000000000..12fc16775 --- /dev/null +++ b/packages/PLStream/uxnt/README @@ -0,0 +1,8 @@ +The UXNT.LIB library is used SWI-Prolog and XPCE to make the NT and 95 +filesystem a bit more like the Unix one. It deals with mapping directory +separators, ensuring there are only single separators (mapping // to \ +for example) that root-directories of devices (c:/, etc.) are handled +properly, no matter how the name is formed. It also implemends readdir() +and friends for Unix-compatible access to the directory. + + Regards --- Jan diff --git a/packages/PLStream/uxnt/dirent.h b/packages/PLStream/uxnt/dirent.h new file mode 100644 index 000000000..6984639ea --- /dev/null +++ b/packages/PLStream/uxnt/dirent.h @@ -0,0 +1,51 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _DIRENT_H_INCLUDED +#define _DIRENT_H_INCLUDED + +#include + +#undef _export +#if defined(_UXNT_KERNEL) && !defined(__LCC__) +#define _export _declspec(dllexport) +#else +#define _export extern +#endif + +#define DIRENT_MAX 512 + +typedef struct dirent +{ void * data; /* actually WIN32_FIND_DATA * */ + int first; + void * handle; /* actually HANDLE */ + /* dirent */ + char d_name[DIRENT_MAX+1]; +} DIR; + +_export DIR * opendir(const char *path); +_export int closedir(DIR *dp); +_export struct dirent * readdir(DIR *dp); + +#endif /*_DIRENT_H_INCLUDED*/ diff --git a/packages/PLStream/uxnt/utf8.c b/packages/PLStream/uxnt/utf8.c new file mode 100644 index 000000000..c6e730e43 --- /dev/null +++ b/packages/PLStream/uxnt/utf8.c @@ -0,0 +1,101 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker and Anjo Anjewierden + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "utf8.h" + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +UTF-8 Decoding, based on http://www.cl.cam.ac.uk/~mgk25/unicode.html +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +#define CONT(i) ISUTF8_CB(in[1]) +#define VAL(i, s) ((in[i]&0x3f) << s) + +static char * +_xos_utf8_get_char(const char *in, int *chr) +{ /* 2-byte, 0x80-0x7ff */ + if ( (in[0]&0xe0) == 0xc0 && CONT(1) ) + { *chr = ((in[0]&0x1f) << 6)|VAL(1,0); + return (char *)in+2; + } + /* 3-byte, 0x800-0xffff */ + if ( (in[0]&0xf0) == 0xe0 && CONT(1) && CONT(2) ) + { *chr = ((in[0]&0xf) << 12)|VAL(1,6)|VAL(2,0); + return (char *)in+3; + } + /* 4-byte, 0x10000-0x1FFFFF */ + if ( (in[0]&0xf8) == 0xf0 && CONT(1) && CONT(2) && CONT(3) ) + { *chr = ((in[0]&0x7) << 18)|VAL(1,12)|VAL(2,6)|VAL(3,0); + return (char *)in+4; + } + /* 5-byte, 0x200000-0x3FFFFFF */ + if ( (in[0]&0xfc) == 0xf8 && CONT(1) && CONT(2) && CONT(3) && CONT(4) ) + { *chr = ((in[0]&0x3) << 24)|VAL(1,18)|VAL(2,12)|VAL(3,6)|VAL(4,0); + return (char *)in+5; + } + /* 6-byte, 0x400000-0x7FFFFFF */ + if ( (in[0]&0xfe) == 0xfc && CONT(1) && CONT(2) && CONT(3) && CONT(4) && CONT(5) ) + { *chr = ((in[0]&0x1) << 30)|VAL(1,24)|VAL(2,18)|VAL(3,12)|VAL(4,6)|VAL(5,0); + return (char *)in+4; + } + + *chr = *in; + + return (char *)in+1; +} + + +static char * +_xos_utf8_put_char(char *out, int chr) +{ if ( chr < 0x80 ) + { *out++ = chr; + } else if ( chr < 0x800 ) + { *out++ = 0xc0|((chr>>6)&0x1f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x10000 ) + { *out++ = 0xe0|((chr>>12)&0x0f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x200000 ) + { *out++ = 0xf0|((chr>>18)&0x07); + *out++ = 0x80|((chr>>12)&0x3f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x4000000 ) + { *out++ = 0xf8|((chr>>24)&0x03); + *out++ = 0x80|((chr>>18)&0x3f); + *out++ = 0x80|((chr>>12)&0x3f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } else if ( chr < 0x80000000 ) + { *out++ = 0xfc|((chr>>30)&0x01); + *out++ = 0x80|((chr>>24)&0x3f); + *out++ = 0x80|((chr>>18)&0x3f); + *out++ = 0x80|((chr>>12)&0x3f); + *out++ = 0x80|((chr>>6)&0x3f); + *out++ = 0x80|(chr&0x3f); + } + + return out; +} + diff --git a/packages/PLStream/uxnt/utf8.h b/packages/PLStream/uxnt/utf8.h new file mode 100644 index 000000000..410557d18 --- /dev/null +++ b/packages/PLStream/uxnt/utf8.h @@ -0,0 +1,58 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker and Anjo Anjewierden + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef UTF8_H_INCLUDED +#define UTF8_H_INCLUDED + +#define UTF8_MALFORMED_REPLACEMENT 0xfffd + +#define ISUTF8_MB(c) ((unsigned)(c) >= 0xc0 && (unsigned)(c) <= 0xfd) + +#define ISUTF8_CB(c) (((c)&0xc0) == 0x80) /* Is continuation byte */ +#define ISUTF8_FB2(c) (((c)&0xe0) == 0xc0) +#define ISUTF8_FB3(c) (((c)&0xf0) == 0xe0) +#define ISUTF8_FB4(c) (((c)&0xf8) == 0xf0) +#define ISUTF8_FB5(c) (((c)&0xfc) == 0xf8) +#define ISUTF8_FB6(c) (((c)&0xfe) == 0xfc) + +#define UTF8_FBN(c) (!(c&0x80) ? 0 : \ + ISUTF8_FB2(c) ? 1 : \ + ISUTF8_FB3(c) ? 2 : \ + ISUTF8_FB4(c) ? 3 : \ + ISUTF8_FB5(c) ? 4 : \ + ISUTF8_FB6(c) ? 5 : -1) +#define UTF8_FBV(c,n) ( n == 0 ? c : (c & ((0x01<<(6-n))-1)) ) + +#define utf8_get_char(in, chr) \ + (*(in) & 0x80 ? _xos_utf8_get_char(in, chr) \ + : (*(chr) = *(in), (char *)(in)+1)) +#define utf8_put_char(out, chr) \ + ((chr) < 0x80 ? out[0]=(char)(chr), out+1 \ + : _xos_utf8_put_char(out, (chr))) + +extern char *_xos_utf8_get_char(const char *in, int *chr); +extern char *_xos_utf8_put_char(char *out, int chr); + +#endif /*UTF8_H_INCLUDED*/ diff --git a/packages/PLStream/uxnt/uxnt.c b/packages/PLStream/uxnt/uxnt.c new file mode 100644 index 000000000..01d5e7ed3 --- /dev/null +++ b/packages/PLStream/uxnt/uxnt.c @@ -0,0 +1,883 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define UNICODE 1 +#define _UNICODE 1 + +#define _UXNT_KERNEL 1 +#include "uxnt.h" /* my prototypes */ +#include "utf8.c" + +#include +#include +#include +#include "dirent.h" +#include +#include +#include +#include +#include +#include +#include +#undef mkdir /* avoid conflict */ +#include +#ifndef __LCC__ /* not delete altogether? */ +#define mkdir _xos_mkdir +#endif +#include + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif + + +#ifdef __LCC__ +#define _close close +#define _read read +#define _write write +#define _lseek lseek +#define _tell tell +#define _chdir chdir +#define _mkdir mkdir +#define _rmdir rmdir +#define _getcwd getcwd +#endif + +#define XENOMAP 1 +#define XENOMEM 2 + + + /******************************* + * ERRNO * + *******************************/ + +int +_xos_errno() +{ return errno; +} + + /******************************* + * UTF-8 * + *******************************/ + +static char * +wcstoutf8(char *dest, const wchar_t *src, size_t len) +{ char *o = dest; + char *e = &o[len]; + + for(; *src; src++) + { if ( o+6 > e ) + { errno = ENAMETOOLONG; + return NULL; + } + o = utf8_put_char(o, *src); + } + *o = '\0'; + + return dest; +} + + +/* length of src in UTF-8, excluding terminating EOS */ + +static size_t +wcutf8len(const wchar_t *src) +{ size_t len = 0; + + for(; *src; src++) + { if ( *src < 0x80 ) + { len++; + } else + { char o[6]; + char *e; + e = utf8_put_char(o, *src); + len += e-o; + } + } + + return len; +} + + +static wchar_t * +utf8towcs(wchar_t *dest, const char *src, size_t len) +{ wchar_t *o = dest; + wchar_t *e = &o[len-1]; + + for( ; *src; ) + { int wc; + + src = utf8_get_char(src, &wc); + if ( o >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *o++ = wc; + } + *o = 0; + + return dest; +} + + + + + /******************************* + * HOME * + *******************************/ + +static int +existsAndWriteableDir(const TCHAR *name) +{ DWORD a; + + if ( (a=GetFileAttributes(name)) != 0xFFFFFFFF ) + { if ( a & FILE_ATTRIBUTE_DIRECTORY ) + { if ( !(a & FILE_ATTRIBUTE_READONLY) ) + return TRUE; + } + } + + return FALSE; +} + + +char * +_xos_home() /* expansion of ~ */ +{ static char home[MAXPATHLEN]; + static int done = FALSE; + + if ( !done ) + { TCHAR h[MAXPATHLEN]; + + /* Unix, set by user */ + if ( GetEnvironmentVariable(_T("HOME"), h, sizeof(h)) && + existsAndWriteableDir(h) ) + { _xos_canonical_filenameW(h, home, sizeof(home), 0); + } else if ( GetEnvironmentVariable(_T("USERPROFILE"), h, sizeof(h)) && + existsAndWriteableDir(h) ) + { _xos_canonical_filenameW(h, home, sizeof(home), 0); + } else + { TCHAR d[100]; + TCHAR p[MAXPATHLEN]; + TCHAR tmp[MAXPATHLEN]; + int haved, havep; + + haved = GetEnvironmentVariable(_T("HOMEDRIVE"), d, sizeof(d)); + havep = GetEnvironmentVariable(_T("HOMEPATH"), p, sizeof(p)); + + tmp[0] = '\0'; + if ( haved && havep ) /* Windows-NT */ + { _tcscpy(tmp, d); + _tcscat(tmp, p); + } else if ( haved ) + { _tcscpy(tmp, d); + _tcscat(tmp, _T("\\")); + } else if ( havep ) + { _tcscpy(tmp, p); + } else if ( GetWindowsDirectory(tmp, sizeof(tmp)) == 0 ) + { int drv = _getdrive(); /* A=1 */ + + tmp[0] = drv-1+'a'; + _tcscpy(&tmp[1], _T(":\\")); + } + + _xos_canonical_filenameW(tmp, home, sizeof(home), 0); + } + + done = TRUE; + } + + return home; +} + + + /******************************* + * NAME CONVERSION * + *******************************/ + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Map a UTF-8 string in Prolog internal representation to a UNICODE string +to be used with the Windows UNICODE access functions. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +wchar_t * +_xos_os_filenameW(const char *cname, wchar_t *osname, size_t len) +{ wchar_t *s = osname; + wchar_t *e = &osname[len-1]; + const char *q = cname; + + s = osname; + /* /c:/ --> c:/ */ + if ( q[0] == '/' && q[1] < 0x80 && isalpha(q[1]) && q[2] == ':' && + (q[3] == '/' || q[3] == '\0') ) + { if ( s+2 >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *s++ = q[1]; + *s++ = ':'; + q += 3; + } + + if ( q[0] == '/' || q[0] == '\\' ) /* deal with //host/share */ + { if ( s+1 >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *s++ = '\\'; + } + + while( *q ) /* map / --> \, delete multiple '\' */ + { if ( *q == '/' || *q == '\\' ) + { if ( s+1 >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *s++ = '\\'; + q++; + while(*q == '/' || *q == '\\') + q++; + } else + { int wc; + + q = utf8_get_char(q, &wc); + if ( s+2 >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *s++ = wc; + } + } + + while(s > osname+1 && s[-1] == '\\' ) /* delete trailing '\' */ + s--; + /* d: --> d:\ */ + if ( s == &osname[2] && osname[1] == ':' && + osname[0] < 0x80 && isalpha(osname[0]) ) + *s++ = '\\'; + *s = '\0'; + + return osname; +} + + +char * +_xos_os_filename(const char *cname, char *osname, size_t len) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(cname, buf, PATH_MAX) ) + return NULL; + + return wcstoutf8(osname, buf, len); +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Transform a UNICODE Windows filename into a UTF-8 representation of the +filename in Prolog canonical representation. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +char * +_xos_canonical_filenameW(const wchar_t *spec, + char *xname, size_t len, + int flags) +{ const wchar_t *s = spec; + char *p = xname; + char *e = &xname[len]; + + if ( s[0] < 0x80 && isupper(s[0]) && s[1] == ':' ) + { *p++ = tolower(s[0]); + *p++ = (char)s[1]; + s += 2; + } + + for(; *s; s++) + { int c = *s; + + if ( c == '\\' ) + { c = '/'; + } else if ( (flags&XOS_DOWNCASE) ) + { c = towlower((wchar_t)c); + } + + if ( p+6 >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + p = utf8_put_char(p, c); + } + *p = '\0'; + + return xname; +} + + +char * +_xos_canonical_filename(const char *spec, char *xname, size_t len, int flags) +{ TCHAR buf[PATH_MAX]; + + if ( !utf8towcs(buf, spec, PATH_MAX) ) + return NULL; + + return _xos_canonical_filenameW(buf, xname, len, flags); +} + + +int +_xos_is_absolute_filename(const char *spec) +{ TCHAR buf[PATH_MAX]; + + _xos_os_filenameW(spec, buf, PATH_MAX); + if ( buf[1] == ':' && buf[0] < 0x80 && iswalpha(buf[0]) ) + return TRUE; /* drive */ + if ( buf[0] == '\\' && buf[1] == '\\' ) + return TRUE; /* UNC */ + + return FALSE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Get rid of possible 8+3 characters in the path. The documentation +suggests you can do that using a single FindFirstFile or +GetFullPathName, but it appears you cannot. If you like, here is the +code that doesn't work: + +char * +_xos_long_file_nameW(const char *file, char *longname) +{ DWORD len; + LPTSTR fp; + + if ( !(len=GetFullPathName(file, PATH_MAX, longname, &fp)) || + len >= PATH_MAX ) + strcpy(longname, file); + + return longname; +} +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +TCHAR * +_xos_long_file_nameW(const TCHAR *file, TCHAR *longname, size_t len) +{ const TCHAR *i = file; + TCHAR *o = longname; + TCHAR *ok = longname; + TCHAR *e = &longname[len-1]; + int changed = 0; + + while(*i) + { int dirty = FALSE; + + while(*i && *i != '\\' && *i != '/' ) + { if ( *i == '~' ) + dirty++; + if ( o >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *o++ = *i++; + } + if ( dirty ) + { WIN32_FIND_DATA data; + HANDLE h; + + *o = '\0'; + if ( (h=FindFirstFile(longname, &data)) != INVALID_HANDLE_VALUE ) + { size_t l = _tcslen(data.cFileName); + + if ( ok+l >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + + _tcscpy(ok, data.cFileName); + FindClose(h); + o = ok + l; + changed++; + } + } + if ( *i ) + { if ( o >= e ) + { errno = ENAMETOOLONG; + return NULL; + } + *o++ = *i++; + } + ok = o; + } + + *o = '\0'; + + return longname; +} + + +char * +_xos_long_file_name_toA(const wchar_t *file, char *longname, size_t len) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_long_file_nameW(file, buf, PATH_MAX) ) + return NULL; + + return wcstoutf8(longname, buf, len); +} + + +char * +_xos_long_file_name(const char *file, char *longname, size_t len) +{ TCHAR in[PATH_MAX]; + TCHAR out[PATH_MAX]; + + if ( !utf8towcs(in, file, PATH_MAX) ) + return NULL; + + if ( !_xos_long_file_nameW(in, out, PATH_MAX) ) + return NULL; + + return wcstoutf8(longname, out, len); +} + + +char * +_xos_absolute_filename(const char *local, char *absolute, size_t len) +{ TCHAR buf[PATH_MAX]; + TCHAR *filepart; + TCHAR abs[PATH_MAX]; + + if ( !_xos_os_filenameW(local, buf, PATH_MAX) ) + return NULL; + + if ( GetFullPathName(buf, PATH_MAX, abs, &filepart) ) + return _xos_canonical_filenameW(abs, absolute, len, 0); + + return NULL; +} + + +int +_xos_same_file(const char *p1, const char *p2) +{ if ( strcmp(p1, p2) == 0 ) + { return TRUE; + } else + { TCHAR osp1[PATH_MAX], osp2[PATH_MAX]; + TCHAR abs1[PATH_MAX], abs2[PATH_MAX]; + TCHAR *fp; + + if ( !_xos_os_filenameW(p1, osp1, PATH_MAX) || + !_xos_os_filenameW(p2, osp2, PATH_MAX) ) + return -1; /* error */ + + if ( !GetFullPathName(osp1, PATH_MAX, abs1, &fp) || + !GetFullPathName(osp2, PATH_MAX, abs2, &fp) ) + return -1; + + //fwprintf(stderr, _T("f1='%s'\nf2='%s'\n"), abs1, abs2); + + if ( _tcsicmp(abs1, abs2) == 0 ) + return TRUE; + } + + return FALSE; +} + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Apply file-name limitations to a path-name. For DOS-type filesystems, +this implies limitation to the 8+3 convention and omitting illegal +characters. NT doesn't have all this, but filenames are matched case +insensitive, so we map everything to one case. Note that both arguments +are in UTF-8 encoding! +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +char * +_xos_limited_os_filename(const char *spec, char *limited) +{ const unsigned char *i = (const unsigned char*)spec; + char *o = limited; + + while(*i) + { int wc; + + i = utf8_get_char(i, &wc); + wc = towlower((wchar_t)wc); + o = utf8_put_char(o, wc); + } + *o = '\0'; + + return limited; +} + + + /******************************* + * FILE READ/WRITE * + *******************************/ + +int +_xos_open(const char *path, int access, ...) +{ va_list args; + TCHAR buf[PATH_MAX]; + int mode; + + va_start(args, access); + mode = va_arg(args, int); + va_end(args); + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _wopen(buf, access, mode); +} + + +int +_xos_close(int handle) +{ return _close(handle); +} + + +ssize_t +_xos_read(int handle, void *buf, size_t size) +{ return _read(handle, buf, (unsigned int)size); +} + + +ssize_t +_xos_write(int handle, const void *buf, size_t size) +{ return _write(handle, buf, (unsigned int)size); +} + + +long +_xos_lseek(int handle, long offset, int whence) +{ return _lseek(handle, offset, whence); +} + + +long +_xos_tell(int handle) +{ return _tell(handle); +} + + +FILE * +_xos_fopen(const char *path, const char *mode) +{ TCHAR buf[PATH_MAX]; + TCHAR m[10]; + int i; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return NULL; + + for(i=0; *mode && i < sizeof(m-1); ) + m[i++] = (*mode++)&0xff; + m[i] = 0; + + return _wfopen(buf, m); +} + + + + /******************************* + * FILE MANIPULATIONS * + *******************************/ + +int +_xos_access(const char *path, int mode) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _waccess(buf, mode); +} + + +int +_xos_chmod(const char *path, int mode) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _wchmod(buf, mode); +} + + +int +_xos_remove(const char *path) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _wremove(buf); +} + + +int +_xos_rename(const char *old, const char *new) +{ TCHAR osold[PATH_MAX]; + TCHAR osnew[PATH_MAX]; + + if ( !_xos_os_filenameW(old, osold, PATH_MAX) || + !_xos_os_filenameW(new, osnew, PATH_MAX) ) + return -1; + + return _wrename(osold, osnew); +} + + +int +_xos_stat(const char *path, struct _stat *sbuf) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _wstat(buf, sbuf); +} + + +int +_xos_exists(const char *path, int flags) +{ TCHAR buf[PATH_MAX]; + DWORD a; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + if ( (a=GetFileAttributes(buf)) != 0xFFFFFFFF ) + { if ( flags & _XOS_DIR ) + { if ( a & FILE_ATTRIBUTE_DIRECTORY ) + return TRUE; + else + return FALSE; + } + if ( flags & _XOS_FILE ) + { if ( a & FILE_ATTRIBUTE_DIRECTORY ) + return FALSE; + } + + return TRUE; + } + + return FALSE; +} + + + /******************************* + * DIRECTORIES * + *******************************/ + +DIR * +opendir(const char *path) +{ TCHAR buf[PATH_MAX]; + DIR *dp = malloc(sizeof(DIR)); + + if ( !_xos_os_filenameW(path, buf, PATH_MAX-4) ) + return NULL; + _tcscat(buf, _T("\\*.*")); + + if ( !(dp->data = malloc(sizeof(WIN32_FIND_DATA))) ) + { errno = ENOMEM; + return NULL; + } + dp->first = 1; + dp->handle = FindFirstFile(buf, dp->data); + + if ( dp->handle == INVALID_HANDLE_VALUE ) + { if ( _waccess(buf, 04) ) /* does not exist */ + { free(dp->data); + return NULL; + } + } + + return dp; +} + + +int +closedir(DIR *dp) +{ if ( dp ) + { if ( dp->handle ) + FindClose(dp->handle); + free(dp->data); + free(dp); + + return 0; + } + + return -1; +} + + +static struct dirent * +translate_data(DIR *dp) +{ WIN32_FIND_DATA *data; + + if ( !dp->handle ) + return NULL; + + data = dp->data; + if ( wcstoutf8(dp->d_name, data->cFileName, sizeof(dp->d_name)) ) + return dp; + + return NULL; +} + + +struct dirent * +readdir(DIR *dp) +{ for(;;) + { struct dirent *de; + + if ( dp->first ) + { dp->first = 0; + } else + { if ( dp->handle ) + { if ( !FindNextFile(dp->handle, dp->data) ) + return NULL; + } + } + + if ( (de = translate_data(dp)) ) + return de; + } +} + + +int +_xos_chdir(const char *path) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + if ( buf[0] < 0x80 && isalpha(buf[0]) && buf[1] == ':' ) + { int drv = tolower(buf[0]) - 'a' + 1; + + if ( _getdrive() != drv ) + { if ( _chdrive(drv) < 0 ) + return -1; + } + } + + return _wchdir(buf); +} + + +int +_xos_mkdir(const char *path, int mode) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _wmkdir(buf); +} + + +int +_xos_rmdir(const char *path) +{ TCHAR buf[PATH_MAX]; + + if ( !_xos_os_filenameW(path, buf, PATH_MAX) ) + return -1; + + return _wrmdir(buf); +} + + +char * +_xos_getcwd(char *buf, size_t len) +{ TCHAR buf0[PATH_MAX]; + TCHAR buf1[PATH_MAX]; + + if ( _wgetcwd(buf0, sizeof(buf0)/sizeof(TCHAR)) && + _xos_long_file_nameW(buf0, buf1, sizeof(buf0)/sizeof(TCHAR)) ) + { return _xos_canonical_filenameW(buf1, buf, len, 0); + } + + return NULL; +} + + /******************************* + * ENVIRONMENT * + *******************************/ + +size_t +_xos_getenv(const char *name, char *buf, size_t buflen) +{ TCHAR nm[PATH_MAX]; + TCHAR val[PATH_MAX]; + TCHAR *valp = val; + DWORD size; + + if ( !utf8towcs(nm, name, PATH_MAX) ) + return -1; + size = GetEnvironmentVariable(nm, valp, PATH_MAX); + + if ( size > 0 ) + { size_t rc; + + if ( size >= PATH_MAX ) + { if ( (valp = malloc((size+1)*sizeof(TCHAR))) == NULL ) + return -1; + size = GetEnvironmentVariable(nm, valp, size+1); + } + + if ( wcstoutf8(buf, valp, buflen) ) + rc = strlen(buf); + else + rc = wcutf8len(valp); + + if ( valp != val ) + free(valp); + + return rc; + } + + return -1; +} + + +int +_xos_setenv(const char *name, char *value, int overwrite) +{ TCHAR nm[PATH_MAX]; + TCHAR val[PATH_MAX]; + + if ( !utf8towcs(nm, name, PATH_MAX) ) + return -1; + if ( !overwrite && GetEnvironmentVariable(nm, NULL, 0) > 0 ) + return 0; + if ( !utf8towcs(val, value, PATH_MAX) ) + return -1; + + if ( SetEnvironmentVariable(nm, val) ) + return 0; + + return -1; /* TBD: convert error */ +} diff --git a/packages/PLStream/uxnt/uxnt.h b/packages/PLStream/uxnt/uxnt.h new file mode 100644 index 000000000..09ae6764c --- /dev/null +++ b/packages/PLStream/uxnt/uxnt.h @@ -0,0 +1,154 @@ +/* $Id$ + + Part of SWI-Prolog + + Author: Jan Wielemaker + E-mail: jan@swi.psy.uva.nl + WWW: http://www.swi-prolog.org + Copyright (C): 1985-2002, University of Amsterdam + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _XNT_H_INCLUDED +#define _XNT_H_INCLUDED + +#undef _export +#if defined(_UXNT_KERNEL) && !defined(__MINGW32__) +#define _export _declspec(dllexport) +#else +#define _export extern +#endif + +#include +#include +#include +#include +#if !defined(__MINGW32__) +#if (_MSC_VER < 1300) +typedef long intptr_t; +typedef unsigned long uintptr_t; +#endif +typedef intptr_t ssize_t; /* signed version of size_t */ +#endif + +#ifndef _UXNT_KERNEL +#include + +#undef remove +#undef rename +#undef open +#undef close +#undef read +#undef write +#undef lseek +#undef tell +#undef access +#undef chmod +#undef remove +#undef rename +#undef stat +#undef chdir +#undef mkdir +#undef rmdir +#undef getcwd + +#define remove _xos_remove +#define rename _xos_rename +#define open _xos_open +#define close _xos_close +#define read _xos_read +#define write _xos_write +#define lseek _xos_lseek +#define tell _xos_tell +#define access _xos_access +#define chmod _xos_chmod +#define remove _xos_remove +#define rename _xos_rename +#define statfunc _xos_stat +#define chdir _xos_chdir +#define mkdir _xos_mkdir +#define rmdir _xos_rmdir +#define getcwd _xos_getcwd +#define setenv _xos_setenv +#define fopen(p, m) _xos_fopen(p, m) + +#endif /*_UXNT_KERNEL*/ + +#ifndef __MINGW32__ +#define F_OK 00 +#define R_OK 04 /* access() fields */ +#define W_OK 06 +#endif + + /******************************* + * TYPES, ETC * + *******************************/ + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#undef _xos_stat + +_export char * _xos_home(void); +_export wchar_t*_xos_os_filenameW(const char *cname, + wchar_t *osname, size_t len); +_export char * _xos_os_filename(const char *cname, + char *osname, size_t len); +_export char * _xos_canonical_filenameW(const wchar_t *cname, + char *osname, size_t len, int flags); +_export char * _xos_canonical_filename(const char *cname, + char *osname, size_t len, int flags); +_export int _xos_is_absolute_filename(const char *spec); +_export char * _xos_absolute_filename(const char *local, char *absolute, size_t len); +_export char * _xos_limited_os_filename(const char *spec, char *limited); +_export wchar_t*_xos_long_file_nameW(const wchar_t *n8and3, + wchar_t *name, size_t len); +_export char* _xos_long_file_name_toA(const wchar_t *n8and3, + char *name, size_t len); +_export char * _xos_long_file_name(const char *file, char *longname, + size_t len); +_export int _xos_same_file(const char *p1, const char *p2); +_export int _xos_open(const char *path, int access, ...); +_export FILE* _xos_fopen(const char *path, const char *mode); +_export int _xos_close(int handle); +_export ssize_t _xos_read(int handle, void *buf, size_t size); +_export ssize_t _xos_write(int handle, const void *buf, size_t size); +_export long _xos_lseek(int handle, long offset, int whence); +_export long _xos_tell(int handle); +_export int _xos_access(const char *path, int mode); +_export int _xos_chmod(const char *path, int mode); +_export int _xos_remove(const char *path); +_export int _xos_rename(const char *old, const char *newname); +_export int _xos_stat(const char *path, struct _stat *sbuf); +_export int _xos_chdir(const char *path); +_export int _xos_mkdir(const char *path, int mode); +_export int _xos_rmdir(const char *path); +_export char * _xos_getcwd(char *buf, size_t len); +_export int _xos_errno(void); +_export int _xos_exists(const char *path, int flags); +_export size_t _xos_getenv(const char *name, char *buf, size_t buflen); +_export int _xos_setenv(const char *name, char *value, int overwrite); + +#define _XOS_ISFILE 0x01 +#define _XOS_ISDIR 0x02 + +#define _XOS_FILE 0x0001 /* is a file */ +#define _XOS_DIR 0x0002 /* is a directory */ + +#define XOS_DOWNCASE 0x01 /* _xos_canonical_filename() */ + +#endif /*_XNT_H_INCLUDED*/