GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
str-vec.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 /*
24 
25 The function string_vector::list_in_columns was adapted from a similar
26 function distributed in the GNU file utilities, copyright (C) 85, 88,
27 90, 91, 95, 1996 Free Software Foundation, Inc.
28 
29 */
30 
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34 
35 #include <iostream>
36 #include <string>
37 
38 #include "cmd-edit.h"
39 #include "lo-utils.h"
40 #include "str-vec.h"
41 
42 // FIXME: isn't there some STL trick that could be used to make this
43 // work for all STL containers of std::string objects?
44 
45 string_vector::string_vector (const std::list<std::string>& lst)
46  : Array<std::string> ()
47 {
48  size_t n = lst.size ();
49 
50  resize (n);
51 
52  octave_idx_type i = 0;
53 
54  for (std::list<std::string>::const_iterator p = lst.begin ();
55  p != lst.end ();
56  p++)
57  elem (i++) = *p;
58 }
59 
60 string_vector::string_vector (const std::set<std::string>& lst)
61  : Array<std::string> ()
62 {
63  size_t n = lst.size ();
64 
65  resize (n);
66 
67  octave_idx_type i = 0;
68 
69  for (std::set<std::string>::const_iterator p = lst.begin ();
70  p != lst.end ();
71  p++)
72  elem (i++) = *p;
73 }
74 
75 // Create a string vector from a NULL terminated list of C strings.
76 
77 string_vector::string_vector (const char * const *s)
78  : Array<std::string> ()
79 {
80  octave_idx_type n = 0;
81 
82  if (s)
83  {
84  const char * const *t = s;
85 
86  while (*t++)
87  n++;
88  }
89 
90  resize (n);
91 
92  for (octave_idx_type i = 0; i < n; i++)
93  elem (i) = s[i];
94 }
95 
96 // Create a string vector from up to N C strings. Assumes that N is
97 // nonnegative.
98 
100  : Array<std::string> (dim_vector (n, 1))
101 {
102  for (octave_idx_type i = 0; i < n; i++)
103  elem (i) = s[i];
104 }
105 
107 string_vector::sort (bool make_uniq)
108 {
109  // Don't use Array<std::string>::sort () to allow sorting in place.
112 
113  if (make_uniq)
114  uniq ();
115 
116  return *this;
117 }
120 {
121  octave_idx_type len = length ();
122 
123  if (len > 0)
124  {
125  octave_idx_type k = 0;
126 
127  for (octave_idx_type i = 1; i < len; i++)
128  if (elem (i) != elem (k))
129  if (++k != i)
130  elem (k) = elem (i);
131 
132  if (len != ++k)
133  resize (k);
134  }
135 
136  return *this;
137 }
138 
140 string_vector::append (const std::string& s)
141 {
142  octave_idx_type len = length ();
143 
144  resize (len + 1);
145 
146  elem (len) = s;
147 
148  return *this;
149 }
150 
153 {
154  octave_idx_type len = length ();
155  octave_idx_type sv_len = sv.length ();
156  octave_idx_type new_len = len + sv_len;
157 
158  resize (new_len);
159 
160  for (octave_idx_type i = 0; i < sv_len; i++)
161  elem (len + i) = sv[i];
162 
163  return *this;
164 }
165 
166 std::string
167 string_vector::join (const std::string& sep) const
168 {
169  std::string retval;
170 
171  octave_idx_type len = length ();
172 
173  if (len > 0)
174  {
175  octave_idx_type i;
176 
177  for (i = 0; i < len - 1; i++)
178  retval += elem (i) + sep;
179 
180  retval += elem (i);
181  }
182 
183  return retval;
184 }
185 
186 char **
188 {
189  octave_idx_type len = length ();
190 
191  char **retval = new char * [len + 1];
192 
193  retval[len] = 0;
194 
195  for (octave_idx_type i = 0; i < len; i++)
196  retval[i] = strsave (elem (i).c_str ());
197 
198  return retval;
199 }
200 
201 void
202 string_vector::delete_c_str_vec (const char * const *v)
203 {
204  const char * const *p = v;
205 
206  while (*p)
207  delete [] *p++;
208 
209  delete [] v;
210 }
211 
212 // Format a list in neat columns.
213 
214 std::ostream&
215 string_vector::list_in_columns (std::ostream& os, int width,
216  const std::string& prefix) const
217 {
218  // Compute the maximum name length.
219 
220  octave_idx_type max_name_length = 0;
221  octave_idx_type total_names = length ();
222 
223  if (total_names == 0)
224  {
225  // List empty, remember to end output with a newline.
226 
227  os << "\n";
228  return os;
229  }
230 
231  for (octave_idx_type i = 0; i < total_names; i++)
232  {
233  octave_idx_type name_length = elem (i).length ();
234  if (name_length > max_name_length)
235  max_name_length = name_length;
236  }
237 
238  // Allow at least two spaces between names.
239 
240  max_name_length += 2;
241 
242  // Calculate the maximum number of columns that will fit.
243 
244  octave_idx_type line_length
245  = ((width <= 0 ? command_editor::terminal_cols () : width)
246  - prefix.length ());
247 
248  octave_idx_type nc = line_length / max_name_length;
249  if (nc == 0)
250  nc = 1;
251 
252  // Calculate the number of rows that will be in each column except
253  // possibly for a short column on the right.
254 
255  octave_idx_type nr = total_names / nc + (total_names % nc != 0);
256 
257  // Recalculate columns based on rows.
258 
259  nc = total_names / nr + (total_names % nr != 0);
260 
261  octave_idx_type count;
262  for (octave_idx_type row = 0; row < nr; row++)
263  {
264  count = row;
265  octave_idx_type pos = 0;
266 
267  // Print the next row.
268 
269  os << prefix;
270 
271  while (1)
272  {
273  std::string nm = elem (count);
274 
275  os << nm;
276  octave_idx_type name_length = nm.length ();
277 
278  count += nr;
279  if (count >= total_names)
280  break;
281 
282  octave_idx_type spaces_to_pad = max_name_length - name_length;
283  for (octave_idx_type i = 0; i < spaces_to_pad; i++)
284  os << " ";
285  pos += max_name_length;
286  }
287  os << "\n";
288  }
289 
290  return os;
291 }