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