changeset 14636:3513df68d580

maint: periodic merge of default to jit
author Max Brister <max@2bass.com>
date Sat, 12 May 2012 19:39:44 -0600
parents 54ea692b8ab5 (current diff) 9e4ad3f1f291 (diff)
children 05bf75eaea2a
files build-aux/common.mk configure.ac doc/interpreter/munge-texi.cc scripts/gethelp.cc src/Makefile.am
diffstat 77 files changed, 585 insertions(+), 810 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags
+++ b/.hgtags
@@ -64,3 +64,4 @@
 e320928eeb3aa2370b792e83dafc3e0ddecdc871 release-3-2-4
 ba4d6343524b406b0d15aee34579f80783581c54 release-3-6-1
 704f7895eef03008dd79848eb9da4bfb40787d73 release-3-6-0
+f947d2922febf12dcd1fb6e21b356756ecb54e55 rc-3-6-2-0
--- a/build-aux/common.mk
+++ b/build-aux/common.mk
@@ -342,6 +342,9 @@
 # The full path to the default doc cache file.
 doc_cache_file = @doc_cache_file@
 
+# The full path to the default texi macros file.
+texi_macros_file_file = @texi_macros_file@
+
 # Where to install and expect the info files describing Octave..
 infodir = @infodir@
 
@@ -635,6 +638,7 @@
   -e "s|%OCTAVE_PREFIX%|\"${prefix}\"|" \
   -e "s|%OCTAVE_API_VERSION%|\"${api_version}\"|" \
   -e "s|%OCTAVE_RELEASE%|\"${OCTAVE_RELEASE}\"|" \
+  -e "s|%OCTAVE_TEXI_MACROS_FILE%|\"${texi_macros_file}\"|" \
   -e "s|%OCTAVE_VERSION%|\"${version}\"|"
 $(simple_move_if_change_rule)
 endef
--- a/configure.ac
+++ b/configure.ac
@@ -118,6 +118,7 @@
 OCTAVE_SET_DEFAULT(man1dir, '$(mandir)/man1')
 OCTAVE_SET_DEFAULT(man1ext, '.1')
 OCTAVE_SET_DEFAULT(doc_cache_file, '$(octetcdir)/doc-cache')
+OCTAVE_SET_DEFAULT(texi_macros_file, '$(octetcdir)/macros.texi')
 OCTAVE_SET_DEFAULT(infofile, '$(infodir)/octave.info')
 OCTAVE_SET_DEFAULT(octincludedir, '$(includedir)/octave-$(version)/octave')
 OCTAVE_SET_DEFAULT(fcnfiledir, '$(datadir)/octave/$(version)/m')
--- a/doc/interpreter/Makefile.am
+++ b/doc/interpreter/Makefile.am
@@ -179,23 +179,17 @@
 	@$(GREP) '#define HAVE_UMFPACK 1' $(top_builddir)/config.h > /dev/null || { echo "Documentation creation requires missing UMFPACK library.  Cannot package distribution!" ; exit 1; }
 	@$(GREP) '#define HAVE_QHULL 1' $(top_builddir)/config.h > /dev/null || { echo "Documentation creation requires missing QHULL library.  Cannot package distribution!" ; exit 1; }
 
-octetc_DATA = doc-cache
+octetc_DATA = doc-cache macros.texi
 
 DOCSTRING_FILES = $(shell $(srcdir)/find-docstring-files.sh "$(top_srcdir)")
 
 doc-cache: $(DOCSTRING_FILES) mk_doc_cache.m
-	$(top_builddir)/run-octave -f -q -H $(srcdir)/mk_doc_cache.m doc-cache $(DOCSTRING_FILES) || { rm -f doc-cache; exit 1; }
-
-## Program compiled only to help build documentation.  No need to install
-noinst_PROGRAMS = munge-texi
-
-munge_texi_SOURCES = munge-texi.cc
+	$(top_builddir)/run-octave -f -q -H $(srcdir)/mk_doc_cache.m doc-cache $(srcdir)/macros.texi $(DOCSTRING_FILES) || { rm -f doc-cache; exit 1; }
 
 $(MUNGED_TEXI_SRC): $(DOCSTRING_FILES) $(munge_texi_SOURCES)
 
-%.texi: %.txi
-	@$(MAKE) $(AM_MAKEFLAGS) munge-texi$(BUILD_EXEEXT)
-	./munge-texi $(top_srcdir) $(DOCSTRING_FILES) < $< > $@-t
+%.texi: %.txi munge-texi.pl
+	$(PERL) $(srcdir)/munge-texi.pl $(top_srcdir) $(DOCSTRING_FILES) < $< > $@-t
 	mv $@-t $@
 
 contributors.texi: contributors.in
@@ -253,6 +247,7 @@
   images.mk \
   mk_doc_cache.m \
   mkcontrib.awk \
+  munge-texi.pl \
   octave.dvi \
   octave.html \
   octave.pdf \
--- a/doc/interpreter/basics.txi
+++ b/doc/interpreter/basics.txi
@@ -389,6 +389,8 @@
 
 @DOCSTRING(makeinfo_program)
 
+@DOCSTRING(texi_macros_file)
+
 @DOCSTRING(doc_cache_file)
 
 @DOCSTRING(suppress_verbose_help_message)
--- a/doc/interpreter/doccheck/aspell-octave.en.pws
+++ b/doc/interpreter/doccheck/aspell-octave.en.pws
@@ -534,6 +534,7 @@
 Mahalanobis
 makefile
 makefiles
+makeinfo
 Mandriva
 MANOVA
 manova
@@ -862,6 +863,7 @@
 stringanchors
 strncmp
 strncmpi
+strread
 struct
 structs
 subarrays
--- a/doc/interpreter/install.txi
+++ b/doc/interpreter/install.txi
@@ -196,7 +196,7 @@
 @end table
 
 If you wish to build Octave without GNU readline installed, you must use
-the @code{--disable-readline} option when running the configure script.
+the @option{--disable-readline} option when running the configure script.
 
 The following external software packages are optional but recommended:
 
new file mode 100644
--- /dev/null
+++ b/doc/interpreter/macros.texi
@@ -0,0 +1,65 @@
+@c Copyright (C) 2012 John W. Eaton
+@c
+@c This file is part of Octave.
+@c
+@c Octave is free software; you can redistribute it and/or modify it
+@c under the terms of the GNU General Public License as published by the
+@c Free Software Foundation; either version 3 of the License, or (at
+@c your option) any later version.
+@c 
+@c Octave is distributed in the hope that it will be useful, but WITHOUT
+@c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+@c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+@c for more details.
+@c 
+@c You should have received a copy of the GNU General Public License
+@c along with Octave; see the file COPYING.  If not, see
+@c <http://www.gnu.org/licenses/>.
+
+@c FIXME -- someday, we might replace this with @backslashchar, which
+@c has been added to Texinfo.
+
+@macro xbackslashchar
+\\
+@end macro
+
+@c The following macro is used for the on-line help system, but we don't
+@c want lots of `See also: foo, bar, and baz' strings cluttering the
+@c printed manual (that information should be in the supporting text for
+@c each group of functions and variables).
+
+@macro seealso {args}
+@iftex
+@vskip 2pt
+@end iftex
+@ifnottex
+@c Texinfo @sp should work but in practice produces ugly results for HTML.
+@c A simple blank line produces the correct behavior. 
+@c @sp 1
+
+@end ifnottex
+@noindent
+@strong{See also:} \args\.
+@end macro
+
+@c The following macro marks words that aspell should ignore during
+@c spellchecking.  Within Texinfo it has no effect as it merely replaces
+@c the macro call with the argument itself.
+
+@macro nospell {arg}
+\arg\
+@end macro
+
+@c The following macro works around a situation where the Info/plain text
+@c expansion of the @code{XXX} macro is `XXX'.  The use of the apostrophe
+@c can be confusing if the code segment itself ends with a transpose operator.
+@ifinfo
+@macro xcode{arg}
+\arg\
+@end macro
+@end ifinfo
+@ifnotinfo
+@macro xcode{arg}
+@code{\arg\}
+@end macro
+@end ifnotinfo
--- a/doc/interpreter/mk_doc_cache.m
+++ b/doc/interpreter/mk_doc_cache.m
@@ -38,17 +38,20 @@
     error ("unable to open %s for reading", file);
   else
     tmp = fread (fid, Inf, "*char")';
-    ## Strip off header lines
-    [~, text{i}] = strtok (tmp, doc_delim);
+    if (isempty (strfind (tmp, doc_delim)))
+      ## No delimiter, copy verbatim (this is the case for the file
+      ## containing macro definitions, for example).
+      text{i} = tmp;
+    else
+      ## Strip off header lines
+      [~, text{i}] = strtok (tmp, doc_delim);
+    endif
   endif
 endfor
 text = [text{:}, doc_delim];
 
-## Modify Octave-specific macros before passing to makeinfo
+## Strip Texinfo markers and docstring separators.
 text = regexprep (text, "-\\*- texinfo -\\*-[ \t]*[\r\n]*", "");
-text = regexprep (text, '@seealso *\{([^}]*)\}', "See also: $1.");
-text = regexprep (text, '@nospell *\{([^}]*)\}', "$1");
-text = regexprep (text, '@xcode *\{([^}]*)\}', "$1");
 text = strrep (text, '@', "@@");
 
 ## Write data to temporary file for input to makeinfo
