1 //
2 // C++ Implementation: gm_utils
3 //
4 // Description:
5 //
6 //
7 // Author: Lorenzo Bettini <http://www.lorenzobettini.it>, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #ifdef HAVE_CONFIG_H
14 #include "config.h"
15 #endif
16
17 #include <string.h>
18 #include <sstream>
19
20 #include "gm_utils.h"
21 #include "ggo_options.h"
22 #include "argsdef.h"
23 #include "groups.h"
24
25 using namespace std;
26
27 extern groups_collection_t gengetopt_groups;
28
29 char *
canonize_names(const char * name)30 canonize_names(const char *name) {
31 char *pvar;
32 char *p;
33
34 pvar = strdup(name);
35
36 for (p = pvar; *p; ++p)
37 if (*p == '.' || *p == '-' || *p == '/')
38 *p = '_';
39
40 return pvar;
41 }
42
43 // remove the path from the file name
strip_path(const string & s)44 const string strip_path(const string &s) {
45 string::size_type pos_of_sep;
46
47 pos_of_sep = s.rfind("/");
48 if (pos_of_sep == string::npos)
49 pos_of_sep = s.rfind("\\"); // try also with DOS path sep
50
51 if (pos_of_sep == string::npos)
52 return s; // no path
53
54 return s.substr(pos_of_sep + 1);
55 }
56
to_upper(const string & old)57 const string to_upper(const string &old) {
58 string upper = old;
59
60 for (string::iterator s = upper.begin(); s != upper.end(); ++s)
61 *s = toupper(*s);
62
63 return upper;
64 }
65
canonize_name(const string & old)66 const string canonize_name(const string &old) {
67 string canonized = old;
68
69 for (string::iterator s = canonized.begin(); s != canonized.end(); ++s)
70 if (*s == '.' || *s == '-' || *s == ' ' || *s == '/')
71 *s = '_';
72
73 return canonized;
74 }
75
canonize_enum(const string & old)76 const string canonize_enum(const string &old) {
77 string canonized;
78
79 for (string::const_iterator s = old.begin(); s != old.end(); ++s)
80 if (*s == '-')
81 canonized += "MINUS_";
82 else if (*s == '+')
83 canonized += "PLUS_";
84 else
85 canonized += *s;
86
87 return canonized;
88 }
89
has_multiple_options_all_string()90 bool has_multiple_options_all_string() {
91 if (!has_multiple_options())
92 return false;
93
94 struct gengetopt_option * opt = 0;
95
96 foropt {
97 if (opt->multiple && (opt->type && opt->type != ARG_STRING))
98 return false;
99 }
100
101 return true;
102 }
103
has_multiple_options_string()104 bool has_multiple_options_string() {
105 if (!has_multiple_options())
106 return false;
107
108 struct gengetopt_option * opt = 0;
109
110 foropt {
111 if (opt->multiple && opt->type == ARG_STRING)
112 return true;
113 }
114
115 return false;
116 }
117
has_multiple_options()118 bool has_multiple_options() {
119 struct gengetopt_option * opt = 0;
120
121 foropt {
122 if (opt->multiple)
123 return true;
124 }
125
126 return false;
127 }
128
has_multiple_options_with_type()129 bool has_multiple_options_with_type() {
130 gengetopt_option * opt = 0;
131
132 for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
133 != gengetopt_options.end() && (opt = *it); ++it)
134 if (opt->multiple && opt->type)
135 return true;
136
137 return false;
138 }
139
has_multiple_options_with_default()140 bool has_multiple_options_with_default() {
141 gengetopt_option * opt = 0;
142
143 for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
144 != gengetopt_options.end() && (opt = *it); ++it)
145 if (opt->multiple && opt->default_given)
146 return true;
147
148 return false;
149 }
150
has_options_with_details(bool strict_hidden)151 bool has_options_with_details(bool strict_hidden) {
152 gengetopt_option * opt = 0;
153
154 for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
155 != gengetopt_options.end() && (opt = *it); ++it)
156 if (opt->details && (!strict_hidden || !opt->hidden))
157 return true;
158
159 return false;
160 }
161
has_options_with_type()162 bool has_options_with_type() {
163 gengetopt_option * opt = 0;
164
165 for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
166 != gengetopt_options.end() && (opt = *it); ++it)
167 if (opt->type && opt->type != ARG_FLAG)
168 return true;
169
170 return false;
171 }
172
has_options_with_mode()173 bool has_options_with_mode() {
174 gengetopt_option * opt = 0;
175
176 for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
177 != gengetopt_options.end() && (opt = *it); ++it)
178 if (opt->mode_value)
179 return true;
180
181 return false;
182 }
183
has_required()184 bool has_required() {
185 struct gengetopt_option * opt = 0;
186
187 foropt {
188 if (opt->required)
189 return true;
190 }
191
192 groups_collection_t::const_iterator end = gengetopt_groups.end();
193 for (groups_collection_t::const_iterator idx = gengetopt_groups.begin(); idx
194 != end; ++idx) {
195 if (idx->second.required) {
196 return true;
197 }
198 }
199
200 return false;
201 }
202
has_dependencies()203 bool has_dependencies() {
204 struct gengetopt_option * opt = 0;
205
206 foropt {
207 if (opt->dependon)
208 return true;
209 }
210
211 return false;
212 }
213
has_options()214 bool has_options() {
215 struct gengetopt_option * opt = 0;
216
217 foropt {
218 if (opt->short_opt) {
219 if (opt->short_opt != 'h' && opt->short_opt != 'V')
220 return true;
221 }
222 }
223
224 return false;
225 }
226
has_hidden_options()227 bool has_hidden_options() {
228 struct gengetopt_option * opt = 0;
229
230 foropt {
231 if (opt->hidden) {
232 return true;
233 }
234 }
235
236 return false;
237 }
238
has_values()239 bool has_values() {
240 struct gengetopt_option * opt = 0;
241
242 for (gengetopt_option_list::iterator it = gengetopt_options.begin(); it
243 != gengetopt_options.end(); ++it) {
244 opt = *it;
245 if (opt->acceptedvalues) {
246 return true;
247 }
248 }
249
250 return false;
251 }
252
not_newlines(const string & buf,int & num_of_newlines)253 int not_newlines(const string &buf, int &num_of_newlines) {
254 num_of_newlines = 0;
255 // searches for the first non newline char
256 string::size_type notnewline = buf.find_first_not_of("\r\n");
257
258 if (notnewline == string::npos) {
259 // a string made only of newlines
260 num_of_newlines = buf.size();
261 return num_of_newlines;
262 }
263
264 if (notnewline) {
265 // everything before the non newline char is a newline
266 num_of_newlines = notnewline;
267 return notnewline;
268 }
269
270 return 0;
271 }
272
wrap_cstr(string & wrapped,unsigned int from_column,unsigned int second_indent,const string & orig)273 void wrap_cstr(string& wrapped, unsigned int from_column,
274 unsigned int second_indent, const string &orig) {
275 int next_space = from_column;
276 string next_word;
277 const char * out_buf = orig.c_str();
278 ostringstream stream;
279 const unsigned int second_line_column = from_column + second_indent;
280 string indent(second_line_column, ' ');
281 int newline_chars = 0;
282 int num_of_newlines = 0;
283
284 while (*out_buf) {
285 // check for a new line
286 if ((newline_chars = not_newlines(out_buf, num_of_newlines))) {
287 for (int i = 1; i <= num_of_newlines; ++i)
288 stream << "\\n";
289
290 out_buf += newline_chars;
291
292 if (*out_buf) {
293 stream << indent;
294 next_space = second_line_column;
295 continue;
296 } else
297 break;
298 }
299
300 // find next word (including any preceeding spaces)
301 bool had_word = false;
302 while ((*out_buf) && (*out_buf != ' ' || !had_word) &&
303 !not_newlines(out_buf, num_of_newlines)) {
304 had_word = *out_buf != ' ';
305 next_word += *out_buf++;
306 next_space++;
307 }
308
309 // wrap line if it's too long
310 if (next_space > 79) {
311 // trim leading spaces
312 std::size_t pos = next_word.find_first_not_of(' ');
313 if( pos == std::string::npos )
314 next_word.empty();
315 else if( pos )
316 next_word.erase( 0, pos );
317
318 stream << "\\n" << indent << next_word;
319 next_space = second_line_column + next_word.size();
320 } else
321 stream << next_word; // simply write word
322
323 next_word = "";
324 }
325
326 wrapped += stream.str();
327 }
328
is_numeric(const gengetopt_option * opt)329 bool is_numeric(const gengetopt_option *opt) {
330 switch (opt->type) {
331 case ARG_INT:
332 case ARG_SHORT:
333 case ARG_LONG:
334 case ARG_FLOAT:
335 case ARG_DOUBLE:
336 case ARG_LONGDOUBLE:
337 case ARG_LONGLONG:
338 return true;
339 default:
340 return false;
341 }
342 }
343
string_contains(const char * s,const char * tofind)344 bool string_contains(const char *s, const char *tofind) {
345 if (!s)
346 return false;
347
348 return (strstr(s, tofind) != 0);
349 }
350