mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
145 lines
15 KiB
C
145 lines
15 KiB
C
/***********************************************************************************************************************************
|
|
Helper macros for LibC.xs
|
|
***********************************************************************************************************************************/
|
|
|
|
/***********************************************************************************************************************************
|
|
Package Names
|
|
***********************************************************************************************************************************/
|
|
#define PACKAGE_NAME "pgBackRest"
|
|
#define PACKAGE_NAME_LIBC PACKAGE_NAME "::LibC"
|
|
|
|
/***********************************************************************************************************************************
|
|
Load C error into ERROR_SV_error
|
|
|
|
#define FUNCTION_NAME_ERROR "libcExceptionNew"
|
|
|
|
#define ERROR_SV() \
|
|
SV *ERROR_SV_error; \
|
|
\
|
|
{ \
|
|
// Push parameters onto the Perl stack \
|
|
ENTER; \
|
|
SAVETMPS; \
|
|
PUSHMARK(SP); \
|
|
EXTEND(SP, 2); \
|
|
PUSHs(sv_2mortal(newSViv(errorCode()))); \
|
|
PUSHs(sv_2mortal(newSVpv(errorMessage(), 0))); \
|
|
PUTBACK; \
|
|
\
|
|
// Call error function \
|
|
int count = call_pv(PACKAGE_NAME_LIBC "::" FUNCTION_NAME_ERROR, G_SCALAR); \
|
|
SPAGAIN; \
|
|
\
|
|
// Check that correct number of parameters was returned \
|
|
if (count != 1) \
|
|
croak("expected 1 return value from " FUNCTION_NAME_ERROR "()"); \
|
|
\
|
|
// Make a copy of the error that can be returned \
|
|
ERROR_SV_error = newSVsv(POPs); \
|
|
\
|
|
// Clean up the stack \
|
|
PUTBACK; \
|
|
FREETMPS; \
|
|
LEAVE; \
|
|
}
|
|
|
|
This turned out to be a dead end because Perl 5.10 does not support croak_sv(), but this code has been kept for example purposes.
|
|
***********************************************************************************************************************************/
|
|
|
|
/***********************************************************************************************************************************
|
|
Error handling macros that throw a Perl error when a C error is caught
|
|
***********************************************************************************************************************************/
|
|
#define ERROR_XS_BEGIN() \
|
|
ERROR_TRY()
|
|
|
|
#define ERROR_XS() \
|
|
croak("PGBRCLIB:%d:%s:%d:%s", errorCode(), errorFileName(), errorFileLine(), errorMessage());
|
|
|
|
#define ERROR_XS_END() \
|
|
ERROR_CATCH_ANY() \
|
|
{ \
|
|
ERROR_XS(); \
|
|
}
|
|
|
|
/***********************************************************************************************************************************
|
|
Core context handling macros, only intended to be called from other macros
|
|
***********************************************************************************************************************************/
|
|
#define MEM_CONTEXT_XS_CORE_BEGIN(memContext) \
|
|
/* Switch to the new memory context */ \
|
|
MemContext *MEM_CONTEXT_XS_memContextOld = memContextSwitch(memContext); \
|
|
\
|
|
/* Store any errors to be croaked to Perl at the end */ \
|
|
volatile bool MEM_CONTEXT_XS_croak = false; \
|
|
\
|
|
/* Try the statement block */ \
|
|
ERROR_TRY()
|
|
|
|
#define MEM_CONTEXT_XS_CORE_END() \
|
|
/* Set error to be croak to Perl later */ \
|
|
ERROR_CATCH_ANY() \
|
|
{ \
|
|
MEM_CONTEXT_XS_croak = true; \
|
|
} \
|
|
/* Free the context on error */ \
|
|
ERROR_FINALLY() \
|
|
{ \
|
|
memContextSwitch(MEM_CONTEXT_XS_memContextOld); \
|
|
}
|
|
|
|
/***********************************************************************************************************************************
|
|
Simplifies creation of the memory context in contructors and includes error handling
|
|
***********************************************************************************************************************************/
|
|
#define MEM_CONTEXT_XS_NEW_BEGIN(contextName) \
|
|
{ \
|
|
/* Attempt to create the memory context */ \
|
|
MemContext *MEM_CONTEXT_XS_memContext = NULL; \
|
|
\
|
|
ERROR_TRY() \
|
|
{ \
|
|
MEM_CONTEXT_XS_memContext = memContextNew(contextName); \
|
|
} \
|
|
ERROR_CATCH_ANY() \
|
|
{ \
|
|
ERROR_XS() \
|
|
} \
|
|
\
|
|
MEM_CONTEXT_XS_CORE_BEGIN(MEM_CONTEXT_XS_memContext)
|
|
|
|
#define MEM_CONTEXT_XS_NEW_END() \
|
|
MEM_CONTEXT_XS_CORE_END(); \
|
|
\
|
|
/* Free context and croak on error */ \
|
|
if (MEM_CONTEXT_XS_croak) \
|
|
{ \
|
|
memContextFree(MEM_CONTEXT_XS_memContext); \
|
|
\
|
|
ERROR_XS() \
|
|
} \
|
|
}
|
|
|
|
#define MEM_COMTEXT_XS() \
|
|
MEM_CONTEXT_XS_memContext
|
|
|
|
/***********************************************************************************************************************************
|
|
Simplifies switching the memory context in functions and includes error handling
|
|
***********************************************************************************************************************************/
|
|
#define MEM_CONTEXT_XS_BEGIN(memContext) \
|
|
{ \
|
|
MEM_CONTEXT_XS_CORE_BEGIN(memContext)
|
|
|
|
#define MEM_CONTEXT_XS_END() \
|
|
MEM_CONTEXT_XS_CORE_END(); \
|
|
\
|
|
/* Croak on error */ \
|
|
if (MEM_CONTEXT_XS_croak) \
|
|
{ \
|
|
ERROR_XS() \
|
|
} \
|
|
}
|
|
|
|
/***********************************************************************************************************************************
|
|
Free memory context in destructors
|
|
***********************************************************************************************************************************/
|
|
#define MEM_CONTEXT_XS_DESTROY(memContext) \
|
|
memContextFree(memContext)
|