deleted file mode 100644
--- a/doc/interpreter/munge-texi.cc
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
-
-Copyright (C) 1999-2012 John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3 of the License, or (at your
-option) any later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#include <cctype>
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <map>
-
-#include <cstdlib>
-#include <cstring>
-
-static std::string top_srcdir;
-
-static const char doc_delim = '';
-
-static std::map<std::string, std::string> help_text;
-
-static void
-fatal (const std::string& msg)
-{
-  std::cerr << msg << "\n";
-  exit (1);
-}
-
-static void
-usage (void)
-{
-  std::cerr << "usage: munge-texi TOP-SRCDIR DOCSTRING-FILE < file\n";
-  exit (1);
-}
-
-static std::string
-extract_symbol_name (std::istream& is)
-{
-  std::string symbol_name;
-
-  int c;
-  while ((c = is.get ()) != EOF && c != '\n')
-    symbol_name += static_cast<char> (c);
-
-  return symbol_name;
-}
-
-static std::string
-extract_docstring (std::istream& is)
-{
-  std::string doc;
-
-  int c;
-  while ((c = is.get ()) != EOF && c != doc_delim)
-    {
-      // Expand @seealso commands to Texinfo references.
-      if (c == '@')
-        {
-          char buf[16];
-          int i = 0;
-          buf[i++] = static_cast<char> (c);
-
-          if ((   buf[i++] = static_cast<char> (is.get ())) == 's'
-              && (buf[i++] = static_cast<char> (is.get ())) == 'e'
-              && (buf[i++] = static_cast<char> (is.get ())) == 'e'
-              && (buf[i++] = static_cast<char> (is.get ())) == 'a'
-              && (buf[i++] = static_cast<char> (is.get ())) == 'l'
-              && (buf[i++] = static_cast<char> (is.get ())) == 's'
-              && (buf[i++] = static_cast<char> (is.get ())) == 'o'
-              && (buf[i++] = static_cast<char> (is.get ())) == '{')
-            {
-              doc += "@seealso{";
-
-              bool first = true;
-
-              // process @seealso parameters
-              while ((c = is.get ()) != EOF
-                     && c != doc_delim
-                     && c != '}')
-                {
-                  // ignore whitespace and delimiters
-                  while (   c == ' '
-                         || c == '\t'
-                         || c == '\r'
-                         || c == '\n'
-                         || c == ',')
-                    {
-                      c = is.get ();
-                    }
-
-                  // test for end of @seealso
-                  if (c == '}')
-                    break;
-
-                  // get function name
-                  std::string function_name;
-                  do
-                    function_name += static_cast<char> (c);
-                  while ((c = is.get ()) != EOF
-                          && c != doc_delim
-                          && c != ' '
-                          && c != '\t'
-                          && c != '\r'
-                          && c != '\n'
-                          && c != ','
-                          && c != '}');
-                  if (first)
-                    first = false;
-                  else
-                    doc += ", ";
-
-                  if (function_name[0] == '@')
-                    function_name = "@" + function_name;
-
-                  doc += "@ref{doc-" + function_name + ",,"
-                    + function_name + "}";
-
-                  // test for end of @seealso
-                  if (c == '}')
-                    break;
-                }
-              if (c == '}')
-                doc += static_cast<char> (c);
-            }
-          else
-            {
-              for (int j = 0; j < i; j++)
-                doc += buf[j];
-            }
-        }
-      else
-        doc += static_cast<char> (c);
-    }
-  return doc;
-}
-
-static void
-skip_comments (std::ifstream& is)
-{
-  int c;
-
-  bool in_comment = false;
-
-  while ((c = is.get ()) != EOF)
-    {
-      if (c == '#')
-        in_comment = true;
-      else if (c == '\n')
-        in_comment = false;
-      else if (! (in_comment || ::isspace (c)))
-        {
-          is.putback (c);
-          break;
-        }
-    }
-}
-
-static void
-process_doc_file (const std::string& fname)
-{
-  std::ifstream infile (fname.c_str ());
-
-  if (infile)
-    {
-      skip_comments (infile);
-
-      if (infile.get () != doc_delim)
-        fatal ("invalid doc file format");
-
-      std::string symbol_name;
-
-      do
-        {
-          symbol_name = extract_symbol_name (infile);
-
-          if (! symbol_name.empty ())
-            {
-              std::string doc_string = extract_docstring (infile);
-
-              if (help_text.find (symbol_name) != help_text.end ())
-                std::cerr << "ignoring duplicate entry for "
-                          << symbol_name << "\n";
-              else
-                help_text[symbol_name] = doc_string;
-            }
-        }
-      while (! symbol_name.empty ());
-    }
-  else
-    fatal ("unable to open docfile");
-}
-
-static bool
-recover_from_macro (std::ostream& os, char *buf, int i)
-{
-  bool bol = false;
-
-  buf[i] = '\0';
-  os << buf;
-
-  if (buf[i - 1] == '\n')
-    bol = true;
-
-  return bol;
-}
-
-static void
-process_example_file (const std::string& file_name, std::ostream& os)
-{
-  std::ifstream infile (file_name.c_str ());
-
-  if (infile)
-    {
-      os << "@verbatim\n";
-
-      int c;
-      int clast = 0;
-
-      while ((c = infile.get ()) != EOF)
-        {
-          os << static_cast<char> (c);
-          clast = c;
-        }
-
-      if (clast != '\n')
-        os << "\n";
-
-      os << "@end verbatim\n";
-    }
-  else
-    fatal ("unable to open example file " + file_name);
-}
-
-static void
-process_texi_input_file (std::istream& is, std::ostream& os)
-{
-  os << "@c DO NOT EDIT!  Generated automatically by munge-texi.\n\n";
-
-  bool bol = true;
-
-  int c;
-  while ((c = is.get ()) != EOF)
-    {
-      if (bol)
-        {
-          if (c == '@')
-            {
-              char buf[16];
-              int i = 0;
-              buf[i++] = static_cast<char> (c);
-
-              buf[i++] = c = static_cast<char> (is.get ());
-
-              if (c == 'D')
-                {
-                  std::string symbol_name;
-
-                  if (   (buf[i++] = static_cast<char> (is.get ())) == 'O'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'C'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'S'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'T'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'R'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'I'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'N'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'G'
-                      && (buf[i++] = static_cast<char> (is.get ())) == '(')
-                    {
-                      while ((c = is.get ()) != EOF && c != ')')
-                        symbol_name += static_cast<char> (c);
-
-                      if (is.eof ())
-                        fatal ("end of file while reading @DOCSTRING command");
-                      else
-                        {
-                          std::string doc_string = help_text[symbol_name];
-
-                          size_t len = doc_string.length ();
-
-                          int j = 0;
-
-                          // If there is a leading comment with the file
-                          // name, copy it to the output.
-                          if (len > 1
-                              && doc_string[j] == '@'
-                              && doc_string[j+1] == 'c')
-                            {
-                              j = 2;
-                              while (doc_string[j++] != '\n')
-                                /* find eol */;
-
-                              os << doc_string.substr (0, j);
-                            }
-
-                          while (doc_string[j] == ' ')
-                            j++;
-
-                          if (doc_string.substr (j, 15) == "-*- texinfo -*-")
-                            {
-                              j += 15;
-
-                              while (isspace (doc_string[j]))
-                                j++;
-
-                              // Make `see also' references in functions
-                              // possible using @anchor{TAG} (new with
-                              // Texinfo 4.0).
-
-                              if (symbol_name[0] == '@')
-                                symbol_name = "@" + symbol_name;
-
-                              os << "@anchor{doc-" << symbol_name << "}\n";
-
-                              os << doc_string.substr (j);
-                            }
-                          else
-                            os << doc_string;
-                        }
-                    }
-                  else
-                    bol = recover_from_macro (os, buf, i);
-                }
-              else if (c == 'E')
-                {
-                  std::string file_name;
-
-                  if (   (buf[i++] = static_cast<char> (is.get ())) == 'X'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'A'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'M'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'P'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'L'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'E'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'F'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'I'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'L'
-                      && (buf[i++] = static_cast<char> (is.get ())) == 'E'
-                      && (buf[i++] = static_cast<char> (is.get ())) == '(')
-                    {
-                      while ((c = is.get ()) != EOF && c != ')')
-                        file_name += static_cast<char> (c);
-
-                      file_name = top_srcdir + "/examples/" + file_name;
-
-                      process_example_file (file_name, os);
-                    }
-                  else
-                    bol = recover_from_macro (os, buf, i);
-                }
-              else
-                bol = recover_from_macro (os, buf, i);
-            }
-          else
-            os.put (static_cast<char> (c));
-        }
-      else
-        {
-          if (c == '\n')
-            bol = true;
-
-          os.put (static_cast<char> (c));
-        }
-    }
-}
-
-int
-main (int argc, char **argv)
-{
-  int retval = 0;
-
-  if (argc > 1)
-    {
-      top_srcdir = *++argv;
-
-      while (*++argv)
-        process_doc_file (*argv);
-
-      process_texi_input_file (std::cin, std::cout);
-    }
-  else
-    {
-      usage ();
-
-      retval = 1;
-    }
-
-  return retval;
-
-}
new file mode 100755
--- /dev/null
+++ b/doc/interpreter/munge-texi.pl
@@ -0,0 +1,124 @@
+#!/usr/bin/perl -w
+
+# Validate program call
+die "usage: munge-texi TOP-SRCDIR DOCSTRING-FILE < file" if (@ARGV < 2);
+
+$top_srcdir = shift (@ARGV);
+
+# Constant patterns
+$doc_delim = qr/^\c_/;
+$tex_delim = qr/\Q-*- texinfo -*-\E/;
+$comment_line = qr/^\s*(?:$|#)/;
+# Pre-declare hash size for efficiency
+keys(%help_text) = 1800;
+
+################################################################################
+# Load DOCSTRINGS into memory while expanding @seealso references
+foreach $DOCSTRING_file (@ARGV)
+{
+   open (DOCFH, $DOCSTRING_file) or die "Unable to open $DOCSTRING_file\n";
+
+   # Skip comments
+   while (defined ($_ = <DOCFH>) and /$comment_line/o) {;}
+
+   # Validate DOCSTRING file format
+   die "invalid doc file format\n" if (! /$doc_delim/o);
+   
+   do 
+   {
+     chomp;
+     $symbol = substr ($_,1);
+     $docstring = extract_docstring ();
+     if ($help_text{$symbol})
+     {
+        warn "ignoring duplicate entry for $symbol\n";
+     }
+     else
+     {
+       $help_text{$symbol} = $docstring;
+     }
+
+   } while (! eof);
+
+}
+
+################################################################################
+# Process .txi to .texi by expanding @DOCSTRING, @EXAMPLEFILE macros
+
+# Add warning header
+print '@c DO NOT EDIT!  Generated automatically by munge-texi.',"\n\n";
+
+TXI_LINE: while (<STDIN>)
+{
+   if (/^\s*\@DOCSTRING\((\S+)\)/)
+   {
+      $func = $1;
+      $docstring = $help_text{$func};
+      if (! $docstring)
+      {
+        warn "no docstring entry for $func\n";
+        next TXI_LINE;
+      }
+
+      $func =~ s/^@/@@/;   # Texinfo uses @@ to produce '@'
+      $docstring =~ s/^$tex_delim$/\@anchor{doc-$func}/m;
+      print $docstring,"\n";
+
+      next TXI_LINE;
+   }
+   if (/^\s*\@EXAMPLEFILE\((\S+)\)/)
+   {
+      $fname = "$top_srcdir/examples/$1";
+      print '@verbatim',"\n";
+      open (EXAMPFH, $fname) or die "unable to open example file $fname\n";
+      while (<EXAMPFH>) 
+      { 
+         print $_;
+         print "\n" if (eof and substr ($_, -1) ne "\n");
+      }
+      close (EXAMPFH);
+      print '@end verbatim',"\n\n";
+
+      next TXI_LINE;
+   }
+
+   # pass ordinary lines straight through to output
+   print $_;
+}
+
+
+################################################################################
+# Subroutines 
+################################################################################
+sub extract_docstring
+{
+   my ($docstring, $arg_list, $func_list, $repl, $rest_of_line);
+   
+   while (defined ($_ = <DOCFH>) and ! /$doc_delim/o)
+   {
+      # expand any @seealso references
+      if (m'^@seealso{')
+      {
+         # Join multiple lines until full macro body found
+         while (! /}/m) { $_ .= <DOCFH>; }
+
+         ($arg_list, $rest_of_line) = m'^@seealso{(.*)}(.*)?'s;
+        
+         $func_list = $arg_list;
+         $func_list =~ s/\s+//gs;
+         $repl = "";
+         foreach $func (split (/,/, $func_list))
+         {
+            $func =~ s/^@/@@/;   # Texinfo uses @@ to produce '@'
+            $repl .= "\@ref{doc-$func,,$func}, ";
+         }
+         substr($repl,-2) = "";   # Remove last ', ' 
+         $_ = "\@seealso{$repl}$rest_of_line";
+      }
+
+      $docstring .= $_;
+   }
+
+   return $docstring;
+}
+
--- a/doc/interpreter/octave.texi
+++ b/doc/interpreter/octave.texi
@@ -19,46 +19,7 @@
 \input texinfo
 @setfilename octave.info
 
