Mercurial > octave-nkf
comparison libinterp/octave-value/ov-classdef.cc @ 15841:5861c4bde387 classdef
Move classdef related source files to correct location.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Sun, 23 Dec 2012 17:43:06 -0500 |
parents | src/octave-value/ov-classdef.cc@069c552587a0 |
children | 5e5705b3e505 |
comparison
equal
deleted
inserted
replaced
15840:af9e2ad52943 | 15841:5861c4bde387 |
---|---|
1 /* | |
2 | |
3 Copyright (C) 2012 Michael Goffioul | |
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 | |
9 Free Software Foundation; either version 3 of the License, or (at your | |
10 option) any later version. | |
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 | |
18 along with Octave; see the file COPYING. If not, see | |
19 <http://www.gnu.org/licenses/>. | |
20 | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <map> | |
28 | |
29 #include "defun.h" | |
30 #include "ov-builtin.h" | |
31 #include "ov-classdef.h" | |
32 #include "ov-fcn-handle.h" | |
33 #include "ov-typeinfo.h" | |
34 #include "pt-classdef.h" | |
35 | |
36 static std::map<std::string, cdef_class> all_classes; | |
37 static std::map<std::string, cdef_package> all_packages; | |
38 | |
39 static void | |
40 gripe_method_access (const std::string& from, const cdef_method& meth) | |
41 { | |
42 error ("%s: method `%s' has %s access and cannot be run in this context", | |
43 from.c_str (), meth.get_name ().c_str (), | |
44 meth.get_access ().c_str ()); | |
45 } | |
46 | |
47 static void | |
48 gripe_property_access (const std::string& from, const cdef_property& prop, | |
49 bool is_set = false) | |
50 { | |
51 if (is_set) | |
52 error ("%s: property `%s' has %s access and cannot be set in this context", | |
53 from.c_str (), prop.get_name ().c_str (), | |
54 prop.get_set_access ().c_str ()); | |
55 else | |
56 error ("%s: property `%s' has %s access and cannot be obtained in this context", | |
57 from.c_str (), prop.get_name ().c_str (), | |
58 prop.get_get_access ().c_str ()); | |
59 } | |
60 | |
61 static octave_value | |
62 make_fcn_handle (octave_builtin::fcn ff, const std::string& nm) | |
63 { | |
64 octave_value fcn (new octave_builtin (ff, nm)); | |
65 | |
66 octave_value fcn_handle (new octave_fcn_handle (fcn, nm)); | |
67 | |
68 return fcn_handle; | |
69 } | |
70 | |
71 inline octave_value_list | |
72 execute_ov (octave_value val, const octave_value_list& args, int nargout) | |
73 { | |
74 std::list<octave_value_list> idx (1, args); | |
75 | |
76 std::string type ("("); | |
77 | |
78 return val.subsref (type, idx, nargout); | |
79 } | |
80 | |
81 static bool | |
82 check_access (const std::string& req, const std::string& acc) | |
83 { | |
84 if (req == "private") | |
85 return true; | |
86 else if (req == "protected") | |
87 return (acc != "private"); | |
88 else | |
89 return (acc == "public"); | |
90 } | |
91 | |
92 static std::string | |
93 get_base_name (const std::string& nm) | |
94 { | |
95 std::string::size_type pos = nm.find_last_of ('.'); | |
96 | |
97 if (pos != std::string::npos) | |
98 return nm.substr (pos + 1); | |
99 | |
100 return nm; | |
101 } | |
102 | |
103 static std::string | |
104 superclass_access (const std::string& acc) | |
105 { | |
106 if (acc == "public") | |
107 return acc; | |
108 else | |
109 return "protected"; | |
110 } | |
111 | |
112 static cdef_class | |
113 lookup_class (const std::string& name, bool error_if_not_found = true) | |
114 { | |
115 std::map<std::string, cdef_class>::iterator it = all_classes.find (name); | |
116 | |
117 if (it == all_classes.end ()) | |
118 { | |
119 // FIXME: should look into load-path | |
120 if (error_if_not_found) | |
121 error ("class not found: %s", name.c_str ()); | |
122 } | |
123 else | |
124 { | |
125 cdef_class& cls = it->second; | |
126 | |
127 if (! cls.is_builtin ()) | |
128 { | |
129 // FIXME: check whether a class reload is needed | |
130 } | |
131 | |
132 if (cls.ok ()) | |
133 return cls; | |
134 else | |
135 all_classes.erase (it); | |
136 } | |
137 | |
138 return cdef_class (); | |
139 } | |
140 | |
141 static Cell | |
142 lookup_classes (const Cell& cls_names) | |
143 { | |
144 Cell cls (cls_names.numel (), 1); | |
145 | |
146 for (int i = 0; i < cls_names.numel (); i++) | |
147 { | |
148 cdef_class c = lookup_class (cls_names(i).string_value ()); | |
149 | |
150 if (! error_state) | |
151 cls(i) = to_ov (c); | |
152 else | |
153 return Cell (); | |
154 } | |
155 | |
156 return cls; | |
157 } | |
158 | |
159 static bool | |
160 is_superclass (const cdef_class& clsa, const cdef_class& clsb, | |
161 bool allow_equal = true) | |
162 { | |
163 if (allow_equal && clsa == clsb) | |
164 return true; | |
165 else | |
166 { | |
167 Cell c = clsb.get ("SuperClasses").cell_value (); | |
168 | |
169 bool retval = false; | |
170 | |
171 for (int i = 0; ! retval && i < c.numel (); i++) | |
172 { | |
173 cdef_class cls = lookup_class (c(i).string_value ()); | |
174 | |
175 if (! error_state) | |
176 retval = is_superclass (clsa, cls, true); | |
177 } | |
178 | |
179 return retval; | |
180 } | |
181 } | |
182 | |
183 inline bool | |
184 is_strict_superclass (const cdef_class& clsa, const cdef_class& clsb) | |
185 { return is_superclass (clsa, clsb, false); } | |
186 | |
187 static octave_value_list | |
188 class_get_properties (const octave_value_list& args, int /* nargout */) | |
189 { | |
190 octave_value_list retval; | |
191 | |
192 if (args.length () == 1 && args(0).type_name () == "object") | |
193 { | |
194 cdef_class cls (to_cdef (args(0))); | |
195 | |
196 retval(0) = cls.get_properties (); | |
197 } | |
198 | |
199 return retval; | |
200 } | |
201 | |
202 static octave_value_list | |
203 class_get_methods (const octave_value_list& args, int /* nargout */) | |
204 { | |
205 octave_value_list retval; | |
206 | |
207 if (args.length () == 1 && args(0).type_name () == "object") | |
208 { | |
209 cdef_class cls (to_cdef (args(0))); | |
210 | |
211 retval(0) = cls.get_methods (); | |
212 } | |
213 | |
214 return retval; | |
215 } | |
216 | |
217 static octave_value_list | |
218 class_get_superclasses (const octave_value_list& args, int /* nargout */) | |
219 { | |
220 octave_value_list retval; | |
221 | |
222 if (args.length () == 1 && args(0).type_name () == "object" | |
223 && args(0).class_name () == "meta.class") | |
224 { | |
225 cdef_class cls (to_cdef (args(0))); | |
226 | |
227 Cell classes = cls.get ("SuperClasses").cell_value (); | |
228 | |
229 retval(0) = lookup_classes (classes); | |
230 } | |
231 | |
232 return retval; | |
233 } | |
234 | |
235 static octave_value_list | |
236 class_get_inferiorclasses (const octave_value_list& args, int /* nargout */) | |
237 { | |
238 octave_value_list retval; | |
239 | |
240 if (args.length () == 1 && args(0).type_name () == "object" | |
241 && args(0).class_name () == "meta.class") | |
242 { | |
243 cdef_class cls (to_cdef (args(0))); | |
244 | |
245 Cell classes = cls.get ("InferiorClasses").cell_value (); | |
246 | |
247 retval(0) = lookup_classes (classes); | |
248 } | |
249 | |
250 return retval; | |
251 } | |
252 | |
253 static octave_value_list | |
254 class_fromName (const octave_value_list& args, int /* nargout */) | |
255 { | |
256 octave_value_list retval; | |
257 | |
258 if (args.length () == 1) | |
259 { | |
260 std::string name = args(0).string_value (); | |
261 | |
262 if (! error_state) | |
263 retval(0) = to_ov (lookup_class (name)); | |
264 else | |
265 error ("fromName: invalid class name, expected a string value"); | |
266 } | |
267 else | |
268 error ("fromName: invalid number of parameters"); | |
269 | |
270 return retval; | |
271 } | |
272 | |
273 static octave_value_list | |
274 class_fevalStatic (const octave_value_list& args, int nargout) | |
275 { | |
276 octave_value_list retval; | |
277 | |
278 if (args.length () > 1 && args(0).type_name () == "object") | |
279 { | |
280 cdef_class cls (to_cdef (args(0))); | |
281 | |
282 if (! error_state) | |
283 { | |
284 std::string meth_name = args(1).string_value (); | |
285 | |
286 if (! error_state) | |
287 { | |
288 cdef_method meth = cls.find_method (meth_name); | |
289 | |
290 if (meth.ok ()) | |
291 { | |
292 // FIXME: can the context be something else? | |
293 if (meth.check_access ("public")) | |
294 { | |
295 if (meth.is_static ()) | |
296 retval = meth.execute (args.splice (0, 2), nargout); | |
297 else | |
298 error ("fevalStatic: method `%s' is not static", | |
299 meth_name.c_str ()); | |
300 } | |
301 else | |
302 gripe_method_access ("fevalStatic", meth); | |
303 } | |
304 else | |
305 error ("fevalStatic: method not found: %s", | |
306 meth_name.c_str ()); | |
307 } | |
308 else | |
309 error ("fevalStatic: invalid method name, expected a string value"); | |
310 } | |
311 error ("fevalStatic: invalid object, expected a meta.class object"); | |
312 } | |
313 else | |
314 error ("fevalStatic: invalid arguments"); | |
315 | |
316 return retval; | |
317 } | |
318 | |
319 static octave_value_list | |
320 class_getConstant (const octave_value_list& args, int /* nargout */) | |
321 { | |
322 octave_value_list retval; | |
323 | |
324 if (args.length () == 2 && args(0).type_name () == "object" | |
325 && args(0).class_name () == "meta.class") | |
326 { | |
327 cdef_class cls = to_cdef (args(0)); | |
328 | |
329 if (! error_state) | |
330 { | |
331 std::string prop_name = args(1).string_value (); | |
332 | |
333 if (! error_state) | |
334 { | |
335 cdef_property prop = cls.find_property (prop_name); | |
336 | |
337 if (prop.ok ()) | |
338 { | |
339 // FIXME: can the context be something else? | |
340 if (prop.check_get_access ("public")) | |
341 { | |
342 if (prop.is_constant ()) | |
343 retval(0) = prop.get_value (); | |
344 else | |
345 error ("getConstant: property `%s' is not constant", | |
346 prop_name.c_str ()); | |
347 } | |
348 else | |
349 gripe_property_access ("getConstant", prop); | |
350 } | |
351 else | |
352 error ("getConstant: property not found: %s", | |
353 prop_name.c_str ()); | |
354 } | |
355 else | |
356 error ("getConstant: invalid property name, expected a string value"); | |
357 } | |
358 else | |
359 error ("getConstant: invalid object, expected a meta.class object"); | |
360 } | |
361 else | |
362 error ("getConstant: invalid arguments"); | |
363 | |
364 return retval; | |
365 } | |
366 | |
367 #define META_CLASS_CMP(OP, CLSA, CLSB, FUN) \ | |
368 static octave_value_list \ | |
369 class_ ## OP (const octave_value_list& args, int /* nargout */) \ | |
370 { \ | |
371 octave_value_list retval; \ | |
372 \ | |
373 if (args.length () == 2 \ | |
374 && args(0).type_name () == "object" && args(1).type_name () == "object" \ | |
375 && args(0).class_name () == "meta.class" && args(1).class_name () == "meta.class") \ | |
376 { \ | |
377 cdef_class clsa = to_cdef (args(0)); \ | |
378 \ | |
379 cdef_class clsb = to_cdef (args(1)); \ | |
380 \ | |
381 if (! error_state) \ | |
382 retval(0) = FUN (CLSA, CLSB); \ | |
383 else \ | |
384 error (#OP ": invalid objects, expected meta.class objects"); \ | |
385 } \ | |
386 else \ | |
387 error (#OP ": invalid arguments"); \ | |
388 \ | |
389 return retval; \ | |
390 } | |
391 | |
392 META_CLASS_CMP (lt, clsb, clsa, is_strict_superclass) | |
393 META_CLASS_CMP (le, clsb, clsa, is_superclass) | |
394 META_CLASS_CMP (gt, clsa, clsb, is_strict_superclass) | |
395 META_CLASS_CMP (ge, clsa, clsb, is_superclass) | |
396 META_CLASS_CMP (eq, clsa, clsb, operator==) | |
397 META_CLASS_CMP (ne, clsa, clsb, operator!=) | |
398 | |
399 static octave_value_list | |
400 handle_delete (const octave_value_list& /* args */, int /* nargout */) | |
401 { | |
402 octave_value_list retval; | |
403 | |
404 // FIXME: implement this | |
405 | |
406 return retval; | |
407 } | |
408 | |
409 static cdef_class | |
410 make_class (const std::string& name, const std::string& super = std::string()) | |
411 { | |
412 cdef_class cls ("meta.class"); | |
413 | |
414 all_classes[name] = cls; | |
415 cls.put ("ConstructOnLoad", false); | |
416 cls.put ("ContainingPackage", Matrix ()); | |
417 cls.put ("Description", std::string ()); | |
418 cls.put ("DetailedDescription", std::string ()); | |
419 cls.put ("Events", Cell ()); | |
420 cls.put ("Hidden", false); | |
421 cls.put ("InferiorClasses", Cell ()); | |
422 cls.put ("Methods", Cell ()); | |
423 cls.put ("Name", name); | |
424 cls.put ("Properties", Cell ()); | |
425 cls.put ("Sealed", true); | |
426 if (super.empty ()) | |
427 cls.put ("SuperClasses", Cell ()); | |
428 else | |
429 cls.put ("SuperClasses", Cell (octave_value (super))); | |
430 | |
431 return cls; | |
432 } | |
433 | |
434 static cdef_property | |
435 make_property (const cdef_object& cls, const std::string& name, | |
436 const octave_value& get_method = Matrix (), | |
437 const std::string& get_access = "public", | |
438 const octave_value& set_method = Matrix (), | |
439 const std::string& set_access = "public") | |
440 { | |
441 // FIXME: what about default value? | |
442 | |
443 cdef_property prop ("meta.property"); | |
444 | |
445 prop.put ("Name", name); | |
446 prop.put ("Description", std::string ()); | |
447 prop.put ("DetailedDescription", std::string ()); | |
448 prop.put ("Abstract", false); | |
449 prop.put ("Constant", false); | |
450 prop.put ("GetAccess", get_access); | |
451 prop.put ("SetAccess", set_access); | |
452 prop.put ("Dependent", false); | |
453 prop.put ("Transient", false); | |
454 prop.put ("Hidden", false); | |
455 prop.put ("GetObservable", false); | |
456 prop.put ("SetObservable", false); | |
457 prop.put ("GetMethod", get_method); | |
458 prop.put ("SetMethod", set_method); | |
459 prop.put ("DefiningClass", to_ov (cls)); | |
460 | |
461 return prop; | |
462 } | |
463 | |
464 inline cdef_property | |
465 make_attribute (const cdef_object& cls, const std::string& name) | |
466 { | |
467 return make_property (cls, name, Matrix (), "public", Matrix (), "private"); | |
468 } | |
469 | |
470 static cdef_method | |
471 make_method (const cdef_object& cls, const std::string& name, const octave_value& fcn, | |
472 const std::string& m_access = "public", bool is_static = false) | |
473 { | |
474 cdef_method meth ("meta.method"); | |
475 | |
476 meth.put ("Abstract", false); | |
477 meth.put ("Access", m_access); | |
478 meth.put ("DefiningClass", to_ov (cls)); | |
479 meth.put ("Description", std::string ()); | |
480 meth.put ("DetailedDescription", std::string ()); | |
481 meth.put ("Hidden", false); | |
482 meth.put ("Name", name); | |
483 meth.put ("Sealed", true); | |
484 meth.put ("Static", is_static); | |
485 | |
486 meth.set_function (fcn); | |
487 | |
488 return meth; | |
489 } | |
490 | |
491 inline cdef_method | |
492 make_method (const cdef_object& cls, const std::string& name, octave_builtin::fcn ff, | |
493 const std::string& m_access = "public", bool is_static = false) | |
494 { | |
495 octave_value fcn (new octave_builtin (ff, name)); | |
496 | |
497 octave_value fcn_handle (new octave_fcn_handle (fcn, name)); | |
498 | |
499 return make_method (cls, name, fcn_handle, m_access, is_static); | |
500 } | |
501 | |
502 static cdef_package | |
503 make_package (const std::string& nm, | |
504 const std::string& parent = std::string ()) | |
505 { | |
506 cdef_package pack ("meta.package"); | |
507 | |
508 all_packages[nm] = pack; | |
509 pack.put ("Name", nm); | |
510 pack.put ("ContainingPackage", to_ov (all_packages[parent])); | |
511 | |
512 return pack; | |
513 } | |
514 | |
515 DEFINE_OCTAVE_ALLOCATOR (octave_classdef); | |
516 | |
517 int octave_classdef::t_id (-1); | |
518 | |
519 const std::string octave_classdef::t_name ("object"); | |
520 | |
521 void | |
522 octave_classdef::register_type (void) | |
523 { | |
524 t_id = octave_value_typeinfo::register_type | |
525 (octave_classdef::t_name, "<unknown>", octave_value (new octave_classdef ())); | |
526 } | |
527 | |
528 cdef_class | |
529 cdef_object_rep::get_class (void) const | |
530 { | |
531 cdef_class cls = lookup_class (class_name ()); | |
532 | |
533 return cls; | |
534 } | |
535 | |
536 string_vector | |
537 cdef_object_rep::map_keys (void) const | |
538 { | |
539 cdef_class cls = get_class (); | |
540 | |
541 if (cls.ok ()) | |
542 return cls.get_names (); | |
543 | |
544 return string_vector (); | |
545 } | |
546 | |
547 octave_value_list | |
548 handle_cdef_object::subsref (const std::string& type, | |
549 const std::list<octave_value_list>& idx, | |
550 int nargout, int& skip) | |
551 { | |
552 skip = 0; | |
553 | |
554 cdef_class cls = get_class (); | |
555 | |
556 octave_value_list retval; | |
557 | |
558 if (! cls.ok ()) | |
559 return retval; | |
560 | |
561 switch (type[0]) | |
562 { | |
563 case '.': | |
564 { | |
565 std::string name = (idx.front ())(0).string_value (); | |
566 | |
567 // FIXME: get the right context; context should also | |
568 // be linked to the current executing class (if any) | |
569 // such that protected/private methods found in inherited | |
570 // classes are correctly resolved. | |
571 std::string context = "public"; | |
572 | |
573 cdef_method meth = cls.find_method (name); | |
574 | |
575 if (meth.ok ()) | |
576 { | |
577 if (meth.check_access (context)) | |
578 { | |
579 int _nargout = (type.length () > 2 ? 1 : nargout); | |
580 | |
581 octave_value_list args; | |
582 | |
583 skip = 1; | |
584 | |
585 if (type.length () > 1 && type[1] == '(') | |
586 { | |
587 std::list<octave_value_list>::const_iterator it = idx.begin (); | |
588 | |
589 args = *++it; | |
590 | |
591 skip++; | |
592 } | |
593 | |
594 if (meth.is_static ()) | |
595 retval = meth.execute (args, _nargout); | |
596 else | |
597 { | |
598 refcount++; | |
599 retval = meth.execute (cdef_object (this), args, _nargout); | |
600 } | |
601 } | |
602 else | |
603 gripe_method_access ("subsref", meth); | |
604 } | |
605 | |
606 if (skip == 0 && ! error_state) | |
607 { | |
608 cdef_property prop = cls.find_property (name); | |
609 | |
610 if (prop.ok ()) | |
611 { | |
612 if (prop.check_get_access (context)) | |
613 { | |
614 refcount++; | |
615 retval(0) = prop.get_value (cdef_object (this)); | |
616 | |
617 skip = 1; | |
618 } | |
619 else | |
620 gripe_property_access ("subsref", prop); | |
621 } | |
622 else | |
623 error ("subsref: unknown method or property: %s", name.c_str ()); | |
624 } | |
625 break; | |
626 } | |
627 default: | |
628 error ("object cannot be indexed with `%c'", type[0]); | |
629 break; | |
630 } | |
631 | |
632 return retval; | |
633 } | |
634 | |
635 cdef_method | |
636 cdef_class::cdef_class_rep::find_method (const std::string& nm) | |
637 { | |
638 method_iterator it = method_map.find (nm); | |
639 | |
640 if (it == method_map.end ()) | |
641 { | |
642 // FIXME: look into class directory | |
643 } | |
644 else | |
645 { | |
646 cdef_method& meth = it->second; | |
647 | |
648 // FIXME: check if method reload needed | |
649 | |
650 if (meth.ok ()) | |
651 return meth; | |
652 } | |
653 | |
654 // Look into superclasses | |
655 | |
656 Cell super_classes = get ("SuperClasses").cell_value (); | |
657 | |
658 for (int i = 0; i < super_classes.numel (); i++) | |
659 { | |
660 cdef_class cls = lookup_class (super_classes(i).string_value ()); | |
661 | |
662 if (! error_state) | |
663 { | |
664 cdef_method meth = cls.find_method (nm); | |
665 | |
666 if (meth.ok ()) | |
667 return meth; | |
668 } | |
669 } | |
670 | |
671 return cdef_method (); | |
672 } | |
673 | |
674 void | |
675 cdef_class::cdef_class_rep::install_method (const cdef_method& meth) | |
676 { | |
677 method_map[meth.get_name ()] = meth; | |
678 } | |
679 | |
680 void | |
681 cdef_class::cdef_class_rep::load_all_methods (void) | |
682 { | |
683 // FIXME: re-scan class directory | |
684 } | |
685 | |
686 Cell | |
687 cdef_class::cdef_class_rep::get_methods (void) | |
688 { | |
689 std::map<std::string,cdef_method> meths; | |
690 | |
691 std::map<std::string,int> count; | |
692 | |
693 count["public"] = count["protected"] = count["private"] = 0; | |
694 | |
695 find_methods (meths, count); | |
696 | |
697 if (! error_state) | |
698 { | |
699 Cell c (count["public"] + count["protected"], 1); | |
700 | |
701 int idx = 0; | |
702 | |
703 for (std::map<std::string,cdef_method>::const_iterator it = meths.begin (); | |
704 it != meths.end (); ++it) | |
705 if (::check_access ("protected", it->second.get_access ())) | |
706 c (idx++, 0) = to_ov (it->second); | |
707 | |
708 return c; | |
709 } | |
710 | |
711 return Cell (); | |
712 } | |
713 | |
714 void | |
715 cdef_class::cdef_class_rep::find_methods (std::map<std::string,cdef_method>& meths, | |
716 std::map<std::string,int>& count) | |
717 { | |
718 load_all_methods (); | |
719 | |
720 method_const_iterator it; | |
721 | |
722 for (it = method_map.begin (); it != method_map.end (); ++it) | |
723 { | |
724 std::string nm = it->second.get_name (); | |
725 | |
726 if (meths.find (nm) == meths.end ()) | |
727 { | |
728 std::string acc = it->second.get_access (); | |
729 | |
730 meths[nm] = it->second; | |
731 count[acc]++; | |
732 } | |
733 } | |
734 | |
735 // Look into superclasses | |
736 | |
737 Cell super_classes = get ("SuperClasses").cell_value (); | |
738 | |
739 for (int i = 0; i < super_classes.numel (); i++) | |
740 { | |
741 cdef_class cls = lookup_class (super_classes(i).string_value ()); | |
742 | |
743 if (! error_state) | |
744 cls.get_rep ()->find_methods (meths, count); | |
745 else | |
746 break; | |
747 } | |
748 } | |
749 | |
750 cdef_property | |
751 cdef_class::cdef_class_rep::find_property (const std::string& nm) | |
752 { | |
753 property_iterator it = property_map.find (nm); | |
754 | |
755 if (it != property_map.end ()) | |
756 { | |
757 cdef_property& prop = it->second; | |
758 | |
759 if (prop.ok ()) | |
760 return prop; | |
761 } | |
762 | |
763 // Look into superclasses | |
764 | |
765 Cell super_classes = get ("SuperClasses").cell_value (); | |
766 | |
767 for (int i = 0; i < super_classes.numel (); i++) | |
768 { | |
769 cdef_class cls = lookup_class (super_classes(i).string_value ()); | |
770 | |
771 if (! error_state) | |
772 { | |
773 cdef_property prop = cls.find_property (nm); | |
774 | |
775 if (prop.ok ()) | |
776 return prop; | |
777 } | |
778 } | |
779 | |
780 return cdef_property (); | |
781 } | |
782 | |
783 void | |
784 cdef_class::cdef_class_rep::install_property (const cdef_property& prop) | |
785 { | |
786 property_map[prop.get_name ()] = prop; | |
787 } | |
788 | |
789 Cell | |
790 cdef_class::cdef_class_rep::get_properties (void) | |
791 { | |
792 std::map<std::string,cdef_property> props; | |
793 | |
794 std::map<std::string,int> count; | |
795 | |
796 count["public"] = count["protected"] = count["private"] = 0; | |
797 | |
798 find_properties (props, count); | |
799 | |
800 if (! error_state) | |
801 { | |
802 Cell c (count["public"] + count["protected"], 1); | |
803 | |
804 int idx = 0; | |
805 | |
806 for (std::map<std::string,cdef_property>::const_iterator it = props.begin (); | |
807 it != props.end (); ++it) | |
808 if (::check_access ("protected", it->second.get_get_access ())) | |
809 c (idx++, 0) = to_ov (it->second); | |
810 | |
811 return c; | |
812 } | |
813 | |
814 return Cell (); | |
815 } | |
816 | |
817 void | |
818 cdef_class::cdef_class_rep::find_properties (std::map<std::string,cdef_property>& props, | |
819 std::map<std::string,int>& count) | |
820 { | |
821 property_const_iterator it; | |
822 | |
823 for (it = property_map.begin (); it != property_map.end (); ++it) | |
824 { | |
825 std::string nm = it->second.get_name (); | |
826 | |
827 if (props.find (nm) == props.end ()) | |
828 { | |
829 std::string acc = it->second.get_get_access (); | |
830 | |
831 props[nm] = it->second; | |
832 count[acc]++; | |
833 } | |
834 } | |
835 | |
836 // Look into superclasses | |
837 | |
838 Cell super_classes = get ("SuperClasses").cell_value (); | |
839 | |
840 for (int i = 0; i < super_classes.numel (); i++) | |
841 { | |
842 cdef_class cls = lookup_class (super_classes(i).string_value ()); | |
843 | |
844 if (! error_state) | |
845 cls.get_rep ()->find_properties (props, count); | |
846 else | |
847 break; | |
848 } | |
849 } | |
850 | |
851 void | |
852 cdef_class::cdef_class_rep::find_names (std::map<std::string,std::string>& names, | |
853 std::map<std::string,int>& count) | |
854 { | |
855 load_all_methods (); | |
856 | |
857 for (method_const_iterator it = method_map.begin (); | |
858 it != method_map.end(); ++it) | |
859 { | |
860 std::string nm = it->second.get_name (); | |
861 | |
862 if (names.find (nm) == names.end ()) | |
863 { | |
864 std::string acc = it->second.get_access (); | |
865 | |
866 names[nm] = acc; | |
867 count[acc]++; | |
868 } | |
869 } | |
870 | |
871 for (property_const_iterator it = property_map.begin (); | |
872 it != property_map.end (); ++it) | |
873 { | |
874 std::string nm = it->second.get_name (); | |
875 | |
876 if (names.find (nm) == names.end ()) | |
877 { | |
878 std::string acc = it->second.get_get_access (); | |
879 | |
880 names[nm] = acc; | |
881 count[acc]++; | |
882 } | |
883 } | |
884 | |
885 // Look into superclasses | |
886 | |
887 Cell super_classes = get ("SuperClasses").cell_value (); | |
888 | |
889 for (int i = 0; i < super_classes.numel (); i++) | |
890 { | |
891 cdef_class cls = lookup_class (super_classes(i).string_value ()); | |
892 | |
893 if (! error_state) | |
894 cls.get_rep ()->find_names (names, count); | |
895 else | |
896 break; | |
897 } | |
898 } | |
899 | |
900 string_vector | |
901 cdef_class::cdef_class_rep::get_names (void) | |
902 { | |
903 std::map<std::string,std::string> names; | |
904 | |
905 std::map<std::string,int> count; | |
906 | |
907 count["public"] = count["protected"] = count["private"] = 0; | |
908 | |
909 find_names (names, count); | |
910 | |
911 if (! error_state) | |
912 { | |
913 string_vector v (count["public"]); | |
914 | |
915 int idx = 0; | |
916 for (std::map<std::string,std::string>::const_iterator it = names.begin (); | |
917 it != names.end (); ++it) | |
918 { | |
919 if (it->second == "public") | |
920 v[idx++] = it->first; | |
921 } | |
922 | |
923 return v.sort (true); | |
924 } | |
925 | |
926 return string_vector (); | |
927 } | |
928 | |
929 void | |
930 cdef_class::cdef_class_rep::delete_object (cdef_object obj) | |
931 { | |
932 method_iterator it = method_map.find ("delete"); | |
933 | |
934 if (it != method_map.end ()) | |
935 { | |
936 std::string cls_name = obj.class_name (); | |
937 | |
938 obj.set_class_name (get ("Name").string_value ()); | |
939 | |
940 it->second.execute (obj, octave_value_list (), 0); | |
941 | |
942 obj.set_class_name (cls_name); | |
943 } | |
944 | |
945 // FIXME: should we destroy corresponding properties here? | |
946 | |
947 // Call "delete" in super classes | |
948 | |
949 Cell super_classes = get ("SuperClasses").cell_value (); | |
950 | |
951 for (int i = 0; i < super_classes.numel (); i++) | |
952 { | |
953 cdef_class cls = lookup_class (super_classes(i).string_value ()); | |
954 | |
955 if (!error_state) | |
956 cls.delete_object (obj); | |
957 } | |
958 } | |
959 | |
960 cdef_class | |
961 cdef_class::make_meta_class (const tree_classdef* t) | |
962 { | |
963 cdef_class retval; | |
964 | |
965 return retval; | |
966 } | |
967 | |
968 octave_value | |
969 cdef_property::cdef_property_rep::get_value (const cdef_object& obj) | |
970 { | |
971 // FIXME: should check whether we're already in get accessor method | |
972 | |
973 octave_value retval; | |
974 | |
975 octave_value get_fcn = get ("GetMethod"); | |
976 | |
977 std::string get_access = get ("GetAccess").string_value (); | |
978 | |
979 if (get_access != "public") | |
980 { | |
981 // FIXME: should check the current call stack | |
982 } | |
983 | |
984 if (get_fcn.is_empty ()) | |
985 retval = obj.get (get ("Name").string_value ()); | |
986 else | |
987 { | |
988 octave_value_list args; | |
989 | |
990 args(0) = to_ov (obj); | |
991 | |
992 args = execute_ov (get_fcn, args, 1); | |
993 | |
994 if (! error_state) | |
995 retval = args(0); | |
996 } | |
997 | |
998 return retval; | |
999 } | |
1000 | |
1001 bool | |
1002 cdef_property::check_get_access (const std::string& req) const | |
1003 { | |
1004 return ::check_access (req, get_get_access ()); | |
1005 } | |
1006 | |
1007 bool | |
1008 cdef_property::check_set_access (const std::string& req) const | |
1009 { | |
1010 return ::check_access (req, get_set_access ()); | |
1011 } | |
1012 | |
1013 void | |
1014 cdef_method::cdef_method_rep::check_method (void) | |
1015 { | |
1016 // FIXME: check whether re-load is needed | |
1017 } | |
1018 | |
1019 octave_value_list | |
1020 cdef_method::cdef_method_rep::execute (const octave_value_list& args, | |
1021 int nargout) | |
1022 { | |
1023 octave_value_list retval; | |
1024 | |
1025 if (! get ("Abstract").bool_value ()) | |
1026 { | |
1027 check_method (); | |
1028 | |
1029 if (function.is_defined ()) | |
1030 { | |
1031 retval = execute_ov (function, args, nargout); | |
1032 } | |
1033 } | |
1034 else | |
1035 error ("%s: cannot execute abstract method", | |
1036 get ("Name").string_value ().c_str ()); | |
1037 | |
1038 return retval; | |
1039 } | |
1040 | |
1041 octave_value_list | |
1042 cdef_method::cdef_method_rep::execute (const cdef_object& obj, | |
1043 const octave_value_list& args, | |
1044 int nargout) | |
1045 { | |
1046 octave_value_list retval; | |
1047 | |
1048 if (! get ("Abstract").bool_value ()) | |
1049 { | |
1050 check_method (); | |
1051 | |
1052 octave_value_list new_args; | |
1053 | |
1054 if (function.is_defined ()) | |
1055 { | |
1056 new_args.resize (args.length () + 1); | |
1057 | |
1058 new_args(0) = to_ov (obj); | |
1059 for (int i = 0; i < args.length (); i++) | |
1060 new_args(i+1) = args(i); | |
1061 | |
1062 retval = execute_ov (function, new_args, nargout); | |
1063 } | |
1064 } | |
1065 else | |
1066 error ("%s: cannot execute abstract method", | |
1067 get ("Name").string_value ().c_str ()); | |
1068 | |
1069 return retval; | |
1070 } | |
1071 | |
1072 bool | |
1073 cdef_method::check_access (const std::string& req) const | |
1074 { | |
1075 return ::check_access (req, get_access ()); | |
1076 } | |
1077 | |
1078 static cdef_package | |
1079 lookup_package (const std::string& name) | |
1080 { | |
1081 std::map<std::string, cdef_package>::const_iterator it = all_packages.find (name); | |
1082 | |
1083 if (it != all_packages.end ()) | |
1084 { | |
1085 cdef_package pack = it->second; | |
1086 | |
1087 if (pack.ok ()) | |
1088 return pack; | |
1089 else | |
1090 error ("invalid package: %s", name.c_str ()); | |
1091 } | |
1092 else | |
1093 error ("package not found: %s", name.c_str ()); | |
1094 | |
1095 return cdef_package (); | |
1096 } | |
1097 | |
1098 static octave_value_list | |
1099 package_fromName (const octave_value_list& args, int /* nargout */) | |
1100 { | |
1101 octave_value_list retval; | |
1102 | |
1103 if (args.length () == 1) | |
1104 { | |
1105 std::string name = args(0).string_value (); | |
1106 | |
1107 if (! error_state) | |
1108 retval(0) = to_ov (lookup_package (name)); | |
1109 else | |
1110 error ("fromName: invalid package name, expected a string value"); | |
1111 } | |
1112 else | |
1113 error ("fromName: invalid number of parameters"); | |
1114 | |
1115 return retval; | |
1116 } | |
1117 | |
1118 static octave_value_list | |
1119 package_get_classes (const octave_value_list& args, int /* nargout */) | |
1120 { | |
1121 octave_value_list retval (1, Matrix ()); | |
1122 | |
1123 if (args.length () == 1 && args(0).type_name () == "object" | |
1124 && args(0).class_name () == "meta.package") | |
1125 { | |
1126 cdef_package pack (to_cdef (args(0))); | |
1127 | |
1128 retval(0) = pack.get_classes (); | |
1129 } | |
1130 | |
1131 return retval; | |
1132 } | |
1133 | |
1134 static octave_value_list | |
1135 package_get_functions (const octave_value_list& args, int /* nargout */) | |
1136 { | |
1137 octave_value_list retval (1, Matrix ()); | |
1138 | |
1139 if (args.length () == 0 && args(0).type_name () == "object" | |
1140 && args(0).class_name () == "meta.package") | |
1141 { | |
1142 cdef_package pack (to_cdef (args(0))); | |
1143 | |
1144 retval(0) = pack.get_functions (); | |
1145 } | |
1146 | |
1147 return retval; | |
1148 } | |
1149 | |
1150 static octave_value_list | |
1151 package_get_packages (const octave_value_list& args, int /* nargout */) | |
1152 { | |
1153 octave_value_list retval (1, Matrix ()); | |
1154 | |
1155 if (args.length () == 0 && args(0).type_name () == "object" | |
1156 && args(0).class_name () == "meta.package") | |
1157 { | |
1158 cdef_package pack (to_cdef (args(0))); | |
1159 | |
1160 retval(0) = pack.get_packages (); | |
1161 } | |
1162 | |
1163 return retval; | |
1164 } | |
1165 | |
1166 void | |
1167 cdef_package::cdef_package_rep::install_class (const cdef_class& cls, | |
1168 const std::string& nm) | |
1169 { | |
1170 class_map[nm] = cls; | |
1171 } | |
1172 | |
1173 void | |
1174 cdef_package::cdef_package_rep::install_function (const octave_value& fcn, | |
1175 const std::string& nm) | |
1176 { | |
1177 function_map[nm] = fcn; | |
1178 } | |
1179 | |
1180 void | |
1181 cdef_package::cdef_package_rep::install_package (const cdef_package& pack, | |
1182 const std::string& nm) | |
1183 { | |
1184 package_map[nm] = pack; | |
1185 } | |
1186 | |
1187 octave_value_list | |
1188 cdef_package::cdef_package_rep::subsref (const std::string& type, | |
1189 const std::list<octave_value_list>& idx, | |
1190 int nargout, int& skip) | |
1191 { | |
1192 return handle_cdef_object::subsref (type, idx, nargout, skip); | |
1193 } | |
1194 | |
1195 template<class T1, class T2> | |
1196 Cell | |
1197 map2Cell (const std::map<T1, T2>& m) | |
1198 { | |
1199 Cell retval (1, m.size ()); | |
1200 int i = 0; | |
1201 | |
1202 for (typename std::map<T1, T2>::const_iterator it = m.begin (); | |
1203 it != m.end (); ++it, ++i) | |
1204 { | |
1205 retval(i) = to_ov (it->second); | |
1206 } | |
1207 | |
1208 return retval; | |
1209 } | |
1210 | |
1211 Cell | |
1212 cdef_package::cdef_package_rep::get_classes (void) const | |
1213 { return map2Cell (class_map); } | |
1214 | |
1215 Cell | |
1216 cdef_package::cdef_package_rep::get_functions (void) const | |
1217 { return map2Cell (function_map); } | |
1218 | |
1219 Cell | |
1220 cdef_package::cdef_package_rep::get_packages (void) const | |
1221 { return map2Cell (package_map); } | |
1222 | |
1223 octave_value_list | |
1224 octave_classdef::subsref (const std::string& type, | |
1225 const std::list<octave_value_list>& idx, | |
1226 int nargout) | |
1227 { | |
1228 int skip = 0; | |
1229 octave_value_list retval; | |
1230 | |
1231 // FIXME: should check "subsref" method first | |
1232 | |
1233 retval = object.subsref (type, idx, nargout, skip); | |
1234 | |
1235 if (! error_state) | |
1236 { | |
1237 if (type.length () > skip && idx.size () > skip) | |
1238 retval = retval(0).next_subsref (nargout, type, idx, skip); | |
1239 } | |
1240 | |
1241 return retval; | |
1242 } | |
1243 | |
1244 void | |
1245 install_classdef (void) | |
1246 { | |
1247 octave_classdef::register_type (); | |
1248 | |
1249 /* meta classes */ | |
1250 cdef_class handle = make_class ("handle"); | |
1251 cdef_class meta_class = make_class ("meta.class", "handle"); | |
1252 cdef_class meta_property = make_class ("meta.property", "handle"); | |
1253 cdef_class meta_method = make_class ("meta.method", "handle"); | |
1254 cdef_class meta_event = make_class ("meta.event", "handle"); | |
1255 cdef_class meta_package = make_class ("meta.package", "handle"); | |
1256 cdef_class meta_dynproperty = make_class ("meta.dynamicproperty", "handle"); | |
1257 | |
1258 /* meta.class properties */ | |
1259 meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad")); | |
1260 meta_class.install_property (make_property (meta_class, "ContainingPackage")); | |
1261 meta_class.install_property (make_property (meta_class, "Description")); | |
1262 meta_class.install_property (make_property (meta_class, "DetailedDescription")); | |
1263 meta_class.install_property (make_property (meta_class, "Events")); | |
1264 meta_class.install_property (make_attribute (meta_class, "Hidden")); | |
1265 meta_class.install_property | |
1266 (make_property (meta_class, "InferiorClasses", | |
1267 make_fcn_handle (class_get_inferiorclasses, "meta.class>get.InferiorClasses"), | |
1268 "public", Matrix (), "private")); | |
1269 meta_class.install_property | |
1270 (make_property (meta_class, "Methods", | |
1271 make_fcn_handle (class_get_methods, "meta.class>get.Methods"), | |
1272 "public", Matrix (), "private")); | |
1273 meta_class.install_property | |
1274 (make_property (meta_class, "MethodList", | |
1275 make_fcn_handle (class_get_methods, "meta.class>get.MethodList"), | |
1276 "public", Matrix (), "private")); | |
1277 meta_class.install_property (make_attribute (meta_class, "Name")); | |
1278 meta_class.install_property | |
1279 (make_property (meta_class, "Properties", | |
1280 make_fcn_handle (class_get_properties, "meta.class>get.Properties"), | |
1281 "public", Matrix (), "private")); | |
1282 meta_class.install_property | |
1283 (make_property (meta_class, "PropertyList", | |
1284 make_fcn_handle (class_get_properties, "meta.class>get.PropertyList"), | |
1285 "public", Matrix (), "private")); | |
1286 meta_class.install_property (make_attribute (meta_class, "Sealed")); | |
1287 meta_class.install_property | |
1288 (make_property (meta_class, "SuperClasses", | |
1289 make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClasses"), | |
1290 "public", Matrix (), "private")); | |
1291 meta_class.install_property | |
1292 (make_property (meta_class, "SuperClassList", | |
1293 make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClassList"), | |
1294 "public", Matrix (), "private")); | |
1295 /* meta.class methods */ | |
1296 meta_class.install_method (make_method (meta_class, "fromName", class_fromName, | |
1297 "public", true)); | |
1298 meta_class.install_method (make_method (meta_class, "fevalStatic", class_fevalStatic, | |
1299 "public", false)); | |
1300 meta_class.install_method (make_method (meta_class, "getConstant", class_getConstant, | |
1301 "public", false)); | |
1302 meta_class.install_method (make_method (meta_class, "eq", class_eq)); | |
1303 meta_class.install_method (make_method (meta_class, "ne", class_ne)); | |
1304 meta_class.install_method (make_method (meta_class, "lt", class_lt)); | |
1305 meta_class.install_method (make_method (meta_class, "le", class_le)); | |
1306 meta_class.install_method (make_method (meta_class, "gt", class_gt)); | |
1307 meta_class.install_method (make_method (meta_class, "ge", class_ge)); | |
1308 | |
1309 /* meta.method properties */ | |
1310 meta_method.install_property (make_attribute (meta_method, "Abstract")); | |
1311 meta_method.install_property (make_attribute (meta_method, "Access")); | |
1312 meta_method.install_property (make_attribute (meta_method, "DefiningClass")); | |
1313 meta_method.install_property (make_attribute (meta_method, "Description")); | |
1314 meta_method.install_property (make_attribute (meta_method, "DetailedDescription")); | |
1315 meta_method.install_property (make_attribute (meta_method, "Hidden")); | |
1316 meta_method.install_property (make_attribute (meta_method, "Name")); | |
1317 meta_method.install_property (make_attribute (meta_method, "Sealed")); | |
1318 meta_method.install_property (make_attribute (meta_method, "Static")); | |
1319 | |
1320 /* meta.property properties */ | |
1321 meta_property.install_property (make_attribute (meta_property, "Name")); | |
1322 meta_property.install_property (make_attribute (meta_property, "Description")); | |
1323 meta_property.install_property (make_attribute (meta_property, "DetailedDescription")); | |
1324 meta_property.install_property (make_attribute (meta_property, "Abstract")); | |
1325 meta_property.install_property (make_attribute (meta_property, "Constant")); | |
1326 meta_property.install_property (make_attribute (meta_property, "GetAccess")); | |
1327 meta_property.install_property (make_attribute (meta_property, "SetAccess")); | |
1328 meta_property.install_property (make_attribute (meta_property, "Dependent")); | |
1329 meta_property.install_property (make_attribute (meta_property, "Transient")); | |
1330 meta_property.install_property (make_attribute (meta_property, "Hidden")); | |
1331 meta_property.install_property (make_attribute (meta_property, "GetObservable")); | |
1332 meta_property.install_property (make_attribute (meta_property, "SetObservable")); | |
1333 meta_property.install_property (make_attribute (meta_property, "GetMethod")); | |
1334 meta_property.install_property (make_attribute (meta_property, "SetMethod")); | |
1335 meta_property.install_property (make_attribute (meta_property, "DefiningClass")); | |
1336 /* meta.property events */ | |
1337 // FIXME: add events | |
1338 | |
1339 /* handle methods */ | |
1340 handle.install_method (make_method (handle, "delete", handle_delete)); | |
1341 | |
1342 /* meta.package properties */ | |
1343 meta_package.install_property (make_attribute (meta_package, "Name")); | |
1344 meta_package.install_property (make_property (meta_package, "ContainingPackage")); | |
1345 meta_package.install_property | |
1346 (make_property (meta_package, "ClassList", | |
1347 make_fcn_handle (package_get_classes, "meta.package>get.ClassList"), | |
1348 "public", Matrix (), "private")); | |
1349 meta_package.install_property | |
1350 (make_property (meta_package, "Classes", | |
1351 make_fcn_handle (package_get_classes, "meta.package>get.Classes"), | |
1352 "public", Matrix (), "private")); | |
1353 meta_package.install_property | |
1354 (make_property (meta_package, "FunctionList", | |
1355 make_fcn_handle (package_get_functions, "meta.package>get.FunctionList"), | |
1356 "public", Matrix (), "private")); | |
1357 meta_package.install_property | |
1358 (make_property (meta_package, "Functions", | |
1359 make_fcn_handle (package_get_functions, "meta.package>get.Functions"), | |
1360 "public", Matrix (), "private")); | |
1361 meta_package.install_property | |
1362 (make_property (meta_package, "PackageList", | |
1363 make_fcn_handle (package_get_packages, "meta.package>get.PackageList"), | |
1364 "public", Matrix (), "private")); | |
1365 meta_package.install_property | |
1366 (make_property (meta_package, "Packages", | |
1367 make_fcn_handle (package_get_packages, "meta.package>get.Packages"), | |
1368 "public", Matrix (), "private")); | |
1369 meta_package.install_method (make_method (meta_package, "fromName", package_fromName, | |
1370 "public", true)); | |
1371 | |
1372 /* create "meta" package */ | |
1373 cdef_package package_meta = make_package ("meta"); | |
1374 package_meta.install_class (meta_class, "class"); | |
1375 package_meta.install_class (meta_property, "property"); | |
1376 package_meta.install_class (meta_method, "method"); | |
1377 package_meta.install_class (meta_package, "package"); | |
1378 package_meta.install_class (meta_event, "event"); | |
1379 package_meta.install_class (meta_dynproperty, "dynproperty"); | |
1380 } | |
1381 | |
1382 DEFUN (__meta_get_package__, args, , "") | |
1383 { | |
1384 octave_value retval; | |
1385 | |
1386 if (args.length () == 1) | |
1387 { | |
1388 std::string cname = args(0).string_value (); | |
1389 | |
1390 if (! error_state) | |
1391 retval = to_ov (lookup_package (cname)); | |
1392 else | |
1393 error ("invalid package name, expected a string value"); | |
1394 } | |
1395 else | |
1396 print_usage (); | |
1397 | |
1398 return retval; | |
1399 } | |
1400 | |
1401 DEFUN (__superclass_reference__, args, /* nargout */, | |
1402 "-*- texinfo -*-\n\ | |
1403 @deftypefn {Built-in Function} {} __superclass_reference__ ()\n\ | |
1404 Undocumented internal function.\n\ | |
1405 @end deftypefn") | |
1406 { | |
1407 octave_value retval; | |
1408 | |
1409 std::cerr << "__superclass_reference__ (" | |
1410 << args(0).string_value () << ", " | |
1411 << args(1).string_value () << ", " | |
1412 << args(2).string_value () << ")" | |
1413 << std::endl; | |
1414 | |
1415 return retval; | |
1416 } | |
1417 | |
1418 DEFUN (__meta_class_query__, args, /* nargout */, | |
1419 "-*- texinfo -*-\n\ | |
1420 @deftypefn {Built-in Function} {} __meta_class_query__ ()\n\ | |
1421 Undocumented internal function.\n\ | |
1422 @end deftypefn") | |
1423 { | |
1424 octave_value retval; | |
1425 | |
1426 std::cerr << "__meta_class_query__ (" | |
1427 << args(0).string_value () << ", " | |
1428 << args(1).string_value () << ")" | |
1429 << std::endl; | |
1430 | |
1431 if (args.length () == 2) | |
1432 { | |
1433 std::string pkg = args(0).string_value (); | |
1434 std::string cls = args(1).string_value (); | |
1435 | |
1436 if (! pkg.empty ()) | |
1437 cls = pkg + "." + cls; | |
1438 | |
1439 if (! error_state) | |
1440 retval = to_ov (lookup_class (cls)); | |
1441 else | |
1442 error ("invalid class name, expected a string value"); | |
1443 } | |
1444 else | |
1445 print_usage (); | |
1446 | |
1447 return retval; | |
1448 } | |
1449 | |
1450 /* | |
1451 ;;; Local Variables: *** | |
1452 ;;; mode: C++ *** | |
1453 ;;; End: *** | |
1454 */ |