changelog shortlog tags changeset files revisions annotate raw

src/pr-output.cc

changeset 10289: 4b124317dc38
parent:829e69ec3110
author: John W. Eaton <jwe@octave.org>
date: Tue Feb 09 20:58:55 2010 -0500 (56 minutes ago)
permissions: -rw-r--r--
description: base_properties::set_children: account for hidden children
1/*
2
3Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 John W. Eaton
5
6This file is part of Octave.
7
8Octave is free software; you can redistribute it and/or modify it
9under the terms of the GNU General Public License as published by the
10Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13Octave is distributed in the hope that it will be useful, but WITHOUT
14ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with Octave; see the file COPYING. If not, see
20<http://www.gnu.org/licenses/>.
21
22*/
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include <cfloat>
29#include <cstdio>
30#include <cstring>
31
32#include <iomanip>
33#include <iostream>
34#include <sstream>
35#include <string>
36
37#include "Array-util.h"
38#include "CMatrix.h"
39#include "Range.h"
40#include "cmd-edit.h"
41#include "dMatrix.h"
42#include "lo-mappers.h"
43#include "lo-math.h"
44#include "mach-info.h"
45#include "oct-cmplx.h"
46#include "quit.h"
47#include "str-vec.h"
48
49#include "Cell.h"
50#include "defun.h"
51#include "error.h"
52#include "gripes.h"
53#include "oct-obj.h"
54#include "oct-stream.h"
55#include "pager.h"
56#include "pr-output.h"
57#include "sysdep.h"
58#include "unwind-prot.h"
59#include "utils.h"
60#include "variables.h"
61
62// TRUE means use a scaled fixed point format for `format long' and
63// `format short'.
64static bool Vfixed_point_format = false;
65
66// The maximum field width for a number printed by the default output
67// routines.
68static int Voutput_max_field_width = 10;
69
70// The precision of the numbers printed by the default output
71// routines.
72static int Voutput_precision = 5;
73
74// TRUE means that the dimensions of empty objects should be printed
75// like this: x = [](2x0).
76bool Vprint_empty_dimensions = true;
77
78// TRUE means that the rows of big matrices should be split into
79// smaller slices that fit on the screen.
80static bool Vsplit_long_rows = true;
81
82// How many levels of structure elements should we print?
83int Vstruct_levels_to_print = 2;
84
85// TRUE means don't do any fancy formatting.
86static bool free_format = false;
87
88// TRUE means print plus sign for nonzero, blank for zero.
89static bool plus_format = false;
90
91// First char for > 0, second for < 0, third for == 0.
92static std::string plus_format_chars = "+ ";
93
94// TRUE means always print in a rational approximation
95static bool rat_format = false;
96
97// Used to force the length of the rational approximation string for Frats
98static int rat_string_len = -1;
99
100// TRUE means always print like dollars and cents.
101static bool bank_format = false;
102
103// TRUE means print data in hexadecimal format.
104static int hex_format = 0;
105
106// TRUE means print data in binary-bit-pattern format.
107static int bit_format = 0;
108
109// TRUE means don't put newlines around the column number headers.
110static bool compact_format = false;
111
112// TRUE means use an e format.
113static bool print_e = false;
114
115// TRUE means use a g format.
116static bool print_g = false;
117
118// TRUE means print E instead of e for exponent field.
119static bool print_big_e = false;
120
121class pr_formatted_float;
122class pr_rational_float;
123
124static int
125current_output_max_field_width (void)
126{
127 return Voutput_max_field_width;
128}
129
130static int
131current_output_precision (void)
132{
133 return Voutput_precision;
134}
135
136class
137float_format
138{
139public:
140
141 float_format (int w = current_output_max_field_width (),
142 int p = current_output_precision (), int f = 0)
143 : fw (w), prec (p), fmt (f), up (0), sp (0) { }
144
145 float_format (const float_format& ff)
146 : fw (ff.fw), prec (ff.prec), fmt (ff.fmt), up (ff.up), sp (ff.sp) { }
147
148 float_format& operator = (const float_format& ff)
149 {
150 if (&ff != this)
151 {
152 fw = ff.fw;
153 prec = ff.prec;
154 fmt = ff.fmt;
155 up = ff.up;
156 sp = ff.sp;
157 }
158
159 return *this;
160 }
161
162 ~float_format (void) { }
163
164 float_format& scientific (void) { fmt = std::ios::scientific; return *this; }
165 float_format& fixed (void) { fmt = std::ios::fixed; return *this; }
166 float_format& general (void) { fmt = 0; return *this; }
167
168 float_format& uppercase (void) { up = std::ios::uppercase; return *this; }
169 float_format& lowercase (void) { up = 0; return *this; }
170
171 float_format& precision (int p) { prec = p; return *this; }
172
173 float_format& width (int w) { fw = w; return *this; }
174
175 float_format& trailing_zeros (bool tz = true)
176 { sp = tz ? std::ios::showpoint : 0; return *this; }
177
178 friend std::ostream& operator << (std::ostream& os,
179 const pr_formatted_float& pff);
180
181 friend std::ostream& operator << (std::ostream& os,
182 const pr_rational_float& pff);
183
184private:
185
186 // Field width. Zero means as wide as necessary.
187 int fw;
188
189 // Precision.
190 int prec;
191
192 // Format.
193 int fmt;
194
195 // E or e.
196 int up;
197
198 // Show trailing zeros.
199 int sp;
200};
201
202class
203pr_formatted_float
204{
205public:
206
207 const float_format& f;
208
209 double val;
210
211 pr_formatted_float (const float_format& f_arg, double val_arg)
212 : f (f_arg), val (val_arg) { }
213};
214
215std::ostream&
216operator << (std::ostream& os, const pr_formatted_float& pff)
217{
218 if (pff.f.fw >= 0)
219 os << std::setw (pff.f.fw);
220
221 if (pff.f.prec >= 0)
222 os << std::setprecision (pff.f.prec);
223
224 std::ios::fmtflags oflags =
225 os.flags (static_cast<std::ios::fmtflags>
226 (pff.f.fmt | pff.f.up | pff.f.sp));
227
228 os << pff.val;
229
230 os.flags (oflags);
231
232 return os;
233}
234
235static inline std::string
236rational_approx (double val, int len)
237{
238 std::string s;
239
240 if (len <= 0)
241 len = 10;
242
243 if (xisinf (val))
244 s = "1/0";
245 else if (xisnan (val))
246 s = "0/0";
247 else if (val < INT_MIN || val > INT_MAX || D_NINT (val) == val)
248 {
249 std::ostringstream buf;
250 buf.flags (std::ios::fixed);
251 buf << std::setprecision (0) << xround(val);
252 s = buf.str ();
253 }
254 else
255 {
256 double lastn = 1.;
257 double lastd = 0.;
258 double n = xround (val);
259 double d = 1.;
260 double frac = val - n;
261 int m = 0;
262
263 std::ostringstream buf2;
264 buf2.flags (std::ios::fixed);
265 buf2 << std::setprecision (0) << static_cast<int>(n);
266 s = buf2.str();
267
268 while (1)
269 {
270 double flip = 1. / frac;
271 double step = xround (flip);
272 double nextn = n;
273 double nextd = d;
274
275 // Have we converged to 1/intmax ?
276 if (m > 100 || fabs (frac) < 1 / static_cast<double>(INT_MAX))
277 {
278 lastn = n;
279 lastd = d;
280 break;
281 }
282
283 frac = flip - step;
284 n = n * step + lastn;
285 d = d * step + lastd;
286 lastn = nextn;
287 lastd = nextd;
288
289 std::ostringstream buf;
290 buf.flags (std::ios::fixed);
291 buf << std::setprecision (0) << static_cast<int>(n)
292 << "/" << static_cast<int>(d);
293 m++;
294
295 if (n < 0 && d < 0)
296 {
297 // Double negative, string can be two characters longer..
298 if (buf.str().length() > static_cast<unsigned int>(len + 2) &&
299 m > 1)
300 break;
301 }
302 else if (buf.str().length() > static_cast<unsigned int>(len) &&
303 m > 1)
304 break;
305
306 s = buf.str();
307 }
308
309 if (lastd < 0.)
310 {
311 // Move sign to the top
312 lastd = - lastd;
313 lastn = - lastn;
314 std::ostringstream buf;
315 buf.flags (std::ios::fixed);
316 buf << std::setprecision (0) << static_cast<int>(lastn)
317 << "/" << static_cast<int>(lastd);
318 s = buf.str();
319 }
320 }
321
322 return s;
323}
324
325class
326pr_rational_float
327{
328public:
329
330 const float_format& f;
331
332 double val;
333
334 pr_rational_float (const float_format& f_arg, double val_arg)
335 : f (f_arg), val (val_arg) { }
336};
337
338std::ostream&
339operator << (std::ostream& os, const pr_rational_float& prf)
340{
341 int fw = (rat_string_len > 0 ? rat_string_len : prf.f.fw);
342 std::string s = rational_approx (prf.val, fw);
343
344 if (fw >= 0)
345 os << std::setw (fw);
346
347 std::ios::fmtflags oflags =
348 os.flags (static_cast<std::ios::fmtflags>
349 (prf.f.fmt | prf.f.up | prf.f.sp));
350
351 if (fw > 0 && s.length() > static_cast<unsigned int>(fw))
352 os << "*";
353 else
354 os << s;
355
356 os.flags (oflags);
357
358 return os;
359}
360
361// Current format for real numbers and the real part of complex
362// numbers.
363static float_format *curr_real_fmt = 0;
364
365// Current format for the imaginary part of complex numbers.
366static float_format *curr_imag_fmt = 0;
367
368static double
369pr_max_internal (const Matrix& m)
370{
371 octave_idx_type nr = m.rows ();
372 octave_idx_type nc = m.columns ();
373
374 double result = -DBL_MAX;
375
376 bool all_inf_or_nan = true;
377
378 for (octave_idx_type j = 0; j < nc; j++)
379 for (octave_idx_type i = 0; i < nr; i++)
380 {
381 double val = m(i,j);
382 if (xisinf (val) || xisnan (val))
383 continue;
384
385 all_inf_or_nan = false;
386
387 if (val > result)
388 result = val;
389 }
390
391 if (all_inf_or_nan)
392 result = 0.0;
393
394 return result;
395}
396
397static double
398pr_min_internal (const Matrix& m)
399{
400 octave_idx_type nr = m.rows ();
401 octave_idx_type nc = m.columns ();
402
403 double result = DBL_MAX;
404
405 bool all_inf_or_nan = true;
406
407 for (octave_idx_type j = 0; j < nc; j++)
408 for (octave_idx_type i = 0; i < nr; i++)
409 {
410 double val = m(i,j);
411 if (xisinf (val) || xisnan (val))
412 continue;
413
414 all_inf_or_nan = false;
415
416 if (val < result)
417 result = val;
418 }
419
420 if (all_inf_or_nan)
421 result = 0.0;
422
423 return result;
424}
425
426// FIXME -- it would be nice to share more code among these
427// functions,..
428
429static void
430set_real_format (int digits, bool inf_or_nan, bool int_only, int &fw)
431{
432 static float_format fmt;
433
434 int prec = Voutput_precision;
435
436 int ld, rd;
437
438 if (rat_format)
439 {
440 fw = 0;
441 rd = 0;
442 }
443 else if (bank_format)
444 {
445 fw = digits < 0 ? 4 : digits + 3;
446 if (inf_or_nan && fw < 4)
447 fw = 4;
448 rd = 2;
449 }
450 else if (hex_format)
451 {
452 fw = 2 * sizeof (double);
453 rd = 0;
454 }
455 else if (bit_format)
456 {
457 fw = 8 * sizeof (double);
458 rd = 0;
459 }
460 else if (inf_or_nan || int_only)
461 {
462 fw = 1 + digits;
463 if (inf_or_nan && fw < 4)
464 fw = 4;
465 rd = fw;
466 }
467 else
468 {
469 if (digits > 0)
470 {
471 ld = digits;
472 rd = prec > digits ? prec - digits : prec;
473 digits++;
474 }
475 else
476 {
477 ld = 1;
478 rd = prec > digits ? prec - digits : prec;
479 digits = -digits + 1;
480 }
481
482 fw = 1 + ld + 1 + rd;
483 if (inf_or_nan && fw < 4)
484 fw = 4;
485 }
486
487 if (! (rat_format || bank_format || hex_format || bit_format)
488 && (fw > Voutput_max_field_width || print_e || print_g))
489 {
490 if (print_g)
491 fmt = float_format ();
492 else
493 {
494 int exp_field = 4;
495 if (digits > 100)
496 exp_field++;
497
498 fw = 2 + prec + exp_field;
499 if (inf_or_nan && fw < 4)
500 fw = 4;
501
502 fmt = float_format (fw, prec - 1, std::ios::scientific);
503 }
504
505 if (print_big_e)
506 fmt.uppercase ();
507 }
508 else if (! bank_format && (inf_or_nan || int_only))
509 fmt = float_format (fw, rd);
510 else
511 fmt = float_format (fw, rd, std::ios::fixed);
512
513 curr_real_fmt = &fmt;
514}
515
516static void
517set_format (double d, int& fw)
518{
519 curr_real_fmt = 0;
520 curr_imag_fmt = 0;
521
522 if (free_format)
523 return;
524
525 bool inf_or_nan = (xisinf (d) || xisnan (d));
526
527 bool int_only = (! inf_or_nan && D_NINT (d) == d);
528
529 double d_abs = d < 0.0 ? -d : d;
530
531 int digits = (inf_or_nan || d_abs == 0.0)
532 ? 0 : static_cast<int> (floor (log10 (d_abs) + 1.0));
533
534 set_real_format (digits, inf_or_nan, int_only, fw);
535}
536
537static inline void
538set_format (double d)
539{
540 int fw;
541 set_format (d, fw);
542}
543
544static void
545set_real_matrix_format (int x_max, int x_min, bool inf_or_nan,
546 int int_or_inf_or_nan, int& fw)
547{
548 static float_format fmt;
549
550 int prec = Voutput_precision;
551
552 int ld, rd;
553
554 if (rat_format)
555 {
556 fw = 9;
557 rd = 0;
558 }
559 else if (bank_format)
560 {
561 int digits = x_max > x_min ? x_max : x_min;
562 fw = digits <= 0 ? 4 : digits + 3;
563 if (inf_or_nan && fw < 4)
564 fw = 4;
565 rd = 2;
566 }
567 else if (hex_format)
568 {
569 fw = 2 * sizeof (double);
570 rd = 0;
571 }
572 else if (bit_format)
573 {
574 fw = 8 * sizeof (double);
575 rd = 0;
576 }
577 else if (Vfixed_point_format && ! print_g)
578 {
579 rd = prec;
580 fw = rd + 2;
581 if (inf_or_nan && fw < 4)
582 fw = 4;
583 }
584 else if (int_or_inf_or_nan)
585 {
586 int digits = x_max > x_min ? x_max : x_min;
587 fw = digits <= 0 ? 2 : digits + 1;
588 if (inf_or_nan && fw < 4)
589 fw = 4;
590 rd = fw;
591 }
592 else
593 {
594 int ld_max, rd_max;
595 if (x_max > 0)
596 {
597 ld_max = x_max;
598 rd_max = prec > x_max ? prec - x_max : prec;
599 x_max++;
600 }
601 else
602 {
603 ld_max = 1;
604 rd_max = prec > x_max ? prec - x_max : prec;
605 x_max = -x_max + 1;
606 }
607
608 int ld_min, rd_min;
609 if (x_min > 0)
610 {
611 ld_min = x_min;
612 rd_min = prec > x_min ? prec - x_min : prec;
613 x_min++;
614 }
615 else
616 {
617 ld_min = 1;
618 rd_min = prec > x_min ? prec - x_min : prec;
619 x_min = -x_min + 1;
620 }
621
622 ld = ld_max > ld_min ? ld_max : ld_min;
623 rd = rd_max > rd_min ? rd_max : rd_min;
624
625 fw = 1 + ld + 1 + rd;
626 if (inf_or_nan && fw < 4)
627 fw = 4;
628 }
629
630 if (! (rat_format || bank_format || hex_format || bit_format)
631 && (print_e
632 || print_g
633 || (! Vfixed_point_format && fw > Voutput_max_field_width)))
634 {
635 if (print_g)
636 fmt = float_format ();
637 else
638 {
639 int exp_field = 4;
640 if (x_max > 100 || x_min > 100)
641 exp_field++;
642
643 fw = 2 + prec + exp_field;
644 if (inf_or_nan && fw < 4)
645 fw = 4;
646
647 fmt = float_format (fw, prec - 1, std::ios::scientific);
648 }
649
650 if (print_big_e)
651 fmt.uppercase ();
652 }
653 else if (! bank_format && int_or_inf_or_nan)
654 fmt = float_format (fw, rd);
655 else
656 fmt = float_format (fw, rd, std::ios::fixed);
657
658 curr_real_fmt = &fmt;
659}
660
661static void
662set_format (const Matrix& m, int& fw, double& scale)
663{
664 curr_real_fmt = 0;
665 curr_imag_fmt = 0;
666
667 if (free_format)
668 return;
669
670 bool inf_or_nan = m.any_element_is_inf_or_nan ();
671
672 bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan ();
673
674 Matrix m_abs = m.abs ();
675 double max_abs = pr_max_internal (m_abs);
676 double min_abs = pr_min_internal (m_abs);
677
678 int x_max = max_abs == 0.0
679 ? 0 : static_cast<int> (floor (log10 (max_abs) + 1.0));
680
681 int x_min = min_abs == 0.0
682 ? 0 : static_cast<int> (floor (log10 (min_abs) + 1.0));
683
684 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 : std::pow (10.0, x_max - 1);
685
686 set_real_matrix_format (x_max, x_min, inf_or_nan, int_or_inf_or_nan, fw);
687}
688
689static inline void
690set_format (const Matrix& m)
691{
692 int fw;
693 double scale;
694 set_format (m, fw, scale);
695}
696
697static void
698set_complex_format (int x_max, int x_min, int r_x, bool inf_or_nan,
699 int int_only, int& r_fw, int& i_fw)
700{
701 static float_format r_fmt;
702 static float_format i_fmt;
703
704 int prec = Voutput_precision;
705
706 int ld, rd;
707
708 if (rat_format)
709 {
710 i_fw = 0;
711 r_fw = 0;
712 rd = 0;
713 }
714 else if (bank_format)
715 {
716 int digits = r_x;
717 i_fw = 0;
718 r_fw = digits <= 0 ? 4 : digits + 3;
719 if (inf_or_nan && r_fw < 4)
720 r_fw = 4;
721 rd = 2;
722 }
723 else if (hex_format)
724 {
725 r_fw = 2 * sizeof (double);
726 i_fw = 2 * sizeof (double);
727 rd = 0;
728 }
729 else if (bit_format)
730 {
731 r_fw = 8 * sizeof (double);
732 i_fw = 8 * sizeof (double);
733 rd = 0;
734 }
735 else if (inf_or_nan || int_only)
736 {
737 int digits = x_max > x_min ? x_max : x_min;
738 i_fw = digits <= 0 ? 1 : digits;
739 r_fw = i_fw + 1;
740 if (inf_or_nan && i_fw < 3)
741 {
742 i_fw = 3;
743 r_fw = 4;
744 }
745 rd = r_fw;
746 }
747 else
748 {
749 int ld_max, rd_max;
750 if (x_max > 0)
751 {
752 ld_max = x_max;
753 rd_max = prec > x_max ? prec - x_max : prec;
754 x_max++;
755 }
756 else
757 {
758 ld_max = 1;
759 rd_max = prec > x_max ? prec - x_max : prec;
760 x_max = -x_max + 1;
761 }
762
763 int ld_min, rd_min;
764 if (x_min > 0)
765 {
766 ld_min = x_min;
767 rd_min = prec > x_min ? prec - x_min : prec;
768 x_min++;
769 }
770 else
771 {
772 ld_min = 1;
773 rd_min = prec > x_min ? prec - x_min : prec;
774 x_min = -x_min + 1;
775 }
776
777 ld = ld_max > ld_min ? ld_max : ld_min;
778 rd = rd_max > rd_min ? rd_max : rd_min;
779
780 i_fw = ld + 1 + rd;
781 r_fw = i_fw + 1;
782 if (inf_or_nan && i_fw < 3)
783 {
784 i_fw = 3;
785 r_fw = 4;
786 }
787 }
788
789 if (! (rat_format || bank_format || hex_format || bit_format)
790 && (r_fw > Voutput_max_field_width || print_e || print_g))
791 {
792 if (print_g)
793 {
794 r_fmt = float_format ();
795 i_fmt = float_format ();
796 }
797 else
798 {
799 int exp_field = 4;
800 if (x_max > 100 || x_min > 100)
801 exp_field++;
802
803 i_fw = prec + exp_field;
804 r_fw = i_fw + 1;
805 if (inf_or_nan && i_fw < 3)
806 {
807 i_fw = 3;
808 r_fw = 4;
809 }
810
811 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
812 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
813 }
814
815 if (print_big_e)
816 {
817 r_fmt.uppercase ();
818 i_fmt.uppercase ();
819 }
820 }
821 else if (! bank_format && (inf_or_nan || int_only))
822 {
823 r_fmt = float_format (r_fw, rd);
824 i_fmt = float_format (i_fw, rd);
825 }
826 else
827 {
828 r_fmt = float_format (r_fw, rd, std::ios::fixed);
829 i_fmt = float_format (i_fw, rd, std::ios::fixed);
830 }
831
832 curr_real_fmt = &r_fmt;
833 curr_imag_fmt = &i_fmt;
834}
835
836static void
837set_format (const Complex& c, int& r_fw, int& i_fw)
838{
839 curr_real_fmt = 0;
840 curr_imag_fmt = 0;
841
842 if (free_format)
843 return;
844
845 double rp = c.real ();
846 double ip = c.imag ();
847
848 bool inf_or_nan = (xisinf (c) || xisnan (c));
849
850 bool int_only = (D_NINT (rp) == rp && D_NINT (ip) == ip);
851
852 double r_abs = rp < 0.0 ? -rp : rp;
853 double i_abs = ip < 0.0 ? -ip : ip;
854
855 int r_x = (xisinf (rp) || xisnan (rp) || r_abs == 0.0)
856 ? 0 : static_cast<int> (floor (log10 (r_abs) + 1.0));
857
858 int i_x = (xisinf (ip) || xisnan (ip) || i_abs == 0.0)
859 ? 0 : static_cast<int> (floor (log10 (i_abs) + 1.0));
860
861 int x_max, x_min;
862
863 if (r_x > i_x)
864 {
865 x_max = r_x;
866 x_min = i_x;
867 }
868 else
869 {
870 x_max = i_x;
871 x_min = r_x;
872 }
873
874 set_complex_format (x_max, x_min, r_x, inf_or_nan, int_only, r_fw, i_fw);
875}
876
877static inline void
878set_format (const Complex& c)
879{
880 int r_fw, i_fw;
881 set_format (c, r_fw, i_fw);
882}
883
884static void
885set_complex_matrix_format (int x_max, int x_min, int r_x_max,
886 int r_x_min, bool inf_or_nan,
887 int int_or_inf_or_nan, int& r_fw, int& i_fw)
888{
889 static float_format r_fmt;
890 static float_format i_fmt;
891
892 int prec = Voutput_precision;
893
894 int ld, rd;
895
896 if (rat_format)
897 {
898 i_fw = 9;
899 r_fw = 9;
900 rd = 0;
901 }
902 else if (bank_format)
903 {
904 int digits = r_x_max > r_x_min ? r_x_max : r_x_min;
905 i_fw = 0;
906 r_fw = digits <= 0 ? 4 : digits + 3;
907 if (inf_or_nan && r_fw < 4)
908 r_fw = 4;
909 rd = 2;
910 }
911 else if (hex_format)
912 {
913 r_fw = 2 * sizeof (double);
914 i_fw = 2 * sizeof (double);
915 rd = 0;
916 }
917 else if (bit_format)
918 {
919 r_fw = 8 * sizeof (double);
920 i_fw = 8 * sizeof (double);
921 rd = 0;
922 }
923 else if (Vfixed_point_format && ! print_g)
924 {
925 rd = prec;
926 i_fw = rd + 1;
927 r_fw = i_fw + 1;
928 if (inf_or_nan && i_fw < 3)
929 {
930 i_fw = 3;
931 r_fw = 4;
932 }
933 }
934 else if (int_or_inf_or_nan)
935 {
936 int digits = x_max > x_min ? x_max : x_min;
937 i_fw = digits <= 0 ? 1 : digits;
938 r_fw = i_fw + 1;
939 if (inf_or_nan && i_fw < 3)
940 {
941 i_fw = 3;
942 r_fw = 4;
943 }
944 rd = r_fw;
945 }
946 else
947 {
948 int ld_max, rd_max;
949 if (x_max > 0)
950 {
951 ld_max = x_max;
952 rd_max = prec > x_max ? prec - x_max : prec;
953 x_max++;
954 }
955 else
956 {
957 ld_max = 1;
958 rd_max = prec > x_max ? prec - x_max : prec;
959 x_max = -x_max + 1;
960 }
961
962 int ld_min, rd_min;
963 if (x_min > 0)
964 {
965 ld_min = x_min;
966 rd_min = prec > x_min ? prec - x_min : prec;
967 x_min++;
968 }
969 else
970 {
971 ld_min = 1;
972 rd_min = prec > x_min ? prec - x_min : prec;
973 x_min = -x_min + 1;
974 }
975
976 ld = ld_max > ld_min ? ld_max : ld_min;
977 rd = rd_max > rd_min ? rd_max : rd_min;
978
979 i_fw = ld + 1 + rd;
980 r_fw = i_fw + 1;
981 if (inf_or_nan && i_fw < 3)
982 {
983 i_fw = 3;
984 r_fw = 4;
985 }
986 }
987
988 if (! (rat_format || bank_format || hex_format || bit_format)
989 && (print_e
990 || print_g
991 || (! Vfixed_point_format && r_fw > Voutput_max_field_width)))
992 {
993 if (print_g)
994 {
995 r_fmt = float_format ();
996 i_fmt = float_format ();
997 }
998 else
999 {
1000 int exp_field = 4;
1001 if (x_max > 100 || x_min > 100)
1002 exp_field++;
1003
1004 i_fw = prec + exp_field;
1005 r_fw = i_fw + 1;
1006 if (inf_or_nan && i_fw < 3)
1007 {
1008 i_fw = 3;
1009 r_fw = 4;
1010 }
1011
1012 r_fmt = float_format (r_fw, prec - 1, std::ios::scientific);
1013 i_fmt = float_format (i_fw, prec - 1, std::ios::scientific);
1014 }
1015
1016 if (print_big_e)
1017 {
1018 r_fmt.uppercase ();
1019 i_fmt.uppercase ();
1020 }
1021 }
1022 else if (! bank_format && int_or_inf_or_nan)
1023 {
1024 r_fmt = float_format (r_fw, rd);
1025 i_fmt = float_format (i_fw, rd);
1026 }
1027 else
1028 {
1029 r_fmt = float_format (r_fw, rd, std::ios::fixed);
1030 i_fmt = float_format (i_fw, rd, std::ios::fixed);
1031 }
1032
1033 curr_real_fmt = &r_fmt;
1034 curr_imag_fmt = &i_fmt;
1035}
1036
1037static void
1038set_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale)
1039{
1040 curr_real_fmt = 0;
1041 curr_imag_fmt = 0;
1042
1043 if (free_format)
1044 return;
1045
1046 Matrix rp = real (cm);
1047 Matrix ip = imag (cm);
1048
1049 bool inf_or_nan = cm.any_element_is_inf_or_nan ();
1050
1051 bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan ()
1052 && ip.all_elements_are_int_or_inf_or_nan ());
1053
1054 Matrix r_m_abs = rp.abs ();
1055 double r_max_abs = pr_max_internal (r_m_abs);
1056 double r_min_abs = pr_min_internal (r_m_abs);
1057
1058 Matrix i_m_abs = ip.abs ();
1059 double i_max_abs = pr_max_internal (i_m_abs);
1060 double i_min_abs = pr_min_internal (i_m_abs);
1061
1062 int r_x_max = r_max_abs == 0.0
1063 ? 0 : static_cast<int> (floor (log10 (r_max_abs) + 1.0));
1064
1065 int r_x_min = r_min_abs == 0.0
1066 ? 0 : static_cast<int> (floor (log10 (r_min_abs) + 1.0));
1067
1068 int i_x_max = i_max_abs == 0.0
1069 ? 0 : static_cast<int> (floor (log10 (i_max_abs) + 1.0));
1070
1071 int i_x_min = i_min_abs == 0.0
1072 ? 0 : static_cast<int> (floor (log10 (i_min_abs) + 1.0));
1073
1074 int x_max = r_x_max > i_x_max ? r_x_max : i_x_max;
1075 int x_min = r_x_min > i_x_min ? r_x_min : i_x_min;
1076
1077 scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 : std::pow (10.0, x_max - 1);
1078
1079 set_complex_matrix_format (x_max, x_min, r_x_max, r_x_min, inf_or_nan,
1080 int_or_inf_or_nan, r_fw, i_fw);
1081}
1082
1083static inline void
1084set_format (const ComplexMatrix& cm)
1085{
1086 int r_fw, i_fw;
1087 double scale;
1088 set_format (cm, r_fw, i_fw, scale);
1089}
1090
1091static void
1092set_range_format (int x_max, int x_min, int all_ints, int& fw)
1093{
1094 static float_format fmt;
1095
1096 int prec = Voutput_precision;
1097
1098 int ld, rd;
1099
1100 if (rat_format)
1101 {
1102 fw = 9;
1103 rd = 0;
1104 }
1105 else if (bank_format)
1106 {
1107 int digits = x_max > x_min ? x_max : x_min;
1108 fw = digits < 0 ? 5 : digits + 4;
1109 rd = 2;
1110 }
1111 else if (hex_format)
1112 {
1113 fw = 2 * sizeof (double);
1114 rd = 0;
1115 }
1116 else if (bit_format)
1117 {
1118 fw = 8 * sizeof (double);
1119 rd = 0;
1120 }
1121 else if (all_ints)
1122 {
1123 int digits = x_max > x_min ? x_max : x_min;
1124 fw = digits + 1;
1125 rd = fw;
1126 }
1127 else if (Vfixed_point_format && ! print_g)
1128 {
1129 rd = prec;
1130 fw = rd + 3;
1131 }
1132 else
1133 {
1134 int ld_max, rd_max;
1135 if (x_max > 0)
1136 {
1137 ld_max = x_max;
1138 rd_max = prec > x_max ? prec - x_max : prec;
1139 x_max++;
1140 }
1141 else
1142 {
1143 ld_max = 1;
1144 rd_max = prec > x_max ? prec - x_max : prec;
1145 x_max = -x_max + 1;
1146 }
1147
1148 int ld_min, rd_min;
1149 if (x_min > 0)
1150 {
1151 ld_min = x_min;
1152 rd_min = prec > x_min ? prec - x_min : prec;
1153 x_min++;
1154 }
1155 else
1156 {
1157 ld_min = 1;
1158 rd_min = prec > x_min ? prec - x_min : prec;
1159 x_min = -x_min + 1;
1160 }
1161
1162 ld = ld_max > ld_min ? ld_max : ld_min;
1163 rd = rd_max > rd_min ? rd_max : rd_min;
1164
1165 fw = ld + rd + 3;
1166 }
1167
1168 if (! (rat_format || bank_format || hex_format || bit_format)
1169 && (print_e
1170 || print_g
1171 || (! Vfixed_point_format && fw > Voutput_max_field_width)))
1172 {
1173 if (print_g)
1174 fmt = float_format ();
1175 else
1176 {
1177 int exp_field = 4;
1178 if (x_max > 100 || x_min > 100)
1179 exp_field++;
1180
1181 fw = 3 + prec + exp_field;
1182
1183 fmt = float_format (fw, prec - 1, std::ios::scientific);
1184 }
1185
1186 if (print_big_e)
1187 fmt.uppercase ();
1188 }
1189 else if (! bank_format && all_ints)
1190 fmt = float_format (fw, rd);
1191 else
1192 fmt = float_format (fw, rd, std::ios::fixed);
1193
1194 curr_real_fmt = &fmt;
1195}
1196
1197static void
1198set_format (const Range& r, int& fw, double& scale)
1199{
1200 curr_real_fmt = 0;
1201 curr_imag_fmt = 0;
1202
1203 if (free_format)
1204 return;
1205
1206 double r_min = r.base ();
1207 double r_max = r.limit ();
1208
1209 if (r_max < r_min)
1210 {
1211 double tmp = r_max;
1212 r_max = r_min;
1213 r_min = tmp;
1214 }
1215
1216 bool all_ints = r.all_elements_are_ints ();
1217
1218 double max_abs = r_max < 0.0 ? -r_max : r_max;
1219 double min_abs = r_min < 0.0 ? -r_min : r_min;
1220
1221 int x_max = max_abs == 0.0
1222 ? 0 : static_cast<int> (floor (log10 (max_abs) + 1.0));
1223
1224 int x_min = min_abs == 0.0
1225 ? 0 : static_cast<int> (floor (log10 (min_abs) + 1.0));
1226
1227 scale = (x_max == 0 || all_ints) ? 1.0 : std::pow (10.0, x_max - 1);
1228
1229 set_range_format (x_max, x_min, all_ints, fw);
1230}
1231
1232static inline void
1233set_format (const Range& r)
1234{
1235 int fw;
1236 double scale;
1237 set_format (r, fw, scale);
1238}
1239
1240union equiv
1241{
1242 double d;
1243 unsigned char i[sizeof (double)];
1244};
1245
1246#define PRINT_CHAR_BITS(os, c) \
1247 do \
1248 { \
1249 unsigned char ctmp = c; \
1250 char stmp[9]; \
1251 stmp[0] = (ctmp & 0x80) ? '1' : '0'; \
1252 stmp[1] = (ctmp & 0x40) ? '1' : '0'; \
1253 stmp[2] = (ctmp & 0x20) ? '1' : '0'; \
1254 stmp[3] = (ctmp & 0x10) ? '1' : '0'; \
1255 stmp[4] = (ctmp & 0x08) ? '1' : '0'; \
1256 stmp[5] = (ctmp & 0x04) ? '1' : '0'; \
1257 stmp[6] = (ctmp & 0x02) ? '1' : '0'; \
1258 stmp[7] = (ctmp & 0x01) ? '1' : '0'; \
1259 stmp[8] = '\0'; \
1260 os << stmp; \
1261 } \
1262 while (0)
1263
1264#define PRINT_CHAR_BITS_SWAPPED(os, c) \
1265 do \
1266 { \
1267 unsigned char ctmp = c; \
1268 char stmp[9]; \
1269 stmp[0] = (ctmp & 0x01) ? '1' : '0'; \
1270 stmp[1] = (ctmp & 0x02) ? '1' : '0'; \
1271 stmp[2] = (ctmp & 0x04) ? '1' : '0'; \
1272 stmp[3] = (ctmp & 0x08) ? '1' : '0'; \
1273 stmp[4] = (ctmp & 0x10) ? '1' : '0'; \
1274 stmp[5] = (ctmp & 0x20) ? '1' : '0'; \
1275 stmp[6] = (ctmp & 0x40) ? '1' : '0'; \
1276 stmp[7] = (ctmp & 0x80) ? '1' : '0'; \
1277 stmp[8] = '\0'; \
1278 os << stmp; \
1279 } \
1280 while (0)
1281
1282static void
1283pr_any_float (const float_format *fmt, std::ostream& os, double d, int fw = 0)
1284{
1285 if (fmt)
1286 {
1287 // Unless explicitly asked for, always print in big-endian
1288 // format for hex and bit formats.
1289 //
1290 // {bit,hex}_format == 1: print big-endian
1291 // {bit,hex}_format == 2: print native
1292
1293 if (hex_format)
1294 {
1295 equiv tmp;
1296 tmp.d = d;
1297
1298 // Unless explicitly asked for, always print in big-endian
1299 // format.
1300
1301 // FIXME -- is it correct to swap bytes for VAX
1302 // formats and not for Cray?
1303
1304 // FIXME -- will bad things happen if we are
1305 // interrupted before resetting the format flags and fill
1306 // character?
1307
1308 oct_mach_info::float_format flt_fmt =
1309 oct_mach_info::native_float_format ();
1310
1311 char ofill = os.fill ('0');
1312
1313 std::ios::fmtflags oflags
1314 = os.flags (std::ios::right | std::ios::hex);
1315
1316 if (hex_format > 1
1317 || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
1318 || flt_fmt == oct_mach_info::flt_fmt_cray
1319 || flt_fmt == oct_mach_info::flt_fmt_unknown)
1320 {
1321 for (size_t i = 0; i < sizeof (double); i++)
1322 os << std::setw (2) << static_cast<int> (tmp.i[i]);
1323 }
1324 else
1325 {
1326 for (int i = sizeof (double) - 1; i >= 0; i--)
1327 os << std::setw (2) << static_cast<int> (tmp.i[i]);
1328 }
1329
1330 os.fill (ofill);
1331 os.setf (oflags);
1332 }
1333 else if (bit_format)
1334 {
1335 equiv tmp;
1336 tmp.d = d;
1337
1338 // FIXME -- is it correct to swap bytes for VAX
1339 // formats and not for Cray?
1340
1341 oct_mach_info::float_format flt_fmt =
1342 oct_mach_info::native_float_format ();
1343
1344 if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
1345 || flt_fmt == oct_mach_info::flt_fmt_cray
1346 || flt_fmt == oct_mach_info::flt_fmt_unknown)
1347 {
1348 for (size_t i = 0; i < sizeof (double); i++)
1349 PRINT_CHAR_BITS (os, tmp.i[i]);
1350 }
1351 else
1352 {
1353 if (bit_format > 1)
1354 {
1355 for (size_t i = 0; i < sizeof (double); i++)
1356 PRINT_CHAR_BITS_SWAPPED (os, tmp.i[i]);
1357 }
1358 else
1359 {
1360 for (int i = sizeof (double) - 1; i >= 0; i--)
1361 PRINT_CHAR_BITS (os, tmp.i[i]);
1362 }
1363 }
1364 }
1365 else if (octave_is_NA (d))
1366 {
1367 if (fw > 0)
1368 os << std::setw (fw) << "NA";
1369 else
1370 os << "NA";
1371 }
1372 else if (rat_format)
1373 os << pr_rational_float (*fmt, d);
1374 else if (xisinf (d))
1375 {
1376 const char *s;
1377 if (d < 0.0)
1378 s = "-Inf";
1379 else
1380 s = "Inf";
1381
1382 if (fw > 0)
1383 os << std::setw (fw) << s;
1384 else
1385 os << s;
1386 }
1387 else if (xisnan (d))
1388 {
1389 if (fw > 0)
1390 os << std::setw (fw) << "NaN";
1391 else
1392 os << "NaN";
1393 }
1394 else
1395 os << pr_formatted_float (*fmt, d);
1396 }
1397 else
1398 os << d;
1399}
1400
1401static inline void
1402pr_float (std::ostream& os, double d, int fw = 0, double scale = 1.0)
1403{
1404 if (Vfixed_point_format && ! print_g && scale != 1.0)
1405 d /= scale;
1406
1407 pr_any_float (curr_real_fmt, os, d, fw);
1408}
1409
1410static inline void
1411pr_imag_float (std::ostream& os, double d, int fw = 0)
1412{
1413 pr_any_float (curr_imag_fmt, os, d, fw);
1414}
1415
1416static void
1417pr_complex (std::ostream& os, const Complex& c, int r_fw = 0,
1418 int i_fw = 0, double scale = 1.0)
1419{
1420 Complex tmp
1421 = (Vfixed_point_format && ! print_g && scale != 1.0) ? c / scale : c;
1422
1423 double r = tmp.real ();
1424
1425 pr_float (os, r, r_fw);
1426
1427 if (! bank_format)
1428 {
1429 double i = tmp.imag ();
1430 if (! (hex_format || bit_format) && lo_ieee_signbit (i))
1431 {
1432 os << " - ";
1433 i = -i;
1434 pr_imag_float (os, i, i_fw);
1435 }
1436 else
1437 {
1438 if (hex_format || bit_format)
1439 os << " ";
1440 else
1441 os << " + ";
1442
1443 pr_imag_float (os, i, i_fw);
1444 }
1445 os << "i";
1446 }
1447}
1448
1449static void
1450print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc, bool pr_as_read_syntax)
1451{
1452 assert (nr == 0 || nc == 0);
1453
1454 if (pr_as_read_syntax)
1455 {
1456 if (nr == 0 && nc == 0)
1457 os << "[]";
1458 else
1459 os << "zeros (" << nr << ", " << nc << ")";
1460 }
1461 else
1462 {
1463 os << "[]";
1464
1465 if (Vprint_empty_dimensions)
1466 os << "(" << nr << "x" << nc << ")";
1467 }
1468}
1469
1470static void
1471print_empty_nd_array (std::ostream& os, const dim_vector& dims,
1472 bool pr_as_read_syntax)
1473{
1474 assert (dims.any_zero ());
1475
1476 if (pr_as_read_syntax)
1477 os << "zeros (" << dims.str (',') << ")";
1478 else
1479 {
1480 os << "[]";
1481
1482 if (Vprint_empty_dimensions)
1483 os << "(" << dims.str () << ")";
1484 }
1485}
1486
1487static void
1488pr_scale_header (std::ostream& os, double scale)
1489{
1490 if (Vfixed_point_format && ! print_g && scale != 1.0)
1491 {
1492 os << " "
1493 << std::setw (8) << std::setprecision (1)
1494 << std::setiosflags (std::ios::scientific|std::ios::left)
1495 << scale
1496 << std::resetiosflags (std::ios::scientific|std::ios::left)
1497 << " *\n";
1498
1499 if (! compact_format)
1500 os << "\n";
1501 }
1502}
1503
1504static void
1505pr_col_num_header (std::ostream& os, octave_idx_type total_width, int max_width,
1506 octave_idx_type lim, octave_idx_type col, int extra_indent)
1507{
1508 if (total_width > max_width && Vsplit_long_rows)
1509 {
1510 if (col != 0)
1511 {
1512 if (compact_format)
1513 os << "\n";
1514 else
1515 os << "\n\n";
1516 }
1517
1518 octave_idx_type num_cols = lim - col;
1519
1520 os << std::setw (extra_indent) << "";
1521
1522 if (num_cols == 1)
1523 os << " Column " << col + 1 << ":\n";
1524 else if (num_cols == 2)
1525 os << " Columns " << col + 1 << " and " << lim << ":\n";
1526 else
1527 os << " Columns " << col + 1 << " through " << lim << ":\n";
1528
1529 if (! compact_format)
1530 os << "\n";
1531 }
1532}
1533
1534template <class T>
1535/* static */ inline void
1536pr_plus_format (std::ostream& os, const T& val)
1537{
1538 if (val > T (0))
1539 os << plus_format_chars[0];
1540 else if (val < T (0))
1541 os << plus_format_chars[1];
1542 else
1543 os << plus_format_chars[2];
1544}
1545
1546void
1547octave_print_internal (std::ostream& os, double d,
1548 bool /* pr_as_read_syntax */)
1549{
1550 if (plus_format)
1551 {
1552 pr_plus_format (os, d);
1553 }
1554 else
1555 {
1556 set_format (d);
1557 if (free_format)
1558 os << d;
1559 else
1560 pr_float (os, d);
1561 }
1562}
1563
1564void
1565octave_print_internal (std::ostream& os, const Matrix& m,
1566 bool pr_as_read_syntax, int extra_indent)
1567{
1568 octave_idx_type nr = m.rows ();
1569 octave_idx_type nc = m.columns ();
1570
1571 if (nr == 0 || nc == 0)
1572 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
1573 else if (plus_format && ! pr_as_read_syntax)
1574 {
1575 for (octave_idx_type i = 0; i < nr; i++)
1576 {
1577 for (octave_idx_type j = 0; j < nc; j++)
1578 {
1579 octave_quit ();
1580
1581 pr_plus_format (os, m(i,j));
1582 }
1583
1584 if (i < nr - 1)
1585 os << "\n";
1586 }
1587 }
1588 else
1589 {
1590 int fw;
1591 double scale = 1.0;
1592 set_format (m, fw, scale);
1593 int column_width = fw + 2;
1594 octave_idx_type total_width = nc * column_width;
1595 octave_idx_type max_width = command_editor::terminal_cols ();
1596
1597 if (pr_as_read_syntax)
1598 max_width -= 4;
1599 else
1600 max_width -= extra_indent;
1601
1602 if (max_width < 0)
1603 max_width = 0;
1604
1605 if (free_format)
1606 {
1607 if (pr_as_read_syntax)
1608 os << "[\n";
1609
1610 os << m;
1611
1612 if (pr_as_read_syntax)
1613 os << "]";
1614
1615 return;
1616 }
1617
1618 octave_idx_type inc = nc;
1619 if (total_width > max_width && Vsplit_long_rows)
1620 {
1621 inc = max_width / column_width;
1622 if (inc == 0)
1623 inc++;
1624 }
1625
1626 if (pr_as_read_syntax)
1627 {
1628 for (octave_idx_type i = 0; i < nr; i++)
1629 {
1630 octave_idx_type col = 0;
1631 while (col < nc)
1632 {
1633 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1634
1635 for (octave_idx_type j = col; j < lim; j++)
1636 {
1637 octave_quit ();
1638
1639 if (i == 0 && j == 0)
1640 os << "[ ";
1641 else
1642 {
1643 if (j > col && j < lim)
1644 os << ", ";
1645 else
1646 os << " ";
1647 }
1648
1649 pr_float (os, m(i,j));
1650 }
1651
1652 col += inc;
1653
1654 if (col >= nc)
1655 {
1656 if (i == nr - 1)
1657 os << " ]";
1658 else
1659 os << ";\n";
1660 }
1661 else
1662 os << " ...\n";
1663 }
1664 }
1665 }
1666 else
1667 {
1668 pr_scale_header (os, scale);
1669
1670 for (octave_idx_type col = 0; col < nc; col += inc)
1671 {
1672 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1673
1674 pr_col_num_header (os, total_width, max_width, lim, col,
1675 extra_indent);
1676
1677 for (octave_idx_type i = 0; i < nr; i++)
1678 {
1679 os << std::setw (extra_indent) << "";
1680
1681 for (octave_idx_type j = col; j < lim; j++)
1682 {
1683 octave_quit ();
1684
1685 os << " ";
1686
1687 pr_float (os, m(i,j), fw, scale);
1688 }
1689
1690 if (i < nr - 1)
1691 os << "\n";
1692 }
1693 }
1694 }
1695 }
1696}
1697
1698void
1699octave_print_internal (std::ostream& os, const DiagMatrix& m,
1700 bool pr_as_read_syntax, int extra_indent)
1701{
1702 octave_idx_type nr = m.rows ();
1703 octave_idx_type nc = m.columns ();
1704
1705 if (nr == 0 || nc == 0)
1706 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
1707 else if (plus_format && ! pr_as_read_syntax)
1708 {
1709 for (octave_idx_type i = 0; i < nr; i++)
1710 {
1711 for (octave_idx_type j = 0; j < nc; j++)
1712 {
1713 octave_quit ();
1714
1715 pr_plus_format (os, m(i,j));
1716 }
1717
1718 if (i < nr - 1)
1719 os << "\n";
1720 }
1721 }
1722 else
1723 {
1724 int fw;
1725 double scale = 1.0;
1726 set_format (Matrix (m.diag ()), fw, scale);
1727 int column_width = fw + 2;
1728 octave_idx_type total_width = nc * column_width;
1729 octave_idx_type max_width = command_editor::terminal_cols ();
1730
1731 if (pr_as_read_syntax)
1732 max_width -= 4;
1733 else
1734 max_width -= extra_indent;
1735
1736 if (max_width < 0)
1737 max_width = 0;
1738
1739 if (free_format)
1740 {
1741 if (pr_as_read_syntax)
1742 os << "[\n";
1743
1744 os << Matrix (m);
1745
1746 if (pr_as_read_syntax)
1747 os << "]";
1748
1749 return;
1750 }
1751
1752 octave_idx_type inc = nc;
1753 if (total_width > max_width && Vsplit_long_rows)
1754 {
1755 inc = max_width / column_width;
1756 if (inc == 0)
1757 inc++;
1758 }
1759
1760 if (pr_as_read_syntax)
1761 {
1762 os << "diag (";
1763
1764 octave_idx_type col = 0;
1765 while (col < nc)
1766 {
1767 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1768
1769 for (octave_idx_type j = col; j < lim; j++)
1770 {
1771 octave_quit ();
1772
1773 if (j == 0)
1774 os << "[ ";
1775 else
1776 {
1777 if (j > col && j < lim)
1778 os << ", ";
1779 else
1780 os << " ";
1781 }
1782
1783 pr_float (os, m(j,j));
1784 }
1785
1786 col += inc;
1787
1788 if (col >= nc)
1789 os << " ]";
1790 else
1791 os << " ...\n";
1792 }
1793 os << ")";
1794 }
1795 else
1796 {
1797 os << "Diagonal Matrix\n\n";
1798 pr_scale_header (os, scale);
1799
1800 // kluge. Get the true width of a number.
1801 int zero_fw;
1802
1803 {
1804 std::ostringstream tmp_oss;
1805 pr_float (tmp_oss, 0.0, fw, scale);
1806 zero_fw = tmp_oss.str ().length ();
1807 }
1808
1809 for (octave_idx_type col = 0; col < nc; col += inc)
1810 {
1811 octave_idx_type lim = col + inc < nc ? col + inc : nc;
1812
1813 pr_col_num_header (os, total_width, max_width, lim, col,
1814 extra_indent);
1815
1816 for (octave_idx_type i = 0; i < nr; i++)
1817 {
1818 os << std::setw (extra_indent) << "";
1819
1820 for (octave_idx_type j = col; j < lim; j++)
1821 {
1822 octave_quit ();
1823
1824 os << " ";
1825
1826 if (i == j)
1827 pr_float (os, m(i,j), fw, scale);
1828 else
1829 os << std::setw (zero_fw) << '0';
1830
1831 }
1832
1833 if (i < nr - 1)
1834 os << "\n";
1835 }
1836 }
1837 }
1838 }
1839}
1840#define PRINT_ND_ARRAY(os, nda, NDA_T, ELT_T, MAT_T) \
1841 do \
1842 { \
1843 if (nda.is_empty ()) \
1844 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax); \
1845 else \
1846 { \
1847 \
1848 int ndims = nda.ndims (); \
1849 \
1850 dim_vector dims = nda.dims (); \
1851 \
1852 Array<octave_idx_type> ra_idx (ndims, 0); \
1853 \
1854 octave_idx_type m = 1; \
1855 \
1856 for (int i = 2; i < ndims; i++) \
1857 m *= dims(i); \
1858 \
1859 octave_idx_type nr = dims(0); \
1860 octave_idx_type nc = dims(1); \
1861 \
1862 for (octave_idx_type i = 0; i < m; i++) \
1863 { \
1864 octave_quit (); \
1865 \
1866 std::string nm = "ans"; \
1867 \
1868 if (m > 1) \
1869 { \
1870 nm += "(:,:,"; \
1871 \
1872 std::ostringstream buf; \
1873 \
1874 for (int k = 2; k < ndims; k++) \
1875 { \
1876 buf << ra_idx(k) + 1; \
1877 \
1878 if (k < ndims - 1) \
1879 buf << ","; \
1880 else \
1881 buf << ")"; \
1882 } \
1883 \
1884 nm += buf.str (); \
1885 } \
1886 \
1887 Array<idx_vector> idx (ndims); \
1888 \
1889 idx(0) = idx_vector (':'); \
1890 idx(1) = idx_vector (':'); \
1891 \
1892 for (int k = 2; k < ndims; k++) \
1893 idx(k) = idx_vector (ra_idx(k)); \
1894 \
1895 octave_value page \
1896 = MAT_T (Array2<ELT_T> (nda.index (idx), nr, nc)); \
1897 \
1898 page.print_with_name (os, nm); \
1899 \
1900 if (i < m) \
1901 NDA_T::increment_index (ra_idx, dims, 2); \
1902 } \
1903 } \
1904 } \
1905 while (0)
1906
1907void
1908octave_print_internal (std::ostream& os, const NDArray& nda,
1909 bool pr_as_read_syntax, int extra_indent)
1910{
1911 switch (nda.ndims ())
1912 {
1913 case 1:
1914 case 2:
1915 octave_print_internal (os, nda.matrix_value (),
1916 pr_as_read_syntax, extra_indent);
1917 break;
1918
1919 default:
1920 PRINT_ND_ARRAY (os, nda, NDArray, double, Matrix);
1921 break;
1922 }
1923}
1924
1925template <>
1926/* static */ inline void
1927pr_plus_format<> (std::ostream& os, const Complex& c)
1928{
1929 double rp = c.real ();
1930 double ip = c.imag ();
1931
1932 if (rp == 0.0)
1933 {
1934 if (ip == 0.0)
1935 os << " ";
1936 else
1937 os << "i";
1938 }
1939 else if (ip == 0.0)
1940 pr_plus_format (os, rp);
1941 else
1942 os << "c";
1943}
1944
1945void
1946octave_print_internal (std::ostream& os, const Complex& c,
1947 bool /* pr_as_read_syntax */)
1948{
1949 if (plus_format)
1950 {
1951 pr_plus_format (os, c);
1952 }
1953 else
1954 {
1955 set_format (c);
1956 if (free_format)
1957 os << c;
1958 else
1959 pr_complex (os, c);
1960 }
1961}
1962
1963void
1964octave_print_internal (std::ostream& os, const ComplexMatrix& cm,
1965 bool pr_as_read_syntax, int extra_indent)
1966{
1967 octave_idx_type nr = cm.rows ();
1968 octave_idx_type nc = cm.columns ();
1969
1970 if (nr == 0 || nc == 0)
1971 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
1972 else if (plus_format && ! pr_as_read_syntax)
1973 {
1974 for (octave_idx_type i = 0; i < nr; i++)
1975 {
1976 for (octave_idx_type j = 0; j < nc; j++)
1977 {
1978 octave_quit ();
1979
1980 pr_plus_format (os, cm(i,j));
1981 }
1982
1983 if (i < nr - 1)
1984 os << "\n";
1985 }
1986 }
1987 else
1988 {
1989 int r_fw, i_fw;
1990 double scale = 1.0;
1991 set_format (cm, r_fw, i_fw, scale);
1992 int column_width = i_fw + r_fw;
1993 column_width += (rat_format || bank_format || hex_format
1994 || bit_format) ? 2 : 7;
1995 octave_idx_type total_width = nc * column_width;
1996 octave_idx_type max_width = command_editor::terminal_cols ();
1997
1998 if (pr_as_read_syntax)
1999 max_width -= 4;
2000 else
2001 max_width -= extra_indent;
2002
2003 if (max_width < 0)
2004 max_width = 0;
2005
2006 if (free_format)
2007 {
2008 if (pr_as_read_syntax)
2009 os << "[\n";
2010
2011 os << cm;
2012
2013 if (pr_as_read_syntax)
2014 os << "]";
2015
2016 return;
2017 }
2018
2019 octave_idx_type inc = nc;
2020 if (total_width > max_width && Vsplit_long_rows)
2021 {
2022 inc = max_width / column_width;
2023 if (inc == 0)
2024 inc++;
2025 }
2026
2027 if (pr_as_read_syntax)
2028 {
2029 for (octave_idx_type i = 0; i < nr; i++)
2030 {
2031 octave_idx_type col = 0;
2032 while (col < nc)
2033 {
2034 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2035
2036 for (octave_idx_type j = col; j < lim; j++)
2037 {
2038 octave_quit ();
2039
2040 if (i == 0 && j == 0)
2041 os << "[ ";
2042 else
2043 {
2044 if (j > col && j < lim)
2045 os << ", ";
2046 else
2047 os << " ";
2048 }
2049
2050 pr_complex (os, cm(i,j));
2051 }
2052
2053 col += inc;
2054
2055 if (col >= nc)
2056 {
2057 if (i == nr - 1)
2058 os << " ]";
2059 else
2060 os << ";\n";
2061 }
2062 else
2063 os << " ...\n";
2064 }
2065 }
2066 }
2067 else
2068 {
2069 pr_scale_header (os, scale);
2070
2071 for (octave_idx_type col = 0; col < nc; col += inc)
2072 {
2073 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2074
2075 pr_col_num_header (os, total_width, max_width, lim, col,
2076 extra_indent);
2077
2078 for (octave_idx_type i = 0; i < nr; i++)
2079 {
2080 os << std::setw (extra_indent) << "";
2081
2082 for (octave_idx_type j = col; j < lim; j++)
2083 {
2084 octave_quit ();
2085
2086 os << " ";
2087
2088 pr_complex (os, cm(i,j), r_fw, i_fw, scale);
2089 }
2090
2091 if (i < nr - 1)
2092 os << "\n";
2093 }
2094 }
2095 }
2096 }
2097}
2098
2099void
2100octave_print_internal (std::ostream& os, const ComplexDiagMatrix& cm,
2101 bool pr_as_read_syntax, int extra_indent)
2102{
2103 octave_idx_type nr = cm.rows ();
2104 octave_idx_type nc = cm.columns ();
2105
2106 if (nr == 0 || nc == 0)
2107 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
2108 else if (plus_format && ! pr_as_read_syntax)
2109 {
2110 for (octave_idx_type i = 0; i < nr; i++)
2111 {
2112 for (octave_idx_type j = 0; j < nc; j++)
2113 {
2114 octave_quit ();
2115
2116 pr_plus_format (os, cm(i,j));
2117 }
2118
2119 if (i < nr - 1)
2120 os << "\n";
2121 }
2122 }
2123 else
2124 {
2125 int r_fw, i_fw;
2126 double scale = 1.0;
2127 set_format (ComplexMatrix (cm.diag ()), r_fw, i_fw, scale);
2128 int column_width = i_fw + r_fw;
2129 column_width += (rat_format || bank_format || hex_format
2130 || bit_format) ? 2 : 7;
2131 octave_idx_type total_width = nc * column_width;
2132 octave_idx_type max_width = command_editor::terminal_cols ();
2133
2134 if (pr_as_read_syntax)
2135 max_width -= 4;
2136 else
2137 max_width -= extra_indent;
2138
2139 if (max_width < 0)
2140 max_width = 0;
2141
2142 if (free_format)
2143 {
2144 if (pr_as_read_syntax)
2145 os << "[\n";
2146
2147 os << ComplexMatrix (cm);
2148
2149 if (pr_as_read_syntax)
2150 os << "]";
2151
2152 return;
2153 }
2154
2155 octave_idx_type inc = nc;
2156 if (total_width > max_width && Vsplit_long_rows)
2157 {
2158 inc = max_width / column_width;
2159 if (inc == 0)
2160 inc++;
2161 }
2162
2163 if (pr_as_read_syntax)
2164 {
2165 os << "diag (";
2166
2167 octave_idx_type col = 0;
2168 while (col < nc)
2169 {
2170 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2171
2172 for (octave_idx_type j = col; j < lim; j++)
2173 {
2174 octave_quit ();
2175
2176 if (j == 0)
2177 os << "[ ";
2178 else
2179 {
2180 if (j > col && j < lim)
2181 os << ", ";
2182 else
2183 os << " ";
2184 }
2185
2186 pr_complex (os, cm(j,j));
2187 }
2188
2189 col += inc;
2190
2191 if (col >= nc)
2192 os << " ]";
2193 else
2194 os << " ...\n";
2195 }
2196 os << ")";
2197 }
2198 else
2199 {
2200 os << "Diagonal Matrix\n\n";
2201 pr_scale_header (os, scale);
2202
2203 // kluge. Get the true width of a number.
2204 int zero_fw;
2205
2206 {
2207 std::ostringstream tmp_oss;
2208 pr_complex (tmp_oss, Complex (0.0), r_fw, i_fw, scale);
2209 zero_fw = tmp_oss.str ().length ();
2210 }
2211
2212 for (octave_idx_type col = 0; col < nc; col += inc)
2213 {
2214 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2215
2216 pr_col_num_header (os, total_width, max_width, lim, col,
2217 extra_indent);
2218
2219 for (octave_idx_type i = 0; i < nr; i++)
2220 {
2221 os << std::setw (extra_indent) << "";
2222
2223 for (octave_idx_type j = col; j < lim; j++)
2224 {
2225 octave_quit ();
2226
2227 os << " ";
2228
2229 if (i == j)
2230 pr_complex (os, cm(i,j), r_fw, i_fw, scale);
2231 else
2232 os << std::setw (zero_fw) << '0';
2233 }
2234
2235 if (i < nr - 1)
2236 os << "\n";
2237 }
2238 }
2239 }
2240 }
2241}
2242
2243void
2244octave_print_internal (std::ostream& os, const PermMatrix& m,
2245 bool pr_as_read_syntax, int extra_indent)
2246{
2247 octave_idx_type nr = m.rows ();
2248 octave_idx_type nc = m.columns ();
2249
2250 if (nr == 0 || nc == 0)
2251 print_empty_matrix (os, nr, nc, pr_as_read_syntax);
2252 else if (plus_format && ! pr_as_read_syntax)
2253 {
2254 for (octave_idx_type i = 0; i < nr; i++)
2255 {
2256 for (octave_idx_type j = 0; j < nc; j++)
2257 {
2258 octave_quit ();
2259
2260 pr_plus_format (os, m(i,j));
2261 }
2262
2263 if (i < nr - 1)
2264 os << "\n";
2265 }
2266 }
2267 else
2268 {
2269 int fw = 2;
2270 int column_width = fw + 2;
2271 octave_idx_type total_width = nc * column_width;
2272 octave_idx_type max_width = command_editor::terminal_cols ();
2273
2274 if (pr_as_read_syntax)
2275 max_width -= 4;
2276 else
2277 max_width -= extra_indent;
2278
2279 if (max_width < 0)
2280 max_width = 0;
2281
2282 if (free_format)
2283 {
2284 if (pr_as_read_syntax)
2285 os << "[\n";
2286
2287 os << Matrix (m);
2288
2289 if (pr_as_read_syntax)
2290 os << "]";
2291
2292 return;
2293 }
2294
2295 octave_idx_type inc = nc;
2296 if (total_width > max_width && Vsplit_long_rows)
2297 {
2298 inc = max_width / column_width;
2299 if (inc == 0)
2300 inc++;
2301 }
2302
2303 if (pr_as_read_syntax)
2304 {
2305 Array<octave_idx_type> pvec = m.pvec ();
2306 bool colp = m.is_col_perm ();
2307
2308 os << "eye (";
2309 if (colp) os << ":, ";
2310
2311 octave_idx_type col = 0;
2312 while (col < nc)
2313 {
2314 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2315
2316 for (octave_idx_type j = col; j < lim; j++)
2317 {
2318 octave_quit ();
2319
2320 if (j == 0)
2321 os << "[ ";
2322 else
2323 {
2324 if (j > col && j < lim)
2325 os << ", ";
2326 else
2327 os << " ";
2328 }
2329
2330 os << pvec (j);
2331 }
2332
2333 col += inc;
2334
2335 if (col >= nc)
2336 os << " ]";
2337 else
2338 os << " ...\n";
2339 }
2340 if (! colp) os << ", :";
2341 os << ")";
2342 }
2343 else
2344 {
2345 os << "Permutation Matrix\n\n";
2346
2347 for (octave_idx_type col = 0; col < nc; col += inc)
2348 {
2349 octave_idx_type lim = col + inc < nc ? col + inc : nc;
2350
2351 pr_col_num_header (os, total_width, max_width, lim, col,
2352 extra_indent);
2353
2354 for (octave_idx_type i = 0; i < nr; i++)
2355 {
2356 os << std::setw (extra_indent) << "";
2357
2358 for (octave_idx_type j = col; j < lim; j++)
2359 {
2360 octave_quit ();
2361
2362 os << " ";
2363
2364 os << std::setw (fw) << m(i,j);
2365 }
2366
2367 if (i < nr - 1)
2368 os << "\n";
2369 }
2370 }
2371 }
2372 }
2373}
2374
2375void
2376octave_print_internal (std::ostream& os, const ComplexNDArray& nda,
2377 bool pr_as_read_syntax, int extra_indent)
2378{
2379 switch (nda.ndims ())
2380 {
2381 case 1:
2382 case 2:
2383 octave_print_internal (os, nda.matrix_value (),
2384 pr_as_read_syntax, extra_indent);
2385 break;
2386
2387 default:
2388 PRINT_ND_ARRAY (os, nda, ComplexNDArray, Complex, ComplexMatrix);
2389 break;
2390 }
2391}
2392
2393void
2394octave_print_internal (std::ostream& os, bool d, bool pr_as_read_syntax)
2395{
2396 octave_print_internal (os, double (d), pr_as_read_syntax);
2397}
2398
2399// FIXME -- write single precision versions of the printing functions.
2400
2401void
2402octave_print_internal (std::ostream& os, float d, bool pr_as_read_syntax)
2403{
2404 octave_print_internal (os, double (d), pr_as_read_syntax);
2405}
2406
2407void
2408octave_print_internal (std::ostream& os, const FloatMatrix& m,
2409 bool pr_as_read_syntax, int extra_indent)
2410{
2411 octave_print_internal (os, Matrix (m), pr_as_read_syntax, extra_indent);
2412}
2413
2414void
2415octave_print_internal (std::ostream& os, const FloatDiagMatrix& m,
2416 bool pr_as_read_syntax, int extra_indent)
2417{
2418 octave_print_internal (os, DiagMatrix (m), pr_as_read_syntax, extra_indent);
2419}
2420
2421void
2422octave_print_internal (std::ostream& os, const FloatNDArray& nda,
2423 bool pr_as_read_syntax, int extra_indent)
2424{
2425 octave_print_internal (os, NDArray (nda), pr_as_read_syntax, extra_indent);
2426}
2427
2428void
2429octave_print_internal (std::ostream& os, const FloatComplex& c,
2430 bool pr_as_read_syntax)
2431{
2432 octave_print_internal (os, Complex (c), pr_as_read_syntax);
2433}
2434
2435void
2436octave_print_internal (std::ostream& os, const FloatComplexMatrix& cm,
2437 bool pr_as_read_syntax, int extra_indent)
2438{
2439 octave_print_internal (os, ComplexMatrix (cm), pr_as_read_syntax, extra_indent);
2440}
2441
2442void
2443octave_print_internal (std::ostream& os, const FloatComplexDiagMatrix& cm,
2444 bool pr_as_read_syntax, int extra_indent)
2445{
2446 octave_print_internal (os, ComplexDiagMatrix (cm), pr_as_read_syntax, extra_indent);
2447}
2448
2449void
2450octave_print_internal (std::ostream& os, const FloatComplexNDArray& nda,
2451 bool pr_as_read_syntax, int extra_indent)
2452{
2453 octave_print_internal (os, ComplexNDArray (nda), pr_as_read_syntax, extra_indent);
2454}
2455
2456void
2457octave_print_internal (std::ostream& os, const Range& r,
2458 bool pr_as_read_syntax, int extra_indent)
2459{
2460 double base = r.base ();
2461 double increment = r.inc ();
2462 double limit = r.limit ();
2463 octave_idx_type num_elem = r.nelem ();
2464
2465 if (plus_format && ! pr_as_read_syntax)
2466 {
2467 for (octave_idx_type i = 0; i < num_elem; i++)
2468 {
2469 octave_quit ();
2470
2471 double val = base + i * increment;
2472
2473 pr_plus_format (os, val);
2474 }
2475 }
2476 else
2477 {
2478 int fw;
2479 double scale = 1.0;
2480 set_format (r, fw, scale);
2481
2482 if (pr_as_read_syntax)
2483 {
2484 if (free_format)
2485 {
2486 os << base << " : ";
2487 if (increment != 1.0)
2488 os << increment << " : ";
2489 os << limit;
2490 }
2491 else
2492 {
2493 pr_float (os, base, fw);
2494 os << " : ";
2495 if (increment != 1.0)
2496 {
2497 pr_float (os, increment, fw);
2498 os << " : ";
2499 }
2500 pr_float (os, limit, fw);
2501 }
2502 }
2503 else
2504 {
2505 int column_width = fw + 2;
2506 octave_idx_type total_width = num_elem * column_width;
2507 octave_idx_type max_width = command_editor::terminal_cols ();
2508
2509 if (free_format)
2510 {
2511 os << r;
2512 return;
2513 }
2514
2515 octave_idx_type inc = num_elem;
2516 if (total_width > max_width && Vsplit_long_rows)
2517 {
2518 inc = max_width / column_width;
2519 if (inc == 0)
2520 inc++;
2521 }
2522
2523 max_width -= extra_indent;
2524
2525 if (max_width < 0)
2526 max_width = 0;
2527
2528 pr_scale_header (os, scale);
2529
2530 octave_idx_type col = 0;
2531 while (col < num_elem)
2532 {
2533 octave_idx_type lim = col + inc < num_elem ? col + inc : num_elem;
2534
2535 pr_col_num_header (os, total_width, max_width, lim, col,
2536 extra_indent);
2537
2538 os << std::setw (extra_indent) << "";
2539
2540 for (octave_idx_type i = col; i < lim; i++)
2541 {
2542 octave_quit ();
2543
2544 double val = base + i * increment;
2545
2546 if (i == num_elem - 1)
2547 {
2548 // See the comments in Range::matrix_value.
2549
2550 if ((increment > 0 && val > limit)
2551 || (increment < 0 && val < limit))
2552 val = limit;
2553 }
2554
2555 os << " ";
2556
2557 pr_float (os, val, fw, scale);
2558 }
2559
2560 col += inc;
2561 }
2562 }
2563 }
2564}
2565
2566void
2567octave_print_internal (std::ostream& os, const boolMatrix& bm,
2568 bool pr_as_read_syntax,
2569 int extra_indent)
2570{
2571 Matrix tmp (bm);
2572 octave_print_internal (os, tmp, pr_as_read_syntax, extra_indent);
2573}
2574
2575void
2576octave_print_internal (std::ostream& os, const boolNDArray& nda,
2577 bool pr_as_read_syntax,
2578 int extra_indent)
2579{
2580 switch (nda.ndims ())
2581 {
2582 case 1:
2583 case 2:
2584 octave_print_internal (os, nda.matrix_value (),
2585 pr_as_read_syntax, extra_indent);
2586 break;
2587
2588 default:
2589 PRINT_ND_ARRAY (os, nda, boolNDArray, bool, boolMatrix);
2590 break;
2591 }
2592}
2593
2594void
2595octave_print_internal (std::ostream& os, const charMatrix& chm,
2596 bool pr_as_read_syntax,
2597 int /* extra_indent FIXME */,
2598 bool pr_as_string)
2599{
2600 if (pr_as_string)
2601 {
2602 octave_idx_type nstr = chm.rows ();
2603
2604 if (pr_as_read_syntax && nstr > 1)
2605 os << "[ ";
2606
2607 if (nstr != 0)
2608 {
2609 for (octave_idx_type i = 0; i < nstr; i++)
2610 {
2611 octave_quit ();
2612
2613 std::string row = chm.row_as_string (i);
2614
2615 if (pr_as_read_syntax)
2616 {
2617 os << "\"" << undo_string_escapes (row) << "\"";
2618
2619 if (i < nstr - 1)
2620 os << "; ";
2621 }
2622 else
2623 {
2624 os << row;
2625
2626 if (i < nstr - 1)
2627 os << "\n";
2628 }
2629 }
2630 }
2631
2632 if (pr_as_read_syntax && nstr > 1)
2633 os << " ]";
2634 }
2635 else
2636 {
2637 os << "sorry, printing char matrices not implemented yet\n";
2638 }
2639}
2640
2641void
2642octave_print_internal (std::ostream& os, const charNDArray& nda,
2643 bool pr_as_read_syntax, int extra_indent,
2644 bool pr_as_string)
2645{
2646 switch (nda.ndims ())
2647 {
2648 case 1:
2649 case 2:
2650 octave_print_internal (os, nda.matrix_value (),
2651 pr_as_read_syntax, extra_indent, pr_as_string);
2652 break;
2653
2654 default:
2655 PRINT_ND_ARRAY (os, nda, charNDArray, char, charMatrix);
2656 break;
2657 }
2658}
2659
2660void
2661octave_print_internal (std::ostream& os, const std::string& s,
2662 bool pr_as_read_syntax, int extra_indent)
2663{
2664 Array<std::string> nda (dim_vector (1, 1), s);
2665
2666 octave_print_internal (os, nda, pr_as_read_syntax, extra_indent);
2667}
2668
2669void
2670octave_print_internal (std::ostream& os, const Array<std::string>& nda,
2671 bool pr_as_read_syntax, int /* extra_indent */)
2672{
2673 // FIXME -- this mostly duplicates the code in the
2674 // PRINT_ND_ARRAY macro.
2675
2676 if (nda.is_empty ())
2677 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
2678 else if (nda.length () == 1)
2679 {
2680 os << nda(0);
2681 }
2682 else
2683 {
2684 int ndims = nda.ndims ();
2685
2686 dim_vector dims = nda.dims ();
2687
2688 Array<octave_idx_type> ra_idx (ndims, 0);
2689
2690 octave_idx_type m = 1;
2691
2692 for (int i = 2; i < ndims; i++)
2693 m *= dims(i);
2694
2695 octave_idx_type nr = dims(0);
2696 octave_idx_type nc = dims(1);
2697
2698 for (octave_idx_type i = 0; i < m; i++)
2699 {
2700 std::string nm = "ans";
2701
2702 if (m > 1)
2703 {
2704 nm += "(:,:,";
2705
2706 std::ostringstream buf;
2707
2708 for (int k = 2; k < ndims; k++)
2709 {
2710 buf << ra_idx(k) + 1;
2711
2712 if (k < ndims - 1)
2713 buf << ",";
2714 else
2715 buf << ")";
2716 }
2717
2718 nm += buf.str ();
2719 }
2720
2721 Array<idx_vector> idx (ndims);
2722
2723 idx(0) = idx_vector (':');
2724 idx(1) = idx_vector (':');
2725
2726 for (int k = 2; k < ndims; k++)
2727 idx(k) = idx_vector (ra_idx(k));
2728
2729 Array2<std::string> page (nda.index (idx), nr, nc);
2730
2731 // FIXME -- need to do some more work to put these
2732 // in neatly aligned columns...
2733
2734 octave_idx_type n_rows = page.rows ();
2735 octave_idx_type n_cols = page.cols ();
2736
2737 os << nm << " =\n\n";
2738
2739 for (octave_idx_type ii = 0; ii < n_rows; ii++)
2740 {
2741 for (octave_idx_type jj = 0; jj < n_cols; jj++)
2742 os << " " << page(ii,jj);
2743
2744 os << "\n";
2745 }
2746
2747 if (i < m - 1)
2748 os << "\n";
2749
2750 if (i < m)
2751 increment_index (ra_idx, dims, 2);
2752 }
2753 }
2754}
2755
2756template <class T>
2757class
2758octave_print_conv
2759{
2760public:
2761 typedef T print_conv_type;
2762};
2763
2764#define PRINT_CONV(T1, T2) \
2765 template <> \
2766 class \
2767 octave_print_conv<T1> \
2768 { \
2769 public: \
2770 typedef T2 print_conv_type; \
2771 }
2772
2773PRINT_CONV (octave_int8, octave_int16);
2774PRINT_CONV (octave_uint8, octave_uint16);
2775
2776#undef PRINT_CONV
2777
2778template <class T>
2779/* static */ inline void
2780pr_int (std::ostream& os, const T& d, int fw = 0)
2781{
2782 size_t sz = d.byte_size();
2783 const unsigned char * tmpi = d.iptr();
2784
2785 // Unless explicitly asked for, always print in big-endian
2786 // format for hex and bit formats.
2787 //
2788 // {bit,hex}_format == 1: print big-endian
2789 // {bit,hex}_format == 2: print native
2790
2791 if (hex_format)
2792 {
2793 char ofill = os.fill ('0');
2794
2795 std::ios::fmtflags oflags
2796 = os.flags (std::ios::right | std::ios::hex);
2797
2798 if (hex_format > 1 || oct_mach_info::words_big_endian ())
2799 {
2800 for (size_t i = 0; i < sz; i++)
2801 os << std::setw (2) << static_cast<int> (tmpi[i]);
2802 }
2803 else
2804 {
2805 for (int i = sz - 1; i >= 0; i--)
2806 os << std::setw (2) << static_cast<int> (tmpi[i]);
2807 }
2808
2809 os.fill (ofill);
2810 os.setf (oflags);
2811 }
2812 else if (bit_format)
2813 {
2814 if (oct_mach_info::words_big_endian ())
2815 {
2816 for (size_t i = 0; i < sz; i++)
2817 PRINT_CHAR_BITS (os, tmpi[i]);
2818 }
2819 else
2820 {
2821 if (bit_format > 1)
2822 {
2823 for (size_t i = 0; i < sz; i++)
2824 PRINT_CHAR_BITS_SWAPPED (os, tmpi[i]);
2825 }
2826 else
2827 {
2828 for (int i = sz - 1; i >= 0; i--)
2829 PRINT_CHAR_BITS (os, tmpi[i]);
2830 }
2831 }
2832 }
2833 else
2834 {
2835 os << std::setw (fw)
2836 << typename octave_print_conv<T>::print_conv_type (d);
2837
2838 if (bank_format)
2839 os << ".00";
2840 }
2841}
2842
2843// FIXME -- all this mess with abs is an attempt to avoid seeing
2844//
2845// warning: comparison of unsigned expression < 0 is always false
2846//
2847// from GCC. Isn't there a better way
2848
2849template <class T>
2850/* static */ inline T
2851abs (T x)
2852{
2853 return x < 0 ? -x : x;
2854}
2855
2856#define INSTANTIATE_ABS(T) \
2857 template /* static */ inline T abs (T)
2858
2859INSTANTIATE_ABS(signed char);
2860INSTANTIATE_ABS(short);
2861INSTANTIATE_ABS(int);
2862INSTANTIATE_ABS(long);
2863INSTANTIATE_ABS(long long);
2864
2865#define SPECIALIZE_UABS(T) \
2866 template <> \
2867 /* static */ inline unsigned T \
2868 abs (unsigned T x) \
2869 { \
2870 return x; \
2871 }
2872
2873SPECIALIZE_UABS(char)
2874SPECIALIZE_UABS(short)
2875SPECIALIZE_UABS(int)
2876SPECIALIZE_UABS(long)
2877SPECIALIZE_UABS(long long)
2878
2879template void
2880pr_int (std::ostream&, const octave_int8&, int);
2881
2882template void
2883pr_int (std::ostream&, const octave_int16&, int);
2884
2885template void
2886pr_int (std::ostream&, const octave_int32&, int);
2887
2888template void
2889pr_int (std::ostream&, const octave_int64&, int);
2890
2891template void
2892pr_int (std::ostream&, const octave_uint8&, int);
2893
2894template void
2895pr_int (std::ostream&, const octave_uint16&, int);
2896
2897template void
2898pr_int (std::ostream&, const octave_uint32&, int);
2899
2900template void
2901pr_int (std::ostream&, const octave_uint64&, int);
2902
2903template <class T>
2904void
2905octave_print_internal_template (std::ostream& os, const octave_int<T>& val,
2906 bool)
2907{
2908 if (plus_format)
2909 {
2910 pr_plus_format (os, val);
2911 }
2912 else
2913 {
2914 if (free_format)
2915 os << typename octave_print_conv<octave_int<T> >::print_conv_type (val);
2916 else
2917 pr_int (os, val);
2918 }
2919}
2920
2921#define PRINT_INT_SCALAR_INTERNAL(TYPE) \
2922 OCTINTERP_API void \
2923 octave_print_internal (std::ostream& os, const octave_int<TYPE>& val, bool dummy) \
2924 { \
2925 octave_print_internal_template (os, val, dummy); \
2926 }
2927
2928PRINT_INT_SCALAR_INTERNAL (int8_t)
2929PRINT_INT_SCALAR_INTERNAL (uint8_t)
2930PRINT_INT_SCALAR_INTERNAL (int16_t)
2931PRINT_INT_SCALAR_INTERNAL (uint16_t)
2932PRINT_INT_SCALAR_INTERNAL (int32_t)
2933PRINT_INT_SCALAR_INTERNAL (uint32_t)
2934PRINT_INT_SCALAR_INTERNAL (int64_t)
2935PRINT_INT_SCALAR_INTERNAL (uint64_t)
2936
2937template <class T>
2938/* static */ inline void
2939octave_print_internal_template (std::ostream& os, const intNDArray<T>& nda,
2940 bool pr_as_read_syntax, int extra_indent)
2941{
2942 // FIXME -- this mostly duplicates the code in the
2943 // PRINT_ND_ARRAY macro.
2944
2945 if (nda.is_empty ())
2946 print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
2947 else if (nda.length () == 1)
2948 octave_print_internal_template (os, nda(0), pr_as_read_syntax);
2949 else if (plus_format && ! pr_as_read_syntax)
2950 {
2951 int ndims = nda.ndims ();
2952
2953 Array<octave_idx_type> ra_idx (ndims, 0);
2954
2955 dim_vector dims = nda.dims ();
2956
2957 octave_idx_type m = 1;
2958
2959 for (int i = 2; i < ndims; i++)
2960 m *= dims(i);
2961
2962 octave_idx_type nr = dims(0);
2963 octave_idx_type nc = dims(1);
2964
2965 for (octave_idx_type i = 0; i < m; i++)
2966 {
2967 if (m > 1)
2968 {
2969 std::string nm = "ans(:,:,";
2970
2971 std::ostringstream buf;
2972
2973 for (int k = 2; k < ndims; k++)
2974 {
2975 buf << ra_idx(k) + 1;
2976
2977 if (k < ndims - 1)
2978 buf << ",";
2979 else
2980 buf << ")";
2981 }
2982
2983 nm += buf.str ();
2984
2985 os << nm << " =\n\n";
2986 }
2987
2988 Array<idx_vector> idx (ndims);
2989
2990 idx(0) = idx_vector (':');
2991 idx(1) = idx_vector (':');
2992
2993 for (int k = 2; k < ndims; k++)
2994 idx(k) = idx_vector (ra_idx(k));
2995
2996 Array2<T> page (nda.index (idx), nr, nc);
2997
2998 for (octave_idx_type ii = 0; ii < nr; ii++)
2999 {
3000 for (octave_idx_type jj = 0; jj < nc; jj++)
3001 {
3002 octave_quit ();
3003
3004 pr_plus_format (os, page(ii,jj));
3005 }
3006
3007 if ((ii < nr - 1) || (i < m -1))
3008 os << "\n";
3009 }
3010
3011 if (i < m - 1)
3012 {
3013 os << "\n";
3014 increment_index (ra_idx, dims, 2);
3015 }
3016 }
3017 }
3018 else
3019 {
3020 int ndims = nda.ndims ();
3021
3022 dim_vector dims = nda.dims ();
3023
3024 Array<octave_idx_type> ra_idx (ndims, 0);
3025
3026 octave_idx_type m = 1;
3027
3028 for (int i = 2; i < ndims; i++)
3029 m *= dims(i);
3030
3031 octave_idx_type nr = dims(0);
3032 octave_idx_type nc = dims(1);
3033
3034 int fw = 0;
3035 if (hex_format)
3036 fw = 2 * nda(0).byte_size ();
3037 else if (bit_format)
3038 fw = nda(0).nbits ();
3039 else
3040 {
3041 bool isneg = false;
3042 int digits = 0;
3043
3044 for (octave_idx_type i = 0; i < dims.numel (); i++)
3045 {
3046 int new_digits = static_cast<int>
3047 (floor (log10 (double (abs (nda(i).value ()))) + 1.0));
3048
3049 if (new_digits > digits)
3050 digits = new_digits;
3051
3052 if (! isneg)
3053 isneg = (abs (nda(i).value ()) != nda(i).value ());
3054 }
3055
3056 fw = digits + isneg;
3057 }
3058
3059 int column_width = fw + (rat_format ? 0 : (bank_format ? 5 : 2));
3060 octave_idx_type total_width = nc * column_width;
3061 int max_width = command_editor::terminal_cols () - extra_indent;
3062 octave_idx_type inc = nc;
3063 if (total_width > max_width && Vsplit_long_rows)
3064 {
3065 inc = max_width / column_width;
3066 if (inc == 0)
3067 inc++;
3068 }
3069
3070 for (octave_idx_type i = 0; i < m; i++)
3071 {
3072 if (m > 1)
3073 {
3074 std::string nm = "ans(:,:,";
3075
3076 std::ostringstream buf;
3077
3078 for (int k = 2; k < ndims; k++)
3079 {
3080 buf << ra_idx(k) + 1;
3081
3082 if (k < ndims - 1)
3083 buf << ",";
3084 else
3085 buf << ")";
3086 }
3087
3088 nm += buf.str ();
3089
3090 os << nm << " =\n\n";
3091 }
3092
3093 Array<idx_vector> idx (ndims);
3094
3095 idx(0) = idx_vector (':');
3096 idx(1) = idx_vector (':');
3097
3098 for (int k = 2; k < ndims; k++)
3099 idx(k) = idx_vector (ra_idx(k));
3100
3101 Array2<T> page (nda.index (idx), nr, nc);
3102
3103 if (free_format)
3104 {
3105 if (pr_as_read_syntax)
3106 os << "[\n";
3107
3108 for (octave_idx_type ii = 0; ii < nr; ii++)
3109 {
3110 for (octave_idx_type jj = 0; jj < nc; jj++)
3111 {
3112 octave_quit ();
3113 os << " ";
3114 os << typename octave_print_conv<T>::print_conv_type (page(ii,jj));
3115 }
3116 os << "\n";
3117 }
3118
3119 if (pr_as_read_syntax)
3120 os << "]";
3121 }
3122 else
3123 {
3124 octave_idx_type n_rows = page.rows ();
3125 octave_idx_type n_cols = page.cols ();
3126
3127 for (octave_idx_type col = 0; col < n_cols; col += inc)
3128 {
3129 octave_idx_type lim = col + inc < n_cols ? col + inc : n_cols;
3130
3131 pr_col_num_header (os, total_width, max_width, lim, col,
3132 extra_indent);
3133
3134 for (octave_idx_type ii = 0; ii < n_rows; ii++)
3135 {
3136 os << std::setw (extra_indent) << "";
3137
3138 for (octave_idx_type jj = col; jj < lim; jj++)
3139 {
3140 octave_quit ();
3141 os << " ";
3142 pr_int (os, page(ii,jj), fw);
3143 }
3144 if ((ii < n_rows - 1) || (i < m -1))
3145 os << "\n";
3146 }
3147 }
3148 }
3149
3150 if (i < m - 1)
3151 {
3152 os << "\n";
3153 increment_index (ra_idx, dims, 2);
3154 }
3155 }
3156 }
3157}
3158
3159#define PRINT_INT_ARRAY_INTERNAL(TYPE) \
3160 OCTINTERP_API void \
3161 octave_print_internal (std::ostream& os, const intNDArray<TYPE>& nda, \
3162 bool pr_as_read_syntax, int extra_indent) \
3163 { \
3164 octave_print_internal_template (os, nda, pr_as_read_syntax, extra_indent); \
3165 }
3166
3167PRINT_INT_ARRAY_INTERNAL (octave_int8)
3168PRINT_INT_ARRAY_INTERNAL (octave_uint8)
3169PRINT_INT_ARRAY_INTERNAL (octave_int16)
3170PRINT_INT_ARRAY_INTERNAL (octave_uint16)
3171PRINT_INT_ARRAY_INTERNAL (octave_int32)
3172PRINT_INT_ARRAY_INTERNAL (octave_uint32)
3173PRINT_INT_ARRAY_INTERNAL (octave_int64)
3174PRINT_INT_ARRAY_INTERNAL (octave_uint64)
3175
3176void
3177octave_print_internal (std::ostream&, const Cell&, bool, int, bool)
3178{
3179 panic_impossible ();
3180}
3181
3182DEFUN (rats, args, nargout,
3183 "-*- texinfo -*-\n\
3184@deftypefn {Built-in Function} {} rats (@var{x}, @var{len})\n\
3185Convert @var{x} into a rational approximation represented as a string.\n\
3186You can convert the string back into a matrix as follows:\n\
3187\n\
3188@example\n\
3189@group\n\
3190 r = rats(hilb(4));\n\
3191 x = str2num(r)\n\
3192@end group\n\
3193@end example\n\
3194\n\
3195The optional second argument defines the maximum length of the string\n\
3196representing the elements of @var{x}. By default @var{len} is 9.\n\
3197@seealso{format, rat}\n\
3198@end deftypefn")
3199{
3200 octave_value retval;
3201
3202 int nargin = args.length ();
3203
3204 if (nargin < 1 || nargin > 2 || nargout > 1)
3205 print_usage ();
3206 else
3207 {
3208 unwind_protect frame;
3209
3210 frame.protect_var (rat_string_len);
3211
3212 rat_string_len = 9;
3213
3214 if (nargin == 2)
3215 rat_string_len = args(1).nint_value ();
3216
3217 if (! error_state)
3218 {
3219 octave_value arg = args(0);
3220
3221 if (arg.is_numeric_type ())
3222 {
3223 frame.protect_var (rat_format);
3224
3225 rat_format = true;
3226
3227 std::ostringstream buf;
3228 args(0).print (buf);
3229 std::string s = buf.str ();
3230
3231 std::list<std::string> lst;
3232
3233 size_t n = 0;
3234 size_t s_len = s.length ();
3235
3236 while (n < s_len)
3237 {
3238 size_t m = s.find ('\n', n);
3239
3240 if (m == std::string::npos)
3241 {
3242 lst.push_back (s.substr (n));
3243 break;
3244 }
3245 else
3246 {
3247 lst.push_back (s.substr (n, m - n));
3248 n = m + 1;
3249 }
3250 }
3251
3252 retval = string_vector (lst);
3253 }
3254 else
3255 error ("rats: expecting numeric input");
3256 }
3257 }
3258
3259 return retval;
3260}
3261
3262DEFUN (disp, args, nargout,
3263 "-*- texinfo -*-\n\
3264@deftypefn {Built-in Function} {} disp (@var{x})\n\
3265Display the value of @var{x}. For example,\n\
3266\n\
3267@example\n\
3268@group\n\
3269disp (\"The value of pi is:\"), disp (pi)\n\
3270\n\
3271 @print{} the value of pi is:\n\
3272 @print{} 3.1416\n\
3273@end group\n\
3274@end example\n\
3275\n\
3276@noindent\n\
3277Note that the output from @code{disp} always ends with a newline.\n\
3278\n\
3279If an output value is requested, @code{disp} prints nothing and\n\
3280returns the formatted output in a string.\n\
3281@seealso{fdisp}\n\
3282@end deftypefn")
3283{
3284 octave_value_list retval;
3285
3286 int nargin = args.length ();
3287
3288 if (nargin == 1 && nargout < 2)
3289 {
3290 if (nargout == 0)
3291 args(0).print (octave_stdout);
3292 else
3293 {
3294 octave_value arg = args(0);
3295 std::ostringstream buf;
3296 arg.print (buf);
3297 retval = octave_value (buf.str (), arg.is_dq_string () ? '"' : '\'');
3298 }
3299 }
3300 else
3301 print_usage ();
3302
3303 return retval;
3304}
3305
3306DEFUN (fdisp, args, ,
3307 "-*- texinfo -*-\n\
3308@deftypefn {Built-in Function} {} fdisp (@var{fid}, @var{x})\n\
3309Display the value of @var{x} on the stream @var{fid}. For example,\n\
3310\n\
3311@example\n\
3312@group\n\
3313fdisp (stdout, \"The value of pi is:\"), fdisp (stdout, pi)\n\
3314\n\
3315 @print{} the value of pi is:\n\
3316 @print{} 3.1416\n\
3317@end group\n\
3318@end example\n\
3319\n\
3320@noindent\n\
3321Note that the output from @code{fdisp} always ends with a newline.\n\
3322@seealso{disp}\n\
3323@end deftypefn")
3324{
3325 octave_value_list retval;
3326
3327 int nargin = args.length ();
3328
3329 if (nargin == 2)
3330 {
3331 int fid = octave_stream_list::get_file_number (args (0));
3332
3333 octave_stream os = octave_stream_list::lookup (fid, "fdisp");
3334
3335 if (! error_state)
3336 {
3337 std::ostream *osp = os.output_stream ();
3338
3339 if (osp)
3340 args(1).print (*osp);
3341 else
3342 error ("fdisp: stream not open for writing");
3343 }
3344 }
3345 else
3346 print_usage ();
3347
3348 return retval;
3349}
3350
3351/*
3352%!test
3353%! format short
3354%! fd = tmpfile ();
3355%! for r = [0, Inf -Inf, NaN]
3356%! for i = [0, Inf -Inf, NaN]
3357%! fdisp (fd, complex (r, i));
3358%! endfor
3359%! endfor
3360%! fclose (fd);
3361*/
3362
3363static void
3364init_format_state (void)
3365{
3366 free_format = false;
3367 plus_format = false;
3368 rat_format = false;
3369 bank_format = false;
3370 hex_format = 0;
3371 bit_format = 0;
3372 compact_format = false;
3373 print_e = false;
3374 print_big_e = false;
3375 print_g = false;
3376}
3377
3378static void
3379set_output_prec_and_fw (int prec, int fw)
3380{
3381 Voutput_precision = prec;
3382 Voutput_max_field_width = fw;
3383}
3384
3385static void
3386set_format_style (int argc, const string_vector& argv)
3387{
3388 int idx = 1;
3389
3390 if (--argc > 0)
3391 {
3392 std::string arg = argv[idx++];
3393
3394 if (arg == "short")
3395 {
3396 if (--argc > 0)
3397 {
3398 arg = argv[idx++];
3399
3400 if (arg == "e")
3401 {
3402 init_format_state ();
3403 print_e = true;
3404 }
3405 else if (arg == "E")
3406 {
3407 init_format_state ();
3408 print_e = true;
3409 print_big_e = true;
3410 }
3411 else if (arg == "g")
3412 {
3413 init_format_state ();
3414 print_g = true;
3415 }
3416 else if (arg == "G")
3417 {
3418 init_format_state ();
3419 print_g = true;
3420 print_big_e = true;
3421 }
3422 else
3423 {
3424 error ("format: unrecognized option `short %s'",
3425 arg.c_str ());
3426 return;
3427 }
3428 }
3429 else
3430 init_format_state ();
3431
3432 set_output_prec_and_fw (5, 10);
3433 }
3434 else if (arg == "long")
3435 {
3436 if (--argc > 0)
3437 {
3438 arg = argv[idx++];
3439
3440 if (arg == "e")
3441 {
3442 init_format_state ();
3443 print_e = true;
3444 }
3445 else if (arg == "E")
3446 {
3447 init_format_state ();
3448 print_e = true;
3449 print_big_e = true;
3450 }
3451 else if (arg == "g")
3452 {
3453 init_format_state ();
3454 print_g = true;
3455 }
3456 else if (arg == "G")
3457 {
3458 init_format_state ();
3459 print_g = true;
3460 print_big_e = true;
3461 }
3462 else
3463 {
3464 error ("format: unrecognized option `long %s'",
3465 arg.c_str ());
3466 return;
3467 }
3468 }
3469 else
3470 init_format_state ();
3471
3472 set_output_prec_and_fw (15, 20);
3473 }
3474 else if (arg == "hex")
3475 {
3476 init_format_state ();
3477 hex_format = 1;
3478 }
3479 else if (arg == "native-hex")
3480 {
3481 init_format_state ();
3482 hex_format = 2;
3483 }
3484 else if (arg == "bit")
3485 {
3486 init_format_state ();
3487 bit_format = 1;
3488 }
3489 else if (arg == "native-bit")
3490 {
3491 init_format_state ();
3492 bit_format = 2;
3493 }
3494 else if (arg == "+" || arg == "plus")
3495 {
3496 if (--argc > 0)
3497 {
3498 arg = argv[idx++];
3499
3500 if (arg.length () == 3)
3501 plus_format_chars = arg;
3502 else
3503 {
3504 error ("format: invalid option for plus format");
3505 return;
3506 }
3507 }
3508 else
3509 plus_format_chars = "+ ";
3510
3511 init_format_state ();
3512 plus_format = true;
3513 }
3514 else if (arg == "rat")
3515 {
3516 init_format_state ();
3517 rat_format = true;
3518 }
3519 else if (arg == "bank")
3520 {
3521 init_format_state ();
3522 bank_format = true;
3523 }
3524 else if (arg == "free")
3525 {
3526 init_format_state ();
3527 free_format = true;
3528 }
3529 else if (arg == "none")
3530 {
3531 init_format_state ();
3532 free_format = true;
3533 }
3534 else if (arg == "compact")
3535 {
3536 compact_format = true;
3537 }
3538 else if (arg == "loose")
3539 {
3540 compact_format = false;
3541 }
3542 else
3543 error ("format: unrecognized format state `%s'", arg.c_str ());
3544 }
3545 else
3546 {
3547 init_format_state ();
3548 set_output_prec_and_fw (5, 10);
3549 }
3550}
3551
3552DEFUN (format, args, ,
3553 "-*- texinfo -*-\n\
3554@deffn {Command} format\n\
3555@deffnx {Command} format options\n\
3556Reset or specify the format of the output produced by @code{disp} and\n\
3557Octave's normal echoing mechanism. This command only affects the display\n\
3558of numbers but not how they are stored or computed. To change the internal\n\
3559representation from the default double use one of the conversion functions\n\
3560such as @code{single}, @code{uint8}, @code{int64}, etc.\n\
3561\n\
3562By default, Octave displays 5 significant digits in a human readable form\n\
3563(option @samp{short} paired with @samp{loose} format for matrices).\n\
3564If @code{format} is invoked without any options, this default format\n\
3565is restored.\n\
3566\n\
3567Valid formats for floating point numbers are listed in the following\n\
3568table.\n\
3569\n\
3570@table @code\n\
3571@item short\n\
3572Fixed point format with 5 significant figures in a field that is a maximum\n\
3573of 10 characters wide. (default).\n\
3574\n\
3575If Octave is unable to format a matrix so that columns line up on the\n\
3576decimal point and all numbers fit within the maximum field width then\n\
3577it switches to an exponential @samp{e} format.\n\
3578\n\
3579@item long\n\
3580Fixed point format with 15 significant figures in a field that is a maximum\n\
3581of 20 characters wide.\n\
3582\n\
3583As with the @samp{short} format, Octave will switch to an exponential\n\
3584@samp{e} format if it is unable to format a matrix properly using the\n\
3585current format.\n\
3586\n\
3587@item short e\n\
3588@itemx long e\n\
3589Exponential format. The number to be represented is split between a mantissa\n\
3590and an exponent (power of 10). The mantissa has 5 significant digits in the\n\
3591short format and 15 digits in the long format.\n\
3592For example, with the @samp{short e} format, @code{pi} is displayed as\n\
3593@code{3.1416e+00}.\n\
3594\n\
3595@item short E\n\
3596@itemx long E\n\
3597Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\
3598@samp{E} to indicate the exponent.\n\
3599For example, with the @samp{long E} format, @code{pi} is displayed as\n\
3600@code{3.14159265358979E+00}.\n\
3601\n\
3602@item short g\n\
3603@itemx long g\n\
3604Optimally choose between fixed point and exponential format based on\n\
3605the magnitude of the number.\n\
3606For example, with the @samp{short g} format,\n\
3607@code{pi .^ [2; 4; 8; 16; 32]} is displayed as\n\
3608\n\
3609@example\n\
3610@group\n\
3611ans =\n\
3612\n\
3613 9.8696\n\
3614 97.409\n\
3615 9488.5\n\
3616 9.0032e+07\n\
3617 8.1058e+15\n\
3618@end group\n\
3619@end example\n\
3620\n\
3621@item long G\n\
3622@itemx short G\n\
3623Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\
3624@samp{E} to indicate the exponent.\n\
3625\n\
3626@item free\n\
3627@itemx none\n\
3628Print output in free format, without trying to line up columns of\n\
3629matrices on the decimal point. This also causes complex numbers to be\n\
3630formatted as numeric pairs like this @samp{(0.60419, 0.60709)} instead\n\
3631of like this @samp{0.60419 + 0.60709i}.\n\
3632@end table\n\
3633\n\
3634The following formats affect all numeric output (floating point and\n\
3635integer types).\n\
3636\n\
3637@table @code\n\
3638@item +\n\
3639@itemx + @var{chars}\n\
3640@itemx plus\n\
3641@itemx plus @var{chars}\n\
3642Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\
3643matrix elements. This format can be very useful for examining the\n\
3644structure of a large sparse matrix.\n\
3645\n\
3646The optional argument @var{chars} specifies a list of 3 characters to use\n\
3647for printing values greater than zero, less than zero and equal to zero.\n\
3648For example, with the @samp{+ \"+-.\"} format, @code{[1, 0, -1; -1, 0, 1]}\n\
3649is displayed as\n\
3650\n\
3651@example\n\
3652@group\n\
3653ans =\n\
3654\n\
3655+.-\n\
3656-.+\n\
3657@end group\n\
3658@end example\n\
3659\n\
3660@item bank\n\
3661Print in a fixed format with two digits to the right of the decimal\n\
3662point.\n\
3663\n\
3664@item native-hex\n\
3665Print the hexadecimal representation of numbers as they are stored in\n\
3666memory. For example, on a workstation which stores 8 byte real values\n\
3667in IEEE format with the least significant byte first, the value of\n\
3668@code{pi} when printed in @code{native-hex} format is @code{400921fb54442d18}.\n\
3669\n\
3670@item hex\n\
3671The same as @code{native-hex}, but always print the most significant\n\
3672byte first.\n\
3673@item native-bit\n\
3674Print the bit representation of numbers as stored in memory.\n\
3675For example, the value of @code{pi} is\n\
3676\n\
3677@example\n\
3678@group\n\
367901000000000010010010000111111011\n\
368001010100010001000010110100011000\n\
3681@end group\n\
3682@end example\n\