Octave logo Octave-Forge - Extra packages for GNU Octave
Home · Packages · Developers · Documentation · Function Reference · FAQ · Bugs · Mailing Lists · Links · SVN
  • Main Page
  • Classes
  • Files

libcruft/misc/f77-fcn.h

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