Mercurial > octave-nkf
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 } |