1 /*
2
3 This file is from Nitrogen, an X11 background setter.
4 Copyright (C) 2006 Dave Foster & Javeed Shaikh
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 */
21
22 #include "ArgParser.h"
23 #include "gcs-i18n.h"
24
parse(int argc,char ** argv)25 bool ArgParser::parse
26 (int argc, char ** argv) {
27 std::vector<Glib::ustring> argVec;
28 for (int i = 0; i < argc; i++) {
29 argVec.push_back(Glib::ustring(argv[i]));
30 }
31
32 return this->parse(argVec);
33 }
34
parse(std::vector<Glib::ustring> argVec)35 bool ArgParser::parse
36 (std::vector<Glib::ustring> argVec) {
37 bool retval = true;
38
39 for (std::vector<Glib::ustring>::const_iterator i = argVec.begin() + 1; i != argVec.end(); i++) {
40 std::string arg(*i);
41 std::string key = arg;
42 std::string value;
43
44 if (key == "-h" || key == "--help") {
45 received_args["help"];
46 continue;
47 }
48
49 std::string::size_type minuspos;
50 if ((minuspos = key.find ("--")) == std::string::npos) {
51 // this is not an arg, append it
52 // to the extra string
53 if (extra_arg_str.length ()) {
54 // it has stuff, we need to add blank space
55 extra_arg_str += " ";
56 }
57 extra_arg_str += key;
58 continue;
59 }
60
61 key = std::string (key, minuspos + 2);
62
63 std::string::size_type pos = key.find ('=');
64 if (pos != std::string::npos) {
65 key.erase (pos);
66 value = std::string (arg, pos + 3);
67 }
68
69 std::map<std::string, Arg>::const_iterator iter;
70 Arg current;
71
72 if ((iter = expected_args.find (key)) == expected_args.end ()) {
73 // ignore this argument and set the error string
74 retval = false;
75 error_str += _("Unexpected argument ") + key + "\n";
76 continue;
77 } else {
78 current = iter->second;
79 }
80
81 if (current.get_has_arg () && !value.length ()) {
82 // this expects an arg, but has received none.
83 retval = false;
84 error_str += key + _(" expects an argument.") + "\n";
85 } else if (value.length () && !current.get_has_arg ()) {
86 retval = false;
87 error_str += key + _(" does not expect an argument.") + "\n";
88 }
89
90 if (conflicts (key)) {
91 // use the previously supplied argument
92 retval = false;
93 error_str += key + _(" conflicts with another argument.") + "\n";
94 continue;
95 }
96
97 // save it.
98 received_args[key] = value;
99 }
100
101 return retval;
102 }
103
help_text(void) const104 std::string ArgParser::help_text (void) const {
105 std::string ret_str = _("Usage:");
106
107 std::map<std::string, Arg>::const_iterator iter;
108
109 for (iter=expected_args.begin();iter!=expected_args.end();iter++) {
110 std::string name = "--" + iter->first;
111 std::string arg = iter->second.get_has_arg () ? "=[arg]" : "";
112 std::string desc = iter->second.get_desc ();
113 ret_str += "\n\t" + name + arg + "\n\t\t" + desc;
114 }
115
116 return ret_str;
117 }
118
conflicts(std::string key)119 bool ArgParser::conflicts (std::string key) {
120 std::vector< std::vector<std::string> >::const_iterator iter;
121
122 // Look through the exclusive iter. Cramped together to fit
123 // into 80 columns.
124 for (iter=exclusive.begin();iter!=exclusive.end();iter++) {
125 std::vector<std::string>::const_iterator str_iter;
126
127 // Look through every option in this exclusive series.
128 for (str_iter=iter->begin();str_iter!=iter->end();str_iter++) {
129 if (*str_iter == key) {
130 // this option cannot be used with any others
131 // in this vector.
132 // check if any of the options in this vector
133 // have already been specified.
134 std::vector<std::string>::const_iterator new_str_iter;
135 for (new_str_iter=iter->begin();new_str_iter!=iter->end();new_str_iter++) {
136 if (received_args.find (*new_str_iter) != received_args.end ()) {
137 // this option conflicts with a
138 // previous option.
139 return true;
140 }
141 }
142 // no conflicts.
143 return false;
144 }
145 }
146 }
147
148 return false;
149 }
150