Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include "oct-shlib.h"
00028
00029 #include <defaults.h>
00030 #include "dynamic-ld.h"
00031 #include "error.h"
00032 #include "gripes.h"
00033 #include "oct-obj.h"
00034 #include "ov-mex-fcn.h"
00035 #include "ov.h"
00036 #include "profiler.h"
00037 #include "toplev.h"
00038 #include "unwind-prot.h"
00039
00040 DEFINE_OCTAVE_ALLOCATOR (octave_mex_function);
00041
00042 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_mex_function,
00043 "mex function", "mex function");
00044
00045 octave_mex_function::octave_mex_function
00046 (void *fptr, bool fmex, const octave_shlib& shl,
00047 const std::string& nm)
00048 : octave_function (nm), mex_fcn_ptr (fptr), exit_fcn_ptr (0),
00049 have_fmex (fmex), sh_lib (shl)
00050 {
00051 mark_fcn_file_up_to_date (time_parsed ());
00052
00053 std::string file_name = fcn_file_name ();
00054
00055 system_fcn_file
00056 = (! file_name.empty ()
00057 && Voct_file_dir == file_name.substr (0, Voct_file_dir.length ()));
00058 }
00059
00060 octave_mex_function::~octave_mex_function (void)
00061 {
00062 if (exit_fcn_ptr)
00063 (*exit_fcn_ptr) ();
00064
00065 octave_dynamic_loader::remove_mex (my_name, sh_lib);
00066 }
00067
00068 std::string
00069 octave_mex_function::fcn_file_name (void) const
00070 {
00071 return sh_lib.file_name ();
00072 }
00073
00074 octave_time
00075 octave_mex_function::time_parsed (void) const
00076 {
00077 return sh_lib.time_loaded ();
00078 }
00079
00080 octave_value_list
00081 octave_mex_function::subsref (const std::string& type,
00082 const std::list<octave_value_list>& idx,
00083 int nargout)
00084 {
00085 octave_value_list retval;
00086
00087 switch (type[0])
00088 {
00089 case '(':
00090 {
00091 int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
00092
00093 retval = do_multi_index_op (tmp_nargout, idx.front ());
00094 }
00095 break;
00096
00097 case '{':
00098 case '.':
00099 {
00100 std::string nm = type_name ();
00101 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
00102 }
00103 break;
00104
00105 default:
00106 panic_impossible ();
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 if (idx.size () > 1)
00120 retval = retval(0).next_subsref (nargout, type, idx);
00121
00122 return retval;
00123 }
00124
00125
00126 extern octave_value_list
00127 call_mex (bool have_fmex, void *f, const octave_value_list& args,
00128 int nargout, octave_mex_function *curr_mex_fcn);
00129
00130 octave_value_list
00131 octave_mex_function::do_multi_index_op (int nargout,
00132 const octave_value_list& args)
00133 {
00134 octave_value_list retval;
00135
00136 if (error_state)
00137 return retval;
00138
00139 if (args.has_magic_colon ())
00140 ::error ("invalid use of colon in function argument list");
00141 else
00142 {
00143 unwind_protect frame;
00144
00145 octave_call_stack::push (this);
00146
00147 frame.add_fcn (octave_call_stack::pop);
00148
00149 try
00150 {
00151 BEGIN_PROFILER_BLOCK (profiler_name ())
00152 retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this);
00153 END_PROFILER_BLOCK
00154 }
00155 catch (octave_execution_exception)
00156 {
00157 gripe_library_execution_error ();
00158 }
00159 }
00160
00161 return retval;
00162 }