-@c The following macro is used for the on-line help system, but we don't
-@c want lots of `See also: foo, bar, and baz' strings cluttering the
-@c printed manual (that information should be in the supporting text for
-@c each group of functions and variables).
-
-@macro seealso {args}
-@iftex
-@vskip 2pt
-@end iftex
-@ifnottex
-@c Texinfo @sp should work but in practice produces ugly results for HTML.
-@c A simple blank line produces the correct behavior. 
-@c @sp 1
-
-@end ifnottex
-@noindent
-@strong{See also:} \args\.
-@end macro
-
-@c The following macro marks words that aspell should ignore during
-@c spellchecking.  Within Texinfo it has no effect as it merely replaces
-@c the macro call with the argument itself.
-
-@macro nospell {arg}
-\arg\
-@end macro
-
-@c The following macro works around a situation where the Info/plain text
-@c expansion of the @code{XXX} macro is `XXX'.  The use of the apostrophe
-@c can be confusing if the code segment itself ends with a transpose operator.
-@ifinfo
-@macro xcode{arg}
-\arg\
-@end macro
-@end ifinfo
-@ifnotinfo
-@macro xcode{arg}
-@code{\arg\}
-@end macro
-@end ifnotinfo
+@include macros.texi
 
 @ifinfo
 @format
--- a/liboctave/Array.cc
+++ b/liboctave/Array.cc
@@ -884,7 +884,8 @@
 // The default fill value.  Override if you want a different one.
 
 template <class T>
-const T& Array<T>::resize_fill_value ()
+T
+Array<T>::resize_fill_value (void) const
 {
   static T zero = T ();
   return zero;
@@ -1164,16 +1165,21 @@
 Array<T>::assign (const idx_vector& i, const idx_vector& j,
                   const Array<T>& rhs, const T& rfv)
 {
+  bool initial_dims_all_zero = dimensions.all_zero ();
+
   // Get RHS extents, discarding singletons.
   dim_vector rhdv = rhs.dims ();
+
   // Get LHS extents, allowing Fortran indexing in the second dim.
   dim_vector dv = dimensions.redim (2);
+
   // Check for out-of-bounds and form resizing dimensions.
   dim_vector rdv;
+
   // In the special when all dimensions are zero, colons are allowed
   // to inquire the shape of RHS.  The rules are more obscure, so we
   // solve that elsewhere.
-  if (dv.all_zero ())
+  if (initial_dims_all_zero)
     rdv = zero_dims_inquire (i, j, rhdv);
   else
     {
@@ -1267,6 +1273,8 @@
     assign (ia(0), ia(1), rhs, rfv);
   else if (ial > 0)
     {
+      bool initial_dims_all_zero = dimensions.all_zero ();
+
       // Get RHS extents, discarding singletons.
       dim_vector rhdv = rhs.dims ();
 
@@ -1279,7 +1287,7 @@
       // In the special when all dimensions are zero, colons are
       // allowed to inquire the shape of RHS.  The rules are more
       // obscure, so we solve that elsewhere.
-      if (dv.all_zero ())
+      if (initial_dims_all_zero)
         rdv = zero_dims_inquire (ia, rhdv);
       else
         {
--- a/liboctave/Array.h
+++ b/liboctave/Array.h
@@ -450,46 +450,69 @@
 
   Array<T> index (const Array<idx_vector>& ia) const;
 
-  static const T& resize_fill_value ();
+  virtual T resize_fill_value (void) const;
 
   // Resizing (with fill).
 
-  void resize1 (octave_idx_type n, const T& rfv = resize_fill_value ());
+  void resize1 (octave_idx_type n, const T& rfv);
+  void resize1 (octave_idx_type n) { resize1 (n, resize_fill_value ()); }
 
-  void resize (octave_idx_type n) GCC_ATTR_DEPRECATED
-    { resize1 (n); }
+  void resize (octave_idx_type n) GCC_ATTR_DEPRECATED { resize1 (n); }
 
-  void resize (octave_idx_type nr, octave_idx_type nc,
-               const T& rfv = resize_fill_value ()) GCC_ATTR_DEPRECATED
+  void resize (octave_idx_type nr, octave_idx_type nc, const T& rfv) GCC_ATTR_DEPRECATED
   {
     resize2 (nr, nc, rfv);
   }
 
-  void resize (const dim_vector& dv, const T& rfv = resize_fill_value ());
+  void resize (octave_idx_type nr, octave_idx_type nc) GCC_ATTR_DEPRECATED
+  {
+    resize2 (nr, nc, resize_fill_value ());
+  }
+
+  void resize (const dim_vector& dv, const T& rfv);
+  void resize (const dim_vector& dv) { resize (dv, resize_fill_value ()); }
 
   // Indexing with possible resizing and fill
   // FIXME -- this is really a corner case, that should better be
   // handled directly in liboctinterp.
 
-  Array<T> index (const idx_vector& i, bool resize_ok,
-                  const T& rfv = resize_fill_value ()) const;
+  Array<T> index (const idx_vector& i, bool resize_ok, const T& rfv) const;
+  Array<T> index (const idx_vector& i, bool resize_ok) const
+  {
+    return index (i, resize_ok, resize_fill_value ());
+  }
 
-  Array<T> index (const idx_vector& i, const idx_vector& j,
-                  bool resize_ok, const T& rfv = resize_fill_value ()) const;
+  Array<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok, const T& rfv) const;
+  Array<T> index (const idx_vector& i, const idx_vector& j, bool resize_ok) const
+  {
+    return index (i, j, resize_ok, resize_fill_value ());
+  }
 
-  Array<T> index (const Array<idx_vector>& ia,
-                  bool resize_ok, const T& rfv = resize_fill_value ()) const;
+  Array<T> index (const Array<idx_vector>& ia, bool resize_ok, const T& rfv) const;
+  Array<T> index (const Array<idx_vector>& ia, bool resize_ok) const
+  {
+    return index (ia, resize_ok, resize_fill_value ());
+  }
 
   // Indexed assignment (always with resize & fill).
 
-  void assign (const idx_vector& i, const Array<T>& rhs,
-               const T& rfv = resize_fill_value ());
+  void assign (const idx_vector& i, const Array<T>& rhs, const T& rfv);
+  void assign (const idx_vector& i, const Array<T>& rhs)
+  {
+    assign (i, rhs, resize_fill_value ());
+  }
 
-  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs,
-               const T& rfv = resize_fill_value ());
+  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs, const T& rfv);
+  void assign (const idx_vector& i, const idx_vector& j, const Array<T>& rhs)
+  {
+    assign (i, j, rhs, resize_fill_value ());
+  }
 
-  void assign (const Array<idx_vector>& ia, const Array<T>& rhs,
-               const T& rfv = resize_fill_value ());
+  void assign (const Array<idx_vector>& ia, const Array<T>& rhs, const T& rfv);
+  void assign (const Array<idx_vector>& ia, const Array<T>& rhs)
+  {
+    assign (ia, rhs, resize_fill_value ());
+  }
 
   // Deleting elements.
 
@@ -672,8 +695,11 @@
 
 private:
 
-  void resize2 (octave_idx_type nr, octave_idx_type nc,
-                const T& rfv = resize_fill_value ());
+  void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv);
+  void resize2 (octave_idx_type nr, octave_idx_type nc)                
+  {
+    resize2 (nr, nc, resize_fill_value ());
+  }
 
   static void instantiation_guard ();
 };
--- a/liboctave/CColVector.h
+++ b/liboctave/CColVector.h
@@ -132,8 +132,7 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexColumnVector& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, ComplexColumnVector& a);
 
-  void resize (octave_idx_type n,
-               const Complex& rfv = Array<Complex>::resize_fill_value ())
+  void resize (octave_idx_type n, const Complex& rfv = Complex (0))
   {
     Array<Complex>::resize (dim_vector (n, 1), rfv);
   }
--- a/liboctave/CMatrix.h
+++ b/liboctave/CMatrix.h
@@ -152,7 +152,7 @@
   ComplexColumnVector column (octave_idx_type i) const;
 
   void resize (octave_idx_type nr, octave_idx_type nc,
-               const Complex& rfv = resize_fill_value ())
+               const Complex& rfv = Complex (0))
   {
     MArray<Complex>::resize (dim_vector (nr, nc), rfv);
   }
@@ -378,9 +378,6 @@
 
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexMatrix& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, ComplexMatrix& a);
-
-  static Complex resize_fill_value (void) { return Complex (0.0, 0.0); }
-
 };
 
 extern OCTAVE_API ComplexMatrix conj (const ComplexMatrix& a);
--- a/liboctave/CNDArray.h
+++ b/liboctave/CNDArray.h
@@ -135,8 +135,6 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ComplexNDArray& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, ComplexNDArray& a);
 
-  static Complex resize_fill_value (void) { return Complex (0.0, 0.0); }
-
   //  bool all_elements_are_real (void) const;
   //  bool all_integers (double& max_val, double& min_val) const;
 
--- a/liboctave/CRowVector.h
+++ b/liboctave/CRowVector.h
@@ -112,8 +112,7 @@
   friend std::ostream& operator << (std::ostream& os, const ComplexRowVector& a);
   friend std::istream& operator >> (std::istream& is, ComplexRowVector& a);
 
-  void resize (octave_idx_type n,
-               const Complex& rfv = Array<Complex>::resize_fill_value ())
+  void resize (octave_idx_type n, const Complex& rfv = Complex (0))
   {
     Array<Complex>::resize (dim_vector (1, n), rfv);
   }
--- a/liboctave/DiagArray2.cc
+++ b/liboctave/DiagArray2.cc
@@ -82,16 +82,6 @@
 
 // A two-dimensional array with diagonal elements only.
 
-template <typename T>
-void
-DiagArray2<T>::check_idx (octave_idx_type r, octave_idx_type c) const
-{
-  if (r < 0 || r >= dim1 ())
-    gripe_index_out_of_range (2, 1, r+1, dim1 ());
-  if (c < 0 || c >= dim2 ())
-    gripe_index_out_of_range (2, 2, c+1, dim2 ());
-}
-
 template <class T>
 void
 DiagArray2<T>::resize (octave_idx_type r, octave_idx_type c,
@@ -121,3 +111,24 @@
 
   return result;
 }
+
+template <typename T>
+bool
+DiagArray2<T>::check_idx (octave_idx_type r, octave_idx_type c) const
+{
+  bool ok = true;
+
+  if (r < 0 || r >= dim1 ())
+    {
+      gripe_index_out_of_range (2, 1, r+1, dim1 ());
+      ok = false;
+    }
+
+  if (c < 0 || c >= dim2 ())
+    {
+      gripe_index_out_of_range (2, 2, c+1, dim2 ());
+      ok = false;
+    }
+
+  return ok;
+}
--- a/liboctave/DiagArray2.h
+++ b/liboctave/DiagArray2.h
@@ -119,22 +119,33 @@
   T& dgelem (octave_idx_type i)
     { return Array<T>::elem (i); }
 
-  void check_idx (octave_idx_type r, octave_idx_type c) const;
+  T checkelem (octave_idx_type r, octave_idx_type c) const
+    {
+      return check_idx (r, c) ? elem (r, c) : T (0);
+    }
 
   T operator () (octave_idx_type r, octave_idx_type c) const
     {
 #if defined (BOUNDS_CHECKING)
-      check_idx (r, c);
+      checkelem (r, c);
+#else
+      return elem (r, c);
 #endif
-      return elem (r, c);
+    }
+
+  T& checkelem (octave_idx_type r, octave_idx_type c)
+    {
+      static T zero (0);
+      return check_idx (r, c) ? elem (r, c) : zero;
     }
 
   T& operator () (octave_idx_type r, octave_idx_type c)
     {
 #if defined (BOUNDS_CHECKING)
-      check_idx (r, c);
+      return checkelem (r, c);
+#else
+      return elem (r, c);
 #endif
-      return elem (r, c);
     }
 
   // No checking.
@@ -150,8 +161,11 @@
   T dgxelem (octave_idx_type i) const
     { return Array<T>::xelem (i); }
 
-  void resize (octave_idx_type n, octave_idx_type m,
-               const T& rfv = Array<T>::resize_fill_value ());
+  void resize (octave_idx_type n, octave_idx_type m, const T& rfv);
+  void resize (octave_idx_type n, octave_idx_type m)
+  {
+    resize (n, m, Array<T>::resize_fill_value ());
+  }
 
   DiagArray2<T> transpose (void) const;
   DiagArray2<T> hermitian (T (*fcn) (const T&) = 0) const;
@@ -166,6 +180,10 @@
 
   void print_info (std::ostream& os, const std::string& prefix) const
     { Array<T>::print_info (os, prefix); }
+
+private:
+
+  bool check_idx (octave_idx_type r, octave_idx_type c) const;
 };
 
 #endif
--- a/liboctave/boolMatrix.h
+++ b/liboctave/boolMatrix.h
@@ -84,14 +84,10 @@
   friend std::istream& operator >> (std::istream& is, Matrix& a);
 #endif
 
-  void resize (octave_idx_type nr, octave_idx_type nc,
-               bool rfv = resize_fill_value ())
+  void resize (octave_idx_type nr, octave_idx_type nc, bool rfv = false)
   {
     Array<bool>::resize (dim_vector (nr, nc), rfv);
   }
-
-  static bool resize_fill_value (void) { return false; }
-
 };
 
 MM_BOOL_OP_DECLS (boolMatrix, boolMatrix, OCTAVE_API)
--- a/liboctave/boolNDArray.h
+++ b/liboctave/boolNDArray.h
@@ -96,8 +96,6 @@
   // friend std::ostream& operator << (std::ostream& os, const NDArray& a);
   // friend std::istream& operator >> (std::istream& is, NDArray& a);
 
-  static bool resize_fill_value (void) { return false; }
-
   //  bool all_elements_are_real (void) const;
   //  bool all_integers (double& max_val, double& min_val) const;
 
--- a/liboctave/chMatrix.h
+++ b/liboctave/chMatrix.h
@@ -86,8 +86,7 @@
 
   charMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type r2, octave_idx_type c2) const;
 
-  void resize (octave_idx_type nr, octave_idx_type nc,
-               char rfv = resize_fill_value ())
+  void resize (octave_idx_type nr, octave_idx_type nc, char rfv = 0)
   {
     Array<char>::resize (dim_vector (nr, nc), rfv);
   }
@@ -103,9 +102,6 @@
   friend std::ostream& operator << (std::ostream& os, const Matrix& a);
   friend std::istream& operator >> (std::istream& is, Matrix& a);
 #endif
-
-  static char resize_fill_value (void) { return '\0'; }
-
 };
 
 MS_CMP_OP_DECLS (charMatrix, char, OCTAVE_API)
--- a/liboctave/chNDArray.h
+++ b/liboctave/chNDArray.h
@@ -92,8 +92,6 @@
   // friend std::ostream& operator << (std::ostream& os, const charNDArray& a);
   // friend std::istream& operator >> (std::istream& is, charNDArray& a);
 
-  static char resize_fill_value (void) { return '\0'; }
-
   charNDArray diag (octave_idx_type k = 0) const;
 
   charNDArray diag (octave_idx_type m, octave_idx_type n) const;
--- a/liboctave/dColVector.h
+++ b/liboctave/dColVector.h
@@ -99,8 +99,7 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const ColumnVector& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, ColumnVector& a);
 
-  void resize (octave_idx_type n,
-               const double& rfv = Array<double>::resize_fill_value ())
+  void resize (octave_idx_type n, const double& rfv = 0)
   {
     Array<double>::resize (dim_vector (n, 1), rfv);
   }
--- a/liboctave/dMatrix.h
+++ b/liboctave/dMatrix.h
@@ -125,8 +125,7 @@
 
   ColumnVector column (octave_idx_type i) const;
 
-  void resize (octave_idx_type nr, octave_idx_type nc,
-               double rfv = resize_fill_value ())
+  void resize (octave_idx_type nr, octave_idx_type nc, double rfv = 0)
   {
     MArray<double>::resize (dim_vector (nr, nc), rfv);
   }
@@ -334,8 +333,6 @@
 
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const Matrix& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, Matrix& a);
-
-  static double resize_fill_value (void) { return 0; }
 };
 
 // Publish externally used friend functions.
--- a/liboctave/dNDArray.h
+++ b/liboctave/dNDArray.h
@@ -150,8 +150,6 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const NDArray& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, NDArray& a);
 
-  static double resize_fill_value (void) { return 0; }
-
   NDArray diag (octave_idx_type k = 0) const;
 
   NDArray diag (octave_idx_type m, octave_idx_type n) const;
--- a/liboctave/dRowVector.h
+++ b/liboctave/dRowVector.h
@@ -92,8 +92,7 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const RowVector& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, RowVector& a);
 
-  void resize (octave_idx_type n,
-               const double& rfv = Array<double>::resize_fill_value ())
+  void resize (octave_idx_type n, const double& rfv = 0)
   {
     Array<double>::resize (dim_vector (1, n), rfv);
   }
--- a/liboctave/dim-vector.cc
+++ b/liboctave/dim-vector.cc
@@ -272,16 +272,11 @@
     {
       dim_vector retval = alloc (n);
 
-      int pad = 0;
       for (int i = 0; i < n_dims; i++)
-        {
-          retval.rep[i] = rep[i];
-          if (rep[i] != 0)
-            pad = 1;
-        }
+        retval.rep[i] = rep[i];
 
       for (int i = n_dims; i < n; i++)
-        retval.rep[i] = pad;
+        retval.rep[i] = 1;
 
       return retval;
     }
--- a/liboctave/dim-vector.h
+++ b/liboctave/dim-vector.h
@@ -381,8 +381,7 @@
   // Force certain dimensionality, preserving numel ().  Missing
   // dimensions are set to 1, redundant are folded into the trailing
   // one.  If n = 1, the result is 2d and the second dim is 1
-  // (dim_vectors are always at least 2D).  If the original dimensions
-  // were all zero, the padding value is zero.
+  // (dim_vectors are always at least 2D).
 
   dim_vector redim (int n) const;
 
--- a/liboctave/fCColVector.h
+++ b/liboctave/fCColVector.h
@@ -134,8 +134,7 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexColumnVector& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatComplexColumnVector& a);
 
