GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
ov-base.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <istream>
31#include <limits>
32#include <ostream>
33
34#include "lo-ieee.h"
35#include "lo-mappers.h"
36
37#include "defun.h"
38#include "errwarn.h"
39#include "interpreter-private.h"
40#include "interpreter.h"
41#include "mxarray.h"
42#include "oct-hdf5.h"
43#include "oct-lvalue.h"
44#include "oct-map.h"
45#include "oct-stream.h"
46#include "ops.h"
47#include "ov-base.h"
48#include "ov-cell.h"
49#include "ov-ch-mat.h"
50#include "ov-classdef.h"
51#include "ov-complex.h"
52#include "ov-cx-mat.h"
53#include "ov-fcn-handle.h"
54#include "ov-range.h"
55#include "ov-re-mat.h"
56#include "ov-scalar.h"
57#include "ov-str-mat.h"
58#include "ovl.h"
59#include "parse.h"
60#include "pr-flt-fmt.h"
61#include "pr-output.h"
62#include "utils.h"
63#include "variables.h"
64#include "ov-inline.h"
65
68{
70
71 if (x == btyp_bool)
72 x = btyp_double;
73 if (y == btyp_bool)
74 y = btyp_double;
75
77 retval = static_cast<builtin_type_t> (x | y);
78 else if (x <= btyp_uint64 && y <= btyp_float)
79 retval = x;
80 else if (x <= btyp_float && y <= btyp_uint64)
81 retval = y;
82 else if ((x >= btyp_int8 && x <= btyp_int64
83 && y >= btyp_int8 && y <= btyp_int64)
84 || (x >= btyp_uint8 && x <= btyp_uint64
85 && y >= btyp_uint8 && y <= btyp_uint64))
86 retval = (x > y) ? x : y;
87
88 return retval;
89}
90
92{
93 "double", "single", "double", "single",
94 "int8", "int16", "int32", "int64",
95 "uint8", "uint16", "uint32", "uint64",
96 "logical", "char",
97 "struct", "cell", "function_handle", "unknown"
98};
99
101 "<unknown type>", "unknown");
102
103#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
104 // Disable this warning for the use of the "count" member variable in
105 // the default constructor. Push the current state so we can restore
106 // the warning state.
107# pragma GCC diagnostic push
108# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
109#endif
110
111octave_base_value::octave_base_value () : m_count (1), count (m_count) { }
112
113#if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
114# pragma GCC diagnostic pop
115#endif
116
119{
120 return resize (dim_vector ()).clone ();
121}
122
123// FIXME: Unlike other virtual functions in the octave_base_value
124// class, the storable_value and make_storable_value functions defined
125// here are not used by the corresponding octave_value functions. This
126// inconsistency is likely to cause some confusion.
132
135{
136 return this;
137}
138
141{
142 std::string nm = type_name ();
143 error ("squeeze: invalid operation for %s type", nm.c_str ());
144}
145
148{
149 err_wrong_type_arg ("full: invalid operation for %s type", type_name ());
150}
151
154{
155 err_invalid_conversion (type_name (), "double");
156}
157
160{
161 const octave_base_value *cthis = this;
162 return cthis->as_double ();
163}
164
167{
168 err_invalid_conversion (type_name (), "single");
169}
170
176
182
188
194
200
203{
204 err_invalid_conversion (type_name (), "uint16");
205}
206
209{
210 err_invalid_conversion (type_name (), "uint32");
211}
212
215{
216 err_invalid_conversion (type_name (), "uint64");
217}
218
219Matrix
221{
222 const dim_vector dv = dims ();
223 Matrix mdv (1, dv.ndims ());
224 for (octave_idx_type i = 0; i < dv.ndims (); i++)
225 mdv(i) = dv(i);
226 return mdv;
227}
228
231{
232 return octave::dims_to_numel (dims (), idx);
233}
234
237simple_subsref (char type, octave_value_list& idx, int nargout)
238{
239 std::list<octave_value_list> idx_list;
240 idx_list.push_back (idx);
241 return subsref (std::string {type}, idx_list, nargout);
242}
243
245octave_base_value::subsref (const std::string&,
246 const std::list<octave_value_list>&)
247{
248 std::string nm = type_name ();
249 error ("can't perform indexing operations for %s type", nm.c_str ());
250}
251
253octave_base_value::subsref (const std::string&,
254 const std::list<octave_value_list>&, int)
255{
256 std::string nm = type_name ();
257 error ("can't perform indexing operations for %s type", nm.c_str ());
258}
259
261octave_base_value::subsref (const std::string& type,
262 const std::list<octave_value_list>& idx,
263 bool /* auto_add */)
264{
265 // This way we may get a more meaningful error message.
266 return subsref (type, idx);
267}
268
271{
272 std::string nm = type_name ();
273 error ("can't perform indexing operations for %s type", nm.c_str ());
274}
275
276octave::idx_vector
277octave_base_value::index_vector (bool /* require_integers */) const
278{
279 std::string nm = '<' + type_name () + '>';
280 octave::err_invalid_index (nm.c_str ());
281}
282
285 const octave_value& rhs)
286{
287 std::list<octave_value_list> idx_list;
288 idx_list.push_back (idx);
289
290 return subsasgn (std::string {type}, idx_list, rhs);
291}
292
294octave_base_value::subsasgn (const std::string& type,
295 const std::list<octave_value_list>& idx,
296 const octave_value& rhs)
297{
298 octave_value retval;
299
300 if (is_defined ())
301 {
302 if (! isnumeric ())
303 {
304 std::string nm = type_name ();
305 error ("can't perform indexed assignment for %s type", nm.c_str ());
306 }
307
308 switch (type[0])
309 {
310 case '(':
311 {
312 if (type.length () == 1)
313 retval = numeric_assign (type, idx, rhs);
314 else if (isempty ())
315 {
316 // Allow conversion of empty matrix to some other
317 // type in cases like
318 //
319 // x = []; x(i).f = rhs
320
321 octave_value tmp = octave_value::empty_conv (type, rhs);
322
323 retval = tmp.subsasgn (type, idx, rhs);
324 }
325 else
326 {
327 std::string nm = type_name ();
328 error ("in indexed assignment of %s, last rhs index must be ()",
329 nm.c_str ());
330 }
331 }
332 break;
333
334 case '{':
335 case '.':
336 {
337 std::string nm = type_name ();
338 error ("%s cannot be indexed with %c", nm.c_str (), type[0]);
339 }
340 break;
341
342 default:
343 error ("unexpected: index not '(', '{', or '.' in octave_base_value::subsasgn - please report this bug");
345 }
346 else
347 {
348 // Create new object of appropriate type for given index and rhs
349 // types and then call undef_subsasgn for that object.
350
351 octave_value tmp = octave_value::empty_conv (type, rhs);
352
353 retval = tmp.undef_subsasgn (type, idx, rhs);
354 }
355
356 return retval;
357}
358
360octave_base_value::undef_subsasgn (const std::string& type,
361 const std::list<octave_value_list>& idx,
362 const octave_value& rhs)
363{
364 // In most cases, undef_subsasgn is handled the sams as subsasgn. One
365 // exception is octave_class objects.
366
367 return subsasgn (type, idx, rhs);
368}
369
372{
373 err_wrong_type_arg ("octave_base_value::nnz ()", type_name ());
374}
375
378{
379 return numel ();
380}
381
384{
385 err_wrong_type_arg ("octave_base_value::nfields ()", type_name ());
386}
387
390{
391 err_wrong_type_arg ("octave_base_value::reshape ()", type_name ());
392}
393
396{
397 err_wrong_type_arg ("octave_base_value::permute ()", type_name ());
398}
399
402{
403 err_wrong_type_arg ("octave_base_value::resize ()", type_name ());
404}
405
408{
409 err_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
410}
411
414{
415 err_wrong_type_arg ("octave_base_value::matrix_type ()", type_name ());
416}
417
420{
421 return 0.0;
422}
423
426{
427 return 0.0;
428}
429
431octave_base_value::convert_to_str (bool pad, bool force, char type) const
432{
433 octave_value retval = convert_to_str_internal (pad, force, type);
434
435 if (! force && isnumeric ())
436 warn_implicit_conversion ("Octave:num-to-str",
437 type_name (), retval.type_name ());
438
439 return retval;
440}
441
444{
445 err_wrong_type_arg ("octave_base_value::convert_to_str_internal ()",
446 type_name ());
447}
448
449void
451{
453 ("octave_base_value::convert_to_row_or_column_vector ()", type_name ());
454}
455
456void
457octave_base_value::print (std::ostream&, bool)
458{
459 err_wrong_type_arg ("octave_base_value::print ()", type_name ());
460}
461
462void
463octave_base_value::print_raw (std::ostream&, bool) const
464{
465 err_wrong_type_arg ("octave_base_value::print_raw ()", type_name ());
466}
467
468bool
470 const std::string& name) const
471{
472 indent (os);
473
474 if (print_as_scalar ())
475 os << name << " = ";
476 else
477 {
478 os << name << " =";
479 newline (os);
480 if (! Vcompact_format)
481 newline (os);
482
483 return true;
484 }
485
486 return false;
487}
488
489void
490octave_base_value::print_with_name (std::ostream& output_buf,
491 const std::string& name,
492 bool print_padding)
493{
494 bool pad_after = print_name_tag (output_buf, name);
495
496 print (output_buf);
497
498 if (print_padding && pad_after && ! Vcompact_format)
499 newline (output_buf);
500}
501
507
508void
510 const std::string& /* prefix */) const
511{
512 os << "no info for type: " << type_name () << "\n";
513}
514
515#define INT_CONV_METHOD(T, F) \
516 T \
517 octave_base_value::F ## _value (bool require_int, bool frc_str_conv) const \
518 { \
519 T retval = 0; \
520 \
521 double d = 0.0; \
522 \
523 try \
524 { \
525 d = double_value (frc_str_conv); \
526 } \
527 catch (octave::execution_exception& ee) \
528 { \
529 err_wrong_type_arg (ee, "octave_base_value::" #F "_value ()", type_name ()); \
530 } \
531 \
532 static constexpr double out_of_range_top \
533 = static_cast<double> (std::numeric_limits<T>::max ()) + 1.0; \
534 if (require_int && octave::math::x_nint (d) != d) \
535 error_with_cfn ("conversion of %g to " #T " value failed", d); \
536 else if (d < std::numeric_limits<T>::min ()) \
537 retval = std::numeric_limits<T>::min (); \
538 else if (d >= out_of_range_top) \
539 retval = std::numeric_limits<T>::max (); \
540 else \
541 retval = static_cast<T> (octave::math::fix (d)); \
542 \
543 return retval; \
544 }
545
546INT_CONV_METHOD (short int, short)
547INT_CONV_METHOD (unsigned short int, ushort)
548
550INT_CONV_METHOD (unsigned int, uint)
551
552INT_CONV_METHOD (long int, long)
553INT_CONV_METHOD (unsigned long int, ulong)
554
555INT_CONV_METHOD (int64_t, int64)
556INT_CONV_METHOD (uint64_t, uint64)
557
558int
559octave_base_value::nint_value (bool frc_str_conv) const
560{
561 double d = 0.0;
562
563 try
564 {
565 d = double_value (frc_str_conv);
566 }
567 catch (octave::execution_exception& ee)
568 {
569 err_wrong_type_arg (ee, "octave_base_value::nint_value ()", type_name ());
570 }
571
572 if (octave::math::isnan (d))
573 error ("conversion of NaN to integer value failed");
574
575 return static_cast<int> (octave::math::fix (d));
576}
577
578double
580{
581 err_wrong_type_arg ("octave_base_value::double_value ()", type_name ());
582}
583
584float
586{
587 err_wrong_type_arg ("octave_base_value::float_value ()", type_name ());
588}
589
590Cell
592{
593 err_wrong_type_arg ("octave_base_value::cell_value()", type_name ());
594}
595
596Matrix
598{
599 err_wrong_type_arg ("octave_base_value::matrix_value()", type_name ());
600}
601
604{
605 err_wrong_type_arg ("octave_base_value::float_matrix_value()", type_name ());
606}
607
610{
611 err_wrong_type_arg ("octave_base_value::array_value()", type_name ());
612}
613
616{
617 err_wrong_type_arg ("octave_base_value::float_array_value()", type_name ());
618}
619
622{
623 err_wrong_type_arg ("octave_base_value::complex_value()", type_name ());
624}
625
628{
629 err_wrong_type_arg ("octave_base_value::float_complex_value()", type_name ());
630}
631
634{
635 err_wrong_type_arg ("octave_base_value::complex_matrix_value()",
636 type_name ());
637}
638
641{
642 err_wrong_type_arg ("octave_base_value::float_complex_matrix_value()",
643 type_name ());
644}
645
648{
649 err_wrong_type_arg ("octave_base_value::complex_array_value()", type_name ());
650}
651
654{
655 err_wrong_type_arg ("octave_base_value::float_complex_array_value()",
656 type_name ());
657}
658
659bool
661{
662 err_wrong_type_arg ("octave_base_value::bool_value()", type_name ());
663}
664
667{
668 err_wrong_type_arg ("octave_base_value::bool_matrix_value()", type_name ());
669}
670
673{
674 err_wrong_type_arg ("octave_base_value::bool_array_value()", type_name ());
675}
676
679{
680 octave_value tmp = convert_to_str (false, force);
681
682 return tmp.char_matrix_value ();
683}
684
687{
688 err_wrong_type_arg ("octave_base_value::char_array_value()", type_name ());
689}
690
693{
694 err_wrong_type_arg ("octave_base_value::sparse_matrix_value()", type_name ());
695}
696
699{
700 err_wrong_type_arg ("octave_base_value::sparse_complex_matrix_value()",
701 type_name ());
702}
703
706{
707 err_wrong_type_arg ("octave_base_value::sparse_bool_matrix_value()",
708 type_name ());
709}
710
713{
714 err_wrong_type_arg ("octave_base_value::diag_matrix_value()", type_name ());
715}
716
719{
720 err_wrong_type_arg ("octave_base_value::float_diag_matrix_value()",
721 type_name ());
722}
723
726{
727 err_wrong_type_arg ("octave_base_value::complex_diag_matrix_value()",
728 type_name ());
729}
730
733{
734 err_wrong_type_arg ("octave_base_value::float_complex_diag_matrix_value()",
735 type_name ());
736}
737
740{
741 err_wrong_type_arg ("octave_base_value::perm_matrix_value()", type_name ());
742}
743
746{
747 err_wrong_type_arg ("octave_base_value::int8_scalar_value()", type_name ());
748}
749
752{
753 err_wrong_type_arg ("octave_base_value::int16_scalar_value()", type_name ());
754}
755
758{
759 err_wrong_type_arg ("octave_base_value::int32_scalar_value()", type_name ());
760}
761
764{
765 err_wrong_type_arg ("octave_base_value::int64_scalar_value()", type_name ());
766}
767
770{
771 err_wrong_type_arg ("octave_base_value::uint8_scalar_value()", type_name ());
772}
773
776{
777 err_wrong_type_arg ("octave_base_value::uint16_scalar_value()", type_name ());
778}
779
782{
783 err_wrong_type_arg ("octave_base_value::uint32_scalar_value()", type_name ());
784}
785
788{
789 err_wrong_type_arg ("octave_base_value::uint64_scalar_value()", type_name ());
790}
791
794{
795 err_wrong_type_arg ("octave_base_value::int8_array_value()", type_name ());
796}
797
800{
801 err_wrong_type_arg ("octave_base_value::int16_array_value()", type_name ());
802}
803
807 err_wrong_type_arg ("octave_base_value::int32_array_value()", type_name ());
808}
809
812{
813 err_wrong_type_arg ("octave_base_value::int64_array_value()", type_name ());
814}
815
818{
819 err_wrong_type_arg ("octave_base_value::uint8_array_value()", type_name ());
820}
821
824{
825 err_wrong_type_arg ("octave_base_value::uint16_array_value()", type_name ());
826}
827
830{
831 err_wrong_type_arg ("octave_base_value::uint32_array_value()", type_name ());
832}
833
836{
837 err_wrong_type_arg ("octave_base_value::uint64_array_value()", type_name ());
838}
839
842{
843 octave_value tmp = convert_to_str (pad, true);
844
845 return tmp.string_vector_value ();
846}
847
848std::string
850{
851 octave_value tmp = convert_to_str (force);
852
853 return tmp.string_value ();
854}
855
856std::string
858{
859 err_wrong_type_arg ("octave_base_value::xstring_value()", type_name ());
860}
861
864{
865 err_wrong_type_arg ("octave_base_value::cellstr_value()", type_name ());
866}
867
868octave::range<double>
870{
871 err_wrong_type_arg ("octave_base_value::range_value()", type_name ());
872}
873
874// For now, enable only range<double>.
875
878{
879 err_wrong_type_arg ("octave_base_value::map_value()", type_name ());
880}
881
884{
885 octave_map tmp = map_value ();
886
887 if (tmp.numel () != 1)
888 error ("invalid conversion of multi-dimensional struct to scalar struct");
889
890 return octave_scalar_map (tmp.checkelem (0));
891}
892
895{
896 err_wrong_type_arg ("octave_base_value::map_keys()", type_name ());
897}
898
899bool
900octave_base_value::isfield (const std::string&) const
901{
902 err_wrong_type_arg ("octave_base_value::isfield()", type_name ());
903}
904
905std::size_t
907{
908 err_wrong_type_arg ("octave_base_value::nparents()", type_name ());
909}
910
911std::list<std::string>
913{
914 err_wrong_type_arg ("octave_base_value::parent_class_name_list()",
915 type_name ());
916}
917
920{
921 err_wrong_type_arg ("octave_base_value::parent_class_names()", type_name ());
922}
923
926{
927 if (! silent)
928 err_wrong_type_arg ("octave_base_value::classdef_object_value()",
929 type_name ());
930
931 return nullptr;
932}
933
936{
937 if (! silent)
938 err_wrong_type_arg ("octave_base_value::function_value()", type_name ());
939
940 return nullptr;
941}
942
945{
946 if (! silent)
947 err_wrong_type_arg ("octave_base_value::user_function_value()",
948 type_name ());
949 return nullptr;
950}
951
954{
955 if (! silent)
956 err_wrong_type_arg ("octave_base_value::user_script_value()", type_name ());
957
958 return nullptr;
959}
960
963{
964 if (! silent)
965 err_wrong_type_arg ("octave_base_value::user_code_value()", type_name ());
966
967 return nullptr;
968}
969
972{
973 if (! silent)
974 err_wrong_type_arg ("octave_base_value::fcn_handle_value()", type_name ());
975
976 return nullptr;
977}
978
981{
982 err_wrong_type_arg ("octave_base_value::list_value()", type_name ());
983}
984
985bool
987{
988 err_wrong_type_arg ("octave_base_value::save_ascii()", type_name ());
989}
990
991bool
993{
994 err_wrong_type_arg ("octave_base_value::load_ascii()", type_name ());
995}
996
997bool
999{
1000 err_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
1001}
1002
1003bool
1005 octave::mach_info::float_format)
1006{
1007 err_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
1008}
1009
1010bool
1012{
1013 err_wrong_type_arg ("octave_base_value::save_binary()", type_name ());
1014}
1015
1016bool
1018{
1019 err_wrong_type_arg ("octave_base_value::load_binary()", type_name ());
1020}
1021
1022int
1024 int, octave::mach_info::float_format) const
1025{
1026 err_wrong_type_arg ("octave_base_value::write()", type_name ());
1027}
1028
1029mxArray *
1031{
1032 return nullptr;
1033}
1034
1037{
1038 err_wrong_type_arg ("octave_base_value::diag ()", type_name ());
1039}
1040
1043{
1044 err_wrong_type_arg ("octave_base_value::diag ()", type_name ());
1045}
1046
1049{
1050 err_wrong_type_arg ("octave_base_value::sort ()", type_name ());
1051}
1052
1056{
1057 err_wrong_type_arg ("octave_base_value::sort ()", type_name ());
1058}
1059
1062{
1063 err_wrong_type_arg ("octave_base_value::issorted ()", type_name ());
1064}
1065
1068{
1069 err_wrong_type_arg ("octave_base_value::sort_rows_idx ()", type_name ());
1070}
1071
1074{
1075 err_wrong_type_arg ("octave_base_value::is_sorted_rows ()", type_name ());
1076}
1077
1078const char *
1080{
1081 static const char *names[num_unary_mappers] =
1082 {
1083 "abs",
1084 "acos",
1085 "acosh",
1086 "angle",
1087 "arg",
1088 "asin",
1089 "asinh",
1090 "atan",
1091 "atanh",
1092 "cbrt",
1093 "ceil",
1094 "conj",
1095 "cos",
1096 "cosh",
1097 "erf",
1098 "erfinv",
1099 "erfcinv",
1100 "erfc",
1101 "erfcx",
1102 "erfi",
1103 "dawson",
1104 "exp",
1105 "expm1",
1106 "isfinite",
1107 "fix",
1108 "floor",
1109 "gamma",
1110 "imag",
1111 "isinf",
1112 "isna",
1113 "isnan",
1114 "lgamma",
1115 "log",
1116 "log2",
1117 "log10",
1118 "log1p",
1119 "real",
1120 "round",
1121 "roundb",
1122 "signum",
1123 "sin",
1124 "sinh",
1125 "sqrt",
1126 "tan",
1127 "tanh",
1128 "isalnum",
1129 "isalpha",
1130 "isascii",
1131 "iscntrl",
1132 "isdigit",
1133 "isgraph",
1134 "islower",
1135 "isprint",
1136 "ispunct",
1137 "isspace",
1138 "isupper",
1139 "isxdigit",
1140 "signbit",
1141 "tolower",
1142 "toupper"
1143 };
1144
1145 if (umap < 0 || umap >= num_unary_mappers)
1146 return "unknown";
1147 else
1148 return names[umap];
1149}
1150
1151void
1152octave_base_value::warn_load (const char *type) const
1153{
1155 ("Octave:load-save-unavailable",
1156 "%s: loading %s files not available in this version of Octave",
1157 s_t_name.c_str (), type);
1158}
1159
1160void
1161octave_base_value::warn_save (const char *type) const
1162{
1164 ("Octave:load-save-unavailable",
1165 "%s: saving %s files not available in this version of Octave",
1166 s_t_name.c_str (), type);
1167}
1168
1171{
1172 error ("%s: not defined for %s", get_umap_name (umap), type_name ().c_str ());
1173}
1174
1175void
1177{
1178 err_wrong_type_arg ("octave_base_value::lock ()", type_name ());
1179}
1180
1181void
1183{
1184 err_wrong_type_arg ("octave_base_value::unlock ()", type_name ());
1185}
1186
1189{
1190 std::map<std::string, octave_value> m
1191 = {{ "class", this->class_name () },
1192 { "type", this->type_name () },
1193 { "dims", this->dims().as_array () }
1194 };
1195
1196 return octave_value (m);
1197}
1198
1199OCTAVE_NORETURN static
1200void
1201err_indexed_assignment (const std::string& tn1, const std::string& tn2)
1202{
1203 error ("assignment of '%s' to indexed '%s' not implemented",
1204 tn2.c_str (), tn1.c_str ());
1205}
1206
1207OCTAVE_NORETURN static
1208void
1209err_assign_conversion_failed (const std::string& tn1, const std::string& tn2)
1210{
1211 error ("type conversion for assignment of '%s' to indexed '%s' failed",
1212 tn2.c_str (), tn1.c_str ());
1213}
1214
1215OCTAVE_NORETURN static
1216void
1217err_no_conversion (const std::string& on, const std::string& tn1,
1218 const std::string& tn2)
1219{
1220 error ("operator %s: no conversion for assignment of '%s' to indexed '%s'",
1221 on.c_str (), tn2.c_str (), tn1.c_str ());
1222}
1223
1225octave_base_value::numeric_assign (const std::string& type,
1226 const std::list<octave_value_list>& idx,
1227 const octave_value& rhs)
1228{
1229 octave_value retval;
1230
1231 if (idx.front ().empty ())
1232 error ("missing index in indexed assignment");
1233
1234 int t_lhs = type_id ();
1235 int t_rhs = rhs.type_id ();
1236
1237 octave::type_info& ti = octave::__get_type_info__ ();
1238
1239 octave::type_info::assign_op_fcn f
1240 = ti.lookup_assign_op (octave_value::op_asn_eq, t_lhs, t_rhs);
1241
1242 bool done = false;
1243
1244 if (f)
1245 {
1246 f (*this, idx.front (), rhs.get_rep ());
1247
1248 done = true;
1249 }
1250
1251 if (done)
1252 {
1253 m_count++;
1254 retval = octave_value (this);
1255 }
1256 else
1257 {
1258 int t_result = ti.lookup_pref_assign_conv (t_lhs, t_rhs);
1259
1260 if (t_result >= 0)
1261 {
1263 = ti.lookup_widening_op (t_lhs, t_result);
1264
1265 if (! cf)
1266 err_indexed_assignment (type_name (), rhs.type_name ());
1267
1268 octave_base_value *tmp = cf (*this);
1269
1270 if (! tmp)
1271 err_assign_conversion_failed (type_name (), rhs.type_name ());
1272
1273 octave_value val (tmp);
1274
1275 retval = val.subsasgn (type, idx, rhs);
1276
1277 done = true;
1278 }
1279
1280 if (! done)
1281 {
1282 octave_value tmp_rhs;
1283
1286
1289
1290 // Try biased (one-sided) conversions first.
1291 if (cf_rhs.type_id () >= 0
1292 && (ti.lookup_assign_op (octave_value::op_asn_eq,
1293 t_lhs, cf_rhs.type_id ())
1294 || ti.lookup_pref_assign_conv (t_lhs,
1295 cf_rhs.type_id ()) >= 0))
1296 cf_this = nullptr;
1297 else if (cf_this.type_id () >= 0
1298 && (ti.lookup_assign_op (octave_value::op_asn_eq,
1299 cf_this.type_id (), t_rhs)
1300 || ti.lookup_pref_assign_conv (cf_this.type_id (),
1301 t_rhs) >= 0))
1302 cf_rhs = nullptr;
1303
1304 if (cf_rhs)
1305 {
1306 octave_base_value *tmp = cf_rhs (rhs.get_rep ());
1307
1308 if (! tmp)
1309 err_assign_conversion_failed (type_name (), rhs.type_name ());
1310
1311 tmp_rhs = octave_value (tmp);
1312 }
1313 else
1314 tmp_rhs = rhs;
1315
1316 m_count++;
1317 octave_value tmp_lhs = octave_value (this);
1318
1319 if (cf_this)
1320 {
1321 octave_base_value *tmp = cf_this (*this);
1322
1323 if (! tmp)
1324 err_assign_conversion_failed (type_name (), rhs.type_name ());
1325
1326 tmp_lhs = octave_value (tmp);
1327 }
1328
1329 if (! cf_this && ! cf_rhs)
1330 err_no_conversion (octave_value::assign_op_as_string
1332 type_name (), rhs.type_name ());
1333
1334 retval = tmp_lhs.subsasgn (type, idx, tmp_rhs);
1335
1336 done = true;
1337 }
1338 }
1339
1340 // The assignment may have converted to a type that is wider than necessary.
1341
1342 retval.maybe_mutate ();
1343
1344 return retval;
1345}
1346
1347// Current indentation.
1348int octave_base_value::s_curr_print_indent_level = 0;
1349
1350// TRUE means we are at the beginning of a line.
1351bool octave_base_value::s_beginning_of_line = true;
1352
1353// Each print() function should call this before printing anything.
1354//
1355// This doesn't need to be fast, but isn't there a better way?
1356
1357void
1358octave_base_value::indent (std::ostream& os) const
1359{
1360 panic_unless (s_curr_print_indent_level >= 0);
1361
1362 if (s_beginning_of_line)
1363 {
1364 // FIXME: do we need this?
1365 // os << prefix;
1366
1367 for (int i = 0; i < s_curr_print_indent_level; i++)
1368 os << ' ';
1369
1370 s_beginning_of_line = false;
1371 }
1372}
1373
1374// All print() functions should use this to print new lines.
1375
1376void
1377octave_base_value::newline (std::ostream& os) const
1378{
1379 os << "\n";
1380
1381 s_beginning_of_line = true;
1382}
1383
1384// For resetting print state.
1385
1386void
1388{
1389 s_beginning_of_line = true;
1390 s_curr_print_indent_level = 0;
1391}
1392
1398
1399bool
1404
1405bool
1407{
1408 return false;
1409}
1410
1411static octave_base_value *
1412oct_conv_matrix_conv (const octave_base_value&)
1413{
1414 return new octave_matrix ();
1415}
1416
1417static octave_base_value *
1418oct_conv_complex_matrix_conv (const octave_base_value&)
1419{
1420 return new octave_complex_matrix ();
1421}
1422
1423static octave_base_value *
1424oct_conv_string_conv (const octave_base_value&)
1425{
1426 return new octave_char_matrix_str ();
1427}
1428
1429static octave_base_value *
1430oct_conv_cell_conv (const octave_base_value&)
1431{
1432 return new octave_cell ();
1433}
1434
1435static inline octave_value_list
1436sanitize (const octave_value_list& ovl)
1437{
1438 octave_value_list retval = ovl;
1439
1440 for (octave_idx_type i = 0; i < ovl.length (); i++)
1441 {
1442 if (retval(i).is_magic_colon ())
1443 retval(i) = ":";
1444 }
1445
1446 return retval;
1447}
1448
1450make_idx_args (const std::string& type,
1451 const std::list<octave_value_list>& idx,
1452 const std::string& who)
1453{
1454 std::size_t len = type.length ();
1455
1456 if (len != idx.size ())
1457 error ("invalid index for %s", who.c_str ());
1458
1459 Cell type_field (1, len);
1460 Cell subs_field (1, len);
1461
1462 auto p = idx.begin ();
1463
1464 for (std::size_t i = 0; i < len; i++)
1465 {
1466 char t = type[i];
1467
1468 switch (t)
1469 {
1470 case '(':
1471 type_field(i) = "()";
1472 subs_field(i) = Cell (sanitize (*p++));
1473 break;
1474
1475 case '{':
1476 type_field(i) = "{}";
1477 subs_field(i) = Cell (sanitize (*p++));
1478 break;
1479
1480 case '.':
1481 {
1482 type_field(i) = ".";
1483
1484 octave_value_list vlist = *p++;
1485
1486 if (vlist.length () != 1)
1487 error ("only single argument permitted for '.' index");
1488
1489 octave_value val = vlist(0);
1490
1491 if (! val.is_string ())
1492 error ("string argument required for '.' index");
1493
1494 subs_field(i) = val;
1495 }
1496 break;
1497
1498 default:
1499 error ("unexpected: index not '(', '{', or '.' in make_idx_args - please report this bug");
1500 break;
1501 }
1502 }
1503
1504 octave_map m;
1505
1506 m.assign ("type", type_field);
1507 m.assign ("subs", subs_field);
1508
1509 return m;
1510}
1511
1512bool
1514{
1515 octave::tree_evaluator& tw = octave::__get_evaluator__ ();
1516
1517 octave_function *fcn = tw.caller_function ();
1518
1519 // FIXME: we probably need a better check here, or some other
1520 // mechanism to avoid overloaded functions when builtin is used.
1521 // For example, what if someone overloads the builtin function?
1522 // Also, are there other places where using builtin is not properly
1523 // avoiding dispatch?
1524
1525 return (fcn && fcn->name () == "builtin");
1526}
1527
1529
1530void
1550
1551OCTAVE_END_NAMESPACE(octave)
N Dimensional Array with copy-on-write semantics.
Definition Array.h:130
Definition Cell.h:41
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
Array< octave_idx_type > as_array() const
octave_idx_type ndims() const
Number of dimensions.
Definition dim-vector.h:253
virtual bool load_hdf5(octave_hdf5_id loc_id, const char *name)
Definition ov-base.cc:1017
virtual SparseMatrix sparse_matrix_value(bool=false) const
Definition ov-base.cc:692
virtual octave_value full_value() const
Definition ov-base.cc:147
virtual octave_value subsref(const std::string &type, const std::list< octave_value_list > &idx)
Definition ov-base.cc:245
virtual float float_value(bool=false) const
Definition ov-base.cc:585
virtual octave_base_value * make_storable_value()
Definition ov-base.cc:134
virtual bool save_ascii(std::ostream &os)
Definition ov-base.cc:986
virtual octave_int16 int16_scalar_value() const
Definition ov-base.cc:751
virtual octave::range< double > range_value() const
Definition ov-base.cc:869
virtual octave_value as_double() const
Definition ov-base.cc:153
virtual FloatComplexDiagMatrix float_complex_diag_matrix_value(bool=false) const
Definition ov-base.cc:732
virtual octave_idx_type numel() const
Definition ov-base.h:401
virtual uint16NDArray uint16_array_value() const
Definition ov-base.cc:823
virtual ComplexNDArray complex_array_value(bool=false) const
Definition ov-base.cc:647
virtual void print_with_name(std::ostream &output_buf, const std::string &name, bool print_padding=true)
Definition ov-base.cc:490
virtual octave_value fast_elem_extract(octave_idx_type n) const
Definition ov-base.cc:1394
virtual boolNDArray bool_array_value(bool=false) const
Definition ov-base.cc:672
virtual bool print_name_tag(std::ostream &os, const std::string &name) const
Definition ov-base.cc:469
virtual uint32NDArray uint32_array_value() const
Definition ov-base.cc:829
virtual MatrixType matrix_type() const
Definition ov-base.cc:407
virtual FloatComplexNDArray float_complex_array_value(bool=false) const
Definition ov-base.cc:653
virtual octave_user_script * user_script_value(bool silent=false)
Definition ov-base.cc:953
virtual octave_value as_uint8() const
Definition ov-base.cc:196
virtual charNDArray char_array_value(bool=false) const
Definition ov-base.cc:686
virtual string_vector parent_class_names() const
Definition ov-base.cc:919
virtual octave_value_list simple_subsref(char type, octave_value_list &idx, int nargout)
Definition ov-base.cc:237
virtual octave_value diag(octave_idx_type k=0) const
Definition ov-base.cc:1036
virtual octave_int8 int8_scalar_value() const
Definition ov-base.cc:745
virtual Array< std::string > cellstr_value() const
Definition ov-base.cc:863
virtual uint8NDArray uint8_array_value() const
Definition ov-base.cc:817
void indent(std::ostream &os) const
Definition ov-base.cc:1358
virtual octave_uint32 uint32_scalar_value() const
Definition ov-base.cc:781
virtual Matrix size()
Definition ov-base.cc:220
virtual octave_value permute(const Array< int > &vec, bool=false) const
Definition ov-base.cc:395
virtual octave_fcn_handle * fcn_handle_value(bool silent=false)
Definition ov-base.cc:971
virtual charMatrix char_matrix_value(bool force=false) const
Definition ov-base.cc:678
virtual octave_value storable_value()
Definition ov-base.cc:128
void newline(std::ostream &os) const
Definition ov-base.cc:1377
virtual octave_classdef * classdef_object_value(bool silent=false)
Definition ov-base.cc:925
virtual octave_value do_index_op(const octave_value_list &idx, bool resize_ok=false)
Definition ov-base.cc:270
virtual float_display_format get_edit_display_format() const
Definition ov-base.cc:503
virtual octave_value all(int=0) const
Definition ov-base.cc:419
virtual bool isfield(const std::string &) const
Definition ov-base.cc:900
virtual sortmode is_sorted_rows(sortmode mode=UNSORTED) const
Definition ov-base.cc:1073
virtual void unlock()
Definition ov-base.cc:1182
octave_base_value *(* type_conv_fcn)(const octave_base_value &)
Definition ov-base.h:257
virtual octave_value as_uint16() const
Definition ov-base.cc:202
virtual boolMatrix bool_matrix_value(bool=false) const
Definition ov-base.cc:666
virtual FloatComplex float_complex_value(bool=false) const
Definition ov-base.cc:627
virtual octave_value map(unary_mapper_t) const
Definition ov-base.cc:1170
virtual octave_idx_type nzmax() const
Definition ov-base.cc:377
virtual octave_value convert_to_str_internal(bool pad, bool force, char type) const
Definition ov-base.cc:443
virtual FloatComplexMatrix float_complex_matrix_value(bool=false) const
Definition ov-base.cc:640
virtual ComplexMatrix complex_matrix_value(bool=false) const
Definition ov-base.cc:633
virtual void print_raw(std::ostream &os, bool pr_as_read_syntax=false) const
Definition ov-base.cc:463
virtual octave_int32 int32_scalar_value() const
Definition ov-base.cc:757
virtual octave_idx_type nnz() const
Definition ov-base.cc:371
virtual int32NDArray int32_array_value() const
Definition ov-base.cc:805
virtual octave_value dump() const
Definition ov-base.cc:1188
virtual octave_value convert_to_str(bool pad=false, bool force=false, char type='\'') const
Definition ov-base.cc:431
virtual octave_value as_int32() const
Definition ov-base.cc:184
virtual octave::idx_vector index_vector(bool require_integers=false) const
Definition ov-base.cc:277
octave::refcount< octave_idx_type > m_count
Definition ov-base.h:958
virtual octave_uint64 uint64_scalar_value() const
Definition ov-base.cc:787
virtual FloatDiagMatrix float_diag_matrix_value(bool=false) const
Definition ov-base.cc:718
virtual bool save_binary(std::ostream &os, bool save_as_floats)
Definition ov-base.cc:998
virtual type_conv_info numeric_conversion_function() const
Definition ov-base.h:303
octave_value numeric_assign(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition ov-base.cc:1225
void warn_load(const char *type) const
Definition ov-base.cc:1152
virtual octave_value as_double_or_copy()
Definition ov-base.cc:159
virtual int type_id() const
Definition ov-base.h:977
virtual octave_value reshape(const dim_vector &) const
Definition ov-base.cc:389
virtual mxArray * as_mxArray(bool interleaved) const
Definition ov-base.cc:1030
virtual SparseBoolMatrix sparse_bool_matrix_value(bool=false) const
Definition ov-base.cc:705
virtual string_vector map_keys() const
Definition ov-base.cc:894
virtual octave_value_list list_value() const
Definition ov-base.cc:980
virtual uint64NDArray uint64_array_value() const
Definition ov-base.cc:835
virtual void lock()
Definition ov-base.cc:1176
static const char * get_umap_name(unary_mapper_t)
Definition ov-base.cc:1079
virtual int16NDArray int16_array_value() const
Definition ov-base.cc:799
virtual bool load_ascii(std::istream &is)
Definition ov-base.cc:992
virtual bool load_binary(std::istream &is, bool swap, octave::mach_info::float_format fmt)
Definition ov-base.cc:1004
virtual dim_vector dims() const
Definition ov-base.h:382
virtual FloatNDArray float_array_value(bool=false) const
Definition ov-base.cc:615
virtual Array< octave_idx_type > sort_rows_idx(sortmode mode=ASCENDING) const
Definition ov-base.cc:1067
virtual FloatMatrix float_matrix_value(bool=false) const
Definition ov-base.cc:603
virtual octave_value as_int64() const
Definition ov-base.cc:190
virtual octave_idx_type xnumel(const octave_value_list &)
Definition ov-base.cc:230
virtual DiagMatrix diag_matrix_value(bool=false) const
Definition ov-base.cc:712
bool isempty() const
Definition ov-base.h:429
virtual SparseComplexMatrix sparse_complex_matrix_value(bool=false) const
Definition ov-base.cc:698
void reset() const
Definition ov-base.cc:1387
virtual octave_idx_type nfields() const
Definition ov-base.cc:383
virtual bool isnumeric() const
Definition ov-base.h:525
virtual octave_uint8 uint8_scalar_value() const
Definition ov-base.cc:769
virtual int64NDArray int64_array_value() const
Definition ov-base.cc:811
virtual bool print_as_scalar() const
Definition ov-base.h:746
virtual octave_value squeeze() const
Definition ov-base.cc:140
virtual bool fast_elem_insert(octave_idx_type n, const octave_value &x)
Definition ov-base.cc:1400
virtual octave_user_function * user_function_value(bool silent=false)
Definition ov-base.cc:944
virtual bool bool_value(bool=false) const
Definition ov-base.cc:660
virtual octave_value as_uint32() const
Definition ov-base.cc:208
virtual octave_value as_int16() const
Definition ov-base.cc:178
virtual int8NDArray int8_array_value() const
Definition ov-base.cc:793
virtual void print_info(std::ostream &os, const std::string &prefix) const
Definition ov-base.cc:509
virtual std::string xstring_value() const
Definition ov-base.cc:857
virtual bool fast_elem_insert_self(void *where, builtin_type_t btyp) const
Definition ov-base.cc:1406
virtual ComplexDiagMatrix complex_diag_matrix_value(bool=false) const
Definition ov-base.cc:725
virtual bool save_hdf5(octave_hdf5_id loc_id, const char *name, bool save_as_floats)
Definition ov-base.cc:1011
virtual octave_value as_int8() const
Definition ov-base.cc:172
virtual void print(std::ostream &os, bool pr_as_read_syntax=false)
Definition ov-base.cc:457
virtual octave_value resize(const dim_vector &, bool fill=false) const
Definition ov-base.cc:401
virtual octave_value sort(octave_idx_type dim=0, sortmode mode=ASCENDING) const
Definition ov-base.cc:1048
virtual int write(octave::stream &os, int block_size, oct_data_conv::data_type output_type, int skip, octave::mach_info::float_format flt_fmt) const
Definition ov-base.cc:1023
virtual bool is_defined() const
Definition ov-base.h:423
virtual octave_int64 int64_scalar_value() const
Definition ov-base.cc:763
virtual octave_map map_value() const
Definition ov-base.cc:877
virtual NDArray array_value(bool=false) const
Definition ov-base.cc:609
virtual std::string string_value(bool force=false) const
Definition ov-base.cc:849
virtual std::size_t nparents() const
Definition ov-base.cc:906
virtual octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition ov-base.cc:294
virtual octave_user_code * user_code_value(bool silent=false)
Definition ov-base.cc:962
virtual octave_scalar_map scalar_map_value() const
Definition ov-base.cc:883
virtual double double_value(bool=false) const
Definition ov-base.cc:579
virtual octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
Definition ov-base.cc:360
virtual Matrix matrix_value(bool=false) const
Definition ov-base.cc:597
virtual std::string type_name() const
Definition ov-base.h:977
virtual std::string class_name() const
Definition ov-base.h:977
virtual octave_value simple_subsasgn(char type, octave_value_list &idx, const octave_value &rhs)
Definition ov-base.cc:284
virtual sortmode issorted(sortmode mode=UNSORTED) const
Definition ov-base.cc:1061
virtual octave_base_value * empty_clone() const
Definition ov-base.cc:118
virtual octave_function * function_value(bool silent=false)
Definition ov-base.cc:935
virtual octave_value as_single() const
Definition ov-base.cc:166
virtual string_vector string_vector_value(bool pad=false) const
Definition ov-base.cc:841
friend class octave_value
Definition ov-base.h:278
virtual PermMatrix perm_matrix_value() const
Definition ov-base.cc:739
virtual std::list< std::string > parent_class_name_list() const
Definition ov-base.cc:912
virtual octave_value any(int=0) const
Definition ov-base.cc:425
virtual Cell cell_value() const
Definition ov-base.cc:591
virtual void convert_to_row_or_column_vector()
Definition ov-base.cc:450
virtual octave_value as_uint64() const
Definition ov-base.cc:214
virtual octave_uint16 uint16_scalar_value() const
Definition ov-base.cc:775
virtual Complex complex_value(bool=false) const
Definition ov-base.cc:621
void warn_save(const char *type) const
Definition ov-base.cc:1161
std::string name() const
Definition ov-fcn.h:208
octave_scalar_map checkelem(octave_idx_type n) const
Definition oct-map.h:378
octave_idx_type numel() const
Definition oct-map.h:368
void assign(const std::string &k, const Cell &val)
Definition oct-map.h:344
static octave_value make_copy(octave_base_value *rep)
Definition ov-inline.h:129
octave_idx_type length() const
Definition ovl.h:111
const octave_base_value & get_rep() const
Definition ov.h:1374
charMatrix char_matrix_value(bool frc_str_conv=false) const
Definition ov.h:903
bool is_string() const
Definition ov.h:637
static std::string assign_op_as_string(assign_op)
Definition ov.cc:355
octave_value undef_subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
static octave_value empty_conv(const std::string &type, const octave_value &rhs=octave_value())
int type_id() const
Definition ov.h:1358
@ op_asn_eq
Definition ov.h:135
void maybe_mutate()
octave_base_value::type_conv_info numeric_conversion_function() const
Definition ov.h:423
std::string string_value(bool force=false) const
Definition ov.h:983
octave_base_value * clone() const
string_vector string_vector_value(bool pad=false) const
Definition ov.h:986
octave_idx_type length() const
std::string type_name() const
Definition ov.h:1360
octave_value subsasgn(const std::string &type, const std::list< octave_value_list > &idx, const octave_value &rhs)
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning_with_id(const char *id, const char *fmt,...)
Definition error.cc:1093
void error(const char *fmt,...)
Definition error.cc:1003
void err_wrong_type_arg(const char *name, const char *s)
Definition errwarn.cc:166
void err_invalid_conversion(const std::string &from, const std::string &to)
Definition errwarn.cc:71
void warn_implicit_conversion(const char *id, const char *from, const char *to)
Definition errwarn.cc:344
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
F77_RET_T const F77_DBLE * x
F77_RET_T const F77_DBLE const F77_DBLE * f
std::complex< double > Complex
Definition oct-cmplx.h:33
std::complex< float > FloatComplex
Definition oct-cmplx.h:34
int64_t octave_hdf5_id
sortmode
Definition oct-sort.h:97
#define INSTALL_ASSIGNCONV_TI(ti, t1, t2, tr)
Definition ops.h:88
#define INSTALL_WIDENOP_TI(ti, t1, t2, f)
Definition ops.h:92
std::string btyp_class_name[btyp_num_types+1]
Definition ov-base.cc:91
void install_base_type_conversions(octave::type_info &ti)
Definition ov-base.cc:1531
octave_value make_idx_args(const std::string &type, const std::list< octave_value_list > &idx, const std::string &who)
Definition ov-base.cc:1450
builtin_type_t btyp_mixed_numeric(builtin_type_t x, builtin_type_t y)
Determine the resulting type for a possible mixed-type operation.
Definition ov-base.cc:67
#define INT_CONV_METHOD(T, F)
Definition ov-base.cc:515
bool called_from_builtin()
Definition ov-base.cc:1513
#define DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(t, n, c)
Definition ov-base.h:246
builtin_type_t
Definition ov-base.h:83
@ btyp_float_complex
Definition ov-base.h:87
@ btyp_double
Definition ov-base.h:84
@ btyp_float
Definition ov-base.h:85
@ btyp_int64
Definition ov-base.h:91
@ btyp_bool
Definition ov-base.h:96
@ btyp_unknown
Definition ov-base.h:101
@ btyp_uint64
Definition ov-base.h:95
@ btyp_num_types
Definition ov-base.h:102
@ btyp_uint8
Definition ov-base.h:92
@ btyp_int8
Definition ov-base.h:88
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition ovl.h:217
#define panic_unless(cond)
Definition panic.h:59
bool Vcompact_format
Definition pr-output.cc:102
F77_RET_T len
Definition xerbla.cc:61