Mercurial > octave
diff libinterp/corefcn/strfns.cc @ 22280:26109cce022e
New string utility functions to replace caseless_str for liboctave (bug #48726)
* oct-string.h, oct-string.cc: new files that implement strcmp, strcmpi,
strncmp, and strncmpi functions in the new octave::string namespace. This
functions behave like the ones available in the Octave interpreter.
* libinterp/corefcn/strfns.cc: make use of the new functions in liboctave.
* libgui/graphics/QtHandlesUtils.cc, libgui/graphics/QtHandlesUtils.h,
libinterp/corefcn/cellfun.cc, libinterp/dldfcn/chol.cc: make use of the
new functions instead of caseless_str.
* liboctave/util/module.mk: add new files to build system.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Sat, 13 Aug 2016 15:35:58 +0100 |
parents | 278fc29b69ca |
children | bac0d6f07a3e |
line wrap: on
line diff
--- a/libinterp/corefcn/strfns.cc Sat Aug 13 12:49:58 2016 +0100 +++ b/libinterp/corefcn/strfns.cc Sat Aug 13 15:35:58 2016 +0100 @@ -40,6 +40,8 @@ #include "unwind-prot.h" #include "utils.h" +#include "oct-string.h" + DEFUN (char, args, , doc: /* -*- texinfo -*- @deftypefn {} {} char (@var{x}) @@ -311,10 +313,10 @@ static octave_value do_strcmp_fun (const octave_value& arg0, const octave_value& arg1, octave_idx_type n, const char *fcn_name, - bool (*array_op) (const charNDArray&, const charNDArray&, + bool (*array_op) (const Array<char>&, const Array<char>&, octave_idx_type), bool (*str_op) (const std::string&, const std::string&, - octave_idx_type)) + std::string::size_type)) { octave_value retval; @@ -514,21 +516,20 @@ return retval; } -// If both args are arrays, dimensions may be significant. -static bool -strcmp_array_op (const charNDArray& s1, const charNDArray& s2, octave_idx_type) -{ - return (s1.dims () == s2.dims () - && std::equal (s1.data (), s1.data () + s1.numel (), s2.data ())); -} + +// These are required so that they match the same signature as strncmp +// and strncmpi and can therefore be used in do_strcmp_fun. -// Otherwise, just use strings. +template <typename T, typename T_size_type> static bool -strcmp_str_op (const std::string& s1, const std::string& s2, - octave_idx_type) -{ - return s1 == s2; -} +strcmp_ignore_n (const T& s1, const T& s2, T_size_type) +{ return octave::string::strcmp (s1, s2); } + +template <typename T, typename T_size_type> +static bool +strcmpi_ignore_n (const T& s1, const T& s2, T_size_type) +{ return octave::string::strcmpi (s1, s2); } + DEFUN (strcmp, args, , doc: /* -*- texinfo -*- @@ -552,7 +553,7 @@ print_usage (); return ovl (do_strcmp_fun (args(0), args(1), 0, "strcmp", - strcmp_array_op, strcmp_str_op)); + strcmp_ignore_n, strcmp_ignore_n)); } /* @@ -603,29 +604,6 @@ %!error strcmp ("foo", "bar", 3) */ -// Apparently, Matlab ignores the dims with strncmp. -static bool -strncmp_array_op (const charNDArray& s1, const charNDArray& s2, - octave_idx_type n) -{ - octave_idx_type l1 = s1.numel (); - octave_idx_type l2 = s2.numel (); - return (n > 0 && n <= l1 && n <= l2 - && std::equal (s1.data (), s1.data () + n, s2.data ())); -} - -// Otherwise, just use strings. Note that we neither extract substrings (which -// would mean a copy, at least in GCC), nor use string::compare (which is a -// 3-way compare). -static bool -strncmp_str_op (const std::string& s1, const std::string& s2, octave_idx_type n) -{ - octave_idx_type l1 = s1.length (); - octave_idx_type l2 = s2.length (); - return (n > 0 && n <= l1 && n <= l2 - && std::equal (s1.data (), s1.data () + n, s2.data ())); -} - DEFUN (strncmp, args, , doc: /* -*- texinfo -*- @deftypefn {} {} strncmp (@var{s1}, @var{s2}, @var{n}) @@ -665,7 +643,8 @@ if (n > 0) return ovl (do_strcmp_fun (args(0), args(1), n, "strncmp", - strncmp_array_op, strncmp_str_op)); + octave::string::strncmp, + octave::string::strncmp)); else error ("strncmp: N must be greater than 0"); } @@ -683,34 +662,6 @@ %!error strncmp ("abc", "def") */ -// case-insensitive character equality functor -struct icmp_char_eq : public std::binary_function<char, char, bool> -{ - bool operator () (char x, char y) const - { - return std::toupper (x) == std::toupper (y); - } -}; - -// strcmpi is equivalent to strcmp in that it checks all dims. -static bool -strcmpi_array_op (const charNDArray& s1, const charNDArray& s2, octave_idx_type) -{ - return (s1.dims () == s2.dims () - && std::equal (s1.data (), s1.data () + s1.numel (), s2.data (), - icmp_char_eq ())); -} - -// Ditto for string. -static bool -strcmpi_str_op (const std::string& s1, const std::string& s2, - octave_idx_type) -{ - return (s1.size () == s2.size () - && std::equal (s1.data (), s1.data () + s1.size (), s2.data (), - icmp_char_eq ())); -} - DEFUNX ("strcmpi", Fstrcmpi, args, , doc: /* -*- texinfo -*- @deftypefn {} {} strcmpi (@var{s1}, @var{s2}) @@ -735,37 +686,13 @@ print_usage (); return ovl (do_strcmp_fun (args(0), args(1), 0, "strcmpi", - strcmpi_array_op, strcmpi_str_op)); + strcmpi_ignore_n, strcmpi_ignore_n)); } /* %!assert (strcmpi ("abc123", "ABC123"), true) */ -// Like strncmp. -static bool -strncmpi_array_op (const charNDArray& s1, const charNDArray& s2, - octave_idx_type n) -{ - octave_idx_type l1 = s1.numel (); - octave_idx_type l2 = s2.numel (); - return (n > 0 && n <= l1 && n <= l2 - && std::equal (s1.data (), s1.data () + n, s2.data (), - icmp_char_eq ())); -} - -// Ditto. -static bool -strncmpi_str_op (const std::string& s1, const std::string& s2, - octave_idx_type n) -{ - octave_idx_type l1 = s1.length (); - octave_idx_type l2 = s2.length (); - return (n > 0 && n <= l1 && n <= l2 - && std::equal (s1.data (), s1.data () + n, s2.data (), - icmp_char_eq ())); -} - DEFUNX ("strncmpi", Fstrncmpi, args, , doc: /* -*- texinfo -*- @deftypefn {} {} strncmpi (@var{s1}, @var{s2}, @var{n}) @@ -793,7 +720,8 @@ if (n > 0) return ovl (do_strcmp_fun (args(0), args(1), n, "strncmpi", - strncmpi_array_op, strncmpi_str_op)); + octave::string::strncmpi, + octave::string::strncmpi)); else error ("strncmpi: N must be greater than 0"); }