From owner-bug-octave at bevo dot che dot wisc dot edu Sat Dec 7 22:05:33 1996 Subject: 1.93 bug in *scanf(...,"C") From: "John W. Eaton" To: jcardoso at inescn dot pt cc: bug-octave at bevo dot che dot wisc dot edu Date: Sat, 7 Dec 1996 22:04:42 -0600 On 6-Dec-1996, Joao Cardoso wrote: : In C(ompatibility) mode, *scanf skip '*' flag does not work: : : in 1.93: : : octave:1> a="1.1 1.2 1.3" : a = 1.1 1.2 1.3 : octave:2> [q w]=sscanf(a,"%f%*f%f","C") : q = 1.1000 : : w = [] Please try the following patch (it also cleans up some other things). Thanks, jwe Sat Dec 7 22:00:10 1996 John W. Eaton * oct-stream.cc (do_printf_conv, do_scanf_conv, do_oscanf_num_conv, do_oscanf_str_conv): Convert to real functions instead of CPP macros, using templates where necessary. (do_oscanf_num_conv, do_oscanf_str_conv): Correctly handle discarded values. Index: oct-stream.cc =================================================================== RCS file: /home/jwe/src/master/octave/src/oct-stream.cc,v retrieving revision 1.10 diff -c -r1.10 oct-stream.cc *** oct-stream.cc 1996/10/27 21:31:29 1.10 --- oct-stream.cc 1996/12/08 03:57:02 *************** *** 856,885 **** return retval; } ! #define do_scanf_conv(is, fmt, valptr, mval, data, idx, max_size, discard) \ ! do \ ! { \ ! is.scan (fmt, valptr); \ ! \ ! if (is) \ ! { \ ! if (idx == max_size && ! discard) \ ! { \ ! max_size *= 2; \ ! \ ! if (nr > 0) \ ! mval.resize (nr, max_size / nr, 0.0); \ ! else \ ! mval.resize (max_size, 1, 0.0); \ ! \ ! data = mval.fortran_vec (); \ ! } \ ! \ ! if (! discard) \ ! data[idx++] = *(valptr); \ ! } \ ! } \ ! while (0) octave_value octave_base_stream::do_scanf (scanf_format_list& fmt_list, --- 856,900 ---- return retval; } ! template ! void ! do_scanf_conv (istream& is, const char *fmt, T valptr, Matrix& mval, ! double *data, int& idx, int nr, int max_size, ! bool discard) ! { ! is.scan (fmt, valptr); ! ! if (is) ! { ! if (idx == max_size && ! discard) ! { ! max_size *= 2; ! ! if (nr > 0) ! mval.resize (nr, max_size / nr, 0.0); ! else ! mval.resize (max_size, 1, 0.0); ! ! data = mval.fortran_vec (); ! } ! ! if (! discard) ! data[idx++] = *(valptr); ! } ! } ! ! template void ! do_scanf_conv (istream&, const char*, int*, Matrix&, double*, int&, ! int, int, bool); ! ! template void ! do_scanf_conv (istream&, const char*, float*, Matrix&, double*, int&, ! int, int, bool); ! ! template void ! do_scanf_conv (istream&, const char*, double*, Matrix&, double*, int&, ! int, int, bool); ! octave_value octave_base_stream::do_scanf (scanf_format_list& fmt_list, *************** *** 961,967 **** int tmp; do_scanf_conv (is, fmt, &tmp, mval, data, count, ! max_size, discard); } break; --- 976,982 ---- int tmp; do_scanf_conv (is, fmt, &tmp, mval, data, count, ! nr, max_size, discard); } break; *************** *** 972,985 **** double tmp; do_scanf_conv (is, fmt, &tmp, mval, data, ! count, max_size, discard); } else { float tmp; do_scanf_conv (is, fmt, &tmp, mval, data, ! count, max_size, discard); } } break; --- 987,1000 ---- double tmp; do_scanf_conv (is, fmt, &tmp, mval, data, ! count, nr, max_size, discard); } else { float tmp; do_scanf_conv (is, fmt, &tmp, mval, data, ! count, nr, max_size, discard); } } break; *************** *** 1194,1236 **** return retval; } ! #define do_oscanf_num_conv(is, fmt, valptr) \ ! do \ ! { \ ! streambuf *isb = is.rdbuf (); \ ! \ ! if (isb->scan (fmt, valptr) > 0) \ ! { \ ! if (! discard && is) \ ! retval = (double) (*valptr); \ ! } \ ! else \ ! error ("fscanf: conversion failed"); \ ! } \ ! while (0) ! ! #define do_oscanf_str_conv(is, fmt, sptr, maxlen) \ ! do \ ! { \ ! streambuf *isb = is.rdbuf (); \ ! \ ! if (isb->scan (fmt, sptr) > 0) \ ! { \ ! if (! discard && is) \ ! { \ ! sptr[maxlen] = '\0'; \ ! retval = sptr; \ ! } \ ! } \ ! else \ ! error ("fscanf: conversion failed"); \ ! } \ ! while (0) octave_value octave_base_stream::do_oscanf (const scanf_format_elt *elt) { ! octave_value retval = Matrix (); istream *isp = input_stream (); --- 1209,1268 ---- return retval; } ! template ! octave_value ! do_oscanf_num_conv (istream& is, const char *fmt, T valptr, bool discard) ! { ! octave_value retval; ! ! is.scan (fmt, valptr); ! ! if (is) ! { ! if (! discard) ! retval = (double) (*valptr); ! } ! else ! error ("fscanf: conversion failed"); ! ! return retval; ! } ! ! template octave_value ! do_oscanf_num_conv (istream&, const char*, int*, bool); ! ! template octave_value ! do_oscanf_num_conv (istream&, const char*, float*, bool); ! ! template octave_value ! do_oscanf_num_conv (istream&, const char*, double*, bool); ! ! static inline octave_value ! do_oscanf_str_conv (istream& is, const char *fmt, char *sptr, ! int maxlen, bool discard) ! { ! octave_value retval; ! ! is.scan (fmt, sptr); ! ! if (is) ! { ! if (! discard) ! { ! sptr[maxlen] = '\0'; ! retval = sptr; ! } ! } ! else ! error ("fscanf: conversion failed"); ! ! return retval; ! } octave_value octave_base_stream::do_oscanf (const scanf_format_elt *elt) { ! octave_value retval; istream *isp = input_stream (); *************** *** 1260,1266 **** { int tmp; ! do_oscanf_num_conv (is, fmt, &tmp); } break; --- 1292,1298 ---- { int tmp; ! retval = do_oscanf_num_conv (is, fmt, &tmp, discard); } break; *************** *** 1270,1282 **** { double tmp; ! do_oscanf_num_conv (is, fmt, &tmp); } else { float tmp; ! do_oscanf_num_conv (is, fmt, &tmp); } } break; --- 1302,1314 ---- { double tmp; ! retval = do_oscanf_num_conv (is, fmt, &tmp, discard); } else { float tmp; ! retval = do_oscanf_num_conv (is, fmt, &tmp, discard); } } break; *************** *** 1289,1295 **** char *tmp = new char[width + 1]; ! do_oscanf_str_conv (is, fmt, tmp, width); is.setf (flags); --- 1321,1327 ---- char *tmp = new char[width + 1]; ! retval = do_oscanf_str_conv (is, fmt, tmp, width, discard); is.setf (flags); *************** *** 1303,1309 **** int width = elt->width ? elt->width : 65535; char *tmp = new char [width+1]; ! do_oscanf_str_conv (is, fmt, tmp, width); delete [] tmp; } break; --- 1335,1343 ---- int width = elt->width ? elt->width : 65535; char *tmp = new char [width+1]; ! ! retval = do_oscanf_str_conv (is, fmt, tmp, width, discard); ! delete [] tmp; } break; *************** *** 1402,1410 **** const scanf_format_elt *elt = fmt_list.first (); for (int i = 0; i < nconv; i++) { ! retval (i) = do_oscanf (elt); if (! ok ()) break; --- 1436,1449 ---- const scanf_format_elt *elt = fmt_list.first (); + int num_values = 0; + for (int i = 0; i < nconv; i++) { ! octave_value tmp = do_oscanf (elt); ! ! if (tmp.is_defined ()) ! retval (num_values++) = tmp; if (! ok ()) break; *************** *** 1412,1417 **** --- 1451,1458 ---- elt = fmt_list.next (); } + retval.resize (num_values); + // Pick up any trailing stuff. if (ok () && len > nconv) do_oscanf (elt); *************** *** 1642,1679 **** // Ugh again and again. ! #define do_printf_conv(os, fmt, nsa, sa_1, sa_2, have_arg, arg) \ ! do \ ! { \ ! switch (nsa) \ ! { \ ! case 2: \ ! if (have_arg) \ ! os.form (fmt, sa_1, sa_2, arg); \ ! else \ ! os.form (fmt, sa_1, sa_2); \ ! break; \ ! \ ! case 1: \ ! if (have_arg) \ ! os.form (fmt, sa_1, arg); \ ! else \ ! os.form (fmt, sa_1); \ ! break; \ ! \ ! case 0: \ ! if (have_arg) \ ! os.form (fmt, arg); \ ! else \ ! os.form (fmt); \ ! break; \ ! \ ! default: \ ! ::error ("fprintf: internal error handling format"); \ ! break; \ ! } \ ! } \ ! while (0) int octave_base_stream::do_printf (printf_format_list& fmt_list, --- 1683,1733 ---- // Ugh again and again. ! template ! void ! do_printf_conv (ostream& os, const char *fmt, int nsa, int sa_1, ! int sa_2, bool have_arg, T arg) ! { ! switch (nsa) ! { ! case 2: ! if (have_arg) ! os.form (fmt, sa_1, sa_2, arg); ! else ! os.form (fmt, sa_1, sa_2); ! break; ! ! case 1: ! if (have_arg) ! os.form (fmt, sa_1, arg); ! else ! os.form (fmt, sa_1); ! break; ! ! case 0: ! if (have_arg) ! os.form (fmt, arg); ! else ! os.form (fmt); ! break; ! ! default: ! ::error ("fprintf: internal error handling format"); ! break; ! } ! } ! ! template void ! do_printf_conv (ostream&, const char*, int, int, int, bool, int); ! ! template void ! do_printf_conv (ostream&, const char*, int, int, int, bool, long); ! ! template void ! do_printf_conv (ostream&, const char*, int, int, int, bool, double); ! ! template void ! do_printf_conv (ostream&, const char*, int, int, int, bool, const char*); int octave_base_stream::do_printf (printf_format_list& fmt_list, *************** *** 1727,1733 **** const char *fmt = elt->text; if (doing_percent || args == 0) ! do_printf_conv (os, fmt, nsa, sa_1, sa_2, 0, 0.0); else { if (elt->type == 's' && val_cache.looking_at_string ()) --- 1781,1787 ---- const char *fmt = elt->text; if (doing_percent || args == 0) ! do_printf_conv (os, fmt, nsa, sa_1, sa_2, false, 0.0); else { if (elt->type == 's' && val_cache.looking_at_string ()) *************** *** 1735,1741 **** string val = val_cache.string_value (); if (val_cache) ! do_printf_conv (os, fmt, nsa, sa_1, sa_2, 1, val.c_str ()); else break; --- 1789,1795 ---- string val = val_cache.string_value (); if (val_cache) ! do_printf_conv (os, fmt, nsa, sa_1, sa_2, true, val.c_str ()); else break; *************** *** 1753,1769 **** { if (elt->modifier == 'l') do_printf_conv (os, fmt, nsa, sa_1, ! sa_2, 1, (long) val); else do_printf_conv (os, fmt, nsa, sa_1, ! sa_2, 1, (int) val); } break; case 'f': case 'e': case 'E': case 'g': case 'G': do_printf_conv (os, fmt, nsa, sa_1, ! sa_2, 1, val); break; default: --- 1807,1823 ---- { if (elt->modifier == 'l') do_printf_conv (os, fmt, nsa, sa_1, ! sa_2, true, (long) val); else do_printf_conv (os, fmt, nsa, sa_1, ! sa_2, true, (int) val); } break; case 'f': case 'e': case 'E': case 'g': case 'G': do_printf_conv (os, fmt, nsa, sa_1, ! sa_2, true, val); break; default: