f77-fcn.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #if !defined (octave_f77_fcn_h)
00024 #define octave_f77_fcn_h 1
00025 
00026 #include "quit.h"
00027 
00028 #ifdef __cplusplus
00029 extern "C" {
00030 #endif
00031 
00032 /* Hack to stringize macro results. */
00033 #define xSTRINGIZE(x) #x
00034 #define STRINGIZE(x) xSTRINGIZE(x)
00035 
00036 /* How to print an error for the F77_XFCN macro. */
00037 
00038 #define F77_XFCN_ERROR(f, F) \
00039   (*current_liboctave_error_handler) \
00040     ("exception encountered in Fortran subroutine %s", \
00041      STRINGIZE (F77_FUNC (f, F)))
00042 
00043 /* This can be used to call a Fortran subroutine that might call
00044    XSTOPX.  XSTOPX will call lonjmp with current_context.  Once back
00045    here, we'll restore the previous context and return.  We may also
00046    end up here if an interrupt is processed when the Fortran
00047    subroutine is called.  In that case, we resotre the context and go
00048    to the top level.  The error_state should be checked immediately
00049    after this macro is used. */
00050 
00051 #define F77_XFCN(f, F, args) \
00052   do \
00053     { \
00054       octave_jmp_buf saved_context; \
00055       sig_atomic_t saved_octave_interrupt_immediately = octave_interrupt_immediately; \
00056       f77_exception_encountered = 0; \
00057       octave_save_current_context (saved_context); \
00058       if (octave_set_current_context) \
00059         { \
00060           octave_interrupt_immediately = saved_octave_interrupt_immediately; \
00061           octave_restore_current_context (saved_context); \
00062           if (f77_exception_encountered) \
00063             F77_XFCN_ERROR (f, F); \
00064           else \
00065             octave_rethrow_exception (); \
00066         } \
00067       else \
00068         { \
00069           octave_interrupt_immediately++; \
00070           F77_FUNC (f, F) args; \
00071           octave_interrupt_immediately--; \
00072           octave_restore_current_context (saved_context); \
00073         } \
00074     } \
00075   while (0)
00076 
00077 /* So we can check to see if an exception has occurred. */
00078 CRUFT_API extern int f77_exception_encountered;
00079 
00080 #if !defined (F77_FCN)
00081 #define F77_FCN(f, F) F77_FUNC (f, F)
00082 #endif
00083 
00084 #if defined (F77_USES_CRAY_CALLING_CONVENTION)
00085 
00086 #include <fortran.h>
00087 
00088 /* Use these macros to pass character strings from C to Fortran.  */
00089 #define F77_CHAR_ARG(x) octave_make_cray_ftn_ch_dsc (x, strlen (x))
00090 #define F77_CONST_CHAR_ARG(x) \
00091   octave_make_cray_const_ftn_ch_dsc (x, strlen (x))
00092 #define F77_CHAR_ARG2(x, l) octave_make_cray_ftn_ch_dsc (x, l)
00093 #define F77_CONST_CHAR_ARG2(x, l) octave_make_cray_const_ftn_ch_dsc (x, l)
00094 #define F77_CXX_STRING_ARG(x) \
00095   octave_make_cray_const_ftn_ch_dsc (x.c_str (), x.length ())
00096 #define F77_CHAR_ARG_LEN(l)
00097 #define F77_CHAR_ARG_DECL octave_cray_ftn_ch_dsc
00098 #define F77_CONST_CHAR_ARG_DECL octave_cray_ftn_ch_dsc
00099 #define F77_CHAR_ARG_LEN_DECL
00100 
00101 /* Use these macros to write C-language functions that accept
00102    Fortran-style character strings.  */
00103 #define F77_CHAR_ARG_DEF(s, len) octave_cray_ftn_ch_dsc s
00104 #define F77_CONST_CHAR_ARG_DEF(s, len) octave_cray_ftn_ch_dsc s
00105 #define F77_CHAR_ARG_LEN_DEF(len)
00106 #define F77_CHAR_ARG_USE(s) s.ptr
00107 #define F77_CHAR_ARG_LEN_USE(s, len) (s.mask.len>>3)
00108 
00109 #define F77_RET_T int
00110 #define F77_RETURN(retval) return retval;
00111 
00112 /* FIXME -- these should work for SV1 or Y-MP systems but will
00113    need to be changed for others.  */
00114 
00115 typedef union
00116 {
00117   const char *const_ptr;
00118   char *ptr;
00119   struct
00120   {
00121     unsigned off : 6;
00122     unsigned len : 26;
00123     unsigned add : 32;
00124   } mask;
00125 } octave_cray_descriptor;
00126 
00127 typedef void *octave_cray_ftn_ch_dsc;
00128 
00129 #ifdef __cplusplus
00130 #define OCTAVE_F77_FCN_INLINE inline
00131 #else
00132 #define OCTAVE_F77_FCN_INLINE
00133 #endif
00134 
00135 static OCTAVE_F77_FCN_INLINE octave_cray_ftn_ch_dsc
00136 octave_make_cray_ftn_ch_dsc (char *ptr_arg, unsigned long len_arg)
00137 {
00138   octave_cray_descriptor desc;
00139   desc.ptr = ptr_arg;
00140   desc.mask.len = len_arg << 3;
00141   return *((octave_cray_ftn_ch_dsc *) &desc);
00142 }
00143 
00144 static OCTAVE_F77_FCN_INLINE octave_cray_ftn_ch_dsc
00145 octave_make_cray_const_ftn_ch_dsc (const char *ptr_arg, unsigned long len_arg)
00146 {
00147   octave_cray_descriptor desc;
00148   desc.const_ptr = ptr_arg;
00149   desc.mask.len = len_arg << 3;
00150   return *((octave_cray_ftn_ch_dsc *) &desc);
00151 }
00152 
00153 #ifdef __cplusplus
00154 #undef OCTAVE_F77_FCN_INLINE
00155 #endif
00156 
00157 #elif defined (F77_USES_VISUAL_FORTRAN_CALLING_CONVENTION)
00158 
00159 /* Use these macros to pass character strings from C to Fortran.  */
00160 #define F77_CHAR_ARG(x) x, strlen (x)
00161 #define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x)
00162 #define F77_CHAR_ARG2(x, l) x, l
00163 #define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l)
00164 #define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ())
00165 #define F77_CHAR_ARG_LEN(l)
00166 #define F77_CHAR_ARG_DECL char *, int
00167 #define F77_CONST_CHAR_ARG_DECL const char *, int
00168 #define F77_CHAR_ARG_LEN_DECL
00169 
00170 /* Use these macros to write C-language functions that accept
00171    Fortran-style character strings.  */
00172 #define F77_CHAR_ARG_DEF(s, len) char *s, int len
00173 #define F77_CONST_CHAR_ARG_DEF(s, len) const char *s, int len
00174 #define F77_CHAR_ARG_LEN_DEF(len)
00175 #define F77_CHAR_ARG_USE(s) s
00176 #define F77_CHAR_ARG_LEN_USE(s, len) len
00177 
00178 #define F77_RET_T void
00179 #define F77_RETURN(retval)
00180 
00181 #else
00182 
00183 /* Assume f2c-compatible calling convention.  */
00184 
00185 /* Use these macros to pass character strings from C to Fortran.  */
00186 #define F77_CHAR_ARG(x) x
00187 #define F77_CONST_CHAR_ARG(x) F77_CHAR_ARG (x)
00188 #define F77_CHAR_ARG2(x, l) x
00189 #define F77_CONST_CHAR_ARG2(x, l) F77_CHAR_ARG2 (x, l)
00190 #define F77_CXX_STRING_ARG(x) F77_CONST_CHAR_ARG2 (x.c_str (), x.length ())
00191 #define F77_CHAR_ARG_LEN(l) , l
00192 #define F77_CHAR_ARG_DECL char *
00193 #define F77_CONST_CHAR_ARG_DECL const char *
00194 #define F77_CHAR_ARG_LEN_DECL , long
00195 
00196 /* Use these macros to write C-language functions that accept
00197    Fortran-style character strings.  */
00198 #define F77_CHAR_ARG_DEF(s, len) char *s
00199 #define F77_CONST_CHAR_ARG_DEF(s, len) const char *s
00200 #define F77_CHAR_ARG_LEN_DEF(len) , long len
00201 #define F77_CHAR_ARG_USE(s) s
00202 #define F77_CHAR_ARG_LEN_USE(s, len) len
00203 
00204 #define F77_RET_T int
00205 #define F77_RETURN(retval) return retval;
00206 
00207 #endif
00208 
00209 
00210 /* Build a C string local variable CS from the Fortran string parameter S
00211    declared as F77_CHAR_ARG_DEF(s, len) or F77_CONST_CHAR_ARG_DEF(s, len).
00212    The string will be cleaned up at the end of the current block.
00213    Needs to include <cstring> and <vector>.  */
00214 
00215 #define F77_CSTRING(s, len, cs) \
00216  OCTAVE_LOCAL_BUFFER (char, cs, F77_CHAR_ARG_LEN_USE (s, len) + 1); \
00217  memcpy (cs, F77_CHAR_ARG_USE (s), F77_CHAR_ARG_LEN_USE (s, len)); \
00218  cs[F77_CHAR_ARG_LEN_USE(s, len)] = '\0'
00219 
00220 
00221 extern CRUFT_API F77_RET_T
00222 F77_FUNC (xstopx, XSTOPX) (F77_CONST_CHAR_ARG_DECL
00223                            F77_CHAR_ARG_LEN_DECL) GCC_ATTR_NORETURN;
00224 
00225 #ifdef __cplusplus
00226 }
00227 #endif
00228 
00229 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines