error.c

00001 /*****************************************************************************
00002  *                            error.c
00003  * This function contains the error handling routine of the sgml parser. This
00004  * routine creates the error term to throw in case of an exception.
00005  *
00006  ***************************************************************************/
00007 
00008 #include <errno.h>
00009 #include <stdlib.h>
00010 #include "error.h"
00011 #include <assert.h>
00012 #include <string.h>
00013 #include <stdio.h>
00014 #include "cinterf.h"
00015 #include "dtd.h"
00016 #include "error_term.h"
00017 
00018 prolog_term global_error_term = (prolog_term)NULL;
00019 prolog_term global_warning_term = (prolog_term)NULL;
00020 
00027 int
00028 sgml2pl_error(plerrorid id, ...)
00029 { 
00030   prolog_term except = p2p_new();
00031   prolog_term formal = p2p_new();
00032   prolog_term swi = p2p_new();
00033   prolog_term tmp1 = p2p_new();
00034   prolog_term tmp;
00035 
00036   va_list args;
00037   char msgbuf[1024];
00038   char *msg = NULL;
00039 
00040   va_start(args, id);
00041   /*Create the appropriate error term based on the type of error*/
00042   switch(id)
00043     { 
00044     case ERR_ERRNO:                                     /*Standard unix errors*/
00045       { 
00046         int err = va_arg(args, int);
00047         msg = strerror(err);
00048 
00049           switch(err)
00050             { 
00051               /*Not enough memory error*/
00052             case ENOMEM:
00053           
00054               c2p_functor("sgml", 1, tmp1);     
00055               tmp = p2p_arg( tmp1, 1);
00056               c2p_functor( "resource_error", 1, tmp);
00057           
00058               c2p_string( "no_memory", p2p_arg( tmp, 1));
00059               p2p_unify( tmp1, formal); 
00060               break;
00061               /*No access error*/
00062             case EACCES:
00063               { 
00064                 const char *file = va_arg(args,   const char *);
00065                 const char *action = va_arg(args, const char *);
00066 
00067                 c2p_functor("sgml", 1, tmp1);
00068                 tmp = p2p_arg( tmp1, 1);
00069 
00070                 c2p_functor( "permission_error", 3, tmp);
00071                 c2p_string( (char*)action, p2p_arg(tmp, 1));
00072                 c2p_string( "file", p2p_arg(tmp, 2));
00073                 c2p_string ( (char*)file, p2p_arg(tmp, 3));
00074 
00075                 p2p_unify( tmp1, formal);
00076                 break;
00077               }
00078               /*Entity not found error*/
00079             case ENOENT:
00080               { 
00081                 const char *file = va_arg(args, const char *);
00082          
00083 
00084                 c2p_functor("sgml", 1, tmp1);
00085                 tmp = p2p_arg( tmp1, 1);
00086 
00087                 c2p_functor( "permission_error", 2, tmp);
00088                           
00089                 c2p_string( "file", p2p_arg(tmp, 1));
00090                 c2p_string ( (char*)file, p2p_arg(tmp, 2));
00091 
00092                 p2p_unify( tmp1, formal); 
00093 
00094                 break;
00095               }
00096               /*Defaults to system error*/
00097             default:
00098               {
00099                 c2p_functor("sgml", 1, tmp1);
00100                 tmp = p2p_arg( tmp1, 1);
00101 
00102                 c2p_string("system_error", tmp);
00103                 p2p_unify( tmp1, formal);
00104                 break;
00105               }
00106             }
00107           break;
00108         }
00109     case ERR_TYPE:
00110       { 
00111         const char *expected = va_arg(args, const char*);
00112         prolog_term actual        = va_arg(args, prolog_term);
00113 
00114 
00115         /*Type error*/
00116         c2p_functor("sgml", 1, tmp1);
00117         tmp = p2p_arg( tmp1, 1);
00118 
00119         if( is_attv( actual) && strcmp(expected, "variable") != 0 )
00120           {
00121             c2p_string( "instantiation_error", tmp);
00122             p2p_unify( tmp1, formal);
00123           }
00124         else
00125           {
00126             c2p_functor( "type_error", 2, tmp);
00127             c2p_string( (char*)expected, p2p_arg(tmp, 1));
00128             p2p_unify ( actual, p2p_arg(tmp, 2));
00129             p2p_unify( tmp1, formal);
00130           }
00131         break;
00132       } 
00133     case ERR_DOMAIN:                            /*Domain error*/
00134       { 
00135         const char *expected = va_arg(args, const char*);
00136         prolog_term actual        = va_arg(args, prolog_term);
00137 
00138         /*Improper domain of functor*/
00139         c2p_functor("sgml", 1, tmp1);
00140         tmp = p2p_arg( tmp1, 1);
00141         
00142         if( is_attv( actual) && strcmp(expected, "variable") != 0 )
00143           {
00144             c2p_string( "instantiation_error", tmp);
00145             p2p_unify( tmp1, formal);
00146           }
00147         else
00148           {
00149             c2p_functor( "domain_error", 2, tmp);
00150             c2p_string( (char*)expected, p2p_arg(tmp, 1));
00151             p2p_unify( actual, p2p_arg(tmp, 2));
00152             p2p_unify( tmp1, formal);
00153           }
00154         break;
00155       }
00156     case ERR_EXISTENCE:                 /*Existence error*/
00157       { 
00158         const char *type = va_arg(args, const char *);
00159         prolog_term obj  = va_arg(args, prolog_term);
00160 
00161         /*Resource not found*/
00162         c2p_functor("sgml", 1, tmp1);
00163         tmp = p2p_arg( tmp1, 1);
00164 
00165         c2p_functor( "existence_error", 2, tmp);
00166                                                                               
00167         c2p_string( (char*)type, p2p_arg(tmp, 1));
00168         p2p_unify ( obj, p2p_arg(tmp, 2));
00169                                                                                 
00170         p2p_unify( tmp1, formal);
00171         break;
00172       }
00173     case ERR_FAIL:
00174       { 
00175         /*Goal failed error*/
00176         prolog_term goal  = va_arg(args, prolog_term);
00177 
00178         c2p_functor("sgml", 1, tmp1);
00179         tmp = p2p_arg( tmp1, 1);
00180 
00181         c2p_functor( "goal_failed", 1, tmp);
00182 
00183         p2p_unify( p2p_arg( tmp,1), goal);      
00184       
00185         p2p_unify( tmp1, formal);
00186         break;
00187       }
00188     case ERR_LIMIT:
00189       { 
00190         /*Limit exceeded error*/
00191         const char *limit = va_arg(args, const char *);
00192         long maxval  = va_arg(args, long);
00193 
00194         c2p_functor("sgml", 1, tmp1);
00195         tmp = p2p_arg( tmp1, 1);
00196         
00197         c2p_functor( "limit_exceeded", 2, tmp);
00198         c2p_string( (char*)limit, p2p_arg( tmp,1));
00199         c2p_int( maxval, p2p_arg( tmp, 2));
00200         p2p_unify( tmp1, formal);
00201         break;
00202       }
00203     case ERR_MISC:
00204       { 
00205         /*Miscellaneous error*/
00206         const char *id = va_arg(args, const char *);
00207       
00208         const char *fmt = va_arg(args, const char *);
00209 
00210         vsprintf(msgbuf, fmt, args);
00211         msg = msgbuf;
00212 
00213         c2p_functor("sgml", 1, tmp1);
00214         tmp = p2p_arg( tmp1, 1);
00215 
00216         c2p_functor( "miscellaneous", 1, tmp);
00217         c2p_string( (char*)id, p2p_arg( tmp, 1));
00218         p2p_unify( tmp1, formal);
00219         break; 
00220       }
00221     default:
00222       assert(0);
00223     }
00224 
00225   va_end(args);
00226 
00227   if ( msg )
00228     { 
00229       prolog_term msgterm  = p2p_new();
00230 
00231       if ( msg )
00232         { 
00233           c2p_string( msg, msgterm);
00234         }
00235 
00236       tmp = p2p_new();
00237 
00238       c2p_functor( "context", 1, tmp);
00239       p2p_unify( p2p_arg( tmp, 1), msgterm);    
00240       p2p_unify( tmp, swi);
00241     }
00242 
00243   /*Create the error term to throw*/
00244   tmp = p2p_new();
00245   c2p_functor( "error", 2, tmp);
00246   p2p_unify( p2p_arg( tmp, 1), formal);
00247   p2p_unify( p2p_arg( tmp, 2), swi);
00248   p2p_unify( tmp, except);
00249   
00250   return p2p_unify( global_error_term, except);
00251 }
00252 

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