upgrade to latest SWI

This commit is contained in:
Vitor Santos Costa
2011-02-10 00:01:19 +00:00
parent 8e8c361671
commit 232a740d43
48 changed files with 12317 additions and 2703 deletions

View File

@@ -22,24 +22,15 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __MINGW32__
#define __WINDOWS__ 1
#endif
#ifdef __WINDOWS__
#include <uxnt/uxnt.h>
#ifdef __MINGW32__
#include "config.h"
#include <windows.h>
#else
#include <uxnt.h>
#ifdef WIN64
#define MD "config/win64.h"
#else
#define MD "config/win32.h"
#endif
#endif
#include <winsock2.h>
#include "pl-mswchar.h"
#include "windows/mswchar.h"
#define CRLF_MAPPING 1
#endif
@@ -148,14 +139,14 @@ STRYLOCK(IOSTREAM *s)
#define STRYLOCK(s) (TRUE)
#endif
#include "pl-error.h"
typedef void *record_t;
typedef void *Module;
typedef intptr_t term_t;
typedef intptr_t atom_t;
#include "pl-error.h"
extern int fatalError(const char *fm, ...);
extern int PL_error(const char *pred, int arity,
const char *msg, int id, ...);
extern int PL_handle_signals(void);
extern int PL_handle_signals();
extern IOENC initEncoding(void);
extern int reportStreamError(IOSTREAM *s);
extern record_t PL_record(term_t t);
@@ -310,6 +301,11 @@ int
Slock(IOSTREAM *s)
{ SLOCK(s);
if ( s->erased )
{ SUNLOCK(s);
return -1;
}
#ifdef DEBUG_IO_LOCKS
if ( s->locks > 2 )
{ printf(" Lock [%d]: %s: %d locks", PL_thread_self(), Sname(s), s->locks+1);
@@ -331,6 +327,11 @@ StryLock(IOSTREAM *s)
{ if ( !STRYLOCK(s) )
return -1;
if ( s->erased )
{ SUNLOCK(s);
return -1;
}
if ( !s->locks++ )
{ if ( (s->flags & (SIO_NBUF|SIO_OUTPUT)) == (SIO_NBUF|SIO_OUTPUT) )
return S__setbuf(s, NULL, TMPBUFSIZE) == (size_t)-1 ? -1 : 0;
@@ -370,7 +371,7 @@ Sunlock(IOSTREAM *s)
*******************************/
/* return values: -1: error, else #bytes written */
static ssize_t
S__flushbuf(IOSTREAM *s)
{ char *from, *to;
@@ -439,6 +440,52 @@ S__flushbufc(int c, IOSTREAM *s)
}
static int
Swait_for_data(IOSTREAM *s)
{ int fd = Sfileno(s);
fd_set wait;
struct timeval time;
int rc;
if ( fd < 0 )
{ errno = EPERM; /* no permission to select */
s->flags |= SIO_FERR;
return -1;
}
time.tv_sec = s->timeout / 1000;
time.tv_usec = (s->timeout % 1000) * 1000;
FD_ZERO(&wait);
#ifdef __WINDOWS__
FD_SET((SOCKET)fd, &wait);
#else
FD_SET(fd, &wait);
#endif
for(;;)
{ rc = select(fd+1, &wait, NULL, NULL, &time);
if ( rc < 0 && errno == EINTR )
{ if ( PL_handle_signals() < 0 )
{ errno = EPLEXCEPTION;
return -1;
}
continue;
}
break;
}
if ( rc == 0 )
{ s->flags |= (SIO_TIMEOUT|SIO_FERR);
return -1;
}
return 0; /* ok, data available */
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
S__fillbuf() fills the read-buffer, returning the first character of it.
It also realises the SWI-Prolog timeout facility.
@@ -456,51 +503,14 @@ S__fillbuf(IOSTREAM *s)
#ifdef HAVE_SELECT
s->flags &= ~SIO_TIMEOUT;
if ( s->timeout >= 0 )
{ int fd = Sfileno(s);
if ( s->timeout >= 0 && !s->downstream )
{ int rc;
if ( fd >= 0 )
{ fd_set wait;
struct timeval time;
int rc;
time.tv_sec = s->timeout / 1000;
time.tv_usec = (s->timeout % 1000) * 1000;
FD_ZERO(&wait);
#ifdef __WINDOWS__
FD_SET((SOCKET)fd, &wait);
#else
FD_SET(fd, &wait);
#endif
for(;;)
{ rc = select(fd+1, &wait, NULL, NULL, &time);
if ( rc < 0 && errno == EINTR )
{ if ( PL_handle_signals() < 0 )
{ errno = EPLEXCEPTION;
return -1;
}
continue;
}
break;
}
if ( rc == 0 )
{ s->flags |= (SIO_TIMEOUT|SIO_FERR);
return -1;
}
} else
{ errno = EPERM; /* no permission to select */
s->flags |= SIO_FERR;
return -1;
}
if ( (rc=Swait_for_data(s)) < 0 )
return rc;
}
#endif
if ( s->flags & SIO_NBUF )
{ char chr;
ssize_t n;
@@ -1053,124 +1063,60 @@ out:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(*) For ENC_ANSI there is a problem as this deals with multi-modal
streams, streams that may hold escape sequences to move from one
character set to another: ascii ... <esc1> japanese <esc2> ascii ...
Suppose now we have two characters [ascii, japanese]. When reading the
japanese character the first time, the system will translate the
<esc><japanese> and the mode will be japanese. When pushing back, only
the japanese character will be put back, not the escape sequence. What
to do?
peek needs to keep track of the actual bytes processed because not doing
so might lead to an incorrect byte-count in the position term. The
simplest example is that when looking at \r\n in Windows, get_code/1
returns \n, but it returns the same for a single \n.
Often, we could keep track of bufp and reset this, but we must deal with
the case where we fetch a new buffer. In this case, we must copy the few
remaining bytes to the `unbuffer' area.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int
Sungetcode(int c, IOSTREAM *s)
{ switch(s->encoding)
{ case ENC_OCTET:
case ENC_ISO_LATIN_1:
if ( c >= 256 )
return -1; /* illegal */
simple:
if ( s->bufp > s->unbuffer )
{ unget_byte(c, s);
return c;
}
return -1; /* no room */
case ENC_ASCII:
if ( c >= 128 )
return -1; /* illegal */
goto simple;
case ENC_ANSI: /* (*) See above */
{ char b[MB_LEN_MAX];
size_t n;
if ( !s->mbstate ) /* do we need a seperate state? */
{ if ( !(s->mbstate = malloc(sizeof(*s->mbstate))) )
return EOF; /* out of memory */
memset(s->mbstate, 0, sizeof(*s->mbstate));
}
if ( (n = wcrtomb(b, (wchar_t)c, s->mbstate)) != (size_t)-1 &&
s->bufp >= n + s->unbuffer )
{ size_t i;
for(i=n; i-- > 0; )
{ unget_byte(b[i], s);
}
return c;
}
Speekcode(IOSTREAM *s)
{ int c;
char *start;
IOPOS *psave = s->position;
size_t safe = (size_t)-1;
if ( !s->buffer )
{ if ( (s->flags & SIO_NBUF) )
{ errno = EINVAL;
return -1;
}
case ENC_UTF8:
{ if ( (unsigned)c >= 0x8000000 )
return -1;
if ( c < 0x80 )
{ goto simple;
} else
{ char buf[6];
char *p, *end;
end = utf8_put_char(buf, c);
if ( s->bufp - s->unbuffer >= end-buf )
{ for(p=end-1; p>=buf; p--)
{ unget_byte(*p, s);
}
return c;
}
return -1;
}
}
case ENC_UNICODE_BE:
{ if ( c >= 0x10000 )
return -1;
if ( s->bufp-1 > s->unbuffer )
{ unget_byte(c&0xff, s);
unget_byte((c>>8)&0xff, s);
return c;
}
return -1;
}
case ENC_UNICODE_LE:
{ if ( c >= 0x10000 )
return -1;
if ( s->bufp-1 > s->unbuffer )
{ unget_byte((c>>8)&0xff, s);
unget_byte(c&0xff, s);
return c;
}
return -1;
}
case ENC_WCHAR:
{ pl_wchar_t chr = c;
if ( s->bufp-sizeof(chr) >= s->unbuffer )
{ char *p = (char*)&chr;
int n;
for(n=sizeof(chr); --n>=0; )
unget_byte(p[n], s);
return c;
}
return -1;
}
case ENC_UNKNOWN:
if ( S__setbuf(s, NULL, 0) == (size_t)-1 )
return -1;
}
assert(0);
return -1;
if ( (s->flags & SIO_FEOF) )
return -1;
if ( s->bufp + UNDO_SIZE > s->limitp )
{ safe = s->limitp - s->bufp;
memcpy(s->buffer-safe, s->bufp, safe);
}
start = s->bufp;
s->position = NULL;
c = Sgetcode(s);
s->position = psave;
if ( Sferror(s) )
return -1;
s->flags &= ~(SIO_FEOF|SIO_FEOF2);
if ( s->bufp > start )
{ s->bufp = start;
} else
{ assert(safe != (size_t)-1);
s->bufp = s->buffer-safe;
}
return c;
}
/*******************************
* PUTW/GETW *
*******************************/
@@ -1393,6 +1339,10 @@ Sfeof(IOSTREAM *s)
return -1;
}
if ( s->downstream != NULL &&
Sfeof(s->downstream))
return TRUE;
if ( S__fillbuf(s) == -1 )
return TRUE;
@@ -1709,6 +1659,22 @@ Stell(IOSTREAM *s)
* CLOSE *
*******************************/
void
unallocStream(IOSTREAM *s)
{
#ifdef O_PLMT
if ( s->mutex )
{ recursiveMutexDelete(s->mutex);
free(s->mutex);
s->mutex = NULL;
}
#endif
if ( !(s->flags & SIO_STATIC) )
free(s);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(*) Sclose() can be called recursively. For example if an XPCE object is
only referenced from an open stream, the close-function will delete the
@@ -1766,19 +1732,13 @@ Sclose(IOSTREAM *s)
run_close_hooks(s); /* deletes Prolog registration */
SUNLOCK(s);
#ifdef O_PLMT
if ( s->mutex )
{ recursiveMutexDelete(s->mutex);
free(s->mutex);
s->mutex = NULL;
}
#endif
s->magic = SIO_CMAGIC;
if ( s->message )
free(s->message);
if ( !(s->flags & SIO_STATIC) )
free(s);
if ( s->references == 0 )
unallocStream(s);
else
s->erased = TRUE;
return rval;
}
@@ -1896,11 +1856,34 @@ Svprintf(const char *fm, va_list args)
#define A_LEFT 0 /* left-aligned field */
#define A_RIGHT 1 /* right-aligned field */
#define SNPRINTF3(fm, a1) \
{ size_t __r; \
assert(fs == fbuf); \
__r = snprintf(fs, sizeof(fbuf), fm, a1); \
if ( __r >= sizeof(fbuf) ) \
{ if ( (fs_malloced = fs = malloc(__r+1)) == NULL ) goto error; \
__r = snprintf(fs, __r+1, fm, a1); \
} \
fe = fs+__r; \
}
#define SNPRINTF4(fm, a1, a2) \
{ size_t __r; \
assert(fs == fbuf); \
__r = snprintf(fs, sizeof(fbuf), fm, a1, a2); \
if ( __r >= sizeof(fbuf) ) \
{ if ( (fs_malloced = fs = malloc(__r+1)) == NULL ) goto error; \
__r = snprintf(fs, __r+1, fm, a1, a2); \
} \
fe = fs+__r; \
}
int
Svfprintf(IOSTREAM *s, const char *fm, va_list args)
{ intptr_t printed = 0;
{ int printed = 0;
char buf[TMPBUFSIZE];
int tmpbuf;
char *fs_malloced = NULL;
SLOCK(s);
@@ -1988,8 +1971,7 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
*fp++ = '#';
*fp++ = 'p';
*fp = '\0';
sprintf(fs, fmbuf, ptr);
fe = &fs[strlen(fs)];
SNPRINTF3(fmbuf, ptr);
break;
}
@@ -2022,7 +2004,7 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
if ( islong < 2 )
{ *fp++ = *fm;
*fp = '\0';
sprintf(fs, fmbuf, v);
SNPRINTF3(fmbuf, v);
} else
{
#ifdef __WINDOWS__
@@ -2033,9 +2015,8 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
#endif
*fp++ = *fm;
*fp = '\0';
sprintf(fs, fmbuf, vl);
SNPRINTF3(fmbuf, vl);
}
fe = &fs[strlen(fs)];
break;
}
@@ -2050,16 +2031,16 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
*fp++ = '%';
if ( modified )
*fp++ = '#';
if ( has_arg2 ) /* specified percission */
if ( has_arg2 ) /* specified precission */
{ *fp++ = '.';
*fp++ = '*';
*fp++ = *fm;
*fp = '\0';
sprintf(fs, fmbuf, arg2, v);
SNPRINTF4(fmbuf, arg2, v);
} else
{ *fp++ = *fm;
*fp = '\0';
sprintf(fs, fmbuf, v);
SNPRINTF3(fmbuf, v);
}
fe = &fs[strlen(fs)];
@@ -2125,6 +2106,10 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
}
}
fm++;
if ( fs_malloced )
{ fs_malloced = NULL;
free(fs_malloced);
}
}
} else if ( *fm == '\\' && fm[1] )
{ OUTCHR(s, fm[1]);
@@ -2144,6 +2129,9 @@ Svfprintf(IOSTREAM *s, const char *fm, va_list args)
return (int)printed;
error:
if ( fs_malloced )
free(fs_malloced);
SUNLOCK(s);
return -1;
}
@@ -2184,7 +2172,7 @@ Svsprintf(char *buf, const char *fm, va_list args)
int
Svdprintf(const char *fm, va_list args)
{ int rval;
IOSTREAM *s = Soutput;
IOSTREAM *s = Serror;
Slock(s);
rval = Svfprintf(s, fm, args);
@@ -2677,7 +2665,6 @@ is of no value.
IOSTREAM *
Snew(void *handle, int flags, IOFUNCTIONS *functions)
{ IOSTREAM *s;
int fd;
if ( !(s = malloc(sizeof(IOSTREAM))) )
{ errno = ENOMEM;
@@ -2708,6 +2695,7 @@ Snew(void *handle, int flags, IOFUNCTIONS *functions)
#endif
#ifndef __WINDOWS__ /* (*) */
{ int fd;
if ( (fd = Sfileno(s)) >= 0 )
{ if ( isatty(fd) )
s->flags |= SIO_ISATTY;
@@ -2715,6 +2703,7 @@ Snew(void *handle, int flags, IOFUNCTIONS *functions)
fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
}
}
#endif
return s;
@@ -2746,6 +2735,7 @@ Sopen_file(const char *path, const char *how)
enum {lnone=0,lread,lwrite} lock = lnone;
IOSTREAM *s;
IOENC enc = ENC_UNKNOWN;
int wait = TRUE;
for( ; *how; how++)
{ switch(*how)
@@ -2756,6 +2746,9 @@ Sopen_file(const char *path, const char *how)
case 'r': /* no record */
flags &= ~SIO_RECORDPOS;
break;
case 'L': /* lock r: read, w: write */
wait = FALSE;
/*FALLTHROUGH*/
case 'l': /* lock r: read, w: write */
if ( *++how == 'r' )
lock = lread;
@@ -2811,7 +2804,7 @@ Sopen_file(const char *path, const char *how)
memset(&buf, 0, sizeof(buf));
buf.l_type = (lock == lread ? F_RDLCK : F_WRLCK);
if ( fcntl(fd, F_SETLKW, &buf) < 0 )
if ( fcntl(fd, wait ? F_SETLKW : F_SETLK, &buf) < 0 )
{ int save = errno;
close(fd);
errno = save;
@@ -2821,14 +2814,20 @@ Sopen_file(const char *path, const char *how)
#if __WINDOWS__
HANDLE h = (HANDLE)_get_osfhandle(fd);
OVERLAPPED ov;
int flags = 0;
if ( lock == lwrite )
flags |= LOCKFILE_EXCLUSIVE_LOCK;
if ( !wait )
flags |= LOCKFILE_FAIL_IMMEDIATELY;
memset(&ov, 0, sizeof(ov));
if ( !LockFileEx(h, (lock == lread ? 0 : LOCKFILE_EXCLUSIVE_LOCK),
if ( !LockFileEx(h, flags,
0,
0, 0xfffffff,
&ov) )
{ close(fd);
errno = EACCES; /* TBD: proper error */
errno = (wait ? EACCES : EAGAIN); /* TBD: proper error */
return NULL;
}
#else
@@ -2912,7 +2911,7 @@ Sfileno(IOSTREAM *s)
#ifdef HAVE_POPEN
#ifdef __WINDOWS__
#include "popen.c"
#include "windows/popen.c"
#define popen(cmd, how) pt_popen(cmd, how)
#define pclose(fd) pt_pclose(fd)
@@ -3458,4 +3457,3 @@ Scleanup(void)
*s = S__iob0[i]; /* re-initialise */
}
}