GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
dynamic-ld.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2017 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <iostream>
28 #include <list>
29 
30 #include "file-stat.h"
31 #include "oct-env.h"
32 #include "oct-time.h"
33 #include "singleton-cleanup.h"
34 
35 #include <defaults.h>
36 
37 #include "defun.h"
38 #include "dynamic-ld.h"
39 #include "ov-fcn.h"
40 #include "ov-dld-fcn.h"
41 #include "ov-mex-fcn.h"
42 #include "parse.h"
43 #include "unwind-prot.h"
44 #include "utils.h"
45 #include "variables.h"
46 
47 #define STRINGIFY(s) STRINGIFY1(s)
48 #define STRINGIFY1(s) #s
49 
50 class
52 {
53 public:
54 
55  typedef std::list<octave::dynamic_library>::iterator iterator;
56  typedef std::list<octave::dynamic_library>::const_iterator const_iterator;
57 
58  static void append (const octave::dynamic_library& shl);
59 
60  static void remove (octave::dynamic_library& shl,
62 
63  static octave::dynamic_library find_file (const std::string& file_name);
64 
65  static void display (void);
66 
67 private:
68 
69  octave_shlib_list (void) : lib_list () { }
70 
71  ~octave_shlib_list (void) { }
72 
73  void do_append (const octave::dynamic_library& shl);
74 
75  void do_remove (octave::dynamic_library& shl,
77 
78  octave::dynamic_library do_find_file (const std::string& file_name) const;
79 
80  void do_display (void) const;
81 
83 
84  static void cleanup_instance (void) { delete instance; instance = 0; }
85 
86  static bool instance_ok (void);
87 
88  // List of libraries we have loaded.
89  std::list<octave::dynamic_library> lib_list;
90 
91  // No copying!
92 
94 
96 };
97 
99 
100 void
102 {
103  lib_list.push_back (shl);
104 }
105 
106 void
109 {
110  for (iterator p = lib_list.begin (); p != lib_list.end (); p++)
111  {
112  if (*p == shl)
113  {
114  // Erase first to avoid potentially invalidating the pointer by the
115  // following hooks.
116  lib_list.erase (p);
117 
118  shl.close (cl_hook);
119 
120  break;
121  }
122  }
123 }
124 
127 {
129 
130  for (const_iterator p = lib_list.begin (); p != lib_list.end (); p++)
131  {
132  if (p->file_name () == file_name)
133  {
134  retval = *p;
135  break;
136  }
137  }
138 
139  return retval;
140 }
141 
142 void
144 {
145  std::cerr << "current shared libraries:" << std::endl;
146  for (const_iterator p = lib_list.begin (); p != lib_list.end (); p++)
147  std::cerr << " " << p->file_name () << std::endl;
148 }
149 
150 bool
152 {
153  bool retval = true;
154 
155  if (! instance)
156  {
157  instance = new octave_shlib_list ();
158 
159  if (instance)
161  }
162 
163  if (! instance)
164  error ("unable to create shared library list object!");
165 
166  return retval;
167 }
168 
169 void
171 {
172  if (instance_ok ())
173  instance->do_append (shl);
174 }
175 
176 void
179 {
180  if (instance_ok ())
181  instance->do_remove (shl, cl_hook);
182 }
183 
186 {
187  return (instance_ok ())
188  ? instance->do_find_file (file_name) : octave::dynamic_library ();
189 }
190 
191 void
193 {
194  if (instance_ok ())
195  instance->do_display ();
196 }
197 
199 
201 
202 bool
204 {
205  bool retval = true;
206 
207  if (! instance)
208  {
210 
211  if (instance)
213  }
214 
215  if (! instance)
216  error ("unable to create dynamic loader object!");
217 
218  return retval;
219 }
220 
221 static void
223 {
224  warning_with_id ("Octave:reload-forces-clear", " %s", fcn_name.c_str ());
225 
227 }
228 
229 static void
231 {
232  if (oct_file.number_of_functions_loaded () > 1)
233  {
234  warning_with_id ("Octave:reload-forces-clear",
235  "reloading %s clears the following functions:",
236  oct_file.file_name ().c_str ());
237 
239  }
240  else
242 }
243 
246  const std::string& file_name,
247  bool relative)
248 {
249  octave_function *retval = 0;
250 
252 
253  frame.protect_var (octave_dynamic_loader::doing_load);
254 
255  doing_load = true;
256 
258 
259  if (oct_file && oct_file.is_out_of_date ())
260  clear (oct_file);
261 
262  if (! oct_file)
263  {
264  oct_file.open (file_name);
265 
266  if (oct_file)
267  octave_shlib_list::append (oct_file);
268  }
269 
270  if (! oct_file)
271  error ("%s is not a valid shared library", file_name.c_str ());
272 
273  void *function = oct_file.search (fcn_name, name_mangler);
274 
275  if (! function)
276  {
277  // FIXME: can we determine this C mangling scheme
278  // automatically at run time or configure time?
279 
280  function = oct_file.search (fcn_name, name_uscore_mangler);
281  }
282 
283  if (function)
284  {
286  = reinterpret_cast<octave_dld_fcn_getter> (function);
287 
288  retval = f (oct_file, relative);
289 
290  if (! retval)
291  error ("failed to install .oct file function '%s'",
292  fcn_name.c_str ());
293  }
294 
295  return retval;
296 }
297 
300  const std::string& file_name,
301  bool /*relative*/)
302 {
303  octave_function *retval = 0;
304 
306 
307  frame.protect_var (octave_dynamic_loader::doing_load);
308 
309  doing_load = true;
310 
312 
313  if (mex_file && mex_file.is_out_of_date ())
314  clear (mex_file);
315 
316  if (! mex_file)
317  {
318  mex_file.open (file_name);
319 
320  if (mex_file)
321  octave_shlib_list::append (mex_file);
322  }
323 
324  if (! mex_file)
325  error ("%s is not a valid shared library", file_name.c_str ());
326 
327  void *function = 0;
328 
329  bool have_fmex = false;
330 
331  function = mex_file.search (fcn_name, mex_mangler);
332 
333  if (! function)
334  {
335  // FIXME: can we determine this C mangling scheme
336  // automatically at run time or configure time?
337 
338  function = mex_file.search (fcn_name, mex_uscore_mangler);
339 
340  if (! function)
341  {
342  function = mex_file.search (fcn_name, mex_f77_mangler);
343 
344  if (function)
345  have_fmex = true;
346  }
347  }
348 
349  if (function)
350  retval = new octave_mex_function (function, have_fmex, mex_file, fcn_name);
351  else
352  error ("failed to install .mex file function '%s'", fcn_name.c_str ());
353 
354  return retval;
355 }
356 
357 bool
360 {
361  bool retval = false;
362 
363  // We don't need to do anything if this is called because we are in
364  // the process of reloading a .oct file that has changed.
365 
366  if (! doing_load)
367  {
368  retval = shl.remove (fcn_name);
369 
370  if (shl.number_of_functions_loaded () == 0)
372  }
373 
374  return retval;
375 }
376 
377 bool
380 {
381  bool retval = false;
382 
383  // We don't need to do anything if this is called because we are in
384  // the process of reloading a .oct file that has changed.
385 
386  if (! doing_load)
387  {
388  retval = shl.remove (fcn_name);
389 
390  if (shl.number_of_functions_loaded () == 0)
392  }
393 
394  return retval;
395 }
396 
399  const std::string& file_name,
400  bool relative)
401 {
402  return (instance_ok ())
403  ? instance->do_load_oct (fcn_name, file_name, relative) : 0;
404 }
405 
408  const std::string& file_name,
409  bool relative)
410 {
411  return (instance_ok ())
412  ? instance->do_load_mex (fcn_name, file_name, relative) : 0;
413 }
414 
415 bool
418 {
419  return (instance_ok ()) ? instance->do_remove_oct (fcn_name, shl) : false;
420 }
421 
422 bool
425 {
426  return (instance_ok ()) ? instance->do_remove_mex (fcn_name, shl) : false;
427 }
428 
431 {
432  return "G" + name;
433 }
434 
437 {
438  return "_G" + name;
439 }
440 
443 {
444  return "mexFunction";
445 }
446 
449 {
450  return "_mexFunction";
451 }
452 
455 {
456  return STRINGIFY (F77_FUNC (mexfunction, MEXFUNCTION));
457 }
std::list< octave::dynamic_library > lib_list
Definition: dynamic-ld.cc:89
void warning_with_id(const char *id, const char *fmt,...)
Definition: error.cc:803
~octave_shlib_list(void)
Definition: dynamic-ld.cc:71
static std::string mex_uscore_mangler(const std::string &name)
Definition: dynamic-ld.cc:448
void * search(const std::string &nm, name_mangler mangler=0) const
Definition: oct-shlib.h:164
static std::string mex_mangler(const std::string &name)
Definition: dynamic-ld.cc:442
static bool instance_ok(void)
Definition: dynamic-ld.cc:203
static std::string mex_f77_mangler(const std::string &name)
Definition: dynamic-ld.cc:454
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
std::list< octave::dynamic_library >::const_iterator const_iterator
Definition: dynamic-ld.cc:56
NDArray & operator=(const NDArray &a)
Definition: dNDArray.h:70
octave_shlib_list(void)
Definition: dynamic-ld.cc:69
bool do_remove_mex(const std::string &fcn_name, octave::dynamic_library &shl)
Definition: dynamic-ld.cc:378
void protect_var(T &var)
void error(const char *fmt,...)
Definition: error.cc:570
static void append(const octave::dynamic_library &shl)
Definition: dynamic-ld.cc:170
void do_append(const octave::dynamic_library &shl)
Definition: dynamic-ld.cc:101
static octave::dynamic_library find_file(const std::string &file_name)
Definition: dynamic-ld.cc:185
bool is_out_of_date(void) const
Definition: oct-shlib.h:182
static octave_shlib_list * instance
Definition: dynamic-ld.cc:82
static bool remove_oct(const std::string &fcn_name, octave::dynamic_library &shl)
Definition: dynamic-ld.cc:416
static void clear_dld_function(const std::string &name)
Definition: symtab.h:1803
octave_function * do_load_oct(const std::string &fcn_name, const std::string &file_name="", bool relative=false)
Definition: dynamic-ld.cc:245
void do_remove(octave::dynamic_library &shl, octave::dynamic_library::close_hook cl_hook=0)
Definition: dynamic-ld.cc:107
static std::string name_mangler(const std::string &name)
Definition: dynamic-ld.cc:430
#define STRINGIFY(s)
Definition: dynamic-ld.cc:47
OCTAVE_EXPORT octave_value_list any number nd example oindent prints the prompt xample Pick a any number!nd example oindent and waits for the user to enter a value The string entered by the user is evaluated as an so it may be a literal a variable name
Definition: input.cc:871
void(* close_hook)(const std::string &)
Definition: oct-shlib.h:44
bool do_remove_oct(const std::string &fcn_name, octave::dynamic_library &shl)
Definition: dynamic-ld.cc:358
static void add(fptr f)
static octave_dynamic_loader * instance
Definition: dynamic-ld.h:69
octave::dynamic_library do_find_file(const std::string &file_name) const
Definition: dynamic-ld.cc:126
static octave_function * load_oct(const std::string &fcn_name, const std::string &file_name="", bool relative=false)
Definition: dynamic-ld.cc:398
void do_display(void) const
Definition: dynamic-ld.cc:143
static void display(void)
Definition: dynamic-ld.cc:192
octave_value retval
Definition: data.cc:6294
bool append
Definition: load-save.cc:1582
F77_RET_T F77_FUNC(xstopx, XSTOPX) const
Definition: f77-fcn.c:53
octave::unwind_protect frame
Definition: graphics.cc:11584
static bool remove_mex(const std::string &fcn_name, octave::dynamic_library &shl)
Definition: dynamic-ld.cc:423
size_t number_of_functions_loaded(void) const
Definition: oct-shlib.h:179
std::list< octave::dynamic_library >::iterator iterator
Definition: dynamic-ld.cc:55
p
Definition: lu.cc:138
void open(const std::string &f)
Definition: oct-shlib.h:153
static std::string name_uscore_mangler(const std::string &name)
Definition: dynamic-ld.cc:436
octave_function * do_load_mex(const std::string &fcn_name, const std::string &file_name="", bool relative=false)
Definition: dynamic-ld.cc:299
static void cleanup_instance(void)
Definition: dynamic-ld.cc:84
std::string file_name(void) const
Definition: oct-shlib.h:185
bool remove(const std::string &name)
Definition: oct-shlib.h:176
void close(close_hook cl_hook=0)
Definition: oct-shlib.h:156
static void remove(octave::dynamic_library &shl, octave::dynamic_library::close_hook cl_hook=0)
Definition: dynamic-ld.cc:177
octave_function *(* octave_dld_fcn_getter)(const octave::dynamic_library &, bool relative)
Definition: defun-int.h:104
static void clear(octave::dynamic_library &oct_file)
Definition: dynamic-ld.cc:230
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
static octave_function * load_mex(const std::string &fcn_name, const std::string &file_name="", bool relative=false)
Definition: dynamic-ld.cc:407
static void do_clear_function(const std::string &fcn_name)
Definition: dynamic-ld.cc:222
static void cleanup_instance(void)
Definition: dynamic-ld.h:71
static bool doing_load
Definition: dynamic-ld.h:89
static bool instance_ok(void)
Definition: dynamic-ld.cc:151