summaryrefslogtreecommitdiff
path: root/ACE/ACEXML/common/XML_Macros.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ACEXML/common/XML_Macros.h')
-rw-r--r--ACE/ACEXML/common/XML_Macros.h456
1 files changed, 456 insertions, 0 deletions
diff --git a/ACE/ACEXML/common/XML_Macros.h b/ACE/ACEXML/common/XML_Macros.h
new file mode 100644
index 00000000000..9ee1e90c196
--- /dev/null
+++ b/ACE/ACEXML/common/XML_Macros.h
@@ -0,0 +1,456 @@
+// -*- C++ -*-
+
+// ============================================================================
+/**
+ * @file XML_Macros.h
+ *
+ * $Id$
+ *
+ * Writing code that is portable between platforms with or without
+ * native C++ exceptions is hard. The following macros offer some
+ * help on this task.
+ *
+ * @author Nanbor Wang <nanbor@cs.wustl.edu>
+ * @author Aniruddha Gokhale <gokhale@sahyadri.research.bell-labs.com>
+ * @author Carlos O'Ryan <coryan@uci.edu>
+ * @author Krishnakumar B <kitty@cs.wustl.edu>, et al.
+ */
+// ============================================================================
+
+// Macros for handling exceptions.
+
+#ifndef _ACEXML_MACROS_H
+#define _ACEXML_MACROS_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/config-all.h"
+
+# if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+# endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Exception_Macros.h"
+
+// The Windows MFC exception mechanism requires that a caught CException
+// (including the CMemoryException in use here) be freed using its Delete()
+// method. Thus, when MFC is in use and we're catching exceptions as a result
+// of new(), the exception's Delete() method has to be called. No other
+// platform imposes this sort of restriction/requirement. The Windows
+// config stuff (at least for MSVC/MFC) defines a ACE_del_bad_alloc macro
+// that works with its ACE_bad_alloc macro to implement this cleanup
+// requirement. Since no other platform requires this, define it as
+// empty here.
+#if !defined (ACE_del_bad_alloc)
+# define ACE_del_bad_alloc
+#endif
+
+// The following macros assume that an environment variable is passed
+// in/out of each function that can throw an exception. The type of the
+// environment variable is defined by ACEXML_ENV_TYPE.
+
+#if !defined (ACEXML_ENV_TYPE)
+# define ACEXML_ENV_TYPE ACEXML_Env
+#endif /* ACEXML_ENV_TYPE */
+
+// The name of the variable defined by ACEXML_TRY_ENV. Below is the name
+// that we use by default. If you wish to change it you can redefine
+// ACEXML_TRY_ENV to change the default name. Also ACEXML_ADOPT_ENV allows the
+// use of non-standard name within a scope.
+
+#if !defined (ACEXML_TRY_ENV)
+# define ACEXML_TRY_ENV _ACEXML_Env_variable
+#endif /* ACEXML_TRY_ENV */
+
+// The base type of Exception from which all the other exception types are
+// derived. By default, it is set to ACEXML_Exception.
+
+#if !defined (ACEXML_EXCEPTION_TYPE)
+# define ACEXML_EXCEPTION_TYPE ACEXML_Exception
+#endif /* ACEXML_EXCEPTION_TYPE */
+
+// This is the exception caught by ACEXML_CATCHANY.
+#if !defined (ACEXML_ANY_EXCEPTION)
+# define ACEXML_ANY_EXCEPTION ex
+#endif /* ACEXML_ANY_EXCEPTION */
+
+// Declare a new environment variable on the stack. The type of the
+// environment variable is determined by ACEXML_ENV_TYPE.
+#define ACEXML_DECLARE_NEW_ENV \
+ ACEXML_ENV_TYPE ACEXML_TRY_ENV
+
+#if defined (ACE_USES_NATIVE_EXCEPTIONS)
+// -----------------------------------------------------------------
+
+#define ACEXML_ADOPT_ENV (ENV)
+
+// No need to check. Native exceptions handle the control flow
+// automatically when an exception occurs.
+# define ACEXML_CHECK
+
+// Used when the function requires a return value.
+# define ACEXML_CHECK_RETURN(RETV)
+
+// ACEXML_THROW_R_INT should not be used by the user.
+# define ACEXML_THROW_R_INT(EXCEPTION) \
+ throw EXCEPTION
+
+// Throwing an exception is easy. These two macros should _NOT_ be
+// used within try blocks.
+# define ACEXML_THROW(EXCEPTION) \
+ throw EXCEPTION
+
+// Throwing an exception when the function reqires a return value.
+# if defined (__HP_aCC)
+# define ACEXML_THROW_RETURN(EXCEPTION, RETV) \
+ do \
+ { \
+ throw EXCEPTION; \
+ return RETV; \
+ } while (0)
+# else /* WIN32 */
+# define ACEXML_THROW_RETURN(EXCEPTION,RETV) \
+ throw EXCEPTION
+# endif /* WIN32 */
+
+// For compilers with native exceptions, we can simply use try to try. ;-)
+// do {} while (0) is required to avoid compilation warnings.
+# define ACEXML_TRY \
+ do \
+ { \
+ try \
+ {
+# define ACEXML_TRY_NEW_ENV \
+ do \
+ { \
+ ACEXML_ENV_TYPE ACEXML_TRY_ENV; \
+ try \
+ {
+# define ACEXML_TRY_EX(LABEL) \
+ do \
+ { \
+ try \
+ {
+
+// No need to check for exceptions within try block for compilers with
+// native exceptions.
+# define ACEXML_TRY_CHECK
+# define ACEXML_TRY_CHECK_EX(LABEL)
+
+// Likewise, throwing exceptions within try blocks is easy.
+# define ACEXML_TRY_THROW(EXCEPTION) throw EXCEPTION
+# define ACEXML_TRY_THROW_EX(EXCEPTION,LABEL) throw EXCEPTION
+
+// Same thing for catch.
+# define ACEXML_CATCH(EXCEPTION,VAR) \
+ } \
+ catch (EXCEPTION & VAR) \
+ { \
+ ACE_UNUSED_ARG (VAR);
+
+# define ACEXML_CATCHANY \
+ ACEXML_CATCH(ACEXML_EXCEPTION_TYPE, ACEXML_ANY_EXCEPTION)
+
+# define ACEXML_CATCHALL \
+ } \
+ catch (...) \
+ {
+
+// Rethrowing the exception from catch blocks.
+# define ACEXML_RE_THROW throw
+# define ACEXML_RE_THROW_EX(LABEL) throw
+
+// Close the catch block.
+# define ACEXML_ENDTRY \
+ } \
+ } while (0)
+
+#else /* ! ACEXML_USES_NATIVE_EXCEPTIONS */
+// -----------------------------------------------------------------
+
+// When handling compilers without native exceptions, things get a bit
+// hairy. Exceptions are simulated using ACEXML_ENV_TYPE. The trick here is to
+// make sure the flow-of-control can simulate the case when native
+// exceptions occur...
+
+# define ACEXML_ADOPT_ENV(ENV) ACEXML_ENV_TYPE &ACEXML_TRY_ENV = ENV
+
+// Follow every statement that could throw exceptions with ACEXML_CHECK or
+// ACEXML_CHECK_RETURN. These two macros should _NOT_ be used within try
+// blocks. Use ACEXML_TRY_CHECK or ACEXML_TRY_CHECK_EX instead.
+# define ACEXML_CHECK \
+ if (ACEXML_TRY_ENV . exception () != 0) \
+ return
+// When function requires a return value
+# define ACEXML_CHECK_RETURN(RETV) \
+ if (ACEXML_TRY_ENV . exception () != 0) \
+ return RETV
+
+// ACEXML_THROW_R_INT should not be used by the user.
+# define ACEXML_THROW_R_INT(EXCEPTION) ACEXML_TRY_ENV.exception (new EXCEPTION)
+
+// Throwing exceptions will inevitably cause a return from the current
+// function. These two macros should _NOT_ be used within try blocks. Use
+// ACEXML_TRY_THROW or ACEXML_TRY_THROW_EX instead.
+# define ACEXML_THROW(EXCEPTION) \
+ do \
+ { \
+ ACEXML_TRY_ENV.exception (new EXCEPTION); \
+ return; \
+ } while (0)
+
+# define ACEXML_THROW_RETURN(EXCEPTION,RETV) \
+ do \
+ { \
+ ACEXML_TRY_ENV.exception (new EXCEPTION); \
+ return RETV; \
+ } while (0)
+
+// ACEXML_TRY sets up flags to control program flow. ACEXML_TRY_FLAG acts
+// like a one-shot flip-flop. When an exception occurs (detected using
+// ACEXML_TRY_CHECK,) ACEXML_TRY_FLAG will be reset and the control goes
+// back into ACEXML_TRY_LABEL. Since ACEXML_TRY_FLAG is reset, the try
+// block won't get executed again and the control proceeds to the following
+// catch blocks. ACEXML_EXCEPTION_NOT_CAUGHT flag is used to prevent
+// catching an exception twice. This macro assumes there's already an
+// ACEXML_ENV_TYPE variable ACEXML_TRY_ENV defined (which should be the
+// case normally)
+# define ACEXML_TRY \
+ do { \
+ int ACEXML_TRY_FLAG = 1; \
+ int ACEXML_EXCEPTION_NOT_CAUGHT = 1; \
+ ACEXML_TRY_LABEL: \
+ if (ACEXML_TRY_FLAG) \
+ do {
+
+// ACEXML_TRY_NEW_ENV functions like the macro ACEXML_TRY but defines a new
+// ACEXML_ENV_TYPE variable ACEXML_TRY_ENV. It is most often used in the outer
+// most function where no ACEXML_TRY_ENV is available.
+# define ACEXML_TRY_NEW_ENV \
+ do { \
+ ACEXML_ENV_TYPE ACEXML_TRY_ENV;\
+ int ACEXML_TRY_FLAG = 1; \
+ int ACEXML_EXCEPTION_NOT_CAUGHT = 1; \
+ ACEXML_TRY_LABEL: \
+ if (ACEXML_TRY_FLAG) \
+ do {
+
+// ACEXML_TRY_EX works exactly like ACEXML_TRY macro except the label used
+// in the try block is customizable to avoid name clashing. It should be
+// used when nested try blocks or multiple try blocks are required, in the
+// same function.
+# define ACEXML_TRY_EX(LABEL) \
+ do { \
+ int ACEXML_TRY_FLAG = 1; \
+ int ACEXML_EXCEPTION_NOT_CAUGHT = 1; \
+ ACEXML_TRY_LABEL ## LABEL: \
+ if (ACEXML_TRY_FLAG) \
+ do {
+
+// Check for exceptions within try blocks.
+# define ACEXML_TRY_CHECK \
+ { \
+ if (ACEXML_TRY_ENV.exception () != 0) \
+ { \
+ ACEXML_TRY_FLAG = 0; \
+ goto ACEXML_TRY_LABEL; \
+ } \
+ }
+
+// Checking exception within EX try blocks.
+# define ACEXML_TRY_CHECK_EX(LABEL) \
+ { \
+ if (ACEXML_TRY_ENV.exception () != 0) \
+ { \
+ ACEXML_TRY_FLAG = 0; \
+ goto ACEXML_TRY_LABEL ## LABEL; \
+ } \
+ }
+
+// Throwing exception within TRY blocks.
+# define ACEXML_TRY_THROW(EXCEPTION) \
+ { \
+ ACEXML_TRY_ENV.exception (new EXCEPTION); \
+ ACEXML_TRY_FLAG = 0; \
+ goto ACEXML_TRY_LABEL; \
+ }
+
+# define ACEXML_TRY_THROW_EX(EXCEPTION,LABEL) \
+ { \
+ ACEXML_TRY_ENV.exception (new EXCEPTION); \
+ ACEXML_TRY_FLAG = 0; \
+ goto ACEXML_TRY_LABEL ## LABEL; \
+ }
+
+// When exceptions occur or try block finishes execution without exception,
+// control will continue in the catch block. This macro first checks if
+// there's any uncaught exception left. If all the conditions are met, we
+// have caught an exception. It then resets ACEXML_EXCEPTION_NOT_CAUGHT to
+// prevent subsequent catch blocks from catching the same exception again,
+// and extracts out the underlying exception in ACEXML_TRY_ENV. We also make a
+// copy of ACEXML_TRY_ENV in ACEXML_CAUGHT_ENV, in case we want to rethrow the
+// exception. ACEXML_TRY_ENV is cleared out after the exception is caught so
+// you should not use ACEXML_TRY_ENV within the catch block(You should use the
+// exception directly).
+# define ACEXML_CATCH(TYPE,VAR) \
+ } while (0); \
+ do \
+ if (ACEXML_TRY_ENV.exception () != 0 && ACEXML_EXCEPTION_NOT_CAUGHT && \
+ TYPE::_downcast(ACEXML_TRY_ENV.exception ()) != 0) \
+ { \
+ ACEXML_ENV_TYPE ACEXML_CAUGHT_ENV = ACEXML_TRY_ENV;\
+ ACEXML_EXCEPTION_NOT_CAUGHT = 0; \
+ TYPE &VAR = *TYPE::_downcast (ACEXML_CAUGHT_ENV.exception ()); \
+ ACE_UNUSED_ARG (VAR); \
+ ACEXML_TRY_ENV.clear ();
+
+// ACEXML_CATCHANY uses ACEXML_CATCH to catch all exceptions derived from
+// ACEXML_EXCEPTION_TYPE
+# define ACEXML_CATCHANY ACEXML_CATCH (ACEXML_EXCEPTION_TYPE, ACEXML_ANY_EXCEPTION)
+
+// Since there's no other exception for compilers without exception
+// support, we simply catch all ACEXML_EXCEPTION_TYPE exceptions for
+// ACEXML_CATCHALL.
+# define ACEXML_CATCHALL ACEXML_CATCHANY
+
+// Rethrowing exception within catch blocks. Notice that we depend on the
+// ACEXML_CHECK/ACEXML_CHECK_RETURN following the ACEXML_ENDTRY, or
+// ACEXML_TRY_CHECK/ ACEXML_TRY_CHECK_EX following the ACEXML_ENDTRY when
+// the catch block is within another try block, to do the "Right
+// Thing[TM]."
+# define ACEXML_RE_THROW \
+ do {\
+ ACEXML_TRY_ENV = ACEXML_CAUGHT_ENV; \
+ goto ACEXML_TRY_LABEL; \
+ } while (0)
+# define ACEXML_RE_THROW_EX(LABEL) \
+ do {\
+ ACEXML_TRY_ENV = ACEXML_CAUGHT_ENV; \
+ goto ACEXML_TRY_LABEL ## LABEL; \
+ } while (0)
+
+// Close the try block. Since exceptions may not get caught, and exceptions
+// can also be rethrown from the catch block, it's always a good idea to
+// follow ACEXML_ENDTRY with ACEXML_CHECK or ACEXML_TRY_CHECK (depending on
+// the context.)
+# define ACEXML_ENDTRY \
+ } while (0); \
+ } while (0)
+
+#endif /* ! ACE_USES_NATIVE_EXCEPTIONS */
+
+// ACE_HAS_EXCEPTIONS is not the same as ACE_NEW_THROWS_EXCEPTIONS.
+#if defined(ACE_NEW_THROWS_EXCEPTIONS)
+
+# define ACEXML_NEW_THROW_EX(POINTER,CONSTRUCTOR,EXCEPTION) \
+ do { try { POINTER = new CONSTRUCTOR; } \
+ catch (ACE_bad_alloc) { ACE_del_bad_alloc errno = ENOMEM; ACEXML_THROW_R_INT (EXCEPTION); } \
+ } while (0)
+
+#else /* ! ACE_NEW_THROWS_EXCEPTIONS */
+
+# define ACEXML_NEW_THROW_EX(POINTER,CONSTRUCTOR,EXCEPTION) \
+ do { POINTER = new CONSTRUCTOR; \
+ if (POINTER == 0) { errno = ENOMEM; ACEXML_THROW_R_INT (EXCEPTION); } \
+ } while (0)
+
+#endif /* ACE_NEW_THROWS_EXCEPTIONS */
+
+# define ACEXML_GUARD_THROW_EX(MUTEX,OBJ,LOCK,EXCEPTION) \
+ ACE_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) ACEXML_THROW_R_INT (EXCEPTION);
+
+# define ACEXML_READ_GUARD_THROW_EX(MUTEX,OBJ,LOCK,EXCEPTION) \
+ ACE_Read_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) ACEXML_THROW_R_INT (EXCEPTION);
+
+# define ACEXML_WRITE_GUARD_THROW_EX(MUTEX,OBJ,LOCK,EXCEPTION) \
+ ACE_Write_Guard< MUTEX > OBJ (LOCK); \
+ if (OBJ.locked () == 0) ACEXML_THROW_R_INT (EXCEPTION);
+
+//@{
+/**
+ * @name Native C++ exceptions portability macros.
+ *
+ * The following macros are used to write code portable between platforms
+ * with and without native C++ exception support. Their main goal is to
+ * hide the presence of the ACEXML_ENV_TYPE argument, but they collaborate
+ * with the ACEXML_TRY_* macros to emulate the try/catch blocks.
+ */
+
+/// Define a macro to emit code only when ACEXML_ENV_TYPE is used
+#if !defined (ACE_USES_NATIVE_EXCEPTIONS) || defined (ACEXML_ENV_BKWD_COMPAT)
+# define ACEXML_ENV_EMIT_CODE(X) X
+#else
+# define ACEXML_ENV_EMIT_CODE(X)
+#endif /* ACE_USES_NATIVE_EXCEPTIONS && ! ACEXML_ENV_BKWD_COMPAT */
+
+/// Another macro to emit code only when ACEXML_ENV_TYPE is used
+#if !defined (ACE_USES_NATIVE_EXCEPTIONS) || defined (ACEXML_ENV_BKWD_COMPAT)
+# define ACEXML_ENV_EMIT_CODE2(X,Y) X,Y
+#else
+# define ACEXML_ENV_EMIT_CODE2(X,Y)
+#endif /* ACE_USES_NATIVE_EXCEPTIONS && ! ACEXML_ENV_BKWD_COMPAT */
+
+/// Helper macro
+#define ACEXML_ENV_EMIT_DUMMY
+
+/// Declare a ACEXML_ENV_TYPE argument as the last argument of a
+/// function
+/**
+ * Normally this macro is used as follows:
+ *
+ * <CODE>void my_funct (int x, int y ACEXML_ENV_ARG_DECL);</CODE>
+ *
+ * Its purpose is to provide developers (and users) with a mechanism to
+ * write code that is portable to platforms with and without native C++
+ * exceptions.
+ */
+#define ACEXML_ENV_ARG_DECL \
+ ACEXML_ENV_EMIT_CODE2(ACEXML_ENV_EMIT_DUMMY, \
+ ACEXML_ENV_TYPE &ACEXML_TRY_ENV)
+
+/// Declare a ACEXML_ENV_TYPE argument that is not used by the
+/// function definition.
+/**
+ * Similar to ACEXML_ENV_ARG_DECL, but the formal parameter name is dropped to
+ * avoid warnings about unused parameters
+ */
+#define ACEXML_ENV_ARG_DECL_NOT_USED \
+ ACEXML_ENV_EMIT_CODE2(ACEXML_ENV_EMIT_DUMMY, \
+ ACEXML_ENV_TYPE &)
+
+/// Declare a ACEXML_ENV_TYPE argument for methods that do not take any other
+/// parameters
+#define ACEXML_ENV_SINGLE_ARG_DECL \
+ ACEXML_ENV_EMIT_CODE(ACEXML_ENV_TYPE &ACEXML_TRY_ENV)
+
+/// Declare a ACEXML_ENV_TYPE argument for methods which don't use it.
+#define ACEXML_ENV_SINGLE_ARG_DECL_NOT_USED \
+ ACEXML_ENV_EMIT_CODE(ACEXML_ENV_TYPE &)
+
+/// Use the ACEXML_ENV_TYPE argument in a nested call
+#define ACEXML_ENV_ARG_PARAMETER \
+ ACEXML_ENV_EMIT_CODE2(ACEXML_ENV_EMIT_DUMMY, \
+ ACEXML_TRY_ENV)
+
+/// Use the ACEXML_ENV_TYPE argument in a nested call, assuming that the
+/// called function takes only the ACEXML_TRY_ENV argument.
+#define ACEXML_ENV_SINGLE_ARG_PARAMETER \
+ ACEXML_ENV_EMIT_CODE(ACEXML_TRY_ENV)
+
+/// Eliminate unused argument warnings about ACEXML_TRY_ENV
+#define ACEXML_ENV_ARG_NOT_USED \
+ ACEXML_ENV_EMIT_CODE(ACE_UNUSED_ARG(ACEXML_TRY_ENV))
+//@}
+
+#if !defined (ACE_USES_NATIVE_EXCEPTIONS)
+// This thing can be moved above when we drop ACEXML_ENV_BKWD_COMPAT.
+# define ACEXML_ENV_RAISE(ex) ACEXML_TRY_ENV.exception (ex)
+#else
+# define ACEXML_ENV_RAISE(ex) (ex)->_raise ()
+#endif /* ACEXML_CORBA_HAS_EXCEPTIONS */
+
+#include /**/ "ace/post.h"
+
+#endif /* _ACEXML_MACROS_H */