67#include "YapStreams.h"
87void Yap_RestartYap(
int flag)
91 restore_absmi_regs(&Yap_standard_regs);
93 siglongjmp(*LOCAL_RestartEnv, flag);
98#define set_key_b(k, ks, q, i, t) \
99 if (strcmp(ks, q) == 0) \
101 i->k = (t == TermTrue ? true : false); \
102 return i->k || t == TermFalse; \
105#define set_key_i(k, ks, q, i, t) \
106 if (strcmp(ks, q) == 0) \
108 i->k = IsIntegerTerm(t) ? IntegerOfTerm(t) : 0; \
109 return IsIntegerTerm(t); \
112#define set_key_s(k, ks, q, i, t) \
113 if (strcmp(ks, q) == 0) \
115 const char *s = IsAtomTerm(t) ? RepAtom(AtomOfTerm(t))->StrOfAE \
116 : IsStringTerm(t) ? StringOfTerm(t) : NULL; \
119 char *tmp = calloc(1, strlen(s) + 1); \
123 return i->k != NULL; \
126#define set_key_t(k, ks, q, i, t) \
127 if (strcmp(ks, q) == 0) \
129 i->k = Yap_SaveTerm(t); \
135 set_key_i(errorNo,
"errorNo", q, i, t);
136 set_key_i(errorClass,
"errorClass", q, i, t);
137 set_key_s(errorAsText,
"errorAsText", q, i, t);
138 set_key_s(classAsText,
"classAsText", q, i, t);
139 set_key_i(errorLine,
"errorLine", q, i, t);
140 set_key_s(errorFunction,
"errorFunction", q, i, t);
141 set_key_s(errorFile,
"errorFile", q, i, t);
142 set_key_i(prologPredLine,
"prologPredLine", q, i, t);
143 set_key_s(prologPredName,
"prologPredName", q, i, t);
144 set_key_i(prologPredArity,
"prologPredArity", q, i, t);
145 set_key_s(prologPredModule,
"prologPredModule", q, i, t);
146 set_key_s(prologPredFile,
"prologPredFile", q, i, t);
147 set_key_i(parserPos,
"parserPos", q, i, t);
148 set_key_i(parserLine,
"parserLine", q, i, t);
149 set_key_i(parserFirstLine,
"parserFirstLine", q, i, t);
150 set_key_i(parserLastLine,
"parserLastLine", q, i, t);
151 set_key_s(parserTextA,
"parserTextA", q, i, t);
152 set_key_i(parserTextB,
"parserTextB", q, i, t);
153 set_key_s(parserFile,
"parserFile", q, i, t);
154 set_key_b(parserReadingCode,
"parserReadingcode", q, i, t);
155 set_key_b(prologConsulting,
"prologConsulting", q, i, t);
156 set_key_s(culprit,
"culprit", q, i, t);
158 set_key_s(prologStack,
"prologStack", q, i, t);
159 set_key_s(errorMsg,
"errorMsg", q, i, t);
163#define query_key_b(k, ks, q, i) \
164 if (strcmp(ks, q) == 0) \
166 return i->k ? TermTrue : TermFalse; \
169#define query_key_i(k, ks, q, i) \
170 if (strcmp(ks, q) == 0) \
172 return MkIntegerTerm(i->k); \
175#define query_key_s(k, ks, q, i) \
176 if (strcmp(ks, q) == 0) \
178 if (i->k && i->k[0] != '\0') \
179 return MkAtomTerm(Yap_LookupAtom(i->k)); \
181 return TermEmptyAtom; \
184#define query_key_t(k, ks, q, i) \
185 if (strcmp(ks, q) == 0) \
188 if ((t = i->k) == 0) \
195 query_key_i(errorNo,
"errorNo", q, i);
196 query_key_i(errorClass,
"errorClass", q, i);
197 query_key_s(errorAsText,
"errorAsText", q, i);
198 query_key_s(classAsText,
"classAsText", q, i);
199 query_key_i(errorLine,
"errorLine", q, i);
200 query_key_s(errorFunction,
"errorFunction", q, i);
201 query_key_s(errorFile,
"errorFile", q, i);
202 query_key_i(prologPredLine,
"prologPredLine", q, i);
203 query_key_s(prologPredName,
"prologPredName", q, i);
204 query_key_i(prologPredArity,
"prologPredArity", q, i);
205 query_key_s(prologPredModule,
"prologPredModule", q, i);
206 query_key_s(prologPredFile,
"prologPredFile", q, i);
207 query_key_i(parserLine,
"parserLine", q, i);
208 query_key_i(parserFirstLine,
"parserFirstLine", q, i);
209 query_key_i(parserLastLine,
"parserLastLine", q, i);
210 query_key_s(parserTextA,
"parserTextA", q, i);
211 query_key_i(parserTextB,
"parserTextB", q, i);
212 query_key_s(parserFile,
"parserFile", q, i);
213 query_key_b(parserReadingCode,
"parserReadingCode", q, i);
214 query_key_b(prologConsulting,
"prologConsulting", q, i);
215 query_key_s(prologStack,
"prologStack", q, i);
216 query_key_s(culprit,
"culprit", q, i);
217 query_key_s(errorMsg,
"errorMsg", q, i);
221static void print_key_b(FILE *of,
const char *key,
bool v)
223 const char *b = v ?
"true" :
"false";
224 fprintf(of,
"%s: %s\n", key, b);
227static void print_key_i(FILE *of,
const char *key, YAP_Int v)
229 fprintf(of,
"%s: " Int_FORMAT
"\n", key, v);
232static void print_key_s(FILE *of,
const char *key,
const char *v)
235 fprintf(of,
"%s: %s\n", key, v);
238static void print_key_t(FILE *of,
const char *key, YAP_Term v)
241 fprintf(of,
"%s: %s\n", key, Yap_TermToBuffer(v, Quote_illegal_f | Ignore_ops_f | Handle_cyclics_f));
247 if (i->errorNo == YAP_NO_ERROR)
251 print_key_s(out,
"errorAsText", (i->errorAsText ? i->errorAsText : Yap_errorName(i->errorNo) ));
252 print_key_s(out,
"classAsText",
253 (i->classAsText ? i->classAsText: Yap_errorClassName(i->errorClass)));
254 print_key_i(out,
"parserPos", i->parserPos);
255 print_key_i(out,
"parserLine", i->parserLine);
256 print_key_i(out,
"parserFirstLine", i->parserFirstLine);
257 print_key_i(out,
"parserLastLine", i->parserLastLine);
258 print_key_s(out,
"parserTextA", i->parserTextA);
259 print_key_i(out,
"parserTextB", i->parserTextB);
260 print_key_s(out,
"parserFile", i->parserFile);
261 print_key_i(out,
"errorNo", i->errorNo);
262 print_key_s(out,
"errorClass", (i->classAsText ? i->classAsText: Yap_errorClassName(i->errorClass)));
263 print_key_i(out,
"errorLine", i->errorLine);
264 print_key_s(out,
"errorFunction", i->errorFunction);
265 print_key_s(out,
"errorFile", i->errorFile);
266 print_key_i(out,
"prologPredLine", i->prologPredLine);
267 print_key_s(out,
"prologPredName", i->prologPredName);
268 print_key_i(out,
"prologPredArity", i->prologPredArity);
269 print_key_s(out,
"prologPredModule", i->prologPredModule);
270 print_key_s(out,
"prologPredFile", i->prologPredFile);
271 print_key_b(out,
"parserReadingCode", i->parserReadingCode);
272 print_key_b(out,
"prologConsulting", i->prologConsulting);
273 print_key_s(out,
"culprit", i->culprit);
274 print_key_s(out,
"prologStack", i->prologStack);
275 print_key_t(out,
"errorUserterm", i->errorUserTerm);
276 print_key_s(out,
"errorMsg", i->errorMsg);
277 print_key_i(out,
"errorMsgLen", i->errorMsgLen);
280static YAP_Term add_key_b(
const char *key,
bool v, YAP_Term o0)
283 tkv[1] = v ? TermTrue : TermFalse;
284 tkv[0] = MkAtomTerm(Yap_LookupAtom(key));
285 Term node = Yap_MkApplTerm(FunctorEq, 2, tkv);
286 return MkPairTerm(node, o0);
289static YAP_Term add_key_i(
const char *key, YAP_Int v, YAP_Term o0)
292 tkv[1] = MkIntegerTerm(v), tkv[0] = MkAtomTerm(Yap_LookupAtom(key));
293 Term node = Yap_MkApplTerm(FunctorEq, 2, tkv);
294 return MkPairTerm(node, o0);
297static YAP_Term add_key_s(
const char *key,
const char *v, YAP_Term o0)
300 if (!v || v[0]==
'\0')
303 tkv[1] = MkStringTerm(v);
304 tkv[0] = MkAtomTerm(Yap_LookupAtom(key));
305 Term node = Yap_MkApplTerm(FunctorEq, 2, tkv);
306 return MkPairTerm(node, o0);
309static YAP_Term add_key_t(
const char *key, YAP_Term v, YAP_Term o0)
319 if (i->errorNo == YAP_NO_ERROR)
323 o = add_key_i(
"errorNo", i->errorNo, o);
324 o = add_key_i(
"errorClass", i->errorClass, o);
325 o = add_key_s(
"errorAsText", i->errorAsText, o);
326 o = add_key_s(
"classAsText", i->classAsText, o);
327 o = add_key_i(
"errorLine", i->errorLine, o);
328 o = add_key_s(
"errorFunction", i->errorFunction, o);
329 o = add_key_s(
"errorFile", i->errorFile, o);
330 o = add_key_i(
"prologPredLine", i->prologPredLine, o);
331 o = add_key_s(
"prologPredName", i->prologPredName, o);
332 o = add_key_i(
"prologPredArity", i->prologPredArity, o);
333 o = add_key_s(
"prologPredModule", i->prologPredModule, o);
334 o = add_key_s(
"prologPredFile", i->prologPredFile, o);
335 o = add_key_i(
"parserPos", i->parserPos, o);
336 o = add_key_i(
"parserLine", i->parserLine, o);
337 o = add_key_i(
"parserFirstLine", i->parserFirstLine, o);
338 o = add_key_i(
"parserLastLine", i->parserLastLine, o);
339 o = add_key_s(
"parserTextA", i->parserTextA, o);
340 o = add_key_i(
"parserTextB", i->parserTextB, o);
341 o = add_key_s(
"parserFile", i->parserFile, o);
342 o = add_key_b(
"parserReadingCode", i->parserReadingCode, o);
343 o = add_key_b(
"prologConsulting", i->prologConsulting, o);
344 o = add_key_s(
"culprit", i->culprit, o);
345 o = add_key_s(
"prologStack", i->prologStack, o);
346 o = add_key_t(
"errorUserterm", i->errorUserTerm, o);
347 o = add_key_s(
"errorMsg", i->errorMsg, o);
351void Yap_do_warning__(
const char *file,
const char *
function,
int line,
352 yap_error_number type, Term t, ...)
355 char tmpbuf[PATH_MAX];
363 p = RepPredProp(PredPropByFunc(FunctorPrintMessage,
370 fmt = va_arg(ap,
char *);
374 vsnprintf(tmpbuf, PATH_MAX - 1, fmt, ap);
376 (void)vsprintf(tmpbuf, fmt, ap);
379 ts[1] = MkAtomTerm(AtomWarning);
380 ts[0] = MkAtomTerm(Yap_LookupAtom(tmpbuf));
381 Yap_execute_pred(p, ts,
true PASS_REGS);
382 LOCAL_PrologMode &= ~InErrorMode;
387bool Yap_Warning(
const char *s, ...)
395 char tmpbuf[PATH_MAX];
396 yap_error_number err;
398 if (LOCAL_DoingUndefp)
400 LOCAL_DoingUndefp =
true;
402 if (LOCAL_PrologMode & InErrorMode && (err = LOCAL_ActiveError->errorNo))
404 fprintf(stderr,
"%% Warning %s WITHIN ERROR %s %s\n", s,
405 LOCAL_ActiveError->classAsText,
406 LOCAL_ActiveError->errorAsText);
410 LOCAL_PrologMode |= InErrorMode;
411 pred = RepPredProp(PredPropByFunc(FunctorPrintMessage,
414 fmt = va_arg(ap,
char *);
418 vsnprintf(tmpbuf, PATH_MAX - 1, fmt, ap);
420 (void)vsprintf(tmpbuf, fmt, ap);
425 LOCAL_DoingUndefp =
false;
426 LOCAL_PrologMode &= ~InErrorMode;
430 if (pred->OpcodeOfPred == UNDEF_OPCODE || pred->OpcodeOfPred == FAIL_OPCODE)
432 fprintf(stderr,
"warning message: %s\n", tmpbuf);
433 LOCAL_DoingUndefp =
false;
434 LOCAL_PrologMode &= ~InErrorMode;
438 ts[1] = MkAtomTerm(AtomWarning);
439 ts[0] = MkAtomTerm(Yap_LookupAtom(tmpbuf));
440 rc = Yap_execute_pred(pred, ts,
true PASS_REGS);
441 LOCAL_PrologMode &= ~InErrorMode;
445void Yap_InitError__(
const char *file,
const char *
function,
int lineno,
446 yap_error_number e, Term t, ...)
454 fmt = va_arg(ap,
char *);
457 tmpbuf = malloc(PATH_MAX);
459 vsnprintf(tmpbuf, PATH_MAX - 1, fmt, ap);
461 (void)vsprintf(tmpbuf, fmt, ap);
467 if (LOCAL_ActiveError->errorNo != YAP_NO_ERROR)
469 yap_error_number err = LOCAL_ActiveError->errorNo;
470 fprintf(stderr,
"%% Warning %s WITHIN ERRORR\n", Yap_errorName(err));
473 LOCAL_ActiveError->errorNo = e;
474 LOCAL_ActiveError->errorFile = NULL;
475 LOCAL_ActiveError->errorFunction = NULL;
476 LOCAL_ActiveError->errorLine = 0;
477 if (fmt && fmt[0] && tmpbuf)
479 LOCAL_ActiveError->errorMsg = malloc(strlen(tmpbuf) + 1);
480 strcpy((
char *)LOCAL_ActiveError->errorMsg, tmpbuf);
483 { LOCAL_ActiveError->errorMsg = NULL;
488bool Yap_PrintWarning(Term twarning)
491 if (LOCAL_DoingUndefp)
497 PredEntry *pred = RepPredProp(PredPropByFunc(
498 FunctorPrintMessage, PROLOG_MODULE));
500 __android_log_print(ANDROID_LOG_INFO,
"YAPDroid ",
" warning(%s)",
501 Yap_TermToBuffer(twarning, Quote_illegal_f |
506 if (pred->OpcodeOfPred == UNDEF_OPCODE || pred->OpcodeOfPred == FAIL_OPCODE)
508 fprintf(stderr,
"%s:%ld/* d:%d warning */:\n", LOCAL_ActiveError->errorFile,
509 LOCAL_ActiveError->errorLine, 0);
512 ARG1 = MkAtomTerm(AtomWarning);
513 LOCAL_PrologMode &= ~InErrorMode;
514 rc = Yap_execute_pred(pred, NULL,
true PASS_REGS);
515 LOCAL_within_print_message =
false;
519bool Yap_HandleError__(
const char *file,
const char *
function,
int lineno,
523 yap_error_number err = LOCAL_Error_TYPE;
526 if (LOCAL_ErrorMessage)
528 serr = LOCAL_ErrorMessage;
536 case RESOURCE_ERROR_STACK:
537 if (!Yap_dogc(PASS_REGS1))
539 Yap_Error__(
false, file,
function, lineno, RESOURCE_ERROR_STACK, ARG1,
543 LOCAL_PrologMode = UserMode;
545 case RESOURCE_ERROR_AUXILIARY_STACK:
546 if (LOCAL_MAX_SIZE < (
char *)AuxSp - AuxBase)
548 LOCAL_MAX_SIZE += 1024;
550 if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE))
553 Yap_Error__(
false, file,
function, lineno, RESOURCE_ERROR_AUXILIARY_STACK,
557 LOCAL_PrologMode = UserMode;
559 case RESOURCE_ERROR_HEAP:
560 if (!Yap_growheap(FALSE, 0, NULL))
562 Yap_Error__(
false, file,
function, lineno, RESOURCE_ERROR_HEAP, ARG2,
568 if (LOCAL_PrologMode == UserMode)
573 LOCAL_PrologMode &= ~InErrorMode;
578int Yap_SWIHandleError(
const char *s, ...)
581 yap_error_number err = LOCAL_Error_TYPE;
590 case RESOURCE_ERROR_STACK:
591 if (!Yap_dogc(PASS_REGS1))
593 Yap_Error(RESOURCE_ERROR_STACK, TermNil, serr);
597 case RESOURCE_ERROR_AUXILIARY_STACK:
598 if (LOCAL_MAX_SIZE < (
char *)AuxSp - AuxBase)
600 LOCAL_MAX_SIZE += 1024;
602 if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE))
605 Yap_Error(RESOURCE_ERROR_AUXILIARY_STACK, ARG1, serr);
609 case RESOURCE_ERROR_HEAP:
610 if (!Yap_growheap(
false, 0, NULL))
612 Yap_Error(RESOURCE_ERROR_HEAP, ARG2, serr);
616 Yap_Error(err, TermNil, serr);
621static void error_exit_yap(
int value)
624 if (!(LOCAL_PrologMode & BootMode))
630 fprintf(stderr,
"\n Exiting ....\n");
632 void *callstack = malloc(64 * K);
634 int frames = backtrace(callstack, 64 * K - 1);
635 char **strs = backtrace_symbols(callstack, frames);
636 fprintf(stderr,
"%% C-Execution stack:\n");
637 for (i = 0; i < frames; ++i)
639 fprintf(stderr,
"%% %s\n", strs[i]);
648#define YAP_BUF_SIZE 512
650static char tmpbuf[YAP_BUF_SIZE];
659#undef BEGIN_ERROR_CLASSES
661#undef END_ERROR_CLASSES
669#define BEGIN_ERROR_CLASSES() \
670 static Atom mkerrorct(yap_error_class_number c) \
675#define ECLASS(CL, A, B) \
677 return Yap_LookupAtom(A);
679#define END_ERROR_CLASSES() \
684#define BEGIN_ERRORS() \
685 static Term mkerrort(yap_error_number e, Term culprit, Term info) \
687 if (!e) e= USER_DEFINED_ERROR; \
688 if (!info) info = TermNil; \
696 ft[0] = MkAtomTerm(Yap_LookupAtom(C "_error")); \
698 return Yap_MkApplTerm(FunctorError, 2, ft); \
705 nt[0] = MkAtomTerm(Yap_LookupAtom(C)); \
706 nt[1] = MkVarTerm(); \
707 if (culprit) Yap_unify(nt[1], culprit); \
708 ft[0] = Yap_MkApplTerm(Yap_MkFunctor(mkerrorct(B), 2), 2, nt); \
710 return Yap_MkApplTerm(FunctorError, 2, ft); \
717 nt[0] = MkVarTerm(); \
718 if (culprit) Yap_unify(nt[0], culprit); \
719 ft[0] = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom(C), 1), 1, nt); \
721 return Yap_MkApplTerm(FunctorError, 2, ft); \
724#define E2(A, B, C, D) \
728 nt[0] = MkAtomTerm(Yap_LookupAtom(C)); \
729 nt[1] = MkAtomTerm(Yap_LookupAtom(D)); \
730 nt[2] = MkVarTerm(); \
731 if (culprit) Yap_unify(nt[2], culprit); \
732 ft[0] = Yap_MkApplTerm(Yap_MkFunctor(mkerrorct(B), 3), 3, nt); \
734 return Yap_MkApplTerm(FunctorError, 2, ft); \
737#define END_ERRORS() \
751 new_error->top_error = LOCAL_ActiveError;
752 LOCAL_ActiveError = new_error;
766 *ep = LOCAL_ActiveError->top_error;
768 LOCAL_ActiveError = ep;
769 if (e->
errorNo && !ep->errorNo && pass)
772 memmove(ep, e,
sizeof(*e));
790 yap_error_number type, Term where,
const char *msg, ...)
793 char tmpbuf[PATH_MAX];
795 if ( LOCAL_ActiveError->errorNo)
798 fprintf(stderr,
"%s:%d:0 %s() caused a %s while processing error or warning!!!!!\n\n", file, lineno,
function, Yap_errorName(type));
803 LOCAL_ActiveError->errorUserTerm = 0 ;
808 (void)vsnprintf(tmpbuf, PATH_MAX - 1, msg, ap);
810 (void)vsprintf(tmpbuf, mag, ap);
819 Yap_Error__(
true, file,
function, lineno, type, where, tmpbuf);
822 Yap_ThrowExistingError();
828void Yap_ThrowExistingError(
void)
830 if (LOCAL_RestartEnv ||
831 IsNonVarTerm(Yap_GetGlobal(AtomZip)))
843 Term et = MkAddressTerm(i);
844 return Yap_MkApplTerm(FunctorException, 1, &et);
856 i = (Yap_local.ActiveError);
858 memset(i,0,
sizeof(*Yap_local.ActiveError));
859 if (i->errorNo != USER_DEFINED_ERROR) {
860 i->errorAsText = Yap_errorName(i->errorNo);
861 i->errorClass = Yap_errorClass(i->errorNo);
862 i->classAsText = Yap_errorClassName(i->errorClass);
864 Term culprit = TermNil;
867 culprit = i->culprit_t;
868 else if (i->culprit_t)
869 culprit = Yap_BufferToTerm(i->culprit, TermNil);
870 else if (i->errorMsg)
871 culprit = MkStringTerm(i->errorMsg);
873 return mkerrort(i->errorNo, culprit,
MkSysError(i));
883 const char *
function,
int lineno, yap_error_number type,
884 Term where,
const char *s)
886 if (!Yap_pc_add_location(r, P, B, ENV))
887 Yap_env_add_location(r, CP, B, ENV, 0);
890 r->culprit_t = TermNone;
895 r->culprit_t = Yap_SaveTerm(where);
896 r->culprit = Yap_TermToBuffer(where, Quote_illegal_f | Handle_vars_f | Handle_cyclics_f);
898 if (type != SYNTAX_ERROR && LOCAL_consult_level > 0)
900 r->parserFile = Yap_ConsultingFile(PASS_REGS1)->StrOfAE;
901 r->parserLine = Yap_source_line_no();
904 r->parserFile = NULL;
916 LOCAL_PrologMode |= InErrorMode;
921 sprintf(LOCAL_FileNameBuf,
"%s:%d in C-function %s ", file, lineno,
923 tf = MkAtomTerm(Yap_LookupAtom(LOCAL_FileNameBuf));
925 if (Yap_heap_regs && !(LOCAL_PrologMode & BootMode))
926 fprintf(stderr,
"***** Processing Error %d (%lx,%x) %s***\n", type,
927 (
unsigned long int)LOCAL_Signals, LOCAL_PrologMode, fmt);
929 fprintf(stderr,
"***** Processing Error %d (%x) %s***\n", type,
930 LOCAL_PrologMode, fmt);
933 if (r->
errorNo == SYNTAX_ERROR)
937 else if (r->
errorNo == SYNTAX_ERROR_NUMBER)
942 if (type == INTERRUPT_EVENT)
944 fprintf(stderr,
"%% YAP exiting: cannot handle signal %d\n",
945 (
int)IntOfTerm(where));
951 ns = malloc(strlen(s)+1);
982 int lineno, yap_error_number type, Term where, ...)
991 case SYSTEM_ERROR_INTERNAL:
993 fprintf(stderr,
"%% Internal YAP Error: %s exiting....\n", tmpbuf);
994 if (LOCAL_PrologMode & BootMode)
996 fprintf(stderr,
"%% YAP crashed while booting %s\n", tmpbuf);
1002 fprintf(stderr,
"%% Bug found while executing %s\n", tmpbuf);
1005 void *callstack[256];
1007 int frames = backtrace(callstack, 256);
1008 char **strs = backtrace_symbols(callstack, frames);
1009 fprintf(stderr,
"Execution stack:\n");
1010 for (i = 0; i < frames; ++i)
1012 fprintf(stderr,
" %s\n", strs[i]);
1019 case SYSTEM_ERROR_FATAL:
1021 fprintf(stderr,
"%% Fatal YAP Error: %s exiting....\n", tmpbuf);
1024 case INTERRUPT_EVENT:
1028 case USER_DEFINED_EVENT:
1031 LOCAL_ActiveError->errorUserTerm = TermNil;
1038 LOCAL_ActiveError->errorNo = ABORT_EVENT;
1040 LOCAL_PrologMode &= ~InErrorMode;
1043 case CALL_COUNTER_UNDERFLOW_EVENT:
1045 LOCAL_ReductionsCounterOn = FALSE;
1046 LOCAL_PredEntriesCounterOn = FALSE;
1047 LOCAL_RetriesCounterOn = FALSE;
1048 LOCAL_ActiveError->errorNo = CALL_COUNTER_UNDERFLOW_EVENT;
1051 LOCAL_PrologMode &= ~InErrorMode;
1053 case PRED_ENTRY_COUNTER_UNDERFLOW_EVENT:
1055 LOCAL_ReductionsCounterOn = FALSE;
1056 LOCAL_PredEntriesCounterOn = FALSE;
1057 LOCAL_RetriesCounterOn = FALSE;
1058 LOCAL_ActiveError->errorNo = PRED_ENTRY_COUNTER_UNDERFLOW_EVENT;
1061 LOCAL_PrologMode &= ~InErrorMode;
1063 case RETRY_COUNTER_UNDERFLOW_EVENT:
1065 LOCAL_ReductionsCounterOn = FALSE;
1066 LOCAL_PredEntriesCounterOn = FALSE;
1067 LOCAL_RetriesCounterOn = FALSE;
1068 LOCAL_ActiveError->errorNo = RETRY_COUNTER_UNDERFLOW_EVENT;
1071 LOCAL_PrologMode &= ~InErrorMode;
1074 va_start(ap, where);
1075 fmt = va_arg(ap,
char *);
1078 s = malloc(PATH_MAX);
1080 (void)vsnprintf(s, PATH_MAX - 1, fmt, ap);
1082 (void)vsprintf(s, fmt, ap);
1089 if (P == (
yamop *)(FAILCODE))
1091 LOCAL_PrologMode &= ~InErrorMode;
1096 if (type == ABORT_EVENT || LOCAL_PrologMode & BootMode)
1098 LOCAL_PrologMode &= ~AbortMode;
1099 LOCAL_PrologMode &= ~InErrorMode;
1102 if (LOCAL_PrologMode & AsyncIntMode)
1103 Yap_signal(YAP_FAIL_SIGNAL);
1109 LOCAL_PrologMode &= ~AbortMode;
1110 LOCAL_PrologMode |= InErrorMode;
1117 if (LOCAL_ActiveError->errorNo != SYNTAX_ERROR &&
1118 trueLocalPrologFlag(STACK_DUMP_ON_ERROR_FLAG) )
1119 LOCAL_ActiveError->prologStack = Yap_dump_stack();
1121 LOCAL_ActiveError->prologStack = NULL;
1123 CalculateStackGap(PASS_REGS1);
1131 if (LOCAL_DoingUndefp)
1133 LOCAL_DoingUndefp =
false;
1139 if (!LOCAL_ActiveError) {
1144 pop_text_stack(LOCAL_MallocDepth + 1);
1147 LOCAL_Error_TYPE = type;
1150 LOCAL_Error_TYPE = YAP_NO_ERROR;
1151 LOCAL_ActiveError->culprit = NULL;
1156 LOCAL_PrologMode = UserMode;
1161static Int close_error(USES_REGS1)
1163 if (!LOCAL_CommittedError)
1165 LOCAL_CommittedError->errorNo = YAP_NO_ERROR;
1167 LOCAL_ErrorMessage = NULL;
1168 free(LOCAL_CommittedError);
1169 LOCAL_CommittedError = NULL;
1173#undef BEGIN_ERROR_CLASSES
1175#undef END_ERROR_CLASSES
1183#define BEGIN_ERROR_CLASSES() typedef enum aux_class \
1186#define ECLASS(CL, A, B) CL##__,
1188#define END_ERROR_CLASSES() \
1192#define BEGIN_ERRORS()
1196#define E2(X, Y, Z, W)
1201#undef BEGIN_ERROR_CLASSES
1203#undef END_ERROR_CLASSES
1211#define BEGIN_ERROR_CLASSES() static const char *c_error_class_name[] = {
1213#define ECLASS(CL, A, B) A,
1215#define END_ERROR_CLASSES() \
1226#define BEGIN_ERRORS() static struct c_error_info c_error_list[] = {
1227#define E0(X, Y, Z) {X, Y##__, Z},
1228#define E(X, Y, Z) {X, Y##__, Z},
1229#define E1(X, Y, Z) {X, Y##__, Z},
1230#define E2(X, Y, Z, W) {X, Y##__, Z " " W},
1231#define END_ERRORS() \
1233 0, YAPC_NO_ERROR, "" \
1241yap_error_class_number Yap_errorClass(yap_error_number e)
1243 return c_error_list[e].class;
1246yap_error_class_number Yap_errorClassNumber(
const char *s)
1249 while (c_error_class_name[i] &&
1250 strcmp(c_error_class_name[i], s) != 0)
1254 if (!c_error_class_name[i])
1255 return USER_DEFINED_ERROR_CLASS;
1258char *Yap_errorClassName(yap_error_class_number e)
1260 return (
char *)c_error_class_name[e];
1268 t = LOCAL_ActiveError;
1270 if (t->errorUserTerm)
1271 return t->errorUserTerm;
1278 Term tc = t->culprit_t ? t->culprit_t :
1279 t->culprit ? Yap_BufferToTerm(t->culprit, TermNil) : TermNone;
1280 if (IsVarTerm(tc)) tc=TermNil;
1282 if (t->errorNo == USER_DEFINED_ERROR) {
1285 ft[1] = err2list(t);
1286 o = Yap_MkApplTerm(FunctorError, 2, ft);
1288 o = mkerrort(t->errorNo, tc, err2list(t));
1300 i = LOCAL_ActiveError;
1301 if (!IsApplTerm(t) || FunctorOfTerm(t) != FunctorError)
1303 i->errorUserTerm = Yap_SaveTerm(t);
1304 i->errorNo = THROW_EVENT;
1306 if (IsApplTerm(t) && FunctorOfTerm(t) == FunctorError) {
1307 Term t1 = ArgOfTerm(1, t);
1308 i->errorClass = USER_DEFINED_ERROR_CLASS;
1309 i->errorNo = USER_DEFINED_ERROR;
1310 if (IsAtomTerm(t1)) {
1311 i->classAsText = i->errorAsText = RepAtom(AtomOfTerm(t1))->StrOfAE;
1312 i->errorClass = Yap_errorClassNumber(i->classAsText);
1313 if (i->errorClass == INSTANTIATION_ERROR_CLASS)
1314 i->errorNo = INSTANTIATION_ERROR;
1315 }
else if (IsApplTerm(t1)) {
1317 Functor f = FunctorOfTerm(t1);
1318 arity_t a = ArityOfFunctor(f);
1319 i->classAsText = RepAtom(NameOfFunctor(f))->StrOfAE;
1320 i->errorClass = Yap_errorClassNumber(i->classAsText);
1321 Term t11 = ArgOfTerm(1, t1);
1322 if (IsAtomTerm(t11)) {
1323 i->errorAsText = RepAtom(AtomOfTerm(t11))->StrOfAE;
1327 s1 = i->errorAsText;
1329 i->errorAsText = i->classAsText;
1330 }
else if (a == 3) {
1331 Term t12 = ArgOfTerm(2, t1);
1332 if (IsAtomTerm(t12)) {
1333 s2 = RepAtom(AtomOfTerm(t12))->StrOfAE;
1334 char *buf = i->errorAsText = malloc(strlen(s1) + strlen(s2) + 2);
1341 }
else if (IsAtomTerm(t11)) {
1380 if (LOCAL_ActiveError->errorNo)
1381 return LOCAL_ActiveError;
1403 FILE *of = GLOBAL_Stream[LOCAL_c_output_stream].file ? GLOBAL_Stream[LOCAL_c_output_stream].file : stderr;
1404 printErr(LOCAL_ActiveError, of);
1412 if (LOCAL_ActiveError->errorNo) {
1429 i = LOCAL_ActiveError;
1431 LOCAL_PrologMode &= ~InErrorMode;
1442 LOCAL_PrologMode |= InErrorMode;
1446static Int read_exception(USES_REGS1)
1451 Term rc = err2list(t);
1453 return Yap_unify(ARG2, rc);
1456static Int print_exception(USES_REGS1)
1458 Term t1 = Deref(ARG1);
1459 if (IsAddressTerm(t1))
1461 FILE *of = GLOBAL_Stream[LOCAL_c_error_stream].file ? GLOBAL_Stream[LOCAL_c_error_stream].file : stderr;
1463 if (t->parserFile && t->parserLine)
1465 fprintf(of,
"\n%s:%ld:0 error: while parsing %s\n\n", t->parserFile,
1466 t->parserLine, t->errorAsText);
1468 else if (t->prologPredFile && t->prologPredLine)
1470 fprintf(of,
"\n%s:%ld:0 error: while running %s\n\n",
1471 t->prologPredFile, t->prologPredLine, t->errorAsText);
1473 else if (t->errorFile && t->errorLine)
1475 fprintf(of,
"\n%s:%ld:0 error: while executing %s\n\n", t->errorFile,
1476 t->errorLine, t->errorAsText);
1482 return Yap_WriteTerm(LOCAL_c_error_stream, t1, TermNil PASS_REGS);
1488static Int query_exception(USES_REGS1)
1490 const char *query = NULL;
1493 if (IsAtomTerm((t = Deref(ARG1))))
1494 query = RepAtom(AtomOfTerm(t))->StrOfAE;
1495 if (IsStringTerm(t))
1496 query = StringOfTerm(t);
1497 if (!IsAddressTerm(Deref(ARG2)))
1501 Term rc = queryErr(query, y);
1503 return Yap_unify(ARG3, rc);
1509static Int set_exception(USES_REGS1)
1511 const char *query = NULL;
1514 if (IsAtomTerm((t = Deref(ARG1))))
1515 query = RepAtom(AtomOfTerm(t))->StrOfAE;
1516 if (IsStringTerm(t))
1517 query = StringOfTerm(t);
1518 if (!IsAddressTerm(Deref(ARG1)))
1521 Term t3 = Deref(ARG3);
1528 return setErr(query, y, t3);
1533drop_exception(USES_REGS1)
1537 if (LOCAL_Error_TYPE) {
1538 if ( LOCAL_ActiveError->errorNo != USER_DEFINED_ERROR &&
1539 LOCAL_ActiveError->errorUserTerm) {
1540 rc = Yap_unify(LOCAL_ActiveError->errorUserTerm, ARG1);
1541 }
else { tn = MkErrorTerm(LOCAL_ActiveError);
1543 rc = Yap_unify(tn, ARG1);
1546 memset(LOCAL_ActiveError, 0,
sizeof(*LOCAL_ActiveError));
1548 LOCAL_PrologMode &= ~InErrorMode;
1552static Int new_exception(USES_REGS1)
1555 return Yap_unify(ARG1, t);
1558bool Yap_get_exception(USES_REGS1)
1560 Term tn = Yap_GetGlobal(AtomZip);
1561 if (!IsVarTerm(tn) && tn != TermNil)
1574 while (c_error_list[i].name)
1576 if (c_error_list[i].
class == USER_DEFINED_ERROR_CLASS)
1578 return USER_DEFINED_ERROR;
1579 if (c_error_list[i].
class != c)
1585 if (strcmp(c_error_list[i].name, s) == 0)
1593char *Yap_errorName(yap_error_number e) {
if (e != USER_DEFINED_ERROR)
1594 return (
char*)c_error_list[e].name;
1599 i->errorNo = ERROR_EVENT;
1600 i->errorClass = EVENT;
1614Int is_nonvar__(
const char *file,
const char *
function,
int lineno, Term t USES_REGS)
1619 Yap_ThrowError(INSTANTIATION_ERROR, t, NULL);
1622 return t == TermTrue || t == TermFalse;
1631static Int is_nonvar1(USES_REGS1)
1633 Term t = Deref(ARG1);
1634 return is_nonvar__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1637bool is_boolean__(
const char *file,
const char *
function,
int lineno, Term t USES_REGS)
1645 return t == TermTrue || t == TermFalse;
1648static Int is_boolean1(USES_REGS1)
1650 Term t = Deref(ARG1);
1651 return is_boolean__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1654bool must_be_boolean__(
const char *file,
const char *
function,
int lineno, Term t USES_REGS)
1662 if ( t == TermTrue || t == TermFalse )
1671static Int must_be_boolean1(USES_REGS1)
1673 Term t = Deref(ARG1);
1674 return must_be_boolean__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1678bool is_atom__(
const char *file,
const char *
function,
int lineno, Term t USES_REGS)
1686 return IsAtomTerm(t);
1689static Int is_atom1( USES_REGS1 )
1691 Term t = Deref(ARG1);
1692 return is_atom__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1696bool must_be_atom__(
const char *file,
const char *
function,
int lineno, Term t USES_REGS)
1712static Int must_be_atom1( USES_REGS1 )
1714 Term t = Deref(ARG1);
1715 return must_be_atom__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1724bool is_list__(
const char *file,
const char *
function,
int lineno, Term list USES_REGS)
1728 Int n = Yap_SkipList(&list, &tailp);
1729 if (IsVarTerm(*tailp))
1731 if (*tailp != TermNil || n < 0)
1738static Int is_list1( USES_REGS1 )
1740 Term t = Deref(ARG1);
1741 return is_list__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1744bool must_be_list__(
const char *file,
const char *
function,
int lineno, Term list USES_REGS)
1748 Int n = Yap_SkipList(&list, &tailp);
1749 if (IsVarTerm(*tailp))
1751 if (*tailp != TermNil || n < 0)
1758static Int must_be_list1( USES_REGS1 )
1760 Term t = Deref(ARG1);
1761 return must_be_list__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1771Int callable(USES_REGS1)
1773 Term t = Deref(ARG1);
1779 Term mod = CurrentModule;
1782 Term G = Yap_StripModule(Deref(ARG1), &mod);
1788 else if (!IsAtomTerm(mod))
1799 if (IsExtensionFunctor(f))
1808 else if (IsPairTerm(G) || IsAtomTerm(G))
1825bool is_callable__(
const char *file,
const char *
function,
int lineno, Term t USES_REGS)
1833 Term mod = CurrentModule;
1836 Term G = Yap_StripModule(Deref(ARG1), &mod);
1843 else if (!IsAtomTerm(mod))
1855 if (IsExtensionFunctor(f))
1864 else if (IsPairTerm(G) || IsAtomTerm(G))
1874static Int is_callable1( USES_REGS1 )
1876 Term t = Deref(ARG1);
1877 return is_callable__(__FILE__,__FUNCTION__,__LINE__,t PASS_REGS);
1880bool Yap_callable(Term t)
1882 Term mod = CurrentModule;
1885 Term G = Yap_StripModule(Deref(t), &mod);
1890 else if (!IsAtomTerm(mod))
1901 if (IsExtensionFunctor(f))
1910 else if (IsPairTerm(G) || IsAtomTerm(G))
1925static Int must_be_callable1(USES_REGS1)
1927 Term mod = CurrentModule;
1930 Term G = Yap_StripModule(Deref(ARG1), &mod);
1934 Yap_ThrowError(INSTANTIATION_ERROR, G, NULL);
1937 else if (!IsAtomTerm(mod))
1939 Yap_ThrowError(TYPE_ERROR_ATOM, mod, NULL);
1944 Yap_ThrowError(INSTANTIATION_ERROR, G, NULL);
1950 if (IsExtensionFunctor(f))
1952 Yap_ThrowError(TYPE_ERROR_CALLABLE, G, NULL);
1959 else if (IsPairTerm(G) || IsAtomTerm(G))
1965 Yap_ThrowError(TYPE_ERROR_CALLABLE, G, NULL);
1981 Yap_ThrowError(INSTANTIATION_ERROR, t,
"");
1983 if (t == TermNil || IsPairTerm(t))
1987 Yap_ThrowError(TYPE_ERROR_LIST, t,
"");
1994static Int must_be_bound1(USES_REGS1)
1996 Term t = Deref(ARG1);
1999 Yap_ThrowError(INSTANTIATION_ERROR, ARG1, NULL);
2007static Int must_be_ground1(USES_REGS1)
2009 Term t = Deref(ARG1);
2011 if (!Yap_IsGroundTerm(t))
2012 Yap_ThrowError(INSTANTIATION_ERROR, ARG1, NULL);
2031static Int must_be_predicate_indicator1(USES_REGS1)
2033 Term G = Deref(ARG1);
2035 Term mod = CurrentModule;
2037 G = Yap_YapStripModule(G, &mod);
2038 if (!mod) mod = TermProlog;
2041 Yap_ThrowError(INSTANTIATION_ERROR, G, NULL);
2043 if (!IsVarTerm(mod) && !IsAtomTerm(mod))
2045 Yap_Error(TYPE_ERROR_ATOM, G, NULL);
2051 if (IsExtensionFunctor(f))
2053 Yap_ThrowError(TYPE_ERROR_PREDICATE_INDICATOR, G, NULL);
2055 if (f == FunctorSlash || f == FunctorDoubleSlash)
2057 Term name = ArgOfTerm(1, G), arity = ArgOfTerm(2, G);
2058 name = Yap_YapStripModule(name, &mod);
2059 if (!mod) mod = TermProlog;
2060 if (IsVarTerm(name))
2062 Yap_ThrowError(INSTANTIATION_ERROR, name, NULL);
2064 else if (!IsAtomTerm(name))
2066 Yap_ThrowError(TYPE_ERROR_ATOM, name, NULL);
2068 if (IsVarTerm(arity))
2070 Yap_ThrowError(INSTANTIATION_ERROR, arity, NULL);
2072 else if (!IsIntegerTerm(arity))
2074 Yap_ThrowError(TYPE_ERROR_INTEGER, arity, NULL);
2078 Int ar = IntegerOfTerm(arity);
2081 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, arity, NULL);
2083 if (f == FunctorDoubleSlash)
2085 arity = MkIntegerTerm(ar + 2);
2087 return Yap_unify(mod, ARG2) && Yap_unify(name, ARG3) &&
2088 Yap_unify(arity, ARG4);
2092 Yap_ThrowError(TYPE_ERROR_PREDICATE_INDICATOR, G, NULL);
2096void Yap_InitErrorPreds(
void)
2099 Yap_InitCPred(
"$print_exception", 1, print_exception, 0);
2100 Yap_InitCPred(
"print_exception", 1, print_exception, 0);
2101 Yap_InitCPred(
"$reset_exception", 1, reset_exception, 0);
2103 Yap_InitCPred(
"$new_exception", 1, new_exception, 0);
2104 Yap_InitCPred(
"$set_exception", 3, set_exception, 0);
2105 Yap_InitCPred(
"$read_exception", 2, read_exception, 0);
2106 Yap_InitCPred(
"$query_exception", 3, query_exception, 0);
2107 Yap_InitCPred(
"$drop_exception", 1, drop_exception, 0);
2108 Yap_InitCPred(
"$close_error", 1, close_error, HiddenPredFlag);
2111 Yap_InitCPred(
"callable", 1, callable, TestPredFlag);
2112 Yap_InitCPred(
"is_bound", 1, is_nonvar1, TestPredFlag);
2113 Yap_InitCPred(
"is_boolean", 1, is_boolean1, TestPredFlag);
2114 Yap_InitCPred(
"is_atom", 1, is_atom1, TestPredFlag);
2115 Yap_InitCPred(
"is_boolean", 1, is_boolean1, TestPredFlag);
2116 Yap_InitCPred(
"is_callable", 1, is_callable1, TestPredFlag);
2117 Yap_InitCPred(
"is_list", 1, is_list1, TestPredFlag);
2118 Yap_InitCPred(
"is_nonvar", 1, is_nonvar1, TestPredFlag);
2120 Yap_InitCPred(
"must_be_atom", 1, must_be_atom1, TestPredFlag);
2121 Yap_InitCPred(
"must_be_boolean", 1, must_be_boolean1, TestPredFlag);
2122 Yap_InitCPred(
"must_be_bound", 1, must_be_bound1, TestPredFlag);
2123 Yap_InitCPred(
"must_be_callable", 1, must_be_callable1, TestPredFlag);
2124 Yap_InitCPred(
"must_be_ground", 1, must_be_ground1, TestPredFlag);
2125 Yap_InitCPred(
"must_be_list", 1, must_be_list1, TestPredFlag);
2127 Yap_InitCPred(
"is_list", 1, is_list1, TestPredFlag);
2128 Yap_InitCPred(
"must_be_predicate_indicator", 4, must_be_predicate_indicator1, 0);
load_foreign_files/3 has works for the following configurations:
void Yap_must_be_list(Term t)
Dereferenced term t must start as a list:
bool Yap_ResetException(yap_error_descriptor_t *i)
clean up (notice that the code ensures ActiveError exists on exit
void Yap_PrintException(yap_error_descriptor_t *i)
print descriptor to user_output/stdout
yap_error_descriptor_t * Yap_PeekException(void)
is an error active?
bool Yap_RaiseException()
let's go
yap_error_number Yap_errorNumber(yap_error_class_number c, const char *s)
given a string(s, lookup for a corresponding error class r numbe
bool Yap_RestartException(yap_error_descriptor_t *i)
clean up (notice that the code ensures ActiveError exists on exit
yap_error_descriptor_t * Yap_GetException(void)
clone Active Error
Term Yap_MkFullError(yap_error_descriptor_t *i)
convert a C-error to a Prolog term:
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.
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.
Term MkSysError(yap_error_descriptor_t *i)
Wrap the error descriptor as exception/2.
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;
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:
all we need to know about an error/throw
uintptr_t parserPos
syntax and other parsing errors
const char * errorFunction
C-function.
const char * errorFile
C-file.
yap_error_number errorNo
error identifier
yap_error_class_number errorClass
kind of error: derived from errorNo;
char * classAsText
errorClass as text
char * errorAsText
errorNo as text
bool prologConsulting
whether we are consulting
intptr_t errorLine
c-code that generated the error C-line