Mercurial > hg > octave-lyh
diff src/oct-stream.cc @ 3268:fdc7dd08cd85
[project @ 1999-09-10 05:16:49 by jwe]
author | jwe |
---|---|
date | Fri, 10 Sep 1999 05:17:51 +0000 |
parents | 8092e8197ce4 |
children | 9c782a34b545 |
line wrap: on
line diff
--- a/src/oct-stream.cc +++ b/src/oct-stream.cc @@ -24,6 +24,7 @@ #include <config.h> #endif +#include <cassert> #include <cstring> #include <iomanip.h> @@ -83,7 +84,7 @@ { if (! xisinf (d)) { - if (d > 0.0) + if (d >= 0.0) retval = NINT (d); else ::error ("%s: negative value invalid as size specification", @@ -99,11 +100,14 @@ } static void -get_size (const Matrix& size, int& nr, int& nc, const char *warn_for) +get_size (const Matrix& size, int& nr, int& nc, bool& one_elt_size_spec, + const char *warn_for) { nr = -1; nc = -1; + one_elt_size_spec = false; + double dnr = -1.0; double dnc = -1.0; @@ -112,6 +116,8 @@ if (sz_nr == 1 && sz_nc == 1) { + one_elt_size_spec = true; + dnr = size (0, 0); dnc = 1.0; } @@ -140,7 +146,7 @@ { nr = get_size (dnr, warn_for); - if (! error_state && dnc > 0.0) + if (! error_state && dnc >= 0.0) nc = get_size (dnc, warn_for); } } @@ -874,7 +880,9 @@ int nr = -1; int nc = -1; - get_size (size, nr, nc, "fread"); + bool ignore; + + get_size (size, nr, nc, ignore, "fread"); if (! error_state) { @@ -898,8 +906,8 @@ template <class T> void do_scanf_conv (istream& is, const char *fmt, T valptr, Matrix& mval, - double *data, int& idx, int nr, int max_size, - bool discard) + double *data, int& idx, int& conv_count, int nr, + int max_size, bool discard) { is.scan (fmt, valptr); @@ -918,41 +926,55 @@ } if (! discard) - data[idx++] = *(valptr); + { + conv_count++; + data[idx++] = *(valptr); + } } } template void do_scanf_conv (istream&, const char*, int*, Matrix&, double*, int&, - int, int, bool); + int&, int, int, bool); template void do_scanf_conv (istream&, const char*, long int*, Matrix&, double*, int&, - int, int, bool); + int&, int, int, bool); template void do_scanf_conv (istream&, const char*, short int*, Matrix&, double*, int&, - int, int, bool); + int&, int, int, bool); #if 0 template void do_scanf_conv (istream&, const char*, float*, Matrix&, double*, int&, - int, int, bool); + int&, int, int, bool); #endif template void do_scanf_conv (istream&, const char*, double*, Matrix&, double*, int&, - int, int, bool); + int&, int, int, bool); octave_value octave_base_stream::do_scanf (scanf_format_list& fmt_list, - int nr, int nc, int& count) + int nr, int nc, bool one_elt_size_spec, + int& conversion_count) { - count = 0; + conversion_count = 0; + + int data_index = 0; octave_value retval = Matrix (); + if (nr == 0 || nc == 0) + { + if (one_elt_size_spec) + nc = 0; + + return Matrix (nr, nc, 0.0); + } + istream *isp = input_stream (); bool all_char_conv = fmt_list.all_character_conversions (); @@ -960,17 +982,40 @@ Matrix mval; double *data = 0; int max_size = 0; + int max_conv = 0; int final_nr = 0; int final_nc = 0; - if (nr > 0) + if (all_char_conv) + { + if (one_elt_size_spec) + { + mval.resize (1, 512, 0.0); + data = mval.fortran_vec (); + max_size = 512; + + if (nr > 0) + max_conv = nr; + } + else if (nr > 0 && nc > 0) + { + mval.resize (nr, 32, 0.0); + data = mval.fortran_vec (); + max_size = nr * 32; + + max_conv = nr * nc; + } + } + else if (nr > 0) { if (nc > 0) { mval.resize (nr, nc, 0.0); data = mval.fortran_vec (); max_size = nr * nc; + + max_conv = max_size; } else { @@ -998,27 +1043,32 @@ { if (elt) { - if (count == max_size) + if (max_conv > 0 && conversion_count == max_conv) + { + if (all_char_conv && one_elt_size_spec) + { + final_nr = 1; + final_nc = data_index; + } + else + { + final_nr = nr; + final_nc = (data_index - 1) / nr + 1; + } + + break; + } + else if (data_index == max_size) { if (nr > 0) { - if (nc > 0) - { - final_nr = nr; - final_nc = nc; - - break; - } - else - { - max_size *= 2; - mval.resize (nr, max_size / nr, 0.0); - data = mval.fortran_vec (); - } + max_size *= 2; + mval.resize (nr, max_size / nr, 0.0); + data = mval.fortran_vec (); } else { - max_size *=2; + max_size *= 2; mval.resize (max_size, 1, 0.0); data = mval.fortran_vec (); } @@ -1045,7 +1095,8 @@ case 'h': { short int tmp; - do_scanf_conv (is, fmt, &tmp, mval, data, count, + do_scanf_conv (is, fmt, &tmp, mval, data, + data_index, conversion_count, nr, max_size, discard); } break; @@ -1053,7 +1104,8 @@ case 'l': { long int tmp; - do_scanf_conv (is, fmt, &tmp, mval, data, count, + do_scanf_conv (is, fmt, &tmp, mval, data, + data_index, conversion_count, nr, max_size, discard); } break; @@ -1061,7 +1113,8 @@ default: { int tmp; - do_scanf_conv (is, fmt, &tmp, mval, data, count, + do_scanf_conv (is, fmt, &tmp, mval, data, + data_index, conversion_count, nr, max_size, discard); } break; @@ -1073,7 +1126,8 @@ { double tmp; - do_scanf_conv (is, fmt, &tmp, mval, data, count, + do_scanf_conv (is, fmt, &tmp, mval, data, + data_index, conversion_count, nr, max_size, discard); } break; @@ -1084,21 +1138,46 @@ case 's': { - int len = strlen (fmt); - char *tmp_fmt = new char [len+1]; - strcpy (tmp_fmt, fmt); - if (tmp_fmt[len-1] == 's') - tmp_fmt[len-1] = 'c'; - - int width = elt->width ? elt->width : 1; - - char *tmp = new char [width+1]; - - is.scan (tmp_fmt, tmp); - - delete [] tmp_fmt; - - tmp[width] = '\0'; + int width = elt->width; + + if (elt->type == 'c' && width == 0) + width = 1; + + char *tmp = 0; + + if (width) + { + tmp = new char [width+1]; + + is.scan (fmt, tmp); + + tmp[width] = '\0'; + } + else + { + // We're looking at a `%s' format. We have to + // skip initial whitespace and then read until + // the next whitespace character. + + ostrstream buf; + + int c = EOF; + + while (is && (c = is.get ()) != EOF && isspace (c)) + /* skip leading whitespace */; + + if (is && c != EOF) + buf << (char) c; + + while (is && (c = is.get ()) != EOF && ! isspace (c)) + buf << (char) c; + + buf << ends; + + tmp = buf.str (); + } + + width = strlen (tmp); if (is) { @@ -1106,9 +1185,11 @@ if (! discard) { + conversion_count++; + while (i < width && tmp[i] != '\0') { - if (count == max_size) + if (data_index == max_size) { max_size *= 2; @@ -1120,7 +1201,7 @@ data = mval.fortran_vec (); } - data[count++] = tmp[i++]; + data[data_index++] = tmp[i++]; } } } @@ -1146,22 +1227,40 @@ } else if (! is) { - if (nr > 0) + if (all_char_conv) { - if (count > nr) + if (one_elt_size_spec) + { + final_nr = 1; + final_nc = data_index; + } + else if (data_index > nr) { final_nr = nr; - final_nc = (count - 1) / nr + 1; + final_nc = (data_index - 1) / nr + 1; } else { - final_nr = count; + final_nr = data_index; + final_nc = 1; + } + } + else if (nr > 0) + { + if (data_index > nr) + { + final_nr = nr; + final_nc = (data_index - 1) / nr + 1; + } + else + { + final_nr = data_index; final_nc = 1; } } else { - final_nr = count; + final_nr = data_index; final_nc = 1; } @@ -1194,17 +1293,10 @@ { mval.resize (final_nr, final_nc, 0.0); + retval = mval; + if (all_char_conv) - { - if (nr < 0) - mval = mval.transpose (); - - retval = mval; - - retval = retval.convert_to_str (); - } - else - retval = mval; + retval = retval.convert_to_str (); } return retval; @@ -1267,10 +1359,12 @@ int nr = -1; int nc = -1; - get_size (size, nr, nc, "fscanf"); + bool one_elt_size_spec; + + get_size (size, nr, nc, one_elt_size_spec, "fscanf"); if (! error_state) - retval = do_scanf (fmt_list, nr, nc, count); + retval = do_scanf (fmt_list, nr, nc, one_elt_size_spec, count); } break; } @@ -1367,23 +1461,49 @@ case 's': { - // XXX FIXME XXX -- this must be fixed! - - int width = elt->width ? elt->width : 65535; - char *tmp = new char [width+1]; - - if (is.scan (fmt, tmp)) + int width = elt->width; + + char *tmp = 0; + + if (width) { - if (! discard) - { - tmp[width] = '\0'; - retval = tmp; - } + tmp = new char [width+1]; + + is.scan (fmt, tmp); + + tmp[width] = '\0'; } else - quit = true; + { + // We're looking at a `%s' format. We have to + // skip initial whitespace and then read until + // the next whitespace character. + + ostrstream buf; + + int c = EOF; + + while (is && (c = is.get ()) != EOF && isspace (c)) + /* skip leading whitespace */; + + if (is && c != EOF) + buf << (char) c; + + while (is && (c = is.get ()) != EOF && ! isspace (c)) + buf << (char) c; + + buf << ends; + + tmp = buf.str (); + + if (! discard) + retval = tmp; + } delete [] tmp; + + if (! is) + quit = true; } break;