changeset 13661:8a1896fb82d4

Merge with Savannah
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Thu, 08 Sep 2011 00:06:43 -0500
parents 632f653a29a0 (current diff) 7600200a54c8 (diff)
children 32f4713142d8
files doc/interpreter/contributors.in
diffstat 31 files changed, 367 insertions(+), 164 deletions(-) [+]
line wrap: on
line diff
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -1,5 +1,10 @@
-((nil . ((indent-tabs-mode . nil)
-         (fill-column . 72)))
- (c-default-mode "gnu")
+((nil .
+      ((c-file-style . "gnu")
+       (indent-tabs-mode . nil)
+       (fill-column . 72)
+       (eval . (when (string-match "\\.h\\'" (buffer-file-name))
+                 (unless (string-match "/gnulib/" (buffer-file-name))
+                   (c++-mode)
+                   (c-set-style "gnu"))))))
  (change-log-mode . ((indent-tabs-mode . t)))
  (makefile-mode . ((indent-tabs-mode . t))))
--- a/doc/interpreter/contributors.in
+++ b/doc/interpreter/contributors.in
@@ -145,6 +145,7 @@
 G. D. McBain
 Alexander Mamonov
 Christoph Mayer
+JĂșlio Hoffimann Mendes
 Thorsten Meyer
 Petr Mikulik
 Stefan Monnier
--- a/liboctave/CColVector.cc
+++ b/liboctave/CColVector.cc
@@ -242,7 +242,7 @@
 ComplexColumnVector
 conj (const ComplexColumnVector& a)
 {
-  return do_mx_unary_map<Complex, Complex, std::conj> (a);
+  return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
 }
 
 // resize is the destructive equivalent for this one
--- a/liboctave/CMatrix.cc
+++ b/liboctave/CMatrix.cc
@@ -921,7 +921,7 @@
 ComplexMatrix
 conj (const ComplexMatrix& a)
 {
-  return do_mx_unary_map<Complex, Complex, std::conj> (a);
+  return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
 }
 
 // resize is the destructive equivalent for this one
--- a/liboctave/CNDArray.cc
+++ b/liboctave/CNDArray.cc
@@ -760,7 +760,7 @@
 ComplexNDArray
 conj (const ComplexNDArray& a)
 {
-  return do_mx_unary_map<Complex, Complex, std::conj> (a);
+  return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
 }
 
 ComplexNDArray&
--- a/liboctave/CRowVector.cc
+++ b/liboctave/CRowVector.cc
@@ -234,7 +234,7 @@
 ComplexRowVector
 conj (const ComplexRowVector& a)
 {
-  return do_mx_unary_map<Complex, Complex, std::conj> (a);
+  return do_mx_unary_map<Complex, Complex, std::conj<double> > (a);
 }
 
 // resize is the destructive equivalent for this one
--- a/liboctave/fCColVector.cc
+++ b/liboctave/fCColVector.cc
@@ -242,7 +242,7 @@
 FloatComplexColumnVector
 conj (const FloatComplexColumnVector& a)
 {
-  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj> (a);
+  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float> > (a);
 }
 
 // resize is the destructive equivalent for this one
--- a/liboctave/fCMatrix.cc
+++ b/liboctave/fCMatrix.cc
@@ -923,7 +923,7 @@
 FloatComplexMatrix
 conj (const FloatComplexMatrix& a)
 {
-  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj> (a);
+  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float> > (a);
 }
 
 // resize is the destructive equivalent for this one
--- a/liboctave/fCNDArray.cc
+++ b/liboctave/fCNDArray.cc
@@ -757,7 +757,7 @@
 FloatComplexNDArray
 conj (const FloatComplexNDArray& a)
 {
-  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj> (a);
+  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float> > (a);
 }
 
 FloatComplexNDArray&
--- a/liboctave/fCRowVector.cc
+++ b/liboctave/fCRowVector.cc
@@ -234,7 +234,7 @@
 FloatComplexRowVector
 conj (const FloatComplexRowVector& a)
 {
-  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj> (a);
+  return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float> > (a);
 }
 
 // resize is the destructive equivalent for this one
--- a/scripts/plot/cla.m
+++ b/scripts/plot/cla.m
@@ -90,9 +90,8 @@
 endfunction
 
 %!test
-%! hf = figure (1, "visible", "off");
-%! unwind_protect
-%!   clf
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect 
 %!   plot (1:10)
 %!   cla ()
 %!   kids = get (gca, "children");
--- a/scripts/plot/clf.m
+++ b/scripts/plot/clf.m
@@ -81,6 +81,13 @@
 %! unwind_protect  
 %!   l = line;
 %!   assert (!isempty (get (gcf, "children")));
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
 %!   clf;
 %!   assert (isempty (get (gcf, "children")));
 %! unwind_protect_cleanup
--- a/scripts/plot/findall.m
+++ b/scripts/plot/findall.m
@@ -46,8 +46,8 @@
 %!test
 %! hf = figure (1232, "visible", "off");
 %! unwind_protect  
-%!   h = findall;
-%!   all_handles = {"uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "root"; "figure"};
+%!   h = findall (hf);
+%!   all_handles = {"uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "uimenu"; "figure"};
 %!   assert (get (h, 'type'), all_handles)
 %! unwind_protect_cleanup
 %!   close (hf);
--- a/scripts/plot/findobj.m
+++ b/scripts/plot/findobj.m
@@ -248,12 +248,11 @@
 %! hf = figure (fign, "visible", "off");
 %! unwind_protect  
 %!   l = line;
-%!   obj = findobj ("type", "line");
+%!   obj = findobj (hf, "type", "line");
 %!   assert (l, obj);
-%!   assert (gca, findobj ("type", "axes"));
-%!   assert (fign, findobj ("type", "figure"));
-%!   assert (0, findobj ("type", "root"));
-%!   assert (isempty (findobj ("type", "xyzxyz")));
+%!   assert (gca, findobj (hf, "type", "axes"));
+%!   assert (fign, findobj (hf, "type", "figure"));
+%!   assert (isempty (findobj (hf, "type", "xyzxyz")));
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
--- a/scripts/plot/gcf.m
+++ b/scripts/plot/gcf.m
@@ -57,9 +57,7 @@
 %!test
 %! hf = figure (1232, "visible", "off");
 %! unwind_protect  
-%!   line;
-%!   clf;
-%!   assert (isempty (get (gcf, "children")));
+%!   assert (gcf, 1232);
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
--- a/scripts/plot/line.m
+++ b/scripts/plot/line.m
@@ -50,9 +50,9 @@
 %!   assert (get (h, "xdata"), [0 1], eps);
 %!   assert (get (h, "ydata"), [0 1], eps);
 %!   assert (get (h, "type"), "line");
-%!   assert (get (h, "color"), [0 0 0]);
-%!   assert (get (h, "linestyle"), "-");
-%!   assert (get (h, "linewidth"), 0.5, eps);
+%!   assert (get (h, "color"), get(0,'defaultlinecolor'));
+%!   assert (get (h, "linestyle"), get(0,'defaultlinelinestyle'));
+%!   assert (get (h, "linewidth"), get(0,'defaultlinelinewidth'), eps);
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
--- a/scripts/plot/loglog.m
+++ b/scripts/plot/loglog.m
@@ -61,10 +61,47 @@
 endfunction
 
 %!demo
+%! clf ();
 %! t = 1:0.01:10;
 %! x = sort ((t .* (1 + rand (size (t)))) .^ 2);
 %! y = ((t .* (1 + rand (size (t)))) .^ 2);
 %! loglog (x, y);
 
-## Remove from test statistics.  No real tests possible.
-%!assert (1)
+%!demo
+%! clf ();
+%! a = logspace (-5, 1, 10);
+%! b =-logspace (-5, 1, 10);
+%! 
+%! subplot (1, 2, 1)
+%! loglog (a, b)
+%! xlabel ('loglog (a, b)')
+%! 
+%! subplot (1, 2, 2)
+%! loglog (a, abs (b))
+%! set (gca, 'ydir', 'reverse')
+%! xlabel ('loglog (a, abs (b))')
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
+%!   a = logspace (-5, 1, 10);
+%!   b = logspace (-5, 1, 10);
+%!   loglog (a, b)
+%!   assert (get (gca, "yscale"), "log");
+%!   assert (get (gca, "xscale"), "log");
+%! unwind_protect_cleanup
+%! close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
+%!   a = logspace (-5, 1, 10);
+%!   b =-logspace (-5, 1, 10);
+%!   loglog (a, b)
+%!   axis tight
+%!   assert (all (get (gca, "ytick") < 0));
+%! unwind_protect_cleanup
+%! close (hf);
+%! end_unwind_protect
+
--- a/scripts/plot/semilogx.m
+++ b/scripts/plot/semilogx.m
@@ -65,5 +65,42 @@
 %! y = (x .* (1 + rand (size (x)))) .^ 2;
 %! semilogx (y, x);
 
-## Remove from test statistics.  No real tests possible.
-%!assert (1)
+%!demo
+%! clf ();
+%! a = logspace (-5, 1, 10);
+%! b =-logspace (-5, 1, 10);
+%! 
+%! subplot (1, 2, 1)
+%! semilogx (b, a)
+%! xlabel ('semilogx (a, b)')
+%! 
+%! subplot (1, 2, 2)
+%! semilogx (abs (b), a)
+%! set (gca, 'ydir', 'reverse')
+%! xlabel ('semilogx (a, abs (b))')
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
+%!   a = logspace (-5, 1, 10);
+%!   b = logspace (-5, 1, 10);
+%!   semilogx (a, b)
+%!   assert (get (gca, "xscale"), "log");
+%!   assert (get (gca, "yscale"), "linear");
+%! unwind_protect_cleanup
+%! close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
+%!   a = logspace (-5, 1, 10);
+%!   b =-logspace (-5, 1, 10);
+%!   semilogx (a, b)
+%!   axis tight
+%!   assert (all (get (gca, "ytick") < 0));
+%! unwind_protect_cleanup
+%! close (hf);
+%! end_unwind_protect
+
+
--- a/scripts/plot/semilogy.m
+++ b/scripts/plot/semilogy.m
@@ -66,5 +66,42 @@
 %! y = (x .* (1 + rand (size (x)))) .^ 2;
 %! semilogy (x, y);
 
-## Remove from test statistics.  No real tests possible.
-%!assert (1)
+%!demo
+%! clf ();
+%! a = logspace (-5, 1, 10);
+%! b =-logspace (-5, 1, 10);
+%! 
+%! subplot (1, 2, 1)
+%! semilogy (a, b)
+%! xlabel ('semilogy (a, b)')
+%! 
+%! subplot (1, 2, 2)
+%! semilogy (a, abs (b))
+%! set (gca, 'ydir', 'reverse')
+%! xlabel ('semilogy (a, abs (b))')
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
+%!   a = logspace (-5, 1, 10);
+%!   b = logspace (-5, 1, 10);
+%!   semilogy (a, b)
+%!   assert (get (gca, "yscale"), "log");
+%!   assert (get (gca, "xscale"), "linear");
+%! unwind_protect_cleanup
+%! close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure (1232, "visible", "off");
+%! unwind_protect  
+%!   a = logspace (-5, 1, 10);
+%!   b =-logspace (-5, 1, 10);
+%!   semilogy (a, b)
+%!   axis tight
+%!   assert (all (get (gca, "ytick") < 0));
+%! unwind_protect_cleanup
+%! close (hf);
+%! end_unwind_protect
+
+
--- a/scripts/plot/whitebg.m
+++ b/scripts/plot/whitebg.m
@@ -145,6 +145,8 @@
 endfunction
 
 %!test
+%! dac = get (0, "defaultaxescolor");
+%! dfc = get (0, "defaultfigurecolor");
 %! set (0, "defaultaxescolor", [1 1 1]);
 %! set (0, "defaultfigurecolor", [1 1 1]);
 %! hf = figure (1232, "visible", "off");
@@ -160,4 +162,6 @@
 %!   assert (get (gca, "color"), [0.2 0.2 0.2]);
 %! unwind_protect_cleanup
 %!   close (hf);
+%!   set (0, "defaultaxescolor", dac);
+%!   set (0, "defaultfigurecolor", dfc);
 %! end_unwind_protect
--- a/src/graphics.cc
+++ b/src/graphics.cc
@@ -5184,8 +5184,8 @@
         {
           if (xisinf (min_pos))
             {
-              // warning ("axis: logscale with no positive values to plot");
-              return retval;
+              // FIXME -- need to handle log plots with all negative data.
+              return default_lim ();
             }
 
           if (min_val <= 0)
--- a/src/ov-base.cc
+++ b/src/ov-base.cc
@@ -50,6 +50,7 @@
 #include "ov-str-mat.h"
 #include "ov-fcn-handle.h"
 #include "parse.h"
+#include "pr-output.h"
 #include "utils.h"
 #include "variables.h"
 
@@ -419,7 +420,9 @@
     {
       os << name << " =";
       newline (os);
-      newline (os);
+      if (! Vcompact_format)
+        newline (os);
+
       retval = true;
     }
 
@@ -435,7 +438,7 @@
 
   print (output_buf);
 
-  if (print_padding && pad_after)
+  if (print_padding  && pad_after && ! Vcompact_format)
     newline (output_buf);
 }
 
--- a/src/ov-class.cc
+++ b/src/ov-class.cc
@@ -1020,7 +1020,8 @@
   indent (os);
   os << name << " =";
   newline (os);
-  newline (os);
+  if (! Vcompact_format)
+    newline (os);
 
   return retval;
 }
--- a/src/ov-cx-sparse.cc
+++ b/src/ov-cx-sparse.cc
@@ -904,7 +904,7 @@
       ARRAY_MAPPER (atan, Complex, ::atan);
       ARRAY_MAPPER (atanh, Complex, ::atanh);
       ARRAY_MAPPER (ceil, Complex, ::ceil);
-      ARRAY_MAPPER (conj, Complex, std::conj);
+      ARRAY_MAPPER (conj, Complex, std::conj<double>);
       ARRAY_MAPPER (cos, Complex, std::cos);
       ARRAY_MAPPER (cosh, Complex, std::cosh);
       ARRAY_MAPPER (exp, Complex, std::exp);
--- a/src/ov-range.cc
+++ b/src/ov-range.cc
@@ -370,7 +370,9 @@
     {
       os << name << " =";
       newline (os);
-      newline (os);
+      if (! Vcompact_format)
+        newline (os);
+
       retval = true;
     }
 
--- a/src/ov-struct.cc
+++ b/src/ov-struct.cc
@@ -1335,11 +1335,14 @@
 
       increment_indent_level ();
 
-      newline (os);
+      if (! Vcompact_format)
+        newline (os);
+
       indent (os);
       os << "scalar structure containing the fields:";
       newline (os);
-      newline (os);
+      if (! Vcompact_format)
+        newline (os);
 
       increment_indent_level ();
 
--- a/src/ov.cc
+++ b/src/ov.cc
@@ -2690,25 +2690,6 @@
   octave_lazy_index::register_type ();
 }
 
-#if 0
-DEFUN (cast, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} cast (@var{val}, @var{type})\n\
-Convert @var{val} to the new data type @var{type}.\n\
-@seealso{class, typeinfo}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  if (args.length () == 2)
-    error ("cast: not implemented");
-  else
-    print_usage ();
-
-  return retval;
-}
-#endif
-
 DEFUN (sizeof, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} sizeof (@var{val})\n\
