]> git.mxchange.org Git - simgear.git/blob - simgear/misc/strutils.cxx
Better error reporting for effects
[simgear.git] / simgear / misc / strutils.cxx
1 // String utilities.
2 //
3 // Written by Bernie Bright, started 1998
4 //
5 // Copyright (C) 1998  Bernie Bright - bbright@bigpond.net.au
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #include <ctype.h>
24 #include <cstring>
25
26 #include "strutils.hxx"
27
28 namespace simgear {
29     namespace strutils {
30
31         /**
32          * 
33          */
34         static vector<string>
35         split_whitespace( const string& str, int maxsplit )
36         {
37             vector<string> result;
38             string::size_type len = str.length();
39             string::size_type i = 0;
40             string::size_type j;
41             int countsplit = 0;
42
43             while (i < len)
44             {
45                 while (i < len && isspace((unsigned char)str[i]))
46                 {
47                     ++i;
48                 }
49
50                 j = i;
51
52                 while (i < len && !isspace((unsigned char)str[i]))
53                 {
54                     ++i;
55                 }
56
57                 if (j < i)
58                 {
59                     result.push_back( str.substr(j, i-j) );
60                     ++countsplit;
61                     while (i < len && isspace((unsigned char)str[i]))
62                     {
63                         ++i;
64                     }
65
66                     if (maxsplit && (countsplit >= maxsplit) && i < len)
67                     {
68                         result.push_back( str.substr( i, len-i ) );
69                         i = len;
70                     }
71                 }
72             }
73
74             return result;
75         }
76
77         /**
78          * 
79          */
80         vector<string>
81         split( const string& str, const char* sep, int maxsplit )
82         {
83             if (sep == 0)
84                 return split_whitespace( str, maxsplit );
85
86             vector<string> result;
87             int n = std::strlen( sep );
88             if (n == 0)
89             {
90                 // Error: empty separator string
91                 return result;
92             }
93             const char* s = str.c_str();
94             string::size_type len = str.length();
95             string::size_type i = 0;
96             string::size_type j = 0;
97             int splitcount = 0;
98
99             while (i+n <= len)
100             {
101                 if (s[i] == sep[0] && (n == 1 || std::memcmp(s+i, sep, n) == 0))
102                 {
103                     result.push_back( str.substr(j,i-j) );
104                     i = j = i + n;
105                     ++splitcount;
106                     if (maxsplit && (splitcount >= maxsplit))
107                         break;
108                 }
109                 else
110                 {
111                     ++i;
112                 }
113             }
114
115             result.push_back( str.substr(j,len-j) );
116             return result;
117         }
118
119         /**
120          * The lstrip(), rstrip() and strip() functions are implemented
121          * in do_strip() which uses an additional parameter to indicate what
122          * type of strip should occur.
123          */
124         const int LEFTSTRIP = 0;
125         const int RIGHTSTRIP = 1;
126         const int BOTHSTRIP = 2;
127
128         static string
129         do_strip( const string& s, int striptype )
130         {
131             //     if (s.empty())
132             //      return s;
133
134             string::size_type len = s.length();
135             string::size_type i = 0;
136             if (striptype != RIGHTSTRIP)
137             {
138                 while (i < len && isspace(s[i]))
139                 {
140                     ++i;
141                 }
142             }
143
144             string::size_type j = len;
145             if (striptype != LEFTSTRIP)
146             {
147                 do
148                 {
149                     --j;
150                 }
151                 while (j >= 1 && isspace(s[j]));
152                 ++j;
153             }
154
155             if (i == 0 && j == len)
156             {
157                 return s;
158             }
159             else
160             {
161                 return s.substr( i, j - i );
162             }
163         }
164
165         string
166         lstrip( const string& s )
167         {
168             return do_strip( s, LEFTSTRIP );
169         }
170
171         string
172         rstrip( const string& s )
173         {
174             return do_strip( s, RIGHTSTRIP );
175         }
176
177         string
178         strip( const string& s )
179         {
180             return do_strip( s, BOTHSTRIP );
181         }
182
183     } // end namespace strutils
184 } // end namespace simgear