-  void resize (octave_idx_type n,
-               const FloatComplex& rfv = Array<FloatComplex>::resize_fill_value ())
+  void resize (octave_idx_type n, const FloatComplex& rfv = FloatComplex (0))
   {
     Array<FloatComplex>::resize (dim_vector (n, 1), rfv);
   }
--- a/liboctave/fCMatrix.h
+++ b/liboctave/fCMatrix.h
@@ -157,7 +157,7 @@
   FloatComplexColumnVector column (octave_idx_type i) const;
 
   void resize (octave_idx_type nr, octave_idx_type nc,
-               const FloatComplex& rfv = resize_fill_value ())
+               const FloatComplex& rfv = FloatComplex (0))
   {
     MArray<FloatComplex>::resize (dim_vector (nr, nc), rfv);
   }
@@ -383,9 +383,6 @@
 
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexMatrix& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatComplexMatrix& a);
-
-  static FloatComplex resize_fill_value (void) { return FloatComplex (0.0, 0.0); }
-
 };
 
 extern OCTAVE_API FloatComplexMatrix conj (const FloatComplexMatrix& a);
--- a/liboctave/fCNDArray.h
+++ b/liboctave/fCNDArray.h
@@ -135,8 +135,6 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatComplexNDArray& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatComplexNDArray& a);
 
-  static FloatComplex resize_fill_value (void) { return FloatComplex (0.0, 0.0); }
-
   //  bool all_elements_are_real (void) const;
   //  bool all_integers (float& max_val, float& min_val) const;
 
--- a/liboctave/fCRowVector.h
+++ b/liboctave/fCRowVector.h
@@ -116,8 +116,7 @@
   friend std::ostream& operator << (std::ostream& os, const FloatComplexRowVector& a);
   friend std::istream& operator >> (std::istream& is, FloatComplexRowVector& a);
 
-  void resize (octave_idx_type n,
-               const FloatComplex& rfv = Array<FloatComplex>::resize_fill_value ())
+  void resize (octave_idx_type n, const FloatComplex& rfv = FloatComplex (0))
   {
     Array<FloatComplex>::resize (dim_vector (1, n), rfv);
   }
--- a/liboctave/fColVector.h
+++ b/liboctave/fColVector.h
@@ -102,8 +102,7 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatColumnVector& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatColumnVector& a);
 
-  void resize (octave_idx_type n,
-               const float& rfv = Array<float>::resize_fill_value ())
+  void resize (octave_idx_type n, const float& rfv = 0)
   {
     Array<float>::resize (dim_vector (n, 1), rfv);
   }
--- a/liboctave/fMatrix.h
+++ b/liboctave/fMatrix.h
@@ -126,8 +126,7 @@
 
   FloatColumnVector column (octave_idx_type i) const;
 
-  void resize (octave_idx_type nr, octave_idx_type nc,
-               float rfv = resize_fill_value ())
+  void resize (octave_idx_type nr, octave_idx_type nc, float rfv = 0)
   {
     MArray<float>::resize (dim_vector (nr, nc), rfv);
   }
@@ -334,9 +333,6 @@
 
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatMatrix& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatMatrix& a);
-
-  static float resize_fill_value (void) { return 0; }
-
 };
 
 // Publish externally used friend functions.
--- a/liboctave/fNDArray.h
+++ b/liboctave/fNDArray.h
@@ -147,8 +147,6 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatNDArray& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatNDArray& a);
 
-  static float resize_fill_value (void) { return 0; }
-
   FloatNDArray diag (octave_idx_type k = 0) const;
 
   FloatNDArray diag (octave_idx_type m, octave_idx_type n) const;
--- a/liboctave/fRowVector.h
+++ b/liboctave/fRowVector.h
@@ -93,8 +93,7 @@
   friend OCTAVE_API std::ostream& operator << (std::ostream& os, const FloatRowVector& a);
   friend OCTAVE_API std::istream& operator >> (std::istream& is, FloatRowVector& a);
 
-  void resize (octave_idx_type n,
-               const float& rfv = Array<float>::resize_fill_value ())
+  void resize (octave_idx_type n, const float& rfv = 0)
   {
     Array<float>::resize (dim_vector (1, n), rfv);
   }
--- a/liboctave/intNDArray.h
+++ b/liboctave/intNDArray.h
@@ -115,9 +115,6 @@
 
   static octave_idx_type compute_index (Array<octave_idx_type>& ra_idx,
                             const dim_vector& dimensions);
-
-  static T resize_fill_value (void) { return 0; }
-
 };
 
 // i/o
--- a/liboctave/str-vec.h
+++ b/liboctave/str-vec.h
@@ -88,7 +88,7 @@
     return longest;
   }
 
-  void resize (octave_idx_type n, const std::string& rfv = resize_fill_value ())
+  void resize (octave_idx_type n, const std::string& rfv = std::string ())
   {
     Array<std::string>::resize (dim_vector (n, 1), rfv);
   }
--- a/run-octave.in
+++ b/run-octave.in
@@ -45,6 +45,7 @@
 LOADPATH="$d1_path:$d2_path:$d3_path"
 IMAGEPATH="$top_srcdir/scripts/image"
 DOCFILE="$builddir/doc/interpreter/doc-cache"
+TEXIMACROSFILE="$top_srcdir/doc/interpreter/macros.texi"
 INFOFILE="$top_srcdir/doc/interpreter/octave.info"
 
 ## Checking for string equality below with prepended x's in order to
@@ -70,4 +71,4 @@
   exec $builddir/libtool --mode=execute $driver \
     "$builddir/src/octave" --no-init-path --path="$LOADPATH" \
     --image-path="$IMAGEPATH" --doc-cache-file="$DOCFILE" \
-    --info-file="$INFOFILE" "$@"
+    --texi-macros-file="$TEXIMACROSFILE" --info-file="$INFOFILE" "$@"
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -325,21 +325,17 @@
 	: > time/$(octave_dirstamp)
 
 if AMCOND_BUILD_DOCS
-## Program compiled only to help build documentation.  No installation needed.
-noinst_PROGRAMS = gethelp
 
-gethelp_SOURCES = gethelp.cc
-
-.DOCSTRINGS: $(FCN_FILES) $(GEN_FCN_FILES) mkdoc $(gethelp_SOURCES) Makefile
-	@$(MAKE) $(AM_MAKEFLAGS) gethelp$(BUILD_EXEEXT)
+.DOCSTRINGS: $(FCN_FILES) $(GEN_FCN_FILES) mkdoc.pl Makefile
 	if [ "x$(srcdir)" != "x." ] && [ -f $(srcdir)/DOCSTRINGS ] && [ ! -f DOCSTRINGS ]; then \
 		cp $(srcdir)/DOCSTRINGS DOCSTRINGS; \
 		touch -r $(srcdir)/DOCSTRINGS DOCSTRINGS; \
 	fi
 	@echo "creating .DOCSTRINGS from .m script files"
-	@$(srcdir)/mkdoc "$(srcdir)" $(FCN_FILES) -- $(GEN_FCN_FILES) > $@
+	@$(PERL) $(srcdir)/mkdoc.pl "$(srcdir)" $(FCN_FILES) -- $(GEN_FCN_FILES) > $@
 	$(top_srcdir)/build-aux/move-if-change $@ DOCSTRINGS
 	touch $@
+
 endif
 
 $(GEN_FCN_FILES) : %.m : %.in Makefile
@@ -427,7 +423,7 @@
   $(FCN_FILES_IN) \
   $(GEN_FCN_FILES) \
   DOCSTRINGS \
-  mkdoc \
+  mkdoc.pl \
   mk-pkg-add
 
 DISTCLEANFILES = \
deleted file mode 100644
--- a/scripts/gethelp.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
-
-Copyright (C) 1999-2012 John W. Eaton
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3 of the License, or (at your
-option) any later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#include <cstdio>
-
-#include <iostream>
-#include <string>
-
-static bool
-looks_like_octave_copyright (const std::string& s)
-{
-  // Perhaps someday we will want to do more here, so leave this as a
-  // separate function.
-
-  return (s.substr (0, 9) == "Copyright" || s.substr (0, 6) == "Author");
-}
-
-// Eat whitespace and comments from FFILE, returning the text of the
-// first block of comments that doesn't look like a copyright notice,
-
-static std::string
-extract_help_text (void)
-{
-  std::string help_txt;
-
-  bool first_comments_seen = false;
-  bool begin_comment = false;
-  bool have_help_text = false;
-  bool in_comment = false;
-  bool discard_space = true;
-  int c;
-
-  while ((c = std::cin.get ()) != EOF)
-    {
-      if (begin_comment)
-        {
-          if (c == '%' || c == '#')
-            continue;
-          else if (discard_space && c == ' ')
-            {
-              discard_space = false;
-              continue;
-            }
-          else
-            begin_comment = false;
-        }
-
-      if (in_comment)
-        {
-          if (! have_help_text)
-            {
-              first_comments_seen = true;
-              help_txt += static_cast<char> (c);
-            }
-
-          if (c == '\n')
-            {
-              in_comment = false;
-              discard_space = true;
-
-              if ((c = std::cin.get ()) != EOF)
-                {
-                  if (c == '\n')
-                    break;
-                }
-              else
-                break;
-            }
-        }
-      else
-        {
-          switch (c)
-            {
-            case ' ':
-            case '\t':
-              if (first_comments_seen)
-                have_help_text = true;
-              break;
-
-            case '\n':
-              if (first_comments_seen)
-                have_help_text = true;
-              continue;
-
-            case '%':
-            case '#':
-              begin_comment = true;
-              in_comment = true;
-              break;
-
-            default:
-              goto done;
-            }
-        }
-    }
-
- done:
-
-  if (! help_txt.empty ())
-    {
-      if (looks_like_octave_copyright (help_txt))
-        help_txt.resize (0);
-
-      if (help_txt.empty ())
-        help_txt = extract_help_text ();
-    }
-
-  return help_txt;
-}
-
-int
-main (int argc, char **argv)
-{
-  std::string name;
-  std::string file_name;
-
-  if (argc != 3)
-    {
-      std::cerr << "usage: gethelp name file-name\n";
-      return 1;
-    }
-  else
-    {
-      name = argv[1];
-      file_name = argv[2];
-    }
-
-  std::string help_text = extract_help_text ();
-
-  if (! help_text.empty ())
-    {
-      std::cout << "" << name << "\n"
-                << "@c " << name << " " << file_name << "\n"
-                << help_text;
-
-      if (help_text[help_text.length () - 1] != '\n')
-        std::cout << "\n";
-    }
-
-  return 0;
-}
--- a/scripts/help/__makeinfo__.m
+++ b/scripts/help/__makeinfo__.m
@@ -94,18 +94,15 @@
   ## Texinfo crashes if @end tex does not appear first on the line.
   text = regexprep (text, '^ +@end tex', '@end tex', 'lineanchors');
 
