diff -r b225a520e334 NEWS --- a/NEWS Wed Apr 04 21:09:40 2012 -0700 +++ b/NEWS Thu Apr 05 08:50:33 2012 -0700 @@ -1,6 +1,19 @@ Summary of important user-visible changes for version 3.8: --------------------------------------------------------- + ** New internal variable `single_quote_escape_processing' added. + + This variable is present for greater Matlab compatibility and + is automatically turned on by the '--traditional' command line + switch. Ordinarily, escape sequences such as '\n' are not + converted when enclosed by single quotes. Matlab, however, + does do escape processing within single quotes for the functions + printf, sprintf, fprintf, error, warning, regexp, regexpi, and + regexprep. When this variable is true Octave processes + strings in the same manner as Matlab. + + Type `help single_quote_escape_processing' for more information. + ** Warning IDs renamed: Octave:array-as-scalar => Octave:array-to-scalar diff -r b225a520e334 doc/interpreter/basics.txi --- a/doc/interpreter/basics.txi Wed Apr 04 21:09:40 2012 -0700 +++ b/doc/interpreter/basics.txi Thu Apr 05 08:50:33 2012 -0700 @@ -220,6 +220,7 @@ history_timestamp_format_string = "%%-- %D %I:%M %p --%%" page_screen_output = false print_empty_dimensions = false +single_quote_escape_processing = true @end group @end example diff -r b225a520e334 scripts/io/strread.m --- a/scripts/io/strread.m Wed Apr 04 21:09:40 2012 -0700 +++ b/scripts/io/strread.m Thu Apr 05 08:50:33 2012 -0700 @@ -748,7 +748,7 @@ %! a = rand (10, 1); %! b = char (randi ([65, 85], 10, 1)); %! for k = 1:10 -%! str = sprintf ('%s %.6f %s\n', str, a(k), b(k)); +%! str = sprintf ("%s %.6f %s\n", str, a(k), b(k)); %! endfor %! [aa, bb] = strread (str, "%f %s"); %! assert (a, aa, 1e-6); diff -r b225a520e334 src/DLD-FUNCTIONS/regexp.cc --- a/src/DLD-FUNCTIONS/regexp.cc Wed Apr 04 21:09:40 2012 -0700 +++ b/src/DLD-FUNCTIONS/regexp.cc Thu Apr 05 08:50:33 2012 -0700 @@ -109,9 +109,11 @@ if (error_state) return retval; - const std::string pattern = args(1).string_value (); + std::string pattern = args(1).string_value (); if (error_state) return retval; + if (Vsingle_quote_escape_processing && args(1).is_sq_string ()) + pattern = do_string_escapes (pattern); regexp::opts options; options.case_insensitive (case_insensitive); @@ -1036,14 +1038,16 @@ if (error_state) return retval; - const std::string pattern = args(1).string_value (); + std::string pattern = args(1).string_value (); if (error_state) return retval; + if (Vsingle_quote_escape_processing && args(1).is_sq_string ()) + pattern = do_string_escapes (pattern); std::string replacement = args(2).string_value (); if (error_state) return retval; - if (args(2).is_sq_string ()) + if (Vsingle_quote_escape_processing && args(2).is_sq_string ()) replacement = do_string_escapes (replacement); // Pack options excluding 'tokenize' and various output diff -r b225a520e334 src/error.cc --- a/src/error.cc Wed Apr 04 21:09:40 2012 -0700 +++ b/src/error.cc Thu Apr 05 08:50:33 2012 -0700 @@ -789,6 +789,8 @@ if (arg.is_string ()) { tstr = arg.string_value (); + if (Vsingle_quote_escape_processing && arg.is_sq_string ()) + tstr = do_string_escapes (tstr); msg = tstr.c_str (); if (! msg) diff -r b225a520e334 src/file-io.cc --- a/src/file-io.cc Wed Apr 04 21:09:40 2012 -0700 +++ b/src/file-io.cc Thu Apr 05 08:50:33 2012 -0700 @@ -910,7 +910,13 @@ tmp_args(i-fmt_n-1) = args(i); } - result = os.printf (args(fmt_n), tmp_args, who); + std::string fmt = args(fmt_n).string_value (); + if (error_state) + return retval; + if (Vsingle_quote_escape_processing && args(fmt_n).is_sq_string ()) + fmt = do_string_escapes (fmt); + + result = os.printf (fmt, tmp_args, who); } else ::error ("%s: format TEMPLATE must be a string", who.c_str ()); @@ -961,7 +967,13 @@ tmp_args(i-1) = args(i); } - result = stdout_stream.printf (args(0), tmp_args, who); + std::string fmt = args(0).string_value (); + if (error_state) + return retval; + if (Vsingle_quote_escape_processing && args(0).is_sq_string ()) + fmt = do_string_escapes (fmt); + + result = stdout_stream.printf (fmt, tmp_args, who); } else ::error ("%s: format TEMPLATE must be a string", who.c_str ()); @@ -1053,9 +1065,7 @@ if (os.is_valid ()) { - octave_value fmt_arg = args(0); - - if (fmt_arg.is_string ()) + if (args(0).is_string ()) { octave_value_list tmp_args; @@ -1067,10 +1077,16 @@ tmp_args(i-1) = args(i); } - retval(2) = os.printf (fmt_arg, tmp_args, who); + std::string fmt = args(0).string_value (); + if (error_state) + return retval; + if (Vsingle_quote_escape_processing && args(0).is_sq_string ()) + fmt = do_string_escapes (fmt); + + retval(2) = os.printf (fmt, tmp_args, who); retval(1) = os.error (); retval(0) = octave_value (ostr->str (), - fmt_arg.is_sq_string () ? '\'' : '"'); + args(0).is_sq_string () ? '\'' : '"'); } else ::error ("%s: format TEMPLATE must be a string", who.c_str ()); diff -r b225a520e334 src/ov.cc --- a/src/ov.cc Wed Apr 04 21:09:40 2012 -0700 +++ b/src/ov.cc Thu Apr 05 08:50:33 2012 -0700 @@ -3068,6 +3068,7 @@ Process format specification string @var{template}.\n\ \n\ @item error\n\ address@hidden warning\n\ Process format specification string @var{template}.\n\ \n\ @item regexp\n\ @@ -3081,7 +3082,7 @@ When called from inside a function with the \"local\" option, the variable is\n\ changed locally for the function and any subroutines it calls. The original\n\ variable value is restored when exiting the function.\n\ address@hidden, sprintf, fprintf, error, regexp, regexpi, regexprep}\n\ address@hidden, sprintf, fprintf, error, warning, regexp, regexpi, regexprep}\n\ @end deftypefn") { return SET_INTERNAL_VARIABLE (single_quote_escape_processing);