[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Q: Low hanging fruit?
From: |
David Bateman |
Subject: |
Re: Q: Low hanging fruit? |
Date: |
Wed, 12 Mar 2008 01:06:08 +0100 |
User-agent: |
Thunderbird 2.0.0.12 (X11/20080306) |
David Bateman wrote:
> John W. Eaton wrote:
>> On 11-Mar-2008, David Bateman wrote:
>>
>> | Ok, added that as well, together with some test code for the function.
>>
>> Please send dlmread/dlmwrite as hg changesets when they are ready.
>>
> Will do..
>
>> | size_t n =
>> str.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
>>
>> Is there a way to write this using isletter?
>>
> probably, though I might use Jaroslav's version of the spreadsheet
> format parser..
>
> regards
> David
>
>
>> jwe
>>
>>
>
>
Here is my changeset that adds these functions to Octave.
Regards
David
# HG changeset patch
# User David Bateman <address@hidden>
# Date 1205280294 -3600
# Node ID 3920cc2703d5942dc7f5e82396247e0205c3d9d2
# Parent fba7d54cf29efd15c10d39e668e4b07be2d8a376
Port dlmread, dlmwrite, csvread and csvwrite from octave-forge
diff --git a/doc/ChangeLog b/doc/ChangeLog
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,8 @@ 2008-02-25 Ben Abbott <address@hidden
+2008-03-12 David Bateman <address@hidden>
+
+ * interpreter/io.txi: Document dlmread, dlmwrite, csvread and
+ csvwrite.
+
2008-02-25 Ben Abbott <address@hidden>
* interpreter/geometryimages.m, interpreter/interpimages.m,
diff --git a/doc/interpreter/io.txi b/doc/interpreter/io.txi
--- a/doc/interpreter/io.txi
+++ b/doc/interpreter/io.txi
@@ -199,6 +199,17 @@ and @code{fclose}.
and @code{fclose}.
@DOCSTRING(fdisp)
+
+Octave can also read and write matrices text files such as comma
+separated lists.
+
address@hidden(dlmwrite)
+
address@hidden(dlmread)
+
address@hidden(csvwrite)
+
address@hidden(csvread)
@menu
* Saving Data on Unexpected Exits::
diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,9 @@ 2008-03-07 John W. Eaton <address@hidden
+2008-03-12 David Bateman <address@hidden>
+
+ * io/dlmwrite.m, io/csvread.m, io/csvwrite.m: Files ported from
+ octave-forge.
+ * io/Makefile.in (SOURCES): Add them here.
+
2008-03-07 John W. Eaton <address@hidden>
* plot/contourf.m: Set axes layer property to "top".
diff --git a/scripts/io/Makefile.in b/scripts/io/Makefile.in
--- a/scripts/io/Makefile.in
+++ b/scripts/io/Makefile.in
@@ -32,7 +32,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
-SOURCES = beep.m
+SOURCES = beep.m csvread.m csvwrite.m dlmwrite.m
DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
diff --git a/scripts/io/csvread.m b/scripts/io/csvread.m
new file mode 100644
--- /dev/null
+++ b/scripts/io/csvread.m
@@ -0,0 +1,30 @@
+## Copyright (C) 2001, 2008 Paul Kienzle
+##
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {x} = csvread (@var{filename})
+## Read the matrix @var{x} from a file.
+##
+## This function is equivalent to dlmread (@var{filename}, "," , ...)
+##
+## @seealso{dlmread, dlmwrite, csvwrite}
+## @end deftypefn
+
+function m = csvread (f, varargin)
+ m = dlmread (f, ',', varargin{:});
+endfunction
diff --git a/scripts/io/csvwrite.m b/scripts/io/csvwrite.m
new file mode 100644
--- /dev/null
+++ b/scripts/io/csvwrite.m
@@ -0,0 +1,30 @@
+## Copyright (C) 2001, 2008 Paul Kienzle
+##
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {x} = csvwrite (@var{filename}, @var{x})
+## Write the matrix @var{x} to a file.
+##
+## This function is equivalent to dlmwrite(@var{filename},@var{x},",",...)
+##
+## @seealso{dlmread, dlmwrite, csvread}
+## @end deftypefn
+
+function csvwrite(f, m, varargin)
+ dlmwrite (f, m, ',', varargin{:});
+endfunction
diff --git a/scripts/io/dlmwrite.m b/scripts/io/dlmwrite.m
new file mode 100644
--- /dev/null
+++ b/scripts/io/dlmwrite.m
@@ -0,0 +1,201 @@
+## Copyright (C) 2002, 2008 Paul Kienzle
+##
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} dlmwrite (@var{file}, @var{a})
+## @deftypefnx {Function File} {} dmlwrite (@var{file}, @var{a}, @var{delim},
@var{r}, @var{c})
+## @deftypefnx {Function File} {} dmlwrite (@var{file}, @var{a}, 'attrib1',
@var{value1}, 'attrib2', @var{value2}, @dots{})
+## @deftypefnx {Function File} {} dmlwrite (@var{file}, @var{a}, '-append',
@dots{})
+##
+## Write the matrix @var{a} to the text @var{file} using delimiters.
+##
+## @table @var
+## @item delim
+## the delimiter to use to separate values on a row
+##
+## @item r
+## the number of delimiter-only lines to add to the start of the file
+##
+## @item c
+## the number of delimiters to prepend to each line of data.
+##
+## @item '-append'
+## append to the end of the @var{file}.
+##
+## @item 'append', state
+## Either @samp{'on'} or @samp{'off'}. See @samp{'-append'} above.
+##
+## @item 'delimiter', d
+## See @var{delim} above.
+##
+## @item 'newline', os
+## The character(s) to use to separate each row. Three special cases
+## exist for this option. @samp{'unix'} is changed into "\n", @samp{'pc'} is
+## changed into "\r\n", and @samp{'mac'} is changed into "\r". Other
+## values for this option are kept as is.
+##
+## @item 'roffset', r
+## See @var{r} above.
+##
+## @item 'coffset', c
+## See @var{c} above.
+##
+## @item 'precision', p
+## The precision to use when writing the file. It can either be a
+## format string (as used by fprintf) or a number of significant digits.
+## @end table
+##
+## @example
+## @var{A} = reshape(1:16,4,4);
+## dlmwrite(@code{"file.csv"}, @var{A})
+## @end example
+##
+## Note the extra escaping of the backslashes necessary in using the
+## latex delimiter of "\\" with a unix style newline.
+##
+## @example
+## dlmwrite(@code{"file.tex"}, @var{a}, 'delimiter', '&', 'newline', '\\\\\n')
+## @end example
+##
+## @seealso{dlmread, csvread, csvwrite}
+## @end deftypefn
+
+## Author: Paul Kienzle <address@hidden>
+##
+## This program was originally granted to the public domain
+##
+## 2002-03-08 Paul Kienzle <address@hidden>
+## * Initial revision
+## 2005-11-27 Bill Denney <address@hidden>
+## * Significant modifications of the input arguements for additional
+## functionality.
+
+function dlmwrite (file, a, varargin)
+
+ if (nargin < 2 || ! ischar( file))
+ ptint_usage ();
+ endif
+
+ ## set defaults
+ delim = ",";
+ r = 0;
+ c = 0;
+ newline = "\n";
+ precision = "%.16g";
+ opentype = "wt";
+
+ ## process the input arguements
+ i = 0;
+ while (i < length (varargin))
+ i = i + 1;
+ if (strcmpi (varargin{i}, "delimiter"))
+ i = i + 1;
+ delim = varargin{i};
+ elseif (strcmpi (varargin{i}, "newline"))
+ i = i + 1;
+ newline = varargin{i};
+ if (strcmpi (newline, "unix"))
+ newline = "\n";
+ elseif (strcmpi (newline, "pc"))
+ newline = "\r\n";
+ elseif (strcmpi (newline, "mac"))
+ newline = "\r";
+ endif
+ elseif (strcmpi (varargin{i}, "roffset"))
+ i = i + 1;
+ r = varargin{i};
+ elseif (strcmpi (varargin{i}, "coffset"))
+ i = i + 1;
+ c = varargin{i};
+ elseif (strcmpi (varargin{i}, "precision"))
+ i = i + 1;
+ precision = varargin{i};
+ if (! strcmpi (class (precision), "char"))
+ precision = sprintf ("%.%gg", precision);
+ endif
+ elseif (strcmpi (varargin{i}, "-append"))
+ opentype = "at";
+ elseif (strcmpi (varargin{i}, "append"))
+ i = i + 1;
+ if (strcmpi (varargin{i}, "on"))
+ opentype = "at";
+ elseif (strcmpi (varargin{i}, "off"))
+ opentype = "wt";
+ else
+ error ("dlmwrite: append must be \"on\" or \"off\".");
+ endif
+ else
+ if (i == 1)
+ delim = varargin{i};
+ elseif (i == 2)
+ r = varargin{i};
+ elseif (i == 3)
+ c = varargin{i};
+ else
+ print_usage();
+ endif
+ endif
+ endwhile
+
+ [fid, msg] = fopen (file, opentype);
+ if (fid < 0)
+ error (msg);
+ else
+ if (r > 0)
+ fprintf (fid, "%s", repmat ([repmat(delim, 1, c + columns(a) - 1), ...
+ newline], 1, r));
+ endif
+ if (iscomplex (a))
+ cprecision = regexprep (precision, '^%([-\d.])','%+$1');
+ template = [precision, cprecision, "i", ...
+ repmat([delim, precision, cprecision, "i"], 1, ...
+ columns(a) - 1), newline ];
+ else
+ template = [precision, repmat([delim, precision], 1, columns(a) - 1),...
+ newline];
+ endif
+ if (c > 0)
+ template = [repmat(delim, 1, c), template];
+ endif
+ if (iscomplex (a))
+ a = a.';
+ b = zeros (2*rows(a), columns (a));
+ b(1: 2 : end, :) = real (a);
+ b(2: 2 : end, :) = imag (a);
+ fprintf (fid, template, b);
+ else
+ fprintf (fid, template, a.');
+ endif
+ fclose (fid);
+ endif
+endfunction
+
+%!test
+%! f = tmpnam();
+%!
dlmwrite(f,[1,2;3,4],'precision','%5.2f','newline','unix','roffset',1,'coffset',1);
+%! fid = fopen(f,"rt");
+%! f1 = char(fread(fid,Inf,'char')');
+%! fclose(fid);
+%!
dlmwrite(f,[5,6],'precision','%5.2f','newline','unix','coffset',1,'delimiter',',','-append');
+%! fid = fopen(f,"rt");
+%! f2 = char(fread(fid,Inf,'char')');
+%! fclose(fid);
+%! unlink(f);
+%!
+%! assert(f1,",,\n, 1.00, 2.00\n, 3.00, 4.00\n");
+%! assert(f2,",,\n, 1.00, 2.00\n, 3.00, 4.00\n, 5.00, 6.00\n");
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@ 2008-03-11 John W. Eaton <address@hidden
+2008-03-12 David Bateman <address@hidden>
+
+ * DLD-FUNCTIONS/dlmread.cc: Function ported from octave forge. Add
+ spreadsheet style ranges.
+ * MAkefile.in (DLD_XSRC): Add dlmread.cc.
+
2008-03-11 John W. Eaton <address@hidden>
* DLD-FUNCTIONS/eig.cc (Feig): Handle possible error from EIG.
diff --git a/src/DLD-FUNCTIONS/dlmread.cc b/src/DLD-FUNCTIONS/dlmread.cc
new file mode 100644
--- /dev/null
+++ b/src/DLD-FUNCTIONS/dlmread.cc
@@ -0,0 +1,421 @@
+/*
+
+Copyright (C) 2008 Jonathan Stickel
+
+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/>.
+
+*/
+
+/*
+ Adapted from previous version of dlmread.occ as authored by Kai Habel,
+ but core code has been completely re-written.
+*/
+
+#include <fstream>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "lo-ieee.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+static bool
+isletter (char c)
+{
+ return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
+}
+
+static bool
+read_cell_spec(std::istream& is, unsigned long& row, unsigned long& col)
+{
+
+ bool stat = false;
+
+ if (is.peek () == std::istream::traits_type::eof())
+ stat = true;
+ else
+ {
+ if (isletter (is.peek ()))
+ {
+
+ col = 0;
+ while (is && isletter (is.peek ()))
+ {
+ char ch = is.get ();
+ col *= 26;
+ if (ch >= 'a')
+ col += ch - 'a';
+ else
+ col += ch - 'A';
+ }
+
+ if (is)
+ {
+ is >> row;
+ row --;
+ if (is)
+ stat = true;
+ }
+ }
+ }
+
+ return stat;
+}
+
+static bool
+parse_range_spec(const octave_value& range_spec,
+ unsigned long& rlo, unsigned long& clo,
+ unsigned long& rup, unsigned long& cup)
+{
+ bool stat = true;
+
+ if (range_spec.is_string ())
+ {
+ std::istringstream is (range_spec.string_value ());
+ char ch = is.peek ();
+
+ if (ch == '.' || ch == ':')
+ {
+ rlo = 0;
+ clo = 0;
+ ch = is.get ();
+ if (ch == '.')
+ {
+ ch = is.get ();
+ if (ch != '.')
+ stat = false;
+ }
+ }
+ else
+ {
+ stat = read_cell_spec (is, rlo, clo);
+
+ if (stat)
+ {
+ ch = is.peek ();
+
+ if (ch == '.' || ch == ':')
+ {
+ ch = is.get ();
+ if (ch == '.')
+ {
+ ch = is.get ();
+ if (!is || ch != '.')
+ stat = false;
+ }
+
+ rup = ULONG_MAX - 1;
+ cup = ULONG_MAX - 1;
+ }
+ else
+ {
+ rup = rlo;
+ cup = clo;
+ if (!is || !is.eof ())
+ stat = false;
+ }
+ }
+ }
+
+ if (stat && is && !is.eof ())
+ stat = read_cell_spec (is, rup, cup);
+
+ if (! is || !is.eof ())
+ stat = false;
+ }
+ else if (range_spec.is_real_matrix () && range_spec.numel () == 4)
+ {
+ ColumnVector range(range_spec.vector_value());
+ // double --> unsigned int
+ rlo = static_cast<unsigned long> (range(0));
+ clo = static_cast<unsigned long> (range(1));
+ rup = static_cast<unsigned long> (range(2));
+ cup = static_cast<unsigned long> (range(3));
+ }
+ else
+ stat = false;
+
+ return stat;
+}
+
+DEFUN_DLD (dlmread, args, ,
+ "-*- texinfo -*-\n\
address@hidden {Loadable Function} address@hidden =} dlmread (@var{file})\n\
address@hidden {Loadable Function} address@hidden =} dlmread (@var{file},
@var{sep})\n\
address@hidden {Loadable Function} address@hidden =} dlmread (@var{file},
@var{sep}, @var{R0}, @var{C0})\n\
address@hidden {Loadable Function} address@hidden =} dlmread (@var{file},
@var{sep}, @var{range})\n\
+Read the matrix @var{data} from a text file. If not defined the separator\n\
+between fields is determined from the file itself. Otherwise the\n\
+separation character is defined by @var{sep}.\n\
+\n\
+Given two scalar arguments @var{r0} and @var{c0}, these define the starting\n\
+row and column of the data to be read. These values are indexed from zero,\n\
+such that the first row corresponds to an index of zero.\n\
+\n\
+The @var{range} parameter must be a 4 element vector containing the upper\n\
+left and lower right corner @address@hidden,@var{C0},@var{R1},@var{C1}]} or\n\
+a spreadsheet style range such as 'A2..Q15'. The lowest index value is zero.\n\
address@hidden deftypefn")
+{
+ octave_value_list retval;
+ int nargin = args.length();
+ bool sepflag = 0;
+ if (nargin < 1 || nargin > 4)
+ {
+ print_usage ();
+ return retval;
+ }
+
+ if ( !args (0).is_string() )
+ {
+ error ("dlmread: 1st argument must be a string");
+ return retval;
+ }
+
+ std::string fname (args(0).string_value());
+ std::ifstream file (fname.c_str());
+ if (!file)
+ {
+ error("dlmread: could not open file");
+ return retval;
+ }
+
+ // set default separator
+ std::string sep;
+ if (nargin > 1)
+ {
+ if (args(1).is_sq_string ())
+ sep = do_string_escapes (args(1).string_value());
+ else
+ sep = args(1).string_value();
+ }
+
+ unsigned long i = 0, j = 0, r = 1, c = 1, rmax = 0, cmax = 0;
+ std::string line;
+ std::string str;
+ Matrix rdata;
+ ComplexMatrix cdata;
+ bool iscmplx = false;
+ size_t pos1, pos2;
+
+ // take a subset if a range was given
+ unsigned long r0 = 0, c0 = 0, r1 = ULONG_MAX-1, c1 = ULONG_MAX-1;
+ if (nargin > 2)
+ {
+ if (nargin == 3)
+ {
+ if (! parse_range_spec(args (2), r0, c0, r1, c1))
+ error ("dlmread: error parsing range");
+ }
+ else if (nargin == 4)
+ {
+ r0 = args(2).ulong_value();
+ c0 = args(3).ulong_value();
+ }
+ }
+
+ if (!error_state)
+ {
+ unsigned long maxrows = r1 - r0;
+
+ // Skip the r0 leading lines as these might be a header
+ for (unsigned long m = 0; m < r0; m++)
+ getline (file, line);
+ r1 -= r0;
+
+
+ // read in the data one field at a time, growing the data matrix as
needed
+ while (getline (file, line))
+ {
+ // skip blank lines for compatibility
+ if (line.find_first_not_of (" \t") == NPOS)
+ continue;
+
+ //to be compatible with matlab, blank separator should correspond
+ //to whitespace as delimter;
+ if (! sep.length ())
+ {
+ size_t n = line.find_first_of (",:; \t",
+ line.find_first_of ("0123456789"));
+ if (n == NPOS)
+ {
+ sep = " \t";
+ sepflag = 1;
+ }
+ else
+ {
+ char ch = line.at (n);
+
+ switch (line.at (n))
+ {
+ case ' ':
+ case '\t':
+ sepflag = 1;
+ default:
+ sep = ch;
+ }
+ }
+ }
+
+ r = (r > i + 1 ? r : i + 1);
+ j = 0;
+ pos1 = 0;
+ do {
+ pos2 = line.find_first_of (sep, pos1);
+ str = line.substr (pos1, pos2 - pos1);
+
+ if (sepflag && pos2 != NPOS)
+ // treat consecutive separators as one
+ pos2 = line.find_first_not_of (sep, pos2) - 1;
+
+ c = (c > j + 1 ? c : j + 1);
+ if (r > rmax || c > cmax)
+ {
+ // use resize_and_fill for the case of not-equal length rows
+ if (iscmplx)
+ cdata.resize_and_fill (r, c, 0);
+ else
+ rdata.resize_and_fill (r, c, 0);
+ rmax = r;
+ cmax = c;
+ }
+
+ std::istringstream tmp_stream (str);
+ double x = octave_read_double (tmp_stream);
+ if (tmp_stream)
+ {
+ if (tmp_stream.eof())
+ if (iscmplx)
+ cdata (i, j++) = x;
+ else
+ rdata (i, j++) = x;
+ else
+ {
+ double y = octave_read_double (tmp_stream);
+
+ if (!iscmplx && y != 0.)
+ {
+ iscmplx = true;
+ cdata = ComplexMatrix (rdata);
+ }
+
+ if (iscmplx)
+ cdata (i, j++) = Complex (x, y);
+ else
+ rdata (i, j++) = x;
+ }
+ }
+ else if (iscmplx)
+ cdata (i, j++) = 0.;
+ else
+ rdata (i, j++) = 0.;
+
+ if (pos2 != NPOS)
+ pos1 = pos2 + 1;
+ else
+ pos1 = NPOS;
+
+ } while ( pos1 != NPOS );
+ if (nargin == 3 && i == maxrows)
+ break;
+ i++;
+ }
+
+ if (nargin > 2)
+ {
+ if (nargin == 3)
+ {
+ if (r1 >= r)
+ r1 = r - 1;
+ if (c1 >= c)
+ c1 = c - 1;
+ }
+ else if (nargin == 4)
+ {
+ // if r1 and c1 are not given, use what was found to be the
maximum
+ r1 = r - 1;
+ c1 = c - 1;
+ }
+
+ // now take the subset of the matrix
+ if (iscmplx)
+ {
+ cdata = cdata.extract (0, c0, r1, c1);
+ cdata.resize (r1 + 1, c1 - c0 + 1);
+ }
+ else
+ {
+ rdata = rdata.extract (0, c0, r1, c1);
+ rdata.resize (r1 + 1, c1 - c0 + 1);
+ }
+ }
+
+ if (iscmplx)
+ retval(0) = octave_value(cdata);
+ else
+ retval(0) = octave_value(rdata);
+ }
+
+ return retval;
+}
+
+/*
+
+%!shared file
+%! file = tmpnam ();
+%! fid = fopen (file, "wt");
+%! fwrite (fid, "1, 2, 3\n4, 5, 6\n7, 8, 9\n10, 11, 12");
+%! fclose (fid);
+
+%!assert (dlmread (file), [1, 2, 3; 4, 5, 6; 7, 8, 9;10, 11, 12]);
+%!assert (dlmread (file, ","), [1, 2, 3; 4, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ",", [1, 0, 2, 1]), [4, 5; 7, 8]);
+%!assert (dlmread (file, ",", "B1..C2"), [2, 3; 5, 6]);
+%!assert (dlmread (file, ",", "B1:C2"), [2, 3; 5, 6]);
+%!assert (dlmread (file, ",", "..C2"), [1, 2, 3; 4, 5, 6]);
+%!assert (dlmread (file, ",", 0, 1), [2, 3; 5, 6; 8, 9; 11, 12]);
+%!assert (dlmread (file, ",", "B1.."), [2, 3; 5, 6; 8, 9; 11, 12]);
+%!error (dlmread (file, ",", [0 1]))
+
+%!test
+%! unlink (file);
+
+%!shared file
+%! file = tmpnam ();
+%! fid = fopen (file, "wt");
+%! fwrite (fid, "1, 2, 3\n4+4i, 5, 6\n7, 8, 9\n10, 11, 12");
+%! fclose (fid);
+
+%!assert (dlmread (file), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ","), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ",", [1, 0, 2, 1]), [4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", "A2..B3"), [4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", "A2:B3"), [4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", "..B3"), [1, 2; 4 + 4i, 5; 7, 8]);
+%!assert (dlmread (file, ",", 1, 0), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!assert (dlmread (file, ",", "A2.."), [4 + 4i, 5, 6; 7, 8, 9; 10, 11, 12]);
+%!error (dlmread (file, ",", [0 1]))
+
+%!test
+%! unlink (file);
+
+*/
diff --git a/src/Makefile.in b/src/Makefile.in
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -64,8 +64,8 @@ OPT_INC := $(addprefix ../liboctave/, $(
DLD_XSRC := balance.cc besselj.cc betainc.cc bsxfun.cc cellfun.cc chol.cc \
ccolamd.cc colamd.cc colloc.cc conv2.cc convhulln.cc daspk.cc \
- dasrt.cc dassl.cc det.cc dispatch.cc dmperm.cc eig.cc expm.cc \
- fft.cc fft2.cc fftn.cc fftw.cc filter.cc find.cc fsolve.cc \
+ dasrt.cc dassl.cc det.cc dispatch.cc dlmread.cc dmperm.cc eig.cc \
+ expm.cc fft.cc fft2.cc fftn.cc fftw.cc filter.cc find.cc fsolve.cc \
gammainc.cc gcd.cc getgrent.cc getpwent.cc getrusage.cc \
givens.cc hess.cc inv.cc kron.cc lsode.cc \
lu.cc luinc.cc matrix_type.cc md5sum.cc minmax.cc pinv.cc qr.cc \
- Re: Q: Low hanging fruit?, (continued)
Re: Q: Low hanging fruit?, David Bateman, 2008/03/11
- Re: Q: Low hanging fruit?, Jaroslav Hajek, 2008/03/11
- Re: Q: Low hanging fruit?, David Bateman, 2008/03/11
- Re: Q: Low hanging fruit?, Jaroslav Hajek, 2008/03/11
- Re: Q: Low hanging fruit?, David Bateman, 2008/03/11
- Re: Q: Low hanging fruit?, Jaroslav Hajek, 2008/03/11
Re: Q: Low hanging fruit?, John W. Eaton, 2008/03/11
Re: Q: Low hanging fruit?, David Bateman, 2008/03/11
Re: Q: Low hanging fruit?,
David Bateman <=
Re: Q: Low hanging fruit?, John W. Eaton, 2008/03/11
Re: Q: Low hanging fruit?, David Bateman, 2008/03/12
Re: Q: Low hanging fruit?, David Bateman, 2008/03/12
Re: Q: Low hanging fruit?, John W. Eaton, 2008/03/12
Re: Q: Low hanging fruit?, Bill Denney, 2008/03/16
- Re: Q: Low hanging fruit?, David Bateman, 2008/03/16
- Re: Q: Low hanging fruit?, Ben Abbott, 2008/03/16
- Re: Q: Low hanging fruit?, Bill Denney, 2008/03/16
- Re: Q: Low hanging fruit?, Søren Hauberg, 2008/03/17
- Re: Q: Low hanging fruit?, Bill Denney, 2008/03/17