Mercurial > hg > octave-lyh
annotate src/strfns.cc @ 8372:8dff9cba15fe
move str2mat to deprecated and make it a simple wrapper around char
author | Thorsten Meyer <thorsten.meyier@gmx.de> |
---|---|
date | Thu, 04 Dec 2008 22:16:52 +0100 |
parents | 349a555729a9 |
children | 9d456730b7a8 |
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\ | |
48 Create a string array from a numeric matrix, cell array, or list of\n\ | |
49 \n\ | |
50 If the argument is a numeric matrix, each element of the matrix is\n\ | |
51 converted to the corresponding ASCII character. For example,\n\ | |
52 \n\ | |
53 @example\n\ | |
54 @group\n\ | |
4734 | 55 char ([97, 98, 99])\n\ |
4358 | 56 @result{} \"abc\"\n\ |
57 @end group\n\ | |
58 @end example\n\ | |
59 \n\ | |
60 If the argument is a cell array of strings, the result is a string array\n\ | |
61 with each element corresponding to one element of the cell array.\n\ | |
62 \n\ | |
63 For multiple string arguments, the result is a string array with each\n\ | |
64 element corresponding to the arguments.\n\ | |
65 \n\ | |
66 The returned values are padded with blanks as needed to make each row\n\ | |
67 of the string array have the same length.\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\ |
3361 | 159 Return 1 if @var{a} is a string. Otherwise, return 0.\n\ |
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 | |
5415 | 174 DEFUN (strcmp, args, , |
175 "-*- texinfo -*-\n\ | |
6678 | 176 @deftypefn {Built-in Function} {} strcmp (@var{s1}, @var{s2})\n\ |
5415 | 177 Return 1 if the character strings @var{s1} and @var{s2} are the same,\n\ |
178 and 0 otherwise.\n\ | |
5674 | 179 \n\ |
180 If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\ | |
181 of the same size is returned, containing the values described above for\n\ | |
182 every member of the cell array. The other argument may also be a cell\n\ | |
183 array of strings (of the same size or with only one element), char matrix\n\ | |
184 or character string.\n\ | |
185 \n\ | |
186 @strong{Caution:} For compatibility with @sc{Matlab}, Octave's strcmp\n\ | |
187 function returns 1 if the character strings are equal, and 0 otherwise.\n\ | |
188 This is just the opposite of the corresponding C library function.\n\ | |
189 @seealso{strcmpi, strncmp, strncmpi}\n\ | |
5415 | 190 @end deftypefn") |
191 { | |
5531 | 192 octave_value retval; |
5415 | 193 |
5416 | 194 if (args.length () == 2) |
195 { | |
196 bool s1_string = args(0).is_string (); | |
197 bool s1_cell = args(0).is_cell (); | |
198 bool s2_string = args(1).is_string (); | |
199 bool s2_cell = args(1).is_cell (); | |
5415 | 200 |
5416 | 201 if (s1_string && s2_string) |
202 { | |
203 // Must match exactly in all dimensions. | |
204 | |
205 const dim_vector dv1 = args(0).dims (); | |
206 const dim_vector dv2 = args(1).dims (); | |
5415 | 207 |
5416 | 208 if (dv1.length () == dv2.length ()) |
209 { | |
210 for (int i = 0; i < dv1.length (); i++) | |
211 { | |
212 if (dv1(i) != dv2(i)) | |
213 { | |
214 retval = false; | |
215 return retval; | |
216 } | |
217 } | |
5415 | 218 |
5416 | 219 if (dv1(0) == 0) |
220 retval = true; | |
221 else | |
222 { | |
223 charNDArray s1 = args(0).char_array_value (); | |
224 charNDArray s2 = args(1).char_array_value (); | |
5415 | 225 |
5416 | 226 for (int i = 0; i < dv1.numel (); i++) |
227 { | |
228 if (s1(i) != s2(i)) | |
229 { | |
230 retval = false; | |
231 return retval; | |
232 } | |
233 } | |
5415 | 234 |
5416 | 235 retval = true; |
236 } | |
5415 | 237 } |
238 } | |
5416 | 239 else if ((s1_string && s2_cell) || (s1_cell && s2_string)) |
5415 | 240 { |
5416 | 241 string_vector str; |
242 Cell cell; | |
243 int r; | |
5415 | 244 |
5416 | 245 if (s1_string) |
246 { | |
247 str = args(0).all_strings (); | |
248 r = args(0).rows (); | |
249 cell = args(1).cell_value (); | |
250 } | |
251 else | |
252 { | |
253 str = args(1).all_strings (); | |
254 r = args(1).rows (); | |
255 cell = args(0).cell_value (); | |
256 } | |
257 | |
5862 | 258 if (r == 0 || r == 1) |
5416 | 259 { |
260 // Broadcast the string. | |
261 | |
262 boolNDArray output (cell.dimensions); | |
5415 | 263 |
5862 | 264 std::string s = r == 0 ? std::string () : str[0]; |
265 | |
5416 | 266 for (int i = 0; i < cell.length (); i++) |
6250 | 267 { |
268 if (cell(i).is_string ()) | |
269 output(i) = (cell(i).string_value () == s); | |
270 else | |
271 output(i) = false; | |
272 } | |
5416 | 273 |
274 retval = output; | |
275 } | |
276 else if (r > 1) | |
5415 | 277 { |
5416 | 278 if (cell.length () == 1) |
5415 | 279 { |
5416 | 280 // Broadcast the cell. |
281 | |
282 const dim_vector dv (r, 1); | |
283 boolNDArray output (dv); | |
284 | |
285 if (cell(0).is_string ()) | |
286 { | |
287 const std::string str2 = cell(0).string_value (); | |
5415 | 288 |
5416 | 289 for (int i = 0; i < r; i++) |
290 output(i) = (str[i] == str2); | |
291 } | |
292 else | |
293 { | |
294 for (int i = 0; i < r; i++) | |
295 output(i) = false; | |
296 } | |
297 | |
298 retval = output; | |
5415 | 299 } |
300 else | |
301 { | |
5416 | 302 // Must match in all dimensions. |
303 | |
304 boolNDArray output (cell.dimensions); | |
5415 | 305 |
5416 | 306 if (cell.length () == r) |
307 { | |
308 for (int i = 0; i < r; i++) | |
6250 | 309 { |
310 if (cell(i).is_string ()) | |
311 output(i) = (str[i] == cell(i).string_value ()); | |
312 else | |
313 output(i) = false; | |
314 } | |
5415 | 315 |
5416 | 316 retval = output; |
317 } | |
318 else | |
319 retval = false; | |
5415 | 320 } |
321 } | |
322 } | |
5416 | 323 else if (s1_cell && s2_cell) |
5415 | 324 { |
5416 | 325 Cell cell1; |
326 Cell cell2; | |
5415 | 327 |
5416 | 328 int r1 = args(0).numel (); |
329 int r2; | |
330 | |
331 if (r1 == 1) | |
332 { | |
333 // Make the singleton cell2. | |
5415 | 334 |
5416 | 335 cell1 = args(1).cell_value (); |
336 cell2 = args(0).cell_value (); | |
337 r1 = cell1.length (); | |
338 r2 = 1; | |
339 } | |
340 else | |
341 { | |
342 cell1 = args(0).cell_value (); | |
343 cell2 = args(1).cell_value (); | |
344 r2 = cell2.length (); | |
345 } | |
5415 | 346 |
5416 | 347 const dim_vector size1 = cell1.dimensions; |
348 const dim_vector size2 = cell2.dimensions; | |
349 | |
350 boolNDArray output (size1); | |
351 | |
352 if (r2 == 1) | |
353 { | |
354 // Broadcast cell2. | |
355 | |
356 if (! cell2(0).is_string ()) | |
5415 | 357 { |
5416 | 358 for (int i = 0; i < r1; i++) |
359 output(i) = false; | |
5415 | 360 } |
361 else | |
5416 | 362 { |
363 const std::string str2 = cell2(0).string_value (); | |
364 | |
365 for (int i = 0; i < r1; i++) | |
366 { | |
367 if (cell1(i).is_string ()) | |
368 { | |
369 const std::string str1 = cell1(i).string_value (); | |
370 output(i) = (str1 == str2); | |
371 } | |
372 else | |
373 output(i) = false; | |
374 } | |
375 } | |
5415 | 376 } |
5416 | 377 else |
378 { | |
379 if (size1 != size2) | |
380 { | |
381 error ("strcmp: nonconformant cell arrays"); | |
382 return retval; | |
383 } | |
384 | |
385 for (int i = 0; i < r1; i++) | |
386 { | |
387 if (cell1(i).is_string () && cell2(i).is_string ()) | |
388 { | |
389 const std::string str1 = cell1(i).string_value (); | |
390 const std::string str2 = cell2(i).string_value (); | |
391 output(i) = (str1 == str2); | |
392 } | |
393 else | |
394 output(i) = false; | |
395 } | |
396 } | |
397 | |
398 retval = output; | |
5415 | 399 } |
5531 | 400 else |
401 retval = false; | |
5415 | 402 } |
5416 | 403 else |
5823 | 404 print_usage (); |
5415 | 405 |
406 return retval; | |
407 } | |
408 | |
5862 | 409 /* |
410 %!shared x | |
411 %! x = char (zeros (0, 2)); | |
412 %!assert (strcmp ('', x) == false); | |
413 %!assert (strcmp (x, '') == false); | |
414 %!assert (strcmp (x, x) == true); | |
5911 | 415 ## %!assert (strcmp ({''}, x) == false); |
416 ## %!assert (strcmp ({x}, '') == false); | |
417 ## %!assert (strcmp ({x}, x) == true); | |
418 ## %!assert (strcmp ('', {x}) == false); | |
419 ## %!assert (strcmp (x, {''}) == false); | |
420 ## %!assert (strcmp (x, {x}) == true); | |
421 ## %!assert (all (strcmp ({x; x}, '') == [false; false])); | |
422 ## %!assert (all (strcmp ({x; x}, {''}) == [false; false])); | |
423 ## %!assert (all (strcmp ('', {x; x}) == [false; false])); | |
424 ## %!assert (all (strcmp ({''}, {x; x}) == [false; false])); | |
5862 | 425 %!assert (strcmp ({'foo'}, x) == false); |
426 %!assert (strcmp ({'foo'}, 'foo') == true); | |
427 %!assert (strcmp ({'foo'}, x) == false); | |
428 %!assert (strcmp (x, {'foo'}) == false); | |
429 %!assert (strcmp ('foo', {'foo'}) == true); | |
430 %!assert (strcmp (x, {'foo'}) == false); | |
431 %!shared y | |
432 %! y = char (zeros (2, 0)); | |
433 %!assert (strcmp ('', y) == false); | |
434 %!assert (strcmp (y, '') == false); | |
435 %!assert (strcmp (y, y) == true); | |
436 %!assert (all (strcmp ({''}, y) == [true; true])); | |
437 %!assert (strcmp ({y}, '') == true); | |
438 %!assert (all (strcmp ({y}, y) == [true; true])); | |
439 %!assert (all (strcmp ('', {y}) == [true; true])); | |
440 %!assert (all (strcmp (y, {''}) == [true; true])); | |
441 %!assert (all (strcmp (y, {y}) == [true; true])); | |
5911 | 442 ## %!assert (all (strcmp ({y; y}, '') == [false; false])); |
443 ## %!assert (all (strcmp ({y; y}, {''}) == [false; false])); | |
444 ## %!assert (all (strcmp ('', {y; y}) == [false; false])); | |
445 ## %!assert (all (strcmp ({''}, {y; y}) == [false; false])); | |
5862 | 446 %!assert (all (strcmp ({'foo'}, y) == [false; false])); |
447 %!assert (all (strcmp ({'foo'}, y) == [false; false])); | |
448 %!assert (all (strcmp (y, {'foo'}) == [false; false])); | |
449 %!assert (all (strcmp (y, {'foo'}) == [false; false])); | |
450 */ | |
451 | |
6250 | 452 DEFUN (strncmp, args, , |
453 "-*- texinfo -*-\n\ | |
6678 | 454 @deftypefn {Built-in Function} {} strncmp (@var{s1}, @var{s2}, @var{n})\n\ |
6250 | 455 Return 1 if the first @var{n} characters of strings @var{s1} and @var{s2} are the same,\n\ |
456 and 0 otherwise.\n\ | |
457 \n\ | |
458 @example\n\ | |
459 @group\n\ | |
460 strncmp (\"abce\", \"abcd\", 3)\n\ | |
461 @result{} 1\n\ | |
462 @end group\n\ | |
463 @end example\n\ | |
464 \n\ | |
465 If either @var{s1} or @var{s2} is a cell array of strings, then an array\n\ | |
466 of the same size is returned, containing the values described above for\n\ | |
467 every member of the cell array. The other argument may also be a cell\n\ | |
468 array of strings (of the same size or with only one element), char matrix\n\ | |
469 or character string.\n\ | |
470 \n\ | |
471 @example\n\ | |
472 @group\n\ | |
6256 | 473 strncmp (\"abce\", @{\"abcd\", \"bca\", \"abc\"@}, 3)\n\ |
6250 | 474 @result{} [1, 0, 1]\n\ |
475 @end group\n\ | |
476 @end example\n\ | |
477 \n\ | |
478 @strong{Caution:} For compatibility with @sc{Matlab}, Octave's strncmp\n\ | |
479 function returns 1 if the character strings are equal, and 0 otherwise.\n\ | |
480 This is just the opposite of the corresponding C library function.\n\ | |
481 @seealso{strncmpi, strcmp, strcmpi}\n\ | |
482 @end deftypefn") | |
483 { | |
484 octave_value retval; | |
485 | |
486 if (args.length () == 3) | |
487 { | |
488 bool s1_string = args(0).is_string (); | |
489 bool s1_cell = args(0).is_cell (); | |
490 bool s2_string = args(1).is_string (); | |
491 bool s2_cell = args(1).is_cell (); | |
492 | |
493 // Match only first n strings. | |
494 int n = args(2).int_value (); | |
495 | |
496 if (n <= 0) | |
497 { | |
498 error ("strncmp: N must be greater than 0"); | |
499 return retval; | |
500 } | |
501 | |
502 if (s1_string && s2_string) | |
503 { | |
504 // The only restriction here is that each string has equal or | |
505 // greater than n characters | |
506 | |
507 const dim_vector dv1 = args(0).dims (); | |
508 const dim_vector dv2 = args(1).dims (); | |
509 | |
510 if (dv1.numel () >= n && dv2.numel () >= n) | |
511 { | |
512 // Follow Matlab in the sense that the first n characters of | |
513 // the two strings (in column major order) need to be the same. | |
514 charNDArray s1 = args(0).char_array_value (); | |
515 charNDArray s2 = args(1).char_array_value (); | |
516 | |
517 for (int i = 0; i < n; i++) | |
518 { | |
519 if (s1(i) != s2(i)) | |
520 { | |
521 retval = false; | |
522 return retval; | |
523 } | |
524 } | |
525 | |
526 retval = true; | |
527 } | |
528 else | |
529 retval = false; | |
530 } | |
531 else if ((s1_string && s2_cell) || (s1_cell && s2_string)) | |
532 { | |
533 string_vector str; | |
534 Cell cell; | |
535 int r, c; | |
536 | |
537 if (s1_string) | |
538 { | |
539 str = args(0).all_strings (); | |
540 r = args(0).rows (); | |
541 c = args(0).columns (); | |
542 cell = args(1).cell_value (); | |
543 } | |
544 else | |
545 { | |
546 str = args(1).all_strings (); | |
547 r = args(1).rows (); | |
548 c = args(1).columns (); | |
549 cell = args(0).cell_value (); | |
550 } | |
551 | |
552 if (r == 1) | |
553 { | |
554 // Broadcast the string. | |
555 | |
556 boolNDArray output (cell.dimensions); | |
557 | |
558 if (c < n) | |
559 { | |
560 for (int i = 0; i < cell.length (); i++) | |
561 output(i) = false; | |
562 } | |
563 else | |
564 { | |
565 for (int i = 0; i < cell.length (); i++) | |
566 { | |
567 if (cell(i).is_string ()) | |
568 { | |
569 const std::string str2 = cell(i).string_value (); | |
570 | |
571 if (str2.length() >= n) | |
572 { | |
573 if (str2.compare (0, n, str[0], 0, n) == 0) | |
574 output(i) = true; | |
575 else | |
576 output(i) = false; | |
577 } | |
578 else | |
579 output(i) = false; | |
580 } | |
581 } | |
582 } | |
583 | |
584 retval = output; | |
585 } | |
586 else if (r > 1) | |
587 { | |
588 if (cell.length () == 1) | |
589 { | |
590 // Broadcast the cell. | |
591 | |
592 const dim_vector dv (r, 1); | |
593 boolNDArray output (dv); | |
594 | |
595 if (cell(0).is_string () && c >= n) | |
596 { | |
597 const std::string str2 = cell(0).string_value (); | |
598 | |
599 if (str2.length () >= n) | |
600 { | |
601 for (int i = 0; i < r; i++) | |
602 { | |
603 if (str[i].compare (0, n, str2, 0, n) == 0) | |
604 output(i) = true; | |
605 else | |
606 output(i) = false; | |
607 } | |
608 } | |
609 else | |
610 { | |
611 for (int i = 0; i < r; i++) | |
612 output(i) = false; | |
613 } | |
614 } | |
615 else | |
616 { | |
617 for (int i = 0; i < r; i++) | |
618 output(i) = false; | |
619 } | |
620 | |
621 retval = output; | |
622 } | |
623 else | |
624 { | |
625 // Must match in all dimensions. | |
626 | |
627 boolNDArray output (cell.dimensions); | |
628 | |
629 if (cell.numel () == r) | |
630 { | |
631 for (int i = 0; i < r; i++) | |
632 { | |
633 output(i) = false; | |
634 | |
635 if (cell(i).is_string () && c >= n) | |
636 { | |
637 std::string str2 = cell(i).string_value (); | |
638 | |
639 if (str2.length () >= n | |
640 && str2.compare (0, n, str[i], 0, n) == 0) | |
641 output(i) = true; | |
642 } | |
643 } | |
644 | |
645 retval = output; | |
646 } | |
647 else | |
648 { | |
649 error ("strncmp: the number of rows of the string matrix must match the number of elements in the cell"); | |
650 return retval; | |
651 } | |
652 } | |
653 } | |
654 } | |
655 else if (s1_cell && s2_cell) | |
656 { | |
657 Cell cell1; | |
658 Cell cell2; | |
659 | |
660 int r1 = args(0).numel (); | |
661 int r2; | |
662 | |
663 if (r1 == 1) | |
664 { | |
665 // Make the singleton cell2. | |
666 | |
667 cell1 = args(1).cell_value (); | |
668 cell2 = args(0).cell_value (); | |
669 r1 = cell1.length (); | |
670 r2 = 1; | |
671 } | |
672 else | |
673 { | |
674 cell1 = args(0).cell_value (); | |
675 cell2 = args(1).cell_value (); | |
676 r2 = cell2.length (); | |
677 } | |
678 | |
679 const dim_vector size1 = cell1.dimensions; | |
680 const dim_vector size2 = cell2.dimensions; | |
681 | |
682 boolNDArray output (size1); | |
683 | |
684 if (r2 == 1) | |
685 { | |
686 // Broadcast cell2. | |
687 | |
688 if (! cell2(0).is_string ()) | |
689 { | |
690 for (int i = 0; i < r1; i++) | |
691 output(i) = false; | |
692 } | |
693 else | |
694 { | |
695 const std::string str2 = cell2(0).string_value (); | |
696 | |
697 for (int i = 0; i < r1; i++) | |
698 { | |
699 if (cell1(i).is_string ()) | |
700 { | |
701 const std::string str1 = cell1(i).string_value (); | |
702 | |
703 if (str1.length () >= n && str2.length () >= n | |
704 && str1.compare (0, n, str2, 0, n) == 0) | |
705 output(i) = true; | |
706 else | |
707 output(i) = false; | |
708 } | |
709 else | |
710 output(i) = false; | |
711 } | |
712 } | |
713 } | |
714 else | |
715 { | |
716 if (size1 != size2) | |
717 { | |
718 error ("strncmp: nonconformant cell arrays"); | |
719 return retval; | |
720 } | |
721 | |
722 for (int i = 0; i < r1; i++) | |
723 { | |
724 if (cell1(i).is_string () && cell2(i).is_string ()) | |
725 { | |
726 const std::string str1 = cell1(i).string_value (); | |
727 const std::string str2 = cell2(i).string_value (); | |
728 | |
729 if (str1.length () >= n && str2.length () >= n | |
730 && str1.compare (0, n, str2, 0, n) == 0) | |
731 output(i) = true; | |
732 else | |
733 output(i) = false; | |
734 } | |
735 else | |
736 output(i) = false; | |
737 } | |
738 } | |
739 | |
740 retval = output; | |
741 } | |
742 else | |
743 retval = false; | |
744 } | |
745 else | |
746 print_usage (); | |
747 | |
748 return retval; | |
749 } | |
750 | |
5690 | 751 DEFUN (list_in_columns, args, , |
752 "-*- texinfo -*-\n\ | |
753 @deftypefn {Built-in Function} {} list_in_columns (@var{arg}, @var{width})\n\ | |
754 Return a string containing the elements of @var{arg} listed in\n\ | |
755 columns with an overall maximum width of @var{width}. The argument\n\ | |
756 @var{arg} must be a cell array of character strings or a character array.\n\ | |
757 If @var{width} is not specified, the width of the terminal screen is used.\n\ | |
758 @seealso{terminal_size}\n\ | |
759 @end deftypefn") | |
760 { | |
761 octave_value retval; | |
762 | |
763 int nargin = args.length (); | |
764 | |
765 if (nargin == 1 || nargin == 2) | |
766 { | |
767 string_vector s = args(0).all_strings (); | |
768 | |
769 if (! error_state) | |
770 { | |
5765 | 771 std::ostringstream buf; |
5690 | 772 |
773 if (nargin == 1) | |
774 // Let list_in_columns query terminal width. | |
775 s.list_in_columns (buf); | |
776 else | |
777 { | |
778 int width = args(1).int_value (); | |
779 | |
780 if (! error_state) | |
781 s.list_in_columns (buf, width); | |
782 else | |
783 error ("list_in_columns: expecting width to be an integer"); | |
784 } | |
785 | |
5765 | 786 retval = buf.str (); |
5690 | 787 } |
788 else | |
789 error ("list_in_columns: expecting cellstr or char array"); | |
790 } | |
791 else | |
5823 | 792 print_usage (); |
5690 | 793 |
794 return retval; | |
795 } | |
796 | |
807 | 797 /* |
798 ;;; Local Variables: *** | |
799 ;;; mode: C++ *** | |
800 ;;; End: *** | |
801 */ |