error propagation

This commit is contained in:
Vitor Santos Costa 2018-05-14 16:03:02 +01:00
parent 3369e0085c
commit 65fa980773
15 changed files with 79 additions and 40 deletions

View File

@ -2334,7 +2334,7 @@ X_API void *YAP_RepStreamFromId(int sno) { return GLOBAL_Stream + sno; }
X_API void YAP_CloseAllOpenStreams(void) { X_API void YAP_CloseAllOpenStreams(void) {
BACKUP_H(); BACKUP_H();
Yap_CloseStreams(FALSE); Yap_CloseStreams();
RECOVER_H(); RECOVER_H();
} }

View File

@ -1427,15 +1427,18 @@ static Int execute_depth_limit(USES_REGS1) {
static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) { static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
int lval = 0, out; int lval = 0, out;
Int OldBorder = LOCAL_CBorder; Int OldBorder = LOCAL_CBorder;
// yap_error_descriptor_t *err_info= LOCAL_ActiveError;
LOCAL_CBorder = LCL0 - ENV; LOCAL_CBorder = LCL0 - ENV;
sigjmp_buf signew, *sighold = LOCAL_RestartEnv; sigjmp_buf signew, *sighold = LOCAL_RestartEnv;
LOCAL_RestartEnv = &signew; LOCAL_RestartEnv = &signew;
int i = AllocLevel();
if /* top &&*/( (lval = sigsetjmp(signew, 1)) != 0) { if /* top &&*/( (lval = sigsetjmp(signew, 1)) != 0) {
switch (lval) { switch (lval) {
case 1: { /* restart */ case 1: { /* restart */
/* otherwise, SetDBForThrow will fail entering critical mode */ /* otherwise, SetDBForThrow will fail entering critical mode */
// LOCAL_ActiveError = err_info;
pop_text_stack(0);
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
/* find out where to cut to */ /* find out where to cut to */
/* siglongjmp resets the TR hardware register */ /* siglongjmp resets the TR hardware register */
@ -1454,12 +1457,14 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
} }
break; break;
case 2: { case 2: {
// LOCAL_ActiveError = err_info;
/* arithmetic exception */ /* arithmetic exception */
/* must be done here, otherwise siglongjmp will clobber all the /* must be done here, otherwise siglongjmp will clobber all the
* registers * registers
*/ */
/* reset the registers so that we don't have trash in abstract /* reset the registers so that we don't have trash in abstract
* machine */ * machine */
pop_text_stack(i);
Yap_set_fpu_exceptions( Yap_set_fpu_exceptions(
getAtomicGlobalPrologFlag(ARITHMETIC_EXCEPTIONS_FLAG)); getAtomicGlobalPrologFlag(ARITHMETIC_EXCEPTIONS_FLAG));
P = (yamop *) FAILCODE; P = (yamop *) FAILCODE;
@ -1467,6 +1472,8 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
} }
break; break;
case 3: { /* saved state */ case 3: { /* saved state */
// LOCAL_ActiveError = err_info;
pop_text_stack(i);
LOCAL_CBorder = OldBorder; LOCAL_CBorder = OldBorder;
LOCAL_RestartEnv = sighold; LOCAL_RestartEnv = sighold;
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
@ -1476,6 +1483,7 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
/* abort */ /* abort */
/* can be called from anywhere, must reset registers, /* can be called from anywhere, must reset registers,
*/ */
// LOCAL_ActiveError = err_info;
while (B) { while (B) {
LOCAL_ActiveError->errorNo = ABORT_EVENT; LOCAL_ActiveError->errorNo = ABORT_EVENT;
Yap_JumpToEnv(); Yap_JumpToEnv();
@ -1483,6 +1491,7 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
LOCAL_PrologMode = UserMode; LOCAL_PrologMode = UserMode;
P = (yamop *) FAILCODE; P = (yamop *) FAILCODE;
LOCAL_RestartEnv = sighold; LOCAL_RestartEnv = sighold;
pop_text_stack(i);
return false; return false;
break; break;
case 5: case 5:
@ -1490,12 +1499,15 @@ static bool exec_absmi(bool top, yap_reset_t reset_mode USES_REGS) {
// but we should inform the caller on what happened. // but we should inform the caller on what happened.
// Yap_regp = old_rs; // Yap_regp = old_rs;
// LOCAL_ActiveError = err_info;
restore_TR(); restore_TR();
restore_B(); restore_B();
/* H is not so important, because we're gonna backtrack */ /* H is not so important, because we're gonna backtrack */
restore_H(); restore_H();
/* set stack */ /* set stack */
Yap_JumpToEnv(); Yap_JumpToEnv();
Yap_CloseTemporaryStreams();
pop_text_stack(i);
ASP = (CELL *) PROTECT_FROZEN_B(B); ASP = (CELL *) PROTECT_FROZEN_B(B);
if (B == NULL || B->cp_b == NULL || (CELL*)(B->cp_b) > LCL0 - LOCAL_CBorder) { if (B == NULL || B->cp_b == NULL || (CELL*)(B->cp_b) > LCL0 - LOCAL_CBorder) {

View File

@ -1478,7 +1478,7 @@ void Yap_exit(int value) {
run_halt_hooks(value); run_halt_hooks(value);
Yap_ShutdownLoadForeign(); Yap_ShutdownLoadForeign();
} }
Yap_CloseStreams(false); Yap_CloseStreams();
Yap_CloseReadline(); Yap_CloseReadline();
#if USE_SYSTEM_MALLOC #if USE_SYSTEM_MALLOC
#endif #endif

View File

@ -559,7 +559,7 @@ static Int do_save(int mode USES_REGS) {
Yap_Error(TYPE_ERROR_LIST, t1, "save/1"); Yap_Error(TYPE_ERROR_LIST, t1, "save/1");
return FALSE; return FALSE;
} }
Yap_CloseStreams(TRUE); Yap_CloseStreams();
if ((splfild = open_file(LOCAL_FileNameBuf, O_WRONLY | O_CREAT)) < 0) { if ((splfild = open_file(LOCAL_FileNameBuf, O_WRONLY | O_CREAT)) < 0) {
Yap_Error(SYSTEM_ERROR_INTERNAL, Yap_Error(SYSTEM_ERROR_INTERNAL,
MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf)), MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf)),
@ -1322,7 +1322,7 @@ static int commit_to_saved_state(const char *s, CELL *Astate, CELL *ATrail,
strcpy(tmp, Yap_AbsoluteFile(s, true)); strcpy(tmp, Yap_AbsoluteFile(s, true));
fprintf(stderr, "%% Restoring file %s\n", tmp); fprintf(stderr, "%% Restoring file %s\n", tmp);
} }
Yap_CloseStreams(TRUE); Yap_CloseStreams();
} }
#ifdef DEBUG_RESTORE4 #ifdef DEBUG_RESTORE4
/* /*

View File

@ -667,7 +667,7 @@ static Term float_send(char *s, int sign) {
#endif #endif
{ {
CACHE_REGS CACHE_REGS
return (MkEvalFl(f)); return MkFloatTerm(f);
} }
} }
@ -969,7 +969,8 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) {
*sp++ = ch; *sp++ = ch;
ch = getchr(st); ch = getchr(st);
if (!my_isxdigit(ch, 'F', 'f')) { if (!my_isxdigit(ch, 'F', 'f')) {
Yap_InitError(SYNTAX_ERROR, TermNil, "empty hexadecimal number 0x%C",ch) ; Yap_syntax_error(NULL, st-GLOBAL_Stream);
Yap_ThrowError(SYNTAX_ERROR, TermNil, "empty hexadecimal number 0x%C",ch) ;
return 0; return 0;
} }
while (my_isxdigit(ch, 'F', 'f')) { while (my_isxdigit(ch, 'F', 'f')) {
@ -992,7 +993,8 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) {
base = 8; base = 8;
ch = getchr(st); ch = getchr(st);
if (ch < '0' || ch > '7') { if (ch < '0' || ch > '7') {
Yap_InitError(SYNTAX_ERROR, TermNil, "empty octal number 0b%C", ch) ; Yap_syntax_error(NULL, st-GLOBAL_Stream);
Yap_ThrowError(SYNTAX_ERROR, TermNil, "empty octal number 0b%C", ch) ;
return 0; return 0;
} }
} else if (ch == 'b' && base == 0) { } else if (ch == 'b' && base == 0) {
@ -1000,7 +1002,8 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) {
base = 2; base = 2;
ch = getchr(st); ch = getchr(st);
if (ch < '0' || ch > '1') { if (ch < '0' || ch > '1') {
Yap_InitError(SYNTAX_ERROR, TermNil, "empty binary 0b%C", ch) ; Yap_syntax_error(NULL, st-GLOBAL_Stream);
Yap_ThrowError(SYNTAX_ERROR, TermNil, "empty binary 0b%C", ch) ;
return 0; return 0;
} }
@ -1032,7 +1035,6 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) {
if (has_dot) { if (has_dot) {
unsigned char *dp; unsigned char *dp;
int dc; int dc;
if (chtype(ch = getchr(st)) != NU) { if (chtype(ch = getchr(st)) != NU) {
if (ch == 'e' || ch == 'E') { if (ch == 'e' || ch == 'E') {
if (trueGlobalPrologFlag(ISO_FLAG)) if (trueGlobalPrologFlag(ISO_FLAG))
@ -1173,11 +1175,6 @@ Term Yap_scan_num(StreamDesc *inp, bool error_on) {
while (isspace(ch = getchr(inp))) while (isspace(ch = getchr(inp)))
; ;
#endif #endif
if (LOCAL_ErrorMessage != NULL || ch != -1 || cherr) {
Yap_clean_tokenizer(old_tr, NULL, NULL);
Yap_InitError(SYNTAX_ERROR, ARG2, "while converting stream %d to number", inp-GLOBAL_Stream );
return 0;
}
return out; return out;
} }

View File

@ -757,16 +757,22 @@ static Term write_number(unsigned char *s, seq_tv_t *out,
Term t; Term t;
yap_error_descriptor_t new_error; yap_error_descriptor_t new_error;
bool mdnew = true; bool mdnew = true;
if (!error_on) {
sigjmp_buf signew, *sighold = LOCAL_RestartEnv;
LOCAL_RestartEnv = &signew;
Yap_pushErrorContext(error_on, &new_error); Yap_pushErrorContext(error_on, &new_error);
if /* top &&*/( sigsetjmp(signew, 1) == 0) {
t = Yap_StringToNumberTerm((char *)s, &out->enc,error_on); t = Yap_StringToNumberTerm((char *)s, &out->enc,error_on);
Yap_popErrorContext(mdnew, true); } else {
if (error_on) {
if (t == 0 && LOCAL_ActiveError->errorNo != YAP_NO_ERROR) {
P = FAILCODE;
Yap_HandleError("scanningx");
}
}
Yap_ResetException(LOCAL_ActiveError); Yap_ResetException(LOCAL_ActiveError);
t = 0;
}
Yap_popErrorContext(mdnew, true);
LOCAL_RestartEnv = sighold;
} else {
t = Yap_StringToNumberTerm((char *)s, &out->enc,error_on);
}
return t; return t;
} }

View File

@ -349,7 +349,7 @@ static void wrputf(Float f, struct write_globs *wglb) /* writes a float */
found_dot = TRUE; found_dot = TRUE;
wrputs(".0", stream); wrputs(".0", stream);
} }
found_dot = TRUE; found_dot = true;
} }
wrputc(ch, stream); wrputc(ch, stream);
pt++; pt++;
@ -1264,6 +1264,7 @@ char *Yap_TermToBuffer(Term t, encoding_t enc, int flags) {
GLOBAL_Stream[sno].encoding = enc; GLOBAL_Stream[sno].encoding = enc;
else else
GLOBAL_Stream[sno].encoding = LOCAL_encoding; GLOBAL_Stream[sno].encoding = LOCAL_encoding;
GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
Yap_plwrite(t, GLOBAL_Stream + sno, 0, flags, GLOBAL_MaxPriority); Yap_plwrite(t, GLOBAL_Stream + sno, 0, flags, GLOBAL_MaxPriority);
sf = Yap_MemExportStreamPtr(sno); sf = Yap_MemExportStreamPtr(sno);

View File

@ -357,11 +357,11 @@ Functor EvalArg(Term);
#define FlIsInt(X) (FALSE) #define FlIsInt(X) (FALSE)
#endif #endif
#ifdef M_WILLIAMS //#if defined(M_WILLIAMS)
#define MkEvalFl(X) MkFloatTerm(X) #define MkEvalFl(X) MkFloatTerm(X)
#else //#else
#define MkEvalFl(X) (FlIsInt(X) ? MkIntTerm((Int)(X)) : MkFloatTerm(X)) //#define MkEvalFl(X) (FlIsInt(X) ? MkIntTerm((Int)(X)) : MkFloatTerm(X))
#endif //#endif
/* Macros used by some of the eval functions */ /* Macros used by some of the eval functions */
#define REvalInt(I) \ #define REvalInt(I) \

View File

@ -216,7 +216,7 @@
printed, `%g` will print all floats using 6 digits instead of the printed, `%g` will print all floats using 6 digits instead of the
default 15. default 15.
*/ */
YAP_FLAG(FLOAT_FORMAT_FLAG, "float_format", true, isatom, "%.16g", YAP_FLAG(FLOAT_FORMAT_FLAG, "float_format", true, isatom, "%.16f",
NULL), NULL),
/**< `gc` /**< `gc`

View File

@ -1958,7 +1958,7 @@ MAN_LINKS = NO
# captures the structure of the code including all documentation. # captures the structure of the code including all documentation.
# The default value is: NO. # The default value is: NO.
GENERATE_XML = NO GENERATE_XML = YES
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@ -1966,7 +1966,7 @@ GENERATE_XML = NO
# The default directory is: xml. # The default directory is: xml.
# This tag requires that the tag GENERATE_XML is set to YES. # This tag requires that the tag GENERATE_XML is set to YES.
XML_OUTPUT = YES XML_OUTPUT = xml
# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to # listings (including syntax highlighting and cross-referencing information) to

View File

@ -391,7 +391,9 @@ typedef enum stream_f {
0x1000000, /**< do not close the stream after an abort event */ 0x1000000, /**< do not close the stream after an abort event */
Readline_Stream_f = 0x2000000, /**< the stream is a readline stream */ Readline_Stream_f = 0x2000000, /**< the stream is a readline stream */
FreeOnClose_Stream_f = FreeOnClose_Stream_f =
0x4000000 /**< the stream buffer should be releaed on close */ 0x4000000, /**< the stream buffer should be releaed on close */
CloseOnException_Stream_f =
0x8000000 /**< the stream closed by Yap_Error and friends */
} estream_f; } estream_f;
typedef uint64_t stream_flags_t; typedef uint64_t stream_flags_t;

