diff --git a/C/errors.c b/C/errors.c index b53ec6c43..fd0411bd6 100755 --- a/C/errors.c +++ b/C/errors.c @@ -68,7 +68,24 @@ bool Yap_Warning(const char *s, ...) { rc = Yap_execute_pred(pred, ts, true PASS_REGS); return rc; } -void Yap_InitError(yap_error_number e, Term t, const char *msg) { + +void Yap_InitError__(const char *file, const char *function, int lineno, yap_error_number e, Term t, ...) { + CACHE_REGS + va_list ap; + va_start(ap, t); + const char *fmt; + char tmpbuf[MAXPATHLEN]; + + fmt = va_arg(ap, char *); + if (fmt != NULL) { +#if HAVE_VSNPRINTF + vsnprintf(tmpbuf, MAXPATHLEN - 1, fmt, ap); +#else + (void)vsprintf(tmpbuf, fmt, ap); +#endif + } else + return; + va_end(ap); if (LOCAL_ActiveError->status) { Yap_exit(1); } @@ -76,10 +93,10 @@ void Yap_InitError(yap_error_number e, Term t, const char *msg) { LOCAL_ActiveError->errorFile = NULL; LOCAL_ActiveError->errorFunction = NULL; LOCAL_ActiveError->errorLine = 0; - if (msg) { - LOCAL_Error_Size = strlen(msg); + if (fmt) { + LOCAL_Error_Size = strlen(tmpbuf); LOCAL_ActiveError->errorMsg = malloc(LOCAL_Error_Size + 1); - strcpy(LOCAL_ActiveError->errorMsg, msg); + strcpy(LOCAL_ActiveError->errorMsg, tmpbuf); } else { LOCAL_Error_Size = 0; } diff --git a/C/scanner.c b/C/scanner.c index b247027f2..0f4f1accb 100755 --- a/C/scanner.c +++ b/C/scanner.c @@ -970,6 +970,10 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) { number_overflow(); *sp++ = ch; ch = getchr(st); + if (!iswhexnumber(ch)) { + Yap_InitError(SYNTAX_ERROR, TermNil, "empty hexadecimal number 0x%C",ch) ; + return 0; + } while (my_isxdigit(ch, 'F', 'f')) { Int oval = val; int chval = @@ -982,16 +986,27 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) { if (oval != (val - chval) / 16) /* overflow */ has_overflow = TRUE; ch = getchr(st); + } *chp = ch; } else if (ch == 'o' && base == 0) { - might_be_float = FALSE; + might_be_float = false; base = 8; ch = getchr(st); + if (ch < '0' || ch > '7') { + Yap_InitError(SYNTAX_ERROR, TermNil, "empty octal number 0b%C", ch) ; + return 0; + } } else if (ch == 'b' && base == 0) { - might_be_float = FALSE; + might_be_float = false; base = 2; ch = getchr(st); + if (ch < '0' || ch > '1') { + Yap_InitError(SYNTAX_ERROR, TermNil, "empty binary 0b%C", ch) ; + return 0; + } + + } else { val = base; base = 10; @@ -1011,7 +1026,7 @@ static Term get_num(int *chp, int *chbuffp, StreamDesc *st, int sign) { } val = val * base + ch - '0'; if (val / base != oval || val - oval * base != ch - '0') /* overflow */ - has_overflow = TRUE; + has_overflow = true; ch = getchr(st); } if (might_be_float && (ch == '.' || ch == 'e' || ch == 'E')) { @@ -1162,8 +1177,7 @@ Term Yap_scan_num(StreamDesc *inp, bool error_on) { #endif if (LOCAL_ErrorMessage != NULL || ch != -1 || cherr) { Yap_clean_tokenizer(old_tr, NULL, NULL); - if (error_on) - Yap_Error(SYNTAX_ERROR, ARG2, "converting number"); + Yap_InitError(SYNTAX_ERROR, ARG2, "while converting stream %d to number", inp-GLOBAL_Stream ); return 0; } return out; @@ -1472,7 +1486,7 @@ TokEntry *Yap_tokenizer(struct stream_desc *st, bool store_comments, cherr = 0; CHECK_SPACE(); if ((t->TokInfo = get_num(&cha, &cherr, st, sign)) == 0L) { - if (p) { + if (t->TokInfo == 0) { p->Tok = eot_tok; t->TokInfo = TermError; } diff --git a/C/text.c b/C/text.c index 577a8f39e..2f64a815d 100644 --- a/C/text.c +++ b/C/text.c @@ -719,21 +719,23 @@ static size_t write_length(const unsigned char *s0, seq_tv_t *out USES_REGS) { static Term write_number(unsigned char *s, seq_tv_t *out, bool error_on USES_REGS) { Term t; - yap_error_number erro = LOCAL_Error_TYPE; - int i = push_text_stack(); + yap_error_descriptor_t new_error; + int i = push_text_stack(); + Yap_pushErrorContext(&new_error); t = Yap_StringToNumberTerm((char *)s, &out->enc, error_on); pop_text_stack(i); - LOCAL_Error_TYPE = erro; + Yap_popErrorContext(true); return t; } static Term string_to_term(void *s, seq_tv_t *out USES_REGS) { Term o; - yap_error_number erro = LOCAL_Error_TYPE; - o = out->val.t = Yap_BufferToTerm(s, TermNil); - LOCAL_Error_TYPE = erro; + yap_error_descriptor_t new_error; + Yap_pushErrorContext(&new_error); + o = out->val.t = Yap_BufferToTerm(s, TermNil); + Yap_popErrorContext(true); - return o; + return o; } bool write_Text(unsigned char *inp, seq_tv_t *out USES_REGS) { diff --git a/CXX/yapq.hh b/CXX/yapq.hh index e3f203c8b..bf95657dc 100644 --- a/CXX/yapq.hh +++ b/CXX/yapq.hh @@ -38,12 +38,10 @@ class X_API YAPPredicate; class X_API YAPQuery : public YAPPredicate { bool q_open; int q_state; - yhandle_t q_g, q_handles; + yhandle_t q_handles; struct yami *q_p, *q_cp; - sigjmp_buf q_env; int q_flags; YAP_dogoalinfo q_h; - YAPQuery *oq; YAPPairTerm names; YAPTerm goal; // temporaries diff --git a/include/YapError.h b/include/YapError.h index 0be7c227d..ada04ff9b 100644 --- a/include/YapError.h +++ b/include/YapError.h @@ -37,10 +37,12 @@ #define MAX_ERROR_MSG_SIZE 1024 -struct yami *Yap_Error__(const char *file, const char *function, int lineno, +extern void Yap_InitError__(const char *file, const char *function, int lineno, yap_error_number e, YAP_Term g, ...); + +extern struct yami *Yap_Error__(const char *file, const char *function, int lineno, yap_error_number err, YAP_Term wheret, ...); -void Yap_ThrowError__(const char *file, const char *function, int lineno, +extern void Yap_ThrowError__(const char *file, const char *function, int lineno, yap_error_number err, YAP_Term wheret, ...) #ifndef MSC_VER __attribute__((noreturn)) @@ -50,6 +52,9 @@ void Yap_ThrowError__(const char *file, const char *function, int lineno, #define Yap_NilError(id, ...) \ Yap_Error__(__FILE__, __FUNCTION__, __LINE__, id, TermNil, __VA_ARGS__) +#define Yap_InitError(id, ...) \ + Yap_InitError__(__FILE__, __FUNCTION__, __LINE__, id, TermNil, __VA_ARGS__) + #define Yap_Error(id, inp, ...) \ Yap_Error__(__FILE__, __FUNCTION__, __LINE__, id, inp, __VA_ARGS__) diff --git a/os/YapIOConfig.h.cmake b/os/YapIOConfig.h.cmake index 8501f670f..afda3b27f 100644 --- a/os/YapIOConfig.h.cmake +++ b/os/YapIOConfig.h.cmake @@ -1,3 +1,12 @@ + +// play nice +#ifndef HAVE_PYTHON +#cmakedefine HAVE_PYTHON ${HAVE_PYTHON} +#endif +#if HAVE_PYTHON +#include +#endif + /* Define if you have libreadline */ #ifndef HAVE_LIBREADLINE #cmakedefine HAVE_LIBREADLINE ${HAVE_LIBREADLINE} diff --git a/os/chartypes.c b/os/chartypes.c index bb0d60d20..0fad877be 100644 --- a/os/chartypes.c +++ b/os/chartypes.c @@ -95,9 +95,7 @@ Term Yap_StringToNumberTerm(const char *s, encoding_t *encp, bool error_on) { s++; #endif t = Yap_scan_num(GLOBAL_Stream + sno, error_on); - if (LOCAL_Error_TYPE == SYNTAX_ERROR) - LOCAL_Error_TYPE = YAP_NO_ERROR; - Yap_CloseStream(sno); + Yap_CloseStream(sno); UNLOCK(GLOBAL_Stream[sno].streamlock); return t; } diff --git a/os/readterm.c b/os/readterm.c index e760c10c0..7aa7c9ce5 100644 --- a/os/readterm.c +++ b/os/readterm.c @@ -324,9 +324,9 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos) { CELL *Hi = HR; TokEntry *tok = LOCAL_tokptr; Int cline = tok->TokLine; - Int startpos = tok->TokPos; - errtok = LOCAL_toktide; - Int errpos = errtok->TokPos; + Int startpos = tok->TokPos; + errtok = LOCAL_toktide; + Int errpos = errtok->TokPos; UInt diff = 0; startline = MkIntegerTerm(cline); endline = MkIntegerTerm(cline); @@ -335,15 +335,15 @@ static Term syntax_error(TokEntry *errtok, int sno, Term cmod, Int newpos) { if (LOCAL_ErrorMessage) tm = MkStringTerm(LOCAL_ErrorMessage); else { - tm = MkStringTerm("syntax error"); + tm = MkStringTerm("syntax error"); } if (GLOBAL_Stream[sno].status & Seekable_Stream_f) { if (errpos && newpos >= 0) { char o[128 + 1]; diff = errpos - startpos; if (diff > 128) { - diff = 128; - startpos = errpos - diff; + diff = 128; + startpos = errpos - diff; } #if HAVE_FTELLO Int curpos = ftello(GLOBAL_Stream[sno].file); @@ -729,7 +729,7 @@ static bool complete_clause_processing(FEnv *fe, TokEntry *tokstart) { CACHE_REGS Term v_vp, v_vnames, v_comments, v_pos; - if (fe->t0 & fe->t && !Yap_unify(fe->t, fe->t0)) + if (fe->t0 && fe->t && !Yap_unify(fe->t, fe->t0)) return false; if (fe->t && fe->vp) v_vp = get_variables(fe, tokstart); @@ -907,6 +907,9 @@ static parser_state_t scanError(REnv *re, FEnv *fe, int inp_stream) { } } // go back to the start + if (LOCAL_Error_TYPE == SYNTAX_ERROR) { + return YAP_PARSING_ERROR; + } if (re->seekable) { if (GLOBAL_Stream[inp_stream].status & InMemory_Stream_f) { GLOBAL_Stream[inp_stream].u.mem_string.pos = re->cpos; diff --git a/pl/boot.yap b/pl/boot.yap index 3d093a5c2..861ceda6a 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -107,7 +107,66 @@ private(_). :- use_system_module( '$_strict_iso', ['$check_iso_strict_clause'/1, '$iso_check_goal'/2]). -% be careful here not to generate an undefined exception. +% be careful here not to generate an undefined exception.. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + print_message(L,E) :- '$number_of_clauses'(print_message(L,E), prolog_complete, 1), diff --git a/pl/meta.yap b/pl/meta.yap index 380969f00..9d7b0396b 100644 --- a/pl/meta.yap +++ b/pl/meta.yap @@ -300,8 +300,9 @@ meta_predicate declaration nonvar(G), G = (A = B), !. -'$expand_goals'(\+A,\+A1,('$current_choice_point'(CP),AO,'$$cut_by'(CP)-> false;true),HM,SM,BM,HVars) :- !, - '$expand_goals'(A,A1,AO,HM,SM,BM,HVars). +'$expand_goals'(\+A,\+A1,(AO-> false;true),HM,SM,BM,HVars) :- !, + '$expand_goals'(A,A1,AOO,HM,SM,BM,HVars), + '$clean_cuts'(AOO, AO). '$expand_goals'(once(A),once(A1), ('$current_choice_point'(CP),AO,'$$cut_by'(CP)),HM,SM,BM,HVars) :- !, '$expand_goals'(A,A1,AO0,HM,SM,BM,HVars),