/* -*- mode: C++; c-file-style: "bsd" -*- */ #include "errors.h" #include "porbit-perl.h" typedef struct _SystemExceptionRec SystemExceptionRec; typedef struct _BuiltinExceptionRec BuiltinExceptionRec; struct _SystemExceptionRec { char *repoid; char *package; char *text; }; struct _BuiltinExceptionRec { char *repoid; char *package; }; static SystemExceptionRec system_exceptions[] = { { "IDL:omg.org/CORBA/SystemException:1.0", "CORBA::SystemException", "Unspecified system exception" }, { "IDL:omg.org/CORBA/UNKNOWN:1.0", "CORBA::UNKNOWN", "The unknown exception" }, { "IDL:omg.org/CORBA/BAD_PARAM:1.0", "CORBA::BAD_PARAM", "An invalid parameter was passed" }, { "IDL:omg.org/CORBA/NO_MEMORY:1.0", "CORBA::NO_MEMORY", "Dynamic memory allocation failure" }, { "IDL:omg.org/CORBA/IMP_LIMIT:1.0", "CORBA::IMP_LIMIT", "Violated implementation limit" }, { "IDL:omg.org/CORBA/COMM_FAILURE:1.0" , "CORBA::COMM_FAILURE", "Communication failure" }, { "IDL:omg.org/CORBA/INV_OBJREF:1.0", "CORBA::INV_OBJREF", "Invalid object reference" }, { "IDL:omg.org/CORBA/NO_PERMISSION:1.0", "CORBA::NO_PERMISSION", "No permission for attempted operation" }, { "IDL:omg.org/CORBA/INTERNAL:1.0", "CORBA::INTERNAL", "ORB internal error" }, { "IDL:omg.org/CORBA/MARSHAL:1.0", "CORBA::MARSHAL", "Error marshalling parameter or result" }, { "IDL:omg.org/CORBA/INITIALIZE:1.0", "CORBA::INITIALIZE", "ORB initialization failure" }, { "IDL:omg.org/CORBA/NO_IMPLEMENT:1.0", "CORBA::NO_IMPLEMENT", "Operation implementation unavailable" }, { "IDL:omg.org/CORBA/BAD_TYPECODE:1.0", "CORBA::BAD_TYPECODE", "Bad typecode" }, { "IDL:omg.org/CORBA/BAD_OPERATION:1.0", "CORBA::BAD_OPERATION", "Invalid operation" }, { "IDL:omg.org/CORBA/NO_RESOURCES:1.0", "CORBA::NO_RESOURCES", "Insufficient resources for request" }, { "IDL:omg.org/CORBA/NO_RESPONSE:1.0", "CORBA::NO_RESPONSE", "Response to request not yet available" }, { "IDL:omg.org/CORBA/PERSIST_STORE:1.0", "CORBA::PERSIST_STORE", "Persistant storage failure" }, { "IDL:omg.org/CORBA/BAD_INV_ORDER:1.0", "CORBA::BAD_INV_ORDER", "Routine invocations out of order" }, { "IDL:omg.org/CORBA/TRANSIENT:1.0", "CORBA::TRANSIENT", "Transient failure - reissue request" }, { "IDL:omg.org/CORBA/FREE_MEM:1.0", "CORBA::FREE_MEM", "Cannot free memory" }, { "IDL:omg.org/CORBA/INV_IDENT:1.0", "CORBA::INV_IDENT", "Invalid identifier syntax" }, { "IDL:omg.org/CORBA/INV_FLAG:1.0", "CORBA::INV_FLAG", "Invalid flag was specified" }, { "IDL:omg.org/CORBA/INTF_REPOS:1.0", "CORBA::INTF_REPOS", "Error accessing interface repository" }, { "IDL:omg.org/CORBA/BAD_CONTEXT:1.0", "CORBA::BAD_CONTEXT", "Error processing context" }, { "IDL:omg.org/CORBA/OBJ_ADAPTER:1.0", "CORBA::OBJ_ADAPTER", "Failure detected by object adapter" }, { "IDL:omg.org/CORBA/DATA_CONVERSION:1.0", "CORBA::DATA_CONVERSION", "Data conversion error" }, { "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0", "CORBA::OBJECT_NOT_EXIST", "Non-existent object, delete reference" }, { "IDL:omg.org/CORBA/TRANSACTION_REQUIRED:1.0", "CORBA::TRANSACTION_REQUIRED", "Transaction required" }, { "IDL:omg.org/CORBA/TRANSACTION_ROLLEDBACK:1.0", "CORBA::TRANSACTION_ROLLEDBACK", "Transaction rolled back" }, { "IDL:omg.org/CORBA/INVALID_TRANSACTION:1.0", "CORBA::INVALID_TRANSACTION", "Invalid transaction" }, }; static const int num_system_exceptions = sizeof(system_exceptions)/sizeof(SystemExceptionRec); static BuiltinExceptionRec builtin_exceptions[] = { { "IDL:omg.org/PortableServer/POA/AdapterAlreadyExists:1.0", "PortableServer::POA::AdapterAlreadyExists" }, { "IDL:omg.org/PortableServer/POA/AdapterInactive:1.0", "PortableServer::POA::AdapterInactive" }, { "IDL:omg.org/PortableServer/POA/AdapterNonExistant:1.0", "PortableServer::POA::AdapterNonExistant" }, { "IDL:omg.org/PortableServer/POA/InvalidPolicy:1.0", "PortableServer::POA::InvalidPolicy" }, { "IDL:omg.org/PortableServer/POA/NoServant:1.0", "PortableServer::POA::NoServant" }, { "IDL:omg.org/PortableServer/POA/ObjectAlreadyActive:1.0", "PortableServer::POA::ObjectAlreadyActive" }, { "IDL:omg.org/PortableServer/POA/ObjectNotActive:1.0", "PortableServer::POA::ObjectNotActive" }, { "IDL:omg.org/PortableServer/POA/ServantAlreadyActive:1.0", "PortableServer::POA::ServantAlreadyActive" }, { "IDL:omg.org/PortableServer/POA/ServantNotActive:1.0", "PortableServer::POA::ServantNotActive" }, { "IDL:omg.org/PortableServer/POA/WrongAdapter:1.0", "PortableServer::POA::WrongAdapter" }, { "IDL:omg.org/PortableServer/POA/WrongPolicy:1.0", "PortableServer::POA::WrongPolicy" }, { "IDL:omg.org/PortableServer/POAManager/AdapterInactive:1.0", "PortableServer::POAManager::AdapterInactive" }, { "IDL:omg.org/PortableServer/Current/NoContext:1.0", "PortableServer::Current::NoContext" }, { "IDL:omg.org/CORBA/TypeCode/Bounds:1.0", "CORBA::TypeCode::Bounds" }, { "IDL:omg.org/CORBA/TypeCode/BadKind:1.0", "CORBA::TypeCode::BadKind" }, }; static const int num_builtin_exceptions = sizeof(builtin_exceptions)/sizeof(BuiltinExceptionRec); static HV *exceptions_hv; /* Takes ownership of exception object */ void porbit_throw (SV *e) { dSP; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(e)); PUTBACK; perl_call_pv("Error::throw", G_DISCARD); fprintf(stderr,"panic: Exception throw returned!"); exit(1); SPAGAIN; FREETMPS; LEAVE; } const char * porbit_find_exception (const char *repoid) { dTHR; SV **svp; if (!exceptions_hv) return NULL; svp = hv_fetch (exceptions_hv, (char *)repoid, strlen(repoid), 0); if (!svp) return NULL; return SvPV(*svp, PL_na); } void porbit_setup_exception (const char *repoid, const char *pkg, const char *parent) { char *varname; SV *sv; AV *av; if (!exceptions_hv) exceptions_hv = newHV(); /* Check if this package has been set up (FIXME: this isn't really * necessary, since we do it in define_exception) */ if (porbit_find_exception (repoid)) return; varname = g_strconcat (pkg, "::_repoid", NULL); sv = perl_get_sv (varname, TRUE); sv_setsv (sv, newSVpv((char *)repoid, 0)); g_free (varname); varname = g_strconcat (pkg, "::ISA", NULL); av = perl_get_av (varname, TRUE); av_push (av, newSVpv((char *)parent, 0)); g_free (varname); hv_store (exceptions_hv, (char *)repoid, strlen(repoid), newSVpv((char *)pkg, 0), 0); } void porbit_init_exceptions (void) { int i; for (i=1; i_major) { case CORBA_NO_EXCEPTION: return NULL; case CORBA_USER_EXCEPTION: if (!strcmp (repoid, ex_PortableServer_POA_InvalidPolicy)) { PortableServer_POA_InvalidPolicy *ipex = (PortableServer_POA_InvalidPolicy *)CORBA_exception_value (ev); AV *av = newAV(); av_push(av, newSVpv("index", 0)); av_push(av, newSViv(ipex->index)); return porbit_user_except (repoid, (SV *)av); } else return porbit_user_except (repoid, (SV *)newAV()); default: sysex = (CORBA_SystemException *)CORBA_exception_value (ev); return porbit_system_except (repoid, sysex->minor, sysex->completed); } }