Error Implementation through error descriptors. The process is as follows:
- Input the error from Prolog or C-code
- Complete the descriptor with state information
- Export the result either as a term or as a C-structure
API
The key routines are:
- Yap_ThrowError(): create an error descriptor and jump to the closest C longjmp handler
- ErrorFromProlog(): try to discriminate between a throw and an system error; if an error doThrowError()
Also included are exception manipulation routines and higher level error handlers, based on pl/error.yap See include/YapError.h for a definition of data-strEuctures, and include/YapErrors.h for a list of implementation supported exceptions
Exception LifeCycle
Exceptions are a dictionary that includee exception type, location, culprit, and user-defined They start in the bottom stage, so that they:
- complete the dictionary;
- force a throw to the exception handler;
- close the bottom-half and move to the top-half
The top-half is Prolog code
|
| Error Handling |
| The error handler is called when there is an execution error or a warning needs to be displayed.
|
|
◆ c_error_info
◆ BEGIN_ERROR_CLASSES [1/3]
#define BEGIN_ERROR_CLASSES |
( |
| ) |
|
Value: static Atom mkerrorct(yap_error_class_number c) \
{ \
switch (c) \
{
Definition at line 1211 of file errors.c.
◆ BEGIN_ERROR_CLASSES [2/3]
#define BEGIN_ERROR_CLASSES |
( |
| ) |
|
Value: typedef enum aux_class \
{
Definition at line 1211 of file errors.c.
◆ BEGIN_ERROR_CLASSES [3/3]
#define BEGIN_ERROR_CLASSES |
( |
| ) |
static const char *c_error_class_name[] = { |
◆ BEGIN_ERRORS [1/3]
Value: static Term mkerrort(yap_error_number e, Term culprit, Term info) \
{ \
if (!e) e= USER_DEFINED_ERROR; \
if (!info) info = TermNil; \
switch (e) \
{
Definition at line 1226 of file errors.c.
◆ BEGIN_ERRORS [2/3]
◆ BEGIN_ERRORS [3/3]
#define BEGIN_ERRORS |
( |
| ) |
static struct c_error_info c_error_list[] = { |
◆ E [1/3]
Value: case A: \
{ \
Term ft[2], nt[2]; \
nt[0] = MkAtomTerm(Yap_LookupAtom(C)); \
nt[1] = MkVarTerm(); \
if (culprit) Yap_unify(nt[1], culprit); \
ft[0] = Yap_MkApplTerm(Yap_MkFunctor(mkerrorct(B), 2), 2, nt); \
ft[1] = info; \
return Yap_MkApplTerm(FunctorError, 2, ft); \
}
Definition at line 1228 of file errors.c.
◆ E [2/3]
◆ E [3/3]
#define E |
( |
|
X, |
|
|
|
Y, |
|
|
|
Z |
|
) |
| {X, Y##__, Z}, |
◆ E0 [1/3]
Value: case A: \
{ \
Term ft[2]; \
ft[0] = MkAtomTerm(Yap_LookupAtom(C "_error")); \
ft[1] = info; \
return Yap_MkApplTerm(FunctorError, 2, ft); \
}
Definition at line 1227 of file errors.c.
◆ E0 [2/3]
◆ E0 [3/3]
#define E0 |
( |
|
X, |
|
|
|
Y, |
|
|
|
Z |
|
) |
| {X, Y##__, Z}, |
◆ E1 [1/3]
Value: case A: \
{ \
Term ft[2], nt[1]; \
nt[0] = MkVarTerm(); \
if (culprit) Yap_unify(nt[0], culprit); \
ft[0] = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom(C), 1), 1, nt); \
ft[1] = info; \
return Yap_MkApplTerm(FunctorError, 2, ft); \
}
Definition at line 1229 of file errors.c.
◆ E1 [2/3]
◆ E1 [3/3]
#define E1 |
( |
|
X, |
|
|
|
Y, |
|
|
|
Z |
|
) |
| {X, Y##__, Z}, |
◆ E2 [1/3]
#define E2 |
( |
|
A, |
|
|
|
B, |
|
|
|
C, |
|
|
|
D |
|
) |
| |
Value: case A: \
{ \
Term ft[2], nt[3]; \
nt[0] = MkAtomTerm(Yap_LookupAtom(C)); \
nt[1] = MkAtomTerm(Yap_LookupAtom(D)); \
nt[2] = MkVarTerm(); \
if (culprit) Yap_unify(nt[2], culprit); \
ft[0] = Yap_MkApplTerm(Yap_MkFunctor(mkerrorct(B), 3), 3, nt); \
ft[1] = info; \
return Yap_MkApplTerm(FunctorError, 2, ft); \
}
Definition at line 1230 of file errors.c.
◆ E2 [2/3]
#define E2 |
( |
|
X, |
|
|
|
Y, |
|
|
|
Z, |
|
|
|
W |
|
) |
| |
◆ E2 [3/3]
#define E2 |
( |
|
X, |
|
|
|
Y, |
|
|
|
Z, |
|
|
|
W |
|
) |
| {X, Y##__, Z " " W}, |
◆ ECLASS [1/3]
#define ECLASS |
( |
|
CL, |
|
|
|
A, |
|
|
|
B |
|
) |
| |
Value: case CL: \
return Yap_LookupAtom(A);
Definition at line 1213 of file errors.c.
◆ ECLASS [2/3]
#define ECLASS |
( |
|
CL, |
|
|
|
A, |
|
|
|
B |
|
) |
| CL##__, |
◆ ECLASS [3/3]
#define ECLASS |
( |
|
CL, |
|
|
|
A, |
|
|
|
B |
|
) |
| A, |
◆ END_ERROR_CLASSES [1/3]
#define END_ERROR_CLASSES |
( |
| ) |
|
◆ END_ERROR_CLASSES [2/3]
#define END_ERROR_CLASSES |
( |
| ) |
|
◆ END_ERROR_CLASSES [3/3]
#define END_ERROR_CLASSES |
( |
| ) |
|
◆ END_ERRORS [1/3]
◆ END_ERRORS [2/3]
◆ END_ERRORS [3/3]
Value: { \
0, YAPC_NO_ERROR, "" \
} \
} \
;
Definition at line 1231 of file errors.c.
◆ query_key_b
#define query_key_b |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
return i->k ? TermTrue : TermFalse; \
}
Definition at line 163 of file errors.c.
◆ query_key_i
#define query_key_i |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
return MkIntegerTerm(i->k); \
}
Definition at line 169 of file errors.c.
◆ query_key_s
#define query_key_s |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
if (i->k && i->k[0] != '\0') \
return MkAtomTerm(Yap_LookupAtom(i->k)); \
else \
return TermEmptyAtom; \
}
Definition at line 175 of file errors.c.
◆ query_key_t
#define query_key_t |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
Term t; \
if ((t = i->k) == 0) \
return TermNil; \
return t; \
}
Definition at line 184 of file errors.c.
◆ set_key_b
#define set_key_b |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i, |
|
|
|
t |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
i->k = (t == TermTrue ? true : false); \
return i->k || t == TermFalse; \
}
Definition at line 98 of file errors.c.
◆ set_key_i
#define set_key_i |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i, |
|
|
|
t |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
i->k = IsIntegerTerm(t) ? IntegerOfTerm(t) : 0; \
return IsIntegerTerm(t); \
}
Definition at line 105 of file errors.c.
◆ set_key_s
#define set_key_s |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i, |
|
|
|
t |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
const char *s = IsAtomTerm(t) ? RepAtom(AtomOfTerm(t))->StrOfAE \
: IsStringTerm(t) ? StringOfTerm(t) : NULL; \
if (s && s[0]) \
{ \
char *tmp = calloc(1, strlen(s) + 1); \
strcpy(tmp, s); \
i->k = tmp; \
} \
return i->k != NULL; \
}
Definition at line 112 of file errors.c.
◆ set_key_t
#define set_key_t |
( |
|
k, |
|
|
|
ks, |
|
|
|
q, |
|
|
|
i, |
|
|
|
t |
|
) |
| |
Value: if (strcmp(ks, q) == 0) \
{ \
i->k = Yap_SaveTerm(t); \
return i->k != 0L; \
}
Definition at line 126 of file errors.c.
◆ YAP_BUF_SIZE
◆ MkErrorTerm()
◆ MkSysError()
Wrap the error descriptor as exception/2.
Definition at line 841 of file errors.c.
◆ Yap_do_warning__()
void Yap_do_warning__ |
( |
const char * |
file, |
|
|
const char * |
function, |
|
|
int |
line, |
|
|
yap_error_number |
type, |
|
|
Term |
t, |
|
|
|
... |
|
) |
| |
◆ Yap_Error__()
yamop * Yap_Error__ |
( |
bool |
throw, |
|
|
const char * |
file, |
|
|
const char * |
function, |
|
|
int |
lineno, |
|
|
yap_error_number |
type, |
|
|
Term |
where, |
|
|
|
... |
|
) |
| |
Yap_Error This function handles errors in the C code.
Check errors.yap for the corresponding Prolog code
- Parameters
-
file | C source |
function | C function |
lineno | C exact line |
type | the error ID (in YAP this is a single integer) |
where | the culprit |
- Returns
- usually FAILCODE
In a good day, the error handler's job is to generate a throw This includes:
- constructing an ISO style error term;
- constructing a list with all available info on the bug
- generating the throw
- forcing backtracking in order to restart
In a bad day, it has to deal with OOM, abort, and errors within errorts
Definition at line 981 of file errors.c.
◆ Yap_errorClass()
yap_error_class_number Yap_errorClass |
( |
yap_error_number |
e | ) |
|
◆ Yap_errorClassName()
char * Yap_errorClassName |
( |
yap_error_class_number |
e | ) |
|
◆ Yap_errorClassNumber()
yap_error_class_number Yap_errorClassNumber |
( |
const char * |
s | ) |
|
◆ Yap_HandleError__()
bool Yap_HandleError__ |
( |
const char * |
file, |
|
|
const char * |
function, |
|
|
int |
lineno, |
|
|
const char * |
s, |
|
|
|
... |
|
) |
| |
◆ Yap_InitError__()
void Yap_InitError__ |
( |
const char * |
file, |
|
|
const char * |
function, |
|
|
int |
lineno, |
|
|
yap_error_number |
e, |
|
|
Term |
t, |
|
|
|
... |
|
) |
| |
◆ Yap_MkErrorRecord()
bool Yap_MkErrorRecord |
( |
yap_error_descriptor_t * |
r, |
|
|
const char * |
file, |
|
|
const char * |
function, |
|
|
int |
lineno, |
|
|
yap_error_number |
type, |
|
|
Term |
where, |
|
|
const char * |
s |
|
) |
| |
complete an error descriptor:
Definition at line 882 of file errors.c.
◆ Yap_MkFullError()
convert a C-error to a Prolog term:
- fill text fields
- wrap descriptor1240
Definition at line 853 of file errors.c.
◆ Yap_MkPrologError()
◆ Yap_popErrorContext()
◆ Yap_PrintWarning()
bool Yap_PrintWarning |
( |
Term |
twarning | ) |
|
◆ Yap_pushErrorContext()
add a new error descriptor, either to the top of the stack, or as the top;
Definition at line 746 of file errors.c.
◆ Yap_RestartYap()
void Yap_RestartYap |
( |
int |
flag | ) |
|
◆ Yap_SWIHandleError()
int Yap_SWIHandleError |
( |
const char * |
s, |
|
|
|
... |
|
) |
| |
◆ Yap_ThrowError__()
void Yap_ThrowError__ |
( |
const char * |
file, |
|
|
const char * |
function, |
|
|
int |
lineno, |
|
|
yap_error_number |
type, |
|
|
Term |
where, |
|
|
const char * |
msg, |
|
|
|
... |
|
) |
| |
Throw an error directly to the error handler.
- Parameters
-
file | where |
function | who |
lineno | when |
type | what, error code |
where | how, user information |
Definition at line 789 of file errors.c.
◆ Yap_ThrowExistingError()
void Yap_ThrowExistingError |
( |
void |
| ) |
|
◆ Yap_Warning()
bool Yap_Warning |
( |
const char * |
s, |
|
|
|
... |
|
) |
| |
|
#define | set_key_b(k, ks, q, i, t) |
|
#define | set_key_i(k, ks, q, i, t) |
|
#define | set_key_s(k, ks, q, i, t) |
|
#define | set_key_t(k, ks, q, i, t) |
|
#define | query_key_b(k, ks, q, i) |
|
#define | query_key_i(k, ks, q, i) |
|
#define | query_key_s(k, ks, q, i) |
|
#define | query_key_t(k, ks, q, i) |
|
#define | YAP_BUF_SIZE 512 |
|
#define | BEGIN_ERROR_CLASSES() |
|
#define | BEGIN_ERROR_CLASSES() |
|
#define | BEGIN_ERROR_CLASSES() static const char *c_error_class_name[] = { |
|
#define | ECLASS(CL, A, B) |
|
#define | ECLASS(CL, A, B) CL##__, |
|
#define | ECLASS(CL, A, B) A, |
|
#define | END_ERROR_CLASSES() |
|
#define | END_ERROR_CLASSES() |
|
#define | END_ERROR_CLASSES() |
|
#define | BEGIN_ERRORS() |
|
#define | BEGIN_ERRORS() |
|
#define | BEGIN_ERRORS() static struct c_error_info c_error_list[] = { |
|
#define | E0(A, B, C) |
|
#define | E0(X, Y, Z) |
|
#define | E0(X, Y, Z) {X, Y##__, Z}, |
|
#define | E(A, B, C) |
|
#define | E(X, Y, Z) |
|
#define | E(X, Y, Z) {X, Y##__, Z}, |
|
#define | E1(A, B, C) |
|
#define | E1(X, Y, Z) |
|
#define | E1(X, Y, Z) {X, Y##__, Z}, |
|
#define | E2(A, B, C, D) |
|
#define | E2(X, Y, Z, W) |
|
#define | E2(X, Y, Z, W) {X, Y##__, Z " " W}, |
|
#define | END_ERRORS() |
|
#define | END_ERRORS() |
|
#define | END_ERRORS() |
|
|
void | Yap_RestartYap (int flag) |
|
Term | MkErrorTerm (yap_error_descriptor_t *t) |
|
void | Yap_do_warning__ (const char *file, const char *function, int line, yap_error_number type, Term t,...) |
|
bool | Yap_Warning (const char *s,...) |
|
void | Yap_InitError__ (const char *file, const char *function, int lineno, yap_error_number e, Term t,...) |
|
bool | Yap_PrintWarning (Term twarning) |
|
bool | Yap_HandleError__ (const char *file, const char *function, int lineno, const char *s,...) |
|
int | Yap_SWIHandleError (const char *s,...) |
|
yap_error_descriptor_t * | Yap_pushErrorContext (bool link, yap_error_descriptor_t *new_error, yap_error_descriptor_t *old_error) |
| add a new error descriptor, either to the top of the stack, or as the top; More...
|
|
yap_error_descriptor_t * | Yap_popErrorContext (bool mdnew, bool pass, yap_error_descriptor_t *old_error) |
|
void | Yap_ThrowError__ (const char *file, const char *function, int lineno, yap_error_number type, Term where, const char *msg,...) |
| Throw an error directly to the error handler. More...
|
|
void | Yap_ThrowExistingError (void) |
|
Term | MkSysError (yap_error_descriptor_t *i) |
| Wrap the error descriptor as exception/2. More...
|
|
Term | Yap_MkFullError (yap_error_descriptor_t *i) |
| convert a C-error to a Prolog term: More...
|
|
bool | Yap_MkErrorRecord (yap_error_descriptor_t *r, const char *file, const char *function, int lineno, yap_error_number type, Term where, const char *s) |
| complete an error descriptor: More...
|
|
yamop * | Yap_Error__ (bool throw, const char *file, const char *function, int lineno, yap_error_number type, Term where,...) |
| Yap_Error This function handles errors in the C code. More...
|
|
yap_error_class_number | Yap_errorClass (yap_error_number e) |
|
yap_error_class_number | Yap_errorClassNumber (const char *s) |
|
char * | Yap_errorClassName (yap_error_class_number e) |
|
Term | Yap_MkPrologError (Term t, yap_error_descriptor_t *i) |
|