@@ -2726,6 +2707,12 @@
   return retval;
 }
 
+/*
+%!assert (sizeof (uint64 (ones (3))), 72)
+%!assert (sizeof (double (zeros (2,4))), 64)
+%!assert (sizeof ({"foo", "bar", "baaz"}), 10)
+*/
+
 DEFUN (subsref, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} subsref (@var{val}, @var{idx})\n\
@@ -2834,3 +2821,63 @@
 
   return retval;
 }
+
+/*
+%!test
+%! a = reshape ([1:25], 5,5);
+%! idx1 = substruct ( "()", {3, 3});
+%! idx2 = substruct ( "()", {2:2:5, 2:2:5});
+%! idx3 = substruct ( "()", {":", [1,5]});
+%! assert (subsref (a, idx1), 13)
+%! assert (subsref (a, idx2), [7 17; 9 19])
+%! assert (subsref (a, idx3), [1:5; 21:25]')
+%! a = subsasgn (a, idx1, 0);
+%! a = subsasgn (a, idx2, 0);
+%! a = subsasgn (a, idx3, 0);
+%! b = [0    6   11   16    0
+%!      0    0   12    0    0
+%!      0    8    0   18    0
+%!      0    0   14    0    0
+%!      0   10   15   20    0];
+%! assert (a,b);
+
+%!test
+%! c = num2cell (reshape ([1:25],5,5));
+%! idx1 = substruct  ( "{}", {3, 3});
+%! idx2 = substruct  ( "()", {2:2:5, 2:2:5});
+%! idx3 = substruct  ( "()", {":", [1,5]});
+%! idx2p = substruct  ( "{}", {2:2:5, 2:2:5});
+%! idx3p = substruct  ( "{}", {":", [1,5]});
+%! assert ({ subsref(c, idx1) }, {13})
+%! assert ({ subsref(c, idx2p) }, {7 9 17 19})
+%! assert ({ subsref(c, idx3p) }, num2cell ([1:5, 21:25]))
+%! c = subsasgn (c, idx1, 0);
+%! c = subsasgn (c, idx2, 0);
+%! c = subsasgn (c, idx3, 0);
+%! d = {0    6   11   16    0
+%!      0    0   12    0    0
+%!      0    8    0   18    0
+%!      0    0   14    0    0
+%!      0   10   15   20    0};
+%! assert (c,d);
+
+%!test
+%! s.a = "ohai";
+%! s.b = "dere";
+%! s.c = 42;
+%! idx1 = substruct (".", "a");
+%! idx2 = substruct (".", "b");
+%! idx3 = substruct (".", "c");
+%! assert (subsref (s, idx1), "ohai")
+%! assert (subsref (s, idx2), "dere")
+%! assert (subsref (s, idx3), 42)
+%! s = subsasgn (s, idx1, "Hello");
+%! s = subsasgn (s, idx2, "There");
+%! s = subsasgn (s, idx3, 163);
+%! t.a = "Hello";
+%! t.b = "There";
+%! t.c = 163;
+%! assert (s, t)
+
+*/
+
--- a/src/ov.h
+++ b/src/ov.h
@@ -987,9 +987,8 @@
   bool print_name_tag (std::ostream& os, const std::string& name) const
     { return rep->print_name_tag (os, name); }
 
