piranna / exceptions4c

Automatically exported from code.google.com/p/exceptions4c
0 stars 0 forks source link

patch to use in a mixed C and C++ project #9

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Well, actually this is a patch (didn't find the patch button)

I wanted to throw an exception from withing a C file and handle it within C++, 
so I made the necessary changes to the header file.

Basically I added #ifdef __cplusplus extern "C" to all the function 
declarations in e4c.h, so they can be used from C++.

Additionally there were Compiler arror because PTHREAD_CANCELED was not defined 
on my system (actually I read somewhere that this is now deprecated), so I 
added a statement that defines it, if it isn't already defined.

Works pretty well, the only limitation seems to be that you can't use native 
C++ and E4C exceptions from within the same source file since the native C++ 
expressions are all overridden by the preprocessor, if e4c.h is included. 
Luckily I didn't intend this and it should only extremely rarely be necessary.

Here are the full changes (generated by SVN):

<code language="C">
Index: e4c.h
===================================================================
--- e4c.h   (.../http://exceptions4c.googlecode.com/svn/trunk/src)  (Revision 408)
+++ e4c.h   (Arbeitskopie)
@@ -51,6 +51,9 @@
 # ifndef EXCEPTIONS4C
 # define EXCEPTIONS4C

+#ifndef PTHREAD_CANCELED
+#define PTHREAD_CANCELED ((void *) -1)
+#endif

 # define E4C_VERSION_(version)         version(2, 10, 3)

@@ -2890,7 +2893,11 @@
  * @see     #e4c_using_context
  * @see     #e4c_reusing_context
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 E4C_BOOL
 e4c_context_is_ready(
    void
@@ -2955,7 +2962,11 @@
  * @see     #e4c_print_exception
  * @see     #e4c_context_set_handlers
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 void
 e4c_context_begin(
    E4C_BOOL                    handle_signals
@@ -2988,7 +2999,11 @@
  * @see     #e4c_using_context
  * @see     #e4c_reusing_context
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 void
 e4c_context_end(
    void
@@ -3048,7 +3063,11 @@
  * @see     #e4c_exception
  * @see     #e4c_print_exception
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 void
 e4c_context_set_handlers(
    /*@dependent@*/ /*@null@*/
@@ -3091,7 +3110,11 @@
  * @see     #e4c_signal_mapping
  * @see     #e4c_default_signal_mappings
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 void
 e4c_context_set_signal_mappings(
    /*@dependent@*/ /*@null@*/
@@ -3123,7 +3146,11 @@
  * @see     #e4c_signal_mapping
  * @see     #e4c_default_signal_mappings
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 /*@observer@*/ /*@null@*/
 const e4c_signal_mapping *
 e4c_context_get_signal_mappings(
@@ -3160,7 +3187,11 @@
  * @see     #e4c_get_status
  * @see     #finally
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 e4c_status
 e4c_get_status(
    void
@@ -3225,7 +3256,11 @@
  * @see     #catch
  * @see     #finally
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 /*@observer@*/ /*@relnull@*/
 const e4c_exception *
 e4c_get_exception(
@@ -3269,7 +3304,11 @@
  *
  * @see     #E4C_VERSION_NUMBER
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 long
 e4c_library_version(
    void
@@ -3315,7 +3354,11 @@
  * @see     #e4c_exception_type
  * @see     #e4c_get_exception
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 E4C_BOOL
 e4c_is_instance_of(
    /*@temp@*/ /*@notnull@*/
@@ -3359,7 +3402,11 @@
  * @see     #e4c_context_begin
  * @see     #e4c_using_context
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 void
 e4c_print_exception(
    /*@temp@*/ /*@notnull@*/
@@ -3411,7 +3458,11 @@
  *
  * @see     #e4c_exception_type
  */
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 void
 e4c_print_exception_type(
    /*@shared@*/ /*@notnull@*/
@@ -3436,9 +3487,11 @@
  * Next functions are undocumented on purpose, because they shouldn't be used
  * directly (but through the "keywords").
  */
-
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
-/*@notnull@*/ /*@temp@*/
+#endif/*@notnull@*/ /*@temp@*/
 struct e4c_continuation_ *
 e4c_frame_first_stage_(
    enum e4c_frame_stage_       stage,
@@ -3459,8 +3512,11 @@
    internalState
 @*/
 ;
-
+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 E4C_BOOL
 e4c_frame_next_stage_(
    void
@@ -3477,7 +3533,11 @@
 @*/
 ;

+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 enum e4c_frame_stage_
 e4c_frame_get_stage_(
    /*@observer@*/ /*@null@*/
@@ -3496,7 +3556,11 @@
 @*/
 ;

+#ifdef __cplusplus
+extern "C"
+#else
 /*@unused@*/ extern
+#endif
 E4C_BOOL
 e4c_frame_catch_(
    /*@temp@*/ /*@null@*/
@@ -3518,8 +3582,11 @@
    internalState
 @*/
 ;
-
-/*@unused@*/ /*@maynotreturn@*/ extern
+#ifdef __cplusplus
+extern "C"
+#else
+/*@unused@*/ /*@maynotreturn@*/extern
+#endif
 void
 e4c_frame_repeat_(
    int                         max_repeat_attempts,
@@ -3542,7 +3609,11 @@
 @*/
 ;

-/*@unused@*/ /*@noreturn@*/ extern
+#ifdef __cplusplus
+extern "C"
+#else
+/*@unused@*/ /*@maynotreturn@*/extern
+#endif
 void
 e4c_exception_throw_verbatim_(
    /*@shared@*/ /*@notnull@*/
@@ -3570,7 +3641,11 @@

 # if defined(HAVE_C99_VSNPRINTF) || defined(HAVE_VSNPRINTF)

-/*@unused@*/ /*@noreturn@*/ extern
+#ifdef __cplusplus
+extern "C"
+#else
+/*@unused@*/ /*@noreturn@*/extern
+#endif
 void
 e4c_exception_throw_format_(
    /*@shared@*/ /*@notnull@*/
</code>
(The diffs are attached as cpp.patch)

Original issue reported on code.google.com by matheoe...@web.de on 10 Jan 2013 at 2:44

Attachments:

GoogleCodeExporter commented 9 years ago
Hi there.

Thanks for the patch; actually I've just created an extern "C" block enclosing 
all the functions together.

Additionaly, I also replaced:

    pthread_exit(PTHREAD_CANCELED);

with:

    pthread_cancel( pthread_self() );

So there's no need to define PTHREAD_CANCELED anymore.

I'm setting this issue to "Accepted" and look forward to your reply. Could you 
please svn-update and confirm the library is working for you this time?

By the way, if you need to use native C++ exceptions, please define 
E4C_NOKEYWORDS and simply use E4C_TRY, E4C_CATCH, E4C_FINALLY and E4C_THROW.

Best regards.

Original comment by guillermocalvo on 11 Jan 2013 at 2:10

GoogleCodeExporter commented 9 years ago
Hi back.

Thanks for your reply; the extern "C" block is working properly.

However with the newest version I'm getting
"undefined reference to pthread_cancel" from the compiler, so I changed these 
lines back to what they were in rev408 and added my define of PTHRREAD_CANCELED.

I don't know why exactly my compile environement knows neither PTHREAD_CANCELED 
nor pthread_cancel. If you wonder which environment that is: I'm developing for 
SymbianOS with the SDK "Symbian1Qt473" and the compiler used is mingw32.

Best regards.

Original comment by matheoe...@web.de on 18 Jan 2013 at 10:58

GoogleCodeExporter commented 9 years ago
I've just added a local definition for PTHREAD_CANCELED when none is provided 
by `pthread.h`.

I also added a compile time parameter so the library is prevented from calling 
`pthread_cancel` (and therefore failing to compile in case it doesn't exist). 
You just need to define the macro MISSING_PTHREAD_CANCEL at compiler level. I 
hope this approach suits your needs.

Please let me know if you have any other issues.

Original comment by guillermocalvo on 18 Jan 2013 at 8:15

GoogleCodeExporter commented 9 years ago
It seems to be working fine.

Original comment by guillermocalvo on 3 Mar 2013 at 12:28