signed wchar
This commit is contained in:
parent
4d3d9c408d
commit
71f0076ed6
25
os/format.c
25
os/format.c
@ -233,10 +233,10 @@ output is directed to the stream used by format/2.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Yap.h"
|
#include "Yap.h"
|
||||||
#include "Yatom.h"
|
|
||||||
#include "YapHeap.h"
|
#include "YapHeap.h"
|
||||||
#include "yapio.h"
|
|
||||||
#include "YapText.h"
|
#include "YapText.h"
|
||||||
|
#include "Yatom.h"
|
||||||
|
#include "yapio.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#if HAVE_UNISTD_H
|
#if HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -257,8 +257,8 @@ output is directed to the stream used by format/2.
|
|||||||
#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
|
#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#include "iopreds.h"
|
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
|
#include "iopreds.h"
|
||||||
|
|
||||||
#define FORMAT_MAX_SIZE 1024
|
#define FORMAT_MAX_SIZE 1024
|
||||||
|
|
||||||
@ -618,7 +618,8 @@ static Int doformat(volatile Term otail, volatile Term oargs,
|
|||||||
goto do_type_atom_error;
|
goto do_type_atom_error;
|
||||||
yhandle_t sl = Yap_StartSlots();
|
yhandle_t sl = Yap_StartSlots();
|
||||||
// stream is already locked.
|
// stream is already locked.
|
||||||
Yap_plwrite(t, GLOBAL_Stream + sno, 0, Handle_vars_f | To_heap_f, GLOBAL_MaxPriority);
|
Yap_plwrite(t, GLOBAL_Stream + sno, 0, Handle_vars_f | To_heap_f,
|
||||||
|
GLOBAL_MaxPriority);
|
||||||
Yap_CloseSlots(sl);
|
Yap_CloseSlots(sl);
|
||||||
break;
|
break;
|
||||||
case 'c': {
|
case 'c': {
|
||||||
@ -810,8 +811,8 @@ static Int doformat(volatile Term otail, volatile Term oargs,
|
|||||||
char *pt, *res;
|
char *pt, *res;
|
||||||
|
|
||||||
tmpbase = tmp1;
|
tmpbase = tmp1;
|
||||||
while (!(res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE,
|
while (!(
|
||||||
radix))) {
|
res = Yap_gmp_to_string(t, tmpbase, TMP_STRING_SIZE, radix))) {
|
||||||
if (tmpbase == tmp1) {
|
if (tmpbase == tmp1) {
|
||||||
tmpbase = NULL;
|
tmpbase = NULL;
|
||||||
} else {
|
} else {
|
||||||
@ -871,7 +872,8 @@ static Int doformat(volatile Term otail, volatile Term oargs,
|
|||||||
t = targs[targ++];
|
t = targs[targ++];
|
||||||
yhandle_t sl = Yap_StartSlots();
|
yhandle_t sl = Yap_StartSlots();
|
||||||
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
|
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
|
||||||
Quote_illegal_f | Ignore_ops_f | To_heap_f, GLOBAL_MaxPriority);
|
Quote_illegal_f | Ignore_ops_f | To_heap_f,
|
||||||
|
GLOBAL_MaxPriority);
|
||||||
Yap_CloseSlots(sl);
|
Yap_CloseSlots(sl);
|
||||||
break;
|
break;
|
||||||
case '@':
|
case '@':
|
||||||
@ -910,7 +912,8 @@ static Int doformat(volatile Term otail, volatile Term oargs,
|
|||||||
{
|
{
|
||||||
Int sl = Yap_InitSlot(args);
|
Int sl = Yap_InitSlot(args);
|
||||||
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
|
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
|
||||||
Handle_vars_f | Use_portray_f | To_heap_f, GLOBAL_MaxPriority);
|
Handle_vars_f | Use_portray_f | To_heap_f,
|
||||||
|
GLOBAL_MaxPriority);
|
||||||
args = Yap_GetFromSlot(sl);
|
args = Yap_GetFromSlot(sl);
|
||||||
Yap_CloseSlots(sl);
|
Yap_CloseSlots(sl);
|
||||||
}
|
}
|
||||||
@ -936,7 +939,8 @@ static Int doformat(volatile Term otail, volatile Term oargs,
|
|||||||
t = targs[targ++];
|
t = targs[targ++];
|
||||||
yhandle_t sl0 = Yap_StartSlots();
|
yhandle_t sl0 = Yap_StartSlots();
|
||||||
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
|
Yap_plwrite(t, GLOBAL_Stream + sno, 0,
|
||||||
Handle_vars_f | Quote_illegal_f | To_heap_f, GLOBAL_MaxPriority);
|
Handle_vars_f | Quote_illegal_f | To_heap_f,
|
||||||
|
GLOBAL_MaxPriority);
|
||||||
Yap_CloseSlots(sl0);
|
Yap_CloseSlots(sl0);
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
@ -1022,8 +1026,7 @@ static Int doformat(volatile Term otail, volatile Term oargs,
|
|||||||
else
|
else
|
||||||
finfo.pad_entries[finfo.padders].filler = fptr[-2];
|
finfo.pad_entries[finfo.padders].filler = fptr[-2];
|
||||||
finfo.padders++;
|
finfo.padders++;
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
do_instantiation_error:
|
do_instantiation_error:
|
||||||
LOCAL_Error_TYPE = INSTANTIATION_ERROR;
|
LOCAL_Error_TYPE = INSTANTIATION_ERROR;
|
||||||
goto do_default_error;
|
goto do_default_error;
|
||||||
|
51
os/getw.h
51
os/getw.h
@ -24,12 +24,12 @@ static int GETW(int sno) {
|
|||||||
case ENC_ISO_ANSI: {
|
case ENC_ISO_ANSI: {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
int out;
|
int out;
|
||||||
int wch;
|
wchar_t wch;
|
||||||
mbstate_t mbstate;
|
mbstate_t mbstate;
|
||||||
|
|
||||||
memset((void *)&(mbstate), 0, sizeof(mbstate_t));
|
memset((void *)&(mbstate), 0, sizeof(mbstate_t));
|
||||||
buf[0] = ch;
|
buf[0] = ch;
|
||||||
int n=1;
|
int n = 1;
|
||||||
while ((out = mbrtowc(&wch, buf, 1, &(mbstate))) != 1) {
|
while ((out = mbrtowc(&wch, buf, 1, &(mbstate))) != 1) {
|
||||||
int ch = buf[0] = GETC();
|
int ch = buf[0] = GETC();
|
||||||
n++;
|
n++;
|
||||||
@ -38,8 +38,8 @@ static int GETW(int sno) {
|
|||||||
}
|
}
|
||||||
return post_process_read_wchar(wch, n, st);
|
return post_process_read_wchar(wch, n, st);
|
||||||
}
|
}
|
||||||
// UTF-8 works o 8 bits.
|
// UTF-8 works o 8 bits.
|
||||||
case ENC_ISO_UTF8: {
|
case ENC_ISO_UTF8: {
|
||||||
int wch;
|
int wch;
|
||||||
unsigned char buf[8];
|
unsigned char buf[8];
|
||||||
|
|
||||||
@ -53,14 +53,14 @@ case ENC_ISO_UTF8: {
|
|||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
// if (!utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8;
|
// if (!utf_cont(*str)) return UTF8PROC_ERROR_INVALIDUTF8;
|
||||||
wch = ((ch & 0x1f)<<6) | (c1 & 0x3f);
|
wch = ((ch & 0x1f) << 6) | (c1 & 0x3f);
|
||||||
return post_process_read_wchar(wch, 2, st);
|
return post_process_read_wchar(wch, 2, st);
|
||||||
}
|
}
|
||||||
if (ch < 0xf0) { // 3-byte sequence
|
if (ch < 0xf0) { // 3-byte sequence
|
||||||
//if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1]))
|
// if ((str + 1 >= end) || !utf_cont(*str) || !utf_cont(str[1]))
|
||||||
// return UTF8PROC_ERROR_INVALIDUTF8;
|
// return UTF8PROC_ERROR_INVALIDUTF8;
|
||||||
// Check for surrogate chars
|
// Check for surrogate chars
|
||||||
//if (ch == 0xed && *str > 0x9f)
|
// if (ch == 0xed && *str > 0x9f)
|
||||||
// return UTF8PROC_ERROR_INVALIDUTF8;
|
// return UTF8PROC_ERROR_INVALIDUTF8;
|
||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
@ -68,7 +68,7 @@ case ENC_ISO_UTF8: {
|
|||||||
int c2 = GETC();
|
int c2 = GETC();
|
||||||
if (c2 == -1)
|
if (c2 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = ((ch & 0xf)<<12) | ((c1 & 0x3f)<<6) | (c2 & 0x3f);
|
wch = ((ch & 0xf) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f);
|
||||||
return post_process_read_wchar(wch, 3, st);
|
return post_process_read_wchar(wch, 3, st);
|
||||||
} else {
|
} else {
|
||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
@ -80,11 +80,12 @@ case ENC_ISO_UTF8: {
|
|||||||
int c3 = GETC();
|
int c3 = GETC();
|
||||||
if (c3 == -1)
|
if (c3 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = ((ch & 7)<<18) | ((c1 & 0x3f)<<12) | ((c2 & 0x3f)<<6) | (c3 & 0x3f);
|
wch = ((ch & 7) << 18) | ((c1 & 0x3f) << 12) | ((c2 & 0x3f) << 6) |
|
||||||
|
(c3 & 0x3f);
|
||||||
return post_process_read_wchar(wch, 4, st);
|
return post_process_read_wchar(wch, 4, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case ENC_UTF16_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
case ENC_UTF16_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
||||||
// little-endian: start with big shot
|
// little-endian: start with big shot
|
||||||
{
|
{
|
||||||
int wch;
|
int wch;
|
||||||
@ -99,21 +100,20 @@ case ENC_UTF16_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|||||||
int c3 = GETC();
|
int c3 = GETC();
|
||||||
if (c3 == -1)
|
if (c3 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = wch + (((c3 << 8) + c2)<<wch) + SURROGATE_OFFSET;
|
wch = wch + (((c3 << 8) + c2) << wch) + SURROGATE_OFFSET;
|
||||||
return post_process_read_wchar(wch, 4, st);
|
return post_process_read_wchar(wch, 4, st);
|
||||||
}
|
}
|
||||||
return post_process_read_wchar(wch, 2, st);
|
return post_process_read_wchar(wch, 2, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ENC_UTF16_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
||||||
case ENC_UTF16_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|
||||||
// little-endian: start with big shot
|
// little-endian: start with big shot
|
||||||
{
|
{
|
||||||
int wch;
|
int wch;
|
||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = (c1) + (ch<<8);
|
wch = (c1) + (ch << 8);
|
||||||
if (wch >= 0xd800 && wch < 0xdc00) {
|
if (wch >= 0xd800 && wch < 0xdc00) {
|
||||||
int c3 = GETC();
|
int c3 = GETC();
|
||||||
if (c3 == -1)
|
if (c3 == -1)
|
||||||
@ -134,12 +134,11 @@ case ENC_UTF16_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = (c1) + (ch<<8);
|
wch = (c1) + (ch << 8);
|
||||||
return post_process_read_wchar(wch, 2, st);
|
return post_process_read_wchar(wch, 2, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ENC_UCS2_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
||||||
case ENC_UCS2_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|
||||||
// little-endian: start with big shot
|
// little-endian: start with big shot
|
||||||
{
|
{
|
||||||
int wch;
|
int wch;
|
||||||
@ -151,7 +150,7 @@ case ENC_UCS2_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|||||||
return post_process_read_wchar(wch, 2, st);
|
return post_process_read_wchar(wch, 2, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
case ENC_ISO_UTF32_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
case ENC_ISO_UTF32_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
||||||
// little-endian: start with big shot
|
// little-endian: start with big shot
|
||||||
{
|
{
|
||||||
int wch = ch;
|
int wch = ch;
|
||||||
@ -165,17 +164,17 @@ case ENC_ISO_UTF32_BE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = (wch << 8 )+c1;
|
wch = (wch << 8) + c1;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch = (wch << 8) +c1;
|
wch = (wch << 8) + c1;
|
||||||
}
|
}
|
||||||
return post_process_read_wchar(wch, 4, st);
|
return post_process_read_wchar(wch, 4, st);
|
||||||
}
|
}
|
||||||
case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
||||||
// little-endian: start with big shot
|
// little-endian: start with big shot
|
||||||
{
|
{
|
||||||
int wch = ch;
|
int wch = ch;
|
||||||
@ -183,21 +182,25 @@ case ENC_ISO_UTF32_LE: // check http://unicode.org/faq/utf_bom.html#utf16-3
|
|||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch += c1<<8;
|
wch += c1 << 8;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch += c1<<16;
|
wch += c1 << 16;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
int c1 = GETC();
|
int c1 = GETC();
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return post_process_weof(st);
|
return post_process_weof(st);
|
||||||
wch += c1<<24;
|
wch += c1 << 24;
|
||||||
}
|
}
|
||||||
return post_process_read_wchar(wch, 4, st);
|
return post_process_read_wchar(wch, 4, st);
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, MkIntTerm(st->encoding),
|
||||||
|
"Bad Encoding\n");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
352
os/iopreds.c
352
os/iopreds.c
@ -33,12 +33,15 @@ static char SccsId[] = "%W% %G%";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Yap.h"
|
#include "Yap.h"
|
||||||
#include "Yatom.h"
|
|
||||||
#include "YapHeap.h"
|
#include "YapHeap.h"
|
||||||
#include "yapio.h"
|
|
||||||
#include "eval.h"
|
|
||||||
#include "YapText.h"
|
#include "YapText.h"
|
||||||
|
#include "Yatom.h"
|
||||||
|
#include "eval.h"
|
||||||
|
#include "yapio.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#if HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
#if HAVE_STDARG_H
|
#if HAVE_STDARG_H
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#endif
|
#endif
|
||||||
@ -96,7 +99,6 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#endif
|
#endif
|
||||||
#include "iopreds.h"
|
#include "iopreds.h"
|
||||||
|
|
||||||
|
|
||||||
#define GETW get_wchar_from_FILE
|
#define GETW get_wchar_from_FILE
|
||||||
#define GETC() fgetwc(st->file)
|
#define GETC() fgetwc(st->file)
|
||||||
#include "getw.h"
|
#include "getw.h"
|
||||||
@ -248,7 +250,7 @@ static void unix_upd_stream_info(StreamDesc *s) {
|
|||||||
filedes = fileno(s->file);
|
filedes = fileno(s->file);
|
||||||
if (isatty(filedes)) {
|
if (isatty(filedes)) {
|
||||||
#if HAVE_TTYNAME
|
#if HAVE_TTYNAME
|
||||||
char *ttys = ttyname(filedes);
|
char *ttys = ttyname_r(filedes, LOCAL_FileNameBuf, YAP_FILENAME_MAX - 1);
|
||||||
if (ttys == NULL)
|
if (ttys == NULL)
|
||||||
s->name = AtomTty;
|
s->name = AtomTty;
|
||||||
else
|
else
|
||||||
@ -266,7 +268,6 @@ static void unix_upd_stream_info(StreamDesc *s) {
|
|||||||
s->status |= Seekable_Stream_f;
|
s->status |= Seekable_Stream_f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void InitFileIO(StreamDesc *s) {
|
static void InitFileIO(StreamDesc *s) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
if (s->status & Socket_Stream_f) {
|
if (s->status & Socket_Stream_f) {
|
||||||
@ -660,7 +661,6 @@ int post_process_read_wchar(int ch, size_t n, StreamDesc *s) {
|
|||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int post_process_weof(StreamDesc *s) {
|
int post_process_weof(StreamDesc *s) {
|
||||||
if (!ResetEOF(s)) {
|
if (!ResetEOF(s)) {
|
||||||
s->status |= Eof_Stream_f;
|
s->status |= Eof_Stream_f;
|
||||||
@ -692,19 +692,18 @@ int PlGetc(int sno) {
|
|||||||
return fgetc(s->file);
|
return fgetc(s->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// layered version
|
||||||
|
static int get_wchar__(int sno) { return fgetwc(GLOBAL_Stream[sno].file); }
|
||||||
|
|
||||||
// layered version
|
static int get_wchar_from_file(int sno) {
|
||||||
static int get_wchar__(int sno) { return fgetwc(GLOBAL_Stream[sno].file); }
|
|
||||||
|
|
||||||
static int get_wchar_from_file(int sno) {
|
|
||||||
return post_process_read_wchar(get_wchar__(sno), 1, GLOBAL_Stream + sno);
|
return post_process_read_wchar(get_wchar__(sno), 1, GLOBAL_Stream + sno);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MB_LEN_MAX
|
#ifndef MB_LEN_MAX
|
||||||
#define MB_LEN_MAX 6
|
#define MB_LEN_MAX 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int handle_write_encoding_error(int sno, wchar_t ch) {
|
static int handle_write_encoding_error(int sno, wchar_t ch) {
|
||||||
if (GLOBAL_Stream[sno].status & RepError_Xml_f) {
|
if (GLOBAL_Stream[sno].status & RepError_Xml_f) {
|
||||||
/* use HTML/XML encoding in ASCII */
|
/* use HTML/XML encoding in ASCII */
|
||||||
int i = ch, digits = 1;
|
int i = ch, digits = 1;
|
||||||
@ -737,9 +736,9 @@ int PlGetc(int sno) {
|
|||||||
(unsigned long int)ch, sno);
|
(unsigned long int)ch, sno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int put_wchar(int sno, wchar_t ch) {
|
int put_wchar(int sno, wchar_t ch) {
|
||||||
/* pass the bucck if we can */
|
/* pass the bucck if we can */
|
||||||
switch (GLOBAL_Stream[sno].encoding) {
|
switch (GLOBAL_Stream[sno].encoding) {
|
||||||
case ENC_OCTET:
|
case ENC_OCTET:
|
||||||
@ -793,8 +792,7 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
break;
|
break;
|
||||||
case ENC_UTF16_LE:
|
case ENC_UTF16_LE: {
|
||||||
{
|
|
||||||
if (ch < 0x10000) {
|
if (ch < 0x10000) {
|
||||||
GLOBAL_Stream[sno].stream_putc(sno, (ch & 0xff));
|
GLOBAL_Stream[sno].stream_putc(sno, (ch & 0xff));
|
||||||
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
||||||
@ -811,8 +809,7 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
case ENC_UTF16_BE:
|
case ENC_UTF16_BE: {
|
||||||
{
|
|
||||||
// computations
|
// computations
|
||||||
if (ch < 0x10000) {
|
if (ch < 0x10000) {
|
||||||
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
||||||
@ -825,12 +822,10 @@ int PlGetc(int sno) {
|
|||||||
GLOBAL_Stream[sno].stream_putc(sno, (lead & 0xff));
|
GLOBAL_Stream[sno].stream_putc(sno, (lead & 0xff));
|
||||||
GLOBAL_Stream[sno].stream_putc(sno, (trail >> 8));
|
GLOBAL_Stream[sno].stream_putc(sno, (trail >> 8));
|
||||||
GLOBAL_Stream[sno].stream_putc(sno, (trail & 0xff));
|
GLOBAL_Stream[sno].stream_putc(sno, (trail & 0xff));
|
||||||
|
|
||||||
}
|
}
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
case ENC_UCS2_LE:
|
case ENC_UCS2_LE: {
|
||||||
{
|
|
||||||
if (ch >= 0x10000) {
|
if (ch >= 0x10000) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -838,8 +833,7 @@ int PlGetc(int sno) {
|
|||||||
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
case ENC_UCS2_BE:
|
case ENC_UCS2_BE: {
|
||||||
{
|
|
||||||
// computations
|
// computations
|
||||||
if (ch < 0x10000) {
|
if (ch < 0x10000) {
|
||||||
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
GLOBAL_Stream[sno].stream_putc(sno, (ch >> 8));
|
||||||
@ -865,34 +859,34 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used by user-code to read characters from the current input stream */
|
/* used by user-code to read characters from the current input stream */
|
||||||
int Yap_PlGetchar(void) {
|
int Yap_PlGetchar(void) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
return (GLOBAL_Stream[LOCAL_c_input_stream].stream_getc(
|
return (
|
||||||
LOCAL_c_input_stream));
|
GLOBAL_Stream[LOCAL_c_input_stream].stream_getc(LOCAL_c_input_stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Yap_PlGetWchar(void) {
|
int Yap_PlGetWchar(void) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
return get_wchar(LOCAL_c_input_stream);
|
return get_wchar(LOCAL_c_input_stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* avoid using a variable to call a function */
|
/* avoid using a variable to call a function */
|
||||||
int Yap_PlFGetchar(void) {
|
int Yap_PlFGetchar(void) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
return (PlGetc(LOCAL_c_input_stream));
|
return (PlGetc(LOCAL_c_input_stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
Term Yap_MkStream(int n) {
|
Term Yap_MkStream(int n) {
|
||||||
Term t[1];
|
Term t[1];
|
||||||
t[0] = MkIntTerm(n);
|
t[0] = MkIntTerm(n);
|
||||||
return (Yap_MkApplTerm(FunctorStream, 1, t));
|
return (Yap_MkApplTerm(FunctorStream, 1, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* given a stream index, get the corresponding fd */
|
/* given a stream index, get the corresponding fd */
|
||||||
Int GetStreamFd(int sno) {
|
Int GetStreamFd(int sno) {
|
||||||
#if HAVE_SOCKET
|
#if HAVE_SOCKET
|
||||||
if (GLOBAL_Stream[sno].status & Socket_Stream_f) {
|
if (GLOBAL_Stream[sno].status & Socket_Stream_f) {
|
||||||
return (GLOBAL_Stream[sno].u.socket.fd);
|
return (GLOBAL_Stream[sno].u.socket.fd);
|
||||||
@ -904,11 +898,11 @@ int PlGetc(int sno) {
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
return (fileno(GLOBAL_Stream[sno].file));
|
return (fileno(GLOBAL_Stream[sno].file));
|
||||||
}
|
}
|
||||||
|
|
||||||
Int Yap_GetStreamFd(int sno) { return GetStreamFd(sno); }
|
Int Yap_GetStreamFd(int sno) { return GetStreamFd(sno); }
|
||||||
|
|
||||||
static int binary_file(const char *file_name) {
|
static int binary_file(const char *file_name) {
|
||||||
#if HAVE_STAT
|
#if HAVE_STAT
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
struct _stat ss;
|
struct _stat ss;
|
||||||
@ -925,9 +919,9 @@ int PlGetc(int sno) {
|
|||||||
#else
|
#else
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_bom(int sno, StreamDesc *st) {
|
static int write_bom(int sno, StreamDesc *st) {
|
||||||
/* dump encoding */
|
/* dump encoding */
|
||||||
switch (st->encoding) {
|
switch (st->encoding) {
|
||||||
case ENC_ISO_UTF8:
|
case ENC_ISO_UTF8:
|
||||||
@ -980,9 +974,9 @@ int PlGetc(int sno) {
|
|||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_bom(int sno, StreamDesc *st) {
|
static void check_bom(int sno, StreamDesc *st) {
|
||||||
int ch1, ch2, ch3, ch4;
|
int ch1, ch2, ch3, ch4;
|
||||||
|
|
||||||
ch1 = fgetc(st->file);
|
ch1 = fgetc(st->file);
|
||||||
@ -1076,11 +1070,10 @@ int PlGetc(int sno) {
|
|||||||
default:
|
default:
|
||||||
ungetc(ch1, st->file);
|
ungetc(ch1, st->file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Yap_initStream(int sno, FILE *fd, const char *name, Term file_name,
|
bool Yap_initStream(int sno, FILE *fd, const char *name, Term file_name,
|
||||||
encoding_t encoding, stream_flags_t flags,
|
encoding_t encoding, stream_flags_t flags, Atom open_mode) {
|
||||||
Atom open_mode) {
|
|
||||||
StreamDesc *st = &GLOBAL_Stream[sno];
|
StreamDesc *st = &GLOBAL_Stream[sno];
|
||||||
st->status = flags;
|
st->status = flags;
|
||||||
|
|
||||||
@ -1114,9 +1107,9 @@ int PlGetc(int sno) {
|
|||||||
Yap_DefaultStreamOps(st);
|
Yap_DefaultStreamOps(st);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool open_header(int sno, Atom open_mode) {
|
static bool open_header(int sno, Atom open_mode) {
|
||||||
if (open_mode == AtomWrite) {
|
if (open_mode == AtomWrite) {
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
const char s[] = "#!";
|
const char s[] = "#!";
|
||||||
@ -1143,11 +1136,11 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPEN_DEFS() \
|
#define OPEN_DEFS() \
|
||||||
PAR("alias", isatom, OPEN_ALIAS), PAR("bom", booleanFlag, OPEN_BOM), \
|
PAR("alias", isatom, OPEN_ALIAS) \
|
||||||
PAR("buffer", isatom, OPEN_BUFFER), \
|
, PAR("bom", booleanFlag, OPEN_BOM), PAR("buffer", isatom, OPEN_BUFFER), \
|
||||||
PAR("close_on_abort", booleanFlag, OPEN_CLOSE_ON_ABORT), \
|
PAR("close_on_abort", booleanFlag, OPEN_CLOSE_ON_ABORT), \
|
||||||
PAR("create", isatom, OPEN_CREATE), \
|
PAR("create", isatom, OPEN_CREATE), \
|
||||||
PAR("encoding", isatom, OPEN_ENCODING), \
|
PAR("encoding", isatom, OPEN_ENCODING), \
|
||||||
@ -1162,18 +1155,18 @@ int PlGetc(int sno) {
|
|||||||
PAR("wait", booleanFlag, OPEN_WAIT), PAR(NULL, ok, OPEN_END)
|
PAR("wait", booleanFlag, OPEN_WAIT), PAR(NULL, ok, OPEN_END)
|
||||||
|
|
||||||
#define PAR(x, y, z) z
|
#define PAR(x, y, z) z
|
||||||
typedef enum open_enum_choices { OPEN_DEFS() } open_choices_t;
|
typedef enum open_enum_choices { OPEN_DEFS() } open_choices_t;
|
||||||
|
|
||||||
#undef PAR
|
#undef PAR
|
||||||
|
|
||||||
#define PAR(x, y, z) \
|
#define PAR(x, y, z) \
|
||||||
{ x, y, z }
|
{ x, y, z }
|
||||||
|
|
||||||
static const param_t open_defs[] = {OPEN_DEFS()};
|
static const param_t open_defs[] = {OPEN_DEFS()};
|
||||||
#undef PAR
|
#undef PAR
|
||||||
|
|
||||||
static Int do_open(
|
static Int
|
||||||
Term file_name, Term t2,
|
do_open(Term file_name, Term t2,
|
||||||
Term tlist USES_REGS) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */
|
Term tlist USES_REGS) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */
|
||||||
Atom open_mode;
|
Atom open_mode;
|
||||||
int sno;
|
int sno;
|
||||||
@ -1263,7 +1256,7 @@ int PlGetc(int sno) {
|
|||||||
s_encoding = "default";
|
s_encoding = "default";
|
||||||
}
|
}
|
||||||
// default encoding, no bom yet
|
// default encoding, no bom yet
|
||||||
encoding = enc_id( s_encoding, ENC_OCTET);
|
encoding = enc_id(s_encoding, ENC_OCTET);
|
||||||
// only set encoding after getting BOM
|
// only set encoding after getting BOM
|
||||||
bool ok = (args[OPEN_EXPAND_FILENAME].used
|
bool ok = (args[OPEN_EXPAND_FILENAME].used
|
||||||
? args[OPEN_EXPAND_FILENAME].tvalue == TermTrue
|
? args[OPEN_EXPAND_FILENAME].tvalue == TermTrue
|
||||||
@ -1279,8 +1272,7 @@ int PlGetc(int sno) {
|
|||||||
|
|
||||||
// Skip scripts that start with !#/.. or similar
|
// Skip scripts that start with !#/.. or similar
|
||||||
bool script =
|
bool script =
|
||||||
(args[OPEN_SCRIPT].used ? args[OPEN_SCRIPT].tvalue == TermTrue
|
(args[OPEN_SCRIPT].used ? args[OPEN_SCRIPT].tvalue == TermTrue : false);
|
||||||
: false);
|
|
||||||
// binary type
|
// binary type
|
||||||
if (args[OPEN_TYPE].used) {
|
if (args[OPEN_TYPE].used) {
|
||||||
Term t = args[OPEN_TYPE].tvalue;
|
Term t = args[OPEN_TYPE].tvalue;
|
||||||
@ -1328,11 +1320,11 @@ int PlGetc(int sno) {
|
|||||||
fname = LOCAL_FileNameBuf;
|
fname = LOCAL_FileNameBuf;
|
||||||
UNLOCK(st->streamlock);
|
UNLOCK(st->streamlock);
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name, "%s: %s",
|
return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name, "%s: %s", fname,
|
||||||
fname, strerror(errno)));
|
strerror(errno)));
|
||||||
else {
|
else {
|
||||||
return (PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, file_name,
|
return (PlIOError(PERMISSION_ERROR_OPEN_SOURCE_SINK, file_name, "%s: %s",
|
||||||
"%s: %s", fname, strerror(errno)));
|
fname, strerror(errno)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if MAC
|
#if MAC
|
||||||
@ -1341,11 +1333,9 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
flags &= ~(Free_Stream_f);
|
flags &= ~(Free_Stream_f);
|
||||||
if (!Yap_initStream(sno, fd, fname, file_name, encoding, flags,
|
if (!Yap_initStream(sno, fd, fname, file_name, encoding, flags, open_mode))
|
||||||
open_mode))
|
|
||||||
return false;
|
return false;
|
||||||
if (!Yap_initStream(sno, fd, fname, file_name, encoding, flags,
|
if (!Yap_initStream(sno, fd, fname, file_name, encoding, flags, open_mode))
|
||||||
open_mode))
|
|
||||||
return false;
|
return false;
|
||||||
if (open_mode == AtomWrite) {
|
if (open_mode == AtomWrite) {
|
||||||
if (needs_bom && !write_bom(sno, st))
|
if (needs_bom && !write_bom(sno, st))
|
||||||
@ -1355,10 +1345,10 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
// follow declaration unless there is v
|
// follow declaration unless there is v
|
||||||
if (st->status & HAS_BOM_f)
|
if (st->status & HAS_BOM_f)
|
||||||
st->encoding = enc_id( s_encoding, st->encoding);
|
st->encoding = enc_id(s_encoding, st->encoding);
|
||||||
else
|
else
|
||||||
st->encoding = encoding;
|
st->encoding = encoding;
|
||||||
Yap_DefaultStreamOps( st);
|
Yap_DefaultStreamOps(st);
|
||||||
if (script)
|
if (script)
|
||||||
open_header(sno, open_mode);
|
open_header(sno, open_mode);
|
||||||
|
|
||||||
@ -1367,102 +1357,101 @@ int PlGetc(int sno) {
|
|||||||
Term t = Yap_MkStream(sno);
|
Term t = Yap_MkStream(sno);
|
||||||
return (Yap_unify(ARG3, t));
|
return (Yap_unify(ARG3, t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @pred open(+ _F_,+ _M_,- _S_) is iso
|
/** @pred open(+ _F_,+ _M_,- _S_) is iso
|
||||||
|
|
||||||
|
|
||||||
Opens the file with name _F_ in mode _M_ (`read`, `write` or
|
Opens the file with name _F_ in mode _M_ (`read`, `write` or
|
||||||
`append`), returning _S_ unified with the stream name.
|
`append`), returning _S_ unified with the stream name.
|
||||||
|
|
||||||
Yap allows 64 streams opened at the same time. If you need more,
|
Yap allows 64 streams opened at the same time. If you need more,
|
||||||
redefine the MaxStreams constant. Each stream is either an input or
|
redefine the MaxStreams constant. Each stream is either an input or
|
||||||
an output stream but not both. There are always 3 open streams:
|
an output stream but not both. There are always 3 open streams:
|
||||||
user_input for reading, user_output for writing and user_error for
|
user_input for reading, user_output for writing and user_error for
|
||||||
writing. If there is no ambiguity, the atoms user_input and
|
writing. If there is no ambiguity, the atoms user_input and
|
||||||
user_output may be referred to as `user`.
|
user_output may be referred to as `user`.
|
||||||
|
|
||||||
The `file_errors` flag controls whether errors are reported when in
|
The `file_errors` flag controls whether errors are reported when in
|
||||||
mode `read` or `append` the file _F_ does not exist or is not
|
mode `read` or `append` the file _F_ does not exist or is not
|
||||||
readable, and whether in mode `write` or `append` the file is not
|
readable, and whether in mode `write` or `append` the file is not
|
||||||
writable.
|
writable.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Int open3(
|
static Int open3(USES_REGS1) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */
|
||||||
USES_REGS1) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */
|
|
||||||
return do_open(Deref(ARG1), Deref(ARG2), TermNil PASS_REGS);
|
return do_open(Deref(ARG1), Deref(ARG2), TermNil PASS_REGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @pred open(+ _F_,+ _M_,- _S_,+ _Opts_) is iso
|
/** @pred open(+ _F_,+ _M_,- _S_,+ _Opts_) is iso
|
||||||
|
|
||||||
Opens the file with name _F_ in mode _M_ (`read`, `write` or
|
Opens the file with name _F_ in mode _M_ (`read`, `write` or
|
||||||
`append`), returning _S_ unified with the stream name, and following
|
`append`), returning _S_ unified with the stream name, and following
|
||||||
these options:
|
these options:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
+ `type(+ _T_)` is iso
|
+ `type(+ _T_)` is iso
|
||||||
|
|
||||||
Specify whether the stream is a `text` stream (default), or a
|
Specify whether the stream is a `text` stream (default), or a
|
||||||
`binary` stream.
|
`binary` stream.
|
||||||
|
|
||||||
+ `reposition(+ _Bool_)` is iso
|
+ `reposition(+ _Bool_)` is iso
|
||||||
Specify whether it is possible to reposition the stream (`true`), or
|
Specify whether it is possible to reposition the stream (`true`), or
|
||||||
not (`false`). By default, YAP enables repositioning for all
|
not (`false`). By default, YAP enables repositioning for all
|
||||||
files, except terminal files and sockets.
|
files, except terminal files and sockets.
|
||||||
|
|
||||||
+ `eof(+ _Action_)` is iso
|
+ `eof(+ _Action_)` is iso
|
||||||
|
|
||||||
Specify the action to take if attempting to input characters from a
|
Specify the action to take if attempting to input characters from a
|
||||||
stream where we have previously found an `end_of_file`. The possible
|
stream where we have previously found an `end_of_file`. The possible
|
||||||
actions are `error`, that raises an error, `reset`, that tries to
|
actions are `error`, that raises an error, `reset`, that tries to
|
||||||
reset the stream and is used for `tty` type files, and `eof_code`,
|
reset the stream and is used for `tty` type files, and `eof_code`,
|
||||||
which generates a new `end_of_file` (default for non-tty files).
|
which generates a new `end_of_file` (default for non-tty files).
|
||||||
|
|
||||||
+ `alias(+ _Name_)` is iso
|
+ `alias(+ _Name_)` is iso
|
||||||
|
|
||||||
Specify an alias to the stream. The alias <tt>Name</tt> must be an atom.
|
Specify an alias to the stream. The alias <tt>Name</tt> must be an atom.
|
||||||
The
|
The
|
||||||
alias can be used instead of the stream descriptor for every operation
|
alias can be used instead of the stream descriptor for every operation
|
||||||
concerning the stream.
|
concerning the stream.
|
||||||
|
|
||||||
The operation will fail and give an error if the alias name is already
|
The operation will fail and give an error if the alias name is already
|
||||||
in use. YAP allows several aliases for the same file, but only
|
in use. YAP allows several aliases for the same file, but only
|
||||||
one is returned by stream_property/2
|
one is returned by stream_property/2
|
||||||
|
|
||||||
+ `bom(+ _Bool_)`
|
+ `bom(+ _Bool_)`
|
||||||
|
|
||||||
If present and `true`, a BOM (<em>Byte Order Mark</em>) was
|
If present and `true`, a BOM (<em>Byte Order Mark</em>) was
|
||||||
detected while opening the file for reading or a BOM was written while
|
detected while opening the file for reading or a BOM was written while
|
||||||
opening the stream. See BOM for details.
|
opening the stream. See BOM for details.
|
||||||
|
|
||||||
+ `encoding(+ _Encoding_)`
|
+ `encoding(+ _Encoding_)`
|
||||||
|
|
||||||
Set the encoding used for text. See Encoding for an overview of
|
Set the encoding used for text. See Encoding for an overview of
|
||||||
wide character and encoding issues.
|
wide character and encoding issues.
|
||||||
|
|
||||||
+ `representation_errors(+ _Mode_)`
|
+ `representation_errors(+ _Mode_)`
|
||||||
|
|
||||||
Change the behaviour when writing characters to the stream that cannot
|
Change the behaviour when writing characters to the stream that cannot
|
||||||
be represented by the encoding. The behaviour is one of `error`
|
be represented by the encoding. The behaviour is one of `error`
|
||||||
(throw and Input/Output error exception), `prolog` (write `\u...\`
|
(throw and Input/Output error exception), `prolog` (write `\u...\`
|
||||||
escape code or `xml` (write `\&#...;` XML character entity).
|
escape code or `xml` (write `\&#...;` XML character entity).
|
||||||
The initial mode is `prolog` for the user streams and
|
The initial mode is `prolog` for the user streams and
|
||||||
`error` for all other streams. See also Encoding.
|
`error` for all other streams. See also Encoding.
|
||||||
|
|
||||||
+ `expand_filename(+ _Mode_)`
|
+ `expand_filename(+ _Mode_)`
|
||||||
|
|
||||||
If _Mode_ is `true` then do filename expansion, then ask Prolog
|
If _Mode_ is `true` then do filename expansion, then ask Prolog
|
||||||
to do file name expansion before actually trying to opening the file:
|
to do file name expansion before actually trying to opening the file:
|
||||||
this includes processing `~` characters and processing `$`
|
this includes processing `~` characters and processing `$`
|
||||||
environment variables at the beginning of the file. Otherwise, just try
|
environment variables at the beginning of the file. Otherwise, just try
|
||||||
to open the file using the given name.
|
to open the file using the given name.
|
||||||
|
|
||||||
The default behavior is given by the Prolog flag
|
The default behavior is given by the Prolog flag
|
||||||
open_expands_filename.
|
open_expands_filename.
|
||||||
|
|
||||||
+ `script( + _Boolean_ )` YAP extension.
|
+ `script( + _Boolean_ )` YAP extension.
|
||||||
|
|
||||||
The file may be a Prolog script. In `read` mode just check for
|
The file may be a Prolog script. In `read` mode just check for
|
||||||
initial lines if they start with the hash symbol, and skip them. In
|
initial lines if they start with the hash symbol, and skip them. In
|
||||||
@ -1471,14 +1460,12 @@ int PlGetc(int sno) {
|
|||||||
permissions as executable. In `append` mode ignore the flag.
|
permissions as executable. In `append` mode ignore the flag.
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static Int open4(
|
static Int open4(USES_REGS1) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */
|
||||||
USES_REGS1) { /* '$open'(+File,+Mode,?Stream,-ReturnCode) */
|
|
||||||
return do_open(Deref(ARG1), Deref(ARG2), Deref(ARG4) PASS_REGS);
|
return do_open(Deref(ARG1), Deref(ARG2), Deref(ARG4) PASS_REGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int p_file_expansion(
|
static Int p_file_expansion(USES_REGS1) { /* '$file_expansion'(+File,-Name) */
|
||||||
USES_REGS1) { /* '$file_expansion'(+File,-Name) */
|
|
||||||
Term file_name = Deref(ARG1);
|
Term file_name = Deref(ARG1);
|
||||||
|
|
||||||
/* we know file_name is bound */
|
/* we know file_name is bound */
|
||||||
@ -1491,9 +1478,9 @@ int PlGetc(int sno) {
|
|||||||
return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name,
|
return (PlIOError(EXISTENCE_ERROR_SOURCE_SINK, file_name,
|
||||||
"absolute_file_name/3"));
|
"absolute_file_name/3"));
|
||||||
return (Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf))));
|
return (Yap_unify(ARG2, MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int p_open_null_stream(USES_REGS1) {
|
static Int p_open_null_stream(USES_REGS1) {
|
||||||
Term t;
|
Term t;
|
||||||
StreamDesc *st;
|
StreamDesc *st;
|
||||||
int sno = GetFreeStreamD();
|
int sno = GetFreeStreamD();
|
||||||
@ -1524,9 +1511,9 @@ int PlGetc(int sno) {
|
|||||||
UNLOCK(st->streamlock);
|
UNLOCK(st->streamlock);
|
||||||
t = Yap_MkStream(sno);
|
t = Yap_MkStream(sno);
|
||||||
return (Yap_unify(ARG1, t));
|
return (Yap_unify(ARG1, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Yap_OpenStream(FILE * fd, char *name, Term file_name, int flags) {
|
int Yap_OpenStream(FILE *fd, char *name, Term file_name, int flags) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
int sno;
|
int sno;
|
||||||
Atom at;
|
Atom at;
|
||||||
@ -1544,13 +1531,13 @@ int PlGetc(int sno) {
|
|||||||
at = AtomRead;
|
at = AtomRead;
|
||||||
Yap_initStream(sno, fd, name, file_name, LOCAL_encoding, flags, at);
|
Yap_initStream(sno, fd, name, file_name, LOCAL_encoding, flags, at);
|
||||||
return sno;
|
return sno;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CheckStream(arg, kind, msg) \
|
#define CheckStream(arg, kind, msg) \
|
||||||
CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg)
|
CheckStream__(__FILE__, __FUNCTION__, __LINE__, arg, kind, msg)
|
||||||
|
|
||||||
static int CheckStream__(const char *file, const char *f, int line,
|
static int CheckStream__(const char *file, const char *f, int line, Term arg,
|
||||||
Term arg, int kind, const char *msg) {
|
int kind, const char *msg) {
|
||||||
int sno = -1;
|
int sno = -1;
|
||||||
arg = Deref(arg);
|
arg = Deref(arg);
|
||||||
if (IsVarTerm(arg)) {
|
if (IsVarTerm(arg)) {
|
||||||
@ -1606,15 +1593,15 @@ int PlGetc(int sno) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return sno;
|
return sno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Yap_CheckStream__(const char *file, const char *f, int line, Term arg,
|
int Yap_CheckStream__(const char *file, const char *f, int line, Term arg,
|
||||||
int kind, const char *msg) {
|
int kind, const char *msg) {
|
||||||
return CheckStream__(file, f, line, arg, kind, msg);
|
return CheckStream__(file, f, line, arg, kind, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Yap_CheckTextStream__(const char *file, const char *f, int line,
|
int Yap_CheckTextStream__(const char *file, const char *f, int line, Term arg,
|
||||||
Term arg, int kind, const char *msg) {
|
int kind, const char *msg) {
|
||||||
int sno;
|
int sno;
|
||||||
if ((sno = CheckStream__(file, f, line, arg, kind, msg)) < 0)
|
if ((sno = CheckStream__(file, f, line, arg, kind, msg)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1629,10 +1616,10 @@ int PlGetc(int sno) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return sno;
|
return sno;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used from C-interface */
|
/* used from C-interface */
|
||||||
int Yap_GetFreeStreamDForReading(void) {
|
int Yap_GetFreeStreamDForReading(void) {
|
||||||
int sno = GetFreeStreamD();
|
int sno = GetFreeStreamD();
|
||||||
StreamDesc *s;
|
StreamDesc *s;
|
||||||
|
|
||||||
@ -1646,16 +1633,16 @@ int PlGetc(int sno) {
|
|||||||
Yap_DefaultStreamOps(s);
|
Yap_DefaultStreamOps(s);
|
||||||
UNLOCK(s->streamlock);
|
UNLOCK(s->streamlock);
|
||||||
return sno;
|
return sno;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pred always_prompt_user
|
* @pred always_prompt_user
|
||||||
*
|
*
|
||||||
* Ensure that the stream always prompts before asking the standard input
|
* Ensure that the stream always prompts before asking the standard input
|
||||||
stream for data.
|
stream for data.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static Int always_prompt_user(USES_REGS1) {
|
static Int always_prompt_user(USES_REGS1) {
|
||||||
StreamDesc *s = GLOBAL_Stream + StdInStream;
|
StreamDesc *s = GLOBAL_Stream + StdInStream;
|
||||||
|
|
||||||
s->status |= Promptable_Stream_f;
|
s->status |= Promptable_Stream_f;
|
||||||
@ -1669,9 +1656,9 @@ int PlGetc(int sno) {
|
|||||||
} else
|
} else
|
||||||
Yap_ConsoleOps(s, false);
|
Yap_ConsoleOps(s, false);
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int close1 /** @pred close(+ _S_) is iso
|
static Int close1 /** @pred close(+ _S_) is iso
|
||||||
|
|
||||||
|
|
||||||
Closes the stream _S_. If _S_ does not stand for a stream
|
Closes the stream _S_. If _S_ does not stand for a stream
|
||||||
@ -1683,8 +1670,7 @@ int PlGetc(int sno) {
|
|||||||
|
|
||||||
(USES_REGS1) { /* '$close'(+GLOBAL_Stream) */
|
(USES_REGS1) { /* '$close'(+GLOBAL_Stream) */
|
||||||
Int sno = CheckStream(
|
Int sno = CheckStream(
|
||||||
ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f),
|
ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f), "close/2");
|
||||||
"close/2");
|
|
||||||
if (sno < 0)
|
if (sno < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (sno <= StdErrStream) {
|
if (sno <= StdErrStream) {
|
||||||
@ -1694,36 +1680,35 @@ int PlGetc(int sno) {
|
|||||||
Yap_CloseStream(sno);
|
Yap_CloseStream(sno);
|
||||||
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CLOSE_DEFS() \
|
#define CLOSE_DEFS() \
|
||||||
PAR("force", booleanFlag, CLOSE_FORCE), PAR(NULL, ok, CLOSE_END)
|
PAR("force", booleanFlag, CLOSE_FORCE), PAR(NULL, ok, CLOSE_END)
|
||||||
|
|
||||||
#define PAR(x, y, z) z
|
#define PAR(x, y, z) z
|
||||||
|
|
||||||
typedef enum close_enum_choices { CLOSE_DEFS() } close_choices_t;
|
typedef enum close_enum_choices { CLOSE_DEFS() } close_choices_t;
|
||||||
|
|
||||||
#undef PAR
|
#undef PAR
|
||||||
|
|
||||||
#define PAR(x, y, z) \
|
#define PAR(x, y, z) \
|
||||||
{ x, y, z }
|
{ x, y, z }
|
||||||
|
|
||||||
static const param_t close_defs[] = {CLOSE_DEFS()};
|
static const param_t close_defs[] = {CLOSE_DEFS()};
|
||||||
#undef PAR
|
#undef PAR
|
||||||
|
|
||||||
/** @pred close(+ _S_,+ _O_) is iso
|
/** @pred close(+ _S_,+ _O_) is iso
|
||||||
|
|
||||||
Closes the stream _S_, following options _O_.
|
Closes the stream _S_, following options _O_.
|
||||||
|
|
||||||
The only valid options are `force(true)` and `force(false)`.
|
The only valid options are `force(true)` and `force(false)`.
|
||||||
YAP currently ignores these options.
|
YAP currently ignores these options.
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
static Int close2(USES_REGS1) { /* '$close'(+GLOBAL_Stream) */
|
static Int close2(USES_REGS1) { /* '$close'(+GLOBAL_Stream) */
|
||||||
Int sno = CheckStream(
|
Int sno = CheckStream(
|
||||||
ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f),
|
ARG1, (Input_Stream_f | Output_Stream_f | Socket_Stream_f), "close/2");
|
||||||
"close/2");
|
|
||||||
Term tlist;
|
Term tlist;
|
||||||
if (sno < 0)
|
if (sno < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
@ -1747,9 +1732,9 @@ int PlGetc(int sno) {
|
|||||||
Yap_CloseStream(sno);
|
Yap_CloseStream(sno);
|
||||||
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
Term read_line(int sno) {
|
Term read_line(int sno) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
Term tail;
|
Term tail;
|
||||||
Int ch;
|
Int ch;
|
||||||
@ -1759,11 +1744,11 @@ int PlGetc(int sno) {
|
|||||||
}
|
}
|
||||||
tail = read_line(sno);
|
tail = read_line(sno);
|
||||||
return (MkPairTerm(MkIntTerm(ch), tail));
|
return (MkPairTerm(MkIntTerm(ch), tail));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ABSOLUTE_FILE_NAME_DEFS() \
|
#define ABSOLUTE_FILE_NAME_DEFS() \
|
||||||
PAR("access", isatom, ABSOLUTE_FILE_NAME_ACCESS), \
|
PAR("access", isatom, ABSOLUTE_FILE_NAME_ACCESS) \
|
||||||
PAR("expand", booleanFlag, ABSOLUTE_FILE_NAME_EXPAND), \
|
, PAR("expand", booleanFlag, ABSOLUTE_FILE_NAME_EXPAND), \
|
||||||
PAR("extensions", ok, ABSOLUTE_FILE_NAME_EXTENSIONS), \
|
PAR("extensions", ok, ABSOLUTE_FILE_NAME_EXTENSIONS), \
|
||||||
PAR("file_errors", is_file_errors, ABSOLUTE_FILE_NAME_FILE_ERRORS), \
|
PAR("file_errors", is_file_errors, ABSOLUTE_FILE_NAME_FILE_ERRORS), \
|
||||||
PAR("file_type", is_file_type, ABSOLUTE_FILE_NAME_FILE_TYPE), \
|
PAR("file_type", is_file_type, ABSOLUTE_FILE_NAME_FILE_TYPE), \
|
||||||
@ -1776,20 +1761,20 @@ int PlGetc(int sno) {
|
|||||||
|
|
||||||
#define PAR(x, y, z) z
|
#define PAR(x, y, z) z
|
||||||
|
|
||||||
typedef enum ABSOLUTE_FILE_NAME_enum_ {
|
typedef enum ABSOLUTE_FILE_NAME_enum_ {
|
||||||
ABSOLUTE_FILE_NAME_DEFS()
|
ABSOLUTE_FILE_NAME_DEFS()
|
||||||
} absolute_file_name_choices_t;
|
} absolute_file_name_choices_t;
|
||||||
|
|
||||||
#undef PAR
|
#undef PAR
|
||||||
|
|
||||||
#define PAR(x, y, z) \
|
#define PAR(x, y, z) \
|
||||||
{ x, y, z }
|
{ x, y, z }
|
||||||
|
|
||||||
static const param_t absolute_file_name_search_defs[] = {
|
static const param_t absolute_file_name_search_defs[] = {
|
||||||
ABSOLUTE_FILE_NAME_DEFS()};
|
ABSOLUTE_FILE_NAME_DEFS()};
|
||||||
#undef PAR
|
#undef PAR
|
||||||
|
|
||||||
static Int abs_file_parameters(USES_REGS1) {
|
static Int abs_file_parameters(USES_REGS1) {
|
||||||
Term t[ABSOLUTE_FILE_NAME_END];
|
Term t[ABSOLUTE_FILE_NAME_END];
|
||||||
Term tlist = Deref(ARG1), tf;
|
Term tlist = Deref(ARG1), tf;
|
||||||
/* get options */
|
/* get options */
|
||||||
@ -1817,8 +1802,7 @@ int PlGetc(int sno) {
|
|||||||
t[ABSOLUTE_FILE_NAME_RELATIVE_TO] = gethdir(TermDot);
|
t[ABSOLUTE_FILE_NAME_RELATIVE_TO] = gethdir(TermDot);
|
||||||
}
|
}
|
||||||
if (args[ABSOLUTE_FILE_NAME_FILE_TYPE].used)
|
if (args[ABSOLUTE_FILE_NAME_FILE_TYPE].used)
|
||||||
t[ABSOLUTE_FILE_NAME_FILE_TYPE] =
|
t[ABSOLUTE_FILE_NAME_FILE_TYPE] = args[ABSOLUTE_FILE_NAME_FILE_TYPE].tvalue;
|
||||||
args[ABSOLUTE_FILE_NAME_FILE_TYPE].tvalue;
|
|
||||||
else
|
else
|
||||||
t[ABSOLUTE_FILE_NAME_FILE_TYPE] = TermTxt;
|
t[ABSOLUTE_FILE_NAME_FILE_TYPE] = TermTxt;
|
||||||
if (args[ABSOLUTE_FILE_NAME_ACCESS].used)
|
if (args[ABSOLUTE_FILE_NAME_ACCESS].used)
|
||||||
@ -1831,8 +1815,7 @@ int PlGetc(int sno) {
|
|||||||
else
|
else
|
||||||
t[ABSOLUTE_FILE_NAME_FILE_ERRORS] = TermError;
|
t[ABSOLUTE_FILE_NAME_FILE_ERRORS] = TermError;
|
||||||
if (args[ABSOLUTE_FILE_NAME_SOLUTIONS].used)
|
if (args[ABSOLUTE_FILE_NAME_SOLUTIONS].used)
|
||||||
t[ABSOLUTE_FILE_NAME_SOLUTIONS] =
|
t[ABSOLUTE_FILE_NAME_SOLUTIONS] = args[ABSOLUTE_FILE_NAME_SOLUTIONS].tvalue;
|
||||||
args[ABSOLUTE_FILE_NAME_SOLUTIONS].tvalue;
|
|
||||||
else
|
else
|
||||||
t[ABSOLUTE_FILE_NAME_SOLUTIONS] = TermFirst;
|
t[ABSOLUTE_FILE_NAME_SOLUTIONS] = TermFirst;
|
||||||
if (args[ABSOLUTE_FILE_NAME_EXPAND].used)
|
if (args[ABSOLUTE_FILE_NAME_EXPAND].used)
|
||||||
@ -1849,14 +1832,13 @@ int PlGetc(int sno) {
|
|||||||
args[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH].tvalue;
|
args[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH].tvalue;
|
||||||
else
|
else
|
||||||
t[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH] =
|
t[ABSOLUTE_FILE_NAME_VERBOSE_FILE_SEARCH] =
|
||||||
(trueGlobalPrologFlag(VERBOSE_FILE_SEARCH_FLAG) ? TermTrue
|
(trueGlobalPrologFlag(VERBOSE_FILE_SEARCH_FLAG) ? TermTrue : TermFalse);
|
||||||
: TermFalse);
|
|
||||||
tf = Yap_MkApplTerm(Yap_MkFunctor(AtomOpt, ABSOLUTE_FILE_NAME_END),
|
tf = Yap_MkApplTerm(Yap_MkFunctor(AtomOpt, ABSOLUTE_FILE_NAME_END),
|
||||||
ABSOLUTE_FILE_NAME_END, t);
|
ABSOLUTE_FILE_NAME_END, t);
|
||||||
return (Yap_unify(ARG2, tf));
|
return (Yap_unify(ARG2, tf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int get_abs_file_parameter(USES_REGS1) {
|
static Int get_abs_file_parameter(USES_REGS1) {
|
||||||
Term t = Deref(ARG1), topts = ARG2;
|
Term t = Deref(ARG1), topts = ARG2;
|
||||||
/* get options */
|
/* get options */
|
||||||
/* done */
|
/* done */
|
||||||
@ -1866,9 +1848,9 @@ int PlGetc(int sno) {
|
|||||||
return Yap_unify(ARG3, ArgOfTerm(i + 1, topts));
|
return Yap_unify(ARG3, ArgOfTerm(i + 1, topts));
|
||||||
Yap_Error(DOMAIN_ERROR_ABSOLUTE_FILE_NAME_OPTION, ARG1, NULL);
|
Yap_Error(DOMAIN_ERROR_ABSOLUTE_FILE_NAME_OPTION, ARG1, NULL);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Yap_InitPlIO(void) {
|
void Yap_InitPlIO(void) {
|
||||||
Int i;
|
Int i;
|
||||||
|
|
||||||
Yap_stdin = stdin;
|
Yap_stdin = stdin;
|
||||||
@ -1881,9 +1863,9 @@ int PlGetc(int sno) {
|
|||||||
GLOBAL_Stream[i].status = Free_Stream_f;
|
GLOBAL_Stream[i].status = Free_Stream_f;
|
||||||
}
|
}
|
||||||
InitStdStreams();
|
InitStdStreams();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Yap_InitIOPreds(void) {
|
void Yap_InitIOPreds(void) {
|
||||||
/* here the Input/Output predicates */
|
/* here the Input/Output predicates */
|
||||||
Yap_InitCPred("always_prompt_user", 0, always_prompt_user,
|
Yap_InitCPred("always_prompt_user", 0, always_prompt_user,
|
||||||
SafePredFlag | SyncPredFlag);
|
SafePredFlag | SyncPredFlag);
|
||||||
@ -1918,4 +1900,4 @@ int PlGetc(int sno) {
|
|||||||
Yap_InitSignalPreds();
|
Yap_InitSignalPreds();
|
||||||
Yap_InitSysPreds();
|
Yap_InitSysPreds();
|
||||||
Yap_InitTimePreds();
|
Yap_InitTimePreds();
|
||||||
}
|
}
|
||||||
|
17
os/iopreds.h
17
os/iopreds.h
@ -18,9 +18,9 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#define HAVE_SOCKET 1
|
#define HAVE_SOCKET 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "Yap.h"
|
|
||||||
#include "Atoms.h"
|
#include "Atoms.h"
|
||||||
|
#include "Yap.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file defines main data-structure for stream management,
|
* This file defines main data-structure for stream management,
|
||||||
@ -206,12 +206,17 @@ typedef struct stream_desc {
|
|||||||
#if defined(YAPOR) || defined(THREADS)
|
#if defined(YAPOR) || defined(THREADS)
|
||||||
lockvar streamlock; /* protect stream access */
|
lockvar streamlock; /* protect stream access */
|
||||||
#endif
|
#endif
|
||||||
int (*stream_putc)(int, int); /** function the stream uses for writing a single octet */
|
int (*stream_putc)(
|
||||||
int (*stream_wputc)(int, int); /** function the stream uses for writing a character */
|
int, int); /** function the stream uses for writing a single octet */
|
||||||
|
int (*stream_wputc)(
|
||||||
|
int, wchar_t); /** function the stream uses for writing a character */
|
||||||
int (*stream_getc)(int); /** function the stream uses for reading an octet. */
|
int (*stream_getc)(int); /** function the stream uses for reading an octet. */
|
||||||
int (*stream_wgetc)(int); /** function the stream uses for reading a character. */
|
int (*stream_wgetc)(
|
||||||
|
int); /** function the stream uses for reading a character. */
|
||||||
|
|
||||||
int (*stream_wgetc_for_read)(int); /* function the stream uses for parser. It may be different from above if the ISO character conversion is on */
|
int (*stream_wgetc_for_read)(
|
||||||
|
int); /* function the stream uses for parser. It may be different
|
||||||
|
from above if the ISO character conversion is on */
|
||||||
encoding_t encoding; /** current encoding for stream */
|
encoding_t encoding; /** current encoding for stream */
|
||||||
} StreamDesc;
|
} StreamDesc;
|
||||||
|
|
||||||
|
174
os/mem.c
174
os/mem.c
@ -24,8 +24,8 @@ static char SccsId[] = "%W% %G%";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Yap.h"
|
#include "Yap.h"
|
||||||
#include "Yatom.h"
|
|
||||||
#include "YapHeap.h"
|
#include "YapHeap.h"
|
||||||
|
#include "Yatom.h"
|
||||||
#include "yapio.h"
|
#include "yapio.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#if HAVE_UNISTD_H
|
#if HAVE_UNISTD_H
|
||||||
@ -44,7 +44,7 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#ifndef S_ISDIR
|
#ifndef S_ISDIR
|
||||||
#define S_ISDIR(x) (((x)&_S_IFDIR)==_S_IFDIR)
|
#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#include "iopreds.h"
|
#include "iopreds.h"
|
||||||
@ -52,7 +52,12 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#include "fmemopen.h"
|
#include "fmemopen.h"
|
||||||
#define HAVE_FMEMOPEN 1
|
#define HAVE_FMEMOPEN 1
|
||||||
#define HAVE_OPEN_MEMSTREAM 1
|
#define HAVE_OPEN_MEMSTREAM 1
|
||||||
FILE * open_memstream (char **buf, size_t *len);
|
FILE *open_memstream(char **buf, size_t *len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __ANDROID__
|
||||||
|
#undef HAVE_FMEMOPEN
|
||||||
|
#undef HAVE_OPEN_MEMSTREAM
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_FMEMOPEN
|
#if HAVE_FMEMOPEN
|
||||||
@ -70,12 +75,10 @@ FILE * open_memstream (char **buf, size_t *len);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !MAY_READ
|
#if !MAY_READ
|
||||||
static int MemGetc( int);
|
static int MemGetc(int);
|
||||||
|
|
||||||
/* read from memory */
|
/* read from memory */
|
||||||
static int
|
static int MemGetc(int sno) {
|
||||||
MemGetc(int sno)
|
|
||||||
{
|
|
||||||
register StreamDesc *s = &GLOBAL_Stream[sno];
|
register StreamDesc *s = &GLOBAL_Stream[sno];
|
||||||
Int ch;
|
Int ch;
|
||||||
int spos;
|
int spos;
|
||||||
@ -83,8 +86,7 @@ MemGetc(int sno)
|
|||||||
spos = s->u.mem_string.pos;
|
spos = s->u.mem_string.pos;
|
||||||
if (spos == s->u.mem_string.max_size) {
|
if (spos == s->u.mem_string.max_size) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ch = s->u.mem_string.buf[spos];
|
ch = s->u.mem_string.buf[spos];
|
||||||
s->u.mem_string.pos = ++spos;
|
s->u.mem_string.pos = ++spos;
|
||||||
}
|
}
|
||||||
@ -93,21 +95,18 @@ MemGetc(int sno)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !MAY_WRITE
|
#if !MAY_WRITE
|
||||||
static int MemPutc( int, int);
|
static int MemPutc(int, int);
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
static int
|
static int MemPutc(int sno, int ch) {
|
||||||
MemPutc(int sno, int ch)
|
|
||||||
{
|
|
||||||
StreamDesc *s = &GLOBAL_Stream[sno];
|
StreamDesc *s = &GLOBAL_Stream[sno];
|
||||||
#if MAC || _MSC_VER
|
#if MAC || _MSC_VER
|
||||||
if (ch == 10)
|
if (ch == 10) {
|
||||||
{
|
|
||||||
ch = '\n';
|
ch = '\n';
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
s->u.mem_string.buf[s->u.mem_string.pos++] = ch;
|
s->u.mem_string.buf[s->u.mem_string.pos++] = ch;
|
||||||
if (s->u.mem_string.pos >= s->u.mem_string.max_size -8) {
|
if (s->u.mem_string.pos >= s->u.mem_string.max_size - 8) {
|
||||||
int old_src = s->u.mem_string.src, new_src;
|
int old_src = s->u.mem_string.src, new_src;
|
||||||
|
|
||||||
/* oops, we have reached an overflow */
|
/* oops, we have reached an overflow */
|
||||||
@ -115,10 +114,11 @@ MemPutc(int sno, int ch)
|
|||||||
char *newbuf;
|
char *newbuf;
|
||||||
|
|
||||||
if (old_src == MEM_BUF_CODE &&
|
if (old_src == MEM_BUF_CODE &&
|
||||||
(newbuf = Yap_AllocAtomSpace(new_max_size*sizeof(char))) != NULL) {
|
(newbuf = Yap_AllocAtomSpace(new_max_size * sizeof(char))) != NULL) {
|
||||||
new_src = MEM_BUF_CODE;
|
new_src = MEM_BUF_CODE;
|
||||||
#if HAVE_MEMMOVE
|
#if HAVE_MEMMOVE
|
||||||
memmove((void *)newbuf, (void *)s->u.mem_string.buf, (size_t)((s->u.mem_string.pos)*sizeof(char)));
|
memmove((void *)newbuf, (void *)s->u.mem_string.buf,
|
||||||
|
(size_t)((s->u.mem_string.pos) * sizeof(char)));
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
Int n = s->u.mem_string.pos;
|
Int n = s->u.mem_string.pos;
|
||||||
@ -131,17 +131,19 @@ MemPutc(int sno, int ch)
|
|||||||
#endif
|
#endif
|
||||||
Yap_FreeAtomSpace(s->u.mem_string.buf);
|
Yap_FreeAtomSpace(s->u.mem_string.buf);
|
||||||
#if !HAVE_SYSTEM_MALLOC
|
#if !HAVE_SYSTEM_MALLOC
|
||||||
} else if ((newbuf = (ADDR)realloc(s->u.mem_string.buf, new_max_size*sizeof(char))) != NULL) {
|
} else if ((newbuf = (ADDR)realloc(s->u.mem_string.buf,
|
||||||
|
new_max_size * sizeof(char))) != NULL) {
|
||||||
new_src = MEM_BUF_MALLOC;
|
new_src = MEM_BUF_MALLOC;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (GLOBAL_Stream[sno].u.mem_string.error_handler) {
|
if (GLOBAL_Stream[sno].u.mem_string.error_handler) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
LOCAL_Error_Size = new_max_size*sizeof(char);
|
LOCAL_Error_Size = new_max_size * sizeof(char);
|
||||||
save_machine_regs();
|
save_machine_regs();
|
||||||
longjmp(*(jmp_buf *)GLOBAL_Stream[sno].u.mem_string.error_handler,1);
|
longjmp(*(jmp_buf *)GLOBAL_Stream[sno].u.mem_string.error_handler, 1);
|
||||||
} else {
|
} else {
|
||||||
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, "YAP could not grow heap for writing to string");
|
Yap_Error(RESOURCE_ERROR_HEAP, TermNil,
|
||||||
|
"YAP could not grow heap for writing to string");
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -151,16 +153,14 @@ MemPutc(int sno, int ch)
|
|||||||
s->u.mem_string.max_size = new_max_size;
|
s->u.mem_string.max_size = new_max_size;
|
||||||
s->u.mem_string.src = new_src;
|
s->u.mem_string.src = new_src;
|
||||||
}
|
}
|
||||||
count_output_char(ch,s);
|
count_output_char(ch, s);
|
||||||
return ((int) ch);
|
return ((int)ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp,
|
||||||
int
|
memBufSource src) {
|
||||||
Yap_open_buf_read_stream(const char *nbuf, size_t nchars, encoding_t *encp, memBufSource src)
|
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
int sno;
|
int sno;
|
||||||
StreamDesc *st;
|
StreamDesc *st;
|
||||||
@ -170,23 +170,23 @@ MemPutc(int sno, int ch)
|
|||||||
|
|
||||||
sno = GetFreeStreamD();
|
sno = GetFreeStreamD();
|
||||||
if (sno < 0)
|
if (sno < 0)
|
||||||
return (PlIOError (RESOURCE_ERROR_MAX_STREAMS,TermNil, "new stream not available for open_mem_read_stream/1"));
|
return (PlIOError(RESOURCE_ERROR_MAX_STREAMS, TermNil,
|
||||||
st = GLOBAL_Stream+sno;
|
"new stream not available for open_mem_read_stream/1"));
|
||||||
|
st = GLOBAL_Stream + sno;
|
||||||
if (encp)
|
if (encp)
|
||||||
encoding = *encp;
|
encoding = *encp;
|
||||||
else
|
else
|
||||||
encoding = LOCAL_encoding;
|
encoding = LOCAL_encoding;
|
||||||
#if MAY_READ
|
#if MAY_READ
|
||||||
// like any file stream.
|
// like any file stream.
|
||||||
f = fmemopen( (void *)nbuf, nchars, "r");
|
f = fmemopen((void *)nbuf, nchars, "r");
|
||||||
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
|
flags = Input_Stream_f | InMemory_Stream_f | Seekable_Stream_f;
|
||||||
#else
|
#else
|
||||||
f = NULL;
|
f = NULL;
|
||||||
flags = Input_Stream_f | InMemory_Stream_f;
|
flags = Input_Stream_f | InMemory_Stream_f;
|
||||||
#endif
|
#endif
|
||||||
Yap_initStream(sno, f, NULL, TermNil,
|
Yap_initStream(sno, f, NULL, TermNil, encoding, flags, AtomRead);
|
||||||
encoding, flags, AtomRead);
|
// like any file stream.
|
||||||
// like any file stream.
|
|
||||||
#if !MAY_READ
|
#if !MAY_READ
|
||||||
/* currently these streams are not seekable */
|
/* currently these streams are not seekable */
|
||||||
st->status = Input_Stream_f | InMemory_Stream_f;
|
st->status = Input_Stream_f | InMemory_Stream_f;
|
||||||
@ -196,13 +196,13 @@ MemPutc(int sno, int ch)
|
|||||||
st->u.mem_string.error_handler = NULL;
|
st->u.mem_string.error_handler = NULL;
|
||||||
st->u.mem_string.src = src;
|
st->u.mem_string.src = src;
|
||||||
#endif
|
#endif
|
||||||
Yap_MemOps( st );
|
Yap_MemOps(st);
|
||||||
UNLOCK(st->streamlock);
|
UNLOCK(st->streamlock);
|
||||||
return sno;
|
return sno;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
open_mem_read_stream (USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
|
open_mem_read_stream(USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
|
||||||
{
|
{
|
||||||
Term t, ti;
|
Term t, ti;
|
||||||
int sno;
|
int sno;
|
||||||
@ -222,10 +222,10 @@ open_mem_read_stream (USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
|
|||||||
ti = TailOfTerm(ti);
|
ti = TailOfTerm(ti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ((nbuf = (char *)Yap_AllocAtomSpace((sl+1)*sizeof(char))) == NULL) {
|
while ((nbuf = (char *)Yap_AllocAtomSpace((sl + 1) * sizeof(char))) == NULL) {
|
||||||
if (!Yap_growheap(FALSE, (sl+1)*sizeof(char), NULL)) {
|
if (!Yap_growheap(FALSE, (sl + 1) * sizeof(char), NULL)) {
|
||||||
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
|
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ti = Deref(ARG1);
|
ti = Deref(ARG1);
|
||||||
@ -244,32 +244,30 @@ open_mem_read_stream (USES_REGS1) /* $open_mem_read_stream(+List,-Stream) */
|
|||||||
}
|
}
|
||||||
nbuf[nchars] = '\0';
|
nbuf[nchars] = '\0';
|
||||||
sno = Yap_open_buf_read_stream(nbuf, nchars, &LOCAL_encoding, MEM_BUF_CODE);
|
sno = Yap_open_buf_read_stream(nbuf, nchars, &LOCAL_encoding, MEM_BUF_CODE);
|
||||||
t = Yap_MkStream (sno);
|
t = Yap_MkStream(sno);
|
||||||
return (Yap_unify (ARG2, t));
|
return (Yap_unify(ARG2, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp,
|
||||||
Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp, memBufSource sr)
|
memBufSource sr) {
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
int sno;
|
int sno;
|
||||||
StreamDesc *st;
|
StreamDesc *st;
|
||||||
|
|
||||||
|
|
||||||
sno = GetFreeStreamD();
|
sno = GetFreeStreamD();
|
||||||
if (sno < 0)
|
if (sno < 0)
|
||||||
return -1;
|
return -1;
|
||||||
st = GLOBAL_Stream+sno;
|
st = GLOBAL_Stream + sno;
|
||||||
st->status = Output_Stream_f | InMemory_Stream_f;
|
st->status = Output_Stream_f | InMemory_Stream_f;
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
if (!nchars) {
|
if (!nchars) {
|
||||||
nchars = Yap_page_size;
|
nchars = Yap_page_size;
|
||||||
}
|
}
|
||||||
buf = malloc( nchars );
|
buf = malloc(nchars);
|
||||||
st->status |= FreeOnClose_Stream_f;
|
st->status |= FreeOnClose_Stream_f;
|
||||||
}
|
}
|
||||||
st->nbuf = buf;
|
st->nbuf = buf;
|
||||||
if(!st->nbuf) {
|
if (!st->nbuf) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
st->nsize = nchars;
|
st->nsize = nchars;
|
||||||
@ -280,7 +278,7 @@ Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp, memBufSou
|
|||||||
st->encoding = *encp;
|
st->encoding = *encp;
|
||||||
else
|
else
|
||||||
st->encoding = LOCAL_encoding;
|
st->encoding = LOCAL_encoding;
|
||||||
Yap_DefaultStreamOps( st );
|
Yap_DefaultStreamOps(st);
|
||||||
#if MAY_WRITE
|
#if MAY_WRITE
|
||||||
st->file = open_memstream(&st->nbuf, &st->nsize);
|
st->file = open_memstream(&st->nbuf, &st->nsize);
|
||||||
st->status |= Seekable_Stream_f;
|
st->status |= Seekable_Stream_f;
|
||||||
@ -288,39 +286,39 @@ Yap_open_buf_write_stream(char *buf, size_t nchars, encoding_t *encp, memBufSou
|
|||||||
st->u.mem_string.pos = 0;
|
st->u.mem_string.pos = 0;
|
||||||
st->u.mem_string.buf = st->nbuf;
|
st->u.mem_string.buf = st->nbuf;
|
||||||
st->u.mem_string.max_size = nchars;
|
st->u.mem_string.max_size = nchars;
|
||||||
#endif
|
#endif
|
||||||
Yap_MemOps( st );
|
Yap_MemOps(st);
|
||||||
UNLOCK(st->streamlock);
|
UNLOCK(st->streamlock);
|
||||||
return sno;
|
return sno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int Yap_OpenBufWriteStream(USES_REGS1) {
|
||||||
Yap_OpenBufWriteStream( USES_REGS1 )
|
|
||||||
{
|
|
||||||
char *nbuf;
|
char *nbuf;
|
||||||
size_t sz = Yap_page_size;
|
size_t sz = Yap_page_size;
|
||||||
|
|
||||||
|
while ((nbuf = (char *)Yap_AllocAtomSpace(Yap_page_size * sizeof(char))) ==
|
||||||
while ((nbuf = (char *)Yap_AllocAtomSpace(Yap_page_size*sizeof(char))) == NULL) {
|
NULL) {
|
||||||
if (!Yap_growheap(FALSE, Yap_page_size*sizeof(char), NULL)) {
|
if (!Yap_growheap(FALSE, Yap_page_size * sizeof(char), NULL)) {
|
||||||
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
|
Yap_Error(RESOURCE_ERROR_HEAP, TermNil, LOCAL_ErrorMessage);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Yap_open_buf_write_stream(nbuf, sz, &GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
|
return Yap_open_buf_write_stream(
|
||||||
|
nbuf, sz, &GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int
|
||||||
open_mem_write_stream (USES_REGS1) /* $open_mem_write_stream(-Stream) */
|
open_mem_write_stream(USES_REGS1) /* $open_mem_write_stream(-Stream) */
|
||||||
{
|
{
|
||||||
Term t;
|
Term t;
|
||||||
int sno;
|
int sno;
|
||||||
|
|
||||||
sno = Yap_OpenBufWriteStream( PASS_REGS1 );
|
sno = Yap_OpenBufWriteStream(PASS_REGS1);
|
||||||
if (sno == -1)
|
if (sno == -1)
|
||||||
return (PlIOError (SYSTEM_ERROR_INTERNAL,TermNil, "new stream not available for open_mem_read_stream/1"));
|
return (PlIOError(SYSTEM_ERROR_INTERNAL, TermNil,
|
||||||
t = Yap_MkStream (sno);
|
"new stream not available for open_mem_read_stream/1"));
|
||||||
return (Yap_unify (ARG1, t));
|
t = Yap_MkStream(sno);
|
||||||
|
return (Yap_unify(ARG1, t));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -331,13 +329,10 @@ open_mem_write_stream (USES_REGS1) /* $open_mem_write_stream(-Stream) */
|
|||||||
* @return temporary buffer, discarded by close and may be moved away
|
* @return temporary buffer, discarded by close and may be moved away
|
||||||
* by other writes..
|
* by other writes..
|
||||||
*/
|
*/
|
||||||
char *
|
char *Yap_MemExportStreamPtr(int sno) {
|
||||||
Yap_MemExportStreamPtr( int sno )
|
|
||||||
{
|
|
||||||
#if MAY_WRITE
|
#if MAY_WRITE
|
||||||
char *s;
|
char *s;
|
||||||
if (fflush(GLOBAL_Stream[sno].file) == 0)
|
if (fflush(GLOBAL_Stream[sno].file) == 0) {
|
||||||
{
|
|
||||||
s = GLOBAL_Stream[sno].nbuf;
|
s = GLOBAL_Stream[sno].nbuf;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -347,11 +342,10 @@ Yap_MemExportStreamPtr( int sno )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Int peek_mem_write_stream(
|
||||||
static Int
|
USES_REGS1) { /* '$peek_mem_write_stream'(+GLOBAL_Stream,?S0,?S) */
|
||||||
peek_mem_write_stream ( USES_REGS1 )
|
Int sno =
|
||||||
{ /* '$peek_mem_write_stream'(+GLOBAL_Stream,?S0,?S) */
|
Yap_CheckStream(ARG1, (Output_Stream_f | InMemory_Stream_f), "close/2");
|
||||||
Int sno = Yap_CheckStream (ARG1, (Output_Stream_f | InMemory_Stream_f), "close/2");
|
|
||||||
Int i;
|
Int i;
|
||||||
Term tf = ARG2;
|
Term tf = ARG2;
|
||||||
CELL *HI;
|
CELL *HI;
|
||||||
@ -359,7 +353,7 @@ peek_mem_write_stream ( USES_REGS1 )
|
|||||||
|
|
||||||
if (sno < 0)
|
if (sno < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
restart:
|
restart:
|
||||||
HI = HR;
|
HI = HR;
|
||||||
#if MAY_WRITE
|
#if MAY_WRITE
|
||||||
if (fflush(GLOBAL_Stream[sno].file) == 0) {
|
if (fflush(GLOBAL_Stream[sno].file) == 0) {
|
||||||
@ -372,14 +366,14 @@ peek_mem_write_stream ( USES_REGS1 )
|
|||||||
#endif
|
#endif
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
--i;
|
--i;
|
||||||
tf = MkPairTerm(MkIntTerm(ptr[i]),tf);
|
tf = MkPairTerm(MkIntTerm(ptr[i]), tf);
|
||||||
if (HR + 1024 >= ASP) {
|
if (HR + 1024 >= ASP) {
|
||||||
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
||||||
HR = HI;
|
HR = HI;
|
||||||
if (!Yap_gcl((ASP-HI)*sizeof(CELL), 3, ENV, Yap_gcP()) ) {
|
if (!Yap_gcl((ASP - HI) * sizeof(CELL), 3, ENV, Yap_gcP())) {
|
||||||
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
||||||
Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
|
Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
i = GLOBAL_Stream[sno].u.mem_string.pos;
|
i = GLOBAL_Stream[sno].u.mem_string.pos;
|
||||||
tf = ARG2;
|
tf = ARG2;
|
||||||
@ -388,12 +382,10 @@ peek_mem_write_stream ( USES_REGS1 )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
UNLOCK(GLOBAL_Stream[sno].streamlock);
|
||||||
return (Yap_unify(ARG3,tf));
|
return (Yap_unify(ARG3, tf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Yap_MemOps(StreamDesc *st) {
|
||||||
Yap_MemOps( StreamDesc *st )
|
|
||||||
{
|
|
||||||
#if MAY_WRITE
|
#if MAY_WRITE
|
||||||
st->stream_putc = FilePutc;
|
st->stream_putc = FilePutc;
|
||||||
#else
|
#else
|
||||||
@ -407,13 +399,12 @@ void
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Yap_CloseMemoryStream( int sno )
|
bool Yap_CloseMemoryStream(int sno) {
|
||||||
{
|
if (!(GLOBAL_Stream[sno].status & Output_Stream_f)) {
|
||||||
if (!(GLOBAL_Stream[sno].status & Output_Stream_f) ) {
|
|
||||||
#if MAY_WRITE
|
#if MAY_WRITE
|
||||||
fclose(GLOBAL_Stream[sno].file);
|
fclose(GLOBAL_Stream[sno].file);
|
||||||
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
|
if (GLOBAL_Stream[sno].status & FreeOnClose_Stream_f)
|
||||||
free( GLOBAL_Stream[sno].nbuf );
|
free(GLOBAL_Stream[sno].nbuf);
|
||||||
#else
|
#else
|
||||||
if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE)
|
if (GLOBAL_Stream[sno].u.mem_string.src == MEM_BUF_CODE)
|
||||||
Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf);
|
Yap_FreeAtomSpace(GLOBAL_Stream[sno].u.mem_string.buf);
|
||||||
@ -436,15 +427,14 @@ bool Yap_CloseMemoryStream( int sno )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void Yap_InitMems(void) {
|
||||||
Yap_InitMems( void )
|
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
Term cm = CurrentModule;
|
Term cm = CurrentModule;
|
||||||
CurrentModule = CHARSIO_MODULE;
|
CurrentModule = CHARSIO_MODULE;
|
||||||
Yap_InitCPred ("open_mem_read_stream", 2, open_mem_read_stream, SyncPredFlag);
|
Yap_InitCPred("open_mem_read_stream", 2, open_mem_read_stream, SyncPredFlag);
|
||||||
Yap_InitCPred ("open_mem_write_stream", 1, open_mem_write_stream, SyncPredFlag);
|
Yap_InitCPred("open_mem_write_stream", 1, open_mem_write_stream,
|
||||||
Yap_InitCPred ("peek_mem_write_stream", 3, peek_mem_write_stream, SyncPredFlag);
|
SyncPredFlag);
|
||||||
|
Yap_InitCPred("peek_mem_write_stream", 3, peek_mem_write_stream,
|
||||||
|
SyncPredFlag);
|
||||||
CurrentModule = cm;
|
CurrentModule = cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
484
os/sig.c
484
os/sig.c
@ -18,173 +18,160 @@ static void HandleMatherr(int sig, void *sipv, void *uapv);
|
|||||||
|
|
||||||
#define SIG_PROLOG_OFFSET 32 /* Start of Prolog signals */
|
#define SIG_PROLOG_OFFSET 32 /* Start of Prolog signals */
|
||||||
|
|
||||||
#define SIG_EXCEPTION (SIG_PROLOG_OFFSET+0)
|
#define SIG_EXCEPTION (SIG_PROLOG_OFFSET + 0)
|
||||||
#ifdef ATOMGC
|
#ifdef ATOMGC
|
||||||
#define SIG_ATOM_GC (SIG_PROLOG_OFFSET+1)
|
#define SIG_ATOM_GC (SIG_PROLOG_OFFSET + 1)
|
||||||
#endif
|
#endif
|
||||||
#define SIG_GC (SIG_PROLOG_OFFSET+2)
|
#define SIG_GC (SIG_PROLOG_OFFSET + 2)
|
||||||
#ifdef THREADS
|
#ifdef THREADS
|
||||||
#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET+3)
|
#define SIG_THREAD_SIGNAL (SIG_PROLOG_OFFSET + 3)
|
||||||
#endif
|
#endif
|
||||||
#define SIG_FREECLAUSES (SIG_PROLOG_OFFSET+4)
|
#define SIG_FREECLAUSES (SIG_PROLOG_OFFSET + 4)
|
||||||
#define SIG_PLABORT (SIG_PROLOG_OFFSET+5)
|
#define SIG_PLABORT (SIG_PROLOG_OFFSET + 5)
|
||||||
|
|
||||||
static struct signame
|
static struct signame {
|
||||||
{ int sig;
|
int sig;
|
||||||
const char *name;
|
const char *name;
|
||||||
int flags;
|
int flags;
|
||||||
} signames[] =
|
} signames[] = {
|
||||||
{
|
|
||||||
#ifdef SIGHUP
|
#ifdef SIGHUP
|
||||||
{ SIGHUP, "hup", 0},
|
{SIGHUP, "hup", 0},
|
||||||
#endif
|
#endif
|
||||||
{ SIGINT, "int", 0},
|
{SIGINT, "int", 0},
|
||||||
#ifdef SIGQUIT
|
#ifdef SIGQUIT
|
||||||
{ SIGQUIT, "quit", 0},
|
{SIGQUIT, "quit", 0},
|
||||||
#endif
|
#endif
|
||||||
{ SIGILL, "ill", 0},
|
{SIGILL, "ill", 0},
|
||||||
{ SIGABRT, "abrt", 0},
|
{SIGABRT, "abrt", 0},
|
||||||
#if HAVE_SIGFPE
|
#if HAVE_SIGFPE
|
||||||
{ SIGFPE, "fpe", PLSIG_THROW},
|
{SIGFPE, "fpe", PLSIG_THROW},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGKILL
|
#ifdef SIGKILL
|
||||||
{ SIGKILL, "kill", 0},
|
{SIGKILL, "kill", 0},
|
||||||
#endif
|
#endif
|
||||||
{ SIGSEGV, "segv", 0},
|
{SIGSEGV, "segv", 0},
|
||||||
#ifdef SIGPIPE
|
#ifdef SIGPIPE
|
||||||
{ SIGPIPE, "pipe", 0},
|
{SIGPIPE, "pipe", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGALRM
|
#ifdef SIGALRM
|
||||||
{ SIGALRM, "alrm", PLSIG_THROW},
|
{SIGALRM, "alrm", PLSIG_THROW},
|
||||||
#endif
|
#endif
|
||||||
{ SIGTERM, "term", 0},
|
{SIGTERM, "term", 0},
|
||||||
#ifdef SIGUSR1
|
#ifdef SIGUSR1
|
||||||
{ SIGUSR1, "usr1", 0},
|
{SIGUSR1, "usr1", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGUSR2
|
#ifdef SIGUSR2
|
||||||
{ SIGUSR2, "usr2", 0},
|
{SIGUSR2, "usr2", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGCHLD
|
#ifdef SIGCHLD
|
||||||
{ SIGCHLD, "chld", 0},
|
{SIGCHLD, "chld", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGCONT
|
#ifdef SIGCONT
|
||||||
{ SIGCONT, "cont", 0},
|
{SIGCONT, "cont", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGSTOP
|
#ifdef SIGSTOP
|
||||||
{ SIGSTOP, "stop", 0},
|
{SIGSTOP, "stop", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGTSTP
|
#ifdef SIGTSTP
|
||||||
{ SIGTSTP, "tstp", 0},
|
{SIGTSTP, "tstp", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGTTIN
|
#ifdef SIGTTIN
|
||||||
{ SIGTTIN, "ttin", 0},
|
{SIGTTIN, "ttin", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGTTOU
|
#ifdef SIGTTOU
|
||||||
{ SIGTTOU, "ttou", 0},
|
{SIGTTOU, "ttou", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGTRAP
|
#ifdef SIGTRAP
|
||||||
{ SIGTRAP, "trap", 0},
|
{SIGTRAP, "trap", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGBUS
|
#ifdef SIGBUS
|
||||||
{ SIGBUS, "bus", 0},
|
{SIGBUS, "bus", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGSTKFLT
|
#ifdef SIGSTKFLT
|
||||||
{ SIGSTKFLT, "stkflt", 0},
|
{SIGSTKFLT, "stkflt", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGURG
|
#ifdef SIGURG
|
||||||
{ SIGURG, "urg", 0},
|
{SIGURG, "urg", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGIO
|
#ifdef SIGIO
|
||||||
{ SIGIO, "io", 0},
|
{SIGIO, "io", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPOLL
|
#ifdef SIGPOLL
|
||||||
{ SIGPOLL, "poll", 0},
|
{SIGPOLL, "poll", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGXCPU
|
#ifdef SIGXCPU
|
||||||
{ SIGXCPU, "xcpu", PLSIG_THROW},
|
{SIGXCPU, "xcpu", PLSIG_THROW},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGXFSZ
|
#ifdef SIGXFSZ
|
||||||
{ SIGXFSZ, "xfsz", PLSIG_THROW},
|
{SIGXFSZ, "xfsz", PLSIG_THROW},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGVTALRM
|
#ifdef SIGVTALRM
|
||||||
{ SIGVTALRM, "vtalrm", PLSIG_THROW},
|
{SIGVTALRM, "vtalrm", PLSIG_THROW},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPROF
|
#ifdef SIGPROF
|
||||||
{ SIGPROF, "prof", 0},
|
{SIGPROF, "prof", 0},
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPWR
|
#ifdef SIGPWR
|
||||||
{ SIGPWR, "pwr", 0},
|
{SIGPWR, "pwr", 0},
|
||||||
#endif
|
#endif
|
||||||
{ SIG_EXCEPTION, "prolog:exception", 0 },
|
{SIG_EXCEPTION, "prolog:exception", 0},
|
||||||
#ifdef SIG_ATOM_GC
|
#ifdef SIG_ATOM_GC
|
||||||
{ SIG_ATOM_GC, "prolog:atom_gc", 0 },
|
{SIG_ATOM_GC, "prolog:atom_gc", 0},
|
||||||
#endif
|
#endif
|
||||||
{ SIG_GC, "prolog:gc", 0 },
|
{SIG_GC, "prolog:gc", 0},
|
||||||
#ifdef SIG_THREAD_SIGNAL
|
#ifdef SIG_THREAD_SIGNAL
|
||||||
{ SIG_THREAD_SIGNAL, "prolog:thread_signal", 0 },
|
{SIG_THREAD_SIGNAL, "prolog:thread_signal", 0},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ -1, NULL, 0}
|
{-1, NULL, 0}};
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*signal_handler_t)(int, void *, void *);
|
typedef void (*signal_handler_t)(int, void *, void *);
|
||||||
|
|
||||||
#if HAVE_SIGACTION
|
#if HAVE_SIGACTION
|
||||||
static void
|
static void my_signal_info(int sig, void *handler) {
|
||||||
my_signal_info(int sig, void * handler)
|
|
||||||
{
|
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
|
|
||||||
sigact.sa_handler = handler;
|
sigact.sa_handler = handler;
|
||||||
sigemptyset(&sigact.sa_mask);
|
sigemptyset(&sigact.sa_mask);
|
||||||
sigact.sa_flags = SA_SIGINFO;
|
sigact.sa_flags = SA_SIGINFO;
|
||||||
|
|
||||||
sigaction(sig,&sigact,NULL);
|
sigaction(sig, &sigact, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void my_signal(int sig, void *handler) {
|
||||||
my_signal(int sig, void * handler)
|
|
||||||
{
|
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
|
|
||||||
sigact.sa_handler= (void *)handler;
|
sigact.sa_handler = (void *)handler;
|
||||||
sigemptyset(&sigact.sa_mask);
|
sigemptyset(&sigact.sa_mask);
|
||||||
sigact.sa_flags = 0;
|
sigact.sa_flags = 0;
|
||||||
sigaction(sig,&sigact,NULL);
|
sigaction(sig, &sigact, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static void
|
static void my_signal(int sig, void *handler) { signal(sig, handler); }
|
||||||
my_signal(int sig, void *handler)
|
|
||||||
{
|
|
||||||
signal(sig, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void my_signal_info(int sig, void *handler) {
|
||||||
my_signal_info(int sig, void *handler)
|
if (signal(sig, (void *)handler) == SIG_ERR)
|
||||||
{
|
|
||||||
if(signal(sig, (void *)handler) == SIG_ERR)
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* SWI emulation */
|
/* SWI emulation */
|
||||||
int
|
int Yap_signal_index(const char *name) {
|
||||||
Yap_signal_index(const char *name)
|
struct signame *sn = signames;
|
||||||
{ struct signame *sn = signames;
|
|
||||||
char tmp[12];
|
char tmp[12];
|
||||||
|
|
||||||
if ( strncmp(name, "SIG", 3) == 0 && strlen(name) < 12 )
|
if (strncmp(name, "SIG", 3) == 0 && strlen(name) < 12) {
|
||||||
{ char *p = (char *)name+3, *q = tmp;
|
char *p = (char *)name + 3, *q = tmp;
|
||||||
while ((*q++ = tolower(*p++))) {};
|
while ((*q++ = tolower(*p++))) {
|
||||||
|
};
|
||||||
name = tmp;
|
name = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( ; sn->name; sn++ )
|
for (; sn->name; sn++) {
|
||||||
{ if ( !strcmp(sn->name, name) )
|
if (!strcmp(sn->name, name))
|
||||||
return sn->sig;
|
return sn->sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,20 +186,19 @@ Yap_signal_index(const char *name)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_SIGSEGV
|
#if HAVE_SIGSEGV
|
||||||
static void
|
static void SearchForTrailFault(void *ptr, int sure) {
|
||||||
SearchForTrailFault(void *ptr, int sure)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* If the TRAIL is very close to the top of mmaped allocked space,
|
/* If the TRAIL is very close to the top of mmaped allocked space,
|
||||||
then we can try increasing the TR space and restarting the
|
then we can try increasing the TR space and restarting the
|
||||||
instruction. In the worst case, the system will
|
instruction. In the worst case, the system will
|
||||||
crash again
|
crash again
|
||||||
*/
|
*/
|
||||||
#if OS_HANDLES_TR_OVERFLOW && !USE_SYSTEM_MALLOC
|
#if OS_HANDLES_TR_OVERFLOW && !USE_SYSTEM_MALLOC
|
||||||
if ((ptr > (void *)LOCAL_TrailTop-1024 &&
|
if ((ptr > (void *)LOCAL_TrailTop - 1024 &&
|
||||||
TR < (tr_fr_ptr) LOCAL_TrailTop+(64*1024))) {
|
TR < (tr_fr_ptr)LOCAL_TrailTop + (64 * 1024))) {
|
||||||
if (!Yap_growtrail(64*1024, TRUE)) {
|
if (!Yap_growtrail(64 * 1024, TRUE)) {
|
||||||
Yap_Error(RESOURCE_ERROR_TRAIL, TermNil, "YAP failed to reserve %ld bytes in growtrail", K64);
|
Yap_Error(RESOURCE_ERROR_TRAIL, TermNil,
|
||||||
|
"YAP failed to reserve %ld bytes in growtrail", K64);
|
||||||
}
|
}
|
||||||
/* just in case, make sure the OS keeps the signal handler. */
|
/* just in case, make sure the OS keeps the signal handler. */
|
||||||
/* my_signal_info(SIGSEGV, HandleSIGSEGV); */
|
/* my_signal_info(SIGSEGV, HandleSIGSEGV); */
|
||||||
@ -226,24 +212,21 @@ SearchForTrailFault(void *ptr, int sure)
|
|||||||
"likely bug in YAP, segmentation violation");
|
"likely bug in YAP, segmentation violation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This routine believes there is a continuous space starting from the
|
/* This routine believes there is a continuous space starting from the
|
||||||
HeapBase and ending on TrailTop */
|
HeapBase and ending on TrailTop */
|
||||||
static void
|
static void HandleSIGSEGV(int sig, void *sipv, void *uap) {
|
||||||
HandleSIGSEGV(int sig, void *sipv, void *uap)
|
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
|
|
||||||
void *ptr = TR;
|
void *ptr = TR;
|
||||||
int sure = FALSE;
|
int sure = FALSE;
|
||||||
if (LOCAL_PrologMode & ExtendStackMode) {
|
if (LOCAL_PrologMode & ExtendStackMode) {
|
||||||
Yap_Error(SYSTEM_ERROR_FATAL, TermNil, "OS memory allocation crashed at address %p, bailing out\n",LOCAL_TrailTop);
|
Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
|
||||||
|
"OS memory allocation crashed at address %p, bailing out\n",
|
||||||
|
LOCAL_TrailTop);
|
||||||
}
|
}
|
||||||
#if (defined(__svr4__) || defined(__SVR4))
|
#if (defined(__svr4__) || defined(__SVR4))
|
||||||
siginfo_t *sip = sipv;
|
siginfo_t *sip = sipv;
|
||||||
if (
|
if (sip->si_code != SI_NOINFO && sip->si_code == SEGV_MAPERR) {
|
||||||
sip->si_code != SI_NOINFO &&
|
|
||||||
sip->si_code == SEGV_MAPERR) {
|
|
||||||
ptr = sip->si_addr;
|
ptr = sip->si_addr;
|
||||||
sure = TRUE;
|
sure = TRUE;
|
||||||
}
|
}
|
||||||
@ -252,7 +235,7 @@ HandleSIGSEGV(int sig, void *sipv, void *uap)
|
|||||||
ptr = sip->si_addr;
|
ptr = sip->si_addr;
|
||||||
sure = TRUE;
|
sure = TRUE;
|
||||||
#endif
|
#endif
|
||||||
SearchForTrailFault( ptr, sure );
|
SearchForTrailFault(ptr, sure);
|
||||||
}
|
}
|
||||||
#endif /* SIGSEGV */
|
#endif /* SIGSEGV */
|
||||||
|
|
||||||
@ -262,25 +245,26 @@ HandleSIGSEGV(int sig, void *sipv, void *uap)
|
|||||||
#include <fpu_control.h>
|
#include <fpu_control.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* by default Linux with glibc is IEEE compliant anyway..., but we will pretend it is not. */
|
/* by default Linux with glibc is IEEE compliant anyway..., but we will pretend
|
||||||
static bool
|
* it is not. */
|
||||||
set_fpu_exceptions(Term flag)
|
static bool set_fpu_exceptions(Term flag) {
|
||||||
{
|
|
||||||
if (flag == TermTrue) {
|
if (flag == TermTrue) {
|
||||||
#if HAVE_FESETEXCEPTFLAG
|
#if HAVE_FESETEXCEPTFLAG
|
||||||
fexcept_t excepts;
|
fexcept_t excepts;
|
||||||
return fesetexceptflag(&excepts, FE_DIVBYZERO| FE_UNDERFLOW|FE_OVERFLOW) == 0;
|
return fesetexceptflag(&excepts,
|
||||||
|
FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW) == 0;
|
||||||
#elif HAVE_FEENABLEEXCEPT
|
#elif HAVE_FEENABLEEXCEPT
|
||||||
/* I shall ignore de-normalization and precision errors */
|
/* I shall ignore de-normalization and precision errors */
|
||||||
feenableexcept(FE_DIVBYZERO| FE_INVALID|FE_OVERFLOW);
|
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
// Enable zero-divide, overflow and underflow exception
|
// Enable zero-divide, overflow and underflow exception
|
||||||
_controlfp_s(0, ~(_EM_ZERODIVIDE|_EM_UNDERFLOW|_EM_OVERFLOW), _MCW_EM); // Line B
|
_controlfp_s(0, ~(_EM_ZERODIVIDE | _EM_UNDERFLOW | _EM_OVERFLOW),
|
||||||
|
_MCW_EM); // Line B
|
||||||
#elif defined(__hpux)
|
#elif defined(__hpux)
|
||||||
# if HAVE_FESETTRAPENABLE
|
#if HAVE_FESETTRAPENABLE
|
||||||
/* From HP-UX 11.0 onwards: */
|
/* From HP-UX 11.0 onwards: */
|
||||||
fesettrapenable(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW|FE_UNDERFLOW);
|
fesettrapenable(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW);
|
||||||
# else
|
#else
|
||||||
/*
|
/*
|
||||||
Up until HP-UX 10.20:
|
Up until HP-UX 10.20:
|
||||||
FP_X_INV invalid operation exceptions
|
FP_X_INV invalid operation exceptions
|
||||||
@ -290,22 +274,23 @@ set_fpu_exceptions(Term flag)
|
|||||||
FP_X_IMP imprecise (inexact result)
|
FP_X_IMP imprecise (inexact result)
|
||||||
FP_X_CLEAR simply zero to clear all flags
|
FP_X_CLEAR simply zero to clear all flags
|
||||||
*/
|
*/
|
||||||
fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL);
|
fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL | FP_X_UFL);
|
||||||
# endif
|
#endif
|
||||||
#endif /* __hpux */
|
#endif /* __hpux */
|
||||||
#if HAVE_FPU_CONTROL_H && i386 && defined(__GNUC__)
|
#if HAVE_FPU_CONTROL_H && i386 && defined(__GNUC__)
|
||||||
/* I shall ignore denormalization and precision errors */
|
/* I shall ignore denormalization and precision errors */
|
||||||
int v = _FPU_IEEE & ~(_FPU_MASK_IM|_FPU_MASK_ZM|_FPU_MASK_OM|_FPU_MASK_UM);
|
int v = _FPU_IEEE &
|
||||||
|
~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM);
|
||||||
_FPU_SETCW(v);
|
_FPU_SETCW(v);
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_FETESTEXCEPT
|
#if HAVE_FETESTEXCEPT
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SIGFPE
|
#ifdef HAVE_SIGFPE
|
||||||
my_signal (SIGFPE, HandleMatherr);
|
my_signal(SIGFPE, HandleMatherr);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* do IEEE arithmetic in the way the big boys do */
|
/* do IEEE arithmetic in the way the big boys do */
|
||||||
#if HAVE_FESETEXCEPTFLAG
|
#if HAVE_FESETEXCEPTFLAG
|
||||||
fexcept_t excepts;
|
fexcept_t excepts;
|
||||||
return fesetexceptflag(&excepts, 0) == 0;
|
return fesetexceptflag(&excepts, 0) == 0;
|
||||||
@ -314,13 +299,14 @@ set_fpu_exceptions(Term flag)
|
|||||||
feenableexcept(0);
|
feenableexcept(0);
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
// Enable zero-divide, overflow and underflow exception
|
// Enable zero-divide, overflow and underflow exception
|
||||||
_controlfp_s(0, (_EM_ZERODIVIDE|_EM_UNDERFLOW|_EM_OVERFLOW), _MCW_EM); // Line B
|
_controlfp_s(0, (_EM_ZERODIVIDE | _EM_UNDERFLOW | _EM_OVERFLOW),
|
||||||
|
_MCW_EM); // Line B
|
||||||
#elif defined(__hpux)
|
#elif defined(__hpux)
|
||||||
# if HAVE_FESETTRAPENABLE
|
#if HAVE_FESETTRAPENABLE
|
||||||
fesettrapenable(FE_ALL_EXCEPT);
|
fesettrapenable(FE_ALL_EXCEPT);
|
||||||
# else
|
#else
|
||||||
fpsetmask(FP_X_CLEAR);
|
fpsetmask(FP_X_CLEAR);
|
||||||
# endif
|
#endif
|
||||||
#endif /* __hpux */
|
#endif /* __hpux */
|
||||||
#if HAVE_FPU_CONTROL_H && i386 && defined(__GNUC__)
|
#if HAVE_FPU_CONTROL_H && i386 && defined(__GNUC__)
|
||||||
/* this will probably not work in older releases of Linux */
|
/* this will probably not work in older releases of Linux */
|
||||||
@ -328,27 +314,20 @@ set_fpu_exceptions(Term flag)
|
|||||||
_FPU_SETCW(v);
|
_FPU_SETCW(v);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SIGFPE
|
#ifdef HAVE_SIGFPE
|
||||||
my_signal (SIGFPE, SIG_IGN);
|
my_signal(SIGFPE, SIG_IGN);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool Yap_set_fpu_exceptions(Term flag) { return set_fpu_exceptions(flag); }
|
||||||
Yap_set_fpu_exceptions(Term flag)
|
|
||||||
{
|
|
||||||
return set_fpu_exceptions(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
yap_error_number Yap_MathException__(USES_REGS1) {
|
||||||
yap_error_number
|
|
||||||
Yap_MathException__( USES_REGS1 )
|
|
||||||
{
|
|
||||||
#if HAVE_FETESTEXCEPT
|
#if HAVE_FETESTEXCEPT
|
||||||
int raised;
|
int raised;
|
||||||
|
|
||||||
// #pragma STDC FENV_ACCESS ON
|
// #pragma STDC FENV_ACCESS ON
|
||||||
if ((raised = fetestexcept( FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW)) ) {
|
if ((raised = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW))) {
|
||||||
|
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
if (raised & FE_OVERFLOW) {
|
if (raised & FE_OVERFLOW) {
|
||||||
@ -372,7 +351,7 @@ Yap_MathException__( USES_REGS1 )
|
|||||||
if (err) {
|
if (err) {
|
||||||
return EVALUATION_ERROR_UNDEFINED;
|
return EVALUATION_ERROR_UNDEFINED;
|
||||||
}
|
}
|
||||||
if (raised ) {
|
if (raised) {
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
if (raised & FE_OVERFLOW) {
|
if (raised & FE_OVERFLOW) {
|
||||||
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
return EVALUATION_ERROR_FLOAT_OVERFLOW;
|
||||||
@ -387,7 +366,7 @@ Yap_MathException__( USES_REGS1 )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif (defined(__svr4__) || defined(__SVR4))
|
#elif (defined(__svr4__) || defined(__SVR4))
|
||||||
switch(sip->si_code) {
|
switch (sip->si_code) {
|
||||||
case FPE_INTDIV:
|
case FPE_INTDIV:
|
||||||
return EVALUATION_ERROR_ZERO_DIVISOR;
|
return EVALUATION_ERROR_ZERO_DIVISOR;
|
||||||
break;
|
break;
|
||||||
@ -415,9 +394,7 @@ Yap_MathException__( USES_REGS1 )
|
|||||||
return LOCAL_matherror;
|
return LOCAL_matherror;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int fpe_error(USES_REGS1) {
|
||||||
p_fpe_error( USES_REGS1 )
|
|
||||||
{
|
|
||||||
Yap_Error(LOCAL_matherror, LOCAL_mathtt, LOCAL_mathstring);
|
Yap_Error(LOCAL_matherror, LOCAL_mathtt, LOCAL_mathstring);
|
||||||
LOCAL_matherror = YAP_NO_ERROR;
|
LOCAL_matherror = YAP_NO_ERROR;
|
||||||
LOCAL_mathtt = TermNil;
|
LOCAL_mathtt = TermNil;
|
||||||
@ -425,42 +402,35 @@ p_fpe_error( USES_REGS1 )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void HandleMatherr(int sig, void *sipv, void *uapv) {
|
||||||
HandleMatherr(int sig, void *sipv, void *uapv)
|
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
LOCAL_matherror = Yap_MathException( );
|
LOCAL_matherror = Yap_MathException();
|
||||||
/* reset the registers so that we don't have trash in abstract machine */
|
/* reset the registers so that we don't have trash in abstract machine */
|
||||||
Yap_external_signal( worker_id, YAP_FPE_SIGNAL );
|
Yap_external_signal(worker_id, YAP_FPE_SIGNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SIGFPE */
|
#endif /* SIGFPE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
||||||
static RETSIGTYPE
|
static RETSIGTYPE ReceiveSignal(int s, void *x, void *y) {
|
||||||
ReceiveSignal (int s, void *x, void *y)
|
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
LOCAL_PrologMode |= InterruptMode;
|
LOCAL_PrologMode |= InterruptMode;
|
||||||
my_signal (s, ReceiveSignal);
|
my_signal(s, ReceiveSignal);
|
||||||
switch (s)
|
switch (s) {
|
||||||
{
|
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
// always direct SIGINT to console
|
// always direct SIGINT to console
|
||||||
Yap_external_signal( 0, YAP_INT_SIGNAL );
|
Yap_external_signal(0, YAP_INT_SIGNAL);
|
||||||
break;
|
break;
|
||||||
case SIGALRM:
|
case SIGALRM:
|
||||||
Yap_external_signal( worker_id, YAP_ALARM_SIGNAL );
|
Yap_external_signal(worker_id, YAP_ALARM_SIGNAL);
|
||||||
break;
|
break;
|
||||||
case SIGVTALRM:
|
case SIGVTALRM:
|
||||||
Yap_external_signal( worker_id, YAP_VTALARM_SIGNAL );
|
Yap_external_signal(worker_id, YAP_VTALARM_SIGNAL);
|
||||||
break;
|
break;
|
||||||
#ifndef MPW
|
#ifndef MPW
|
||||||
#ifdef HAVE_SIGFPE
|
#ifdef HAVE_SIGFPE
|
||||||
case SIGFPE:
|
case SIGFPE:
|
||||||
Yap_external_signal( worker_id, YAP_FPE_SIGNAL );
|
Yap_external_signal(worker_id, YAP_FPE_SIGNAL);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -469,25 +439,25 @@ ReceiveSignal (int s, void *x, void *y)
|
|||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
case SIGKILL:
|
case SIGKILL:
|
||||||
LOCAL_PrologMode &= ~InterruptMode;
|
LOCAL_PrologMode &= ~InterruptMode;
|
||||||
Yap_Error(INTERRUPT_EVENT,MkIntTerm(s),NULL);
|
Yap_Error(INTERRUPT_EVENT, MkIntTerm(s), NULL);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGUSR1
|
#ifdef SIGUSR1
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
/* force the system to creep */
|
/* force the system to creep */
|
||||||
Yap_external_signal ( worker_id, YAP_USR1_SIGNAL);
|
Yap_external_signal(worker_id, YAP_USR1_SIGNAL);
|
||||||
break;
|
break;
|
||||||
#endif /* defined(SIGUSR1) */
|
#endif /* defined(SIGUSR1) */
|
||||||
#ifdef SIGUSR2
|
#ifdef SIGUSR2
|
||||||
case SIGUSR2:
|
case SIGUSR2:
|
||||||
/* force the system to creep */
|
/* force the system to creep */
|
||||||
Yap_external_signal ( worker_id, YAP_USR2_SIGNAL);
|
Yap_external_signal(worker_id, YAP_USR2_SIGNAL);
|
||||||
break;
|
break;
|
||||||
#endif /* defined(SIGUSR2) */
|
#endif /* defined(SIGUSR2) */
|
||||||
#ifdef SIGPIPE
|
#ifdef SIGPIPE
|
||||||
case SIGPIPE:
|
case SIGPIPE:
|
||||||
/* force the system to creep */
|
/* force the system to creep */
|
||||||
Yap_external_signal ( worker_id, YAP_PIPE_SIGNAL);
|
Yap_external_signal(worker_id, YAP_PIPE_SIGNAL);
|
||||||
break;
|
break;
|
||||||
#endif /* defined(SIGPIPE) */
|
#endif /* defined(SIGPIPE) */
|
||||||
#ifdef SIGHUP
|
#ifdef SIGHUP
|
||||||
@ -498,15 +468,14 @@ ReceiveSignal (int s, void *x, void *y)
|
|||||||
#endif /* defined(SIGHUP) */
|
#endif /* defined(SIGHUP) */
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "\n[ Unexpected signal ]\n");
|
fprintf(stderr, "\n[ Unexpected signal ]\n");
|
||||||
exit (s);
|
exit(s);
|
||||||
}
|
}
|
||||||
LOCAL_PrologMode &= ~InterruptMode;
|
LOCAL_PrologMode &= ~InterruptMode;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (_MSC_VER || defined(__MINGW32__))
|
#if (_MSC_VER || defined(__MINGW32__))
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI MSCHandleSignal(DWORD dwCtrlType) {
|
||||||
MSCHandleSignal(DWORD dwCtrlType) {
|
|
||||||
if (
|
if (
|
||||||
#if THREADS
|
#if THREADS
|
||||||
REMOTE_InterruptsDisabled(0)
|
REMOTE_InterruptsDisabled(0)
|
||||||
@ -516,7 +485,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
) {
|
) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
switch(dwCtrlType) {
|
switch (dwCtrlType) {
|
||||||
case CTRL_C_EVENT:
|
case CTRL_C_EVENT:
|
||||||
case CTRL_BREAK_EVENT:
|
case CTRL_BREAK_EVENT:
|
||||||
#if THREADS
|
#if THREADS
|
||||||
@ -526,58 +495,52 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
Yap_signal(YAP_WINTIMER_SIGNAL);
|
Yap_signal(YAP_WINTIMER_SIGNAL);
|
||||||
LOCAL_PrologMode |= InterruptMode;
|
LOCAL_PrologMode |= InterruptMode;
|
||||||
#endif
|
#endif
|
||||||
return(TRUE);
|
return (TRUE);
|
||||||
default:
|
default:
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* SIGINT can cause problems, if caught before full initialization */
|
||||||
/* SIGINT can cause problems, if caught before full initialization */
|
void Yap_InitOSSignals(int wid) {
|
||||||
void
|
|
||||||
Yap_InitOSSignals (int wid)
|
|
||||||
{
|
|
||||||
if (GLOBAL_PrologShouldHandleInterrupts) {
|
if (GLOBAL_PrologShouldHandleInterrupts) {
|
||||||
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
#if !defined(LIGHT) && !_MSC_VER && !defined(__MINGW32__) && !defined(LIGHT)
|
||||||
my_signal (SIGQUIT, ReceiveSignal);
|
my_signal(SIGQUIT, ReceiveSignal);
|
||||||
my_signal (SIGKILL, ReceiveSignal);
|
my_signal(SIGKILL, ReceiveSignal);
|
||||||
my_signal (SIGUSR1, ReceiveSignal);
|
my_signal(SIGUSR1, ReceiveSignal);
|
||||||
my_signal (SIGUSR2, ReceiveSignal);
|
my_signal(SIGUSR2, ReceiveSignal);
|
||||||
my_signal (SIGHUP, ReceiveSignal);
|
my_signal(SIGHUP, ReceiveSignal);
|
||||||
my_signal (SIGALRM, ReceiveSignal);
|
my_signal(SIGALRM, ReceiveSignal);
|
||||||
my_signal (SIGVTALRM, ReceiveSignal);
|
my_signal(SIGVTALRM, ReceiveSignal);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPIPE
|
#ifdef SIGPIPE
|
||||||
my_signal (SIGPIPE, ReceiveSignal);
|
my_signal(SIGPIPE, ReceiveSignal);
|
||||||
#endif
|
#endif
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
signal (SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
SetConsoleCtrlHandler(MSCHandleSignal,TRUE);
|
SetConsoleCtrlHandler(MSCHandleSignal, TRUE);
|
||||||
#else
|
#else
|
||||||
my_signal (SIGINT, ReceiveSignal);
|
my_signal(SIGINT, ReceiveSignal);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SIGFPE
|
#ifdef HAVE_SIGFPE
|
||||||
my_signal (SIGFPE, HandleMatherr);
|
my_signal(SIGFPE, HandleMatherr);
|
||||||
#endif
|
#endif
|
||||||
#if HAVE_SIGSEGV
|
#if HAVE_SIGSEGV
|
||||||
my_signal_info (SIGSEGV, HandleSIGSEGV);
|
my_signal_info(SIGSEGV, HandleSIGSEGV);
|
||||||
#endif
|
#endif
|
||||||
#ifdef YAPOR_COW
|
#ifdef YAPOR_COW
|
||||||
signal(SIGCHLD, SIG_IGN); /* avoid ghosts */
|
signal(SIGCHLD, SIG_IGN); /* avoid ghosts */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAVE_SIGNAL */
|
#endif /* HAVE_SIGNAL */
|
||||||
|
|
||||||
|
/* wrapper for alarm system call */
|
||||||
/* wrapper for alarm system call */
|
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
|
|
||||||
static DWORD WINAPI
|
static DWORD WINAPI DoTimerThread(LPVOID targ) {
|
||||||
DoTimerThread(LPVOID targ)
|
|
||||||
{
|
|
||||||
Int *time = (Int *)targ;
|
Int *time = (Int *)targ;
|
||||||
HANDLE htimer;
|
HANDLE htimer;
|
||||||
LARGE_INTEGER liDueTime;
|
LARGE_INTEGER liDueTime;
|
||||||
@ -586,73 +549,67 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
liDueTime.QuadPart = -10000000;
|
liDueTime.QuadPart = -10000000;
|
||||||
liDueTime.QuadPart *= time[0];
|
liDueTime.QuadPart *= time[0];
|
||||||
/* add time in usecs */
|
/* add time in usecs */
|
||||||
liDueTime.QuadPart -= time[1]*10;
|
liDueTime.QuadPart -= time[1] * 10;
|
||||||
/* Copy the relative time into a LARGE_INTEGER. */
|
/* Copy the relative time into a LARGE_INTEGER. */
|
||||||
if (SetWaitableTimer(htimer, &liDueTime,0,NULL,NULL,0) == 0) {
|
if (SetWaitableTimer(htimer, &liDueTime, 0, NULL, NULL, 0) == 0) {
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (WaitForSingleObject(htimer, INFINITE) != WAIT_OBJECT_0)
|
if (WaitForSingleObject(htimer, INFINITE) != WAIT_OBJECT_0)
|
||||||
fprintf(stderr,"WaitForSingleObject failed (%ld)\n", GetLastError());
|
fprintf(stderr, "WaitForSingleObject failed (%ld)\n", GetLastError());
|
||||||
Yap_signal (YAP_WINTIMER_SIGNAL);
|
Yap_signal(YAP_WINTIMER_SIGNAL);
|
||||||
/* now, say what is going on */
|
/* now, say what is going on */
|
||||||
Yap_PutValue(AtomAlarm, MkAtomTerm(AtomTrue));
|
Yap_PutValue(AtomAlarm, MkAtomTerm(AtomTrue));
|
||||||
ExitThread(1);
|
ExitThread(1);
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
return(0L);
|
return (0L);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Int
|
static Int enable_interrupts(USES_REGS1) {
|
||||||
enable_interrupts( USES_REGS1 )
|
|
||||||
{
|
|
||||||
LOCAL_InterruptsDisabled--;
|
LOCAL_InterruptsDisabled--;
|
||||||
if (LOCAL_Signals && !LOCAL_InterruptsDisabled) {
|
if (LOCAL_Signals && !LOCAL_InterruptsDisabled) {
|
||||||
CreepFlag = Unsigned(LCL0);
|
CreepFlag = Unsigned(LCL0);
|
||||||
if ( !Yap_only_has_signal( YAP_CREEP_SIGNAL ) )
|
if (!Yap_only_has_signal(YAP_CREEP_SIGNAL))
|
||||||
EventFlag = Unsigned( LCL0 );
|
EventFlag = Unsigned(LCL0);
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int disable_interrupts(USES_REGS1) {
|
||||||
disable_interrupts( USES_REGS1 )
|
|
||||||
{
|
|
||||||
LOCAL_InterruptsDisabled++;
|
LOCAL_InterruptsDisabled++;
|
||||||
CalculateStackGap( PASS_REGS1 );
|
CalculateStackGap(PASS_REGS1);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int alarm4(USES_REGS1) {
|
||||||
alarm4( USES_REGS1 )
|
|
||||||
{
|
|
||||||
Term t = Deref(ARG1);
|
Term t = Deref(ARG1);
|
||||||
Term t2 = Deref(ARG2);
|
Term t2 = Deref(ARG2);
|
||||||
Int i1, i2;
|
Int i1, i2;
|
||||||
if (IsVarTerm(t)) {
|
if (IsVarTerm(t)) {
|
||||||
Yap_Error(INSTANTIATION_ERROR, t, "alarm/2");
|
Yap_Error(INSTANTIATION_ERROR, t, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!IsIntegerTerm(t)) {
|
if (!IsIntegerTerm(t)) {
|
||||||
Yap_Error(TYPE_ERROR_INTEGER, t, "alarm/2");
|
Yap_Error(TYPE_ERROR_INTEGER, t, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (IsVarTerm(t2)) {
|
if (IsVarTerm(t2)) {
|
||||||
Yap_Error(INSTANTIATION_ERROR, t2, "alarm/2");
|
Yap_Error(INSTANTIATION_ERROR, t2, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!IsIntegerTerm(t2)) {
|
if (!IsIntegerTerm(t2)) {
|
||||||
Yap_Error(TYPE_ERROR_INTEGER, t2, "alarm/2");
|
Yap_Error(TYPE_ERROR_INTEGER, t2, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
i1 = IntegerOfTerm(t);
|
i1 = IntegerOfTerm(t);
|
||||||
i2 = IntegerOfTerm(t2);
|
i2 = IntegerOfTerm(t2);
|
||||||
if (i1 == 0 && i2 == 0) {
|
if (i1 == 0 && i2 == 0) {
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
Yap_get_signal( YAP_WINTIMER_SIGNAL );
|
Yap_get_signal(YAP_WINTIMER_SIGNAL);
|
||||||
#else
|
#else
|
||||||
Yap_get_signal( YAP_ALARM_SIGNAL );
|
Yap_get_signal(YAP_ALARM_SIGNAL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
@ -667,8 +624,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
DWORD dwThreadId;
|
DWORD dwThreadId;
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
|
|
||||||
hThread = CreateThread(
|
hThread = CreateThread(NULL, /* no security attributes */
|
||||||
NULL, /* no security attributes */
|
|
||||||
0, /* use default stack size */
|
0, /* use default stack size */
|
||||||
DoTimerThread, /* thread function */
|
DoTimerThread, /* thread function */
|
||||||
(LPVOID)time, /* argument to thread function */
|
(LPVOID)time, /* argument to thread function */
|
||||||
@ -681,7 +637,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tout = MkIntegerTerm(0);
|
tout = MkIntegerTerm(0);
|
||||||
return Yap_unify(ARG3,tout) && Yap_unify(ARG4,MkIntTerm(0));
|
return Yap_unify(ARG3, tout) && Yap_unify(ARG4, MkIntTerm(0));
|
||||||
}
|
}
|
||||||
#elif HAVE_SETITIMER && !SUPPORT_CONDOR
|
#elif HAVE_SETITIMER && !SUPPORT_CONDOR
|
||||||
{
|
{
|
||||||
@ -693,14 +649,15 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
new.it_value.tv_usec = i2;
|
new.it_value.tv_usec = i2;
|
||||||
if (setitimer(ITIMER_REAL, &new, &old) < 0) {
|
if (setitimer(ITIMER_REAL, &new, &old) < 0) {
|
||||||
#if HAVE_STRERROR
|
#if HAVE_STRERROR
|
||||||
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer: %s", strerror(errno));
|
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer: %s",
|
||||||
|
strerror(errno));
|
||||||
#else
|
#else
|
||||||
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer %d", errno);
|
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer %d", errno);
|
||||||
#endif
|
#endif
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return Yap_unify(ARG3,MkIntegerTerm(old.it_value.tv_sec)) &&
|
return Yap_unify(ARG3, MkIntegerTerm(old.it_value.tv_sec)) &&
|
||||||
Yap_unify(ARG4,MkIntegerTerm(old.it_value.tv_usec));
|
Yap_unify(ARG4, MkIntegerTerm(old.it_value.tv_usec));
|
||||||
}
|
}
|
||||||
#elif HAVE_ALARM && !SUPPORT_CONDOR
|
#elif HAVE_ALARM && !SUPPORT_CONDOR
|
||||||
{
|
{
|
||||||
@ -709,7 +666,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
|
|
||||||
left = alarm(i1);
|
left = alarm(i1);
|
||||||
tout = MkIntegerTerm(left);
|
tout = MkIntegerTerm(left);
|
||||||
return Yap_unify(ARG3,tout) && Yap_unify(ARG4,MkIntTerm(0)) ;
|
return Yap_unify(ARG3, tout) && Yap_unify(ARG4, MkIntTerm(0));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* not actually trying to set the alarm */
|
/* not actually trying to set the alarm */
|
||||||
@ -719,28 +676,26 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
"alarm not available in this configuration");
|
"alarm not available in this configuration");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static Int
|
static Int virtual_alarm(USES_REGS1) {
|
||||||
virtual_alarm( USES_REGS1 )
|
|
||||||
{
|
|
||||||
Term t = Deref(ARG1);
|
Term t = Deref(ARG1);
|
||||||
Term t2 = Deref(ARG2);
|
Term t2 = Deref(ARG2);
|
||||||
if (IsVarTerm(t)) {
|
if (IsVarTerm(t)) {
|
||||||
Yap_Error(INSTANTIATION_ERROR, t, "alarm/2");
|
Yap_Error(INSTANTIATION_ERROR, t, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!IsIntegerTerm(t)) {
|
if (!IsIntegerTerm(t)) {
|
||||||
Yap_Error(TYPE_ERROR_INTEGER, t, "alarm/2");
|
Yap_Error(TYPE_ERROR_INTEGER, t, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (IsVarTerm(t2)) {
|
if (IsVarTerm(t2)) {
|
||||||
Yap_Error(INSTANTIATION_ERROR, t2, "alarm/2");
|
Yap_Error(INSTANTIATION_ERROR, t2, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!IsIntegerTerm(t2)) {
|
if (!IsIntegerTerm(t2)) {
|
||||||
Yap_Error(TYPE_ERROR_INTEGER, t2, "alarm/2");
|
Yap_Error(TYPE_ERROR_INTEGER, t2, "alarm/2");
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
#if _MSC_VER || defined(__MINGW32__)
|
#if _MSC_VER || defined(__MINGW32__)
|
||||||
{
|
{
|
||||||
@ -754,8 +709,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
DWORD dwThreadId;
|
DWORD dwThreadId;
|
||||||
HANDLE hThread;
|
HANDLE hThread;
|
||||||
|
|
||||||
hThread = CreateThread(
|
hThread = CreateThread(NULL, /* no security attributes */
|
||||||
NULL, /* no security attributes */
|
|
||||||
0, /* use default stack size */
|
0, /* use default stack size */
|
||||||
DoTimerThread, /* thread function */
|
DoTimerThread, /* thread function */
|
||||||
(LPVOID)time, /* argument to thread function */
|
(LPVOID)time, /* argument to thread function */
|
||||||
@ -768,7 +722,7 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tout = MkIntegerTerm(0);
|
tout = MkIntegerTerm(0);
|
||||||
return Yap_unify(ARG3,tout) && Yap_unify(ARG4,MkIntTerm(0));
|
return Yap_unify(ARG3, tout) && Yap_unify(ARG4, MkIntTerm(0));
|
||||||
}
|
}
|
||||||
#elif HAVE_SETITIMER && !SUPPORT_CONDOR
|
#elif HAVE_SETITIMER && !SUPPORT_CONDOR
|
||||||
{
|
{
|
||||||
@ -780,14 +734,15 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
new.it_value.tv_usec = IntegerOfTerm(t2);
|
new.it_value.tv_usec = IntegerOfTerm(t2);
|
||||||
if (setitimer(ITIMER_VIRTUAL, &new, &old) < 0) {
|
if (setitimer(ITIMER_VIRTUAL, &new, &old) < 0) {
|
||||||
#if HAVE_STRERROR
|
#if HAVE_STRERROR
|
||||||
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer: %s", strerror(errno));
|
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer: %s",
|
||||||
|
strerror(errno));
|
||||||
#else
|
#else
|
||||||
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer %d", errno);
|
Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "setitimer %d", errno);
|
||||||
#endif
|
#endif
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return Yap_unify(ARG3,MkIntegerTerm(old.it_value.tv_sec)) &&
|
return Yap_unify(ARG3, MkIntegerTerm(old.it_value.tv_sec)) &&
|
||||||
Yap_unify(ARG4,MkIntegerTerm(old.it_value.tv_usec));
|
Yap_unify(ARG4, MkIntegerTerm(old.it_value.tv_usec));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* not actually trying to set the alarm */
|
/* not actually trying to set the alarm */
|
||||||
@ -797,17 +752,15 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
"virtual_alarm not available in this configuration");
|
"virtual_alarm not available in this configuration");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef VAX
|
#ifdef VAX
|
||||||
|
|
||||||
/* avoid longjmp botch */
|
/* avoid longjmp botch */
|
||||||
|
|
||||||
int vax_absmi_fp;
|
int vax_absmi_fp;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int eh;
|
int eh;
|
||||||
int flgs;
|
int flgs;
|
||||||
int ap;
|
int ap;
|
||||||
@ -821,40 +774,33 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
int dummy5;
|
int dummy5;
|
||||||
int dummy6;
|
int dummy6;
|
||||||
int oldpc;
|
int oldpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
*VaxFramePtr;
|
* VaxFramePtr;
|
||||||
|
|
||||||
|
VaxFixFrame(dummy) {
|
||||||
VaxFixFrame (dummy)
|
|
||||||
{
|
|
||||||
int maxframes = 100;
|
int maxframes = 100;
|
||||||
VaxFramePtr fp = (VaxFramePtr) (((int *) &dummy) - 6);
|
VaxFramePtr fp = (VaxFramePtr)(((int *)&dummy) - 6);
|
||||||
while (--maxframes)
|
while (--maxframes) {
|
||||||
{
|
fp = (VaxFramePtr)fp->fp;
|
||||||
fp = (VaxFramePtr) fp->fp;
|
if (fp->flgs == 0) {
|
||||||
if (fp->flgs == 0)
|
|
||||||
{
|
|
||||||
if (fp->oldfp >= ®S[6] && fp->oldfp < ®S[REG_SIZE])
|
if (fp->oldfp >= ®S[6] && fp->oldfp < ®S[REG_SIZE])
|
||||||
fp->oldfp = vax_absmi_fp;
|
fp->oldfp = vax_absmi_fp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
int WINAPI win_yap(HANDLE, DWORD, LPVOID);
|
int WINAPI win_yap(HANDLE, DWORD, LPVOID);
|
||||||
|
|
||||||
int WINAPI win_yap(HANDLE hinst, DWORD reason, LPVOID reserved)
|
int WINAPI win_yap(HANDLE hinst, DWORD reason, LPVOID reserved) {
|
||||||
{
|
switch (reason) {
|
||||||
switch (reason)
|
|
||||||
{
|
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
@ -865,20 +811,19 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(YAPOR) || defined(THREADS)) && !defined(USE_PTHREAD_LOCKING)
|
#if (defined(YAPOR) || defined(THREADS)) && !defined(USE_PTHREAD_LOCKING)
|
||||||
#ifdef sparc
|
#ifdef sparc
|
||||||
void rw_lock_voodoo(void);
|
void rw_lock_voodoo(void);
|
||||||
|
|
||||||
void
|
void rw_lock_voodoo(void) {
|
||||||
rw_lock_voodoo(void) {
|
|
||||||
/* code taken from the Linux kernel, it handles shifting between locks */
|
/* code taken from the Linux kernel, it handles shifting between locks */
|
||||||
/* Read/writer locks, as usual this is overly clever to make it as fast as possible. */
|
/* Read/writer locks, as usual this is overly clever to make it as fast as
|
||||||
|
* possible. */
|
||||||
/* caches... */
|
/* caches... */
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__("___rw_read_enter_spin_on_wlock:\n"
|
||||||
"___rw_read_enter_spin_on_wlock:\n"
|
|
||||||
" orcc %g2, 0x0, %g0\n"
|
" orcc %g2, 0x0, %g0\n"
|
||||||
" be,a ___rw_read_enter\n"
|
" be,a ___rw_read_enter\n"
|
||||||
" ldstub [%g1 + 3], %g2\n"
|
" ldstub [%g1 + 3], %g2\n"
|
||||||
@ -926,28 +871,21 @@ MSCHandleSignal(DWORD dwCtrlType) {
|
|||||||
" bne,a ___rw_write_enter_spin_on_wlock\n"
|
" bne,a ___rw_write_enter_spin_on_wlock\n"
|
||||||
" stb %g0, [%g1 + 3]\n"
|
" stb %g0, [%g1 + 3]\n"
|
||||||
" retl\n"
|
" retl\n"
|
||||||
" mov %g4, %o7\n"
|
" mov %g4, %o7\n");
|
||||||
);
|
}
|
||||||
}
|
|
||||||
#endif /* sparc */
|
#endif /* sparc */
|
||||||
|
|
||||||
|
|
||||||
#endif /* YAPOR || THREADS */
|
#endif /* YAPOR || THREADS */
|
||||||
|
|
||||||
void
|
void Yap_InitSignalPreds(void) {
|
||||||
Yap_InitSignalPreds(void)
|
|
||||||
{
|
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
Term cm = CurrentModule;
|
Term cm = CurrentModule;
|
||||||
|
|
||||||
Yap_InitCPred ("$fpe_error", 0, p_fpe_error, 0);
|
Yap_InitCPred("$fpe_error", 0, fpe_error, 0);
|
||||||
Yap_InitCPred ("$alarm", 4, alarm4, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("$alarm", 4, alarm4, SafePredFlag | SyncPredFlag);
|
||||||
CurrentModule = HACKS_MODULE;
|
CurrentModule = HACKS_MODULE;
|
||||||
Yap_InitCPred ("virtual_alarm", 4, virtual_alarm, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("virtual_alarm", 4, virtual_alarm, SafePredFlag | SyncPredFlag);
|
||||||
Yap_InitCPred ("enable_interrupts", 0, enable_interrupts, SafePredFlag);
|
Yap_InitCPred("enable_interrupts", 0, enable_interrupts, SafePredFlag);
|
||||||
Yap_InitCPred ("disable_interrupts", 0, disable_interrupts, SafePredFlag);
|
Yap_InitCPred("disable_interrupts", 0, disable_interrupts, SafePredFlag);
|
||||||
CurrentModule = cm;
|
CurrentModule = cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -635,6 +635,7 @@ static Term
|
|||||||
do_glob(const char *spec, bool glob_vs_wordexp) {
|
do_glob(const char *spec, bool glob_vs_wordexp) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
char u[YAP_FILENAME_MAX + 1];
|
char u[YAP_FILENAME_MAX + 1];
|
||||||
|
char *espec = u;
|
||||||
if (spec == NULL) {
|
if (spec == NULL) {
|
||||||
return TermNil;
|
return TermNil;
|
||||||
}
|
}
|
||||||
@ -642,7 +643,6 @@ static Term
|
|||||||
{
|
{
|
||||||
WIN32_FIND_DATA find;
|
WIN32_FIND_DATA find;
|
||||||
HANDLE hFind;
|
HANDLE hFind;
|
||||||
const char *espec;
|
|
||||||
CELL *dest;
|
CELL *dest;
|
||||||
Term tf;
|
Term tf;
|
||||||
|
|
||||||
@ -673,7 +673,6 @@ static Term
|
|||||||
return tf;
|
return tf;
|
||||||
}
|
}
|
||||||
#elif HAVE_WORDEXP || HAVE_GLOB
|
#elif HAVE_WORDEXP || HAVE_GLOB
|
||||||
char *espec = u;
|
|
||||||
strncpy(espec, spec, sizeof(u));
|
strncpy(espec, spec, sizeof(u));
|
||||||
/* Expand the string for the program to run. */
|
/* Expand the string for the program to run. */
|
||||||
size_t pathcount;
|
size_t pathcount;
|
||||||
|
663
os/ypsocks.c
663
os/ypsocks.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user