home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21fs.zip / octave / octave-2.1.23 / src / pr-output.cc < prev    next >
C/C++ Source or Header  |  2000-01-15  |  43KB  |  2,093 lines

  1. /*
  2.  
  3. Copyright (C) 1996, 1997 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 2, or (at your option) any
  10. 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, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include <cfloat>
  28. #include <cmath>
  29. #include <cstdio>
  30. #include <cstring>
  31.  
  32. #include <string>
  33.  
  34. #include <iomanip.h>
  35. #include <iostream.h>
  36. #include <strstream.h>
  37.  
  38. #include "CMatrix.h"
  39. #include "Range.h"
  40. #include "cmd-edit.h"
  41. #include "dMatrix.h"
  42. #include "lo-mappers.h"
  43. #include "mach-info.h"
  44. #include "oct-cmplx.h"
  45. #include "str-vec.h"
  46.  
  47. #include "defun.h"
  48. #include "error.h"
  49. #include "gripes.h"
  50. #include "oct-obj.h"
  51. #include "pager.h"
  52. #include "pr-output.h"
  53. #include "sysdep.h"
  54. #include "utils.h"
  55. #include "variables.h"
  56.  
  57. // TRUE means use a scaled fixed point format for `format long' and
  58. // `format short'.
  59. static bool Vfixed_point_format;
  60.  
  61. // The maximum field width for a number printed by the default output
  62. // routines.
  63. static int Voutput_max_field_width;
  64.  
  65. // The precision of the numbers printed by the default output
  66. // routines.
  67. static int Voutput_precision;
  68.  
  69. // TRUE means that the dimensions of empty matrices should be printed
  70. // like this: x = [](2x0).
  71. static bool Vprint_empty_dimensions;
  72.  
  73. // TRUE means that the rows of big matrices should be split into
  74. // smaller slices that fit on the screen.
  75. static bool Vsplit_long_rows;
  76.  
  77. // Current format string for real numbers and the real part of complex
  78. // numbers.
  79. static char *curr_real_fmt = 0;
  80.  
  81. // Current format string for the imaginary part of complex numbers.
  82. static char *curr_imag_fmt = 0;
  83.  
  84. // TRUE means don't do any fancy formatting.
  85. static bool free_format = false;
  86.  
  87. // TRUE means print plus sign for nonzero, blank for zero.
  88. static bool plus_format = false;
  89.  
  90. // TRUE means always print like dollars and cents.
  91. static bool bank_format = false;
  92.  
  93. // TRUE means print data in hexadecimal format.
  94. static bool hex_format = false;
  95.  
  96. // TRUE means print data in binary-bit-pattern format.
  97. static int bit_format = 0;
  98.  
  99. // TRUE means don't put newlines around the column number headers.
  100. static bool compact_format = false;
  101.  
  102. // TRUE means use an e format.
  103. static bool print_e = false;
  104.  
  105. // TRUE means print E instead of e for exponent field.
  106. static bool print_big_e = false;
  107.  
  108. // XXX FIXME XXX -- these should probably be somewhere else.
  109.  
  110. static double
  111. pr_max_internal (const Matrix& m)
  112. {
  113.   int nr = m.rows ();
  114.   int nc = m.columns ();
  115.  
  116.   double result = -DBL_MAX;
  117.  
  118.   for (int j = 0; j < nc; j++)
  119.     for (int i = 0; i < nr; i++)
  120.       {
  121.     double val = m (i, j);
  122.     if (xisinf (val) || xisnan (val))
  123.       continue;
  124.  
  125.     if (val > result)
  126.       result = val;
  127.       }
  128.   return result;
  129. }
  130.  
  131. static double
  132. pr_min_internal (const Matrix& m)
  133. {
  134.   int nr = m.rows ();
  135.   int nc = m.columns ();
  136.  
  137.   double result = DBL_MAX;
  138.  
  139.   for (int j = 0; j < nc; j++)
  140.     for (int i = 0; i < nr; i++)
  141.       {
  142.     double val = m (i, j);
  143.     if (xisinf (val) || xisnan (val))
  144.       continue;
  145.  
  146.     if (val < result)
  147.       result = val;
  148.       }
  149.   return result;
  150. }
  151.  
  152. // XXX FIXME XXX -- it would be nice to share more code among these
  153. // functions,..
  154.  
  155. static void
  156. set_real_format (bool sign, int digits, bool inf_or_nan, bool nan_or_int,
  157.          int &fw)
  158. {
  159.   static char fmt_buf[128];
  160.  
  161.   int prec = Voutput_precision;
  162.  
  163.   int ld, rd;
  164.  
  165.   if (bank_format)
  166.     {
  167.       fw = digits < 0 ? 4 : digits + 3;
  168.       if (inf_or_nan && fw < 3)
  169.     fw = 3;
  170.       fw += sign;
  171.       rd = 2;
  172.     }
  173.   else if (hex_format)
  174.     {
  175.       fw = 2 * sizeof (double);
  176.       rd = 0;
  177.     }
  178.   else if (bit_format)
  179.     {
  180.       fw = 8 * sizeof (double);
  181.       rd = 0;
  182.     }
  183.   else if (nan_or_int)
  184.     {
  185.       fw = digits;
  186.       if (inf_or_nan && fw < 3)
  187.     fw = 3;
  188.       fw += sign;
  189.       rd = 0;
  190.     }
  191.   else
  192.     {
  193.       if (digits > 0)
  194.     {
  195.       ld = digits;
  196.       rd = prec > digits ? prec - digits : prec;
  197.       digits++;
  198.     }
  199.       else
  200.     {
  201.       ld = 1;
  202.       rd = prec > digits ? prec - digits : prec;
  203.       digits = -digits + 1;
  204.     }
  205.  
  206.       fw = ld + 1 + rd;
  207.       if (inf_or_nan && fw < 3)
  208.     fw = 3;
  209.       fw += sign;
  210.     }
  211.  
  212.   if (! (bank_format || hex_format || bit_format)
  213.       && (fw > Voutput_max_field_width || print_e))
  214.     {
  215.       int exp_field = 4;
  216.       if (digits > 100)
  217.     exp_field++;
  218.  
  219.       fw = 2 + prec + exp_field;
  220.       if (inf_or_nan && fw < 3)
  221.     fw = 3;
  222.       fw += sign;
  223.  
  224.       if (print_big_e)
  225.     sprintf (fmt_buf, "%%%d.%dE", fw, prec - 1);
  226.       else
  227.     sprintf (fmt_buf, "%%%d.%de", fw, prec - 1);
  228.     }
  229.   else
  230.     {
  231.       sprintf (fmt_buf, "%%%d.%df", fw, rd);
  232.     }
  233.  
  234.   curr_real_fmt = &fmt_buf[0];
  235. }
  236.  
  237. static void
  238. set_format (double d, int& fw)
  239. {
  240.   curr_real_fmt = 0;
  241.   curr_imag_fmt = 0;
  242.  
  243.   if (free_format)
  244.     return;
  245.  
  246.   bool sign = (d < 0.0);
  247.  
  248.   bool inf_or_nan = (xisinf (d) || xisnan (d));
  249.  
  250.   bool nan_or_int = (xisnan (d) || D_NINT (d) == d);
  251.  
  252.   double d_abs = d < 0.0 ? -d : d;
  253.  
  254.   int digits = (inf_or_nan || d_abs == 0.0)
  255.     ? 0 : static_cast<int> (floor (log10 (d_abs) + 1.0));
  256.  
  257.   set_real_format (sign, digits, inf_or_nan, nan_or_int, fw);
  258. }
  259.  
  260. static inline void
  261. set_format (double d)
  262. {
  263.   int fw;
  264.   set_format (d, fw);
  265. }
  266.  
  267. static void
  268. set_real_matrix_format (bool sign, int x_max, int x_min,
  269.             bool inf_or_nan, int int_or_inf_or_nan, int& fw)
  270. {
  271.   static char fmt_buf[128];
  272.  
  273.   int prec = Voutput_precision;
  274.  
  275.   int ld, rd;
  276.  
  277.   if (bank_format)
  278.     {
  279.       int digits = x_max > x_min ? x_max : x_min;
  280.       fw = digits <= 0 ? 4 : digits + 3;
  281.       if (inf_or_nan && fw < 3)
  282.     fw = 3;
  283.       fw += sign;
  284.       rd = 2;
  285.     }
  286.   else if (hex_format)
  287.     {
  288.       fw = 2 * sizeof (double);
  289.       rd = 0;
  290.     }
  291.   else if (bit_format)
  292.     {
  293.       fw = 8 * sizeof (double);
  294.       rd = 0;
  295.     }
  296.   else if (Vfixed_point_format)
  297.     {
  298.       rd = prec;
  299.       fw = rd + 2;
  300.       if (inf_or_nan && fw < 3)
  301.     fw = 3;
  302.       fw += sign;
  303.     }
  304.   else if (int_or_inf_or_nan)
  305.     {
  306.       int digits = x_max > x_min ? x_max : x_min;
  307.       fw = digits <= 0 ? 1 : digits;
  308.       if (inf_or_nan && fw < 3)
  309.     fw = 3;
  310.       fw += sign;
  311.       rd = 0;
  312.     }
  313.   else
  314.     {
  315.       int ld_max, rd_max;
  316.       if (x_max > 0)
  317.     {
  318.       ld_max = x_max;
  319.       rd_max = prec > x_max ? prec - x_max : prec;
  320.       x_max++;
  321.     }
  322.       else
  323.     {
  324.       ld_max = 1;
  325.       rd_max = prec > x_max ? prec - x_max : prec;
  326.       x_max = -x_max + 1;
  327.     }
  328.  
  329.       int ld_min, rd_min;
  330.       if (x_min > 0)
  331.     {
  332.       ld_min = x_min;
  333.       rd_min = prec > x_min ? prec - x_min : prec;
  334.       x_min++;
  335.     }
  336.       else
  337.     {
  338.       ld_min = 1;
  339.       rd_min = prec > x_min ? prec - x_min : prec;
  340.       x_min = -x_min + 1;
  341.     }
  342.  
  343.       ld = ld_max > ld_min ? ld_max : ld_min;
  344.       rd = rd_max > rd_min ? rd_max : rd_min;
  345.  
  346.       fw = ld + 1 + rd;
  347.       if (inf_or_nan && fw < 3)
  348.     fw = 3;
  349.       fw += sign;
  350.     }
  351.  
  352.   if (! (bank_format || hex_format || bit_format)
  353.       && (print_e
  354.       || (! Vfixed_point_format && fw > Voutput_max_field_width)))
  355.     {
  356.       int exp_field = 4;
  357.       if (x_max > 100 || x_min > 100)
  358.     exp_field++;
  359.  
  360.       fw = 2 + prec + exp_field;
  361.       if (inf_or_nan && fw < 3)
  362.     fw = 3;
  363.       fw += sign;
  364.  
  365.       if (print_big_e)
  366.     sprintf (fmt_buf, "%%%d.%dE", fw, prec - 1);
  367.       else
  368.     sprintf (fmt_buf, "%%%d.%de", fw, prec - 1);
  369.     }
  370.   else
  371.     {
  372.       sprintf (fmt_buf, "%%%d.%df", fw, rd);
  373.     }
  374.  
  375.   curr_real_fmt = &fmt_buf[0];
  376. }
  377.  
  378. static void
  379. set_format (const Matrix& m, int& fw, double& scale)
  380. {
  381.   curr_real_fmt = 0;
  382.   curr_imag_fmt = 0;
  383.  
  384.   if (free_format)
  385.     return;
  386.  
  387.   bool sign = m.any_element_is_negative ();
  388.  
  389.   bool inf_or_nan = m.any_element_is_inf_or_nan ();
  390.  
  391.   bool int_or_inf_or_nan = m.all_elements_are_int_or_inf_or_nan ();
  392.  
  393.   Matrix m_abs = m.abs ();
  394.   double max_abs = pr_max_internal (m_abs);
  395.   double min_abs = pr_min_internal (m_abs);
  396.  
  397.   int x_max = max_abs == 0.0
  398.     ? 0 : static_cast<int> (floor (log10 (max_abs) + 1.0));
  399.  
  400.   int x_min = min_abs == 0.0
  401.     ? 0 : static_cast<int> (floor (log10 (min_abs) + 1.0));
  402.  
  403.   scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 : pow (10.0, x_max - 1);
  404.  
  405.   set_real_matrix_format (sign, x_max, x_min, inf_or_nan,
  406.               int_or_inf_or_nan, fw);
  407. }
  408.  
  409. static inline void
  410. set_format (const Matrix& m)
  411. {
  412.   int fw;
  413.   double scale;
  414.   set_format (m, fw, scale);
  415. }
  416.  
  417. static void
  418. set_complex_format (bool sign, int x_max, int x_min, int r_x,
  419.             bool inf_or_nan, int int_only, int& r_fw, int& i_fw)
  420. {
  421.   static char r_fmt_buf[128];
  422.   static char i_fmt_buf[128];
  423.  
  424.   int prec = Voutput_precision;
  425.  
  426.   int ld, rd;
  427.  
  428.   if (bank_format)
  429.     {
  430.       int digits = r_x;
  431.       i_fw = 0;
  432.       r_fw = digits <= 0 ? 4 : digits + 3;
  433.       if (inf_or_nan && r_fw < 3)
  434.     r_fw = 3;
  435.       r_fw += sign;
  436.       rd = 2;
  437.     }
  438.   else if (hex_format)
  439.     {
  440.       r_fw = 2 * sizeof (double);
  441.       i_fw = 2 * sizeof (double);
  442.       rd = 0;
  443.     }
  444.   else if (bit_format)
  445.     {
  446.       r_fw = 8 * sizeof (double);
  447.       i_fw = 8 * sizeof (double);
  448.       rd = 0;
  449.     }
  450.   else if (inf_or_nan || int_only)
  451.     {
  452.       int digits = x_max > x_min ? x_max : x_min;
  453.       i_fw = r_fw = digits <= 0 ? 1 : digits;
  454.       if (inf_or_nan && i_fw < 3)
  455.     i_fw = r_fw = 3;
  456.       r_fw += sign;
  457.       rd = 0;
  458.     }
  459.   else
  460.     {
  461.       int ld_max, rd_max;
  462.       if (x_max > 0)
  463.     {
  464.       ld_max = x_max;
  465.       rd_max = prec > x_max ? prec - x_max : prec;
  466.       x_max++;
  467.     }
  468.       else
  469.     {
  470.       ld_max = 1;
  471.       rd_max = prec > x_max ? prec - x_max : prec;
  472.       x_max = -x_max + 1;
  473.     }
  474.  
  475.       int ld_min, rd_min;
  476.       if (x_min > 0)
  477.     {
  478.       ld_min = x_min;
  479.       rd_min = prec > x_min ? prec - x_min : prec;
  480.       x_min++;
  481.     }
  482.       else
  483.     {
  484.       ld_min = 1;
  485.       rd_min = prec > x_min ? prec - x_min : prec;
  486.       x_min = -x_min + 1;
  487.     }
  488.  
  489.       ld = ld_max > ld_min ? ld_max : ld_min;
  490.       rd = rd_max > rd_min ? rd_max : rd_min;
  491.  
  492.       i_fw = r_fw = ld + 1 + rd;
  493.       if (inf_or_nan && i_fw < 3)
  494.     i_fw = r_fw = 3;
  495.       r_fw += sign;
  496.     }
  497.  
  498.   if (! (bank_format || hex_format || bit_format)
  499.       && (r_fw > Voutput_max_field_width || print_e))
  500.     {
  501.       int exp_field = 4;
  502.       if (x_max > 100 || x_min > 100)
  503.     exp_field++;
  504.  
  505.       i_fw = r_fw = 1 + prec + exp_field;
  506.       if (inf_or_nan && i_fw < 3)
  507.     i_fw = r_fw = 3;
  508.       r_fw += sign;
  509.  
  510.       if (print_big_e)
  511.     {
  512.       sprintf (r_fmt_buf, "%%%d.%dE", r_fw, prec - 1);
  513.       sprintf (i_fmt_buf, "%%%d.%dE", i_fw, prec - 1);
  514.     }
  515.       else
  516.     {
  517.       sprintf (r_fmt_buf, "%%%d.%de", r_fw, prec - 1);
  518.       sprintf (i_fmt_buf, "%%%d.%de", i_fw, prec - 1);
  519.     }
  520.     }
  521.   else
  522.     {
  523.       sprintf (r_fmt_buf, "%%%d.%df", r_fw, rd);
  524.       sprintf (i_fmt_buf, "%%%d.%df", i_fw, rd);
  525.     }
  526.  
  527.   curr_real_fmt = &r_fmt_buf[0];
  528.   curr_imag_fmt = &i_fmt_buf[0];
  529. }
  530.  
  531. static void
  532. set_format (const Complex& c, int& r_fw, int& i_fw)
  533. {
  534.   curr_real_fmt = 0;
  535.   curr_imag_fmt = 0;
  536.  
  537.   if (free_format)
  538.     return;
  539.  
  540.   double rp = c.real ();
  541.   double ip = c.imag ();
  542.  
  543.   bool sign = (rp < 0.0);
  544.  
  545.   bool inf_or_nan = (xisinf (c) || xisnan (c));
  546.  
  547.   bool int_only = (D_NINT (rp) == rp && D_NINT (ip) == ip);
  548.  
  549.   double r_abs = rp < 0.0 ? -rp : rp;
  550.   double i_abs = ip < 0.0 ? -ip : ip;
  551.  
  552.   int r_x = r_abs == 0.0
  553.     ? 0 : static_cast<int> (floor (log10 (r_abs) + 1.0));
  554.  
  555.   int i_x = i_abs == 0.0
  556.     ? 0 : static_cast<int> (floor (log10 (i_abs) + 1.0));
  557.  
  558.   int x_max, x_min;
  559.  
  560.   if (r_x > i_x)
  561.     {
  562.       x_max = r_x;
  563.       x_min = i_x;
  564.     }
  565.   else
  566.     {
  567.       x_max = i_x;
  568.       x_min = r_x;
  569.     }
  570.  
  571.   set_complex_format (sign, x_max, x_min, r_x, inf_or_nan, int_only,
  572.               r_fw, i_fw);
  573. }
  574.  
  575. static inline void
  576. set_format (const Complex& c)
  577. {
  578.   int r_fw, i_fw;
  579.   set_format (c, r_fw, i_fw);
  580. }
  581.  
  582. static void
  583. set_complex_matrix_format (bool sign, int x_max, int x_min,
  584.                int r_x_max, int r_x_min, bool inf_or_nan,
  585.                int int_or_inf_or_nan, int& r_fw, int& i_fw)
  586. {
  587.   static char r_fmt_buf[128];
  588.   static char i_fmt_buf[128];
  589.  
  590.   int prec = Voutput_precision;
  591.  
  592.   int ld, rd;
  593.  
  594.   if (bank_format)
  595.     {
  596.       int digits = r_x_max > r_x_min ? r_x_max : r_x_min;
  597.       i_fw = 0;
  598.       r_fw = digits <= 0 ? 4 : digits + 3;
  599.       if (inf_or_nan && i_fw < 3)
  600.     i_fw = r_fw = 3;
  601.       r_fw += sign;
  602.       rd = 2;
  603.     }
  604.   else if (hex_format)
  605.     {
  606.       r_fw = 2 * sizeof (double);
  607.       i_fw = 2 * sizeof (double);
  608.       rd = 0;
  609.     }
  610.   else if (bit_format)
  611.     {
  612.       r_fw = 8 * sizeof (double);
  613.       i_fw = 8 * sizeof (double);
  614.       rd = 0;
  615.     }
  616.   else if (Vfixed_point_format)
  617.     {
  618.       rd = prec;
  619.       i_fw = r_fw = rd + 2;
  620.       if (inf_or_nan && i_fw < 3)
  621.     i_fw = r_fw = 3;
  622.       r_fw += sign;
  623.     }
  624.   else if (int_or_inf_or_nan)
  625.     {
  626.       int digits = x_max > x_min ? x_max : x_min;
  627.       i_fw = r_fw = digits <= 0 ? 1 : digits;
  628.       if (inf_or_nan && i_fw < 3)
  629.     i_fw = r_fw = 3;
  630.       r_fw += sign;
  631.       rd = 0;
  632.     }
  633.   else
  634.     {
  635.       int ld_max, rd_max;
  636.       if (x_max > 0)
  637.     {
  638.       ld_max = x_max;
  639.       rd_max = prec > x_max ? prec - x_max : prec;
  640.       x_max++;
  641.     }
  642.       else
  643.     {
  644.       ld_max = 1;
  645.       rd_max = prec > x_max ? prec - x_max : prec;
  646.       x_max = -x_max + 1;
  647.     }
  648.  
  649.       int ld_min, rd_min;
  650.       if (x_min > 0)
  651.     {
  652.       ld_min = x_min;
  653.       rd_min = prec > x_min ? prec - x_min : prec;
  654.       x_min++;
  655.     }
  656.       else
  657.     {
  658.       ld_min = 1;
  659.       rd_min = prec > x_min ? prec - x_min : prec;
  660.       x_min = -x_min + 1;
  661.     }
  662.  
  663.       ld = ld_max > ld_min ? ld_max : ld_min;
  664.       rd = rd_max > rd_min ? rd_max : rd_min;
  665.  
  666.       i_fw = r_fw = ld + 1 + rd;
  667.       if (inf_or_nan && i_fw < 3)
  668.     i_fw = r_fw = 3;
  669.       r_fw += sign;
  670.     }
  671.  
  672.   if (! (bank_format || hex_format || bit_format)
  673.       && (print_e
  674.       || (! Vfixed_point_format && r_fw > Voutput_max_field_width)))
  675.     {
  676.       int exp_field = 4;
  677.       if (x_max > 100 || x_min > 100)
  678.     exp_field++;
  679.  
  680.       i_fw = r_fw = 1 + prec + exp_field;
  681.       if (inf_or_nan && i_fw < 3)
  682.     i_fw = r_fw = 3;
  683.       r_fw += sign;
  684.  
  685.       if (print_big_e)
  686.     {
  687.       sprintf (r_fmt_buf, "%%%d.%dE", r_fw, prec - 1);
  688.       sprintf (i_fmt_buf, "%%%d.%dE", i_fw, prec - 1);
  689.     }
  690.       else
  691.     {
  692.       sprintf (r_fmt_buf, "%%%d.%de", r_fw, prec - 1);
  693.       sprintf (i_fmt_buf, "%%%d.%de", i_fw, prec - 1);
  694.     }
  695.     }
  696.   else
  697.     {
  698.       sprintf (r_fmt_buf, "%%%d.%df", r_fw, rd);
  699.       sprintf (i_fmt_buf, "%%%d.%df", i_fw, rd);
  700.     }
  701.  
  702.   curr_real_fmt = &r_fmt_buf[0];
  703.   curr_imag_fmt = &i_fmt_buf[0];
  704. }
  705.  
  706. static void
  707. set_format (const ComplexMatrix& cm, int& r_fw, int& i_fw, double& scale)
  708. {
  709.   curr_real_fmt = 0;
  710.   curr_imag_fmt = 0;
  711.  
  712.   if (free_format)
  713.     return;
  714.  
  715.   Matrix rp = real (cm);
  716.   Matrix ip = imag (cm);
  717.  
  718.   bool sign = rp.any_element_is_negative ();
  719.  
  720.   bool inf_or_nan = cm.any_element_is_inf_or_nan ();
  721.  
  722.   bool int_or_inf_or_nan = (rp.all_elements_are_int_or_inf_or_nan ()
  723.                 && ip.all_elements_are_int_or_inf_or_nan ());
  724.  
  725.   Matrix r_m_abs = rp.abs ();
  726.   double r_max_abs = pr_max_internal (r_m_abs);
  727.   double r_min_abs = pr_min_internal (r_m_abs);
  728.  
  729.   Matrix i_m_abs = ip.abs ();
  730.   double i_max_abs = pr_max_internal (i_m_abs);
  731.   double i_min_abs = pr_min_internal (i_m_abs);
  732.  
  733.   int r_x_max = r_max_abs == 0.0
  734.     ? 0 : static_cast<int> (floor (log10 (r_max_abs) + 1.0));
  735.  
  736.   int r_x_min = r_min_abs == 0.0
  737.     ? 0 : static_cast<int> (floor (log10 (r_min_abs) + 1.0));
  738.  
  739.   int i_x_max = i_max_abs == 0.0
  740.     ? 0 : static_cast<int> (floor (log10 (i_max_abs) + 1.0));
  741.  
  742.   int i_x_min = i_min_abs == 0.0
  743.     ? 0 : static_cast<int> (floor (log10 (i_min_abs) + 1.0));
  744.  
  745.   int x_max = r_x_max > i_x_max ? r_x_max : i_x_max;
  746.   int x_min = r_x_min > i_x_min ? r_x_min : i_x_min;
  747.  
  748.   scale = (x_max == 0 || int_or_inf_or_nan) ? 1.0 : pow (10.0, x_max - 1);
  749.  
  750.   set_complex_matrix_format (sign, x_max, x_min, r_x_max, r_x_min,
  751.                  inf_or_nan, int_or_inf_or_nan, r_fw, i_fw);
  752. }
  753.  
  754. static inline void
  755. set_format (const ComplexMatrix& cm)
  756. {
  757.   int r_fw, i_fw;
  758.   double scale;
  759.   set_format (cm, r_fw, i_fw, scale);
  760. }
  761.  
  762. static void
  763. set_range_format (bool sign, int x_max, int x_min, int all_ints,
  764.           int& fw)
  765. {
  766.   static char fmt_buf[128];
  767.  
  768.   int prec = Voutput_precision;
  769.  
  770.   int ld, rd;
  771.  
  772.   if (bank_format)
  773.     {
  774.       int digits = x_max > x_min ? x_max : x_min;
  775.       fw = sign + digits < 0 ? 4 : digits + 3;
  776.       rd = 2;
  777.     }
  778.   else if (hex_format)
  779.     {
  780.       fw = 2 * sizeof (double);
  781.       rd = 0;
  782.     }
  783.   else if (bit_format)
  784.     {
  785.       fw = 8 * sizeof (double);
  786.       rd = 0;
  787.     }
  788.   else if (all_ints)
  789.     {
  790.       int digits = x_max > x_min ? x_max : x_min;
  791.       fw = sign + digits;
  792.       rd = 0;
  793.     }
  794.   else if (Vfixed_point_format)
  795.     {
  796.       rd = prec;
  797.       fw = rd + 2 + sign;
  798.     }
  799.   else
  800.     {
  801.       int ld_max, rd_max;
  802.       if (x_max > 0)
  803.     {
  804.       ld_max = x_max;
  805.       rd_max = prec > x_max ? prec - x_max : prec;
  806.       x_max++;
  807.     }
  808.       else
  809.     {
  810.       ld_max = 1;
  811.       rd_max = prec > x_max ? prec - x_max : prec;
  812.       x_max = -x_max + 1;
  813.     }
  814.  
  815.       int ld_min, rd_min;
  816.       if (x_min > 0)
  817.     {
  818.       ld_min = x_min;
  819.       rd_min = prec > x_min ? prec - x_min : prec;
  820.       x_min++;
  821.     }
  822.       else
  823.     {
  824.       ld_min = 1;
  825.       rd_min = prec > x_min ? prec - x_min : prec;
  826.       x_min = -x_min + 1;
  827.     }
  828.  
  829.       ld = ld_max > ld_min ? ld_max : ld_min;
  830.       rd = rd_max > rd_min ? rd_max : rd_min;
  831.  
  832.       fw = sign + ld + 1 + rd;
  833.     }
  834.  
  835.   if (! (bank_format || hex_format || bit_format)
  836.       && (print_e
  837.       || (! Vfixed_point_format && fw > Voutput_max_field_width)))
  838.     {
  839.       int exp_field = 4;
  840.       if (x_max > 100 || x_min > 100)
  841.     exp_field++;
  842.  
  843.       fw = sign + 2 + prec + exp_field;
  844.  
  845.       if (print_big_e)
  846.     sprintf (fmt_buf, "%%%d.%dE", fw, prec - 1);
  847.       else
  848.     sprintf (fmt_buf, "%%%d.%de", fw, prec - 1);
  849.     }
  850.   else
  851.     {
  852.       sprintf (fmt_buf, "%%%d.%df", fw, rd);
  853.     }
  854.  
  855.   curr_real_fmt = &fmt_buf[0];
  856. }
  857.  
  858. static void
  859. set_format (const Range& r, int& fw, double& scale)
  860. {
  861.   curr_real_fmt = 0;
  862.   curr_imag_fmt = 0;
  863.  
  864.   if (free_format)
  865.     return;
  866.  
  867.   double r_min = r.base ();
  868.   double r_max = r.limit ();
  869.  
  870.   if (r_max < r_min)
  871.     {
  872.       double tmp = r_max;
  873.       r_max = r_min;
  874.       r_min = tmp;
  875.     }
  876.  
  877.   bool sign = (r_min < 0.0);
  878.  
  879.   bool all_ints = r.all_elements_are_ints ();
  880.  
  881.   double max_abs = r_max < 0.0 ? -r_max : r_max;
  882.   double min_abs = r_min < 0.0 ? -r_min : r_min;
  883.  
  884.   int x_max = max_abs == 0.0
  885.     ? 0 : static_cast<int> (floor (log10 (max_abs) + 1.0));
  886.  
  887.   int x_min = min_abs == 0.0
  888.     ? 0 : static_cast<int> (floor (log10 (min_abs) + 1.0));
  889.  
  890.   scale = (x_max == 0 || all_ints) ? 1.0 : pow (10.0, x_max - 1);
  891.  
  892.   set_range_format (sign, x_max, x_min, all_ints, fw);
  893. }
  894.  
  895. static inline void
  896. set_format (const Range& r)
  897. {
  898.   int fw;
  899.   double scale;
  900.   set_format (r, fw, scale);
  901. }
  902.  
  903. union equiv
  904. {
  905.   double d;
  906.   unsigned char i[sizeof (double)];
  907. };
  908.  
  909. #define PRINT_CHAR_BITS(os, c) \
  910.   do \
  911.     { \
  912.       unsigned char ctmp = c; \
  913.       char stmp[9]; \
  914.       stmp[0] = (ctmp & 0x80) ? '1' : '0'; \
  915.       stmp[1] = (ctmp & 0x40) ? '1' : '0'; \
  916.       stmp[2] = (ctmp & 0x20) ? '1' : '0'; \
  917.       stmp[3] = (ctmp & 0x10) ? '1' : '0'; \
  918.       stmp[4] = (ctmp & 0x08) ? '1' : '0'; \
  919.       stmp[5] = (ctmp & 0x04) ? '1' : '0'; \
  920.       stmp[6] = (ctmp & 0x02) ? '1' : '0'; \
  921.       stmp[7] = (ctmp & 0x01) ? '1' : '0'; \
  922.       stmp[8] = '\0'; \
  923.       os << stmp; \
  924.     } \
  925.   while (0)
  926.  
  927. #define PRINT_CHAR_BITS_SWAPPED(os, c) \
  928.   do \
  929.     { \
  930.       unsigned char ctmp = c; \
  931.       char stmp[9]; \
  932.       stmp[0] = (ctmp & 0x01) ? '1' : '0'; \
  933.       stmp[1] = (ctmp & 0x02) ? '1' : '0'; \
  934.       stmp[2] = (ctmp & 0x04) ? '1' : '0'; \
  935.       stmp[3] = (ctmp & 0x08) ? '1' : '0'; \
  936.       stmp[4] = (ctmp & 0x10) ? '1' : '0'; \
  937.       stmp[5] = (ctmp & 0x20) ? '1' : '0'; \
  938.       stmp[6] = (ctmp & 0x40) ? '1' : '0'; \
  939.       stmp[7] = (ctmp & 0x80) ? '1' : '0'; \
  940.       stmp[8] = '\0'; \
  941.       os << stmp; \
  942.     } \
  943.   while (0)
  944.  
  945. static void
  946. pr_any_float (const char *fmt, ostream& os, double d, int fw = 0)
  947. {
  948. #if defined (SCO)
  949.   // Apparently on some SCO systems NaN == -0.0 is true.  Compiler bug?
  950.   if (d == -0.0 && ! xisnan (d))
  951.     d = 0.0;
  952. #else
  953.   if (d == -0.0)
  954.     d = 0.0;
  955. #endif
  956.  
  957.   if (fmt)
  958.     {
  959.       if (hex_format)
  960.     {
  961.       equiv tmp;
  962.       tmp.d = d;
  963.  
  964.       // Unless explicitly asked for, always print in big-endian
  965.       // format.
  966.  
  967.       // XXX FIXME XXX -- is it correct to swap bytes for VAX
  968.       // formats and not for Cray?
  969.  
  970.       // XXX FIXME XXX -- will bad things happen if we are
  971.       // interrupted before resetting the format flags and fill
  972.       // character?
  973.  
  974.       oct_mach_info::float_format flt_fmt =
  975.         oct_mach_info::native_float_format ();
  976.  
  977.       char ofill = os.fill ('0');
  978.  
  979.       ios::fmtflags oflags = os.setf (ios::right);
  980.       os.setf (ios::hex, ios::basefield);
  981.  
  982.       if (hex_format > 1
  983.           || flt_fmt == oct_mach_info::ieee_big_endian
  984.           || flt_fmt == oct_mach_info::cray
  985.           || flt_fmt == oct_mach_info::unknown)
  986.         {
  987.           for (size_t i = 0; i < sizeof (double); i++)
  988.         os << setw (2) << static_cast<int> (tmp.i[i]);
  989.         }
  990.       else
  991.         {
  992.           for (int i = sizeof (double) - 1; i >= 0; i--)
  993.         os << setw (2) << static_cast<int> (tmp.i[i]);
  994.         }
  995.  
  996.       os.fill (ofill);
  997.       os.setf (oflags);      
  998.     }
  999.       else if (bit_format)
  1000.     {
  1001.       equiv tmp;
  1002.       tmp.d = d;
  1003.  
  1004.       // Unless explicitly asked for, always print in big-endian
  1005.       // format.
  1006.  
  1007.       // XXX FIXME XXX -- is it correct to swap bytes for VAX
  1008.       // formats and not for Cray?
  1009.  
  1010.       oct_mach_info::float_format flt_fmt =
  1011.         oct_mach_info::native_float_format ();
  1012.  
  1013.       if (flt_fmt == oct_mach_info::ieee_big_endian
  1014.           || flt_fmt == oct_mach_info::cray
  1015.           || flt_fmt == oct_mach_info::unknown)
  1016.         {
  1017.           for (size_t i = 0; i < sizeof (double); i++)
  1018.         PRINT_CHAR_BITS (os, tmp.i[i]);
  1019.         }
  1020.       else
  1021.         {
  1022.           if (bit_format > 1)
  1023.         {
  1024.           for (size_t i = 0; i < sizeof (double); i++)
  1025.             PRINT_CHAR_BITS_SWAPPED (os, tmp.i[i]);
  1026.         }
  1027.           else
  1028.         {
  1029.           for (int i = sizeof (double) - 1; i >= 0; i--)
  1030.             PRINT_CHAR_BITS (os, tmp.i[i]);
  1031.         }
  1032.         }
  1033.     }
  1034.       else if (xisinf (d))
  1035.     {
  1036.       const char *s;
  1037.       if (d < 0.0)
  1038.         s = "-Inf";
  1039.       else
  1040.         s = "Inf";
  1041.  
  1042.       if (fw > 0)
  1043.         os << setw (fw) << s;
  1044.       else
  1045.         os << s;
  1046.     }
  1047.       else if (xisnan (d))
  1048.     {
  1049.       if (fw > 0)
  1050.         os << setw (fw) << "NaN";
  1051.       else
  1052.         os << "NaN";
  1053.     }
  1054.       else
  1055.     os.form (fmt, d);
  1056.     }
  1057.   else
  1058.     os << d;
  1059. }
  1060.  
  1061. static inline void
  1062. pr_float (ostream& os, double d, int fw = 0)
  1063. {
  1064.   pr_any_float (curr_real_fmt, os, d, fw);
  1065. }
  1066.  
  1067. static inline void
  1068. pr_imag_float (ostream& os, double d, int fw = 0)
  1069. {
  1070.   pr_any_float (curr_imag_fmt, os, d, fw);
  1071. }
  1072.  
  1073. static void
  1074. pr_complex (ostream& os, const Complex& c, int r_fw = 0, int i_fw = 0)
  1075. {
  1076.   double r = c.real ();
  1077.   pr_float (os, r, r_fw);
  1078.   if (! bank_format)
  1079.     {
  1080.       double i = c.imag ();
  1081.       if (! (hex_format || bit_format) && i < 0)
  1082.     {
  1083.       os << " - ";
  1084.       i = -i;
  1085.       pr_imag_float (os, i, i_fw);
  1086.     }
  1087.       else
  1088.     {
  1089.       if (hex_format || bit_format)
  1090.         os << "  ";
  1091.       else
  1092.         os << " + ";
  1093.  
  1094.       pr_imag_float (os, i, i_fw);
  1095.     }
  1096.       os << "i";
  1097.     }
  1098. }
  1099.  
  1100. static void
  1101. print_empty_matrix (ostream& os, int nr, int nc, bool pr_as_read_syntax)
  1102. {
  1103.   assert (nr == 0 || nc == 0);
  1104.  
  1105.   if (pr_as_read_syntax)
  1106.     {
  1107.       if (nr == 0 && nc == 0)
  1108.     os << "[]";
  1109.       else
  1110.     os << "zeros (" << nr << ", " << nc << ")";
  1111.     }
  1112.   else
  1113.     {
  1114.       os << "[]";
  1115.       if (Vprint_empty_dimensions)
  1116.     os << "(" << nr << "x" << nc << ")";
  1117.     }
  1118. }
  1119.  
  1120. static void
  1121. pr_scale_header (ostream& os, double scale)
  1122. {
  1123.   if (Vfixed_point_format && scale != 1.0)
  1124.     {
  1125.       os.form ("  %-8.1e *\n", scale);
  1126.  
  1127.       if (! compact_format)
  1128.     os << "\n";
  1129.     }
  1130. }
  1131.  
  1132. static void
  1133. pr_col_num_header (ostream& os, int total_width, int max_width,
  1134.            int lim, int col, int extra_indent)
  1135. {
  1136.   if (total_width > max_width && Vsplit_long_rows)
  1137.     {
  1138.       if (col != 0 && ! compact_format)
  1139.     os << "\n\n";
  1140.  
  1141.       int num_cols = lim - col;
  1142.  
  1143.       os << setw (extra_indent) << "";
  1144.  
  1145.       if (num_cols == 1)
  1146.     os << " Column " << col + 1 << ":\n";
  1147.       else if (num_cols == 2)
  1148.     os << " Columns " << col + 1 << " and " << lim << ":\n";
  1149.       else
  1150.     os << " Columns " << col + 1 << " through " << lim << ":\n";
  1151.  
  1152.       if (! compact_format)
  1153.     os << "\n";
  1154.     }
  1155. }
  1156.  
  1157. static inline void
  1158. do_plus_format (ostream& os, double d)
  1159. {
  1160.   if (d == 0.0)
  1161.     os << " ";
  1162.   else if (d < 0.0)
  1163.     os << "-";
  1164.   else
  1165.     os << "+";
  1166. }
  1167.  
  1168. void
  1169. octave_print_internal (ostream& os, double d, bool pr_as_read_syntax)
  1170. {
  1171.   if (plus_format)
  1172.     {
  1173.       do_plus_format (os, d);
  1174.     }
  1175.   else
  1176.     {
  1177.       set_format (d);
  1178.       if (free_format)
  1179.     os << d;
  1180.       else
  1181.     pr_float (os, d);
  1182.     }
  1183. }
  1184.  
  1185. void
  1186. octave_print_internal (ostream& os, const Matrix& m, bool pr_as_read_syntax,
  1187.                int extra_indent)
  1188. {
  1189.   int nr = m.rows ();
  1190.   int nc = m.columns ();
  1191.  
  1192.   if (nr == 0 || nc == 0)
  1193.     print_empty_matrix (os, nr, nc, pr_as_read_syntax);
  1194.   else if (plus_format && ! pr_as_read_syntax)
  1195.     {
  1196.       for (int i = 0; i < nr; i++)
  1197.     {
  1198.       for (int j = 0; j < nc; j++)
  1199.         {
  1200.           if (j == 0)
  1201.         os << "  ";
  1202.  
  1203.           do_plus_format (os, m (i, j));
  1204.         }
  1205.  
  1206.       if (i < nr - 1)
  1207.         os << "\n";
  1208.     }
  1209.     }
  1210.   else
  1211.     {
  1212.       int fw;
  1213.       double scale = 1.0;
  1214.       set_format (m, fw, scale);
  1215.       int column_width = fw + 2;
  1216.       int total_width = nc * column_width;
  1217.       int max_width = command_editor::terminal_cols ();
  1218.  
  1219.       if (pr_as_read_syntax)
  1220.     max_width -= 4;
  1221.       else
  1222.     max_width -= extra_indent;
  1223.  
  1224.       if (max_width < 0)
  1225.     max_width = 0;
  1226.  
  1227.       if (free_format)
  1228.     {
  1229.       if (pr_as_read_syntax)
  1230.         os << "[\n";
  1231.  
  1232.       os << m;
  1233.  
  1234.       if (pr_as_read_syntax)
  1235.         os << "]";
  1236.  
  1237.       return;
  1238.     }
  1239.  
  1240.       int inc = nc;
  1241.       if (total_width > max_width && Vsplit_long_rows)
  1242.     {
  1243.       inc = max_width / column_width;
  1244.       if (inc == 0)
  1245.         inc++;
  1246.     }
  1247.  
  1248.       if (pr_as_read_syntax)
  1249.     {
  1250.       for (int i = 0; i < nr; i++)
  1251.         {
  1252.           int col = 0;
  1253.           while (col < nc)
  1254.         {
  1255.           int lim = col + inc < nc ? col + inc : nc;
  1256.  
  1257.           for (int j = col; j < lim; j++)
  1258.             {
  1259.               if (i == 0 && j == 0)
  1260.             os << "[ ";
  1261.               else
  1262.             {
  1263.               if (j > col && j < lim)
  1264.                 os << ", ";
  1265.               else
  1266.                 os << "  ";
  1267.             }
  1268.  
  1269.               pr_float (os, m (i, j));
  1270.             }
  1271.  
  1272.           col += inc;
  1273.  
  1274.           if (col >= nc)
  1275.             {
  1276.               if (i == nr - 1)
  1277.             os << " ]";
  1278.               else
  1279.             os << ";\n";
  1280.             }
  1281.           else
  1282.             os << " ...\n";
  1283.         }
  1284.         }
  1285.     }
  1286.       else
  1287.     {
  1288.       pr_scale_header (os, scale);
  1289.  
  1290.       for (int col = 0; col < nc; col += inc)
  1291.         {
  1292.           int lim = col + inc < nc ? col + inc : nc;
  1293.  
  1294.           pr_col_num_header (os, total_width, max_width, lim, col,
  1295.                  extra_indent);
  1296.  
  1297.           for (int i = 0; i < nr; i++)
  1298.         {
  1299.           os << setw (extra_indent) << "";
  1300.  
  1301.           for (int j = col; j < lim; j++)
  1302.             {
  1303.               os << "  ";
  1304.  
  1305.               double tmp = (Vfixed_point_format && scale != 1.0)
  1306.             ? m(i,j) / scale : m(i,j);
  1307.  
  1308.               pr_float (os, tmp, fw);
  1309.             }
  1310.  
  1311.           if (i < nr - 1)
  1312.             os << "\n";
  1313.         }
  1314.         }
  1315.     }
  1316.     }
  1317. }
  1318.  
  1319. static inline void
  1320. do_plus_format (ostream& os, const Complex& c)
  1321. {
  1322.   double rp = c.real ();
  1323.   double ip = c.imag ();
  1324.  
  1325.   if (rp == 0.0)
  1326.     {
  1327.       if (ip == 0.0)
  1328.     os << " ";
  1329.       else
  1330.     os << "i";
  1331.     }
  1332.   else if (ip == 0.0)
  1333.     do_plus_format (os, rp);
  1334.   else
  1335.     os << "c";
  1336. }
  1337.  
  1338. void
  1339. octave_print_internal (ostream& os, const Complex& c,
  1340.                bool pr_as_read_syntax)
  1341. {
  1342.   if (plus_format)
  1343.     {
  1344.       do_plus_format (os, c);
  1345.     }
  1346.   else
  1347.     {
  1348.       set_format (c);
  1349.       if (free_format)
  1350.     os << c;
  1351.       else
  1352.     pr_complex (os, c);
  1353.     }
  1354. }
  1355.  
  1356. void
  1357. octave_print_internal (ostream& os, const ComplexMatrix& cm,
  1358.                bool pr_as_read_syntax, int extra_indent)
  1359. {
  1360.   int nr = cm.rows ();
  1361.   int nc = cm.columns ();
  1362.  
  1363.  if (nr == 0 || nc == 0)
  1364.     print_empty_matrix (os, nr, nc, pr_as_read_syntax);
  1365.   else if (plus_format && ! pr_as_read_syntax)
  1366.     {
  1367.       for (int i = 0; i < nr; i++)
  1368.     {
  1369.       for (int j = 0; j < nc; j++)
  1370.         {
  1371.           if (j == 0)
  1372.         os << "  ";
  1373.  
  1374.           do_plus_format (os, cm (i, j));
  1375.         }
  1376.  
  1377.       if (i < nr - 1)
  1378.         os << "\n";
  1379.     }
  1380.     }
  1381.   else
  1382.     {
  1383.       int r_fw, i_fw;
  1384.       double scale = 1.0;
  1385.       set_format (cm, r_fw, i_fw, scale);
  1386.       int column_width = i_fw + r_fw;
  1387.       column_width += (bank_format || hex_format|| bit_format) ? 2 : 7;
  1388.       int total_width = nc * column_width;
  1389.       int max_width = command_editor::terminal_cols ();
  1390.  
  1391.       if (pr_as_read_syntax)
  1392.     max_width -= 4;
  1393.       else
  1394.     max_width -= extra_indent;
  1395.  
  1396.       if (max_width < 0)
  1397.     max_width = 0;
  1398.  
  1399.       if (free_format)
  1400.     {
  1401.       if (pr_as_read_syntax)
  1402.         os << "[\n";
  1403.  
  1404.       os << cm;
  1405.  
  1406.       if (pr_as_read_syntax)
  1407.         os << "]";
  1408.  
  1409.       return;
  1410.     }
  1411.  
  1412.       int inc = nc;
  1413.       if (total_width > max_width && Vsplit_long_rows)
  1414.     {
  1415.       inc = max_width / column_width;
  1416.       if (inc == 0)
  1417.         inc++;
  1418.     }
  1419.  
  1420.       if (pr_as_read_syntax)
  1421.     {
  1422.       for (int i = 0; i < nr; i++)
  1423.         {
  1424.           int col = 0;
  1425.           while (col < nc)
  1426.         {
  1427.           int lim = col + inc < nc ? col + inc : nc;
  1428.  
  1429.           for (int j = col; j < lim; j++)
  1430.             {
  1431.               if (i == 0 && j == 0)
  1432.             os << "[ ";
  1433.               else
  1434.             {
  1435.               if (j > col && j < lim)
  1436.                 os << ", ";
  1437.               else
  1438.                 os << "  ";
  1439.             }
  1440.  
  1441.               pr_complex (os, cm (i, j));
  1442.             }
  1443.  
  1444.           col += inc;
  1445.  
  1446.           if (col >= nc)
  1447.             {
  1448.               if (i == nr - 1)
  1449.             os << " ]";
  1450.               else
  1451.             os << ";\n";
  1452.             }
  1453.           else
  1454.             os << " ...\n";
  1455.         }
  1456.         }
  1457.     }
  1458.       else
  1459.     {
  1460.       pr_scale_header (os, scale);
  1461.  
  1462.       for (int col = 0; col < nc; col += inc)
  1463.         {
  1464.           int lim = col + inc < nc ? col + inc : nc;
  1465.  
  1466.           pr_col_num_header (os, total_width, max_width, lim, col,
  1467.                  extra_indent);
  1468.  
  1469.           for (int i = 0; i < nr; i++)
  1470.         {
  1471.           os << setw (extra_indent) << "";
  1472.  
  1473.           for (int j = col; j < lim; j++)
  1474.             {
  1475.               os << "  ";
  1476.  
  1477.               Complex tmp = (Vfixed_point_format && scale != 1.0)
  1478.             ? cm(i,j) / scale : cm(i,j);
  1479.  
  1480.               pr_complex (os, tmp, r_fw, i_fw);
  1481.             }
  1482.  
  1483.           if (i < nr - 1) 
  1484.             os << "\n";
  1485.         }
  1486.         }
  1487.     }
  1488.     }
  1489. }
  1490.  
  1491. void
  1492. octave_print_internal (ostream& os, const Range& r,
  1493.                bool pr_as_read_syntax, int extra_indent)
  1494. {
  1495.   double base = r.base ();
  1496.   double increment = r.inc ();
  1497.   double limit = r.limit ();
  1498.   int num_elem = r.nelem ();
  1499.  
  1500.   if (plus_format && ! pr_as_read_syntax)
  1501.     {
  1502.       os << "  ";
  1503.       for (int i = 0; i < num_elem; i++)
  1504.     {
  1505.       double val = base + i * increment;
  1506.       if (val == 0.0)
  1507.         os << " ";
  1508.       else
  1509.         os << "+";
  1510.     }
  1511.     }
  1512.   else
  1513.     {
  1514.       int fw;
  1515.       double scale = 1.0;
  1516.       set_format (r, fw, scale);
  1517.  
  1518.       if (pr_as_read_syntax)
  1519.     {
  1520.       if (free_format)
  1521.         {
  1522.           os << base << " : ";
  1523.           if (increment != 1.0)
  1524.         os << increment << " : ";
  1525.           os << limit;
  1526.         }
  1527.       else
  1528.         {
  1529.           pr_float (os, base, fw);
  1530.           os << " : ";
  1531.           if (increment != 1.0)
  1532.         {
  1533.           pr_float (os, increment, fw);
  1534.           os << " : ";
  1535.         }
  1536.           pr_float (os, limit, fw);
  1537.         }
  1538.     }
  1539.       else
  1540.     {
  1541.       int column_width = fw + 2;
  1542.       int total_width = num_elem * column_width;
  1543.       int max_width = command_editor::terminal_cols ();
  1544.  
  1545.       if (free_format)
  1546.         {
  1547.           os << r;
  1548.           return;
  1549.         }
  1550.  
  1551.       int inc = num_elem;
  1552.       if (total_width > max_width && Vsplit_long_rows)
  1553.         {
  1554.           inc = max_width / column_width;
  1555.           if (inc == 0)
  1556.         inc++;
  1557.         }
  1558.  
  1559.       max_width -= extra_indent;
  1560.  
  1561.       if (max_width < 0)
  1562.         max_width = 0;
  1563.  
  1564.       pr_scale_header (os, scale);
  1565.  
  1566.       int col = 0;
  1567.       while (col < num_elem)
  1568.         {
  1569.           int lim = col + inc < num_elem ? col + inc : num_elem;
  1570.  
  1571.           pr_col_num_header (os, total_width, max_width, lim, col,
  1572.                  extra_indent);
  1573.  
  1574.           os << setw (extra_indent) << "";
  1575.  
  1576.           for (int i = col; i < lim; i++)
  1577.         {
  1578.           double val = base + i * increment;
  1579.  
  1580.           os << "  ";
  1581.  
  1582.           if (Vfixed_point_format && scale != 1.0)
  1583.             val /= scale;
  1584.  
  1585.           pr_float (os, val, fw);
  1586.         }
  1587.  
  1588.           col += inc;
  1589.  
  1590.           if (col < num_elem)
  1591.         os << "\n";
  1592.         }
  1593.     }
  1594.     }
  1595. }
  1596.  
  1597. void
  1598. octave_print_internal (ostream& os, const boolMatrix& bm,
  1599.                bool pr_as_read_syntax,
  1600.                int extra_indent)
  1601. {
  1602.   Matrix tmp (bm);
  1603.   octave_print_internal (os, tmp, pr_as_read_syntax, extra_indent);
  1604. }
  1605.  
  1606. void
  1607. octave_print_internal (ostream& os, const charMatrix& chm,
  1608.                bool pr_as_read_syntax,
  1609.                int /* extra_indent XXX FIXME XXX */,
  1610.                bool pr_as_string)
  1611. {
  1612.   if (pr_as_string)
  1613.     {
  1614.       int nstr = chm.rows ();
  1615.  
  1616.       if (pr_as_read_syntax && nstr > 1)
  1617.     os << "[ ";
  1618.  
  1619.       if (nstr != 0)
  1620.     {
  1621.       for (int i = 0; i < nstr; i++)
  1622.         {
  1623.           string row = chm.row_as_string (i);
  1624.  
  1625.           if (pr_as_read_syntax)
  1626.         {
  1627.           os << "\"" << undo_string_escapes (row) << "\"";
  1628.  
  1629.           if (i < nstr - 1)
  1630.             os << "; ";
  1631.         }
  1632.           else
  1633.         {
  1634.           os << row;
  1635.  
  1636.           if (i < nstr - 1)
  1637.             os << "\n";
  1638.         }
  1639.         }
  1640.     }
  1641.  
  1642.       if (pr_as_read_syntax && nstr > 1)
  1643.     os << " ]";
  1644.     }
  1645.   else
  1646.     {
  1647.       os << "sorry, printing char matrices not implemented yet\n";
  1648.     }
  1649. }
  1650.  
  1651. DEFUN (disp, args, ,
  1652.   "-*- texinfo -*-\n\
  1653. @deftypefn {Built-in Function} {} disp (@var{x})\n\
  1654. Display the value of @var{x}.  For example,\n\
  1655. \n\
  1656. @example\n\
  1657. disp (\"The value of pi is:\"), disp (pi)\n\
  1658. \n\
  1659.      @print{} the value of pi is:\n\
  1660.      @print{} 3.1416\n\
  1661. @end example\n\
  1662. \n\
  1663. @noindent\n\
  1664. Note that the output from @code{disp} always ends with a newline.\n\
  1665. @end deftypefn")
  1666. {
  1667.   octave_value_list retval;
  1668.  
  1669.   int nargin = args.length ();
  1670.  
  1671.   if (nargin == 1)
  1672.     args(0).print (octave_stdout);
  1673.   else
  1674.     print_usage ("disp");
  1675.  
  1676.   return retval;
  1677. }
  1678.  
  1679. static void
  1680. init_format_state (void)
  1681. {
  1682.   free_format = false;
  1683.   plus_format = false;
  1684.   bank_format = false;
  1685.   hex_format = false;
  1686.   bit_format = 0;
  1687.   print_e = false;
  1688.   print_big_e = false;
  1689. }
  1690.  
  1691. static void
  1692. set_output_prec_and_fw (int prec, int fw)
  1693. {
  1694.   bind_builtin_variable ("output_precision", static_cast<double> (prec));
  1695.   bind_builtin_variable ("output_max_field_width", static_cast<double> (fw));
  1696. }
  1697.  
  1698. static void
  1699. set_format_style (int argc, const string_vector& argv)
  1700. {
  1701.   int idx = 1;
  1702.  
  1703.   if (--argc > 0)
  1704.     {
  1705.       string arg = argv[idx++];
  1706.  
  1707.       if (arg == "short")
  1708.     {
  1709.       if (--argc > 0)
  1710.         {
  1711.           arg = argv[idx++];
  1712.  
  1713.           if (arg == "e")
  1714.         {
  1715.           init_format_state ();
  1716.           print_e = true;
  1717.         }
  1718.           else if (arg == "E")
  1719.         {
  1720.           init_format_state ();
  1721.           print_e = true;
  1722.           print_big_e = true;
  1723.         }
  1724.           else
  1725.         {
  1726.           error ("format: unrecognized option `short %s'",
  1727.              arg.c_str ());
  1728.           return;
  1729.         }
  1730.         }
  1731.       else
  1732.         init_format_state ();
  1733.  
  1734.       set_output_prec_and_fw (3, 8);
  1735.     }
  1736.       else if (arg == "long")
  1737.     {
  1738.       if (--argc > 0)
  1739.         {
  1740.           arg = argv[idx++];
  1741.  
  1742.           if (arg == "e")
  1743.         {
  1744.           init_format_state ();
  1745.           print_e = true;
  1746.         }
  1747.           else if (arg == "E")
  1748.         {
  1749.           init_format_state ();
  1750.           print_e = true;
  1751.           print_big_e = true;
  1752.         }
  1753.           else
  1754.         {
  1755.           error ("format: unrecognized option `long %s'",
  1756.              arg.c_str ());
  1757.           return;
  1758.         }
  1759.         }
  1760.       else
  1761.         init_format_state ();
  1762.  
  1763.       set_output_prec_and_fw (15, 24);
  1764.     }
  1765.       else if (arg == "hex")
  1766.     {
  1767.       init_format_state ();
  1768.       hex_format = true;
  1769.     }
  1770.       else if (arg == "native-hex")
  1771.     {
  1772.       init_format_state ();
  1773.       hex_format = 2;
  1774.     }
  1775.       else if (arg == "bit")
  1776.     {
  1777.       init_format_state ();
  1778.       bit_format = 1;
  1779.     }
  1780.       else if (arg == "native-bit")
  1781.     {
  1782.       init_format_state ();
  1783.       bit_format = 2;
  1784.     }
  1785.       else if (arg == "+" || arg == "plus")
  1786.     {
  1787.       init_format_state ();
  1788.       plus_format = true;
  1789.     }
  1790.       else if (arg == "bank")
  1791.     {
  1792.       init_format_state ();
  1793.       bank_format = true;
  1794.     }
  1795.       else if (arg == "free")
  1796.     {
  1797.       init_format_state ();
  1798.       free_format = true;
  1799.     }
  1800.       else if (arg == "none")
  1801.     {
  1802.       init_format_state ();
  1803.       free_format = true;
  1804.     }
  1805.       else if (arg == "compact")
  1806.     {
  1807.       compact_format = true;
  1808.     }
  1809.       else if (arg == "loose")
  1810.     {
  1811.       compact_format = false;
  1812.     }
  1813.       else
  1814.     error ("format: unrecognized format state `%s'", arg.c_str ());
  1815.     }
  1816.   else
  1817.     {
  1818.       init_format_state ();
  1819.       set_output_prec_and_fw (5, 10);
  1820.     }
  1821. }
  1822.  
  1823. DEFUN_TEXT (format, args, ,
  1824.   "-*- texinfo -*-\n\
  1825. @deffn {Command} format options\n\
  1826. Control the format of the output produced by @code{disp} and Octave's\n\
  1827. normal echoing mechanism.  Valid options are listed in the following\n\
  1828. table.\n\
  1829. \n\
  1830. @table @code\n\
  1831. @item short\n\
  1832. Octave will try to print numbers with at\n\
  1833. least 3 significant figures within a field that is a maximum of 8\n\
  1834. characters wide.\n\
  1835. \n\
  1836. If Octave is unable to format a matrix so that columns line up on the\n\
  1837. decimal point and all the numbers fit within the maximum field width,\n\
  1838. it switches to an @samp{e} format.\n\
  1839. \n\
  1840. @item long\n\
  1841. Octave will try to print numbers with at least 15 significant figures\n\
  1842. within a field that is a maximum of 24 characters wide.\n\
  1843. \n\
  1844. As will the @samp{short} format, Octave will switch to an @samp{e}\n\
  1845. format if it is unable to format a matrix so that columns line up on the\n\
  1846. decimal point and all the numbers fit within the maximum field width.\n\
  1847. \n\
  1848. @item long e\n\
  1849. @itemx short e\n\
  1850. The same as @samp{format long} or @samp{format short} but always display\n\
  1851. output with an @samp{e} format.  For example, with the @samp{short e}\n\
  1852. format, pi is displayed as @code{3.14e+00}.\n\
  1853. \n\
  1854. @item long E\n\
  1855. @itemx short E\n\
  1856. The same as @samp{format long e} or @samp{format short e} but always\n\
  1857. display output with an uppercase @samp{E} format.  For example, with\n\
  1858. the @samp{long E} format, pi is displayed as\n\
  1859. @code{3.14159265358979E+00}.\n\
  1860. \n\
  1861. @item free\n\
  1862. @itemx none\n\
  1863. Print output in free format, without trying to line up columns of\n\
  1864. matrices on the decimal point.  This also causes complex numbers to be\n\
  1865. formatted like this @samp{(0.604194, 0.607088)} instead of like this\n\
  1866. @samp{0.60419 + 0.60709i}.\n\
  1867. \n\
  1868. @item bank\n\
  1869. Print in a fixed format with two places to the right of the decimal\n\
  1870. point.\n\
  1871. \n\
  1872. @item +\n\
  1873. Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\
  1874. matrix elements.  This format can be very useful for examining the\n\
  1875. structure of a large matrix.\n\
  1876. \n\
  1877. @item hex\n\
  1878. Print the hexadecimal representation numbers as they are stored in\n\
  1879. memory.  For example, on a workstation which stores 8 byte real values\n\
  1880. in IEEE format with the least significant byte first, the value of\n\
  1881. @code{pi} when printed in @code{hex} format is @code{400921fb54442d18}.\n\
  1882. This format only works for numeric values.\n\
  1883. \n\
  1884. @item bit\n\
  1885. Print the bit representation of numbers as stored in memory.\n\
  1886. For example, the value of @code{pi} is\n\
  1887. \n\
  1888. @example\n\
  1889. @group\n\
  1890. 01000000000010010010000111111011\n\
  1891. 01010100010001000010110100011000\n\
  1892. @end group\n\
  1893. @end example\n\
  1894. \n\
  1895. (shown here in two 32 bit sections for typesetting purposes) when\n\
  1896. printed in bit format on a workstation which stores 8 byte real values\n\
  1897. in IEEE format with the least significant byte first.  This format only\n\
  1898. works for numeric types.\n\
  1899. @end table\n\
  1900. \n\
  1901. By default, Octave will try to print numbers with at least 5 significant\n\
  1902. figures within a field that is a maximum of 10 characters wide.\n\
  1903. \n\
  1904. If Octave is unable to format a matrix so that columns line up on the\n\
  1905. decimal point and all the numbers fit within the maximum field width,\n\
  1906. it switches to an @samp{e} format.\n\
  1907. \n\
  1908. If @code{format} is invoked without any options, the default format\n\
  1909. state is restored.\n\
  1910. @end deffn")
  1911. {
  1912.   octave_value_list retval;
  1913.  
  1914.   int argc = args.length () + 1;
  1915.  
  1916.   string_vector argv = args.make_argv ("format");
  1917.  
  1918.   if (error_state)
  1919.     return retval;
  1920.  
  1921.   set_format_style (argc, argv);
  1922.  
  1923.   return retval;
  1924. }
  1925.  
  1926. static int
  1927. fixed_point_format (void)
  1928. {
  1929.   Vfixed_point_format = check_preference ("fixed_point_format");
  1930.  
  1931.   return 0;
  1932. }
  1933.  
  1934. static int
  1935. output_max_field_width (void)
  1936. {
  1937.   double val;
  1938.   if (builtin_real_scalar_variable ("output_max_field_width", val)
  1939.       && ! xisnan (val))
  1940.     {
  1941.       int ival = NINT (val);
  1942.       if (ival > 0 && ival == val)
  1943.     {
  1944.       Voutput_max_field_width = ival;
  1945.       return 0;
  1946.     }
  1947.     }
  1948.   gripe_invalid_value_specified ("output_max_field_width");
  1949.   return -1;
  1950. }
  1951.  
  1952. static int
  1953. output_precision (void)
  1954. {
  1955.   double val;
  1956.   if (builtin_real_scalar_variable ("output_precision", val)
  1957.       && ! xisnan (val))
  1958.     {
  1959.       int ival = NINT (val);
  1960.       if (ival >= 0 && ival == val)
  1961.     {
  1962.       Voutput_precision = ival;
  1963.       return 0;
  1964.     }
  1965.     }
  1966.   gripe_invalid_value_specified ("output_precision");
  1967.   return -1;
  1968. }
  1969.  
  1970. static int
  1971. print_empty_dimensions (void)
  1972. {
  1973.   Vprint_empty_dimensions = check_preference ("print_empty_dimensions");
  1974.  
  1975.   return 0;
  1976. }
  1977.  
  1978. static int
  1979. split_long_rows (void)
  1980. {
  1981.   Vsplit_long_rows = check_preference ("split_long_rows");
  1982.  
  1983.   return 0;
  1984. }
  1985.  
  1986. void
  1987. symbols_of_pr_output (void)
  1988. {
  1989.   DEFVAR (fixed_point_format, 0.0, fixed_point_format,
  1990.     "-*- texinfo -*-\n\
  1991. @defvr {Built-in Variable} fixed_point_format\n\
  1992. If the value of this variable is nonzero, Octave will scale all values\n\
  1993. in a matrix so that the largest may be written with one leading digit.\n\
  1994. The scaling factor is printed on the first line of output.  For example,\n\
  1995. \n\
  1996. @example\n\
  1997. @group\n\
  1998. octave:1> logspace (1, 7, 5)'\n\
  1999. ans =\n\
  2000. \n\
  2001.   1.0e+07  *\n\
  2002. \n\
  2003.   0.00000\n\
  2004.   0.00003\n\
  2005.   0.00100\n\
  2006.   0.03162\n\
  2007.   1.00000\n\
  2008. @end group\n\
  2009. @end example\n\
  2010. \n\
  2011. @noindent\n\
  2012. Notice that first value appears to be zero when it is actually 1.  For\n\
  2013. this reason, you should be careful when setting\n\
  2014. @code{fixed_point_format} to a nonzero value.\n\
  2015. \n\
  2016. The default value of @code{fixed_point_format} is 0.\n\
  2017. @end defvr");
  2018.  
  2019.   DEFVAR (output_max_field_width, 10.0, output_max_field_width,
  2020.     "-*- texinfo -*-\n\
  2021. @defvr {Built-in Variable} output_max_field_width\n\
  2022. This variable specifies the maximum width of a numeric output field.\n\
  2023. The default value is 10.\n\
  2024. @end defvr");
  2025.  
  2026.   DEFVAR (output_precision, 5.0, output_precision,
  2027.     "-*- texinfo -*-\n\
  2028. @defvr {Built-in Variable} output_precision\n\
  2029. This variable specifies the minimum number of significant figures to\n\
  2030. display for numeric output.  The default value is 5.\n\
  2031. @end defvr");
  2032.  
  2033.   DEFVAR (print_empty_dimensions, 1.0, print_empty_dimensions,
  2034.     "-*- texinfo -*-\n\
  2035. @defvr {Built-in Variable} print_empty_dimensions\n\
  2036. If the value of @code{print_empty_dimensions} is nonzero, the\n\
  2037. dimensions of empty matrices are printed along with the empty matrix\n\
  2038. symbol, @samp{[]}.  For example, the expression\n\
  2039. \n\
  2040. @example\n\
  2041. zeros (3, 0)\n\
  2042. @end example\n\
  2043. \n\
  2044. @noindent\n\
  2045. will print\n\
  2046. \n\
  2047. @example\n\
  2048. ans = [](3x0)\n\
  2049. @end example\n\
  2050. @end defvr");
  2051.  
  2052.   DEFVAR (split_long_rows, 1.0, split_long_rows,
  2053.     "-*- texinfo -*-\n\
  2054. @defvr {Built-in Variable} split_long_rows\n\
  2055. For large matrices, Octave may not be able to display all the columns of\n\
  2056. a given row on one line of your screen.  This can result in missing\n\
  2057. information or output that is nearly impossible to decipher, depending\n\
  2058. on whether your terminal truncates or wraps long lines.\n\
  2059. \n\
  2060. If the value of @code{split_long_rows} is nonzero, Octave will display\n\
  2061. the matrix in a series of smaller pieces, each of which can fit within\n\
  2062. the limits of your terminal width.  Each set of rows is labeled so that\n\
  2063. you can easily see which columns are currently being displayed.\n\
  2064. For example:\n\
  2065. \n\
  2066. @smallexample\n\
  2067. @group\n\
  2068. octave:13> rand (2,10)\n\
  2069. ans =\n\
  2070. \n\
  2071.  Columns 1 through 6:\n\
  2072. \n\
  2073.   0.75883  0.93290  0.40064  0.43818  0.94958  0.16467\n\
  2074.   0.75697  0.51942  0.40031  0.61784  0.92309  0.40201\n\
  2075. \n\
  2076.  Columns 7 through 10:\n\
  2077. \n\
  2078.   0.90174  0.11854  0.72313  0.73326\n\
  2079.   0.44672  0.94303  0.56564  0.82150\n\
  2080. @end group\n\
  2081. @end smallexample\n\
  2082. \n\
  2083. @noindent\n\
  2084. The default value of @code{split_long_rows} is nonzero.\n\
  2085. @end defvr");
  2086. }
  2087.  
  2088. /*
  2089. ;;; Local Variables: ***
  2090. ;;; mode: C++ ***
  2091. ;;; End: ***
  2092. */
  2093.