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