-  void print_with_name (std::ostream& os, const std::string& name,
-                        bool print_padding = true) const
-    { rep->print_with_name (os, name, print_padding); }
+  void print_with_name (std::ostream& os, const std::string& name) const
+  { rep->print_with_name (os, name, true); }
 
   int type_id (void) const { return rep->type_id (); }
 
--- a/src/pr-output.cc
+++ b/src/pr-output.cc
@@ -103,7 +103,7 @@
 static int bit_format = 0;
 
 // TRUE means don't put newlines around the column number headers.
-static bool compact_format = false;
+bool Vcompact_format = false;
 
 // TRUE means use an e format.
 static bool print_e = false;
@@ -1658,7 +1658,7 @@
          << std::resetiosflags (std::ios::scientific|std::ios::left)
          << " *\n";
 
-      if (! compact_format)
+      if (! Vcompact_format)
         os << "\n";
     }
 }
@@ -1671,7 +1671,7 @@
     {
       if (col != 0)
         {
-          if (compact_format)
+          if (Vcompact_format)
             os << "\n";
           else
             os << "\n\n";
@@ -1688,7 +1688,7 @@
       else
         os << " Columns " << col + 1 << " through " << lim << ":\n";
 
-      if (! compact_format)
+      if (! Vcompact_format)
         os << "\n";
     }
 }
