Mercurial > octave-nkf
annotate src/strfns.cc @ 8461:9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
author | Thorsten Meyer <thorsten.meyier@gmx.de> |
---|---|
date | Mon, 12 Jan 2009 12:13:05 -0500 |
parents | 8dff9cba15fe |
children | ebdf1e058d85 |
rev | line source |
---|---|
807 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002, 2003, 2004, 2005, |
4 2006, 2007 John W. Eaton | |
807 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
807 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
807 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
1192 | 25 #include <config.h> |
807 | 26 #endif |
27 | |
1355 | 28 #include <cctype> |
7528
26d8a92644de
try to avoid ctype macro problems
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
29 |
5765 | 30 #include <sstream> |
807 | 31 |
32 #include "dMatrix.h" | |
33 | |
5416 | 34 #include "Cell.h" |
1355 | 35 #include "defun.h" |
807 | 36 #include "error.h" |
37 #include "gripes.h" | |
2366 | 38 #include "ov.h" |
1355 | 39 #include "oct-obj.h" |
4457 | 40 #include "unwind-prot.h" |
807 | 41 #include "utils.h" |
42 | |
4358 | 43 DEFUN (char, args, , |
44 "-*- texinfo -*-\n\ | |
45 @deftypefn {Built-in Function} {} char (@var{x})\n\ | |
46 @deftypefnx {Built-in Function} {} char (@var{cell_array})\n\ | |
47 @deftypefnx {Built-in Function} {} char (@var{s1}, @var{s2}, @dots{})\n\ | |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
48 Create a string array from one or more numeric matrices, character\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
49 matrices or cell arrays. For numerical input, each element is converted\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
50 to the corresponding ASCII character. The arguments (and elements of\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
51 cell array(s)) are concatenated vertically.\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
52 The returned values are padded with blanks as needed to make each row\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
53 of the string array have the same length. Empty strings are not removed.\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
54 For example,\n\ |
4358 | 55 \n\ |
56 @example\n\ | |
57 @group\n\ | |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
58 char ([97, 98, 99], \"\", @{\"98\", \"99\", 100@}, [\"num\", \"bers\"])\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
59 @result{} [\"abc \"\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
60 \" \"\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
61 \"98 \"\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
62 \"99 \"\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
63 \"d \"\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
64 \"numbers\"]\n\ |
4358 | 65 @end group\n\ |
66 @end example\n\ | |
67 \n\ | |
68 @end deftypefn") | |
69 { | |
70 octave_value retval; | |
71 | |
72 int nargin = args.length (); | |
73 | |
74 if (nargin == 1) | |
5281 | 75 retval = args(0).convert_to_str (true, true, |
76 args(0).is_dq_string () ? '"' : '\''); | |
4358 | 77 else if (nargin > 1) |
78 { | |
79 int n_elts = 0; | |
80 | |
81 int max_len = 0; | |
82 | |
83 for (int i = 0; i < nargin; i++) | |
84 { | |
5707 | 85 string_vector s = args(i).all_strings (); |
4358 | 86 |
87 if (error_state) | |
88 { | |
4457 | 89 error ("char: unable to convert some args to strings"); |
4358 | 90 return retval; |
91 } | |
92 | |
8353
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
93 if (s.length () > 0) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
94 n_elts += s.length (); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
95 else |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
96 n_elts += 1; |
4358 | 97 |
98 int s_max_len = s.max_length (); | |
99 | |
100 if (s_max_len > max_len) | |
101 max_len = s_max_len; | |
102 } | |
103 | |
104 string_vector result (n_elts); | |
105 | |
106 int k = 0; | |
107 | |
108 for (int i = 0; i < nargin; i++) | |
109 { | |
5707 | 110 string_vector s = args(i).all_strings (); |
4358 | 111 |
112 int n = s.length (); | |
113 | |
8353
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
114 if (n > 0) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
115 { |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
116 for (int j = 0; j < n; j++) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
117 { |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
118 std::string t = s[j]; |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
119 int t_len = t.length (); |
4358 | 120 |
8353
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
121 if (max_len > t_len) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
122 t += std::string (max_len - t_len, ' '); |
4358 | 123 |
8353
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
124 result[k++] = t; |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
125 } |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
126 } |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
127 else |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
128 { |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
129 result[k++] = std::string (max_len, ' '); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
130 } |
4358 | 131 } |
132 | |
5280 | 133 retval = octave_value (result, '\''); |
4358 | 134 } |
135 else | |
5823 | 136 print_usage (); |
4358 | 137 |
138 return retval; | |
139 } | |
140 | |
8353
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
141 /* |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
142 %!error <Invalid call to char> char() |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
143 %!assert (char (100) == "d"); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
144 %!assert (all(char (100,100) == ["d";"d"])); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
145 %!assert (all(char ({100,100}) == ["d";"d"])); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
146 %!assert (all(char ([100,100]) == ["dd"])); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
147 %!assert (all(char ({100,{100}}) == ["d";"d"])); |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
148 %!assert (all(char (100, [], 100) == ["d";" ";"d"])) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
149 %!assert (all(char ({100, [], 100}) == ["d";" ";"d"])) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
150 %!assert (all(char ({100,{100, {""}}}) == ["d";"d";" "])) |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
151 %!assert (all(char (["a";"be"], {"c", 100}) == ["a";"be";"c";"d"])) |
8372
8dff9cba15fe
move str2mat to deprecated and make it a simple wrapper around char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8353
diff
changeset
|
152 %!assert(strcmp (char ("a", "bb", "ccc"), ["a "; "bb "; "ccc"])); |
8353
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
153 */ |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
154 |
349a555729a9
keep empty strings in char
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
7528
diff
changeset
|
155 |
4535 | 156 DEFUN (ischar, args, , |
3361 | 157 "-*- texinfo -*-\n\ |
4535 | 158 @deftypefn {Built-in Function} {} ischar (@var{a})\n\ |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
159 Return 1 if @var{a} is a character array. Otherwise, return 0.\n\ |
3361 | 160 @end deftypefn") |
807 | 161 { |
4233 | 162 octave_value retval; |
807 | 163 |
164 int nargin = args.length (); | |
165 | |
166 if (nargin == 1 && args(0).is_defined ()) | |
4233 | 167 retval = args(0).is_string (); |
807 | 168 else |
5823 | 169 print_usage (); |
807 | 170 |
171 return retval; | |
172 } | |
173 | |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
174 /* |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
175 |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
176 %!assert (ischar ("a"), logical (1)); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
177 %!assert (ischar (["ab";"cd"]), logical (1)); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
178 %!assert (ischar ({"ab"}), logical (0)); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
179 %!assert (ischar (1), logical (0)); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
180 %!error <Invalid call to ischar.*> ischar (); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
181 |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
182 */ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
183 |
5415 | 184 DEFUN (strcmp, args, , |
185 "-*- texinfo -*-\n\ | |
6678 | 186 @deftypefn {Built-in Function} {} strcmp (@var{s1}, @var{s2})\n\ |
5415 | 187 Return 1 if the character strings @var{s1} and @var{s2} are the same,\n\ |
188 and 0 otherwise.\n\ | |
5674 | 189 \n\ |
190 If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\ | |
191 of the same size is returned, containing the values described above for\n\ | |
192 every member of the cell array. The other argument may also be a cell\n\ | |
193 array of strings (of the same size or with only one element), char matrix\n\ | |
194 or character string.\n\ | |
195 \n\ | |
196 @strong{Caution:} For compatibility with @sc{Matlab}, Octave's strcmp\n\ | |
197 function returns 1 if the character strings are equal, and 0 otherwise.\n\ | |
198 This is just the opposite of the corresponding C library function.\n\ | |
199 @seealso{strcmpi, strncmp, strncmpi}\n\ | |
5415 | 200 @end deftypefn") |
201 { | |
5531 | 202 octave_value retval; |
5415 | 203 |
5416 | 204 if (args.length () == 2) |
205 { | |
206 bool s1_string = args(0).is_string (); | |
207 bool s1_cell = args(0).is_cell (); | |
208 bool s2_string = args(1).is_string (); | |
209 bool s2_cell = args(1).is_cell (); | |
5415 | 210 |
5416 | 211 if (s1_string && s2_string) |
212 { | |
213 // Must match exactly in all dimensions. | |
214 | |
215 const dim_vector dv1 = args(0).dims (); | |
216 const dim_vector dv2 = args(1).dims (); | |
5415 | 217 |
5416 | 218 if (dv1.length () == dv2.length ()) |
219 { | |
220 for (int i = 0; i < dv1.length (); i++) | |
221 { | |
222 if (dv1(i) != dv2(i)) | |
223 { | |
224 retval = false; | |
225 return retval; | |
226 } | |
227 } | |
5415 | 228 |
5416 | 229 if (dv1(0) == 0) |
230 retval = true; | |
231 else | |
232 { | |
233 charNDArray s1 = args(0).char_array_value (); | |
234 charNDArray s2 = args(1).char_array_value (); | |
5415 | 235 |
5416 | 236 for (int i = 0; i < dv1.numel (); i++) |
237 { | |
238 if (s1(i) != s2(i)) | |
239 { | |
240 retval = false; | |
241 return retval; | |
242 } | |
243 } | |
5415 | 244 |
5416 | 245 retval = true; |
246 } | |
5415 | 247 } |
248 } | |
5416 | 249 else if ((s1_string && s2_cell) || (s1_cell && s2_string)) |
5415 | 250 { |
5416 | 251 string_vector str; |
252 Cell cell; | |
253 int r; | |
5415 | 254 |
5416 | 255 if (s1_string) |
256 { | |
257 str = args(0).all_strings (); | |
258 r = args(0).rows (); | |
259 cell = args(1).cell_value (); | |
260 } | |
261 else | |
262 { | |
263 str = args(1).all_strings (); | |
264 r = args(1).rows (); | |
265 cell = args(0).cell_value (); | |
266 } | |
267 | |
5862 | 268 if (r == 0 || r == 1) |
5416 | 269 { |
270 // Broadcast the string. | |
271 | |
272 boolNDArray output (cell.dimensions); | |
5415 | 273 |
5862 | 274 std::string s = r == 0 ? std::string () : str[0]; |
275 | |
5416 | 276 for (int i = 0; i < cell.length (); i++) |
6250 | 277 { |
278 if (cell(i).is_string ()) | |
279 output(i) = (cell(i).string_value () == s); | |
280 else | |
281 output(i) = false; | |
282 } | |
5416 | 283 |
284 retval = output; | |
285 } | |
286 else if (r > 1) | |
5415 | 287 { |
5416 | 288 if (cell.length () == 1) |
5415 | 289 { |
5416 | 290 // Broadcast the cell. |
291 | |
292 const dim_vector dv (r, 1); | |
293 boolNDArray output (dv); | |
294 | |
295 if (cell(0).is_string ()) | |
296 { | |
297 const std::string str2 = cell(0).string_value (); | |
5415 | 298 |
5416 | 299 for (int i = 0; i < r; i++) |
300 output(i) = (str[i] == str2); | |
301 } | |
302 else | |
303 { | |
304 for (int i = 0; i < r; i++) | |
305 output(i) = false; | |
306 } | |
307 | |
308 retval = output; | |
5415 | 309 } |
310 else | |
311 { | |
5416 | 312 // Must match in all dimensions. |
313 | |
314 boolNDArray output (cell.dimensions); | |
5415 | 315 |
5416 | 316 if (cell.length () == r) |
317 { | |
318 for (int i = 0; i < r; i++) | |
6250 | 319 { |
320 if (cell(i).is_string ()) | |
321 output(i) = (str[i] == cell(i).string_value ()); | |
322 else | |
323 output(i) = false; | |
324 } | |
5415 | 325 |
5416 | 326 retval = output; |
327 } | |
328 else | |
329 retval = false; | |
5415 | 330 } |
331 } | |
332 } | |
5416 | 333 else if (s1_cell && s2_cell) |
5415 | 334 { |
5416 | 335 Cell cell1; |
336 Cell cell2; | |
5415 | 337 |
5416 | 338 int r1 = args(0).numel (); |
339 int r2; | |
340 | |
341 if (r1 == 1) | |
342 { | |
343 // Make the singleton cell2. | |
5415 | 344 |
5416 | 345 cell1 = args(1).cell_value (); |
346 cell2 = args(0).cell_value (); | |
347 r1 = cell1.length (); | |
348 r2 = 1; | |
349 } | |
350 else | |
351 { | |
352 cell1 = args(0).cell_value (); | |
353 cell2 = args(1).cell_value (); | |
354 r2 = cell2.length (); | |
355 } | |
5415 | 356 |
5416 | 357 const dim_vector size1 = cell1.dimensions; |
358 const dim_vector size2 = cell2.dimensions; | |
359 | |
360 boolNDArray output (size1); | |
361 | |
362 if (r2 == 1) | |
363 { | |
364 // Broadcast cell2. | |
365 | |
366 if (! cell2(0).is_string ()) | |
5415 | 367 { |
5416 | 368 for (int i = 0; i < r1; i++) |
369 output(i) = false; | |
5415 | 370 } |
371 else | |
5416 | 372 { |
373 const std::string str2 = cell2(0).string_value (); | |
374 | |
375 for (int i = 0; i < r1; i++) | |
376 { | |
377 if (cell1(i).is_string ()) | |
378 { | |
379 const std::string str1 = cell1(i).string_value (); | |
380 output(i) = (str1 == str2); | |
381 } | |
382 else | |
383 output(i) = false; | |
384 } | |
385 } | |
5415 | 386 } |
5416 | 387 else |
388 { | |
389 if (size1 != size2) | |
390 { | |
391 error ("strcmp: nonconformant cell arrays"); | |
392 return retval; | |
393 } | |
394 | |
395 for (int i = 0; i < r1; i++) | |
396 { | |
397 if (cell1(i).is_string () && cell2(i).is_string ()) | |
398 { | |
399 const std::string str1 = cell1(i).string_value (); | |
400 const std::string str2 = cell2(i).string_value (); | |
401 output(i) = (str1 == str2); | |
402 } | |
403 else | |
404 output(i) = false; | |
405 } | |
406 } | |
407 | |
408 retval = output; | |
5415 | 409 } |
5531 | 410 else |
411 retval = false; | |
5415 | 412 } |
5416 | 413 else |
5823 | 414 print_usage (); |
5415 | 415 |
416 return retval; | |
417 } | |
418 | |
5862 | 419 /* |
420 %!shared x | |
421 %! x = char (zeros (0, 2)); | |
422 %!assert (strcmp ('', x) == false); | |
423 %!assert (strcmp (x, '') == false); | |
424 %!assert (strcmp (x, x) == true); | |
5911 | 425 ## %!assert (strcmp ({''}, x) == false); |
426 ## %!assert (strcmp ({x}, '') == false); | |
427 ## %!assert (strcmp ({x}, x) == true); | |
428 ## %!assert (strcmp ('', {x}) == false); | |
429 ## %!assert (strcmp (x, {''}) == false); | |
430 ## %!assert (strcmp (x, {x}) == true); | |
431 ## %!assert (all (strcmp ({x; x}, '') == [false; false])); | |
432 ## %!assert (all (strcmp ({x; x}, {''}) == [false; false])); | |
433 ## %!assert (all (strcmp ('', {x; x}) == [false; false])); | |
434 ## %!assert (all (strcmp ({''}, {x; x}) == [false; false])); | |
5862 | 435 %!assert (strcmp ({'foo'}, x) == false); |
436 %!assert (strcmp ({'foo'}, 'foo') == true); | |
437 %!assert (strcmp ({'foo'}, x) == false); | |
438 %!assert (strcmp (x, {'foo'}) == false); | |
439 %!assert (strcmp ('foo', {'foo'}) == true); | |
440 %!assert (strcmp (x, {'foo'}) == false); | |
441 %!shared y | |
442 %! y = char (zeros (2, 0)); | |
443 %!assert (strcmp ('', y) == false); | |
444 %!assert (strcmp (y, '') == false); | |
445 %!assert (strcmp (y, y) == true); | |
446 %!assert (all (strcmp ({''}, y) == [true; true])); | |
447 %!assert (strcmp ({y}, '') == true); | |
448 %!assert (all (strcmp ({y}, y) == [true; true])); | |
449 %!assert (all (strcmp ('', {y}) == [true; true])); | |
450 %!assert (all (strcmp (y, {''}) == [true; true])); | |
451 %!assert (all (strcmp (y, {y}) == [true; true])); | |
5911 | 452 ## %!assert (all (strcmp ({y; y}, '') == [false; false])); |
453 ## %!assert (all (strcmp ({y; y}, {''}) == [false; false])); | |
454 ## %!assert (all (strcmp ('', {y; y}) == [false; false])); | |
455 ## %!assert (all (strcmp ({''}, {y; y}) == [false; false])); | |
5862 | 456 %!assert (all (strcmp ({'foo'}, y) == [false; false])); |
457 %!assert (all (strcmp ({'foo'}, y) == [false; false])); | |
458 %!assert (all (strcmp (y, {'foo'}) == [false; false])); | |
459 %!assert (all (strcmp (y, {'foo'}) == [false; false])); | |
460 */ | |
461 | |
6250 | 462 DEFUN (strncmp, args, , |
463 "-*- texinfo -*-\n\ | |
6678 | 464 @deftypefn {Built-in Function} {} strncmp (@var{s1}, @var{s2}, @var{n})\n\ |
6250 | 465 Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2} are the same,\n\ |
466 and 0 otherwise.\n\ | |
467 \n\ | |
468 @example\n\ | |
469 @group\n\ | |
470 strncmp (\"abce\", \"abcd\", 3)\n\ | |
471 @result{} 1\n\ | |
472 @end group\n\ | |
473 @end example\n\ | |
474 \n\ | |
475 If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\ | |
476 of the same size is returned, containing the values described above for\n\ | |
477 every member of the cell array. The other argument may also be a cell\n\ | |
478 array of strings (of the same size or with only one element), char matrix\n\ | |
479 or character string.\n\ | |
480 \n\ | |
481 @example\n\ | |
482 @group\n\ | |
6256 | 483 strncmp (\"abce\", @{\"abcd\", \"bca\", \"abc\"@}, 3)\n\ |
6250 | 484 @result{} [1, 0, 1]\n\ |
485 @end group\n\ | |
486 @end example\n\ | |
487 \n\ | |
488 @strong{Caution:} For compatibility with @sc{Matlab}, Octave's strncmp\n\ | |
489 function returns 1 if the character strings are equal, and 0 otherwise.\n\ | |
490 This is just the opposite of the corresponding C library function.\n\ | |
491 @seealso{strncmpi, strcmp, strcmpi}\n\ | |
492 @end deftypefn") | |
493 { | |
494 octave_value retval; | |
495 | |
496 if (args.length () == 3) | |
497 { | |
498 bool s1_string = args(0).is_string (); | |
499 bool s1_cell = args(0).is_cell (); | |
500 bool s2_string = args(1).is_string (); | |
501 bool s2_cell = args(1).is_cell (); | |
502 | |
503 // Match only first n strings. | |
504 int n = args(2).int_value (); | |
505 | |
506 if (n <= 0) | |
507 { | |
508 error ("strncmp: N must be greater than 0"); | |
509 return retval; | |
510 } | |
511 | |
512 if (s1_string && s2_string) | |
513 { | |
514 // The only restriction here is that each string has equal or | |
515 // greater than n characters | |
516 | |
517 const dim_vector dv1 = args(0).dims (); | |
518 const dim_vector dv2 = args(1).dims (); | |
519 | |
520 if (dv1.numel () >= n && dv2.numel () >= n) | |
521 { | |
522 // Follow Matlab in the sense that the first n characters of | |
523 // the two strings (in column major order) need to be the same. | |
524 charNDArray s1 = args(0).char_array_value (); | |
525 charNDArray s2 = args(1).char_array_value (); | |
526 | |
527 for (int i = 0; i < n; i++) | |
528 { | |
529 if (s1(i) != s2(i)) | |
530 { | |
531 retval = false; | |
532 return retval; | |
533 } | |
534 } | |
535 | |
536 retval = true; | |
537 } | |
538 else | |
539 retval = false; | |
540 } | |
541 else if ((s1_string && s2_cell) || (s1_cell && s2_string)) | |
542 { | |
543 string_vector str; | |
544 Cell cell; | |
545 int r, c; | |
546 | |
547 if (s1_string) | |
548 { | |
549 str = args(0).all_strings (); | |
550 r = args(0).rows (); | |
551 c = args(0).columns (); | |
552 cell = args(1).cell_value (); | |
553 } | |
554 else | |
555 { | |
556 str = args(1).all_strings (); | |
557 r = args(1).rows (); | |
558 c = args(1).columns (); | |
559 cell = args(0).cell_value (); | |
560 } | |
561 | |
562 if (r == 1) | |
563 { | |
564 // Broadcast the string. | |
565 | |
566 boolNDArray output (cell.dimensions); | |
567 | |
568 if (c < n) | |
569 { | |
570 for (int i = 0; i < cell.length (); i++) | |
571 output(i) = false; | |
572 } | |
573 else | |
574 { | |
575 for (int i = 0; i < cell.length (); i++) | |
576 { | |
577 if (cell(i).is_string ()) | |
578 { | |
579 const std::string str2 = cell(i).string_value (); | |
580 | |
581 if (str2.length() >= n) | |
582 { | |
583 if (str2.compare (0, n, str[0], 0, n) == 0) | |
584 output(i) = true; | |
585 else | |
586 output(i) = false; | |
587 } | |
588 else | |
589 output(i) = false; | |
590 } | |
591 } | |
592 } | |
593 | |
594 retval = output; | |
595 } | |
596 else if (r > 1) | |
597 { | |
598 if (cell.length () == 1) | |
599 { | |
600 // Broadcast the cell. | |
601 | |
602 const dim_vector dv (r, 1); | |
603 boolNDArray output (dv); | |
604 | |
605 if (cell(0).is_string () && c >= n) | |
606 { | |
607 const std::string str2 = cell(0).string_value (); | |
608 | |
609 if (str2.length () >= n) | |
610 { | |
611 for (int i = 0; i < r; i++) | |
612 { | |
613 if (str[i].compare (0, n, str2, 0, n) == 0) | |
614 output(i) = true; | |
615 else | |
616 output(i) = false; | |
617 } | |
618 } | |
619 else | |
620 { | |
621 for (int i = 0; i < r; i++) | |
622 output(i) = false; | |
623 } | |
624 } | |
625 else | |
626 { | |
627 for (int i = 0; i < r; i++) | |
628 output(i) = false; | |
629 } | |
630 | |
631 retval = output; | |
632 } | |
633 else | |
634 { | |
635 // Must match in all dimensions. | |
636 | |
637 boolNDArray output (cell.dimensions); | |
638 | |
639 if (cell.numel () == r) | |
640 { | |
641 for (int i = 0; i < r; i++) | |
642 { | |
643 output(i) = false; | |
644 | |
645 if (cell(i).is_string () && c >= n) | |
646 { | |
647 std::string str2 = cell(i).string_value (); | |
648 | |
649 if (str2.length () >= n | |
650 && str2.compare (0, n, str[i], 0, n) == 0) | |
651 output(i) = true; | |
652 } | |
653 } | |
654 | |
655 retval = output; | |
656 } | |
657 else | |
658 { | |
659 error ("strncmp: the number of rows of the string matrix must match the number of elements in the cell"); | |
660 return retval; | |
661 } | |
662 } | |
663 } | |
664 } | |
665 else if (s1_cell && s2_cell) | |
666 { | |
667 Cell cell1; | |
668 Cell cell2; | |
669 | |
670 int r1 = args(0).numel (); | |
671 int r2; | |
672 | |
673 if (r1 == 1) | |
674 { | |
675 // Make the singleton cell2. | |
676 | |
677 cell1 = args(1).cell_value (); | |
678 cell2 = args(0).cell_value (); | |
679 r1 = cell1.length (); | |
680 r2 = 1; | |
681 } | |
682 else | |
683 { | |
684 cell1 = args(0).cell_value (); | |
685 cell2 = args(1).cell_value (); | |
686 r2 = cell2.length (); | |
687 } | |
688 | |
689 const dim_vector size1 = cell1.dimensions; | |
690 const dim_vector size2 = cell2.dimensions; | |
691 | |
692 boolNDArray output (size1); | |
693 | |
694 if (r2 == 1) | |
695 { | |
696 // Broadcast cell2. | |
697 | |
698 if (! cell2(0).is_string ()) | |
699 { | |
700 for (int i = 0; i < r1; i++) | |
701 output(i) = false; | |
702 } | |
703 else | |
704 { | |
705 const std::string str2 = cell2(0).string_value (); | |
706 | |
707 for (int i = 0; i < r1; i++) | |
708 { | |
709 if (cell1(i).is_string ()) | |
710 { | |
711 const std::string str1 = cell1(i).string_value (); | |
712 | |
713 if (str1.length () >= n && str2.length () >= n | |
714 && str1.compare (0, n, str2, 0, n) == 0) | |
715 output(i) = true; | |
716 else | |
717 output(i) = false; | |
718 } | |
719 else | |
720 output(i) = false; | |
721 } | |
722 } | |
723 } | |
724 else | |
725 { | |
726 if (size1 != size2) | |
727 { | |
728 error ("strncmp: nonconformant cell arrays"); | |
729 return retval; | |
730 } | |
731 | |
732 for (int i = 0; i < r1; i++) | |
733 { | |
734 if (cell1(i).is_string () && cell2(i).is_string ()) | |
735 { | |
736 const std::string str1 = cell1(i).string_value (); | |
737 const std::string str2 = cell2(i).string_value (); | |
738 | |
739 if (str1.length () >= n && str2.length () >= n | |
740 && str1.compare (0, n, str2, 0, n) == 0) | |
741 output(i) = true; | |
742 else | |
743 output(i) = false; | |
744 } | |
745 else | |
746 output(i) = false; | |
747 } | |
748 } | |
749 | |
750 retval = output; | |
751 } | |
752 else | |
753 retval = false; | |
754 } | |
755 else | |
756 print_usage (); | |
757 | |
758 return retval; | |
759 } | |
760 | |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
761 /* |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
762 %!error <Invalid call to strncmp.*> strncmp (); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
763 %!error <Invalid call to strncmp.*> strncmp ("abc", "def"); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
764 %!assert (strncmp ("abce", "abc", 3) == 1) |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
765 %!assert (strncmp (100, 100, 1) == 0) |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
766 %!assert (all (strncmp ("abce", {"abcd", "bca", "abc"}, 3) == [1, 0, 1])) |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
767 %!assert (all (strncmp ("abc", {"abcd", "bca", "abc"}, 4) == [0, 0, 0])) |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
768 %!assert (all (strncmp ({"abcd", "bca", "abc"},"abce", 3) == [1, 0, 1])) |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
769 %!assert (all (strncmp ({"abcd", "bca", "abc"},{"abcd", "bca", "abe"}, 3) == [1, 1, 0])) |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
770 */ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
771 |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
772 |
5690 | 773 DEFUN (list_in_columns, args, , |
774 "-*- texinfo -*-\n\ | |
775 @deftypefn {Built-in Function} {} list_in_columns (@var{arg}, @var{width})\n\ | |
776 Return a string containing the elements of @var{arg} listed in\n\ | |
777 columns with an overall maximum width of @var{width}. The argument\n\ | |
778 @var{arg} must be a cell array of character strings or a character array.\n\ | |
779 If @var{width} is not specified, the width of the terminal screen is used.\n\ | |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
780 Newline characters are used to break the lines in the output string.\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
781 For example:\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
782 \n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
783 @example\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
784 @group\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
785 list_in_columns (@{\"abc\", \"def\", \"ghijkl\", \"mnop\", \"qrs\", \"tuv\"@}, 20)\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
786 @result{} ans = abc mnop\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
787 def qrs\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
788 ghijkl tuv\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
789 \n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
790 whos ans\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
791 @result{}\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
792 Variables in the current scope:\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
793 \n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
794 Attr Name Size Bytes Class\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
795 ==== ==== ==== ===== =====\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
796 ans 1x37 37 char\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
797 \n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
798 Total is 37 elements using 37 bytes\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
799 @end group\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
800 @end example\n\ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
801 \n\ |
5690 | 802 @seealso{terminal_size}\n\ |
803 @end deftypefn") | |
804 { | |
805 octave_value retval; | |
806 | |
807 int nargin = args.length (); | |
808 | |
809 if (nargin == 1 || nargin == 2) | |
810 { | |
811 string_vector s = args(0).all_strings (); | |
812 | |
813 if (! error_state) | |
814 { | |
5765 | 815 std::ostringstream buf; |
5690 | 816 |
817 if (nargin == 1) | |
818 // Let list_in_columns query terminal width. | |
819 s.list_in_columns (buf); | |
820 else | |
821 { | |
822 int width = args(1).int_value (); | |
823 | |
824 if (! error_state) | |
825 s.list_in_columns (buf, width); | |
826 else | |
827 error ("list_in_columns: expecting width to be an integer"); | |
828 } | |
829 | |
5765 | 830 retval = buf.str (); |
5690 | 831 } |
832 else | |
833 error ("list_in_columns: expecting cellstr or char array"); | |
834 } | |
835 else | |
5823 | 836 print_usage (); |
5690 | 837 |
838 return retval; | |
839 } | |
840 | |
807 | 841 /* |
8461
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
842 %!error <Invalid call to list_in_columns.*> list_in_columns (); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
843 %!error <Invalid call to list_in_columns.*> list_in_columns (["abc", "def"], 20, 2); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
844 %!error <invalid conversion from string to real scalar.*> list_in_columns (["abc", "def"], "a"); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
845 %!test |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
846 %! input = {"abc", "def", "ghijkl", "mnop", "qrs", "tuv"}; |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
847 %! result = "abc mnop\ndef qrs\nghijkl tuv\n"; |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
848 %! assert (list_in_columns (input, 20) == result); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
849 %!test |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
850 %! input = ["abc"; "def"; "ghijkl"; "mnop"; "qrs"; "tuv"]; |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
851 %! result = "abc mnop \ndef qrs \nghijkl tuv \n"; |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
852 %! assert (list_in_columns (input, 20) == result); |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
853 */ |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
854 |
9d456730b7a8
strfns.cc: improve documentation strings, add examples and tests
Thorsten Meyer <thorsten.meyier@gmx.de>
parents:
8372
diff
changeset
|
855 /* |
807 | 856 ;;; Local Variables: *** |
857 ;;; mode: C++ *** | |
858 ;;; End: *** | |
859 */ |