-  ## Handle @seealso macro
-  see_also_pat = '@seealso *\{(.*)\}';
-  args = regexp (text, see_also_pat, 'tokens');
-  for ii = 1:numel (args)
-    expanded = fsee_also (strtrim (strsplit (args{ii}{:}, ',', true)));
-    text = regexprep (text, see_also_pat, expanded, 'once');
-  endfor
-
-  ## Handle @nospell macro
-  text = regexprep (text, '@nospell *\{([^}]*)\}', "$1");
-  ## Handle @xcode macro
-  text = regexprep (text, '@xcode *\{([^}]*)\}', "$1");
+  file = texi_macros_file ();
+  fid = fopen (file, "r");
+  if (fid < 0)
+    error ("unable to open %s for reading", file);
+  else
+    macros_text = fread (fid, Inf, "*char")';
+    text = cstrcat (macros_text, text);
+  endif
+  fclose (fid);
 
   if (strcmpi (output_type, "texinfo"))
     status = 0;
--- a/scripts/io/textread.m
+++ b/scripts/io/textread.m
@@ -41,7 +41,7 @@
 ## delimiters.
 ## @end itemize
 ##
-## The optional input @var{n} specifes the number of data lines to read; in
+## The optional input @var{n} specifies the number of data lines to read; in
 ## this sense it differs slightly from the format repeat count in strread.
 ##
 ## @seealso{strread, load, dlmread, fscanf, textscan}
--- a/scripts/io/textscan.m
+++ b/scripts/io/textscan.m
@@ -53,9 +53,9 @@
 ## @end itemize
 ##
 ## When reading from a character string, optional input argument @var{n}
-## specifes the number of times @var{format} should be used (i.e., to limit
+## specifies the number of times @var{format} should be used (i.e., to limit
 ## the amount of data read).
-## When reading fro file, @var{n} specifes the number of data lines to read;
+## When reading fro file, @var{n} specifies the number of data lines to read;
 ## in this sense it differs slightly from the format repeat count in strread.
 ##
 ## The output @var{C} is a cell array whose length is given by the number
new file mode 100755
--- /dev/null
+++ b/scripts/mkdoc.pl
@@ -0,0 +1,104 @@
+#! /usr/bin/perl -w
+#
+# Copyright (C) 2012 Rik Wehbring
+#
+# This file is part of Octave.
+#
+# Octave is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# Octave is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+## Expecting arguments in this order:
+##
+##  SRCDIR SRCDIR-FILES ... -- LOCAL-FILES ...
+
+unless (@ARGV >= 2) { die "Usage: $0 srcdir m_filename1 ..." ; }
+
+$srcdir = shift (@ARGV) . '/';
+
+print <<__END_OF_MSG__;
+### DO NOT EDIT!
+###
+### This file is generated automatically from Octave source files.
+### Edit source files directly and run make to update this file.
+
+__END_OF_MSG__
+
+MFILE: foreach $m_fname (@ARGV)
+{
+  if ($m_fname eq "--")
+  {
+    $srcdir = "./";
+    next MFILE;
+  }
+
+  $full_fname = $srcdir . $m_fname;
+  next MFILE unless ( $full_fname =~ m{(.*)/(@|)([^/]*)/(.*)\.m} );
+  if ($2) {
+    $fcn = "$2$3/$4";
+  } else {
+    $fcn = $4;
+  }
+
+  @help_txt = mygethelp ($fcn, $full_fname);
+  next MFILE if ($help_txt[0] eq "");
+
+  print "$fcn\n";
+  print "\@c $fcn scripts/$m_fname\n";
+
+  foreach $_ (@help_txt)
+  {
+    s/^\s+\@/\@/ unless $in_example;
+    s/^\s+\@group/\@group/;
+    s/^\s+\@end\s+group/\@end group/;
+    $in_example = (/\s*\@example\b/ .. /\s*\@end\s+example\b/);
+    print $_;
+  }
+}
+
+################################################################################
+# Subroutines
+################################################################################
+sub mygethelp
+{
+  ($fcn, $fname) = @_[0..1]; 
+  open (FH, $fname) or return "";
+
+  do
+  {
+    @help_txt = ();
+
+    ## Advance to non-blank line
+    while (defined ($_ = <FH>) and /^\s*$/) {;}
+
+    if (! /^\s*(?:#|%)/ or eof (FH))
+    {
+      ## No comment block found.  Return empty string
+      close (FH);
+      return "";
+    }
+
+    ## Extract help text stopping when comment block ends
+    do
+    {
+      ## Remove comment characters at start of line
+      s/^\s*(?:#|%){1,2} ?//;
+      push (@help_txt, $_);
+    } until (! defined ($_ = <FH>) or ! /^\s*(?:#|%)/);
+
+  } until ($help_txt[0] !~ /^(?:Copyright|Author)/); 
+
+  close (FH);
+
+  return @help_txt;
+}
--- a/scripts/pkg/private/get_unsatisfied_deps.m
+++ b/scripts/pkg/private/get_unsatisfied_deps.m
@@ -18,7 +18,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{bad_deps} =} get_unsatisfied_deps (@var{desc},@var{installed_pkgs_lst})
+## @deftypefn {Function File} {@var{bad_deps} =} get_unsatisfied_deps (@var{desc}, @var{installed_pkgs_lst})
 ## Undocumented internal function.
 ## @end deftypefn
 
--- a/scripts/plot/hist.m
+++ b/scripts/plot/hist.m
@@ -149,7 +149,7 @@
   if (nargin > 2 && ! ischar (varargin{iarg}))
     ## Normalise the histogram.
     norm = varargin{iarg++};
-    freq = freq / rows (y) * norm;
+    freq = freq / sum(! isnan (y)) * norm;
   endif
 
   if (nargout > 0)
@@ -182,6 +182,10 @@
 %! assert (xx, [1,2,3]);
 %! assert (nn, [3,2,1]);
 %!test
+%! [nn,xx] = hist ([1 1 1 NaN NaN NaN 2 2 3],[1 2 3], 6);
+%! assert (xx, [1,2,3]);
+%! assert (nn, [3,2,1]);
+%!test
 %! [nn,xx] = hist ([[1:4]', [1:4]'], 3);
 %! assert (xx, [1.5;2.5;3.5]);
 %! assert (nn, [[2,1,1]',[2,1,1]']);
--- a/scripts/plot/print.m
+++ b/scripts/plot/print.m
@@ -21,7 +21,7 @@
 ## @deftypefnx {Function File} {} print (@var{options})
 ## @deftypefnx {Function File} {} print (@var{filename}, @var{options})
 ## @deftypefnx {Function File} {} print (@var{h}, @var{filename}, @var{options})
-## Print a graph, or save it to a file. Both output formatted for 
+## Print a graph, or save it to a file.  Both output formatted for 
 ## printing (PDF and PostScript), and many bitmapped and vector
 ## image formats are supported.
 ##
@@ -35,8 +35,8 @@
 ##
 ## For output to a printer, to a PostScript file, or a PDF file,
 ## the paper size is specified by the figure's @code{papersize}
-## property. The location and size of the image on the page are
-## specified by the figure's @code{paperposition} property. The
+## property.  The location and size of the image on the page are
+## specified by the figure's @code{paperposition} property.  The
 ## orientation of the page is specified by the figure's
 ## @code{paperorientation} property.
 ##
--- a/scripts/plot/shrinkfaces.m
+++ b/scripts/plot/shrinkfaces.m
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} shrinkfaces (@var{p}, @var{sf})
+## @deftypefn  {Function File} {} shrinkfaces (@var{p}, @var{sf})
 ## @deftypefnx {Function File} {@var{nfv} =} shrinkfaces (@var{p}, @var{sf})
 ## @deftypefnx {Function File} {@var{nfv} =} shrinkfaces (@var{fv}, @var{sf})
 ## @deftypefnx {Function File} {@var{nfv} =} shrinkfaces (@var{f}, @var{v}, @var{sf})
@@ -40,7 +40,7 @@
 ## Performing the shrinking on faces which are not convex can lead to
 ## undesired results.
 ##
-## For example
+## For example,
 ##
 ## @example
 ## @group
@@ -57,7 +57,7 @@
 ## @end example
 ##
 ## @noindent
-## draws a triangulated 3/4 circle and the corresponding shrinked
+## draws a triangulated 3/4 circle and the corresponding shrunken
 ## version.
 ## @seealso{patch}
 ## @end deftypefn
--- a/scripts/plot/tetramesh.m
+++ b/scripts/plot/tetramesh.m
@@ -17,9 +17,9 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} tetramesh (@var{T}, @var{X})
-## @deftypefnx {Function File} tetramesh (@var{T}, @var{X}, @var{C})
-## @deftypefnx {Function File} tetramesh (@dots{}, @var{property}, @var{val}, @dots{})
+## @deftypefn  {Function File} {} tetramesh (@var{T}, @var{X})
+## @deftypefnx {Function File} {} tetramesh (@var{T}, @var{X}, @var{C})
+## @deftypefnx {Function File} {} tetramesh (@dots{}, @var{property}, @var{val}, @dots{})
 ## @deftypefnx {Function File} {@var{h} =} tetramesh (@dots{})
 ##
 ## Display the tetrahedrons defined in the m-by-4 matrix @var{T}
--- a/scripts/polynomial/polyfit.m
+++ b/scripts/polynomial/polyfit.m
@@ -22,7 +22,7 @@
 ## @deftypefnx {Function File} {[@var{p}, @var{s}, @var{mu}] =} polyfit (@var{x}, @var{y}, @var{n})
 ## Return the coefficients of a polynomial @var{p}(@var{x}) of degree
 ## @var{n} that minimizes the least-squares-error of the fit to the points
-## @code{[@var{x}, @var{y}]}. If @var{n} is a logical vector, it is used
+## @code{[@var{x}, @var{y}]}.  If @var{n} is a logical vector, it is used
 ## as a mask to selectively force the corresponding polynomial
 ## coefficients to be used or ignored.
 ##
@@ -53,7 +53,7 @@
 ## @end table
 ##
 ## The second output may be used by @code{polyval} to calculate the
-## statistical error limits of the predicted values. In particular, the
+## statistical error limits of the predicted values.  In particular, the
 ## standard deviation of @var{p} coefficients is given by @*
 ## @code{sqrt (diag (s.C)/s.df)*s.normr}.
 ##
--- a/scripts/polynomial/splinefit.m
+++ b/scripts/polynomial/splinefit.m
@@ -17,18 +17,18 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{pp} =} splinefit (@var{x}, @var{y}, @var{breaks})
-## Fits a piecewise cubic spline with breaks (knots) @var{breaks} to the
+## @deftypefn {Function File} {@var{pp} =} splinefit (@var{x}, @var{y}, @var{breaks})
+## Fit a piecewise cubic spline with breaks (knots) @var{breaks} to the
 ## noisy data, @var{x} and @var{y}.  @var{x} is a vector, and @var{y}
-## a vector or ND array.  If @var{y} is an ND array, then @var{x}(j)
-## is matched to @var{y}(:,...,:,j).
+## a vector or N-D array.  If @var{y} is an N-D array, then @var{x}(j)
+## is matched to @var{y}(:,@dots{},:,j).
 ##
-## The fitted spline is returned as a piece-wise polynomial, @var{pp}, and
+## The fitted spline is returned as a piecewise polynomial, @var{pp}, and
 ## may be evaluated using @code{ppval}.
 ##
 ## @deftypefnx {Function File} {@var{pp} =} splinefit (@var{x}, @var{y}, @var{p})
 ## @var{p} is a positive integer defining the number of intervals along @var{x},
-## and @var{p}+1 is the number of breaks. The number of points in each interval
+## and @var{p}+1 is the number of breaks.  The number of points in each interval
 ## differ by no more than 1.
 ##
 ## @deftypefnx {Function File} {@var{pp} =} splinefit (@dots{}, "periodic", @var{periodic})
@@ -39,7 +39,7 @@
 ##
 ## The optional property @var{periodic} is a logical value which specifies
 ## whether a periodic boundary condition is applied to the spline.  The
-## length of the period  is @code{max(@var{breaks})-min(@var{breaks})}.
+## length of the period is @code{max(@var{breaks})-min(@var{breaks})}.
 ## The default value is @code{false}.
 ##
 ## The optional property @var{robust} is a logical value which specifies
@@ -65,12 +65,14 @@
 ## @table @asis
 ## @item "xc"
 ## Vector of the x-locations of the constraints.
+##
 ## @item "yc"
-## Constaining values at the locations, @var{xc}.
+## Constraining values at the locations, @var{xc}.
 ## The default is an array of zeros.
+##
 ## @item "cc"
 ## Coefficients (matrix).  The default is an array of ones.  The number of
-## rows is limited to the order of the piece-wise polynomials, @var{order}.
+## rows is limited to the order of the piecewise polynomials, @var{order}.
 ## @end table
 ##
 ## Constraints are linear combinations of derivatives of order 0 to
--- a/scripts/sparse/bicg.m
+++ b/scripts/sparse/bicg.m
@@ -15,7 +15,6 @@
 ## along with this program; If not, see <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-##
 ## @deftypefn  {Function File} {@var{x} =} bicg (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
 ## @deftypefnx {Function File} {@var{x} =} bicg (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P})
 ## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} bicg (@var{A}, @var{b}, @dots{})
--- a/scripts/sparse/bicgstab.m
+++ b/scripts/sparse/bicgstab.m
@@ -18,7 +18,6 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-##
 ## @deftypefn  {Function File} {@var{x} =} bicgstab (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
 ## @deftypefnx {Function File} {@var{x} =} bicgstab (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P})
 ## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} bicgstab (@var{A}, @var{b}, @dots{})
--- a/scripts/sparse/cgs.m
+++ b/scripts/sparse/cgs.m
@@ -18,7 +18,6 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-##
 ## @deftypefn  {Function File} {@var{x} =} cgs (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
 ## @deftypefnx {Function File} {@var{x} =} cgs (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P})
 ## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} cgs (@var{A}, @var{b}, @dots{})
--- a/src/Cell.cc
+++ b/src/Cell.cc
@@ -97,7 +97,7 @@
 // SV as possible.
 
 Cell::Cell (const dim_vector& dv, const string_vector& sv, bool trim)
-  : Array<octave_value> (dv, resize_fill_value ())
+  : Array<octave_value> (dv, Matrix ())
 {
   octave_idx_type n = sv.length ();
 
@@ -173,8 +173,7 @@
         idx_vector i = idx_arg(0).index_vector ();
 
         if (! error_state)
-          retval = Array<octave_value>::index (i, resize_ok,
-                                               resize_fill_value ());
+          retval = Array<octave_value>::index (i, resize_ok, Matrix ());
       }
       break;
 
@@ -187,8 +186,7 @@
             idx_vector j = idx_arg(1).index_vector ();
 
             if (! error_state)
-              retval = Array<octave_value>::index (i, j, resize_ok,
-                                                    resize_fill_value ());
+              retval = Array<octave_value>::index (i, j, resize_ok, Matrix ());
           }
       }
       break;