@@ -1956,7 +1956,10 @@
         }
       else
         {
-          os << "Diagonal Matrix\n\n";
+          os << "Diagonal Matrix\n";
+          if (! Vcompact_format)
+            os << "\n";
+
           pr_scale_header (os, scale);
 
           // kluge. Get the true width of a number.
@@ -1999,80 +2002,82 @@
         }
     }
 }
-#define PRINT_ND_ARRAY(os, nda, NDA_T, ELT_T, MAT_T) \
-  do \
-    { \
-      if (nda.is_empty ()) \
-        print_empty_nd_array (os, nda.dims (), pr_as_read_syntax); \
-      else \
-        { \
- \
-          int ndims = nda.ndims (); \
- \
-          dim_vector dims = nda.dims (); \
- \
-          Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);\
- \
-          octave_idx_type m = 1; \
- \
-          for (int i = 2; i < ndims; i++) \
-            m *= dims(i); \
- \
-          octave_idx_type nr = dims(0); \
-          octave_idx_type nc = dims(1); \
- \
-          for (octave_idx_type i = 0; i < m; i++) \
-            { \
-              octave_quit (); \
- \
-              std::string nm = "ans"; \
- \
-              if (m > 1) \
-                { \
-                  nm += "(:,:,"; \
- \
-                  std::ostringstream buf; \
- \
-                  for (int k = 2; k < ndims; k++) \
-                    { \
-                      buf << ra_idx(k) + 1; \
- \
-                      if (k < ndims - 1) \
-                        buf << ","; \
-                      else \
-                        buf << ")"; \
-                    } \
- \
-                  nm += buf.str (); \
-                } \
- \
-              Array<idx_vector> idx (dim_vector (ndims, 1)); \
- \
-              idx(0) = idx_vector (':'); \
-              idx(1) = idx_vector (':'); \
- \
-              for (int k = 2; k < ndims; k++) \
-                idx(k) = idx_vector (ra_idx(k)); \
- \
-              octave_value page \
-                = MAT_T (Array<ELT_T> (nda.index (idx), dim_vector (nr, nc))); \
- \
-              if (i != m - 1) \
-                { \
-                  page.print_with_name (os, nm); \
-                } \
-              else \
-                { \
-                  page.print_name_tag (os, nm); \
-                  page.print_raw (os); \
-                } \
-              \
-              if (i < m) \
-                NDA_T::increment_index (ra_idx, dims, 2); \
-            } \
-        } \
-    } \
-  while (0)
+
+template <typename NDA_T, typename ELT_T, typename MAT_T>
+void print_nd_array(std::ostream& os, const NDA_T& nda,
+                    bool pr_as_read_syntax)
+{
+
+  if (nda.is_empty ())
+    print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
+  else
+    {
+
+      int ndims = nda.ndims ();
+
+      dim_vector dims = nda.dims ();
+
+      Array<octave_idx_type> ra_idx (dim_vector (ndims, 1), 0);
+
+      octave_idx_type m = 1;
+
+      for (int i = 2; i < ndims; i++)
+        m *= dims(i);
+
+      octave_idx_type nr = dims(0);
+      octave_idx_type nc = dims(1);
+
+      for (octave_idx_type i = 0; i < m; i++)
+        {
+          octave_quit ();
+
+          std::string nm = "ans";
+
+          if (m > 1)
+            {
+              nm += "(:,:,";
+
+              std::ostringstream buf;
+
+              for (int k = 2; k < ndims; k++)
+                {
+                  buf << ra_idx(k) + 1;
+
+                  if (k < ndims - 1)
+                    buf << ",";
+                  else
+                    buf << ")";
+                }
+
+              nm += buf.str ();
+            }
+
+          Array<idx_vector> idx (dim_vector (ndims, 1));
+
+          idx(0) = idx_vector (':');
+          idx(1) = idx_vector (':');
+
+          for (int k = 2; k < ndims; k++)
+            idx(k) = idx_vector (ra_idx(k));
+
+          octave_value page
+            = MAT_T (Array<ELT_T> (nda.index (idx), dim_vector (nr, nc)));
+
+          if (i != m - 1)
+            {
+              page.print_with_name (os, nm);
+            }
+          else
+            {
+              page.print_name_tag (os, nm);
+              page.print_raw (os);
+            }
+
+          if (i < m)
+            NDA_T::increment_index (ra_idx, dims, 2);
+        }
+    }
+}
 
 void
 octave_print_internal (std::ostream& os, const NDArray& nda,
@@ -2087,7 +2092,7 @@
       break;
 
     default:
-      PRINT_ND_ARRAY (os, nda, NDArray, double, Matrix);
+      print_nd_array <NDArray, double, Matrix> (os, nda, pr_as_read_syntax);
       break;
     }
 }
