str-vec.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 /*
00024 
00025 The function string_vector::list_in_columns was adapted from a similar
00026 function distributed in the GNU file utilities, copyright (C) 85, 88,
00027 90, 91, 95, 1996 Free Software Foundation, Inc.
00028 
00029 */
00030 
00031 #ifdef HAVE_CONFIG_H
00032 #include <config.h>
00033 #endif
00034 
00035 #include <iostream>
00036 #include <string>
00037 
00038 #include "cmd-edit.h"
00039 #include "lo-utils.h"
00040 #include "str-vec.h"
00041 
00042 // FIXME -- isn't there some STL trick that could be used to make this
00043 // work for all STL containers of std::string objects?
00044 
00045 string_vector::string_vector (const std::list<std::string>& lst)
00046   : Array<std::string> ()
00047 {
00048   size_t n = lst.size ();
00049 
00050   resize (n);
00051 
00052   octave_idx_type i = 0;
00053 
00054   for (std::list<std::string>::const_iterator p = lst.begin ();
00055        p != lst.end ();
00056        p++)
00057     elem(i++) = *p;
00058 }
00059 
00060 string_vector::string_vector (const std::set<std::string>& lst)
00061   : Array<std::string> ()
00062 {
00063   size_t n = lst.size ();
00064 
00065   resize (n);
00066 
00067   octave_idx_type i = 0;
00068 
00069   for (std::set<std::string>::const_iterator p = lst.begin ();
00070        p != lst.end ();
00071        p++)
00072     elem(i++) = *p;
00073 }
00074 
00075 // Create a string vector from a NULL terminated list of C strings.
00076 
00077 string_vector::string_vector (const char * const *s)
00078   : Array<std::string> ()
00079 {
00080   octave_idx_type n = 0;
00081 
00082   if (s)
00083     {
00084       const char * const *t = s;
00085 
00086       while (*t++)
00087         n++;
00088     }
00089 
00090   resize (n);
00091 
00092   for (octave_idx_type i = 0; i < n; i++)
00093     elem (i) = s[i];
00094 }
00095 
00096 // Create a string vector from up to N C strings.  Assumes that N is
00097 // nonnegative.
00098 
00099 string_vector::string_vector (const char * const *s, octave_idx_type n)
00100   : Array<std::string> (dim_vector (n, 1))
00101 {
00102   for (octave_idx_type i = 0; i < n; i++)
00103     elem (i) = s[i];
00104 }
00105 
00106 string_vector&
00107 string_vector::sort (bool make_uniq)
00108 {
00109   // Don't use Array<std::string>::sort () to allow sorting in place.
00110   octave_sort<std::string> lsort;
00111   lsort.sort (Array<std::string>::fortran_vec (), length ());
00112 
00113   if (make_uniq)
00114     uniq ();
00115 
00116   return *this;
00117 }
00118 string_vector&
00119 string_vector::uniq (void)
00120 {
00121   octave_idx_type len = length ();
00122 
00123   if (len > 0)
00124     {
00125       octave_idx_type k = 0;
00126 
00127       for (octave_idx_type i = 1; i < len; i++)
00128         if (elem(i) != elem(k))
00129           if (++k != i)
00130             elem(k) = elem(i);
00131 
00132       if (len != ++k)
00133         resize (k);
00134     }
00135 
00136   return *this;
00137 }
00138 
00139 string_vector&
00140 string_vector::append (const std::string& s)
00141 {
00142   octave_idx_type len = length ();
00143 
00144   resize (len + 1);
00145 
00146   elem(len) = s;
00147 
00148   return *this;
00149 }
00150 
00151 string_vector&
00152 string_vector::append (const string_vector& sv)
00153 {
00154   octave_idx_type len = length ();
00155   octave_idx_type sv_len = sv.length ();
00156   octave_idx_type new_len = len + sv_len;
00157 
00158   resize (new_len);
00159 
00160   for (octave_idx_type i = 0; i < sv_len; i++)
00161     elem(len + i) = sv[i];
00162 
00163   return *this;
00164 }
00165 
00166 std::string
00167 string_vector::join (const std::string& sep) const
00168 {
00169   std::string retval;
00170 
00171   octave_idx_type len = length ();
00172 
00173   if (len > 0)
00174     {
00175       octave_idx_type i;
00176 
00177       for (i = 0; i < len - 1; i++)
00178         retval += elem(i) + sep;
00179 
00180       retval += elem(i);
00181     }
00182 
00183   return retval;
00184 }
00185 
00186 char **
00187 string_vector::c_str_vec (void) const
00188 {
00189   octave_idx_type len = length ();
00190 
00191   char **retval = new char * [len + 1];
00192 
00193   retval [len] = 0;
00194 
00195   for (octave_idx_type i = 0; i < len; i++)
00196     retval[i] = strsave (elem(i).c_str ());
00197 
00198   return retval;
00199 }
00200 
00201 void
00202 string_vector::delete_c_str_vec (const char * const *v)
00203 {
00204   const char * const *p = v;
00205 
00206   while (*p)
00207     delete [] *p++;
00208 
00209   delete [] v;
00210 }
00211 
00212 // Format a list in neat columns.
00213 
00214 std::ostream&
00215 string_vector::list_in_columns (std::ostream& os, int width) const
00216 {
00217   // Compute the maximum name length.
00218 
00219   octave_idx_type max_name_length = 0;
00220   octave_idx_type total_names = length ();
00221 
00222   if (total_names == 0)
00223     {
00224       // List empty, remember to end output with a newline.
00225 
00226       os << "\n";
00227       return os;
00228     }
00229 
00230   for (octave_idx_type i = 0; i < total_names; i++)
00231     {
00232       octave_idx_type name_length = elem (i).length ();
00233       if (name_length > max_name_length)
00234         max_name_length = name_length;
00235     }
00236 
00237   // Allow at least two spaces between names.
00238 
00239   max_name_length += 2;
00240 
00241   // Calculate the maximum number of columns that will fit.
00242 
00243   octave_idx_type line_length
00244     = (width <= 0) ? command_editor::terminal_cols () : width;
00245 
00246   octave_idx_type nc = line_length / max_name_length;
00247   if (nc == 0)
00248     nc = 1;
00249 
00250   // Calculate the number of rows that will be in each column except
00251   // possibly  for a short column on the right.
00252 
00253   octave_idx_type nr = total_names / nc + (total_names % nc != 0);
00254 
00255   // Recalculate columns based on rows.
00256 
00257   nc = total_names / nr + (total_names % nr != 0);
00258 
00259   octave_idx_type count;
00260   for (octave_idx_type row = 0; row < nr; row++)
00261     {
00262       count = row;
00263       octave_idx_type pos = 0;
00264 
00265       // Print the next row.
00266 
00267       while (1)
00268         {
00269           std::string nm = elem (count);
00270 
00271           os << nm;
00272           octave_idx_type name_length = nm.length ();
00273 
00274           count += nr;
00275           if (count >= total_names)
00276             break;
00277 
00278           octave_idx_type spaces_to_pad = max_name_length - name_length;
00279           for (octave_idx_type i = 0; i < spaces_to_pad; i++)
00280             os << " ";
00281           pos += max_name_length;
00282         }
00283       os << "\n";
00284     }
00285 
00286   return os;
00287 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines