error_xsb.c

00001 /* File:      error_xsb.c
00002 ** Author(s): Sagonas, Demoen
00003 ** Contact:   xsb-contact@cs.sunysb.edu
00004 ** 
00005 ** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
00006 ** 
00007 ** XSB is free software; you can redistribute it and/or modify it under the
00008 ** terms of the GNU Library General Public License as published by the Free
00009 ** Software Foundation; either version 2 of the License, or (at your option)
00010 ** any later version.
00011 ** 
00012 ** XSB is distributed in the hope that it will be useful, but WITHOUT ANY
00013 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 ** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
00015 ** more details.
00016 ** 
00017 ** You should have received a copy of the GNU Library General Public License
00018 ** along with XSB; if not, write to the Free Software Foundation,
00019 ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020 **
00021 ** $Id: error_xsb.c,v 1.53 2006/05/31 21:28:09 crojo Exp $
00022 ** 
00023 */
00024 
00025 #include "xsb_config.h"
00026 #include "xsb_debug.h"
00027 
00028 #include <stdio.h>
00029 #include <stdarg.h>
00030 #include <string.h>
00031 #include <signal.h>
00032 #include <stdlib.h>
00033 
00034 #include "auxlry.h"
00035 #include "cell_xsb.h"
00036 #include "psc_xsb.h"
00037 #include "subp.h"
00038 #include "register.h"
00039 #include "context.h"
00040 #include "error_xsb.h"
00041 #include "io_builtins_xsb.h"
00042 #include "cinterf.h"
00043 #include "memory_xsb.h"
00044 #include "tries.h"
00045 #include "choice.h"
00046 #include "inst_xsb.h"
00047 #include "macro_xsb.h"
00048 #include "tr_utils.h"
00049 #include "binding.h"
00050 #include "cut_xsb.h"
00051 #include "flags_xsb.h"
00052 #include "term_psc_xsb_i.h"
00053 #include "thread_xsb.h"
00054 
00055 extern void remove_incomplete_tries(CTXTdeclc CPtr);
00056 extern PrRef get_prref(CTXTdeclc Psc psc);
00057 
00058 #ifndef MULTI_THREAD
00059 extern jmp_buf xsb_abort_fallback_environment;
00060 #endif
00061 
00062 FILE *stdmsg;                     /* stream for XSB benign messages */
00063 FILE *stddbg;                     /* stream for XSB debug msgs */
00064 FILE *stdwarn;                    /* stream for XSB warnings */
00065 FILE *stdfdbk;                    /* stream for XSB feedback messages */
00066 
00067 /*----------------------------------------------------------------------*/
00068 
00069 static char *err_msg_table[] = {
00070         "Calculation", "Database", "Evaluation", "Implementation",
00071         "Instantiation", "I/O Control", "I/O End-of-file", "I/O Formatting",
00072         "Operator", "Overflow", "Range", "Syntax", "Type",
00073         "Undefined predicate/function", "Undefined value",
00074         "Underflow", "Zero division" };
00075 
00076 /*----------------------------------------------------------------------*/
00077 
00078 #if defined(DEBUG_VERBOSE) && defined(CP_DEBUG)
00079 extern void print_cp_backtrace();
00080 #endif
00081 
00082 /* TLS: now frees Ball, which was assumed to be malloced.  Use
00083    mem_alloc_nocheck to avoid problems when thowing a memory error. */
00084 DllExport void call_conv xsb_throw(CTXTdeclc prolog_term Ball, unsigned long Ball_len)
00085 {
00086   Psc exceptballpsc;
00087   PrRef Prref;
00088   int isnew;
00089   ClRef clause;
00090   Cell *tptr;
00091   prolog_term term_to_assert;
00092   Cell *space_for_ball_assert;
00093   unsigned long space_for_ball_assert_len = 3*sizeof(Cell);
00094 
00095   space_for_ball_assert = (Cell *) mem_alloc_nocheck(space_for_ball_assert_len,
00096                                                      LEAK_SPACE);
00097   if (!space_for_ball_assert) 
00098     xsb_exit("++Unrecoverable Error[XSB/Runtime]: [Resource] Out of memory");
00099 
00100   exceptballpsc = pair_psc((Pair)insert("$$exception_ball", (byte)2, 
00101                                         pair_psc(insert_module(0,"standard")), 
00102                                         &isnew));
00103   tptr = space_for_ball_assert;
00104   term_to_assert = makecs(tptr);
00105   bld_functor(tptr, exceptballpsc); tptr++;
00106   bld_int(tptr, xsb_thread_self()); tptr++;
00107   cell(tptr) = Ball; 
00108 
00109   assert_code_to_buff_p(CTXTc term_to_assert);
00110   /* need arity of 3, for extra cut_to arg */
00111   Prref = get_prref(CTXTc exceptballpsc);
00112   assert_buff_to_clref_p(CTXTc term_to_assert,3,Prref,0,makeint(0),0,&clause);
00113   mem_dealloc(cs_val(Ball),Ball_len,LEAK_SPACE);
00114   mem_dealloc(space_for_ball_assert,space_for_ball_assert_len,LEAK_SPACE);
00115   /* reset WAM emulator state to Prolog catcher */
00116   if (unwind_stack(CTXT)) xsb_exit("Unwind_stack failed in xsb_throw!");
00117   /* Resume main emulator instruction loop */
00118   longjmp(xsb_abort_fallback_environment, (Integer) &fail_inst);
00119 }
00120 
00121 
00122 /********************************************************************/
00123 /* Error types */
00124 /********************************************************************/
00125 
00126 // void calculation_error
00127 
00128 /*****************/
00129 void call_conv xsb_domain_error(CTXTdeclc char *valid_domain,Cell culprit, 
00130                                         char *predicate,int arity, int arg) 
00131 {
00132   prolog_term ball_to_throw;
00133   int isnew;
00134   Cell *tptr; char message[255];
00135   unsigned long ball_len = 10*sizeof(Cell);
00136 
00137   sprintf(message,"in arg %d of predicate %s/%d)",arg,predicate,arity);
00138 
00139   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00140 
00141   ball_to_throw = makecs(tptr);
00142   bld_functor(tptr, pair_psc(insert("error",3,
00143                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00144   tptr++;
00145   bld_cs(tptr,(Cell) (tptr+3));
00146   tptr++;
00147   bld_string(tptr,string_find(message,1));
00148   tptr++;
00149   bld_copy(tptr,build_xsb_backtrace(CTXT));
00150   tptr++;
00151   bld_functor(tptr, pair_psc(insert("domain_error",2,
00152                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00153   tptr++;
00154   bld_string(tptr,string_find(valid_domain,1));
00155   tptr++;
00156   if (culprit == (Cell)NULL) bld_int(tptr,0); 
00157   else bld_ref(tptr,culprit);
00158 
00159   xsb_throw(CTXTc ball_to_throw,ball_len);
00160 
00161 }
00162 
00163 /*****************/
00164 
00165 void call_conv xsb_existence_error(CTXTdeclc char *object,Cell culprit, 
00166                                         char *predicate,int arity, int arg) 
00167 {
00168   prolog_term ball_to_throw;
00169   int isnew;
00170   Cell *tptr; char message[255];
00171   unsigned long ball_len = 10*sizeof(Cell);
00172 
00173   sprintf(message,"in arg %d of predicate %s/%d)",arg,predicate,arity);
00174 
00175   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00176 
00177   ball_to_throw = makecs(tptr);
00178   bld_functor(tptr, pair_psc(insert("error",3,
00179                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00180   tptr++;
00181   bld_cs(tptr,(Cell) (tptr+3));
00182   tptr++;
00183   bld_string(tptr,string_find(message,1));
00184   tptr++;
00185   bld_copy(tptr,build_xsb_backtrace(CTXT));
00186   tptr++;
00187   bld_functor(tptr, pair_psc(insert("existence_error",2,
00188                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00189   tptr++;
00190   bld_string(tptr,string_find(object,1));
00191   tptr++;
00192   if (culprit == (Cell)NULL) bld_int(tptr,0); 
00193   else bld_ref(tptr,culprit);
00194 
00195   xsb_throw(CTXTc ball_to_throw, ball_len);
00196 
00197 }
00198 
00199 
00200 /*****************/
00201 void call_conv xsb_instantiation_error(CTXTdeclc char *predicate,int arity,
00202                                                  int arg,char *state) 
00203 {
00204   prolog_term ball_to_throw;
00205   int isnew;
00206   Cell *tptr; char message[255];
00207   unsigned long ball_len = 10*sizeof(Cell);
00208 
00209   if (! IsNULL(state)) {
00210     sprintf(message," in arg %d of predicate %s/%d must be %s",arg,predicate,arity,
00211             state);
00212   } else {
00213     sprintf(message," in arg %d of predicate %s/%d",arg,predicate,arity);
00214   }    
00215 
00216   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00217 
00218   ball_to_throw = makecs(tptr);
00219   bld_functor(tptr, pair_psc(insert("error",3,
00220                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00221   tptr++;
00222   bld_string(tptr,string_find("instantiation_error",1));
00223   tptr++;
00224   bld_string(tptr,string_find(message,1));
00225   tptr++;
00226   bld_copy(tptr,build_xsb_backtrace(CTXT));
00227 
00228   xsb_throw(CTXTc ball_to_throw,ball_len);
00229 
00230 }
00231 
00232 /*****************/
00233 /* Operation/Object_type/Culprit */
00234 void call_conv xsb_permission_error(CTXTdeclc
00235                                     char *operation,char *object,Cell culprit, 
00236                                     char *predicate,int arity) 
00237 {
00238   prolog_term ball_to_throw;
00239   int isnew;
00240   Cell *tptr; char message[255];
00241   unsigned long ball_len = 10*sizeof(Cell);
00242 
00243   sprintf(message,"in predicate %s/%d)",predicate,arity);
00244 
00245   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00246 
00247   ball_to_throw = makecs(tptr);
00248   bld_functor(tptr, pair_psc(insert("error",3,
00249                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00250   tptr++;
00251   bld_cs(tptr,(Cell) (tptr+3));
00252   tptr++;
00253   bld_string(tptr,string_find(message,1));
00254   tptr++;
00255   bld_copy(tptr,build_xsb_backtrace(CTXT));
00256   tptr++;
00257   bld_functor(tptr, pair_psc(insert("permission_error",3,
00258                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00259   tptr++;
00260   bld_string(tptr,string_find(operation,1));
00261   tptr++;
00262   bld_string(tptr,string_find(object,1));
00263   tptr++;
00264   if (culprit == (Cell)NULL) bld_int(tptr,0); 
00265   else bld_ref(tptr,culprit);
00266 
00267   xsb_throw(CTXTc ball_to_throw,ball_len);
00268 
00269 }
00270 
00271 /**************/
00272 
00273 #define MsgBuf (*tsgSBuff1)
00274 #define FlagBuf (*tsgSBuff2)
00275 
00276 /* Memory errors are resource errors: therefore we have to be careful
00277    when handling the memory for throwing the error itself.
00278    Accordingly, varstrings are used rather than string finds to avoid
00279    possible overflow of string table, and there is a malloc and
00280    immediate free to make sure we'll have enough for messages to throw
00281    the error.  Similarly, mem_alloc_nocheck() is used to avoid
00282    problems in allocating memory for ball.*/
00283 
00284 void call_conv xsb_resource_error(CTXTdeclc char *resource,
00285                                         char *predicate,int arity) 
00286 {
00287   prolog_term ball_to_throw;
00288   int isnew;
00289   Cell *tptr; char message[255];
00290   unsigned long ball_len = 10*sizeof(Cell);
00291 
00292   tptr = (Cell *) malloc(1000);
00293   if (!tptr) 
00294     xsb_exit("++Unrecoverable Error[XSB/Runtime]: [Resource] Out of memory");
00295   else free(tptr);
00296 
00297   sprintf(message,"in predicate %s/%d)",predicate,arity);
00298   XSB_StrSet(&MsgBuf,message);
00299   XSB_StrSet(&FlagBuf,resource);
00300 
00301   tptr =   (Cell *) mem_alloc_nocheck(ball_len,LEAK_SPACE);
00302   if (!tptr) 
00303     xsb_exit("++Unrecoverable Error[XSB/Runtime]: [Resource] Out of memory");
00304 
00305   ball_to_throw = makecs(tptr);
00306   bld_functor(tptr, pair_psc(insert("error",3,
00307                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00308   tptr++;
00309   bld_cs(tptr,(Cell) (tptr+3));
00310   tptr++;
00311   //  bld_string(tptr,string_find(message,1));
00312   bld_string(tptr,MsgBuf.string);
00313   tptr++;
00314   bld_copy(tptr,build_xsb_backtrace(CTXT));
00315   tptr++;
00316   bld_functor(tptr, pair_psc(insert("resource_error",1,
00317                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00318   tptr++;
00319 
00320   bld_string(tptr,FlagBuf.string);
00321 
00322   xsb_throw(CTXTc ball_to_throw, ball_len);
00323 
00324 }
00325 
00326 /* TLS: exiting in MT engine because I haven't yet put contexts into
00327    mem_xxxocs.  And, I'm not sure whether this is a good idea. */
00328 
00329 #ifdef MULTI_THREAD
00330 void call_conv xsb_memory_error(char *resource,char *message)
00331 {
00332   char exit_message[255];
00333 
00334   sprintf(exit_message,
00335           "++Unrecoverable Error[XSB/Runtime]: [Resource] Out of memory (%s)",
00336           message);
00337   xsb_exit(exit_message);
00338 }
00339 #else
00340 void call_conv xsb_memory_error(char *resource,char *message) {
00341   xsb_resource_error_nopred(CTXTdeclc resource,message);
00342 }
00343 #endif
00344 
00345 /* Like xsb_resource_error(), but does not include predicate and
00346    argument information. */
00347 void call_conv xsb_resource_error_nopred(CTXTdeclc char *resource,char *message)
00348 {
00349   prolog_term ball_to_throw;
00350   int isnew;
00351   Cell *tptr; 
00352   unsigned long ball_len = 10*sizeof(Cell);
00353 
00354   tptr = (Cell *) malloc(1000);
00355   if (!tptr) 
00356     xsb_exit("++Unrecoverable Error[XSB/Runtime]: [Resource] Out of memory");
00357   else free(tptr);
00358 
00359   XSB_StrSet(&MsgBuf,message);
00360   XSB_StrSet(&FlagBuf,resource);
00361 
00362   tptr =   (Cell *) mem_alloc_nocheck(ball_len,LEAK_SPACE);
00363   if (!tptr) 
00364     xsb_exit("++Unrecoverable Error[XSB/Runtime]: [Resource] Out of memory");
00365 
00366   ball_to_throw = makecs(tptr);
00367   bld_functor(tptr, pair_psc(insert("error",3,
00368                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00369   tptr++;
00370   bld_cs(tptr,(Cell) (tptr+3));
00371   tptr++;
00372   //  bld_string(tptr,string_find(message,1));
00373   bld_string(tptr,MsgBuf.string);
00374   tptr++;
00375   bld_copy(tptr,(Integer)nil_string);
00376   tptr++;
00377   bld_functor(tptr, pair_psc(insert("resource_error",1,
00378                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00379   tptr++;
00380 
00381   bld_string(tptr,FlagBuf.string);
00382 
00383   xsb_throw(CTXTc ball_to_throw, ball_len);
00384 
00385 }
00386 
00387 #undef MsgBuf
00388 #undef FlagBuf
00389 
00390 /**************/
00391 
00392 void call_conv xsb_table_error(CTXTdeclc char *message) 
00393 {
00394   prolog_term ball_to_throw;
00395   int isnew;
00396   Cell *tptr;
00397   unsigned long ball_len = 10*sizeof(Cell);
00398 #ifdef MULTI_THREAD
00399   char mtmessage[MAXBUFSIZE];
00400   int tid = xsb_thread_self();
00401   //  th_context *th;
00402   //  th = find_context(xsb_thread_self());
00403 #endif
00404 
00405   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00406   ball_to_throw = makecs(tptr);
00407   bld_functor(tptr, pair_psc(insert("error",3,
00408                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00409 
00410   tptr++;
00411   bld_string(tptr,string_find("table_error",1));
00412   tptr++;
00413 #ifdef MULTI_THREAD
00414   sprintf(mtmessage,"[th %d] %s",tid,message);
00415   bld_string(tptr,string_find(mtmessage,1));
00416 #else  
00417   bld_string(tptr,string_find(message,1));
00418 #endif
00419   tptr++;
00420   bld_copy(tptr,build_xsb_backtrace(CTXT));
00421   xsb_throw(CTXTc ball_to_throw,ball_len);
00422 }                              
00423 
00424 /**************/
00425 
00426 void call_conv xsb_type_error(CTXTdeclc char *valid_type,Cell culprit, 
00427                                         char *predicate,int arity, int arg) 
00428 {
00429   prolog_term ball_to_throw;
00430   int isnew;
00431   Cell *tptr; char message[255];
00432   unsigned long ball_len = 10*sizeof(Cell);
00433 
00434   sprintf(message,"in arg %d of predicate %s/%d)",arg,predicate,arity);
00435 
00436   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00437 
00438   ball_to_throw = makecs(tptr);
00439   bld_functor(tptr, pair_psc(insert("error",3,
00440                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00441   tptr++;
00442   bld_cs(tptr,(Cell) (tptr+3));
00443   tptr++;
00444   bld_string(tptr,string_find(message,1));
00445   tptr++;
00446   bld_copy(tptr,build_xsb_backtrace(CTXT));
00447   tptr++;
00448   bld_functor(tptr, pair_psc(insert("type_error",2,
00449                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00450   tptr++;
00451   bld_string(tptr,string_find(valid_type,1));
00452   tptr++;
00453   if (culprit == (Cell)NULL) bld_int(tptr,0); 
00454   else bld_ref(tptr,culprit);
00455 
00456   xsb_throw(CTXTc ball_to_throw, ball_len);
00457 
00458 }
00459 
00460 /*****************/
00461 
00462 void call_conv xsb_basic_abort(char *message)
00463 {
00464   prolog_term ball_to_throw;
00465   int isnew;
00466   Cell *tptr;
00467   unsigned long ball_len = 10*sizeof(Cell);
00468 #ifdef MULTI_THREAD
00469   char mtmessage[MAXBUFSIZE];
00470   int tid = xsb_thread_self();
00471   th_context *th;
00472   th = find_context(xsb_thread_self());
00473 #endif
00474 
00475   tptr =   (Cell *) mem_alloc(ball_len,LEAK_SPACE);
00476   ball_to_throw = makecs(tptr);
00477   bld_functor(tptr, pair_psc(insert("error",3,
00478                                     (Psc)flags[CURRENT_MODULE],&isnew)));
00479 
00480   tptr++;
00481   bld_string(tptr,string_find("misc_error",1));
00482   tptr++;
00483 #ifdef MULTI_THREAD
00484   sprintf(mtmessage,"[th %d] %s",tid,message);
00485   bld_string(tptr,string_find(mtmessage,1));
00486 #else  
00487   bld_string(tptr,string_find(message,1));
00488 #endif
00489   tptr++;
00490   bld_copy(tptr,build_xsb_backtrace(CTXT));
00491   xsb_throw(CTXTc ball_to_throw,ball_len);
00492 }
00493 
00494 DllExport void call_conv xsb_abort(char *description, ...)
00495 {
00496   char message[MAXBUFSIZE];
00497   va_list args;
00498 
00499   va_start(args, description);
00500   strcpy(message, "++Error[XSB]: [Runtime/C] ");
00501   vsprintf(message+strlen(message), description, args);
00502   if (message[strlen(message)-1] == '\n') message[strlen(message)-1] = 0;
00503   va_end(args);
00504   xsb_basic_abort(message);
00505 }
00506 
00507 DllExport void call_conv abort_xsb(char * description)
00508 {
00509   char message[MAXBUFSIZE];
00510   strcpy(message, "++Error[XSB]: [Runtime/C] ");
00511   sprintf(message+strlen(message), description);
00512   if (message[strlen(message)-1] == '\n')
00513   {
00514     message[strlen(message)-1] = 0;
00515   }
00516   xsb_basic_abort(message);
00517 }
00518 
00519 /* could give these a different ball to throw */
00520 DllExport void call_conv xsb_bug(char *description, ...)
00521 {
00522   char message[MAXBUFSIZE];
00523   va_list args;
00524 
00525   va_start(args, description);
00526 
00527   strcpy(message, "++XSB bug: ");
00528   vsprintf(message+strlen(message), description, args);
00529   if (message[strlen(message)-1] != '\n')
00530     strcat(message, "\n");
00531 
00532   va_end(args);
00533   xsb_basic_abort(message);
00534 }
00535 
00536 DllExport void call_conv bug_xsb(char *description)
00537 {
00538   char message[MAXBUFSIZE];
00539   strcpy(message, "++XSB bug: ");
00540   sprintf(message+strlen(message), description);
00541   if (message[strlen(message)-1] != '\n')
00542     strcat(message, "\n");
00543 
00544   xsb_basic_abort(message);
00545 }
00546 
00547 /*----------------------------------------------------------------------*/
00548 
00549 #define str_op1 (*tsgSBuff1)
00550 #define str_op2 (*tsgSBuff2)
00551 void arithmetic_abort(CTXTdeclc Cell op1, char *OP, Cell op2)
00552 {
00553   XSB_StrSet(&str_op1,"");
00554   XSB_StrSet(&str_op2,"");
00555   print_pterm(CTXTc op1, TRUE, &str_op1);
00556   print_pterm(CTXTc op2, TRUE, &str_op2);
00557   if (isref(op1) || isref(op2)) {
00558     xsb_abort("Uninstantiated argument of evaluable function %s/2\n%s %s %s %s%s",
00559               OP, "   Goal:",
00560               (isref(op1)? "_Var": str_op1.string),
00561               OP,
00562               (isref(op2)? "_Var": str_op2.string),
00563               ", probably as 2nd arg of is/2");
00564   }
00565   else {
00566     xsb_abort("Wrong domain in evaluable function %s/2\n%s %s %s %s found",
00567               OP, "         Arithmetic expression expected, but",
00568               str_op1.string, OP, str_op2.string);
00569   }
00570 }
00571 #undef str_op1
00572 #undef str_op2
00573 
00574 #define str_op (*tsgSBuff1)
00575 void arithmetic_abort1(CTXTdeclc char *OP, Cell op)
00576 {
00577   XSB_StrSet(&str_op,"_Var");
00578   if (! isref(op)) print_pterm(CTXTc op, TRUE, &str_op);
00579   xsb_abort("%s evaluable function %s/2\n%s %s(%s) %s",
00580             (isref(op) ? "Uninstantiated argument of" : "Wrong domain in"),
00581             OP, "   Goal:", OP, str_op.string,
00582             ", probably as 2nd arg of is/2");  
00583 }
00584 #undef str_op
00585 
00586 #define str_op1 (*tsgSBuff1)
00587 void arithmetic_comp_abort(CTXTdeclc Cell op1, char *OP, int op2)
00588 {
00589   XSB_StrSet(&str_op1,"_Var");
00590   if (! isref(op1)) print_pterm(CTXTc op1, TRUE, &str_op1);
00591   xsb_abort("%s arithmetic comparison %s/2\n%s %s %s %d",
00592             (isref(op1) ? "Uninstantiated argument of" : "Wrong type in"),
00593             OP, "   Goal:", str_op1.string, OP, op2);
00594 }
00595 #undef str_op1
00596 
00597 /*----------------------------------------------------------------------*/
00598 
00599 /* this is a soft type of error msg compared to xsb_abort. It doesn't abort the
00600    computation, but sends stuff to stderr */
00601 DllExport void call_conv xsb_error (char *description, ...)
00602 {
00603   va_list args;
00604 
00605   va_start(args, description);
00606   fprintf(stderr, "\n++Error[XSB]: [Runtime/C] ");
00607   vfprintf(stderr, description, args);
00608   va_end(args);
00609   fprintf(stderr, "\n");
00610 #if defined(DEBUG_VERBOSE) && defined(CP_DEBUG)
00611   print_cp_backtrace();
00612 #endif
00613 }
00614 
00615 DllExport void call_conv error_xsb (char *description)
00616 {
00617   fprintf(stderr, "\n++Error[XSB]: [Runtime/C] ");
00618   fprintf(stderr, description);
00619   fprintf(stderr, "\n");
00620 #if defined(DEBUG_VERBOSE) && defined(CP_DEBUG)
00621   print_cp_backtrace();
00622 #endif
00623 }
00624 
00625 DllExport void call_conv xsb_warn(char *description, ...)
00626 {
00627   va_list args;
00628 
00629   va_start(args, description);
00630   fprintf(stdwarn, "\n++Warning[XSB]: [Runtime/C] ");
00631   vfprintf(stdwarn, description, args);
00632   va_end(args);
00633   fprintf(stdwarn, "\n");
00634 #if defined(DEBUG_VERBOSE) && defined(CP_DEBUG)
00635   print_cp_backtrace();
00636 #endif
00637 }
00638 
00639 DllExport void call_conv warn_xsb(char *description)
00640 {
00641   fprintf(stdwarn, "\n++Warning[XSB]: [Runtime/C] ");
00642   fprintf(stdwarn, description);
00643   fprintf(stdwarn, "\n");
00644 #if defined(DEBUG_VERBOSE) && defined(CP_DEBUG)
00645   print_cp_backtrace();
00646 #endif
00647 }
00648 
00649 DllExport void call_conv xsb_mesg(char *description, ...)
00650 {
00651   va_list args;
00652 
00653   va_start(args, description);
00654   vfprintf(stdmsg, description, args);
00655   va_end(args);
00656   fprintf(stdmsg, "\n");
00657 }
00658 
00659 DllExport void call_conv mesg_xsb(char *description)
00660 {
00661   fprintf(stdmsg, description);
00662   fprintf(stdmsg, "\n");
00663 }
00664 
00665 #ifdef DEBUG_VERBOSE
00666 DllExport void call_conv xsb_dbgmsg1(int log_level, char *description, ...)
00667 {
00668   va_list args;
00669 
00670   if (log_level <= cur_log_level) {
00671     va_start(args, description);
00672     vfprintf(stddbg, description, args);
00673     va_end(args);
00674     //    fprintf(stddbg, "\n");
00675   }
00676 }
00677 
00678 DllExport void call_conv dbgmsg1_xsb(int log_level, char *description)
00679 {
00680   if (log_level <= cur_log_level) {
00681     fprintf(stddbg, description);
00682   }
00683 }
00684 #endif
00685 
00686 /*----------------------------------------------------------------------*/
00687 
00688 DllExport void call_conv xsb_exit(char *description, ...)
00689 {
00690   va_list args;
00691 
00692   va_start(args, description);
00693   vfprintf(stderr, description, args);
00694   va_end(args);
00695 
00696   fprintf(stdfdbk, "\nExiting XSB abnormally...\n");
00697   exit(1);
00698 }
00699 
00700 DllExport void call_conv exit_xsb(char *description)
00701 {
00702   fprintf(stderr, description);
00703 
00704   fprintf(stdfdbk, "\nExiting XSB abnormally...\n");
00705   exit(1);
00706 }
00707 
00708 /*----------------------------------------------------------------------*/
00709 
00710 void err_handle(CTXTdeclc int description, int arg, char *f,
00711                 int ar, char *expected, Cell found)
00712 {
00713   char message[240];    /* Allow 3 lines of error reporting.    */
00714   switch (description) {
00715   case INSTANTIATION:
00716     xsb_instantiation_error(CTXTc f,ar,arg,NULL);
00717     /*
00718     sprintf(message, 
00719             "! %s error in argument %d of %s/%d",
00720             err_msg_table[description], arg, f, ar);
00721     break;
00722     */
00723   case RANGE:   /* I assume expected != NULL */
00724     sprintf
00725       (message,
00726        "! %s error: in argument %d of %s/%d\n! %s expected, but %d found",
00727        err_msg_table[description], arg, f, 
00728        ar, expected, (int) int_val(found));
00729     break;
00730   case TYPE:
00731     xsb_type_error(CTXTc expected,found,f,ar,arg);
00732   case ZERO_DIVIDE:
00733     sprintf(message,
00734             "! %s error in %s\n! %s expected, but %lx found",
00735             err_msg_table[description], f, expected, found);
00736     break;
00737   default:
00738     sprintf(message, 
00739             "! %s error (not completely handled yet): %s",
00740             err_msg_table[description], expected);
00741     break;
00742   }
00743   xsb_basic_abort(message);
00744 #if defined(DEBUG_VERBOSE) && defined(CP_DEBUG)
00745   print_cp_backtrace();
00746 #endif
00747 }
00748 
00749 /*************************************************************************/
00750 /*
00751    Builtins for exception handling using a Prolog-based catch-throw
00752 
00753               $$set_scope_marker/0
00754               $$unwind_stack/0
00755               $$clean_up_block/0
00756 
00757    Written by Bart Demoen, after the CW report 98:
00758               A 20' implementation of catch and throw
00759 
00760    7 Febr 1999
00761 
00762 */
00763 
00764 /* TLS: I keep forgetting what is going on here, so I'm documenting
00765    it.  Each time a catch is called, a scope marker is set and this
00766    scope marker points to the literal '$$clean_up_block' in the first
00767    clause of catch.  There is a little monkying to make the scope
00768    marker equal to this (THROWPAD).  Upon a throw, unwind_stack()
00769    checks cp regs of various envs to see whether a given cpreg is
00770    equal to this -- i.e. the env represents that of a catch.  If so,
00771    we fail into the second clause of the catch and try to unify with
00772    the exception ball.  If so, we do what the handler tells us, if
00773    not, we call unwind_stack again to look for the right catcher to
00774    unify with the ball. */
00775 
00776 #ifndef MULTI_THREAD
00777 byte *catch_scope_marker;
00778 #endif
00779 
00780 int set_scope_marker(CTXTdecl)
00781 {
00782   /*   printf("%x %x\n",cp_ereg(breg),ereg);*/
00783    catch_scope_marker = pcreg;
00784    /* skipping a putpval and a call instruction */
00785    /* is there a portable way to do this ?      */
00786    /* instruction builtin has already made pcreg point to the putpval */
00787    catch_scope_marker += THROWPAD;
00788    return(TRUE);
00789 } /* set_scope_marker */
00790 
00791 
00792 
00793 int unwind_stack(CTXTdecl)
00794 {
00795    byte *cp, *cpmark;
00796    CPtr e,b, xtemp1, xtemp2;
00797    CPtr tmp_compl_frm = NULL;
00798 
00799    cpmark = catch_scope_marker;
00800    /* first find the right environment */
00801    e = ereg;
00802    cp = cpreg; /* apparently not pcreg ... maybe not good in general */
00803    while ( (cp != cpmark) && e )
00804      {
00805        /*            printf("cp %d x%x\n",cp,cp);*/
00806        cp = (byte *)e[-1];
00807        e = (CPtr)e[0];
00808      }
00809 
00810    if ( ! e )
00811      xsb_exit("Throw failed because no catcher for throw");
00812 
00813    /* now find the corresponding breg */
00814    b = breg;
00815    while (cp_ereg(b) <= e) {
00816      if (IS_TABLE_INSTRUC(*cp_pcreg(b))) 
00817        tmp_compl_frm = subg_compl_stack_ptr(tcp_subgoal_ptr(b));
00818      b = cp_prevbreg(b);
00819    }
00820    if (IS_TABLE_INSTRUC(*cp_pcreg(b))) 
00821      tmp_compl_frm = subg_compl_stack_ptr(tcp_subgoal_ptr(b));
00822    breg = b;
00823    if (tmp_compl_frm != NULL) {
00824      remove_incomplete_tries(CTXTc prev_compl_frame(tmp_compl_frm));
00825    }
00826    unwind_trail(breg,xtemp1,xtemp2);
00827 
00828    return(FALSE);
00829 
00830 } /* unwind_stack */
00831 
00832 
00833 int clean_up_block(CTXTdecl)
00834 {
00835    if (cp_ereg(breg) > ereg) {
00836      /*     printf("%x %x\n",cp_ereg(breg),ereg); */
00837      breg = (CPtr)cp_prevbreg(breg);
00838    }
00839    return(TRUE);
00840 
00841 } /* clean_up_block */
00842 
00843 /*---------------------------- end of error_xsb.c --------------------------*/
00844 

Generated on Wed Jul 26 13:30:40 2006 for XSB by  doxygen 1.4.5