@@ -2367,7 +2372,10 @@
         }
       else
         {
-          os << "Diagonal Matrix\n\n";
+          os << "Diagonal Matrix\n";
+          if (! Vcompact_format)
+            os << "\n";
+
           pr_scale_header (os, scale);
 
           // kluge. Get the true width of a number.
@@ -2512,7 +2520,9 @@
         }
       else
         {
-          os << "Permutation Matrix\n\n";
+          os << "Permutation Matrix\n";
+          if (! Vcompact_format)
+            os << "\n";
 
           for (octave_idx_type col = 0; col < nc; col += inc)
             {
@@ -2555,7 +2565,8 @@
       break;
 
     default:
-      PRINT_ND_ARRAY (os, nda, ComplexNDArray, Complex, ComplexMatrix);
+      print_nd_array <ComplexNDArray, Complex,
+                      ComplexMatrix> (os, nda, pr_as_read_syntax);
       break;
     }
 }
@@ -2756,7 +2767,8 @@
       break;
 
     default:
-      PRINT_ND_ARRAY (os, nda, boolNDArray, bool, boolMatrix);
+      print_nd_array<boolNDArray, bool,
+                     boolMatrix> (os, nda, pr_as_read_syntax);
       break;
     }
 }
@@ -2822,7 +2834,8 @@
       break;
 
     default:
