Mercurial > hg > octave-lyh
changeset 14212:a0d98842a4d8
maint: periodic merge of stable to default.
author | Rik <octave@nomad.inbox5.com> |
---|---|
date | Wed, 18 Jan 2012 21:14:11 -0800 |
parents | 3f4cae8cb9fc (diff) 846273dae16b (current diff) |
children | a022c04f68cc |
files | |
diffstat | 8 files changed, 200 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/contributors.in +++ b/doc/interpreter/contributors.in @@ -169,6 +169,7 @@ Kai P. Mueller Hannes Müller Victor Munoz +Iain Murray Carmen Navarrete Todd Neal Philip Nienhuis
--- a/scripts/plot/__gnuplot_drawnow__.m +++ b/scripts/plot/__gnuplot_drawnow__.m @@ -205,7 +205,7 @@ endif switch (term) case terminals_with_size - size_str = sprintf ("size %g,%g", gnuplot_size); + size_str = sprintf ("size %.12g,%.12g", gnuplot_size); case "tikz" size_str = sprintf ("size %gin,%gin", gnuplot_size); case "dumb"
--- a/scripts/plot/legend.m +++ b/scripts/plot/legend.m @@ -147,7 +147,7 @@ if (isscalar (kids)) kids = get(kids, "children")(:); else - kids = [get(kids, "children"){:}](:); + kids = flipud ([get(kids, "children"){:}](:)); endif endif nargs = numel (varargin); @@ -1159,3 +1159,24 @@ %! h = legend ("Hello_World", "foo^bar"); %! set (h, "interpreter", "none") +%!demo +%! x = 0:10; +%! y1 = rand (size (x)); +%! y2 = rand (size (x)); +%! [ax, h1, h2] = plotyy (x, y1, x, y2); +%! legend ([h1, h2], {"Blue", "Green"}, "location", "south"); + +%!demo +%! x = 0:10; +%! y1 = rand (size (x)); +%! y2 = rand (size (x)); +%! [ax, h1, h2] = plotyy (x, y1, x, y2); +%! legend ({"Blue", "Green"}, "location", "south"); + +%!demo +%! x = 0:10; +%! y1 = rand (size (x)); +%! y2 = rand (size (x)); +%! [ax, h1, h2] = plotyy (x, y1, x, y2); +%! legend ("Blue", "Green", "location", "south"); +
--- a/scripts/plot/print.m +++ b/scripts/plot/print.m @@ -370,6 +370,10 @@ else fontsize = opts.fontsize; endif + if (! isempty (opts.scalefontsize) && ! opt.scalefontsize != 1) + ## This is done to work around the bbox being whole numbers. + fontsize = fontsize * opts.scalefontsize; + endif set (h(ishandle(h)), "fontsize", fontsize); endif endif
--- a/scripts/plot/private/__print_parse_opts__.m +++ b/scripts/plot/private/__print_parse_opts__.m @@ -36,6 +36,7 @@ arg_st.fig2dev_binary = __quote_path__ (__find_binary__ ("fig2dev")); arg_st.fontsize = ""; arg_st.font = ""; + arg_st.scalefontsize = 1; arg_st.force_solid = 0; # 0=default, -1=dashed, +1=solid arg_st.formatted_for_printing = false; arg_st.ghostscript.binary = __quote_path__ (__ghostscript_binary__ ()); @@ -326,8 +327,12 @@ arg_st.ghostscript.pageoffset = paperposition(1:2); endif else - ## Convert canvas size to points from pixles. - arg_st.canvas_size = arg_st.canvas_size * 72 / arg_st.ghostscript.resolution; + ## Convert canvas size to points from pixels. + if (! isempty (arg_st.fontsize)) + ## Work around the eps bbox having whole numbers (both gnuplot & gl2ps). + arg_st.scalefontsize = arg_st.ghostscript.resolution / 72; + endif + arg_st.ghostscript.resolution = 72; arg_st.ghostscript.papersize = arg_st.canvas_size; arg_st.ghostscript.epscrop = true; arg_st.ghostscript.pageoffset = [0, 0];
--- a/src/file-io.cc +++ b/src/file-io.cc @@ -43,7 +43,9 @@ #include <cstdio> #include <iostream> +#include <locale> #include <stack> +#include <stdexcept> #include <vector> #include <fcntl.h> @@ -1070,7 +1072,7 @@ DEFUN (fscanf, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, @var{size})\n\ -@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} fscanf (@var{fid}, @var{template}, \"C\")\n\ ++@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} fscanf (@var{fid}, @var{template}, @var{locale})\n\ In the first form, read from @var{fid} according to @var{template},\n\ returning the result in the matrix @var{val}.\n\ \n\ @@ -1109,7 +1111,10 @@ with each conversion specifier in @var{template} corresponding to a\n\ single scalar return value. This form is more `C-like', and also\n\ compatible with previous versions of Octave. The number of successful\n\ -conversions is returned in @var{count}\n\ +conversions is returned in @var{count}. It permits to explicitly\n\ +specify a locale to take into account langage specific features, \n\ +such as decimal separator. This operation restores the previous locales\n\ +setting at the end of the conversion.\n\ @ifclear OCTAVE_MANUAL\n\ \n\ See the Formatted Input section of the GNU Octave manual for a\n\ @@ -1131,7 +1136,25 @@ if (! error_state) { if (args(1).is_string ()) - retval = os.oscanf (args(1), who); + { + std::locale oldloc; + try + { + // Use args(2) val as the new locale setting. Keep + // old val for restoring afterwards. + oldloc = + os.imbue (std::locale (args(2).string_value ().c_str ())); + + } + catch (std::runtime_error) + { + // Display a warning if the specified locale is unknown + warning ("fscanf: invalid locale. Try `locale -a' for a list of supported values."); + oldloc = std::locale::classic (); + } + retval = os.oscanf (args(1), who); + os.imbue (oldloc); + } else ::error ("%s: format TEMPLATE must be a string", who.c_str ()); } @@ -1199,7 +1222,7 @@ DEFUN (sscanf, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}, @var{pos}] =} sscanf (@var{string}, @var{template}, @var{size})\n\ -@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}] =} sscanf (@var{string}, @var{template}, \"C\")\n\ +@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}] =} sscanf (@var{string}, @var{template}, @var{locale})\n\ This is like @code{fscanf}, except that the characters are taken from the\n\ string @var{string} instead of from a stream. Reaching the end of the\n\ string is treated as an end-of-file condition. In addition to the values\n\ @@ -1224,8 +1247,22 @@ if (os.is_valid ()) { - if (args(1).is_string ()) - retval = os.oscanf (args(1), who); + if (args(1).is_string ()) + { + // Use args(2) val as the new locale setting. As the os + // object is short lived, we don't need to restore + // locale afterwards. + try + { + os.imbue (std::locale (args(2).string_value ().c_str ())); + } + catch (std::runtime_error) + { + // Display a warning if the specified locale is unknown + warning ("sscanf: invalid locale. Try `locale -a' for a list of supported values."); + } + retval = os.oscanf (args(1), who); + } else ::error ("%s: format TEMPLATE must be a string", who.c_str ()); } @@ -1293,10 +1330,16 @@ return retval; } +/* +%!test +%! assert(sscanf('1,2', '%f', 'C'), 1) +%! assert(sscanf('1,2', '%f', 'fr_FR'), 1.2) +*/ + DEFUN (scanf, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{val}, @var{count}, @var{errmsg}] =} scanf (@var{template}, @var{size})\n\ -@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}]] =} scanf (@var{template}, \"C\")\n\ +@deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}]] =} scanf (@var{template}, @var{locale}))\n\ This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\ \n\ It is currently not useful to call @code{scanf} in interactive\n\
--- a/src/oct-stream.h +++ b/src/oct-stream.h @@ -371,6 +371,12 @@ virtual std::ostream *output_stream (void) { return 0; } + // If the derived class is locale-aware, it must implement this function + // in order to set a new locale. By default, this function avoids messing + // with locales and ignores its input argument. + virtual std::locale imbue ( const std::locale & loc ) + { return std::locale::classic (); } + // Return TRUE if this stream is open. bool is_open (void) const { return open_state; } @@ -613,7 +619,23 @@ { return rep ? rep->output_stream () : 0; } - + + std::locale imbue (const std::locale & loc ) + { + if (!rep) return std::locale::classic (); + + std::istream *is = rep->input_stream (); + std::ostream *os = rep->output_stream (); + + if (os) + { + if (is) + (void) is->imbue (loc); + return os->imbue (loc); + } + return is ? is->imbue (loc) : std::locale::classic (); + } + void clearerr (void) { if (rep) rep->clearerr (); } private:
--- a/src/ov-usr-fcn.cc +++ b/src/ov-usr-fcn.cc @@ -51,6 +51,7 @@ #include "parse.h" #include "profiler.h" #include "variables.h" +#include "ov-fcn-handle.h" // Whether to optimize subsasgn method calls. static bool Voptimize_subsasgn_calls = true; @@ -629,12 +630,15 @@ DEFUN (nargin, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} nargin ()\n\ -@deftypefnx {Built-in Function} {} nargin (@var{fcn_name})\n\ +@deftypefnx {Built-in Function} {} nargin (@var{fcn})\n\ Within a function, return the number of arguments passed to the function.\n\ At the top level, return the number of command line arguments passed to\n\ -Octave. If called with the optional argument @var{fcn_name}, return the\n\ -maximum number of arguments the named function can accept, or -1 if the\n\ -function accepts a variable number of arguments.\n\ +Octave.\n\ +\n\ +If called with the optional argument @var{fcn}, a function name or handle,\n\ +return the declared number of arguments that the function can accept.\n\ +If the last argument is @var{varargin} the returned value is negative.\n\ +This feature does not work on builtin functions.\n\ @seealso{nargout, varargin, isargout, varargout, nthargout}\n\ @end deftypefn") { @@ -644,40 +648,37 @@ if (nargin == 1) { - std::string fname = args(0).string_value (); + octave_value func = args(0); - if (! error_state) + if (func.is_string ()) { - octave_value fcn_val = symbol_table::find_function (fname); - - if (fcn_val.is_user_function ()) - { - octave_user_function *fcn = fcn_val.user_function_value (true); + std::string name = func.string_value (); + func = symbol_table::find_function (name); + if (func.is_undefined ()) + error ("nargout: invalid function name: %s", name.c_str ()); + } - if (fcn) - { - if (fcn->takes_varargs ()) - retval = -1; - else - { - tree_parameter_list *param_list = fcn->parameter_list (); + octave_function *fcn_val = func.function_value (); + if (fcn_val) + { + octave_user_function *fcn = fcn_val->user_function_value (true); - retval = param_list ? param_list->length () : 0; - } - } - else - error ("nargin: loading user-defined function failed"); + if (fcn) + { + tree_parameter_list *param_list = fcn->parameter_list (); + + retval = param_list ? param_list->length () : 0; + if (fcn->takes_varargs ()) + retval = -1 - retval; } else { - // FIXME -- what about built-in functions or functions - // defined in .oct files or .mex files? - - error ("nargin: FCN_NAME must be a user-defined function"); + // Matlab gives up for histc, so maybe it's ok we give up somtimes too. + error ("nargin: nargin information not available for builtin functions"); } } else - error ("nargin: FCN_NAME must be a string"); + error ("nargin: FCN must be a string or function handle"); } else if (nargin == 0) { @@ -695,11 +696,12 @@ DEFUN (nargout, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} nargout ()\n\ -@deftypefnx {Built-in Function} {} nargout (@var{fcn_name})\n\ +@deftypefnx {Built-in Function} {} nargout (@var{fcn})\n\ Within a function, return the number of values the caller expects to\n\ -receive. If called with the optional argument @var{fcn_name}, return the\n\ -maximum number of values the named function can produce, or -1 if the\n\ -function can produce a variable number of values.\n\ +receive. If called with the optional argument @var{fcn}, a function\n\ +name or handle, return the number of declared output values that the\n\ +function can produce. If the final output argument is @var{varargout}\n\ +the returned value is negative.\n\ \n\ For example,\n\ \n\ @@ -718,7 +720,23 @@ will cause @code{nargout} to return 2 inside the function\n\ @code{f}.\n\ \n\ -At the top level, @code{nargout} is undefined.\n\ +In the second usage,\n\ +\n\ +@example\n\ +nargout (@@histc) \% or nargout ('histc')\n\ +@end example\n\ +\n\ +will return 2, because @code{histc} has two outputs, whereas\n\ +\n\ +@example\n\ +nargout (@@deal)\n\ +@end example\n\ +\n\ +will return -1, because @code{deal} has a variable number of outputs.\n\ +\n\ +At the top level, @code{nargout} with no argument is undefined.\n\ +@code{nargout} does not work on builtin functions.\n\ +@code{nargout} returns -1 for all anonymous functions.\n\ @seealso{nargin, varargin, isargout, varargout, nthargout}\n\ @end deftypefn") { @@ -728,30 +746,58 @@ if (nargin == 1) { - std::string fname = args(0).string_value (); + octave_value func = args(0); - if (! error_state) + if (func.is_string ()) + { + std::string name = func.string_value (); + func = symbol_table::find_function (name); + if (func.is_undefined ()) + error ("nargout: invalid function name: %s", name.c_str ()); + } + + if (func.is_inline_function ()) { - octave_value fcn_val = symbol_table::find_user_function (fname); + retval = 1; + return retval; + } + + if (func.is_function_handle ()) + { + octave_fcn_handle *fh = func.fcn_handle_value (); + std::string fh_nm = fh->fcn_name (); - octave_user_function *fcn = fcn_val.user_function_value (true); + if (fh_nm == octave_fcn_handle::anonymous) + { + retval = -1; + return retval; + } + } + + octave_function *fcn_val = func.function_value (); + if (fcn_val) + { + octave_user_function *fcn = fcn_val->user_function_value (true); if (fcn) { + tree_parameter_list *ret_list = fcn->return_list (); + + retval = ret_list ? ret_list->length () : 0; + if (fcn->takes_var_return ()) - retval = -1; - else - { - tree_parameter_list *ret_list = fcn->return_list (); - - retval = ret_list ? ret_list->length () : 0; - } + retval = -1 - retval; } else - error ("nargout: invalid function"); + { + // JWE said this information is not available (currently, 2011-03-10) + // without making intrusive changes to Octave. + // Matlab gives up for histc, so maybe it's ok we give up somtimes too. + error ("nargout: nargout information not available for builtin functions."); + } } else - error ("nargout: FCN_NAME must be a string"); + error ("nargout: FCN must be a string or function handle"); } else if (nargin == 0) {