@@ -206,8 +204,7 @@
           }
 
         if (!error_state)
-          retval = Array<octave_value>::index (iv, resize_ok,
-                                                resize_fill_value ());
+          retval = Array<octave_value>::index (iv, resize_ok, Matrix ());
       }
       break;
     }
--- a/src/Cell.h
+++ b/src/Cell.h
@@ -48,10 +48,10 @@
   Cell (const octave_value_list& ovl);
 
   Cell (octave_idx_type n, octave_idx_type m,
-        const octave_value& val = resize_fill_value ())
+        const octave_value& val = Matrix ())
     : Array<octave_value> (dim_vector (n, m), val) { }
 
-  Cell (const dim_vector& dv, const octave_value& val = resize_fill_value ())
+  Cell (const dim_vector& dv, const octave_value& val = Matrix ())
     : Array<octave_value> (dv, val) { }
 
   Cell (const Array<octave_value>& c)
@@ -86,7 +86,7 @@
   using Array<octave_value>::assign;
 
   void assign (const octave_value_list& idx, const Cell& rhs,
-               const octave_value& fill_val = resize_fill_value ());
+               const octave_value& fill_val = Matrix ());
 
   Cell reshape (const dim_vector& new_dims) const
     { return Array<octave_value>::reshape (new_dims); }
@@ -110,7 +110,11 @@
   bool any_element_is_nan (void) const { return false; }
   bool is_true (void) const { return false; }
 
-  static octave_value resize_fill_value (void) { return Matrix (); }
+  octave_value resize_fill_value (void) const
+  {
+    static Matrix rfv;
+    return rfv;
+  }
 
   Cell diag (octave_idx_type k = 0) const;
 
--- a/src/DLD-FUNCTIONS/chol.cc
+++ b/src/DLD-FUNCTIONS/chol.cc
@@ -129,9 +129,9 @@
 \n\
 @end ifnottex\n\
 \n\
-For full matrices, if the \"lower\" flag is set only the lower triangular part\n\
-of the matrix is used for the factorization, otherwise the upper triangular\n\
-part is used.\n\
+For full matrices, if the \"lower\" flag is set only the lower triangular\n\
+part of the matrix is used for the factorization, otherwise the upper\n\
+triangular part is used.\n\
 \n\
 In general the lower triangular factorization is significantly faster for\n\
 sparse matrices.\n\
@@ -623,6 +623,7 @@
 Update or downdate a Cholesky@tie{}factorization.  Given an upper triangular\n\
 matrix @var{R} and a column vector @var{u}, attempt to determine another\n\
 upper triangular matrix @var{R1} such that\n\
+\n\
 @itemize @bullet\n\
 @item\n\
 @var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\
@@ -634,6 +635,7 @@
 @end itemize\n\
 \n\
 If @var{op} is \"-\", @var{info} is set to\n\
+\n\
 @itemize\n\
 @item 0 if the downdate was successful,\n\
 \n\
@@ -833,6 +835,7 @@
 @var{A1}, where @w{A1(p,p) = A}, @w{A1(:,j) = A1(j,:)' = u} and\n\
 @w{p = [1:j-1,j+1:n+1]}.  @w{u(j)} should be positive.\n\
 On return, @var{info} is set to\n\
+\n\
 @itemize\n\
 @item 0 if the insertion was successful,\n\
 \n\
--- a/src/DLD-FUNCTIONS/rand.cc
+++ b/src/DLD-FUNCTIONS/rand.cc
@@ -358,7 +358,10 @@
 \n\
 By default, the generator is initialized from @code{/dev/urandom} if it is\n\
 available, otherwise from CPU time, wall clock time, and the current\n\
-fraction of a second.\n\
+fraction of a second.  Note that this differs from @sc{matlab}, which\n\
+always initializes the state to the same state at startup.  To obtain\n\
+behavior comparable to @sc{matlab}, initialize with a deterministic state\n\
+vector in Octave's startup files (@pxref{Startup Files}).\n\
 \n\
 To compute the pseudo-random sequence, @code{rand} uses the Mersenne\n\
 Twister with a period of @math{2^{19937}-1} (See M. Matsumoto and\n\
--- a/src/data.cc
+++ b/src/data.cc
@@ -5477,7 +5477,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} mldivide (@var{x}, @var{y})\n\
 Return the matrix left division of @var{x} and @var{y}.\n\
-This function and @w{@xcode{x \\ y}} are equivalent.\n\
+This function and @w{@xcode{x @xbackslashchar{} y}} are equivalent.\n\
 @seealso{mrdivide, ldivide}\n\
 @end deftypefn")
 {
@@ -5594,7 +5594,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} ldivide (@var{x}, @var{y})\n\
 Return the element-by-element left division of @var{x} and @var{y}.\n\
-This function and @w{@xcode{x .\\ y}} are equivalent.\n\
+This function and @w{@xcode{x .@xbackslashchar{} y}} are equivalent.\n\
 @seealso{rdivide, mldivide}\n\
 @end deftypefn")
 {
--- a/src/defaults.cc
+++ b/src/defaults.cc
@@ -294,6 +294,16 @@
 }
 
 static void
