Skip to content

Commit 3e2ff73

Browse files
committed
Add exception handling code to flc
1 parent af8ee0b commit 3e2ff73

File tree

9 files changed

+212
-17
lines changed

9 files changed

+212
-17
lines changed

src/flc.i

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,23 @@
2424

2525
%flc_add_header
2626

27+
/************************
28+
* Exception handling
29+
************************/
30+
31+
/* Rename the error variables' internal C symbols */
32+
#define SWIG_FORTRAN_ERROR_INT flc_ierr
33+
#define SWIG_FORTRAN_ERROR_STR flc_get_serr
34+
35+
/* Restore names in the wrapper code */
36+
%rename(ierr) flc_ierr;
37+
%rename(get_serr) flc_get_serr;
38+
39+
/* Unless we're directly building this module, delay exception handling */
40+
#ifndef SWIGIMPORTED
41+
%include <exception.i>
42+
#endif
43+
2744
/******************************
2845
* Data types and instantiation
2946
******************************/

src/flc_algorithm.i

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
*/
77

88
%module "flc_algorithm"
9-
%import "flc.i"
10-
%flc_add_header
9+
%include "import_flc.i"
1110

1211
%{
1312
#include <algorithm>

src/flc_chrono.i

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
*/
77

88
%module "flc_chrono"
9-
%import "flc.i"
10-
%flc_add_header
9+
%include "import_flc.i"
1110

1211
%{
1312
#include <chrono>

src/flc_random.i

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
*/
77

88
%module "flc_random"
9-
%import "flc.i"
10-
%flc_add_header
9+
%include "import_flc.i"
1110

1211
/******************************
1312
* Generator definition

src/generated/flc.f90

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ module flc
1414
private
1515

1616
! DECLARATION CONSTRUCTS
17+
integer(C_INT), public, &
18+
bind(C, name="flc_ierr") :: ierr
1719
type, bind(C) :: SwigArrayWrapper
1820
type(C_PTR), public :: data = C_NULL_PTR
1921
integer(C_SIZE_T), public :: size = 0
2022
end type
23+
public :: get_serr
2124
public :: get_flibcpp_version
2225
integer(C_INT), protected, public, &
2326
bind(C, name="flibcpp_version_major") :: flibcpp_version_major
@@ -33,6 +36,14 @@ subroutine SWIG_free(cptr) &
3336
use, intrinsic :: ISO_C_BINDING
3437
type(C_PTR), value :: cptr
3538
end subroutine
39+
function swigc_get_serr() &
40+
bind(C, name="_wrap_get_serr") &
41+
result(fresult)
42+
use, intrinsic :: ISO_C_BINDING
43+
import :: swigarraywrapper
44+
type(SwigArrayWrapper) :: fresult
45+
end function
46+
3647
function swigc_flibcpp_version_get() &
3748
bind(C, name="_wrap_flibcpp_version_get") &
3849
result(fresult)
@@ -60,6 +71,17 @@ subroutine SWIGTM_fout_const_SS_char_Sm_(imout, fout)
6071
end do
6172
end subroutine
6273

74+
function get_serr() &
75+
result(swig_result)
76+
use, intrinsic :: ISO_C_BINDING
77+
character(kind=C_CHAR, len=:), allocatable :: swig_result
78+
type(SwigArrayWrapper) :: fresult
79+
80+
fresult = swigc_get_serr()
81+
call SWIGTM_fout_const_SS_char_Sm_(fresult, swig_result)
82+
if (.false.) call SWIG_free(fresult%data)
83+
end function
84+
6385
function get_flibcpp_version() &
6486
result(swig_result)
6587
use, intrinsic :: ISO_C_BINDING

src/generated/flcFORTRAN_wrap.cxx

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,38 @@ template <typename T> T SwigValueInit() {
192192
#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \
193193
{ throw std::logic_error("In " DECL ": " MSG); }
194194

195+
/* Errors in SWIG */
196+
#define SWIG_UnknownError -1
197+
#define SWIG_IOError -2
198+
#define SWIG_RuntimeError -3
199+
#define SWIG_IndexError -4
200+
#define SWIG_TypeError -5
201+
#define SWIG_DivisionByZero -6
202+
#define SWIG_OverflowError -7
203+
#define SWIG_SyntaxError -8
204+
#define SWIG_ValueError -9
205+
#define SWIG_SystemError -10
206+
#define SWIG_AttributeError -11
207+
#define SWIG_MemoryError -12
208+
#define SWIG_NullReferenceError -13
209+
210+
211+
212+
213+
#ifdef __cplusplus
214+
extern "C" {
215+
#endif
216+
void SWIG_check_unhandled_exception_impl(const char* decl);
217+
void SWIG_store_exception(const char* decl, int errcode, const char *msg);
218+
#ifdef __cplusplus
219+
}
220+
#endif
221+
222+
223+
#undef SWIG_exception_impl
224+
#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \
225+
SWIG_store_exception(DECL, CODE, MSG); RETURNNULL;
226+
195227

196228
#include <stdexcept>
197229

@@ -213,23 +245,15 @@ template <typename T> T SwigValueInit() {
213245
#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a))
214246

215247

216-
#include <cstdint>
217-
using std::int32_t;
218-
using std::int64_t;
219-
using std::size_t;
220248

249+
extern "C" {
221250

222-
#include <stdint.h>
223-
251+
int flc_ierr = 0;
224252

225-
extern "C" {
226-
extern const char flibcpp_version[];
227-
extern const int flibcpp_version_major;
228-
extern const int flibcpp_version_minor;
229-
extern const int flibcpp_version_patch;
230253
}
231254

232255

256+
233257
#include <stdlib.h>
234258
#ifdef _MSC_VER
235259
# ifndef strtoull
@@ -257,7 +281,93 @@ SWIGINTERN SwigArrayWrapper SwigArrayWrapper_uninitialized() {
257281

258282
#include <string.h>
259283

284+
285+
// Stored exception message
286+
SWIGINTERN const char* swig_last_exception_cstr = NULL;
287+
// Retrieve error message
288+
SWIGEXPORT const char* flc_get_serr() {
289+
if (!swig_last_exception_cstr) {
290+
SWIG_store_exception("UNKNOWN", SWIG_RuntimeError,
291+
"no error string was present");
292+
}
293+
return swig_last_exception_cstr;
294+
}
295+
296+
297+
#include <string>
298+
299+
300+
#include <cctype>
301+
302+
303+
extern "C" {
304+
// Call this function before any new action
305+
SWIGEXPORT void SWIG_check_unhandled_exception_impl(const char* decl) {
306+
if (flc_ierr != 0) {
307+
// Construct message; calling the error string function ensures that
308+
// the string is allocated if the user did something goofy like
309+
// manually setting the integer. Since this function is not expected to
310+
// be wrapped by a catch statement, it will probably terminate the
311+
// program.
312+
std::string msg("An unhandled exception occurred before a call to ");
313+
msg += decl;
314+
msg += "; ";
315+
std::string prev_msg = flc_get_serr();
316+
prev_msg[0] = std::tolower(prev_msg[0]);
317+
msg += prev_msg;
318+
throw std::runtime_error(msg);
319+
}
320+
}
321+
322+
// Save an exception to the fortran error code and string
323+
SWIGEXPORT void SWIG_store_exception(const char *decl,
324+
int errcode,
325+
const char *msg) {
326+
::flc_ierr = errcode;
327+
328+
static std::string last_exception_msg;
329+
// Save the message to a std::string first
330+
last_exception_msg = "In ";
331+
last_exception_msg += decl;
332+
last_exception_msg += ": ";
333+
last_exception_msg += msg;
334+
swig_last_exception_cstr = last_exception_msg.c_str();
335+
}
336+
}
337+
338+
339+
#include <typeinfo>
340+
#include <stdexcept>
341+
342+
343+
#include <cstdint>
344+
using std::int32_t;
345+
using std::int64_t;
346+
using std::size_t;
347+
348+
349+
#include <stdint.h>
350+
351+
260352
extern "C" {
353+
extern const char flibcpp_version[];
354+
extern const int flibcpp_version_major;
355+
extern const int flibcpp_version_minor;
356+
extern const int flibcpp_version_patch;
357+
}
358+
359+
extern "C" {
360+
SWIGEXPORT SwigArrayWrapper _wrap_get_serr() {
361+
SwigArrayWrapper fresult ;
362+
char *result = 0 ;
363+
364+
result = (char *)flc_get_serr();
365+
fresult.size = strlen(reinterpret_cast< const char* >(result));
366+
fresult.data = const_cast< char * >(result);
367+
return fresult;
368+
}
369+
370+
261371
SWIGEXPORT SwigArrayWrapper _wrap_flibcpp_version_get() {
262372
SwigArrayWrapper fresult ;
263373
char *result = 0 ;

src/generated/flc_algorithmFORTRAN_wrap.cxx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,21 @@ template <typename T> T SwigValueInit() {
193193
{ throw std::logic_error("In " DECL ": " MSG); }
194194

195195

196+
#ifdef __cplusplus
197+
extern "C" {
198+
#endif
199+
void SWIG_check_unhandled_exception_impl(const char* decl);
200+
void SWIG_store_exception(const char* decl, int errcode, const char *msg);
201+
#ifdef __cplusplus
202+
}
203+
#endif
204+
205+
206+
#undef SWIG_exception_impl
207+
#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \
208+
SWIG_store_exception(DECL, CODE, MSG); RETURNNULL;
209+
210+
196211
enum SwigMemFlags {
197212
SWIG_MEM_OWN = 0x01,
198213
SWIG_MEM_RVALUE = 0x02,

src/generated/flc_randomFORTRAN_wrap.cxx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,21 @@ template <typename T> T SwigValueInit() {
193193
{ throw std::logic_error("In " DECL ": " MSG); }
194194

195195

196+
#ifdef __cplusplus
197+
extern "C" {
198+
#endif
199+
void SWIG_check_unhandled_exception_impl(const char* decl);
200+
void SWIG_store_exception(const char* decl, int errcode, const char *msg);
201+
#ifdef __cplusplus
202+
}
203+
#endif
204+
205+
206+
#undef SWIG_exception_impl
207+
#define SWIG_exception_impl(DECL, CODE, MSG, RETURNNULL) \
208+
SWIG_store_exception(DECL, CODE, MSG); RETURNNULL;
209+
210+
196211
enum SwigMemFlags {
197212
SWIG_MEM_OWN = 0x01,
198213
SWIG_MEM_RVALUE = 0x02,

src/import_flc.i

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*!
2+
* \file import_flc.i
3+
*
4+
* Copyright (c) 2019 Oak Ridge National Laboratory, UT-Battelle, LLC.
5+
* Distributed under an MIT open source license: see LICENSE for details.
6+
*/
7+
8+
#ifdef SWIGIMPORTED
9+
#error "To use this header, %include "import_flc.i", don't %import it"
10+
#endif
11+
12+
// Set up macros, etc.
13+
%import "flc.i"
14+
15+
// Support external exceptions
16+
%include <extern_exception.i>
17+
18+
// Instantiate header
19+
%flc_add_header

0 commit comments

Comments
 (0)