-      PRINT_ND_ARRAY (os, nda, charNDArray, char, charMatrix);
+      print_nd_array <charNDArray, char,
+                      charMatrix> (os, nda, pr_as_read_syntax);
       break;
     }
 }
@@ -2840,8 +2853,8 @@
 octave_print_internal (std::ostream& os, const Array<std::string>& nda,
                        bool pr_as_read_syntax, int /* extra_indent */)
 {
-  // FIXME -- this mostly duplicates the code in the
-  // PRINT_ND_ARRAY macro.
+  // FIXME -- this mostly duplicates the code in the print_nd_array<>
+  // function. Can fix this with std::is_same from C++11.
 
   if (nda.is_empty ())
     print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
@@ -2904,7 +2917,9 @@
           octave_idx_type n_rows = page.rows ();
           octave_idx_type n_cols = page.cols ();
 
-          os << nm << " =\n\n";
+          os << nm << " =\n";
+          if (! Vcompact_format)
+            os << "\n";
 
           for (octave_idx_type ii = 0; ii < n_rows; ii++)
             {
@@ -3109,8 +3124,8 @@
 octave_print_internal_template (std::ostream& os, const intNDArray<T>& nda,
                                 bool pr_as_read_syntax, int extra_indent)
 {
-  // FIXME -- this mostly duplicates the code in the
-  // PRINT_ND_ARRAY macro.
+  // FIXME -- this mostly duplicates the code in the print_nd_array<>
+  // function. Can fix this with std::is_same from C++11.
 
   if (nda.is_empty ())
     print_empty_nd_array (os, nda.dims (), pr_as_read_syntax);
@@ -3152,7 +3167,9 @@
 
               nm += buf.str ();
 
-              os << nm << " =\n\n";
+              os << nm << " =\n";
+              if (! Vcompact_format)
+                os << "\n";
             }
 
           Array<idx_vector> idx (dim_vector (ndims, 1));
@@ -3257,7 +3274,9 @@
 
               nm += buf.str ();
 
-              os << nm << " =\n\n";
+              os << nm << " =\n";
+              if (! Vcompact_format)
+                os << "\n";
             }
 
           Array<idx_vector> idx (dim_vector (ndims, 1));
@@ -3539,7 +3558,7 @@
   bank_format = false;
   hex_format = 0;
   bit_format = 0;
-  compact_format = false;
+  Vcompact_format = false;
   print_e = false;
   print_big_e = false;
   print_g = false;
@@ -3714,11 +3733,11 @@
         }
       else if (arg == "compact")
         {
-          compact_format = true;
+          Vcompact_format = true;
         }
       else if (arg == "loose")
         {
-          compact_format = false;
+          Vcompact_format = false;
         }
       else
         error ("format: unrecognized format state `%s'", arg.c_str ());
@@ -3890,12 +3909,12 @@
 \n\
 @table @code\n\
 @item compact\n\
-Remove extra blank space around column number labels producing more compact\n\
-output with more data per page.\n\
+Remove blank lines around column number labels and between\n\
+matrices producing more compact output with more data per page.\n\
 \n\
 @item loose\n\
-Insert blank lines above and below column number labels to produce a more\n\
-readable output with less data per page.  (default).\n\
+Insert blank lines above and below column number labels and between matrices\n\
+to produce a more readable output with less data per page.  (default).\n\
 @end table\n\
 @seealso{fixed_point_format, output_max_field_width, output_precision, split_long_rows, rats}\n\
 @end deftypefn")
--- a/src/pr-output.h
+++ b/src/pr-output.h
@@ -256,4 +256,7 @@
 // like this: x = [](2x0).
 extern bool Vprint_empty_dimensions;
 
+// TRUE means don't put empty lines in output
+extern bool Vcompact_format;
+
 #endif
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1368,7 +1368,9 @@
 
       END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
 
-      if (nchars > -1 && nchars < size)
+      // Cast to avoid signed/unsigned comparison is safe due to
+      // short-circuiting
+      if (nchars > -1 && static_cast<size_t>(nchars) < size)
         break;
       else
         {