Define THROW_EXCEPTION(E) which takes an exception class instance, and uses it to construct an instance of a class which is a subclass of E and ExceptionMixin. The original instance is discarded, and the newly constructed sub-class is thrown. Equivalent to "throw E;". Define THROW_EXCEPTION2(ETYPE,MSG) which takes an exception class type, and argument. Directly constructs a ExceptionMixin sub-class with the given message argument. Equivalent to "throw ETYPE(MSG);". Define PRINT_EXCEPTION2(E, FP) If E is a instance of a sub-class of ExceptionMixin then write information to FP (FILE*). Define SHOW_EXCEPTION(E) If E is a instance of a sub-class of ExceptionMixin then return a std::string with information.
95 lines
2.1 KiB
C++
95 lines
2.1 KiB
C++
/* testBaseException.cpp */
|
|
/**
|
|
* Copyright - See the COPYRIGHT that is included with this distribution.
|
|
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
*/
|
|
/* Author: Matej Sekoranja Date: 2010.10.18 */
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "epicsException.h"
|
|
|
|
|
|
#include <epicsAssert.h>
|
|
|
|
using namespace epics::pvData;
|
|
|
|
struct Unroller
|
|
{
|
|
template <int N>
|
|
void unroll(double d) {
|
|
unroll<N-1>(d);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
void Unroller::unroll<0>(double d) {
|
|
THROW_BASE_EXCEPTION("the root cause");
|
|
}
|
|
|
|
void internalTestBaseException(int unused = 0)
|
|
{
|
|
try {
|
|
// NOTE: 5, 4, 3, 2, 1 calls will be optimized and not shown
|
|
Unroller().unroll<5>(42.0);
|
|
} catch (BaseException& be3) {
|
|
THROW_BASE_EXCEPTION_CAUSE("exception 1", be3);
|
|
}
|
|
}
|
|
|
|
void testBaseException(FILE *fp) {
|
|
fprintf(fp,"testBaseException... ");
|
|
|
|
try {
|
|
THROW_BASE_EXCEPTION("all is OK");
|
|
} catch (BaseException& be) {
|
|
fprintf(fp,"\n\n%s\n\n", be.what());
|
|
}
|
|
|
|
try {
|
|
try {
|
|
internalTestBaseException();
|
|
} catch (BaseException& be2) {
|
|
THROW_BASE_EXCEPTION_CAUSE("exception 2", be2);
|
|
}
|
|
} catch (BaseException& be) {
|
|
fprintf(fp,"\n\n%s\n\n", be.what());
|
|
}
|
|
|
|
fprintf(fp,"PASSED\n");
|
|
}
|
|
|
|
void testLogicException(FILE *fp) {
|
|
try {
|
|
THROW_EXCEPTION(std::logic_error("There is a logic_error"));
|
|
} catch (std::logic_error& be) {
|
|
fprintf(fp,"\n\n%s\n\n", be.what());
|
|
PRINT_EXCEPTION2(be, fp);
|
|
}
|
|
|
|
try {
|
|
THROW_EXCEPTION2(std::logic_error, "There is another logic_error");
|
|
} catch (std::logic_error& be) {
|
|
fprintf(fp,"\n\n%s\n\n", be.what());
|
|
fprintf(fp,"%s\n", SHOW_EXCEPTION(be).c_str());
|
|
}
|
|
}
|
|
|
|
int main(int argc,char *argv[])
|
|
{
|
|
FILE *fp=NULL;
|
|
if(argc>1){
|
|
fp=fopen(argv[1], "w");
|
|
if(!fp) fprintf(stderr,"Failed to open test output file\n");
|
|
}
|
|
if(!fp) fp=stdout;
|
|
testLogicException(fp);
|
|
testBaseException(fp);
|
|
return(0);
|
|
}
|
|
|