# HG changeset patch # User jwe # Date 847940412 0 # Node ID 9b0dd36714ebf48ba432e389578ca63291e79a50 # Parent 0be4639a6c13f289759d88e1c62232ab6598d6b3 [project @ 1996-11-14 02:57:33 by jwe] diff -r 0be4639a6c13 -r 9b0dd36714eb NEWS --- a/NEWS Thu Nov 14 02:53:23 1996 +0000 +++ b/NEWS Thu Nov 14 03:00:12 1996 +0000 @@ -24,6 +24,11 @@ available to make them behave in a way that is compatible with previous versions of Octave. + * Octave can now read files that contain columns of numbers only, + with no header information. The name of the loaded variable is + constructed from the file name. Each line in the file must have + the same number of elements. + * The interface to the pager has changed. The new built-in variable `page_output_immediately' controls when Octave sends output to the pager. If it is nonzero, Octave sends output to the pager as soon diff -r 0be4639a6c13 -r 9b0dd36714eb PROJECTS --- a/PROJECTS Thu Nov 14 02:53:23 1996 +0000 +++ b/PROJECTS Thu Nov 14 03:00:12 1996 +0000 @@ -164,9 +164,6 @@ working on them, it would be good to support other size specifications (integer*2, etc.). - * Make load work to read files that contain numbers only, and put - the values in a matrix named after the file. - * Make load and save work for structures. * Make load and save look for .mat if only given . diff -r 0be4639a6c13 -r 9b0dd36714eb src/ChangeLog --- a/src/ChangeLog Thu Nov 14 02:53:23 1996 +0000 +++ b/src/ChangeLog Thu Nov 14 03:00:12 1996 +0000 @@ -1,5 +1,12 @@ Wed Nov 13 11:13:22 1996 John W. Eaton + * load-save.cc (read_mat_ascii_matrix, get_lines_and_columns, + get_complete_line): New functions, for reading headless text files. + (load_save_format): Add LS_MAT_ASCII, for headless text files. + (do_load): Handle LS_MAT_ASCII files. + Thanks to Mel Melchner for initial version + of this code. + * sysdep.cc: Conditionally include ieeefp.h. (BSD_init, SCO_init): New functions. (sysdep_init): Conditionally call them here. diff -r 0be4639a6c13 -r 9b0dd36714eb src/load-save.cc --- a/src/load-save.cc Thu Nov 14 02:53:23 1996 +0000 +++ b/src/load-save.cc Thu Nov 14 03:00:12 1996 +0000 @@ -73,6 +73,7 @@ { LS_ASCII, LS_BINARY, + LS_MAT_ASCII, LS_MAT_BINARY, LS_UNKNOWN, }; @@ -909,6 +910,152 @@ return name; } +// Get a complete line of input. + +static string +get_complete_line (istream& is) +{ + string retval; + + ostrstream buf; + + char c; + + while (is.get (c)) + { + if (c == '\n') + break; + + buf << c; + } + + buf << ends; + + char *tmp = buf.str (); + + retval = tmp; + + delete [] tmp; + + return retval; +} + +static void +get_lines_and_columns (istream& is, const string& filename, int& nr, int& nc) +{ + streampos pos = is.tellg (); + + int file_line_number = 0; + + nr = 0; + nc = 0; + + while (! (is.eof () || error_state)) + { + string line = get_complete_line (is); + + file_line_number++; + + size_t beg = line.find_first_not_of (" \t"); + + if (beg != NPOS) + { + int tmp_nc = 0; + + while (beg != NPOS) + { + tmp_nc++; + + size_t end = line.find_first_of (" \t", beg); + + if (end != NPOS) + beg = line.find_first_not_of (" \t", end); + else + break; + } + + if (nc == 0) + { + nc = tmp_nc; + nr++; + } + else if (nc == tmp_nc) + nr++; + else + error ("load: %s: inconsistent number of columns near line %d", + filename.c_str (), file_line_number); + } + } + + if (nr == 0 || nc == 0) + error ("load: file `%s' seems to be empty!", filename.c_str ()); + + is.clear (); + is.seekg (pos, ios::beg); +} + +// Extract a matrix from a file of numbers only. +// +// Comments are not allowed. The file should only have numeric values. +// +// Reads the file twice. Once to find the number of rows and columns, +// and once to extract the matrix. +// +// FILENAME is used for error messages. +// +// This format provides no way to tag the data as global. + +static char * +read_mat_ascii_data (istream& is, const string& filename, + octave_value& tc) +{ + char *name = 0; + + string varname; + + size_t pos = filename.find ('.'); + + if (pos != NPOS) + varname = filename.substr (0, pos); + else + varname = filename; + + if (valid_identifier (varname.c_str ())) + { + int nr = 0; + int nc = 0; + + get_lines_and_columns (is, filename, nr, nc); + + if (! error_state) + { + // NR and NC must be greater than zero if we end up here. + + Matrix tmp (nr, nc); + + is >> tmp; + + if (is) + { + tc = tmp; + + name = strsave (varname.c_str ()); + } + else + error ("load: failed to read matrix from file `%s'", + filename.c_str ()); + } + else + error ("load: unable to extract matrix size from file `%s'", + filename.c_str ()); + } + else + error ("load: unable to convert filename `%s' to valid identifier", + filename.c_str ()); + + return name; +} + // Read LEN elements of data from IS in the format specified by // PRECISION, placing the result in DATA. If SWAP is nonzero, swap // the bytes of each element before copying to DATA. FLT_FMT @@ -1287,6 +1434,7 @@ retval = LS_MAT_BINARY; else { + file.clear (); file.seekg (0, ios::beg); char *tmp = extract_keyword (file, "name"); @@ -1294,8 +1442,20 @@ if (tmp) { retval = LS_ASCII; + delete [] tmp; } + else + { + // Try reading the file as numbers only, determining the + // number of rows and columns from the data. We don't + // even bother to check to see if the first item in the + // file is a number, so that get_complete_line() can + // skip any comments that might appear at the top of the + // file. + + retval = LS_MAT_ASCII; + } } } @@ -1337,6 +1497,10 @@ global, tc, doc); break; + case LS_MAT_ASCII: + name = read_mat_ascii_data (stream, orig_fname, tc); + break; + case LS_MAT_BINARY: name = read_mat_binary_data (stream, orig_fname, tc); break; @@ -1350,6 +1514,7 @@ { delete [] name; delete [] doc; + break; } else if (! error_state && name) @@ -1382,6 +1547,14 @@ install_loaded_variable (force, name, tc, global, doc); } } + + delete [] name; + delete [] doc; + + // Only attempt to read one item from a headless text file. + + if (format == LS_MAT_ASCII) + break; } else error ("load: unable to load variable `%s'", name); @@ -1394,11 +1567,9 @@ delete [] name; delete [] doc; + break; } - - delete [] name; - delete [] doc; } if (list_only && count)