+set_default_texi_macros_file (void)
+{
+  std::string def_file = subst_octave_home (OCTAVE_TEXI_MACROS_FILE);
+
+  std::string env_file = octave_env::getenv ("OCTAVE_TEXI_MACROS_FILE");
+
+  Vtexi_macros_file = env_file.empty () ? def_file : env_file;
+}
+
+static void
 set_default_info_file (void)
 {
   std::string std_info_file = subst_octave_home (OCTAVE_INFOFILE);
@@ -393,6 +403,8 @@
 
   set_default_doc_cache_file ();
 
+  set_default_texi_macros_file ();
+
   set_default_info_file ();
 
   set_default_info_prog ();
--- a/src/defaults.in.h
+++ b/src/defaults.in.h
@@ -56,6 +56,10 @@
 #define OCTAVE_DOC_CACHE_FILE %OCTAVE_DOC_CACHE_FILE%
 #endif
 
+#ifndef OCTAVE_TEXI_MACROS_FILE
+#define OCTAVE_TEXI_MACROS_FILE %OCTAVE_TEXI_MACROS_FILE%
+#endif
+
 #ifndef OCTAVE_EXEC_PREFIX
 #define OCTAVE_EXEC_PREFIX %OCTAVE_EXEC_PREFIX%
 #endif
--- a/src/help.cc
+++ b/src/help.cc
@@ -71,6 +71,11 @@
 // (--doc-cache-file file)
 std::string Vdoc_cache_file;
 
+// Name of the file containing local Texinfo macros that are prepended
+// to doc strings before processing.
+// (--texi-macros-file)
+std::string Vtexi_macros_file;
+
 // Name of the info file specified on command line.
 // (--info-file file)
 std::string Vinfo_file;
@@ -1291,6 +1296,30 @@
   return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (doc_cache_file);
 }
 
+DEFUN (texi_macros_file, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} texi_macros_file ()\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} texi_macros_file (@var{new_val})\n\
+@deftypefnx {Built-in Function} {} texi_macros_file (@var{new_val}, \"local\")\n\
+Query or set the internal variable that specifies the name of the\n\
+file containing Texinfo macros that are prepended to documentation strings\n\
+before they are passed to makeinfo.  The default value is \n\
+@file{@var{octave-home}/share/octave/@var{version}/etc/macros.texi},\n\
+in which @var{octave-home} is the root directory of the Octave installation,\n\
+and @var{version} is the Octave version number.\n\
+The default value may be overridden by the environment variable\n\
+@w{@env{OCTAVE_TEXI_MACROS_FILE}}, or the command line argument\n\
+@samp{--texi-macros-file NAME}.\n\
+\n\
+When called from inside a function with the \"local\" option, the variable is\n\
+changed locally for the function and any subroutines it calls.  The original\n\
+variable value is restored when exiting the function.\n\
+@seealso{makeinfo_program}\n\
+@end deftypefn")
+{
+  return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (texi_macros_file);
+}
+
 DEFUN (info_file, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} info_file ()\n\
@@ -1349,7 +1378,7 @@
 When called from inside a function with the \"local\" option, the variable is\n\
 changed locally for the function and any subroutines it calls.  The original\n\
 variable value is restored when exiting the function.\n\
-@seealso{info_file, info_program, doc, help}\n\
+@seealso{texi_macros_file, info_file, info_program, doc, help}\n\
 @end deftypefn")
 {
   return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (makeinfo_program);
--- a/src/help.h
+++ b/src/help.h
@@ -36,6 +36,11 @@
 // (--doc-cache-file file)
 extern std::string Vdoc_cache_file;
 
+// Name of the file containing local Texinfo macros that are prepended
+// to doc strings before processing.
+// (--texi-macros-file)
+extern std::string Vtexi_macros_file;
+
 // Name of the info file specified on command line.
 // (--info-file file)
 extern std::string Vinfo_file;
--- a/src/oct-map.cc
+++ b/src/oct-map.cc
@@ -557,7 +557,7 @@
       for (octave_idx_type i = 0; i < nf; i++)
         {
           if (fill)
-            xvals[i].resize (dv, Cell::resize_fill_value ());
+            xvals[i].resize (dv, Matrix ());
           else
             xvals[i].resize (dv);
         }
@@ -1160,7 +1160,7 @@
       for (octave_idx_type i = 0; i < nf; i++)
         {
           if (&xvals[i] != &ref)
-            xvals[i].resize (dimensions, Cell::resize_fill_value ());
+            xvals[i].resize (dimensions, Matrix ());
         }
 
       optimize_dimensions ();
@@ -1489,7 +1489,7 @@
               Cell tmp = contents(p);
 
               if (fill)
-                tmp.resize (dv, Cell::resize_fill_value ());
+                tmp.resize (dv, Matrix ());
               else
                 tmp.resize (dv);
 
@@ -1669,7 +1669,7 @@
       if (tmp_dims != dimensions)
         {
           for (iterator p = begin (); p != end (); p++)
-            contents(p).resize (tmp_dims, Cell::resize_fill_value ());
+            contents(p).resize (tmp_dims, Matrix ());
 
           dimensions = tmp_dims;
         }
--- a/src/oct-obj.h
+++ b/src/oct-obj.h
@@ -91,8 +91,7 @@
 
   bool empty (void) const { return length () == 0; }
 
-  void resize (octave_idx_type n, const octave_value& rfv
-               = Array<octave_value>::resize_fill_value ())
+  void resize (octave_idx_type n, const octave_value& rfv = octave_value ())
   {
     data.resize (dim_vector (1, n), rfv);
   }
--- a/src/octave.cc
+++ b/src/octave.cc
@@ -150,7 +150,8 @@
 #define NO_SITE_FILE_OPTION 11
 #define NO_WINDOW_SYSTEM_OPTION 12
 #define PERSIST_OPTION 13
-#define TRADITIONAL_OPTION 14
+#define TEXI_MACROS_FILE_OPTION 14
+#define TRADITIONAL_OPTION 15
 struct option long_opts[] =
   {
     { "braindead",        no_argument,       0, TRADITIONAL_OPTION },
@@ -176,6 +177,7 @@
     { "persist",          no_argument,       0, PERSIST_OPTION },
     { "quiet",            no_argument,       0, 'q' },
     { "silent",           no_argument,       0, 'q' },
+    { "texi-macros-file", required_argument, 0, TEXI_MACROS_FILE_OPTION },
     { "traditional",      no_argument,       0, TRADITIONAL_OPTION },
     { "verbose",          no_argument,       0, 'V' },
     { "version",          no_argument,       0, 'v' },
@@ -534,6 +536,7 @@
   --path PATH, -p PATH    Add PATH to head of function search path.\n\
   --persist               Go interactive after --eval or reading from FILE.\n\
   --silent, -q            Don't print message at startup.\n\
+  --texi-macros-file FILE Use Texinfo macros in FILE for makeinfo command.\n\
   --traditional           Set variables for closer MATLAB compatibility.\n\
   --verbose, -V           Enable verbose output in some cases.\n\
   --version, -v           Print version number and exit.\n\
@@ -811,6 +814,11 @@
           persist = true;
           break;
 
+        case TEXI_MACROS_FILE_OPTION:
+          if (optarg)
+            bind_internal_variable ("texi_macros_file", optarg);
+          break;
+
         case TRADITIONAL_OPTION:
           traditional = true;
           break;
--- a/src/ov-complex.cc
+++ b/src/ov-complex.cc
@@ -225,7 +225,7 @@
 {
   if (fill)
     {
-      ComplexNDArray retval (dv, ComplexNDArray::resize_fill_value ());
+      ComplexNDArray retval (dv, Complex (0));
 
       if (dv.numel ())
         retval(0) = scalar;
--- a/src/ov-float.cc
+++ b/src/ov-float.cc
@@ -79,7 +79,7 @@
 {
   if (fill)
     {
-      FloatNDArray retval (dv, NDArray::resize_fill_value());
+      FloatNDArray retval (dv, 0);
 
       if (dv.numel ())
         retval(0) = scalar;
--- a/src/ov-flt-complex.cc
+++ b/src/ov-flt-complex.cc
@@ -210,7 +210,7 @@
 {
   if (fill)
     {
-      FloatComplexNDArray retval (dv, FloatComplexNDArray::resize_fill_value ());
+      FloatComplexNDArray retval (dv, FloatComplex (0));
 
       if (dv.numel ())
         retval(0) = scalar;
--- a/src/ov-range.cc
+++ b/src/ov-range.cc
@@ -335,7 +335,7 @@
 {
   NDArray retval = array_value ();
   if (fill)
-    retval.resize (dv, NDArray::resize_fill_value ());
+    retval.resize (dv, 0);
   else
     retval.resize (dv);
   return retval;
--- a/src/ov-scalar.cc
+++ b/src/ov-scalar.cc
@@ -94,7 +94,7 @@
 {
   if (fill)
     {
-      NDArray retval (dv, NDArray::resize_fill_value());
+      NDArray retval (dv, 0);
 
       if (dv.numel ())
         retval(0) = scalar;
--- a/src/ov-str-mat.cc
+++ b/src/ov-str-mat.cc
@@ -143,7 +143,7 @@
 {
   charNDArray retval (matrix);
   if (fill)
-    retval.resize (dv, charNDArray::resize_fill_value ());
+    retval.resize (dv, 0);
   else
     retval.resize (dv);
   return octave_value (retval, is_sq_string () ? '\'' : '"');
--- a/src/ov-struct.cc
+++ b/src/ov-struct.cc
@@ -2133,6 +2133,8 @@
 %! assert (fieldnames (s), keys');
 
 %!assert (cell2struct ({1; 2}, {"a"; "b"}), struct ("a", 1, "b", 2));
+
+%!assert (cell2struct ({}, {"f"}, 3), struct ("f", {}));
 */
 
 
--- a/src/sparse.cc
+++ b/src/sparse.cc
@@ -78,7 +78,7 @@
 \n\
 @strong{Note}: if multiple values are specified with the same\n\
 @var{i}, @var{j} indices, the corresponding values in @var{s} will\n\
-be added. See @code{accumarray} for an example of how to produce different\n\
+be added.  See @code{accumarray} for an example of how to produce different\n\
 behavior, such as taking the minimum instead.\n\
 \n\
 The following are all equivalent:\n\