1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2017-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 (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #include <list>
31 #include <string>
32 
33 #include "bp-table.h"
34 #include "cdef-manager.h"
35 #include "child-list.h"
36 #include "display.h"
37 #include "error.h"
38 #include "event-manager.h"
39 #include "gtk-manager.h"
40 #include "help.h"
41 #include "input.h"
42 #include "interpreter-private.h"
43 #include "interpreter.h"
44 #include "load-path.h"
45 #include "load-save.h"
46 #include "ov.h"
47 #include "ovl.h"
48 #include "pager.h"
49 #include "symtab.h"
50 
51 namespace octave
52 {
__get_interpreter__(const std::string & who)53   interpreter& __get_interpreter__ (const std::string& who)
54   {
55     interpreter *interp = interpreter::the_interpreter ();
56 
57     if (! interp)
58       {
59         abort ();
60         error ("%s: interpreter context missing", who.c_str ());
61       }
62 
63     return *interp;
64   }
65 
__get_dynamic_loader__(const std::string & who)66   dynamic_loader& __get_dynamic_loader__ (const std::string& who)
67   {
68     interpreter& interp = __get_interpreter__ (who);
69 
70     return interp.get_dynamic_loader ();
71   }
72 
__get_error_system__(const std::string & who)73   error_system& __get_error_system__ (const std::string& who)
74   {
75     interpreter& interp = __get_interpreter__ (who);
76 
77     return interp.get_error_system ();
78   }
79 
__get_gh_manager__(const std::string & who)80   gh_manager& __get_gh_manager__ (const std::string& who)
81   {
82     interpreter& interp = __get_interpreter__ (who);
83 
84     return interp.get_gh_manager ();
85   }
86 
__get_help_system__(const std::string & who)87   help_system& __get_help_system__ (const std::string& who)
88   {
89     interpreter& interp = __get_interpreter__ (who);
90 
91     return interp.get_help_system ();
92   }
93 
__get_input_system__(const std::string & who)94   input_system& __get_input_system__ (const std::string& who)
95   {
96     interpreter& interp = __get_interpreter__ (who);
97 
98     return interp.get_input_system ();
99   }
100 
__get_output_system__(const std::string & who)101   output_system& __get_output_system__ (const std::string& who)
102   {
103     interpreter& interp = __get_interpreter__ (who);
104 
105     return interp.get_output_system ();
106   }
107 
__get_load_path__(const std::string & who)108   load_path& __get_load_path__ (const std::string& who)
109   {
110     interpreter& interp = __get_interpreter__ (who);
111 
112     return interp.get_load_path ();
113   }
114 
__get_load_save_system__(const std::string & who)115   load_save_system& __get_load_save_system__ (const std::string& who)
116   {
117     interpreter& interp = __get_interpreter__ (who);
118 
119     return interp.get_load_save_system ();
120   }
121 
__get_event_manager__(const std::string & who)122   event_manager& __get_event_manager__ (const std::string& who)
123   {
124     interpreter& interp = __get_interpreter__ (who);
125 
126     return interp.get_event_manager ();
127   }
128 
__get_type_info__(const std::string & who)129   type_info& __get_type_info__ (const std::string& who)
130   {
131     interpreter& interp = __get_interpreter__ (who);
132 
133     return interp.get_type_info ();
134   }
135 
__get_symbol_table__(const std::string & who)136   symbol_table& __get_symbol_table__ (const std::string& who)
137   {
138     interpreter& interp = __get_interpreter__ (who);
139 
140     return interp.get_symbol_table ();
141   }
142 
__get_current_scope__(const std::string & who)143   symbol_scope __get_current_scope__ (const std::string& who)
144   {
145     interpreter& interp = __get_interpreter__ (who);
146 
147     return interp.get_current_scope ();
148   }
149 
__require_current_scope__(const std::string & who)150   symbol_scope __require_current_scope__ (const std::string& who)
151   {
152     symbol_scope scope = __get_current_scope__ (who);
153 
154     if (! scope)
155       error ("%s: symbol table scope missing", who.c_str ());
156 
157     return scope;
158   }
159 
__get_evaluator__(const std::string & who)160   tree_evaluator& __get_evaluator__ (const std::string& who)
161   {
162     interpreter& interp = __get_interpreter__ (who);
163 
164     return interp.get_evaluator ();
165   }
166 
__get_bp_table__(const std::string & who)167   bp_table& __get_bp_table__ (const std::string& who)
168   {
169     tree_evaluator& tw = __get_evaluator__ (who);
170 
171     return tw.get_bp_table ();
172   }
173 
__get_child_list__(const std::string & who)174   child_list& __get_child_list__ (const std::string& who)
175   {
176     interpreter& interp = __get_interpreter__ (who);
177 
178     return interp.get_child_list ();
179   }
180 
__get_cdef_manager__(const std::string & who)181   cdef_manager& __get_cdef_manager__ (const std::string& who)
182   {
183     interpreter& interp = __get_interpreter__ (who);
184 
185     return interp.get_cdef_manager ();
186   }
187 
__get_display_info__(const std::string & who)188   display_info& __get_display_info__ (const std::string& who)
189   {
190     interpreter& interp = __get_interpreter__ (who);
191 
192     return interp.get_display_info ();
193   }
194 
__get_gtk_manager__(const std::string & who)195   gtk_manager& __get_gtk_manager__ (const std::string& who)
196   {
197     interpreter& interp = __get_interpreter__ (who);
198 
199     return interp.get_gtk_manager ();
200   }
201 
202   octave_value
get_function_handle(interpreter & interp,const octave_value & arg,const std::string & parameter_name)203   get_function_handle (interpreter& interp, const octave_value& arg,
204                        const std::string& parameter_name)
205   {
206     std::list<std::string> parameter_names;
207     parameter_names.push_back (parameter_name);
208     return get_function_handle (interp, arg, parameter_names);
209   }
210 
211   // May return a function handle object, inline function object, or
212   // function object.
213 
214   octave_value
get_function_handle(interpreter & interp,const octave_value & arg,const std::list<std::string> & parameter_names)215   get_function_handle (interpreter& interp, const octave_value& arg,
216                        const std::list<std::string>& parameter_names)
217   {
218     if (arg.is_function_handle () || arg.is_inline_function ())
219       return arg;
220     else if (arg.is_string ())
221       {
222         std::string fstr = arg.string_value ();
223 
224         if (fstr.empty ())
225           return octave_value ();
226 
227         symbol_table& symtab = interp.get_symbol_table ();
228 
229         octave_value fcn = symtab.find_function (fstr);
230 
231         if (fcn.is_defined ())
232           return fcn;
233 
234         // Possibly warn here that passing the function body in a
235         // character string is discouraged.
236 
237         octave_value_list args (parameter_names.size () + 1);
238         octave_idx_type i = 0;
239         args(i++) = fstr;
240         for (const auto& pname : parameter_names)
241           args(i++) = pname;
242 
243         octave_value_list tmp = interp.feval ("inline", args, 1);
244 
245         if (tmp.length () > 0)
246           return tmp(0);
247       }
248 
249     return octave_value ();
250   }
251 }
252