source: trunk/FACT++/src/tools.cc@ 14098

Last change on this file since 14098 was 14054, checked in by tbretz, 12 years ago
Allow to split command lines without equal signs
File size: 5.2 KB
Line 
1// **************************************************************************
2/** @file tools.cc
3
4@todo
5 - Resolve the dependancies with dim
6 - Move code to a more appropriate place
7 - put stuff in namespaces
8*/
9// **************************************************************************
10#include "tools.h"
11
12#include <stdarg.h>
13
14#include <boost/tokenizer.hpp>
15
16using namespace std;
17
18string Tools::Format(const char *fmt, va_list &ap)
19{
20 int n=256;
21
22 char *ret=0;
23 while (1)
24 {
25 ret = new char[n+1];
26
27 const int sz = vsnprintf(ret, n, fmt, ap);
28 if (sz<=n)
29 break;
30
31 n *= 2;
32 delete [] ret;
33 };
34
35 string str(ret);
36
37 delete [] ret;
38
39 return str;
40}
41
42string Tools::Form(const char *fmt, ...)
43{
44 va_list ap;
45 va_start(ap, fmt);
46
47 string str = Format(fmt, ap);
48
49 va_end(ap);
50
51 return str;
52}
53
54// --------------------------------------------------------------------------
55//
56//! This is a static helper to remove leading and trailing whitespaces.
57//!
58//! @param buf
59//! a pointer to the char array from which the whitespaces should be
60//! removed
61//!
62//! @returns
63//! a std::string with the whitespaces removed from buf
64//
65string Tools::Trim(const string &str)
66{
67 // Trim Both leading and trailing spaces
68 const size_t start = str.find_first_not_of(' '); // Find the first character position after excluding leading blank spaces
69 const size_t end = str.find_last_not_of(' '); // Find the first character position from reverse af
70
71 // if all spaces or empty return an empty string
72 if (string::npos==start || string::npos==end)
73 return string();
74
75 return str.substr(start, end-start+1);
76}
77
78// --------------------------------------------------------------------------
79//
80//! This is a static helper to remove leading and trailing whitespaces and
81//! if available leading and trailing quotes, can be either ' or "
82//!
83//! @param buf
84//! a pointer to the char array to be trimmed
85//!
86//! @returns
87//! a std::string with the content trimmed
88//
89string Tools::TrimQuotes(const string &str)
90{
91 string rc = Trim(str);
92 if (rc.length()<2)
93 return rc;
94
95 const char b = rc[0];
96 const char e = rc[rc.length()-1];
97
98 if ((b=='\"' && e=='\"') || (b=='\'' && e=='\''))
99 return rc.substr(1, rc.length()-2);
100
101 return rc;
102}
103
104// --------------------------------------------------------------------------
105//
106//! This is a static helper to remove leading and trailing whitespaces.
107//!
108//! Usage example:
109//!
110//! \code
111//! string str = " Dies ist ein test fuer einen ganz langen Satz "
112//! "und ob er korrekt umgebrochen und formatiert wird. Alles "
113//! "nur ein simpler test aber trotzdem ganz wichtig.";
114//!
115//! cout << setfill('-') << setw(40) << "+" << endl;
116//! while (1)
117//! {
118//! const string rc = Tools::Wrap(str, 40);
119//! if (rc.empty())
120//! break;
121//! cout << rc << endl;
122//! }
123//! \endcode
124//!
125string Tools::Wrap(string &str, size_t width)
126{
127 const size_t pos = str.length()<width ? string::npos : str.find_last_of(' ', width);
128 if (pos==string::npos)
129 {
130 const string rc = str;
131 str = "";
132 return rc;
133 }
134
135 const size_t indent = str.find_first_not_of(' ');
136
137 const string rc = str.substr(0, pos);
138 const size_t p2 = str.find_first_not_of(' ', pos+1);
139
140 str = str.substr(0, indent) + str.substr(p2==string::npos ? pos+1 : p2);
141
142 return rc;
143}
144
145// --------------------------------------------------------------------------
146//
147//! Splits a string into a filename and command line arguments, like:
148//!
149//! file.txt arg1=argument1 arg2="argument 2" arg3="argument \"3\""
150//!
151//! 'file.txt' will be returned on opt, the arguments will be returned in
152//! the returned map.
153//!
154//! If the returned file name is empty, an error has occured:
155//! If the map is also empty the file name was empty, if the map has
156//! one entry then for this entry the euqal sign was missing.
157//!
158map<string,string> Tools::Split(string &opt, bool allow)
159{
160 using namespace boost;
161 typedef escaped_list_separator<char> separator;
162
163 const string data(opt);
164
165 const tokenizer<separator> tok(data, separator('\\', ' ', '\"'));
166
167 auto it=tok.begin();
168 if (it==tok.end())
169 {
170 opt = "";
171 return map<string,string>();
172 }
173
174 opt = *it++;
175
176 map<string,string> rc;
177
178 int i=-1;
179
180 for (; it!=tok.end(); it++)
181 {
182 if (it->empty())
183 continue;
184
185 i++;
186
187 const size_t pos = it->find_first_of('=');
188 if (pos==string::npos)
189 {
190 if (allow)
191 {
192 rc[to_string(i)] = *it;
193 continue;
194 }
195
196 opt = "";
197 rc.clear();
198 rc[*it] = "";
199 return rc;
200 }
201
202 rc[it->substr(0, pos)] = it->substr(pos+1);
203 }
204
205 return rc;
206}
207
208// --------------------------------------------------------------------------
209//
210//! Returns the string with a comment (introduced by a #) stripped. The
211//! comment mark can be escaped by either \# or "#"
212//!
213string Tools::Uncomment(const string &opt)
214{
215 using namespace boost;
216 typedef escaped_list_separator<char> separator;
217
218 return *tokenizer<separator>(opt, separator('\\', '#', '\"')).begin();
219}
Note: See TracBrowser for help on using the repository browser.