comparison src/ov-fcn-handle.cc @ 7336:745a8299c2b5

[project @ 2007-12-28 20:56:55 by jwe]
author jwe
date Fri, 28 Dec 2007 20:56:58 +0000
parents 97db94ae2cf0
children a9d25da4ed9c
comparison
equal deleted inserted replaced
7335:58f5fab3ebe5 7336:745a8299c2b5
25 #endif 25 #endif
26 26
27 #include <iostream> 27 #include <iostream>
28 #include <sstream> 28 #include <sstream>
29 #include <vector> 29 #include <vector>
30
31 #include "file-ops.h"
30 32
31 #include "defun.h" 33 #include "defun.h"
32 #include "error.h" 34 #include "error.h"
33 #include "gripes.h" 35 #include "gripes.h"
34 #include "input.h" 36 #include "input.h"
61 63
62 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_handle, 64 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_handle,
63 "function handle", 65 "function handle",
64 "function_handle"); 66 "function_handle");
65 67
66 void
67 octave_fcn_handle::reload_warning (const std::string& fcn_type) const
68 {
69 if (warn_reload)
70 {
71 warn_reload = false;
72
73 warning ("reloading %s functions referenced by function handles is not implemented",
74 fcn_type.c_str ());
75 }
76 }
77
78 octave_value_list 68 octave_value_list
79 octave_fcn_handle::subsref (const std::string& type, 69 octave_fcn_handle::subsref (const std::string& type,
80 const std::list<octave_value_list>& idx, 70 const std::list<octave_value_list>& idx,
81 int nargout) 71 int nargout)
82 { 72 {
84 74
85 switch (type[0]) 75 switch (type[0])
86 { 76 {
87 case '(': 77 case '(':
88 { 78 {
89 octave_function *f = function_value (); 79 out_of_date_check (fcn);
90 80
91 if (f && f->time_checked () < Vlast_prompt_time) 81 if (fcn.is_defined ())
92 { 82 {
93 std::string ff_nm = f->fcn_file_name (); 83 octave_function *f = function_value ();
94 84
95 octave_time ottp = f->time_parsed (); 85 if (f)
96 time_t tp = ottp.unix_time (); 86 retval = f->subsref (type, idx, nargout);
97
98 if (ff_nm.empty ())
99 {
100 // FIXME -- need to handle inline and
101 // command-line functions here.
102 }
103 else 87 else
104 { 88 error ("invalid function handle");
105 if (fcn_out_of_date (f, ff_nm, tp))
106 {
107 // FIXME -- there is currently no way to
108 // parse a .m file or reload a .oct file that
109 // leaves the fbi symbol table untouched. We need
110 // a function that will parse the file and return
111 // a pointer to the new function definition
112 // without altering the symbol table.
113
114 if (f->is_nested_function ())
115 reload_warning ("nested");
116 else
117 reload_warning ("functions");
118 }
119 }
120 } 89 }
121
122 if (f)
123 retval = f->subsref (type, idx, nargout);
124 else 90 else
125 error ("invalid function handle"); 91 error ("invalid function handle");
126 } 92 }
127 break; 93 break;
128
129 94
130 case '{': 95 case '{':
131 case '.': 96 case '.':
132 { 97 {
133 std::string typ_nm = type_name (); 98 std::string typ_nm = type_name ();
165 fpath.substr (octaveroot.length ()); 130 fpath.substr (octaveroot.length ());
166 file_stat fs (str); 131 file_stat fs (str);
167 132
168 if (fs.exists ()) 133 if (fs.exists ())
169 { 134 {
170 symbol_record *sr = fbi_sym_tab->lookup (str, true); 135 size_t xpos = str.find_last_of (file_ops::dir_sep_chars);
171 136
172 if (sr) 137 std::string dir_name = str.substr (0, xpos);
173 { 138
174 load_fcn_from_file (sr, false); 139 octave_function *xfcn
175 140 = load_fcn_from_file (str, dir_name, "", nm);
176 fcn = octave_value (new octave_fcn_handle (sr->def (), nm)); 141
177 142 if (xfcn)
178 // The next two lines are needed to force the 143 {
179 // definition of the function back to the one 144 octave_value tmp (xfcn);
180 // that is on the user path. 145
181 sr = fbi_sym_tab->lookup (nm, true); 146 fcn = octave_value (new octave_fcn_handle (tmp, nm));
182
183 load_fcn_from_file (sr, false);
184
185 } 147 }
186 else 148 else
187 { 149 {
188 error ("function handle points to non-existent function"); 150 error ("function handle points to non-existent function");
189 success = false; 151 success = false;
200 dir_path p (load_path::system_path ()); 162 dir_path p (load_path::system_path ());
201 163
202 str = octave_env::make_absolute 164 str = octave_env::make_absolute
203 (p.find_first_of (names), octave_env::getcwd ()); 165 (p.find_first_of (names), octave_env::getcwd ());
204 166
205 symbol_record *sr = fbi_sym_tab->lookup (str, true); 167 size_t xpos = str.find_last_of (file_ops::dir_sep_chars);
206 168
207 if (sr) 169 std::string dir_name = str.substr (0, xpos);
208 { 170
209 load_fcn_from_file (sr, false); 171 octave_function *xfcn = load_fcn_from_file (str, dir_name, "", nm);
210 172
211 fcn = octave_value (new octave_fcn_handle (sr->def (), nm)); 173 if (xfcn)
212 174 {
213 // The next two lines are needed to force the 175 octave_value tmp (xfcn);
214 // definition of the function back to the one 176
215 // that is on the user path. 177 fcn = octave_value (new octave_fcn_handle (tmp, nm));
216 sr = fbi_sym_tab->lookup (nm, true);
217
218 load_fcn_from_file (sr, false);
219 } 178 }
220 else 179 else
221 { 180 {
222 error ("function handle points to non-existent function"); 181 error ("function handle points to non-existent function");
223 success = false; 182 success = false;
226 } 185 }
227 else 186 else
228 { 187 {
229 if (fpath.length () > 0) 188 if (fpath.length () > 0)
230 { 189 {
231 symbol_record *sr = fbi_sym_tab->lookup (fpath, true); 190 size_t xpos = fpath.find_last_of (file_ops::dir_sep_chars);
232 191
233 if (sr) 192 std::string dir_name = fpath.substr (0, xpos);
234 { 193
235 load_fcn_from_file (sr, false); 194 octave_function *xfcn = load_fcn_from_file (fpath, dir_name, "", nm);
236 195
237 fcn = octave_value (new octave_fcn_handle (sr->def (), nm)); 196 if (xfcn)
238 197 {
239 sr = fbi_sym_tab->lookup (nm, true); 198 octave_value tmp (xfcn);
240 199
241 load_fcn_from_file (sr, false); 200 fcn = octave_value (new octave_fcn_handle (tmp, nm));
242 } 201 }
243 else 202 else
244 { 203 {
245 error ("function handle points to non-existent function"); 204 error ("function handle points to non-existent function");
246 success = false; 205 success = false;
247 } 206 }
248 } 207 }
249 else 208 else
250 { 209 {
251 fcn = lookup_function (nm); 210 fcn = symbol_table::find_function (nm);
211
252 if (! fcn.is_function ()) 212 if (! fcn.is_function ())
253 { 213 {
254 error ("function handle points to non-existent function"); 214 error ("function handle points to non-existent function");
255 success = false; 215 success = false;
256 } 216 }
268 os << nm << "\n"; 228 os << nm << "\n";
269 229
270 print_raw (os, true); 230 print_raw (os, true);
271 os << "\n"; 231 os << "\n";
272 232
273 if (fcn.is_undefined()) 233 if (fcn.is_undefined ())
274 return false; 234 return false;
275 235
276 octave_user_function *f = fcn.user_function_value (); 236 octave_user_function *f = fcn.user_function_value ();
277 237
278 Array<symbol_record *> vars = f->sym_tab()->symbol_list(); 238 std::list<symbol_table::symbol_record> vars
279 octave_idx_type varlen = vars.length(); 239 = symbol_table::all_variables (f->scope ());
280 240
281 // Exclude undefined values like __retval__ 241 size_t varlen = vars.size ();
282 for (octave_idx_type i = 0; i < vars.length(); i++)
283 {
284 if (! vars(i)->is_defined ())
285 varlen--;
286 }
287 242
288 if (varlen > 0) 243 if (varlen > 0)
289 { 244 {
290 os << "# length: " << varlen << "\n"; 245 os << "# length: " << varlen << "\n";
291 246
292 for (octave_idx_type i = 0; i < vars.length(); i++) 247 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
293 { 248 p != vars.end (); p++)
294 if (vars(i)->is_defined () && 249 {
295 ! save_ascii_data (os, vars(i)->def(), vars(i)->name(), 250 if (! save_ascii_data (os, p->varval (), p->name (), false, 0))
296 false, 0))
297 return os; 251 return os;
298 } 252 }
299 } 253 }
300 } 254 }
301 else 255 else
355 buf << c; 309 buf << c;
356 } 310 }
357 } 311 }
358 312
359 pos = is.tellg (); 313 pos = is.tellg ();
360 symbol_table *local_sym_tab = 0; 314
315 symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
361 316
362 if (extract_keyword (is, "length", len, true) && len >= 0) 317 if (extract_keyword (is, "length", len, true) && len >= 0)
363 { 318 {
364 if (len > 0) 319 if (len > 0)
365 { 320 {
366 octave_idx_type nlen = len;
367 if (nlen % 2)
368 nlen++;
369
370 local_sym_tab = new symbol_table (((nlen + 1) & ~1) , "LOCAL");
371
372 for (octave_idx_type i = 0; i < len; i++) 321 for (octave_idx_type i = 0; i < len; i++)
373 { 322 {
374 octave_value t2; 323 octave_value t2;
375 bool dummy; 324 bool dummy;
376 325
381 { 330 {
382 error ("load: failed to load anonymous function handle"); 331 error ("load: failed to load anonymous function handle");
383 break; 332 break;
384 } 333 }
385 334
386 symbol_record *sr = local_sym_tab->lookup (name, true); 335 symbol_table::varref (name, local_scope) = t2;
387
388 if (sr)
389 sr->define (t2);
390 else
391 {
392 error ("load: failed to load anonymous function handle");
393 success = false;
394 break;
395 }
396 } 336 }
397 } 337 }
398 } 338 }
399 else 339 else
400 { 340 {
403 } 343 }
404 344
405 if (is && success) 345 if (is && success)
406 { 346 {
407 unwind_protect::begin_frame ("anon_ascii_load"); 347 unwind_protect::begin_frame ("anon_ascii_load");
408 unwind_protect_ptr (curr_sym_tab); 348
409 349 symbol_table::push_scope (local_scope);
410 if (local_sym_tab) 350
411 curr_sym_tab = local_sym_tab; 351 unwind_protect::add (symbol_table::pop_scope);
412 352
413 int parse_status; 353 int parse_status;
414 octave_value anon_fcn_handle = 354 octave_value anon_fcn_handle =
415 eval_string (buf.str (), true, parse_status); 355 eval_string (buf.str (), true, parse_status);
416 356
429 unwind_protect::run_frame ("anon_ascii_load"); 369 unwind_protect::run_frame ("anon_ascii_load");
430 } 370 }
431 else 371 else
432 success = false; 372 success = false;
433 373
434 if (local_sym_tab) 374 symbol_table::erase_scope (local_scope);
435 delete local_sym_tab;
436 } 375 }
437 else 376 else
438 success = set_fcn (octaveroot, fpath); 377 success = set_fcn (octaveroot, fpath);
439 378
440 return success; 379 return success;
471 { 410 {
472 if (nm == "@<anonymous>") 411 if (nm == "@<anonymous>")
473 { 412 {
474 std::ostringstream nmbuf; 413 std::ostringstream nmbuf;
475 414
476 if (fcn.is_undefined()) 415 if (fcn.is_undefined ())
477 return false; 416 return false;
478 417
479 octave_user_function *f = fcn.user_function_value (); 418 octave_user_function *f = fcn.user_function_value ();
480 419
481 Array<symbol_record *> vars = f->sym_tab()->symbol_list(); 420 std::list<symbol_table::symbol_record> vars
482 octave_idx_type varlen = vars.length(); 421 = symbol_table::all_variables (f->scope ());
483 422
484 // Exclude undefined values like __retval__ 423 size_t varlen = vars.size ();
485 for (octave_idx_type i = 0; i < vars.length(); i++)
486 {
487 if (! vars(i)->is_defined ())
488 varlen--;
489 }
490 424
491 if (varlen > 0) 425 if (varlen > 0)
492 nmbuf << nm << " " << varlen; 426 nmbuf << nm << " " << varlen;
493 else 427 else
494 nmbuf << nm; 428 nmbuf << nm;
505 os.write (reinterpret_cast<char *> (&tmp), 4); 439 os.write (reinterpret_cast<char *> (&tmp), 4);
506 os.write (stmp.c_str (), stmp.length ()); 440 os.write (stmp.c_str (), stmp.length ());
507 441
508 if (varlen > 0) 442 if (varlen > 0)
509 { 443 {
510 for (octave_idx_type i = 0; i < vars.length(); i++) 444 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
511 { 445 p != vars.end (); p++)
512 if (vars(i)->is_defined () && 446 {
513 ! save_binary_data (os, vars(i)->def(), vars(i)->name(), 447 if (! save_binary_data (os, p->varval (), p->name (),
514 "", 0, save_as_floats)) 448 "", 0, save_as_floats))
515 return os; 449 return os;
516 } 450 }
517 } 451 }
518 } 452 }
526 std::string buf_str = nmbuf.str (); 460 std::string buf_str = nmbuf.str ();
527 int32_t tmp = buf_str.length (); 461 int32_t tmp = buf_str.length ();
528 os.write (reinterpret_cast<char *> (&tmp), 4); 462 os.write (reinterpret_cast<char *> (&tmp), 4);
529 os.write (buf_str.c_str (), buf_str.length ()); 463 os.write (buf_str.c_str (), buf_str.length ());
530 } 464 }
465
531 return true; 466 return true;
532 } 467 }
533 468
534 bool 469 bool
535 octave_fcn_handle::load_binary (std::istream& is, bool swap, 470 octave_fcn_handle::load_binary (std::istream& is, bool swap,
536 oct_mach_info::float_format fmt) 471 oct_mach_info::float_format fmt)
537 { 472 {
538 bool success = true; 473 bool success = true;
474
539 int32_t tmp; 475 int32_t tmp;
540 if (! is.read (reinterpret_cast<char *> (&tmp), 4)) 476 if (! is.read (reinterpret_cast<char *> (&tmp), 4))
541 return false; 477 return false;
542 if (swap) 478 if (swap)
543 swap_bytes<4> (&tmp); 479 swap_bytes<4> (&tmp);
566 swap_bytes<4> (&tmp); 502 swap_bytes<4> (&tmp);
567 503
568 OCTAVE_LOCAL_BUFFER (char, ctmp2, tmp+1); 504 OCTAVE_LOCAL_BUFFER (char, ctmp2, tmp+1);
569 is.read (ctmp2, tmp); 505 is.read (ctmp2, tmp);
570 506
571 symbol_table *local_sym_tab = 0; 507 symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
508
572 if (len > 0) 509 if (len > 0)
573 { 510 {
574 octave_idx_type nlen = len;
575 if (nlen % 2)
576 nlen++;
577
578 local_sym_tab = new symbol_table (nlen, "LOCAL");
579
580 for (octave_idx_type i = 0; i < len; i++) 511 for (octave_idx_type i = 0; i < len; i++)
581 { 512 {
582 octave_value t2; 513 octave_value t2;
583 bool dummy; 514 bool dummy;
584 std::string doc; 515 std::string doc;
591 { 522 {
592 error ("load: failed to load anonymous function handle"); 523 error ("load: failed to load anonymous function handle");
593 break; 524 break;
594 } 525 }
595 526
596 symbol_record *sr = local_sym_tab->lookup (name, true); 527 symbol_table::varref (name, local_scope) = t2;
597
598 if (sr)
599 {
600 sr->define (t2);
601 sr->document (doc);
602 }
603 else
604 {
605 error ("load: failed to load anonymous function handle");
606 success = false;
607 break;
608 }
609 } 528 }
610 } 529 }
611 530
612 if (is && success) 531 if (is && success)
613 { 532 {
614 unwind_protect::begin_frame ("anon_binary_load"); 533 unwind_protect::begin_frame ("anon_binary_load");
615 unwind_protect_ptr (curr_sym_tab); 534
616 535 symbol_table::push_scope (local_scope);
617 if (local_sym_tab) 536
618 curr_sym_tab = local_sym_tab; 537 unwind_protect::add (symbol_table::pop_scope);
619 538
620 int parse_status; 539 int parse_status;
621 octave_value anon_fcn_handle = 540 octave_value anon_fcn_handle =
622 eval_string (ctmp2, true, parse_status); 541 eval_string (ctmp2, true, parse_status);
623 542
633 success = false; 552 success = false;
634 553
635 unwind_protect::run_frame ("anon_binary_load"); 554 unwind_protect::run_frame ("anon_binary_load");
636 } 555 }
637 556
638 if (local_sym_tab) 557 symbol_table::erase_scope (local_scope);
639 delete local_sym_tab;
640 } 558 }
641 else 559 else
642 { 560 {
643 std::string octaveroot; 561 std::string octaveroot;
644 std::string fpath; 562 std::string fpath;
687 #if defined (HAVE_HDF5) 605 #if defined (HAVE_HDF5)
688 bool 606 bool
689 octave_fcn_handle::save_hdf5 (hid_t loc_id, const char *name, 607 octave_fcn_handle::save_hdf5 (hid_t loc_id, const char *name,
690 bool save_as_floats) 608 bool save_as_floats)
691 { 609 {
610 bool retval = true;
611
692 hid_t group_hid = -1; 612 hid_t group_hid = -1;
693 group_hid = H5Gcreate (loc_id, name, 0); 613 group_hid = H5Gcreate (loc_id, name, 0);
694 if (group_hid < 0 ) return false; 614 if (group_hid < 0)
615 return false;
695 616
696 hid_t space_hid = -1, data_hid = -1, type_hid = -1;; 617 hid_t space_hid = -1, data_hid = -1, type_hid = -1;;
697 bool retval = true;
698 618
699 // attach the type of the variable 619 // attach the type of the variable
700 type_hid = H5Tcopy (H5T_C_S1); 620 type_hid = H5Tcopy (H5T_C_S1);
701 H5Tset_size (type_hid, nm.length () + 1); 621 H5Tset_size (type_hid, nm.length () + 1);
702 if (type_hid < 0) 622 if (type_hid < 0)
754 } 674 }
755 675
756 H5Dclose (data_hid); 676 H5Dclose (data_hid);
757 677
758 octave_user_function *f = fcn.user_function_value (); 678 octave_user_function *f = fcn.user_function_value ();
759 Array<symbol_record *> vars = f->sym_tab()->symbol_list(); 679
760 octave_idx_type varlen = vars.length(); 680 std::list<symbol_table::symbol_record> vars
761 681 = symbol_table::all_variables (f->scope ());
762 // Exclude undefined values like __retval__ 682
763 for (octave_idx_type i = 0; i < vars.length(); i++) 683 size_t varlen = vars.size ();
764 {
765 if (! vars(i)->is_defined ())
766 varlen--;
767 }
768 684
769 if (varlen > 0) 685 if (varlen > 0)
770 { 686 {
771 hid_t as_id = H5Screate (H5S_SCALAR); 687 hid_t as_id = H5Screate (H5S_SCALAR);
772 688
796 H5Tclose (type_hid); 712 H5Tclose (type_hid);
797 H5Gclose (group_hid); 713 H5Gclose (group_hid);
798 return false; 714 return false;
799 } 715 }
800 716
801 for (octave_idx_type i = 0; i < vars.length(); i++) 717 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
802 { 718 p != vars.end (); p++)
803 if (vars(i)->is_defined () && 719 {
804 ! add_hdf5_data (data_hid, vars(i)->def(), vars(i)->name(), 720 if (! add_hdf5_data (data_hid, p->varval (), p->name (),
805 "", false, save_as_floats)) 721 "", false, save_as_floats))
806 break; 722 break;
807 } 723 }
808 H5Gclose (data_hid); 724 H5Gclose (data_hid);
809 } 725 }
881 797
882 bool 798 bool
883 octave_fcn_handle::load_hdf5 (hid_t loc_id, const char *name, 799 octave_fcn_handle::load_hdf5 (hid_t loc_id, const char *name,
884 bool have_h5giterate_bug) 800 bool have_h5giterate_bug)
885 { 801 {
802 bool success = true;
803
886 hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id; 804 hid_t group_hid, data_hid, space_hid, type_hid, type_class_hid, st_id;
887 hsize_t rank; 805 hsize_t rank;
888 int slen; 806 int slen;
889 bool success = true;
890 807
891 group_hid = H5Gopen (loc_id, name); 808 group_hid = H5Gopen (loc_id, name);
892 if (group_hid < 0 ) return false; 809 if (group_hid < 0)
810 return false;
893 811
894 data_hid = H5Dopen (group_hid, "nm"); 812 data_hid = H5Dopen (group_hid, "nm");
895 813
896 if (data_hid < 0) 814 if (data_hid < 0)
897 { 815 {
1015 return false; 933 return false;
1016 } 934 }
1017 H5Tclose (st_id); 935 H5Tclose (st_id);
1018 H5Dclose (data_hid); 936 H5Dclose (data_hid);
1019 937
1020 symbol_table *local_sym_tab = 0;
1021 octave_idx_type len = 0; 938 octave_idx_type len = 0;
1022 939
1023 // we have to pull some shenanigans here to make sure 940 // we have to pull some shenanigans here to make sure
1024 // HDF5 doesn't print out all sorts of error messages if we 941 // HDF5 doesn't print out all sorts of error messages if we
1025 // call H5Aopen for a non-existing attribute 942 // call H5Aopen for a non-existing attribute
1043 } 960 }
1044 961
1045 // restore error reporting: 962 // restore error reporting:
1046 H5Eset_auto (err_func, err_func_data); 963 H5Eset_auto (err_func, err_func_data);
1047 964
965 symbol_table::scope_id local_scope = symbol_table::alloc_scope ();
966
1048 if (len > 0 && success) 967 if (len > 0 && success)
1049 { 968 {
1050 octave_idx_type nlen = len;
1051 if (nlen % 2)
1052 nlen++;
1053
1054 local_sym_tab = new symbol_table (nlen, "LOCAL");
1055
1056 #ifdef HAVE_H5GGET_NUM_OBJS 969 #ifdef HAVE_H5GGET_NUM_OBJS
1057 hsize_t num_obj = 0; 970 hsize_t num_obj = 0;
1058 data_hid = H5Gopen (group_hid, "symbol table"); 971 data_hid = H5Gopen (group_hid, "symbol table");
1059 H5Gget_num_objs (data_hid, &num_obj); 972 H5Gget_num_objs (data_hid, &num_obj);
1060 H5Gclose (data_hid); 973 H5Gclose (data_hid);
1081 } 994 }
1082 995
1083 if (have_h5giterate_bug) 996 if (have_h5giterate_bug)
1084 current_item++; // H5Giterate returns last index processed 997 current_item++; // H5Giterate returns last index processed
1085 998
1086 symbol_record *sr = local_sym_tab->lookup (dsub.name, true); 999 symbol_table::varref (dsub.name, local_scope) = dsub.tc;
1087
1088 if (sr)
1089 sr->define (dsub.tc);
1090 else
1091 {
1092 error ("load: failed to load anonymous function handle");
1093 success = false;
1094 break;
1095 }
1096 } 1000 }
1097 } 1001 }
1098 } 1002 }
1099 1003
1100 if (success) 1004 if (success)
1101 { 1005 {
1102 unwind_protect::begin_frame ("anon_hdf5_load"); 1006 unwind_protect::begin_frame ("anon_hdf5_load");
1103 unwind_protect_ptr (curr_sym_tab); 1007
1104 1008 symbol_table::push_scope (local_scope);
1105 if (local_sym_tab) 1009
1106 curr_sym_tab = local_sym_tab; 1010 unwind_protect::add (symbol_table::pop_scope);
1107 1011
1108 int parse_status; 1012 int parse_status;
1109 octave_value anon_fcn_handle = 1013 octave_value anon_fcn_handle =
1110 eval_string (fcn_tmp, true, parse_status); 1014 eval_string (fcn_tmp, true, parse_status);
1111 1015
1121 success = false; 1025 success = false;
1122 1026
1123 unwind_protect::run_frame ("anon_hdf5_load"); 1027 unwind_protect::run_frame ("anon_hdf5_load");
1124 } 1028 }
1125 1029
1126 if (local_sym_tab) 1030 symbol_table::erase_scope (local_scope);
1127 delete local_sym_tab;
1128 } 1031 }
1129 else 1032 else
1130 { 1033 {
1131 std::string octaveroot; 1034 std::string octaveroot;
1132 std::string fpath; 1035 std::string fpath;
1316 octave_value 1219 octave_value
1317 make_fcn_handle (const std::string& nm) 1220 make_fcn_handle (const std::string& nm)
1318 { 1221 {
1319 octave_value retval; 1222 octave_value retval;
1320 1223
1321 octave_function *fcn = octave_call_stack::current (); 1224 octave_value f = symbol_table::find_function (nm);
1322 1225
1323 std::string parent_name = fcn ? fcn->name () : std::string (); 1226 if (f.is_defined ())
1324
1325 if (! parent_name.empty ())
1326 {
1327 size_t pos = parent_name.find (':');
1328
1329 if (pos != NPOS)
1330 parent_name = parent_name.substr (0, pos);
1331 }
1332
1333 octave_value f = lookup_function (nm, parent_name);
1334
1335 if (f.is_function ())
1336 retval = octave_value (new octave_fcn_handle (f, nm)); 1227 retval = octave_value (new octave_fcn_handle (f, nm));
1337 else 1228 else
1338 error ("error creating function handle \"@%s\"", nm.c_str ()); 1229 error ("error creating function handle \"@%s\"", nm.c_str ());
1339 1230
1340 return retval; 1231 return retval;
1394 if (fh_nm == "@<anonymous>") 1285 if (fh_nm == "@<anonymous>")
1395 { 1286 {
1396 m.assign ("file", ""); 1287 m.assign ("file", "");
1397 1288
1398 octave_user_function *fu = fh->user_function_value (); 1289 octave_user_function *fu = fh->user_function_value ();
1399 Array <symbol_record *> vars = 1290
1400 fu->sym_tab ()->symbol_list (); 1291 std::list<symbol_table::symbol_record> vars
1401 octave_idx_type varlen = vars.length (); 1292 = symbol_table::all_variables (fu->scope ());
1402 1293
1403 // Exclude undefined values like __retval__ 1294 size_t varlen = vars.size ();
1404 for (int i = 0; i < vars.length (); i++)
1405 {
1406 if (! vars (i)->is_defined ())
1407 varlen--;
1408 }
1409 1295
1410 if (varlen > 0) 1296 if (varlen > 0)
1411 { 1297 {
1412 Octave_map ws; 1298 Octave_map ws;
1413 for (octave_idx_type i = 0; i < vars.length (); i++) 1299 for (std::list<symbol_table::symbol_record>::const_iterator p = vars.begin ();
1300 p != vars.end (); p++)
1414 { 1301 {
1415 if (vars (i)->is_defined ()) 1302 ws.assign (p->name (), p->varval ());
1416 ws.assign (vars (i)->name (),
1417 vars (i)->def ());
1418 } 1303 }
1419 1304
1420 m.assign ("workspace", ws); 1305 m.assign ("workspace", ws);
1421 } 1306 }
1422 } 1307 }