]> Creatis software - CreaPhase.git/blob - octave_packages/strings-1.1.0/cstrcmp.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / strings-1.1.0 / cstrcmp.m
1 ## Copyright (C) 2007 Muthiah Annamalai <muthiah.annamalai@uta.edu>
2 ## Copyright (C) 2012 CarnĂ« Draug <carandraug+dev@gmail.com>
3 ##
4 ## This program is free software; you can redistribute it and/or modify it under
5 ## the terms of the GNU General Public License as published by the Free Software
6 ## Foundation; either version 3 of the License, or (at your option) any later
7 ## version.
8 ##
9 ## This program is distributed in the hope that it will be useful, but WITHOUT
10 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 ## details.
13 ##
14 ## You should have received a copy of the GNU General Public License along with
15 ## this program; if not, see <http://www.gnu.org/licenses/>.
16
17 ## -*- texinfo -*-
18 ## @deftypefn {Function File} {@var{rval} =} cstrcmp (@var{s1}, @var{s2})
19 ## Compare strings @var{s1} and @var{s2} like the C function.
20 ##
21 ## Aside the difference to the return values, this function API is exactly the
22 ## same as Octave's @code{strcmp} and will accept cell arrays as well.
23 ##
24 ## @var{rval} indicates the relationship between the strings:
25 ## @itemize @bullet
26 ## @item
27 ## A value of 0 indicates that both strings are equal;
28 ## @item
29 ## A value of +1 indicates that the first character that does not match has a
30 ## greater value in @var{s1} than in @var{s2}.
31 ## @item
32 ## A value of -1 indicates that the first character that does not match has a
33 ## match has a smaller value in @var{s1} than in @var{s2}.
34 ## @end itemize
35 ##
36 ## @example
37 ## @group
38 ## cstrcmp("marry","marry")
39 ##       @result{}  0
40 ## cstrcmp("marry","marri")
41 ##       @result{} +1
42 ## cstrcmp("marri","marry")
43 ##       @result{} -1
44 ## @end group
45 ## @end example
46 ##
47 ## @seealso {strcmp, strcmpi}
48 ## @end deftypefn
49
50 function rval = cstrcmp (s1, s2)
51
52   if (nargin != 2)
53     print_usage();
54   endif
55
56   ## this function is just like Octave's strcmp but the 0 and 1 need to be
57   ## inverted. Once is done, if there are 1, we need to decide if they will
58   ## be positive or negative. Also, since it's possible that the value needs
59   ## to be negative, class must be double (strcmp returns logical)
60   rval = double(!strcmp (s1, s2));
61
62   if (!any (rval))
63     ## all zeros, no need to do anything else
64     return
65   endif
66
67   ## get index of the ones we have to "fix"
68   idx = find (rval == 1);
69   ## if any is not a cell, this simplifies the code that follows
70   if (!iscell (s1)), s1 = {s1}; endif
71   if (!iscell (s2)), s2 = {s2}; endif
72   ## there's 2 hypothesis:
73   ##  - arrays have same length (even if it's only one cell)
74   ##  - arrays have different lengths (in which case, one will have a single cell)
75   if (numel (s1) == numel (s2))
76     rval(idx) = cellfun (@get_sign, s1(idx), s2(idx));
77   elseif (numel (s1) > 1)
78     rval(idx) = cellfun (@get_sign, s1(idx), s2(1));
79   elseif (numel (s2) > 1)
80     rval(idx) = cellfun (@get_sign, s1(1), s2(idx));
81   endif
82 endfunction
83
84 function r = get_sign (s1, s2)
85   ## strings may have different lengths which kinda complicates things
86   ## in case the strings are of different size, we need to make them equal
87   ## If once "trimmed", the strings are equal, the "shortest" string is
88   ## considered smaller since the comparison is made by filling it with null
89
90   ns1  = numel (s1);
91   ns2  = numel (s2);
92   nmin = min (ns1, ns2);
93
94   ## if one of the strings is empty, we are already done
95   if (nmin == 0), r = sign (ns1 - ns2); return endif
96
97   s  = sign (s1(1:nmin) - s2(1:nmin));
98   if (any (s))
99     ## if there's any difference between this part of the two strings, get the
100     ## index of the first occurence and return its value
101     r = s(find (s != 0, 1));
102   else
103     r = sign (ns1 - ns2);
104   endif
105 endfunction
106
107 %!assert(cstrcmp("hello","hello"),0);
108 %!assert(cstrcmp("marry","marie"),+1);
109 %!assert(cstrcmp("Matlab","Octave"),-1);
110 %!assert(cstrcmp("Matlab",{"Octave","Scilab","Lush"}), [-1 -1 +1]);
111 %!assert(cstrcmp({"Octave","Scilab","Lush"},"Matlab"), [+1 +1 -1]);