error handling

documentation:
This commit is contained in:
Vitor Santos Costa 2018-05-13 12:59:17 +01:00
parent 37b1e9043b
commit 3369e0085c
13 changed files with 102 additions and 80 deletions

View File

@ -23,7 +23,7 @@ static char SccsId[] = "%W% %G%";
* *
* @namespace prolog * @namespace prolog
* *
/ */
/** /**
* @defgroup Predicates_on_Atoms Predicates on Atoms and Strings * @defgroup Predicates_on_Atoms Predicates on Atoms and Strings
@ -2307,6 +2307,8 @@ static Int cont_sub_atomic(USES_REGS1) {
} }
} else if (mask & SUB_ATOM_HAS_SIZE) { } else if (mask & SUB_ATOM_HAS_SIZE) {
Term nat = build_new_atomic(mask, p, minv, len PASS_REGS); Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
if (nat == 0)
Yap_ThrowExistingError();
Yap_unify(ARG2, MkIntegerTerm(minv)); Yap_unify(ARG2, MkIntegerTerm(minv));
Yap_unify(ARG4, MkIntegerTerm(after)); Yap_unify(ARG4, MkIntegerTerm(after));
Yap_unify(ARG5, nat); Yap_unify(ARG5, nat);
@ -2317,6 +2319,8 @@ static Int cont_sub_atomic(USES_REGS1) {
} else if (mask & SUB_ATOM_HAS_MIN) { } else if (mask & SUB_ATOM_HAS_MIN) {
after = sz - (minv + len); after = sz - (minv + len);
Term nat = build_new_atomic(mask, p, minv, len PASS_REGS); Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
if (nat == 0)
Yap_ThrowExistingError();
Yap_unify(ARG3, MkIntegerTerm(len)); Yap_unify(ARG3, MkIntegerTerm(len));
Yap_unify(ARG4, MkIntegerTerm(after)); Yap_unify(ARG4, MkIntegerTerm(after));
Yap_unify(ARG5, nat); Yap_unify(ARG5, nat);
@ -2327,6 +2331,8 @@ static Int cont_sub_atomic(USES_REGS1) {
} else if (mask & SUB_ATOM_HAS_AFTER) { } else if (mask & SUB_ATOM_HAS_AFTER) {
len = sz - (minv + after); len = sz - (minv + after);
Term nat = build_new_atomic(mask, p, minv, len PASS_REGS); Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
if (nat == 0)
Yap_ThrowExistingError();
Yap_unify(ARG2, MkIntegerTerm(minv)); Yap_unify(ARG2, MkIntegerTerm(minv));
Yap_unify(ARG3, MkIntegerTerm(len)); Yap_unify(ARG3, MkIntegerTerm(len));
Yap_unify(ARG5, nat); Yap_unify(ARG5, nat);
@ -2336,6 +2342,8 @@ static Int cont_sub_atomic(USES_REGS1) {
} }
} else { } else {
Term nat = build_new_atomic(mask, p, minv, len PASS_REGS); Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
if (nat == 0)
Yap_ThrowExistingError();
Yap_unify(ARG2, MkIntegerTerm(minv)); Yap_unify(ARG2, MkIntegerTerm(minv));
Yap_unify(ARG3, MkIntegerTerm(len)); Yap_unify(ARG3, MkIntegerTerm(len));
Yap_unify(ARG4, MkIntegerTerm(after)); Yap_unify(ARG4, MkIntegerTerm(after));

View File

@ -595,8 +595,15 @@ yap_error_descriptor_t *Yap_popErrorContext(bool mdnew, bool pass) {
} }
return NULL; return NULL;
} }
/**
* Throw an error directly to the error handler
*
* @param file where
* @param function who
* @param lineno when
* @param type what, error code
* @param where how, user information
*/
void Yap_ThrowError__(const char *file, const char *function, int lineno, void Yap_ThrowError__(const char *file, const char *function, int lineno,
yap_error_number type, Term where, ...) { yap_error_number type, Term where, ...) {
va_list ap; va_list ap;
@ -621,6 +628,17 @@ void Yap_ThrowError__(const char *file, const char *function, int lineno,
Yap_exit(5); Yap_exit(5);
} }
/**
* complete delayed error.
*
*/
void Yap_ThrowExistingError(void) {
if (LOCAL_RestartEnv) {
Yap_RestartYap(5);
}
Yap_exit(5);
}
/** /**
* @brief Yap_Error * @brief Yap_Error
* This function handles errors in the C code. Check errors.yap for the * This function handles errors in the C code. Check errors.yap for the
@ -641,18 +659,6 @@ void Yap_ThrowError__(const char *file, const char *function, int lineno,
* *
* In a bad day, it has to deal with OOM, abort, and errors within errorts. * In a bad day, it has to deal with OOM, abort, and errors within errorts.
* *
* The list includes the following options:
* + c=c(file, line, function): where the bug was detected;
*
* + e=p(mod, name, arity, cl, file, lin): where the code was entered;
*
* + p=p(mod, name, arity, cl, file, line): the prolog procedure that caused
*the bug,
*and optionally,
*
* + g=g(Goal): the goal that created this mess
*
* + i=i(Comment): an user-written comment on this bug.
*/ */
yamop *Yap_Error__(bool throw, const char *file, const char *function, yamop *Yap_Error__(bool throw, const char *file, const char *function,
int lineno, yap_error_number type, Term where, ...) { int lineno, yap_error_number type, Term where, ...) {

View File

@ -251,7 +251,7 @@ TCL_SUBST =
# members will be omitted, etc. # members will be omitted, etc.
# The default value is: NO. # The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored # Python sources only. Doxygen will then generate output that is more tailored
@ -277,7 +277,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# Prolog sources. Doxygen will then generate output that is tailored for Prolog. # Prolog sources. Doxygen will then generate output that is tailored for Prolog.
# The default value is: NO. # The default value is: NO.
OPTIMIZE_OUTPUT_FOR_PROLOG = NO OPTIMIZE_OUTPUT_FOR_PROLOG = YES
# Doxygen selects the parser to use depending on the extension of the files it # Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given # parses. With this tag you can assign which parser to use for a given
@ -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 = xml XML_OUTPUT = YES
# 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
@ -1975,7 +1975,7 @@ XML_OUTPUT = xml
# The default value is: YES. # The default value is: YES.
# 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_PROGRAMLISTING = YES XML_PROGRAMLISTING = NO
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output # Configuration options related to the DOCBOOK output

View File

@ -59,10 +59,10 @@ $( document ).ready(function() {
$('div.fragment.well div.line:first').css('margin-top', '15px'); $('div.fragment.well div.line:first').css('margin-top', '15px');
$('div.fragment.well div.line:last').css('margin-bottom', '15px'); $('div.fragment.well div.line:last').css('margin-bottom', '15px');
$('table.doxtable').removeClass('doxtable').addClass('table table-striped table-bordered').each(function(){ $('table.doxtable').removeClass('doxtable').addClass('table table-striped table-bordered table-small;').each(function(){
$(this).prepend('<thead></thead>'); $(this).prepend('<thead></thead>');
$(this).find('tbody > tr:first').prependTo($(this).find('thead')); $(this).find('tbody > tr:first').prependTo($(this).find('thead'));
$(this).bootstrapTable('remove', {class: 'separator'});
$(this).find('td > span.success').parent().addClass('success'); $(this).find('td > span.success').parent().addClass('success');
$(this).find('td > span.warning').parent().addClass('warning'); $(this).find('td > span.warning').parent().addClass('warning');
$(this).find('td > span.danger').parent().addClass('danger'); $(this).find('td > span.danger').parent().addClass('danger');
@ -93,6 +93,7 @@ $( document ).ready(function() {
$(".memitem").removeClass('memitem'); $(".memitem").removeClass('memitem');
$(".memproto").removeClass('memproto'); $(".memproto").removeClass('memproto');
$(".separator").removeClass('separator');
$(".memdoc").removeClass('memdoc'); $(".memdoc").removeClass('memdoc');
$("span.mlabel").removeClass('mlabel'); $("span.mlabel").removeClass('mlabel');
$("table.memberdecls").removeClass('memberdecls'); $("table.memberdecls").removeClass('memberdecls');

View File

@ -8,13 +8,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<!-- <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script> --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME--> <!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME--> <!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/> <link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="$relpath^dynsections.js"></script> <script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search $search
$mathjax $mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" /> <link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
@ -22,7 +21,6 @@ $mathjax
$extrastylesheet $extrastylesheet
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js" integrity="sha384-cs/chFZiN24E4KMATLdqdvsezGxaGsi4hLGOzlXwp5UZB1LY//20VyM2taTB4QvJ" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js" integrity="sha384-uefMccjFJAIv6A+rW+L4AHf99KvxDjWSu1z9VI8SKNVmz4sk7buKt/6v9KI65qnm" crossorigin="anonymous"></script>
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> --> <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> -->
@ -61,8 +59,9 @@ $extrastylesheet
<!-- <\!--END SEARCHENGINE-\-> --> <!-- <\!--END SEARCHENGINE-\-> -->
<!-- <\!--END DISABLE_INDEX-\-> --> <!-- <\!--END DISABLE_INDEX-\-> -->
<!-- </tr> --> <!-- </tr> -->
``<!-- </tbody> --> <!-- </tbody> -->
<!-- </table> --> <!-- </table> -->
<!-- </div> --> <!-- </div> -->
$treeview
<!--END TITLEAREA--> <!--END TITLEAREA-->
<!-- end header part --> <!-- end header part -->

View File

@ -240,6 +240,9 @@ INLINE_ONLY extern inline Term Yap_ensure_atom__(const char *fu, const char *fi,
#define LOCAL_RawTerm LOCAL_ActiveError->errorRawTerm #define LOCAL_RawTerm LOCAL_ActiveError->errorRawTerm
#define LOCAL_ErrorMessage LOCAL_ActiveError->errorMsg #define LOCAL_ErrorMessage LOCAL_ActiveError->errorMsg
extern void Yap_ThrowExistingError(void);
extern yap_error_descriptor_t * Yap_pc_add_location(yap_error_descriptor_t *t, void *pc0, void *b_ptr0, void *env0); extern yap_error_descriptor_t * Yap_pc_add_location(yap_error_descriptor_t *t, void *pc0, void *b_ptr0, void *env0);
extern yap_error_descriptor_t *Yap_env_add_location(yap_error_descriptor_t *t,void *cp0, void * b_ptr0, void *env0, YAP_Int ignore_first); extern yap_error_descriptor_t *Yap_env_add_location(yap_error_descriptor_t *t,void *cp0, void * b_ptr0, void *env0, YAP_Int ignore_first);

View File

@ -24,12 +24,12 @@
]). ]).
/** /**
* @defgroup apply_stub Apply Predicates @defgroup apply_stub Apply Predicates
*
* @ingroup library
*
* @{ @ingroup library
@{
This library provides a SWI-compatible set of utilities for applying a This library provides a SWI-compatible set of utilities for applying a
predicate to all elements of a list. predicate to all elements of a list.
@ -37,14 +37,14 @@ predicate to all elements of a list.
The apply library is a _stub_, it just forwards definitions to the The apply library is a _stub_, it just forwards definitions to the
@ref maplist library. The predicates forwarded are: @ref maplist library. The predicates forwarded are:
- maplist/2, * maplist:maplist/2,
- maplist/3, * maplist:maplist/3,
- maplist/4, * maplist:maplist/4,
- maplist/5, * maplist:maplist/5,
- include/3, * maplist:include/3,
- exclude/3, * maplist:exclude/3,
- partition/4, * maplist:partition/4,
- partition/5 * maplist:partition/5
*/ */

View File

@ -76,6 +76,7 @@
* immediately *preceding* "execution" of that operator. * immediately *preceding* "execution" of that operator.
*/ */
typedef unsigned long sop; /* strip operator */ typedef unsigned long sop; /* strip operator */
typedef unsigned char uch;
typedef long sopno; typedef long sopno;
#define OPRMASK 0xf8000000L #define OPRMASK 0xf8000000L
#define OPDMASK 0x07ffffffL #define OPDMASK 0x07ffffffL

View File

@ -1072,7 +1072,7 @@ static Int with_output_to(USES_REGS1) {
Term tin = Deref(ARG1); Term tin = Deref(ARG1);
Functor f; Functor f;
bool out; bool out;
bool my_mem_stream; bool mem_stream = false;
yhandle_t hdl = Yap_PushHandle(tin); yhandle_t hdl = Yap_PushHandle(tin);
if (IsVarTerm(tin)) { if (IsVarTerm(tin)) {
Yap_Error(INSTANTIATION_ERROR, tin, "with_output_to/3"); Yap_Error(INSTANTIATION_ERROR, tin, "with_output_to/3");
@ -1082,23 +1082,22 @@ static Int with_output_to(USES_REGS1) {
if (f == FunctorAtom || f == FunctorString || f == FunctorCodes1 || if (f == FunctorAtom || f == FunctorString || f == FunctorCodes1 ||
f == FunctorCodes || f == FunctorChars1 || f == FunctorChars) { f == FunctorCodes || f == FunctorChars1 || f == FunctorChars) {
output_stream = Yap_OpenBufWriteStream(PASS_REGS1); output_stream = Yap_OpenBufWriteStream(PASS_REGS1);
my_mem_stream = true; mem_stream = true;
} }
} }
if (my_mem_stream){ if (!mem_stream){
/* needs to change LOCAL_c_output_stream for write */
output_stream = Yap_CheckStream(ARG1, Output_Stream_f, "format/3"); output_stream = Yap_CheckStream(ARG1, Output_Stream_f, "format/3");
my_mem_stream = false;
f = NIL; f = NIL;
} }
if (output_stream == -1) { if (output_stream == -1) {
return false; return false;
} }
LOCAL_c_output_stream = output_stream;
UNLOCK(GLOBAL_Stream[output_stream].streamlock); UNLOCK(GLOBAL_Stream[output_stream].streamlock);
out = Yap_Execute(Deref(ARG2) PASS_REGS); out = Yap_Execute(Deref(ARG2) PASS_REGS);
LOCK(GLOBAL_Stream[output_stream].streamlock); LOCK(GLOBAL_Stream[output_stream].streamlock);
LOCAL_c_output_stream = old_out; LOCAL_c_output_stream = old_out;
if (my_mem_stream) { if (mem_stream) {
Term tat; Term tat;
Term inp = Yap_GetFromHandle(hdl); Term inp = Yap_GetFromHandle(hdl);
if (out) { if (out) {
@ -1113,7 +1112,7 @@ static Int with_output_to(USES_REGS1) {
static Int format(Term tf, Term tas, Term tout USES_REGS) { static Int format(Term tf, Term tas, Term tout USES_REGS) {
Int out; Int out;
Functor f; Functor f;
int output_stream; int output_stream = LOCAL_c_output_stream;
bool mem_stream = false; bool mem_stream = false;
if (IsVarTerm(tout)) { if (IsVarTerm(tout)) {

View File

@ -129,7 +129,7 @@ do_c_built_in(Mod:G, _, H, OUT) :-
var(G1), !, var(G1), !,
do_c_built_metacall(G1, M1, H, OUT). do_c_built_metacall(G1, M1, H, OUT).
do_c_built_in('$do_error'( Error, Goal), M, Head, do_c_built_in('$do_error'( Error, Goal), M, Head,
throw(error(Error,M:Goal)) throw(error(Error,M:(Head :- Goal)))
) :- !. ) :- !.
do_c_built_in(system_error( Error, Goal), M, Head, ErrorG) :- do_c_built_in(system_error( Error, Goal), M, Head, ErrorG) :-
do_c_built_in('$do_error'( Error, Goal), M, Head, ErrorG). do_c_built_in('$do_error'( Error, Goal), M, Head, ErrorG).

View File

@ -39,44 +39,43 @@ the first list.
*/ */
atom_concat(Xs,At) :- atom_concat(Xs,At) :-
must_be( list, Xs),
( var(At) -> ( var(At) ->
'$atom_concat'(Xs, At ) '$atom_concat'(Xs, At )
; ;
'$atom_concat_constraints'(Xs, 0, At, Unbound), must_be( atom, At),
'$process_atom_holes'(Unbound) atom_length(At, Len),
'$atom_used_up'(Xs,Len,Available),
Available >= 0,
'$atom_generate'(Xs,At,Available,0)
). ).
% the constraints are of the form hole: HoleAtom, Begin, Atom, End '$atom_used_up'([H|Xs],Len,Available) :-
'$atom_concat_constraints'([At], 0, At, []) :- !. (
'$atom_concat_constraints'([At0], mid(Next, At), At, [hole(At0, Next, At, end)]) :- !. var(H)
% just slice first atom ->
'$atom_concat_constraints'([At0|Xs], 0, At, Unbound) :- '$atom_used_up'(Xs,Len,Available)
atom(At0), !, ;
sub_atom(At0, 0, _Sz, L, _Ata ), must_be( atom, H),
sub_atom(At, _, L, 0, Atr ), %remainder atom_length(H, L),
'$atom_concat_constraints'(Xs, 0, Atr, Unbound). Li is Len-L,
% first hole: Follow says whether we have two holes in a row, At1 will be our atom '$atom_used_up'(Xs,Li,Available)
'$atom_concat_constraints'([At0|Xs], 0, At, [hole(At0, 0, At, Next)|Unbound]) :- ).
'$atom_concat_constraints'(Xs, mid(Next,_At1), At, Unbound). '$atom_used_up'([],Available,Available).
% end of a run
'$atom_concat_constraints'([At0|Xs], mid(end, At1), At, Unbound) :-
atom(At0), !,
sub_atom(At, Next, _Sz, L, At0),
sub_atom(At, 0, Next, Next, At1),
sub_atom(At, _, L, 0, Atr), %remainder
'$atom_concat_constraints'(Xs, 0, Atr, Unbound).
'$atom_concat_constraints'([At0|Xs], mid(Next,At1), At, Next, [hole(At0, Next, At, Follow)|Unbound]) :-
'$atom_concat_constraints'(Xs, mid(Follow, At1), At, Unbound).
'$process_atom_holes'([]).
'$process_atom_holes'([hole(At0, Next, At1, End)|Unbound]) :- End == end, !,
sub_atom(At1, Next, _, 0, At0),
'$process_atom_holes'(Unbound).
'$process_atom_holes'([hole(At0, Next, At1, Follow)|Unbound]) :-
sub_atom(At1, Next, Sz, _Left, At0),
Follow is Next+Sz,
'$process_atom_holes'(Unbound).
'$atom_generate'([],_,0, _).
'$atom_generate'([H|Xs],At,Available, I0) :-
(
var(H)
->
between(0,Available,I)
;
true
),
sub_atom(At,I0,I,_,H),
More is Available-I,
NI0 is I0+I,
'$atom_generate'(Xs, At, More, NI0).
/** @pred atomic_list_concat(+ _As_,? _A_) /** @pred atomic_list_concat(+ _As_,? _A_)

View File

@ -342,9 +342,15 @@ display_consulting(_F, _, _LC) -->
caller( error(_,Info), _) --> caller( error(_,Info), _) -->
{ '$error_descriptor'(Info, Desc) }, { '$error_descriptor'(Info, Desc) },
({ '$query_exception'(errorGoal, Desc, Call), ({ '$query_exception'(errorGoal, Desc, Call),
Call \= [] Call = M:(H :- G)
} }
-> ->
['~*|at ~w' - [10,M:G],
'~*|called from ~w' - [10,H]
]
;
{Call \= []}
->
['~*|by ~w' - [10,Call]] ['~*|by ~w' - [10,Call]]
; ;
true true

View File

@ -102,4 +102,4 @@
\+(2,?,?), \+(2,?,?),
\+( 0 )]). \+( 0 )]).
@} %% @}