Mercurial > hg > octave-lyh
annotate src/ov-fcn-handle.cc @ 9396:17af7cce7d1b
yet more unwind_protect improvements
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 25 Jun 2009 13:57:38 +0200 |
parents | 1de00ca9c9f2 |
children | f008a3a1bcb0 |
rev | line source |
---|---|
4343 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 John W. Eaton |
4343 | 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 | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
4343 | 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 | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
4343 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <iostream> | |
5765 | 28 #include <sstream> |
5164 | 29 #include <vector> |
4343 | 30 |
7336 | 31 #include "file-ops.h" |
8377
25bc2d31e1bf
improve OCTAVE_LOCAL_BUFFER
Jaroslav Hajek <highegg@gmail.com>
parents:
8021
diff
changeset
|
32 #include "oct-locbuf.h" |
7336 | 33 |
4343 | 34 #include "defun.h" |
4654 | 35 #include "error.h" |
36 #include "gripes.h" | |
5663 | 37 #include "input.h" |
4343 | 38 #include "oct-map.h" |
39 #include "ov-base.h" | |
40 #include "ov-fcn-handle.h" | |
4980 | 41 #include "ov-usr-fcn.h" |
4343 | 42 #include "pr-output.h" |
4980 | 43 #include "pt-pr-code.h" |
44 #include "pt-misc.h" | |
45 #include "pt-stmt.h" | |
46 #include "pt-cmd.h" | |
47 #include "pt-exp.h" | |
48 #include "pt-assign.h" | |
4343 | 49 #include "variables.h" |
4988 | 50 #include "parse.h" |
6625 | 51 #include "unwind-prot.h" |
52 #include "defaults.h" | |
53 #include "file-stat.h" | |
54 #include "load-path.h" | |
55 #include "oct-env.h" | |
4988 | 56 |
57 #include "byte-swap.h" | |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
58 #include "ls-ascii-helper.h" |
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
59 #include "ls-hdf5.h" |
4988 | 60 #include "ls-oct-ascii.h" |
6625 | 61 #include "ls-oct-binary.h" |
4988 | 62 #include "ls-utils.h" |
4343 | 63 |
64 DEFINE_OCTAVE_ALLOCATOR (octave_fcn_handle); | |
65 | |
4612 | 66 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_handle, |
67 "function handle", | |
5946 | 68 "function_handle"); |
4343 | 69 |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
70 octave_fcn_handle::octave_fcn_handle (const octave_value& f, |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
71 const std::string& n) |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
72 : warn_reload (true), fcn (f), nm (n) |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
73 { |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
74 octave_user_function *uf = fcn.user_function_value (true); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
75 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
76 if (uf) |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
77 symbol_table::cache_name (uf->scope (), nm); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
78 } |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
79 |
4924 | 80 octave_value_list |
81 octave_fcn_handle::subsref (const std::string& type, | |
82 const std::list<octave_value_list>& idx, | |
83 int nargout) | |
84 { | |
85 octave_value_list retval; | |
86 | |
87 switch (type[0]) | |
88 { | |
89 case '(': | |
90 { | |
7336 | 91 out_of_date_check (fcn); |
5663 | 92 |
7336 | 93 if (fcn.is_defined ()) |
94 { | |
95 octave_function *f = function_value (); | |
5663 | 96 |
7336 | 97 if (f) |
98 retval = f->subsref (type, idx, nargout); | |
5663 | 99 else |
7336 | 100 error ("invalid function handle"); |
5663 | 101 } |
5312 | 102 else |
103 error ("invalid function handle"); | |
4924 | 104 } |
105 break; | |
106 | |
107 case '{': | |
108 case '.': | |
109 { | |
4930 | 110 std::string typ_nm = type_name (); |
111 error ("%s cannot be indexed with %c", typ_nm.c_str (), type[0]); | |
4924 | 112 } |
113 break; | |
114 | |
115 default: | |
116 panic_impossible (); | |
117 } | |
118 | |
7689
a9d25da4ed9c
octave_fcn_handle::subsref: don't call next_subsref
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
119 // There's no need to call next_subsref here -- |
a9d25da4ed9c
octave_fcn_handle::subsref: don't call next_subsref
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
120 // octave_function::subsref will handle that for us. |
4924 | 121 |
122 return retval; | |
123 } | |
124 | |
4988 | 125 bool |
6625 | 126 octave_fcn_handle::set_fcn (const std::string &octaveroot, |
127 const std::string& fpath) | |
4988 | 128 { |
6625 | 129 bool success = true; |
130 | |
7745
0ff0fc033f28
better handling of functions found by relative lookup
John W. Eaton <jwe@octave.org>
parents:
7744
diff
changeset
|
131 if (octaveroot.length () != 0 |
0ff0fc033f28
better handling of functions found by relative lookup
John W. Eaton <jwe@octave.org>
parents:
7744
diff
changeset
|
132 && fpath.length () >= octaveroot.length () |
0ff0fc033f28
better handling of functions found by relative lookup
John W. Eaton <jwe@octave.org>
parents:
7744
diff
changeset
|
133 && fpath.substr (0, octaveroot.length ()) == octaveroot |
0ff0fc033f28
better handling of functions found by relative lookup
John W. Eaton <jwe@octave.org>
parents:
7744
diff
changeset
|
134 && OCTAVE_EXEC_PREFIX != octaveroot) |
6625 | 135 { |
136 // First check if just replacing matlabroot is enough | |
137 std::string str = OCTAVE_EXEC_PREFIX + | |
138 fpath.substr (octaveroot.length ()); | |
139 file_stat fs (str); | |
140 | |
141 if (fs.exists ()) | |
142 { | |
8007
a2ab20ba78f7
make file_ops a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7901
diff
changeset
|
143 size_t xpos = str.find_last_of (file_ops::dir_sep_chars ()); |
6625 | 144 |
7336 | 145 std::string dir_name = str.substr (0, xpos); |
6625 | 146 |
7336 | 147 octave_function *xfcn |
148 = load_fcn_from_file (str, dir_name, "", nm); | |
6625 | 149 |
7336 | 150 if (xfcn) |
151 { | |
152 octave_value tmp (xfcn); | |
6625 | 153 |
7336 | 154 fcn = octave_value (new octave_fcn_handle (tmp, nm)); |
6625 | 155 } |
156 else | |
157 { | |
158 error ("function handle points to non-existent function"); | |
159 success = false; | |
160 } | |
161 } | |
162 else | |
163 { | |
164 // Next just search for it anywhere in the system path | |
165 string_vector names(3); | |
166 names(0) = nm + ".oct"; | |
167 names(1) = nm + ".mex"; | |
168 names(2) = nm + ".m"; | |
169 | |
6626 | 170 dir_path p (load_path::system_path ()); |
6625 | 171 |
172 str = octave_env::make_absolute | |
173 (p.find_first_of (names), octave_env::getcwd ()); | |
174 | |
8007
a2ab20ba78f7
make file_ops a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7901
diff
changeset
|
175 size_t xpos = str.find_last_of (file_ops::dir_sep_chars ()); |
6625 | 176 |
7336 | 177 std::string dir_name = str.substr (0, xpos); |
178 | |
179 octave_function *xfcn = load_fcn_from_file (str, dir_name, "", nm); | |
4989 | 180 |
7336 | 181 if (xfcn) |
182 { | |
183 octave_value tmp (xfcn); | |
6625 | 184 |
7336 | 185 fcn = octave_value (new octave_fcn_handle (tmp, nm)); |
6625 | 186 } |
187 else | |
188 { | |
189 error ("function handle points to non-existent function"); | |
190 success = false; | |
191 } | |
192 } | |
193 } | |
194 else | |
195 { | |
196 if (fpath.length () > 0) | |
197 { | |
8007
a2ab20ba78f7
make file_ops a proper singleton class
John W. Eaton <jwe@octave.org>
parents:
7901
diff
changeset
|
198 size_t xpos = fpath.find_last_of (file_ops::dir_sep_chars ()); |
6625 | 199 |
7336 | 200 std::string dir_name = fpath.substr (0, xpos); |
201 | |
202 octave_function *xfcn = load_fcn_from_file (fpath, dir_name, "", nm); | |
6625 | 203 |
7336 | 204 if (xfcn) |
205 { | |
206 octave_value tmp (xfcn); | |
6625 | 207 |
7336 | 208 fcn = octave_value (new octave_fcn_handle (tmp, nm)); |
6625 | 209 } |
210 else | |
211 { | |
212 error ("function handle points to non-existent function"); | |
213 success = false; | |
214 } | |
215 } | |
216 else | |
217 { | |
7336 | 218 fcn = symbol_table::find_function (nm); |
219 | |
6625 | 220 if (! fcn.is_function ()) |
221 { | |
222 error ("function handle points to non-existent function"); | |
223 success = false; | |
224 } | |
225 } | |
226 } | |
227 | |
228 return success; | |
229 } | |
230 | |
231 bool | |
6974 | 232 octave_fcn_handle::save_ascii (std::ostream& os) |
6625 | 233 { |
4988 | 234 if (nm == "@<anonymous>") |
235 { | |
6625 | 236 os << nm << "\n"; |
237 | |
4989 | 238 print_raw (os, true); |
239 os << "\n"; | |
6625 | 240 |
7336 | 241 if (fcn.is_undefined ()) |
6625 | 242 return false; |
243 | |
244 octave_user_function *f = fcn.user_function_value (); | |
245 | |
7336 | 246 std::list<symbol_table::symbol_record> vars |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
247 = symbol_table::all_variables (f->scope (), 0); |
6625 | 248 |
7336 | 249 size_t varlen = vars.size (); |
6625 | 250 |
251 if (varlen > 0) | |
252 { | |
253 os << "# length: " << varlen << "\n"; | |
254 | |
7336 | 255 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); |
256 p != vars.end (); p++) | |
6625 | 257 { |
7336 | 258 if (! save_ascii_data (os, p->varval (), p->name (), false, 0)) |
6625 | 259 return os; |
260 } | |
261 } | |
262 } | |
263 else | |
264 { | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
265 octave_function *f = function_value (); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
266 std::string fnm = f ? f->fcn_file_name () : std::string (); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
267 |
6625 | 268 os << "# octaveroot: " << OCTAVE_EXEC_PREFIX << "\n"; |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
269 if (! fnm.empty ()) |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
270 os << "# path: " << fnm << "\n"; |
6625 | 271 os << nm << "\n"; |
4988 | 272 } |
273 | |
274 return true; | |
275 } | |
276 | |
277 bool | |
278 octave_fcn_handle::load_ascii (std::istream& is) | |
279 { | |
6625 | 280 bool success = true; |
281 | |
282 std::streampos pos = is.tellg (); | |
283 std::string octaveroot = extract_keyword (is, "octaveroot", true); | |
284 if (octaveroot.length() == 0) | |
285 { | |
286 is.seekg (pos); | |
287 is.clear (); | |
288 } | |
289 pos = is.tellg (); | |
290 std::string fpath = extract_keyword (is, "path", true); | |
291 if (fpath.length() == 0) | |
292 { | |
293 is.seekg (pos); | |
294 is.clear (); | |
295 } | |
296 | |
4988 | 297 is >> nm; |
4989 | 298 |
4988 | 299 if (nm == "@<anonymous>") |
300 { | |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
301 skip_preceeding_newline (is); |
4988 | 302 |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
303 std::string buf; |
4988 | 304 |
305 if (is) | |
306 { | |
307 | |
308 // Get a line of text whitespace characters included, leaving | |
4989 | 309 // newline in the stream. |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
310 buf = read_until_newline (is, true); |
4989 | 311 |
4988 | 312 } |
313 | |
6625 | 314 pos = is.tellg (); |
7336 | 315 |
9377
610bf90fce2a
update unwind_protect usage everywhere
Jaroslav Hajek <highegg@gmail.com>
parents:
9343
diff
changeset
|
316 unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
317 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
318 // Set up temporary scope to use for evaluating the text that |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
319 // defines the anonymous function. |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
320 |
7336 | 321 symbol_table::scope_id local_scope = symbol_table::alloc_scope (); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9395
diff
changeset
|
322 unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
323 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
324 symbol_table::set_scope (local_scope); |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
325 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
326 octave_call_stack::push (local_scope, 0); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9395
diff
changeset
|
327 unwind_protect::add_fcn (octave_call_stack::pop); |
4988 | 328 |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
329 octave_idx_type len = 0; |
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
330 |
6625 | 331 if (extract_keyword (is, "length", len, true) && len >= 0) |
4989 | 332 { |
6625 | 333 if (len > 0) |
334 { | |
335 for (octave_idx_type i = 0; i < len; i++) | |
336 { | |
337 octave_value t2; | |
338 bool dummy; | |
339 | |
340 std::string name | |
341 = read_ascii_data (is, std::string (), dummy, t2, i); | |
342 | |
343 if (!is) | |
344 { | |
345 error ("load: failed to load anonymous function handle"); | |
346 break; | |
347 } | |
348 | |
7901 | 349 symbol_table::varref (name, local_scope, 0) = t2; |
6625 | 350 } |
351 } | |
4989 | 352 } |
353 else | |
6625 | 354 { |
355 is.seekg (pos); | |
356 is.clear (); | |
357 } | |
358 | |
359 if (is && success) | |
360 { | |
361 int parse_status; | |
362 octave_value anon_fcn_handle = | |
8946
e7e928088e90
fix CRLF issues with text-mode reading in windows when loading ascii data
Benjamin Lindner <lindnerb@users.sourceforge.net>
parents:
8920
diff
changeset
|
363 eval_string (buf, true, parse_status); |
6625 | 364 |
365 if (parse_status == 0) | |
366 { | |
367 octave_fcn_handle *fh = | |
368 anon_fcn_handle.fcn_handle_value (); | |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
369 |
6625 | 370 if (fh) |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
371 { |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
372 fcn = fh->fcn; |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
373 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
374 octave_user_function *uf = fcn.user_function_value (true); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
375 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
376 if (uf) |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
377 symbol_table::cache_name (uf->scope (), nm); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
378 } |
6625 | 379 else |
380 success = false; | |
381 } | |
382 else | |
383 success = false; | |
384 } | |
385 else | |
386 success = false; | |
387 | |
9377
610bf90fce2a
update unwind_protect usage everywhere
Jaroslav Hajek <highegg@gmail.com>
parents:
9343
diff
changeset
|
388 unwind_protect::run_frame (uwp_frame); |
4988 | 389 } |
390 else | |
6625 | 391 success = set_fcn (octaveroot, fpath); |
4988 | 392 |
6625 | 393 return success; |
4988 | 394 } |
395 | |
396 bool | |
6625 | 397 octave_fcn_handle::save_binary (std::ostream& os, bool& save_as_floats) |
4988 | 398 { |
399 if (nm == "@<anonymous>") | |
400 { | |
6625 | 401 std::ostringstream nmbuf; |
402 | |
7336 | 403 if (fcn.is_undefined ()) |
6625 | 404 return false; |
405 | |
406 octave_user_function *f = fcn.user_function_value (); | |
407 | |
7336 | 408 std::list<symbol_table::symbol_record> vars |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
409 = symbol_table::all_variables (f->scope (), 0); |
6625 | 410 |
7336 | 411 size_t varlen = vars.size (); |
6625 | 412 |
413 if (varlen > 0) | |
414 nmbuf << nm << " " << varlen; | |
415 else | |
416 nmbuf << nm; | |
417 | |
418 std::string buf_str = nmbuf.str(); | |
419 int32_t tmp = buf_str.length (); | |
420 os.write (reinterpret_cast<char *> (&tmp), 4); | |
421 os.write (buf_str.c_str (), buf_str.length ()); | |
422 | |
5765 | 423 std::ostringstream buf; |
4988 | 424 print_raw (buf, true); |
5765 | 425 std::string stmp = buf.str (); |
4988 | 426 tmp = stmp.length (); |
5760 | 427 os.write (reinterpret_cast<char *> (&tmp), 4); |
4988 | 428 os.write (stmp.c_str (), stmp.length ()); |
6625 | 429 |
430 if (varlen > 0) | |
431 { | |
7336 | 432 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); |
433 p != vars.end (); p++) | |
6625 | 434 { |
7336 | 435 if (! save_binary_data (os, p->varval (), p->name (), |
6625 | 436 "", 0, save_as_floats)) |
437 return os; | |
438 } | |
439 } | |
440 } | |
441 else | |
442 { | |
443 std::ostringstream nmbuf; | |
444 | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
445 octave_function *f = function_value (); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
446 std::string fnm = f ? f->fcn_file_name () : std::string (); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
447 |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
448 nmbuf << nm << "\n" << OCTAVE_EXEC_PREFIX << "\n" << fnm; |
6625 | 449 |
450 std::string buf_str = nmbuf.str (); | |
451 int32_t tmp = buf_str.length (); | |
452 os.write (reinterpret_cast<char *> (&tmp), 4); | |
453 os.write (buf_str.c_str (), buf_str.length ()); | |
4988 | 454 } |
7336 | 455 |
4988 | 456 return true; |
457 } | |
458 | |
459 bool | |
460 octave_fcn_handle::load_binary (std::istream& is, bool swap, | |
6625 | 461 oct_mach_info::float_format fmt) |
4988 | 462 { |
6625 | 463 bool success = true; |
7336 | 464 |
5828 | 465 int32_t tmp; |
5760 | 466 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) |
4988 | 467 return false; |
468 if (swap) | |
469 swap_bytes<4> (&tmp); | |
470 | |
471 OCTAVE_LOCAL_BUFFER (char, ctmp1, tmp+1); | |
8378
7d0492aa522d
fix use of uninitialized buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
472 is.get (ctmp1, tmp+1, 0); |
4988 | 473 nm = std::string (ctmp1); |
474 | |
475 if (! is) | |
476 return false; | |
477 | |
6625 | 478 if (nm.length() >= 12 && nm.substr (0, 12) == "@<anonymous>") |
4988 | 479 { |
6625 | 480 octave_idx_type len = 0; |
481 | |
482 if (nm.length() > 12) | |
483 { | |
484 std::istringstream nm_is (nm.substr(12)); | |
485 nm_is >> len; | |
486 nm = nm.substr(0,12); | |
487 } | |
488 | |
5760 | 489 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) |
4988 | 490 return false; |
491 if (swap) | |
492 swap_bytes<4> (&tmp); | |
493 | |
494 OCTAVE_LOCAL_BUFFER (char, ctmp2, tmp+1); | |
8378
7d0492aa522d
fix use of uninitialized buffers
Jaroslav Hajek <highegg@gmail.com>
parents:
8377
diff
changeset
|
495 is.get (ctmp2, tmp+1, 0); |
4988 | 496 |
9377
610bf90fce2a
update unwind_protect usage everywhere
Jaroslav Hajek <highegg@gmail.com>
parents:
9343
diff
changeset
|
497 unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
498 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
499 // Set up temporary scope to use for evaluating the text that |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
500 // defines the anonymous function. |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
501 |
7336 | 502 symbol_table::scope_id local_scope = symbol_table::alloc_scope (); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9395
diff
changeset
|
503 unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
504 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
505 symbol_table::set_scope (local_scope); |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
506 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
507 octave_call_stack::push (local_scope, 0); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9395
diff
changeset
|
508 unwind_protect::add_fcn (octave_call_stack::pop); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
509 |
6625 | 510 if (len > 0) |
4989 | 511 { |
6625 | 512 for (octave_idx_type i = 0; i < len; i++) |
513 { | |
514 octave_value t2; | |
515 bool dummy; | |
516 std::string doc; | |
517 | |
518 std::string name = | |
519 read_binary_data (is, swap, fmt, std::string (), | |
520 dummy, t2, doc); | |
521 | |
522 if (!is) | |
523 { | |
524 error ("load: failed to load anonymous function handle"); | |
525 break; | |
526 } | |
527 | |
7336 | 528 symbol_table::varref (name, local_scope) = t2; |
6625 | 529 } |
530 } | |
531 | |
532 if (is && success) | |
533 { | |
534 int parse_status; | |
535 octave_value anon_fcn_handle = | |
536 eval_string (ctmp2, true, parse_status); | |
537 | |
538 if (parse_status == 0) | |
539 { | |
540 octave_fcn_handle *fh = anon_fcn_handle.fcn_handle_value (); | |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
541 |
6625 | 542 if (fh) |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
543 { |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
544 fcn = fh->fcn; |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
545 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
546 octave_user_function *uf = fcn.user_function_value (true); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
547 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
548 if (uf) |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
549 symbol_table::cache_name (uf->scope (), nm); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
550 } |
6625 | 551 else |
552 success = false; | |
553 } | |
4989 | 554 else |
6625 | 555 success = false; |
4989 | 556 } |
6625 | 557 |
9377
610bf90fce2a
update unwind_protect usage everywhere
Jaroslav Hajek <highegg@gmail.com>
parents:
9343
diff
changeset
|
558 unwind_protect::run_frame (uwp_frame); |
4988 | 559 } |
560 else | |
561 { | |
6625 | 562 std::string octaveroot; |
563 std::string fpath; | |
564 | |
8021 | 565 if (nm.find_first_of ("\n") != std::string::npos) |
6225 | 566 { |
6625 | 567 size_t pos1 = nm.find_first_of ("\n"); |
568 size_t pos2 = nm.find_first_of ("\n", pos1 + 1); | |
569 octaveroot = nm.substr (pos1 + 1, pos2 - pos1 - 1); | |
570 fpath = nm.substr (pos2 + 1); | |
571 nm = nm.substr (0, pos1); | |
6225 | 572 } |
6625 | 573 |
574 success = set_fcn (octaveroot, fpath); | |
575 } | |
576 | |
577 return success; | |
4988 | 578 } |
579 | |
580 #if defined (HAVE_HDF5) | |
581 bool | |
582 octave_fcn_handle::save_hdf5 (hid_t loc_id, const char *name, | |
6625 | 583 bool save_as_floats) |
4988 | 584 { |
7336 | 585 bool retval = true; |
586 | |
4988 | 587 hid_t group_hid = -1; |
588 group_hid = H5Gcreate (loc_id, name, 0); | |
7336 | 589 if (group_hid < 0) |
590 return false; | |
4988 | 591 |
592 hid_t space_hid = -1, data_hid = -1, type_hid = -1;; | |
593 | |
594 // attach the type of the variable | |
595 type_hid = H5Tcopy (H5T_C_S1); | |
596 H5Tset_size (type_hid, nm.length () + 1); | |
597 if (type_hid < 0) | |
598 { | |
599 H5Gclose (group_hid); | |
600 return false; | |
601 } | |
602 | |
603 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, 2); | |
604 hdims[0] = 0; | |
605 hdims[1] = 0; | |
5760 | 606 space_hid = H5Screate_simple (0 , hdims, 0); |
4988 | 607 if (space_hid < 0) |
608 { | |
609 H5Tclose (type_hid); | |
610 H5Gclose (group_hid); | |
611 return false; | |
612 } | |
613 | |
614 data_hid = H5Dcreate (group_hid, "nm", type_hid, space_hid, H5P_DEFAULT); | |
615 if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, | |
5760 | 616 H5P_DEFAULT, nm.c_str ()) < 0) |
4988 | 617 { |
618 H5Sclose (space_hid); | |
619 H5Tclose (type_hid); | |
620 H5Gclose (group_hid); | |
621 return false; | |
622 } | |
623 H5Dclose (data_hid); | |
624 | |
625 if (nm == "@<anonymous>") | |
626 { | |
5765 | 627 std::ostringstream buf; |
4988 | 628 print_raw (buf, true); |
5765 | 629 std::string stmp = buf.str (); |
4988 | 630 |
631 // attach the type of the variable | |
632 H5Tset_size (type_hid, stmp.length () + 1); | |
633 if (type_hid < 0) | |
634 { | |
6695 | 635 H5Sclose (space_hid); |
4988 | 636 H5Gclose (group_hid); |
637 return false; | |
638 } | |
639 | |
640 data_hid = H5Dcreate (group_hid, "fcn", type_hid, space_hid, | |
641 H5P_DEFAULT); | |
642 if (data_hid < 0 || H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, | |
5760 | 643 H5P_DEFAULT, stmp.c_str ()) < 0) |
4988 | 644 { |
645 H5Sclose (space_hid); | |
646 H5Tclose (type_hid); | |
647 H5Gclose (group_hid); | |
648 return false; | |
649 } | |
650 | |
651 H5Dclose (data_hid); | |
6625 | 652 |
653 octave_user_function *f = fcn.user_function_value (); | |
654 | |
7336 | 655 std::list<symbol_table::symbol_record> vars |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
656 = symbol_table::all_variables (f->scope (), 0); |
7336 | 657 |
658 size_t varlen = vars.size (); | |
6625 | 659 |
660 if (varlen > 0) | |
661 { | |
662 hid_t as_id = H5Screate (H5S_SCALAR); | |
663 | |
664 if (as_id >= 0) | |
665 { | |
666 hid_t a_id = H5Acreate (group_hid, "SYMBOL_TABLE", | |
667 H5T_NATIVE_IDX, as_id, H5P_DEFAULT); | |
668 | |
669 if (a_id >= 0) | |
670 { | |
671 retval = (H5Awrite (a_id, H5T_NATIVE_IDX, &varlen) >= 0); | |
672 | |
673 H5Aclose (a_id); | |
674 } | |
675 else | |
676 retval = false; | |
677 | |
678 H5Sclose (as_id); | |
679 } | |
680 else | |
681 retval = false; | |
682 | |
683 data_hid = H5Gcreate (group_hid, "symbol table", 0); | |
684 if (data_hid < 0) | |
685 { | |
686 H5Sclose (space_hid); | |
687 H5Tclose (type_hid); | |
688 H5Gclose (group_hid); | |
689 return false; | |
690 } | |
691 | |
7336 | 692 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); |
693 p != vars.end (); p++) | |
6625 | 694 { |
7336 | 695 if (! add_hdf5_data (data_hid, p->varval (), p->name (), |
6625 | 696 "", false, save_as_floats)) |
697 break; | |
698 } | |
699 H5Gclose (data_hid); | |
700 } | |
701 } | |
702 else | |
703 { | |
704 std::string octaveroot = OCTAVE_EXEC_PREFIX; | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
705 |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
706 octave_function *f = function_value (); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
707 std::string fpath = f ? f->fcn_file_name () : std::string (); |
6625 | 708 |
709 H5Sclose (space_hid); | |
710 hdims[0] = 1; | |
711 hdims[1] = octaveroot.length (); | |
712 space_hid = H5Screate_simple (0 , hdims, 0); | |
713 if (space_hid < 0) | |
714 { | |
715 H5Tclose (type_hid); | |
716 H5Gclose (group_hid); | |
717 return false; | |
718 } | |
719 | |
720 H5Tclose (type_hid); | |
721 type_hid = H5Tcopy (H5T_C_S1); | |
722 H5Tset_size (type_hid, octaveroot.length () + 1); | |
723 | |
724 hid_t a_id = H5Acreate (group_hid, "OCTAVEROOT", | |
725 type_hid, space_hid, H5P_DEFAULT); | |
726 | |
727 if (a_id >= 0) | |
728 { | |
729 retval = (H5Awrite (a_id, type_hid, octaveroot.c_str ()) >= 0); | |
730 | |
731 H5Aclose (a_id); | |
732 } | |
733 else | |
6695 | 734 { |
735 H5Sclose (space_hid); | |
736 H5Tclose (type_hid); | |
737 H5Gclose (group_hid); | |
738 return false; | |
739 } | |
6625 | 740 |
741 H5Sclose (space_hid); | |
742 hdims[0] = 1; | |
743 hdims[1] = fpath.length (); | |
744 space_hid = H5Screate_simple (0 , hdims, 0); | |
745 if (space_hid < 0) | |
746 { | |
747 H5Tclose (type_hid); | |
748 H5Gclose (group_hid); | |
749 return false; | |
750 } | |
751 | |
752 H5Tclose (type_hid); | |
753 type_hid = H5Tcopy (H5T_C_S1); | |
754 H5Tset_size (type_hid, fpath.length () + 1); | |
755 | |
756 a_id = H5Acreate (group_hid, "FILE", type_hid, space_hid, H5P_DEFAULT); | |
757 | |
758 if (a_id >= 0) | |
759 { | |
760 retval = (H5Awrite (a_id, type_hid, fpath.c_str ()) >= 0); | |
761 | |
762 H5Aclose (a_id); | |
763 } | |
764 else | |
765 retval = false; | |
4988 | 766 } |
767 | |
768 H5Sclose (space_hid); | |
769 H5Tclose (type_hid); | |
770 H5Gclose (group_hid); | |
771 | |
772 return retval; | |
773 } | |
774 | |
775 bool | |
776 octave_fcn_handle::load_hdf5 (hid_t loc_id, const char *name, | |
6625 | 777 bool have_h5giterate_bug) |
4988 | 778 { |
7336 | 779 bool success = true; |
780 | |
4988 | 781 hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id; |
782 hsize_t rank; | |
783 int slen; | |
784 | |
785 group_hid = H5Gopen (loc_id, name); | |
7336 | 786 if (group_hid < 0) |
787 return false; | |
4988 | 788 |
789 data_hid = H5Dopen (group_hid, "nm"); | |
790 | |
791 if (data_hid < 0) | |
792 { | |
793 H5Gclose (group_hid); | |
794 return false; | |
795 } | |
796 | |
797 type_hid = H5Dget_type (data_hid); | |
798 type_class_hid = H5Tget_class (type_hid); | |
799 | |
800 if (type_class_hid != H5T_STRING) | |
801 { | |
802 H5Tclose (type_hid); | |
803 H5Dclose (data_hid); | |
804 H5Gclose (group_hid); | |
805 return false; | |
806 } | |
807 | |
808 space_hid = H5Dget_space (data_hid); | |
809 rank = H5Sget_simple_extent_ndims (space_hid); | |
810 | |
811 if (rank != 0) | |
812 { | |
813 H5Sclose (space_hid); | |
814 H5Tclose (type_hid); | |
815 H5Dclose (data_hid); | |
816 H5Gclose (group_hid); | |
817 return false; | |
818 } | |
819 | |
820 slen = H5Tget_size (type_hid); | |
821 if (slen < 0) | |
822 { | |
823 H5Sclose (space_hid); | |
824 H5Tclose (type_hid); | |
825 H5Dclose (data_hid); | |
826 H5Gclose (group_hid); | |
827 return false; | |
828 } | |
829 | |
830 OCTAVE_LOCAL_BUFFER (char, nm_tmp, slen); | |
831 | |
832 // create datatype for (null-terminated) string to read into: | |
833 st_id = H5Tcopy (H5T_C_S1); | |
834 H5Tset_size (st_id, slen); | |
835 | |
5760 | 836 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, nm_tmp) < 0) |
4988 | 837 { |
6695 | 838 H5Tclose (st_id); |
4988 | 839 H5Sclose (space_hid); |
840 H5Tclose (type_hid); | |
6695 | 841 H5Dclose (data_hid); |
4988 | 842 H5Gclose (group_hid); |
843 return false; | |
844 } | |
845 H5Tclose (st_id); | |
846 H5Dclose (data_hid); | |
847 nm = nm_tmp; | |
848 | |
849 if (nm == "@<anonymous>") | |
850 { | |
851 data_hid = H5Dopen (group_hid, "fcn"); | |
852 | |
853 if (data_hid < 0) | |
854 { | |
6695 | 855 H5Sclose (space_hid); |
856 H5Tclose (type_hid); | |
4988 | 857 H5Gclose (group_hid); |
858 return false; | |
859 } | |
860 | |
6695 | 861 H5Tclose (type_hid); |
4988 | 862 type_hid = H5Dget_type (data_hid); |
863 type_class_hid = H5Tget_class (type_hid); | |
864 | |
865 if (type_class_hid != H5T_STRING) | |
866 { | |
6695 | 867 H5Sclose (space_hid); |
4988 | 868 H5Tclose (type_hid); |
869 H5Dclose (data_hid); | |
870 H5Gclose (group_hid); | |
871 return false; | |
872 } | |
873 | |
6695 | 874 H5Sclose (space_hid); |
4988 | 875 space_hid = H5Dget_space (data_hid); |
876 rank = H5Sget_simple_extent_ndims (space_hid); | |
877 | |
878 if (rank != 0) | |
879 { | |
880 H5Sclose (space_hid); | |
881 H5Tclose (type_hid); | |
882 H5Dclose (data_hid); | |
883 H5Gclose (group_hid); | |
884 return false; | |
885 } | |
886 | |
887 slen = H5Tget_size (type_hid); | |
888 if (slen < 0) | |
889 { | |
890 H5Sclose (space_hid); | |
891 H5Tclose (type_hid); | |
892 H5Dclose (data_hid); | |
893 H5Gclose (group_hid); | |
894 return false; | |
895 } | |
896 | |
897 OCTAVE_LOCAL_BUFFER (char, fcn_tmp, slen); | |
898 | |
899 // create datatype for (null-terminated) string to read into: | |
900 st_id = H5Tcopy (H5T_C_S1); | |
901 H5Tset_size (st_id, slen); | |
902 | |
5760 | 903 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, fcn_tmp) < 0) |
4988 | 904 { |
6695 | 905 H5Tclose (st_id); |
4988 | 906 H5Sclose (space_hid); |
907 H5Tclose (type_hid); | |
6695 | 908 H5Dclose (data_hid); |
4988 | 909 H5Gclose (group_hid); |
910 return false; | |
911 } | |
6695 | 912 H5Tclose (st_id); |
4988 | 913 H5Dclose (data_hid); |
6625 | 914 |
915 octave_idx_type len = 0; | |
916 | |
917 // we have to pull some shenanigans here to make sure | |
918 // HDF5 doesn't print out all sorts of error messages if we | |
919 // call H5Aopen for a non-existing attribute | |
920 | |
921 H5E_auto_t err_func; | |
922 void *err_func_data; | |
4988 | 923 |
6625 | 924 // turn off error reporting temporarily, but save the error |
925 // reporting function: | |
926 H5Eget_auto (&err_func, &err_func_data); | |
927 H5Eset_auto (0, 0); | |
928 | |
929 hid_t attr_id = H5Aopen_name (group_hid, "SYMBOL_TABLE"); | |
4988 | 930 |
6625 | 931 if (attr_id >= 0) |
932 { | |
933 if (H5Aread (attr_id, H5T_NATIVE_IDX, &len) < 0) | |
934 success = false; | |
935 | |
936 H5Aclose (attr_id); | |
937 } | |
938 | |
939 // restore error reporting: | |
940 H5Eset_auto (err_func, err_func_data); | |
941 | |
9377
610bf90fce2a
update unwind_protect usage everywhere
Jaroslav Hajek <highegg@gmail.com>
parents:
9343
diff
changeset
|
942 unwind_protect::frame_id_t uwp_frame = unwind_protect::begin_frame (); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
943 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
944 // Set up temporary scope to use for evaluating the text that |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
945 // defines the anonymous function. |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
946 |
7336 | 947 symbol_table::scope_id local_scope = symbol_table::alloc_scope (); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9395
diff
changeset
|
948 unwind_protect::add_fcn (symbol_table::erase_scope, local_scope); |
9144
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
949 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
950 symbol_table::set_scope (local_scope); |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
951 |
c6463412aebb
eliminate symbol_table::scope_stack; fix scoping issue with evalin
John W. Eaton <jwe@octave.org>
parents:
8946
diff
changeset
|
952 octave_call_stack::push (local_scope, 0); |
9396
17af7cce7d1b
yet more unwind_protect improvements
Jaroslav Hajek <highegg@gmail.com>
parents:
9395
diff
changeset
|
953 unwind_protect::add_fcn (octave_call_stack::pop); |
7336 | 954 |
6625 | 955 if (len > 0 && success) |
4989 | 956 { |
6625 | 957 #ifdef HAVE_H5GGET_NUM_OBJS |
958 hsize_t num_obj = 0; | |
959 data_hid = H5Gopen (group_hid, "symbol table"); | |
960 H5Gget_num_objs (data_hid, &num_obj); | |
961 H5Gclose (data_hid); | |
962 | |
963 if (num_obj != static_cast<hsize_t>(len)) | |
964 { | |
965 error ("load: failed to load anonymous function handle"); | |
966 success = false; | |
967 } | |
968 #endif | |
969 | |
970 if (! error_state) | |
971 { | |
972 hdf5_callback_data dsub; | |
973 int current_item = 0; | |
974 for (octave_idx_type i = 0; i < len; i++) | |
975 { | |
976 if (H5Giterate (group_hid, "symbol table", ¤t_item, | |
977 hdf5_read_next_data, &dsub) <= 0) | |
978 { | |
979 error ("load: failed to load anonymous function handle"); | |
980 success = false; | |
981 break; | |
982 } | |
983 | |
984 if (have_h5giterate_bug) | |
985 current_item++; // H5Giterate returns last index processed | |
986 | |
7336 | 987 symbol_table::varref (dsub.name, local_scope) = dsub.tc; |
6625 | 988 } |
989 } | |
990 } | |
991 | |
992 if (success) | |
993 { | |
994 int parse_status; | |
995 octave_value anon_fcn_handle = | |
996 eval_string (fcn_tmp, true, parse_status); | |
997 | |
998 if (parse_status == 0) | |
999 { | |
1000 octave_fcn_handle *fh = anon_fcn_handle.fcn_handle_value (); | |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1001 |
6625 | 1002 if (fh) |
7761
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1003 { |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1004 fcn = fh->fcn; |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1005 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1006 octave_user_function *uf = fcn.user_function_value (true); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1007 |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1008 if (uf) |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1009 symbol_table::cache_name (uf->scope (), nm); |
5adeea5de26c
symbol table reporting functions
John W. Eaton <jwe@octave.org>
parents:
7756
diff
changeset
|
1010 } |
6625 | 1011 else |
1012 success = false; | |
1013 } | |
4989 | 1014 else |
6625 | 1015 success = false; |
4989 | 1016 } |
6625 | 1017 |
9377
610bf90fce2a
update unwind_protect usage everywhere
Jaroslav Hajek <highegg@gmail.com>
parents:
9343
diff
changeset
|
1018 unwind_protect::run_frame (uwp_frame); |
4988 | 1019 } |
1020 else | |
1021 { | |
6625 | 1022 std::string octaveroot; |
1023 std::string fpath; | |
1024 | |
1025 // we have to pull some shenanigans here to make sure | |
1026 // HDF5 doesn't print out all sorts of error messages if we | |
1027 // call H5Aopen for a non-existing attribute | |
1028 | |
1029 H5E_auto_t err_func; | |
1030 void *err_func_data; | |
1031 | |
1032 // turn off error reporting temporarily, but save the error | |
1033 // reporting function: | |
1034 H5Eget_auto (&err_func, &err_func_data); | |
1035 H5Eset_auto (0, 0); | |
1036 | |
1037 hid_t attr_id = H5Aopen_name (group_hid, "OCTAVEROOT"); | |
1038 if (attr_id >= 0) | |
6225 | 1039 { |
6695 | 1040 H5Tclose (type_hid); |
6625 | 1041 type_hid = H5Aget_type (attr_id); |
1042 type_class_hid = H5Tget_class (type_hid); | |
1043 | |
1044 if (type_class_hid != H5T_STRING) | |
1045 success = false; | |
1046 else | |
1047 { | |
1048 slen = H5Tget_size (type_hid); | |
1049 st_id = H5Tcopy (H5T_C_S1); | |
1050 H5Tset_size (st_id, slen); | |
1051 OCTAVE_LOCAL_BUFFER (char, root_tmp, slen); | |
1052 | |
1053 if (H5Aread (attr_id, st_id, root_tmp) < 0) | |
1054 success = false; | |
1055 else | |
1056 octaveroot = root_tmp; | |
6695 | 1057 |
1058 H5Tclose (st_id); | |
6625 | 1059 } |
1060 | |
1061 H5Aclose (attr_id); | |
6225 | 1062 } |
6625 | 1063 |
6695 | 1064 if (success) |
6625 | 1065 { |
6695 | 1066 attr_id = H5Aopen_name (group_hid, "FILE"); |
1067 if (attr_id >= 0) | |
1068 { | |
1069 H5Tclose (type_hid); | |
1070 type_hid = H5Aget_type (attr_id); | |
1071 type_class_hid = H5Tget_class (type_hid); | |
6625 | 1072 |
6695 | 1073 if (type_class_hid != H5T_STRING) |
6625 | 1074 success = false; |
1075 else | |
6695 | 1076 { |
1077 slen = H5Tget_size (type_hid); | |
1078 st_id = H5Tcopy (H5T_C_S1); | |
1079 H5Tset_size (st_id, slen); | |
1080 OCTAVE_LOCAL_BUFFER (char, path_tmp, slen); | |
1081 | |
1082 if (H5Aread (attr_id, st_id, path_tmp) < 0) | |
1083 success = false; | |
1084 else | |
1085 fpath = path_tmp; | |
1086 | |
1087 H5Tclose (st_id); | |
1088 } | |
1089 | |
1090 H5Aclose (attr_id); | |
6625 | 1091 } |
1092 } | |
1093 | |
1094 // restore error reporting: | |
1095 H5Eset_auto (err_func, err_func_data); | |
1096 | |
1097 success = (success ? set_fcn (octaveroot, fpath) : success); | |
4988 | 1098 } |
1099 | |
6695 | 1100 H5Tclose (type_hid); |
1101 H5Sclose (space_hid); | |
1102 H5Gclose (group_hid); | |
1103 | |
6625 | 1104 return success; |
4988 | 1105 } |
6625 | 1106 |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1107 #endif |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1108 |
6625 | 1109 /* |
1110 | |
1111 %!test | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1112 %! a = 2; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1113 %! f = @(x) a + x; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1114 %! g = @(x) 2 * x; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1115 %! hm = @flops; |
7745
0ff0fc033f28
better handling of functions found by relative lookup
John W. Eaton <jwe@octave.org>
parents:
7744
diff
changeset
|
1116 %! hdld = @svd; |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1117 %! hbi = @log2; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1118 %! f2 = f; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1119 %! g2 = g; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1120 %! hm2 = hm; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1121 %! hdld2 = hdld; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1122 %! hbi2 = hbi; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1123 %! modes = {"-text", "-binary"}; |
6625 | 1124 %! if (!isempty(findstr(octave_config_info ("DEFS"),"HAVE_HDF5"))) |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1125 %! modes(end+1) = "-hdf5"; |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1126 %! endif |
7901 | 1127 %! for i = 1:numel (modes) |
1128 %! mode = modes{i}; | |
6625 | 1129 %! nm = tmpnam(); |
1130 %! unwind_protect | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1131 %! save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2"); |
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1132 %! clear f2 g2 hm2 hdld2 hbi2 |
6625 | 1133 %! load (nm); |
1134 %! assert (f(2),f2(2)); | |
1135 %! assert (g(2),g2(2)); | |
1136 %! assert (g(3),g2(3)); | |
1137 %! unlink (nm); | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1138 %! save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2"); |
6625 | 1139 %! unwind_protect_cleanup |
1140 %! unlink (nm); | |
1141 %! end_unwind_protect | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1142 %! endfor |
6625 | 1143 |
1144 */ | |
4988 | 1145 |
4343 | 1146 void |
1147 octave_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax) const | |
1148 { | |
1149 print_raw (os, pr_as_read_syntax); | |
1150 newline (os); | |
1151 } | |
1152 | |
1153 void | |
1154 octave_fcn_handle::print_raw (std::ostream& os, bool pr_as_read_syntax) const | |
1155 { | |
4980 | 1156 bool printed = false; |
1157 | |
1158 if (nm == "@<anonymous>") | |
1159 { | |
1160 tree_print_code tpc (os); | |
1161 | |
4989 | 1162 // FCN is const because this member function is, so we can't |
4980 | 1163 // use it to call user_function_value, so we make a copy first. |
1164 | |
1165 octave_value ftmp = fcn; | |
1166 | |
1167 octave_user_function *f = ftmp.user_function_value (); | |
1168 | |
1169 if (f) | |
1170 { | |
1171 tree_parameter_list *p = f->parameter_list (); | |
1172 | |
1173 os << "@("; | |
1174 | |
1175 if (p) | |
1176 p->accept (tpc); | |
1177 | |
1178 os << ") "; | |
1179 | |
1180 tree_statement_list *b = f->body (); | |
1181 | |
1182 if (b) | |
1183 { | |
1184 assert (b->length () == 1); | |
1185 | |
1186 tree_statement *s = b->front (); | |
1187 | |
1188 if (s) | |
1189 { | |
1190 if (s->is_expression ()) | |
1191 { | |
1192 tree_expression *e = s->expression (); | |
1193 | |
1194 if (e) | |
6657 | 1195 e->accept (tpc); |
4980 | 1196 } |
1197 else | |
1198 { | |
1199 tree_command *c = s->command (); | |
1200 | |
1201 tpc.suspend_newline (); | |
1202 c->accept (tpc); | |
1203 tpc.resume_newline (); | |
1204 } | |
1205 } | |
1206 } | |
1207 | |
1208 printed = true; | |
1209 } | |
1210 } | |
1211 | |
1212 if (! printed) | |
1213 octave_print_internal (os, nm, pr_as_read_syntax, | |
1214 current_print_indent_level ()); | |
4343 | 1215 } |
1216 | |
1217 octave_value | |
1218 make_fcn_handle (const std::string& nm) | |
1219 { | |
1220 octave_value retval; | |
1221 | |
9342
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1222 // Bow to the god of compatibility. |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1223 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1224 // FIXME -- it seems ugly to put this here, but there is no single |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1225 // function in the parser that converts from the operator name to |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1226 // the corresponding function name. At least try to do it without N |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1227 // string compares. |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1228 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1229 std::string tnm = nm; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1230 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1231 size_t len = nm.length (); |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1232 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1233 if (len == 3 && nm == ".**") |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1234 tnm = "power"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1235 else if (len == 2) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1236 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1237 if (nm[0] == '.') |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1238 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1239 switch (nm[1]) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1240 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1241 case '\'': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1242 tnm = "transpose"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1243 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1244 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1245 case '+': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1246 tnm = "plus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1247 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1248 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1249 case '-': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1250 tnm = "minus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1251 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1252 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1253 case '*': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1254 tnm = "times"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1255 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1256 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1257 case '/': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1258 tnm = "rdivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1259 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1260 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1261 case '^': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1262 tnm = "power"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1263 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1264 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1265 case '\\': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1266 tnm = "ldivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1267 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1268 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1269 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1270 else if (nm[1] == '=') |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1271 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1272 switch (nm[0]) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1273 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1274 case '<': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1275 tnm = "le"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1276 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1277 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1278 case '=': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1279 tnm = "eq"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1280 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1281 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1282 case '>': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1283 tnm = "ge"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1284 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1285 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1286 case '~': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1287 case '!': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1288 tnm = "ne"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1289 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1290 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1291 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1292 else if (nm == "**") |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1293 tnm = "mpower"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1294 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1295 else if (len == 1) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1296 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1297 switch (nm[0]) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1298 { |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1299 case '~': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1300 case '!': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1301 tnm = "not"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1302 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1303 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1304 case '\'': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1305 tnm = "ctranspose"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1306 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1307 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1308 case '+': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1309 tnm = "plus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1310 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1311 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1312 case '-': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1313 tnm = "minus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1314 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1315 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1316 case '*': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1317 tnm = "mtimes"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1318 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1319 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1320 case '/': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1321 tnm = "mrdivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1322 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1323 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1324 case '^': |
9343
70e0d3b1f26f
fix typos in previous change
John W. Eaton <jwe@octave.org>
parents:
9342
diff
changeset
|
1325 tnm = "mpower"; |
9342
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1326 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1327 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1328 case '\\': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1329 tnm = "mldivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1330 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1331 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1332 case '<': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1333 tnm = "lt"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1334 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1335 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1336 case '>': |
9343
70e0d3b1f26f
fix typos in previous change
John W. Eaton <jwe@octave.org>
parents:
9342
diff
changeset
|
1337 tnm = "gt"; |
9342
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1338 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1339 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1340 case '&': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1341 tnm = "and"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1342 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1343 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1344 case '|': |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1345 tnm = "or"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1346 break; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1347 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1348 } |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1349 |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1350 octave_value f = symbol_table::find_function (tnm); |
6481 | 1351 |
7336 | 1352 if (f.is_defined ()) |
9342
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1353 retval = octave_value (new octave_fcn_handle (f, tnm)); |
4343 | 1354 else |
1355 error ("error creating function handle \"@%s\"", nm.c_str ()); | |
1356 | |
1357 return retval; | |
1358 } | |
1359 | |
9342
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1360 /* |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1361 %!test |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1362 %! x = {".**", "power"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1363 %! ".'", "transpose"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1364 %! ".+", "plus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1365 %! ".-", "minus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1366 %! ".*", "times"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1367 %! "./", "rdivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1368 %! ".^", "power"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1369 %! ".\\", "ldivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1370 %! "<=", "le"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1371 %! "==", "eq"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1372 %! ">=", "ge"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1373 %! "~=", "ne"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1374 %! "!=", "ne"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1375 %! "**", "mpower"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1376 %! "~", "not"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1377 %! "!", "not"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1378 %! "\'", "ctranspose"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1379 %! "+", "plus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1380 %! "-", "minus"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1381 %! "*", "mtimes"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1382 %! "/", "mrdivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1383 %! "^", "mpower"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1384 %! "\\", "mldivide"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1385 %! "<", "lt"; |
9343
70e0d3b1f26f
fix typos in previous change
John W. Eaton <jwe@octave.org>
parents:
9342
diff
changeset
|
1386 %! ">", "gt"; |
9342
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1387 %! "&", "and"; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1388 %! "|", "or"}; |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1389 %! for i = 1:rows (x) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1390 %! assert (functions (str2func (x{i,1})).function, x{i,2}) |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1391 %! endfor |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1392 */ |
2ca8879a140c
allow function handles to be created from operators that correspond to named functions
John W. Eaton <jwe@octave.org>
parents:
9144
diff
changeset
|
1393 |
4933 | 1394 DEFUN (functions, args, , |
4343 | 1395 "-*- texinfo -*-\n\ |
4933 | 1396 @deftypefn {Built-in Function} {} functions (@var{fcn_handle})\n\ |
1397 Return a struct containing information about the function handle\n\ | |
1398 @var{fcn_handle}.\n\ | |
1399 @end deftypefn") | |
4343 | 1400 { |
1401 octave_value retval; | |
1402 | |
4933 | 1403 if (args.length () == 1) |
4343 | 1404 { |
4933 | 1405 octave_fcn_handle *fh = args(0).fcn_handle_value (); |
4343 | 1406 |
1407 if (! error_state) | |
1408 { | |
7744
14b841c47a5f
handle load/save for handles to built-in functions
John W. Eaton <jwe@octave.org>
parents:
7740
diff
changeset
|
1409 octave_function *fcn = fh ? fh->function_value () : 0; |
4343 | 1410 |
4933 | 1411 if (fcn) |
4930 | 1412 { |
4933 | 1413 Octave_map m; |
4649 | 1414 |
4933 | 1415 std::string fh_nm = fh->fcn_name (); |
1416 | |
6625 | 1417 if (fh_nm == "@<anonymous>") |
1418 { | |
1419 std::ostringstream buf; | |
1420 fh->print_raw (buf); | |
1421 m.assign ("function", buf.str ()); | |
1422 | |
1423 m.assign ("type", "anonymous"); | |
1424 } | |
1425 else | |
1426 { | |
1427 m.assign ("function", fh_nm); | |
4343 | 1428 |
6625 | 1429 if (fcn->is_nested_function ()) |
1430 { | |
1431 m.assign ("type", "subfunction"); | |
1432 Cell parentage (dim_vector (1, 2)); | |
1433 parentage.elem(0) = fh_nm; | |
1434 parentage.elem(1) = fcn->parent_fcn_name (); | |
7756
45de7d8dac72
ov-fcn-handle.cc (Ffunctions): fix structure assignment
John W. Eaton <jwe@octave.org>
parents:
7745
diff
changeset
|
1435 m.assign ("parentage", octave_value (parentage)); |
6625 | 1436 } |
1437 else | |
1438 m.assign ("type", "simple"); | |
1439 } | |
4933 | 1440 |
1441 std::string nm = fcn->fcn_file_name (); | |
4343 | 1442 |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1443 if (fh_nm == "@<anonymous>") |
4935 | 1444 { |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1445 m.assign ("file", nm); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1446 |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1447 octave_user_function *fu = fh->user_function_value (); |
6625 | 1448 |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1449 std::list<symbol_table::symbol_record> vars |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1450 = symbol_table::all_variables (fu->scope (), 0); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1451 |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1452 size_t varlen = vars.size (); |
6625 | 1453 |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1454 if (varlen > 0) |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1455 { |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1456 Octave_map ws; |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1457 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin (); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1458 p != vars.end (); p++) |
6625 | 1459 { |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1460 ws.assign (p->name (), p->varval (0)); |
6625 | 1461 } |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1462 |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1463 m.assign ("workspace", ws); |
6625 | 1464 } |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1465 } |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1466 else if (fcn->is_user_function () || fcn->is_user_script ()) |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1467 { |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1468 octave_function *fu = fh->function_value (); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1469 m.assign ("file", fu->fcn_file_name ()); |
4935 | 1470 } |
4343 | 1471 else |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1472 m.assign ("file", ""); |
4933 | 1473 |
1474 retval = m; | |
4343 | 1475 } |
1476 else | |
4933 | 1477 error ("functions: invalid function handle object"); |
4343 | 1478 } |
1479 else | |
4933 | 1480 error ("functions: argument must be a function handle object"); |
4343 | 1481 } |
1482 else | |
5823 | 1483 print_usage (); |
4343 | 1484 |
1485 return retval; | |
1486 } | |
1487 | |
4933 | 1488 DEFUN (func2str, args, , |
4343 | 1489 "-*- texinfo -*-\n\ |
4933 | 1490 @deftypefn {Built-in Function} {} func2str (@var{fcn_handle})\n\ |
1491 Return a string containing the name of the function referenced by\n\ | |
1492 the function handle @var{fcn_handle}.\n\ | |
1493 @end deftypefn") | |
4343 | 1494 { |
1495 octave_value retval; | |
1496 | |
4933 | 1497 if (args.length () == 1) |
4930 | 1498 { |
4933 | 1499 octave_fcn_handle *fh = args(0).fcn_handle_value (); |
4930 | 1500 |
4933 | 1501 if (! error_state && fh) |
1502 { | |
1503 std::string fh_nm = fh->fcn_name (); | |
6416 | 1504 |
1505 if (fh_nm == "@<anonymous>") | |
1506 { | |
1507 std::ostringstream buf; | |
1508 | |
1509 fh->print_raw (buf); | |
1510 | |
1511 retval = buf.str (); | |
1512 } | |
1513 else | |
1514 retval = fh_nm; | |
4933 | 1515 } |
4343 | 1516 else |
4933 | 1517 error ("func2str: expecting valid function handle as first argument"); |
4343 | 1518 } |
1519 else | |
5823 | 1520 print_usage (); |
4343 | 1521 |
1522 return retval; | |
1523 } | |
1524 | |
4933 | 1525 DEFUN (str2func, args, , |
4343 | 1526 "-*- texinfo -*-\n\ |
4933 | 1527 @deftypefn {Built-in Function} {} str2func (@var{fcn_name})\n\ |
1528 Return a function handle constructed from the string @var{fcn_name}.\n\ | |
1529 @end deftypefn") | |
4343 | 1530 { |
1531 octave_value retval; | |
1532 | |
4933 | 1533 if (args.length () == 1) |
4343 | 1534 { |
4933 | 1535 std::string nm = args(0).string_value (); |
4343 | 1536 |
4933 | 1537 if (! error_state) |
1538 retval = make_fcn_handle (nm); | |
4343 | 1539 else |
4933 | 1540 error ("str2func: expecting string as first argument"); |
4343 | 1541 } |
1542 else | |
5823 | 1543 print_usage (); |
4343 | 1544 |
1545 return retval; | |
1546 } | |
1547 | |
1548 /* | |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1549 %!function y = testrecursionfunc (f, x, n) |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1550 %! if (nargin < 3) |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1551 %! n = 0; |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1552 %! endif |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1553 %! if (n > 2) |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1554 %! y = f (x); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1555 %! else |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1556 %! n++; |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1557 %! y = testrecursionfunc (@(x) f(2*x), x, n); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1558 %! endif |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1559 %!test |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1560 %! assert (testrecursionfunc (@(x) x, 1), 8); |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1561 */ |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1562 |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7761
diff
changeset
|
1563 /* |
4343 | 1564 ;;; Local Variables: *** |
1565 ;;; mode: C++ *** | |
1566 ;;; End: *** | |
1567 */ |