6
#include "rutil/ConfigParse.hxx"
7
#include "rutil/Log.hxx"
8
#include "rutil/Logger.hxx"
9
#include "rutil/ParseBuffer.hxx"
10
#include "rutil/WinLeakCheck.hxx"
12
using namespace resip;
15
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
20
ConfigParse::ConfigParse(int argc, char** argv, const resip::Data& defaultConfigFilename)
22
parseCommandLine(argc, argv); // will fill in mCmdLineConfigFilename if present
23
if(mCmdLineConfigFilename.empty())
25
parseConfigFile(defaultConfigFilename);
29
parseConfigFile(mCmdLineConfigFilename);
33
ConfigParse::ConfigParse()
37
ConfigParse::~ConfigParse()
42
ConfigParse::getConfigValue(const resip::Data& name, resip::Data &value)
44
Data lowerName(name); lowerName.lowercase();
45
ConfigValuesMap::iterator it = mConfigValues.find(lowerName);
46
if(it != mConfigValues.end())
56
ConfigParse::getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty)
58
Data ret(defaultValue);
59
if(getConfigValue(name, ret) && ret.empty() && useDefaultIfEmpty)
67
ConfigParse::getConfigValue(const resip::Data& name, bool &value)
69
Data lowerName(name); lowerName.lowercase();
70
ConfigValuesMap::iterator it = mConfigValues.find(lowerName);
71
if(it != mConfigValues.end())
73
if(it->second == "1" ||
74
isEqualNoCase(it->second, "true") ||
75
isEqualNoCase(it->second, "on") ||
76
isEqualNoCase(it->second, "enable"))
81
else if(it->second == "0" ||
82
isEqualNoCase(it->second, "false") ||
83
isEqualNoCase(it->second, "off") ||
84
isEqualNoCase(it->second, "disable"))
89
cerr << "Invalid boolean setting: " << name << " = " << it->second << ": Valid values are: 1,true,on,enable,0,false,off or disable" << endl;
97
ConfigParse::getConfigBool(const resip::Data& name, bool defaultValue)
99
bool ret = defaultValue;
100
getConfigValue(name, ret);
105
ConfigParse::getConfigValue(const resip::Data& name, unsigned long &value)
107
Data lowerName(name); lowerName.lowercase();
108
ConfigValuesMap::iterator it = mConfigValues.find(lowerName);
109
if(it != mConfigValues.end())
111
value = it->second.convertUnsignedLong();
119
ConfigParse::getConfigUnsignedLong(const resip::Data& name, unsigned long defaultValue)
121
unsigned long ret = defaultValue;
122
getConfigValue(name, ret);
127
ConfigParse::getConfigValue(const resip::Data& name, int &value)
129
Data lowerName(name); lowerName.lowercase();
130
ConfigValuesMap::iterator it = mConfigValues.find(lowerName);
131
if(it != mConfigValues.end())
133
value = it->second.convertInt();
142
ConfigParse::getConfigInt(const resip::Data& name, int defaultValue)
144
int ret = defaultValue;
145
getConfigValue(name, ret);
150
ConfigParse::getConfigValue(const resip::Data& name, unsigned short &value)
152
Data lowerName(name); lowerName.lowercase();
153
ConfigValuesMap::iterator it = mConfigValues.find(lowerName);
154
if(it != mConfigValues.end())
156
value = it->second.convertInt();
165
ConfigParse::getConfigUnsignedShort(const resip::Data& name, int defaultValue)
167
int ret = defaultValue;
168
getConfigValue(name, ret);
173
ConfigParse::getConfigValue(const resip::Data& name, std::vector<resip::Data> &value)
175
Data lowerName(name); lowerName.lowercase();
176
std::pair<ConfigValuesMap::iterator,ConfigValuesMap::iterator> valuesIts = mConfigValues.equal_range(lowerName);
178
for (ConfigValuesMap::iterator it=valuesIts.first; it!=valuesIts.second; ++it)
181
ParseBuffer pb(it->second);
183
while(!it->second.empty() && !pb.eof())
186
const char *start = pb.position();
187
pb.skipToOneOf(ParseBuffer::Whitespace, ","); // allow white space
188
pb.data(item, start);
189
value.push_back(item);
201
ConfigParse::insertConfigValue(const resip::Data& name, const resip::Data& value)
203
resip::Data lowerName(name);
204
lowerName.lowercase();
205
mConfigValues.insert(ConfigValuesMap::value_type(lowerName, value));
209
ConfigParse::parseCommandLine(int argc, char** argv)
211
int startingArgForNameValuePairs = 1;
212
// First argument is the configuration filename - it is optional and is never proceeded with a - or /
214
if(argc >= 2 && argv[1][0] != '-' && argv[1][0] != '/')
216
if(argc >= 2 && argv[1][0] != '-')
219
mCmdLineConfigFilename = argv[1];
220
startingArgForNameValuePairs = 2;
223
// Loop through command line arguments and process them
224
for(int i = startingArgForNameValuePairs; i < argc; i++)
226
Data argData(argv[i]);
228
// Process all commandNames that don't take values
229
if(isEqualNoCase(argData, "-?") ||
230
isEqualNoCase(argData, "--?") ||
231
isEqualNoCase(argData, "--help") ||
232
isEqualNoCase(argData, "/?"))
234
printHelpText(argc, argv);
237
else if(argData.at(0) == '-' || argData.at(0) == '/')
241
ParseBuffer pb(argData);
245
pb.skipChars(Data::toBitset("-/")); // Skip any leading -'s or /'s
246
const char * anchor = pb.position();
247
pb.skipToOneOf("=:");
250
pb.data(name, anchor);
252
anchor = pb.position();
254
pb.data(value, anchor);
256
//cout << "Command line Name='" << name << "' value='" << value << "'" << endl;
257
insertConfigValue(name, value);
261
cerr << "Invalid command line parameters:" << endl;
262
cerr << " Name/Value pairs must contain an = or a : between the name and the value" << endl;
266
catch(BaseException& ex)
268
cerr << "Invalid command line parameters:" << endl;
269
cerr << " Exception parsing Name/Value pairs: " << ex << endl;
275
cerr << "Invalid command line parameters:" << endl;
276
cerr << " Name/Value pairs must be prefixed with either a -, --, or a /" << endl;
283
ConfigParse::parseConfigFile(const Data& filename)
285
ifstream configFile(filename.c_str());
289
throw Exception("Error opening/reading configuration file", __FILE__, __LINE__);
294
while(getline(configFile, sline))
299
ParseBuffer pb(line);
302
anchor = pb.position();
303
if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it
305
// Look for end of name
306
pb.skipToOneOf("= \t");
307
pb.data(name,anchor);
308
if(*pb.position()!='=')
314
anchor = pb.position();
317
pb.skipToOneOf("\r\n");
318
pb.data(value, anchor);
320
//cout << "Config file Name='" << name << "' value='" << value << "'" << endl;
321
insertConfigValue(name, value);
326
operator<<(EncodeStream& strm, const ConfigParse& config)
328
ConfigParse::ConfigValuesMap::const_iterator it = config.mConfigValues.begin();
329
for(; it != config.mConfigValues.end(); it++)
331
strm << it->first << " = " << it->second << endl;
338
/* ====================================================================
339
* The Vovida Software License, Version 1.0
341
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
343
* Redistribution and use in source and binary forms, with or without
344
* modification, are permitted provided that the following conditions
347
* 1. Redistributions of source code must retain the above copyright
348
* notice, this list of conditions and the following disclaimer.
350
* 2. Redistributions in binary form must reproduce the above copyright
351
* notice, this list of conditions and the following disclaimer in
352
* the documentation and/or other materials provided with the
355
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
356
* and "Vovida Open Communication Application Library (VOCAL)" must
357
* not be used to endorse or promote products derived from this
358
* software without prior written permission. For written
359
* permission, please contact vocal@vovida.org.
361
* 4. Products derived from this software may not be called "VOCAL", nor
362
* may "VOCAL" appear in their name, without prior written
363
* permission of Vovida Networks, Inc.
365
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
366
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
367
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
368
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
369
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
370
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
371
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
372
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
373
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
374
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
375
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
376
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
379
* ====================================================================
381
* This software consists of voluntary contributions made by Vovida
382
* Networks, Inc. and many individuals on behalf of Vovida Networks,
383
* Inc. For more information on Vovida Networks, Inc., please see
384
* <http://www.vovida.org/>.