View File

@ -95,6 +95,7 @@ Term Yap_StringToNumberTerm(const char *s, encoding_t *encp, bool error_on) {
while (*s && isblank(*s) && Yap_wide_chtype(*s) == BS) while (*s && isblank(*s) && Yap_wide_chtype(*s) == BS)
s++; s++;
#endif #endif
GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
t = Yap_scan_num(GLOBAL_Stream + sno, error_on); t = Yap_scan_num(GLOBAL_Stream + sno, error_on);
Yap_CloseStream(sno); Yap_CloseStream(sno);
UNLOCK(GLOBAL_Stream[sno].streamlock); UNLOCK(GLOBAL_Stream[sno].streamlock);

View File

@ -1384,6 +1384,7 @@ Term Yap_BufferToTerm(const char *s, Term opts) {
sno = Yap_open_buf_read_stream((char *)s, strlen((const char *)s), &l, sno = Yap_open_buf_read_stream((char *)s, strlen((const char *)s), &l,
MEM_BUF_USER); MEM_BUF_USER);
GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
rval = Yap_read_term(sno, opts, false); rval = Yap_read_term(sno, opts, false);
Yap_CloseStream(sno); Yap_CloseStream(sno);
return rval; return rval;
@ -1395,7 +1396,7 @@ Term Yap_UBufferToTerm(const unsigned char *s, Term opts) {
encoding_t l = ENC_ISO_UTF8; encoding_t l = ENC_ISO_UTF8;
sno = Yap_open_buf_read_stream((char *)s, strlen((const char *)s), &l, sno = Yap_open_buf_read_stream((char *)s, strlen((const char *)s), &l,
MEM_BUF_USER); MEM_BUF_USER);
GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
rval = Yap_read_term(sno, opts, false); rval = Yap_read_term(sno, opts, false);
Yap_CloseStream(sno); Yap_CloseStream(sno);
return rval; return rval;
@ -1515,6 +1516,7 @@ static Int read_term_from_string(USES_REGS1) {
char *ss = (char *)s; char *ss = (char *)s;
encoding_t enc = ENC_ISO_UTF8; encoding_t enc = ENC_ISO_UTF8;
int sno = Yap_open_buf_read_stream(ss, len, &enc, MEM_BUF_USER); int sno = Yap_open_buf_read_stream(ss, len, &enc, MEM_BUF_USER);
GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
rc = Yap_read_term(sno, Deref(ARG3), 3); rc = Yap_read_term(sno, Deref(ARG3), 3);
Yap_CloseStream(sno); Yap_CloseStream(sno);
if (!rc) if (!rc)

View File

@ -964,11 +964,11 @@ static Int set_stream(USES_REGS1) { /* Init current_stream */
return do_set_stream(sno, Deref(ARG2) PASS_REGS); return do_set_stream(sno, Deref(ARG2) PASS_REGS);
} }
/* /**
* Called when you want to close all open streams, except for stdin, stdout * Called when you want to close all open streams, except for stdin, stdout
* and stderr * and stderr
*/ */
void Yap_CloseStreams(int loud) { void Yap_CloseStreams(void) {
CACHE_REGS CACHE_REGS
int sno; int sno;
fflush(NULL); fflush(NULL);
@ -979,6 +979,23 @@ void Yap_CloseStreams(int loud) {
} }
} }
/**
* Called when you want to close all temporary streams,
* except for stdin, stdout
* and stderr
*/
void Yap_CloseTemporaryStreams(void) {
CACHE_REGS
int sno;
fflush(NULL);
for (sno = 3; sno < MaxStreams; ++sno) {
if (GLOBAL_Stream[sno].status & Free_Stream_f)
continue;
if (GLOBAL_Stream[sno].status & CloseOnException_Stream_f)
CloseStream(sno);
}
}
static void CloseStream(int sno) { static void CloseStream(int sno) {
CACHE_REGS CACHE_REGS

View File

@ -78,7 +78,8 @@ extern void Yap_UnLockStream(void *);
#define Yap_UnLockStream(X) #define Yap_UnLockStream(X)
#endif #endif
extern Int Yap_GetStreamFd(int); extern Int Yap_GetStreamFd(int);
extern void Yap_CloseStreams(int); extern void Yap_CloseStreams(void);
extern void Yap_CloseTemporaryStreams(void);
extern void Yap_FlushStreams(void); extern void Yap_FlushStreams(void);
extern void Yap_ReleaseStream(int); extern void Yap_ReleaseStream(int);
extern int Yap_PlGetchar(void); extern int Yap_PlGetchar(void);