From bug-octave-request at bevo dot che dot wisc dot edu Wed Jan 1 21:13:17 2003 Subject: Bugs with strings, fread function From: "John W. Eaton" To: James Frye Cc: bug-octave at bevo dot che dot wisc dot edu Date: Wed, 1 Jan 2003 21:12:38 -0600 On 31-Dec-2002, James Frye wrote: | Problem with string arguments; | Problem with fread function. Your analysis was wrong in both cases, but thanks for the test cases. Please try the following patch. You'll need to set the built-in variable implicit_num_to_str_ok to a nonzero value for your script to work the way you expect. With my current sources, this is what I see when I run your test script: octave:3> implicit_num_to_str_ok = 1 implicit_num_to_str_ok = 1 octave:4> tst ('fname', 'tst.bin') --> Starting NEUROPLOT (last rev. 26July01; brain.cs.unr.edu for latest version)...ans = 84 parsearg: nargs = 2ans = tst.bin --> Trying to read binary file 'tst.bin'...fid = { id = 3 name = tst.bin mode = r arch = native status = open } --> File format is 'NCS 1.00'... --> nThings = 1, thingsize = 4. --> Title = TestSuite2 --> ReportOn = MyReport1 --> ReportOn = VOLTAGE --> Title = AI_1 --> Layer = layer_B --> Cell = Excitatory --> Cmp = soma_e1 ncs_data readoctave:5> jwe scripts/ChangeLog: 2003-01-01 John W. Eaton * strings/strcmp.m: Handle cell arrays of strings. src/ChangeLog: 2003-01-01 John W. Eaton * ov-base.cc (octave_base_value::char_matrix_value, octave_base_value::all_strings, octave_base_value::string_value): Attempt conversions here if Vimplicit_num_to_num_ok is true. * ov.cc (Vimplicit_num_to_str_ok): Move here from pt-mat.cc and make extern. * ov.h: Provide decl. * oct-stream.cc (printf_value_cache::looking_at_string): Delete. (printf_value_cache::string_value): Just attempt conversion. (octave_base_stream::do_printf): When doing '%s' format, just attempt converstion. * file-io.cc (Ffread): Allow size to be omitted even when additional arguments are given. Index: scripts/strings/strcmp.m =================================================================== RCS file: /usr/local/cvsroot/octave/scripts/strings/strcmp.m,v retrieving revision 1.20 diff -u -r1.20 strcmp.m --- scripts/strings/strcmp.m 14 Jul 2000 18:49:07 -0000 1.20 +++ scripts/strings/strcmp.m 2 Jan 2003 02:58:14 -0000 at @ -28,21 +28,116 @@ ## Author: jwe -function status = strcmp (s1, s2) +function retval = strcmp (s1, s2) if (nargin != 2) usage ("strcmp (s, t)"); endif - status = 0; - if (isstr (s1) && isstr(s2)) + retval = 0; + + if (isstr (s1)) + [r1, c1] = size (s1); + if (isstr (s2)) + [r2, c2] = size (s2); + if (r1 == r2 && c1 == c2) + if (c1 == 0) + retval = 1; + else + retval = all (all (s1 == s2)); + endif + endif + elseif (iscell (s2)) + [r2, c2] = size (s2); + if (r1 == 1) + t2 = s2(:); + n = length (t2); + retval = zeros (n, 1); + for i = 1:n + retval(i) = strcmp (s1, t2{i}); + endfor + retval = reshape (retval, r2, c2); + elseif (r1 > 1) + if (r2 == 1 && c2 == 1) + t2 = s2{1}; + retval = zeros (r1, 1); + for i = 1:r1 + retval(i) = strcmp (deblank (s1(i,:)), t2); + endfor + else + t2 = s2(:); + n = length (t2); + if (n == r1) + retval = zeros (n, 1); + for i = 1:n + retval(i) = strcmp (deblank (s1(i,:)), t2{i}); + endfor + retval = reshape (retval, r2, c2); + endif + endif + endif + endif + elseif (iscell (s1)) [r1, c1] = size (s1); - [r2, c2] = size (s2); - if (r1 == r2 && c1 == c2) - if (c1 == 0) - status = 1; + if (isstr (s2)) + [r2, c2] = size (s2); + if (r2 == 1) + t1 = s1(:); + n = length (t1); + retval = zeros (n, 1); + for i = 1:n + retval(i) = strcmp (t1{i}, s2); + endfor + retval = reshape (retval, r1, c1); + elseif (r2 > 1) + if (r1 == 1 && c1 == 1) + t1 = s1{1}; + retval = zeros (r2, 1); + for i = 1:r2 + retval(i) = strcmp (t1, deblank (s2(i,:))); + endfor + else + t1 = s1(:); + n = length (t1); + if (n == r2) + retval = zeros (n, 1); + for i = 1:n + retval(i) = strcmp (t2{i}, deblank (s2(i,:))); + endfor + retval = reshape (retval, r1, c1); + endif + endif + endif + elseif (iscell (s2)) + [r2, c2] = size (s2); + if (r1 == 1 && c1 == 1) + t1 = s1{:}; + t2 = s2(:); + n = length (t2); + retval = zeros (n, 1); + for i = 1:n + retval(i) = strcmp (t1, t2{i}); + endfor + retval = reshape (retval, r2, c2); + elseif (r2 == 1 && c2 == 1) + t1 = s1(:); + t2 = s2{:}; + n = length (t1); + retval = zeros (n, 1); + for i = 1:n + retval(i) = strcmp (t1{i}, t2); + endfor + retval = reshape (retval, r1, c1); + elseif (r1 == r2 && c1 == c2) + t1 = s1(:); + t2 = s2(:); + n = length (t1); + for i = 1:n + retval(i) = strcmp (t1{i}, t2{i}); + endfor + retval = reshape (retval, r1, c1); else - status = all (all (s1 == s2)); + error ("strcmp: nonconformant cell arrays"); endif endif endif Index: src/file-io.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/file-io.cc,v retrieving revision 1.132 diff -u -r1.132 file-io.cc --- src/file-io.cc 31 Dec 2002 19:43:07 -0000 1.132 +++ src/file-io.cc 2 Jan 2003 02:58:22 -0000 at @ -1184,17 +1184,24 @@ if (! error_state) { - octave_value size = (nargin > 1) - ? args(1) : octave_value (lo_ieee_inf_value ()); + octave_value size = lo_ieee_inf_value (); + octave_value prec = "uchar"; + octave_value skip = 0; + octave_value arch = "unknown"; - octave_value prec = (nargin > 2) - ? args(2) : octave_value ("uchar"); + int idx = 1; - octave_value skip = (nargin > 3) - ? args(3) : octave_value (0.0); + if (nargin > 1 && ! args(idx).is_string ()) + size = args(idx++); - octave_value arch = (nargin > 4) - ? args(4) : octave_value ("unknown"); + if (nargin > idx) + prec = args(idx++); + + if (nargin > idx) + skip = args(idx++); + + if (nargin > idx) + arch = args(idx++); int count = -1; Index: src/oct-stream.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/oct-stream.cc,v retrieving revision 1.81 diff -u -r1.81 oct-stream.cc --- src/oct-stream.cc 31 Dec 2002 19:43:07 -0000 1.81 +++ src/oct-stream.cc 2 Jan 2003 02:58:23 -0000 at @ -2041,8 +2041,6 @@ bool exhausted (void) { return (val_idx >= n_vals); } - bool looking_at_string (void); - private: const octave_value_list values; at @ -2065,19 +2063,6 @@ printf_value_cache& operator = (const printf_value_cache&); }; -bool -printf_value_cache::looking_at_string (void) -{ - bool retval = false; - - int idx = (elt_idx == 0) ? val_idx : -1; - - if (idx >= 0 && idx < n_vals) - retval = values(idx).is_string (); - - return retval; -} - double printf_value_cache::double_value (void) { at @ -2158,31 +2143,29 @@ { std::string retval; - if (looking_at_string ()) - { - octave_value tval = values (val_idx++); + octave_value tval = values (val_idx++); - if (tval.rows () == 1) - retval = tval.string_value (); - else - { - // In the name of Matlab compatibility. + if (tval.rows () == 1) + retval = tval.string_value (); + else + { + // In the name of Matlab compatibility. - charMatrix chm = tval.char_matrix_value (); + charMatrix chm = tval.char_matrix_value (); - int nr = chm.rows (); - int nc = chm.columns (); + int nr = chm.rows (); + int nc = chm.columns (); - int k = 0; + int k = 0; - retval.resize (nr * nc, '\0'); + retval.resize (nr * nc, '\0'); - for (int j = 0; j < nc; j++) - for (int i = 0; i < nr; i++) - retval[k++] = chm(i,j); - } + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval[k++] = chm(i,j); } - else + + if (error_state) curr_state = conversion_error; return retval; at @ -2298,7 +2281,7 @@ os << elt->text; retval += strlen (elt->text); } - else if (elt->type == 's' && val_cache.looking_at_string ()) + else if (elt->type == 's') { std::string val = val_cache.string_value (); Index: src/ov-base.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/ov-base.cc,v retrieving revision 1.36 diff -u -r1.36 ov-base.cc --- src/ov-base.cc 31 Dec 2002 19:43:07 -0000 1.36 +++ src/ov-base.cc 2 Jan 2003 02:58:23 -0000 at @ -301,8 +301,17 @@ octave_base_value::char_matrix_value (bool) const { charMatrix retval; - gripe_wrong_type_arg ("octave_base_value::char_matrix_value()", - type_name ()); + + if (Vimplicit_num_to_str_ok) + { + octave_value tmp = convert_to_str (); + + if (! error_state) + retval = tmp.char_matrix_value (); + } + else + gripe_wrong_type_arg ("octave_base_value::char_matrix_value()", + type_name ()); return retval; } at @ -310,7 +319,17 @@ octave_base_value::all_strings (void) const { string_vector retval; - gripe_wrong_type_arg ("octave_base_value::all_strings()", type_name ()); + + if (Vimplicit_num_to_str_ok) + { + octave_value tmp = convert_to_str (); + + if (! error_state) + retval = tmp.all_strings (); + } + else + gripe_wrong_type_arg ("octave_base_value::all_strings()", type_name ()); + return retval; } at @ -318,7 +337,17 @@ octave_base_value::string_value (void) const { std::string retval; - gripe_wrong_type_arg ("octave_base_value::string_value()", type_name ()); + + if (Vimplicit_num_to_str_ok) + { + octave_value tmp = convert_to_str (); + + if (! error_state) + retval = tmp.string_value (); + } + else + gripe_wrong_type_arg ("octave_base_value::string_value()", type_name ()); + return retval; } Index: src/ov.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/ov.cc,v retrieving revision 1.70 diff -u -r1.70 ov.cc --- src/ov.cc 31 Dec 2002 19:43:07 -0000 1.70 +++ src/ov.cc 2 Jan 2003 02:58:24 -0000 at @ -80,6 +80,9 @@ // for A already defined and a matrix type. bool Vdo_fortran_indexing; +// Should `[97, 98, 99, "123"]' be a string? +bool Vimplicit_num_to_str_ok; + // Should we allow things like: // // octave> 'abc' + 0 at @ -1723,6 +1726,14 @@ } static int +implicit_num_to_str_ok (void) +{ + Vimplicit_num_to_str_ok = check_preference ("implicit_num_to_str_ok"); + + return 0; +} + +static int implicit_str_to_num_ok (void) { Vimplicit_str_to_num_ok = check_preference ("implicit_str_to_num_ok"); at @ -1819,6 +1830,24 @@ you to select elements of a two-dimensional matrix using a single index\n\ by treating the matrix as a single vector created from the columns of\n\ the matrix. The default value is 0. \n\ + at end defvr"); + + DEFVAR (implicit_num_to_str_ok, false, implicit_num_to_str_ok, + "-*- texinfo -*-\n\ + at defvr {Built-in Variable} implicit_num_to_str_ok\n\ +If the value of at code{implicit_num_to_str_ok} is nonzero, implicit\n\ +conversions of numbers to their ASCII character equivalents are\n\ +allowed when strings are constructed using a mixture of strings and\n\ +numbers in matrix notation. Otherwise, an error message is printed and\n\ +control is returned to the top level. The default value is 0. For\n\ +example,\n\ +\n\ + at example\n\ + at group\n\ +[ \"f\", 111, 111 ]\n\ + at result{} \"foo\"\n\ + at end group\n\ + at end example\n\ at end defvr"); DEFVAR (implicit_str_to_num_ok, false, implicit_str_to_num_ok, Index: src/ov.h =================================================================== RCS file: /usr/local/cvsroot/octave/src/ov.h,v retrieving revision 1.63 diff -u -r1.63 ov.h --- src/ov.h 31 Dec 2002 19:43:07 -0000 1.63 +++ src/ov.h 2 Jan 2003 02:58:24 -0000 at @ -704,6 +704,9 @@ // for A already defined and a matrix type. extern bool Vdo_fortran_indexing; +// Should `[97, 98, 99, "123"]' be a string? +extern bool Vimplicit_num_to_str_ok; + // Should we allow things like: // // octave> 'abc' + 0 Index: src/pt-mat.cc =================================================================== RCS file: /usr/local/cvsroot/octave/src/pt-mat.cc,v retrieving revision 1.45 diff -u -r1.45 pt-mat.cc --- src/pt-mat.cc 20 Dec 2002 22:43:55 -0000 1.45 +++ src/pt-mat.cc 2 Jan 2003 02:58:24 -0000 at @ -48,9 +48,6 @@ // Zero means it should be considered an error. static int Vempty_list_elements_ok; -// Should `[97, 98, 99, "123"]' be a string? -static bool Vimplicit_num_to_str_ok; - // The character to fill with when creating string arrays. char Vstring_fill_char = ' '; at @ -585,14 +582,6 @@ } static int -implicit_num_to_str_ok (void) -{ - Vimplicit_num_to_str_ok = check_preference ("implicit_num_to_str_ok"); - - return 0; -} - -static int string_fill_char (void) { int status = 0; at @ -638,24 +627,6 @@ and the variable at code{a} will be assigned the value @code{[ 1, 3, 5 ]}.\n\ \n\ The default value is 1.\n\ - at end defvr"); - - DEFVAR (implicit_num_to_str_ok, false, implicit_num_to_str_ok, - "-*- texinfo -*-\n\ - at defvr {Built-in Variable} implicit_num_to_str_ok\n\ -If the value of at code{implicit_num_to_str_ok} is nonzero, implicit\n\ -conversions of numbers to their ASCII character equivalents are\n\ -allowed when strings are constructed using a mixture of strings and\n\ -numbers in matrix notation. Otherwise, an error message is printed and\n\ -control is returned to the top level. The default value is 0. For\n\ -example,\n\ -\n\ - at example\n\ - at group\n\ -[ \"f\", 111, 111 ]\n\ - at result{} \"foo\"\n\ - at end group\n\ - at end example\n\ at end defvr"); DEFVAR (string_fill_char, " ", string_fill_char, ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------