1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1994-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_defun_int_h)
27 #define octave_defun_int_h 1
28 
29 #include "octave-config.h"
30 
31 #include <string>
32 
33 #include "ov-builtin.h"
34 #include "ov-dld-fcn.h"
35 #include "version.h"
36 
37 namespace octave
38 {
39   class interpreter;
40 }
41 
42 class octave_value;
43 
44 extern OCTINTERP_API void print_usage (void);
45 extern OCTINTERP_API void print_usage (const std::string&);
46 
47 extern OCTINTERP_API void check_version (const std::string& version,
48                                          const std::string& fcn);
49 
50 extern OCTINTERP_API void
51 install_dld_function (octave_dld_function::fcn f, const std::string& name,
52                       const octave::dynamic_library& shl, const std::string& doc,
53                       bool relative = false);
54 
55 extern OCTINTERP_API void
56 install_dld_function (octave_dld_function::meth m, const std::string& name,
57                       const octave::dynamic_library& shl, const std::string& doc,
58                       bool relative = false);
59 
60 extern OCTINTERP_API void
61 install_mex_function (void *fptr, bool fmex, const std::string& name,
62                       const octave::dynamic_library& shl, bool relative = false);
63 // Gets the shlib of the currently executing DLD function, if any.
64 extern OCTINTERP_API octave::dynamic_library
65 get_current_shlib (void);
66 
67 namespace octave
68 {
69   // FIXME: this class doesn't seem to be used in Octave.  Is it
70   // really needed?
71 
72   // This is a convenience class that calls the above function automatically at
73   // construction time.  When deriving new classes, you can either use it as a
74   // field or as a parent (with multiple inheritance).
75 
76   class auto_shlib : public dynamic_library
77   {
78   public:
79 
auto_shlib(void)80     auto_shlib (void) : dynamic_library (get_current_shlib ()) { }
81 
auto_shlib(const dynamic_library & shl)82     auto_shlib (const dynamic_library& shl) : dynamic_library (shl) { }
83   };
84 }
85 
86 #define FORWARD_DECLARE_FUNX(name)              \
87   extern OCTAVE_EXPORT octave_value_list        \
88   name (const octave_value_list&, int)
89 
90 #define FORWARD_DECLARE_METHODX(name)                           \
91   extern OCTAVE_EXPORT octave_value_list                        \
92   name (octave::interpreter&, const octave_value_list&, int)
93 
94 #define FORWARD_DECLARE_FUN(name)               \
95   FORWARD_DECLARE_FUNX (F ## name)
96 
97 #define FORWARD_DECLARE_METHOD(name)            \
98   FORWARD_DECLARE_METHODX (F ## name)
99 
100 #define DECLARE_FUNX(name, args_name, nargout_name)             \
101   OCTAVE_EXPORT octave_value_list                               \
102   name (const octave_value_list& args_name, int nargout_name)
103 
104 #define DECLARE_METHODX(name, interp_name, args_name, nargout_name)     \
105   OCTAVE_EXPORT octave_value_list                                       \
106   name (octave::interpreter& interp_name,                               \
107         const octave_value_list& args_name, int nargout_name)
108 
109 #define DECLARE_FUN(name, args_name, nargout_name)      \
110   DECLARE_FUNX (F ## name, args_name, nargout_name)
111 
112 #define DECLARE_METHOD(name, interp_name, args_name, nargout_name)      \
113   DECLARE_METHODX (F ## name, interp_name, args_name, nargout_name)
114 
115 #define DECLARE_STATIC_FUNX(name, args_name, nargout_name)      \
116   static octave_value_list                                      \
117   name (const octave_value_list& args_name, int nargout_name)
118 
119 #define DECLARE_STATIC_METHODX(name, interp_name, args_name, nargout_name) \
120   static octave_value_list                                              \
121   name (octave::interpreter& interp_name,                               \
122         const octave_value_list& args_name, int nargout_name)
123 
124 #define DECLARE_STATIC_FUN(name, args_name, nargout_name)       \
125   DECLARE_STATIC_FUNX (F ## name, args_name, nargout_name)
126 
127 #define DECLARE_STATIC_METHOD(name, interp_name, args_name, nargout_name) \
128   DECLARE_STATIC_METHODX (F ## name, interp_name, args_name, nargout_name)
129 
130 // Define the code that will be used to insert the new function into
131 // the symbol table.  We look for this name instead of the actual
132 // function so that we can easily install the doc std::string too.
133 
134 typedef bool (*octave_dld_fcn_installer) (const octave::dynamic_library&, bool relative);
135 
136 typedef octave_function *
137   (*octave_dld_fcn_getter) (const octave::dynamic_library&, bool relative);
138 
139 #if defined (OCTAVE_SOURCE)
140 #  define DEFINE_FUN_INSTALLER_FUN(name, doc)                           \
141   DEFINE_FUNX_INSTALLER_FUN(#name, F ## name, G ## name, "external-doc")
142 #else
143 #  define DEFINE_FUN_INSTALLER_FUN(name, doc)                   \
144   DEFINE_FUNX_INSTALLER_FUN(#name, F ## name, G ## name, doc)
145 #endif
146 
147 #define DEFINE_FUNX_INSTALLER_FUN(name, fname, gname, doc)              \
148   extern "C"                                                            \
149   OCTAVE_EXPORT                                                         \
150   octave_function *                                                     \
151   gname (const octave::dynamic_library& shl, bool relative)             \
152   {                                                                     \
153     check_version (OCTAVE_API_VERSION, name);                           \
154                                                                         \
155     octave_dld_function *fcn                                            \
156       = octave_dld_function::create (fname, shl, name, doc);            \
157                                                                         \
158     if (relative)                                                       \
159       fcn->mark_relative ();                                            \
160                                                                         \
161     return fcn;                                                         \
162   }
163 
164 #endif
165