summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/PropertiesI.cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2008-03-20 11:20:11 -0230
committerDwayne Boone <dwayne@zeroc.com>2008-03-20 11:20:11 -0230
commit82ef8e6f9d564358aeb1685fc82227d77a7beae2 (patch)
tree6d231fa27405cc0290ed456451c872439ef71fd3 /cpp/src/Ice/PropertiesI.cpp
parentMerge branch 'master' of ssh://git/home/git/ice (diff)
downloadice-82ef8e6f9d564358aeb1685fc82227d77a7beae2.tar.bz2
ice-82ef8e6f9d564358aeb1685fc82227d77a7beae2.tar.xz
ice-82ef8e6f9d564358aeb1685fc82227d77a7beae2.zip
Handle \\ in config file parsing
Diffstat (limited to 'cpp/src/Ice/PropertiesI.cpp')
-rw-r--r--cpp/src/Ice/PropertiesI.cpp245
1 files changed, 146 insertions, 99 deletions
diff --git a/cpp/src/Ice/PropertiesI.cpp b/cpp/src/Ice/PropertiesI.cpp
index faf997b0c93..94f8c64914b 100644
--- a/cpp/src/Ice/PropertiesI.cpp
+++ b/cpp/src/Ice/PropertiesI.cpp
@@ -147,7 +147,7 @@ Ice::PropertiesI::setProperty(const string& key, const string& value)
string currentKey = IceUtilInternal::trim(key);
if(currentKey.empty())
{
- return;
+ throw InitializationException(__FILE__, __LINE__, "Attempt to set property with empty key");
}
//
@@ -409,121 +409,168 @@ Ice::PropertiesI::PropertiesI(StringSeq& args, const PropertiesPtr& defaults, co
void
Ice::PropertiesI::parseLine(const string& line, const StringConverterPtr& converter)
{
- string s = line;
+ string key;
+ string value;
- //
- // Remove comments and unescape #'s
- //
- string::size_type idx = 0;
- while((idx = s.find("#", idx)) != string::npos)
- {
- if(idx != 0 && s[idx - 1] == '\\')
- {
- s.erase(idx - 1, 1);
- ++idx;
- }
- else
- {
- s.erase(idx);
- break;
- }
- }
-
- //
- // Split key/value and unescape ='s
- //
- string::size_type split = string::npos;
- idx = 0;
- while((idx = s.find("=", idx)) != string::npos)
- {
- if(idx != 0 && s[idx - 1] == '\\')
- {
- s.erase(idx - 1, 1);
- }
- else if(split == string::npos)
- {
- split = idx;
- }
- ++idx;
- }
-
- if(split == 0 || split == string::npos)
- {
- s = IceUtilInternal::trim(s);
- if(s.length() != 0)
- {
- getProcessLogger()->warning("invalid config file entry: \"" + line + "\"");
- }
- return;
- }
-
- //
- // Deal with espaced spaces. For key we just unescape and trim but
- // for values any esaped spaces must be kept.
- //
- string key = s.substr(0, split);
- while((idx = key.find("\\ ")) != string::npos)
- {
- key.replace(idx, 2, " ");
- }
- key = IceUtilInternal::trim(key);
+ enum ParseState { Key , Value };
+ ParseState state = Key;
- string value = s.substr(split + 1, s.length() - split - 1);
- idx = 0;
- string whitespace = "";
- while(idx < value.length())
+ string whitespace;
+ string escapedspace;
+ bool finished = false;
+ for(string::size_type i = 0; i < line.size(); ++i)
{
- if(value[idx] == '\\')
+ char c = line[i];
+ switch(state)
{
- if(idx + 1 != value.length() &&
- (value[idx + 1] == ' ' || value[idx + 1] == '\t' || value[idx + 1] == '\r' || value[idx + 1] == '\n'))
+ case Key:
+ {
+ switch(c)
{
- whitespace += value[idx + 1];
- idx += 2;
+ case '\\':
+ if(i < line.length() - 1)
+ {
+ c = line[++i];
+ switch(c)
+ {
+ case '\\':
+ case '#':
+ case '=':
+ key += whitespace;
+ whitespace.clear();
+ key += c;
+ break;
+
+ case ' ':
+ if(key.length() != 0)
+ {
+ whitespace += c;
+ }
+ break;
+
+ default:
+ key += whitespace;
+ whitespace.clear();
+ key += '\\';
+ key += c;
+ break;
+ }
+ }
+ else
+ {
+ key += whitespace;
+ key += c;
+ }
+ break;
+
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ if(key.length() != 0)
+ {
+ whitespace += c;
+ }
+ break;
+
+ case '=':
+ whitespace.clear();
+ state = Value;
+ break;
+
+ case '#':
+ finished = true;
+ break;
+
+ default:
+ key += whitespace;
+ whitespace.clear();
+ key += c;
+ break;
}
- else
+ break;
+ }
+
+ case Value:
+ {
+ switch(c)
{
+ case '\\':
+ if(i < line.length() - 1)
+ {
+ c = line[++i];
+ switch(c)
+ {
+ case '\\':
+ case '#':
+ case '=':
+ value += value.length() == 0 ? escapedspace : whitespace;
+ whitespace.clear();
+ escapedspace.clear();
+ value += c;
+ break;
+
+ case ' ':
+ whitespace += c;
+ escapedspace += c;
+ break;
+
+ default:
+ value += value.length() == 0 ? escapedspace : whitespace;
+ whitespace.clear();
+ escapedspace.clear();
+ value += '\\';
+ value += c;
+ break;
+ }
+ }
+ else
+ {
+ value += value.length() == 0 ? escapedspace : whitespace;
+ value += c;
+ }
break;
+
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ if(value.length() != 0)
+ {
+ whitespace += c;
+ }
+ break;
+
+ case '#':
+ value += escapedspace;
+ finished = true;
+ break;
+
+ default:
+ value += value.length() == 0 ? escapedspace : whitespace;
+ whitespace.clear();
+ escapedspace.clear();
+ value += c;
+ break;
}
+ break;
+ }
}
- else if(value[idx] == ' ' || value[idx] == '\t' || value[idx] == '\r' || value[idx] == '\n')
- {
- ++idx;
- }
- else
+ if(finished)
{
break;
}
}
- value = whitespace + value.substr(idx, value.length() - idx);
- if(idx != value.length())
+ value += escapedspace;
+
+ if((state == Key && key.length() != 0) || (state == Value && key.length() == 0))
{
- idx = value.length() - 1;
- whitespace = "";
- while(idx > 0)
- {
- if(value[idx] == ' ' || value[idx] == '\t' || value[idx] == '\r' || value[idx] == '\n')
- {
- if(value[idx - 1] == '\\')
- {
- whitespace += value[idx];
- idx -= 2;
- }
- else
- {
- --idx;
- }
- }
- else
- {
- break;
- }
- }
- value = value.substr(0, idx + 1) + whitespace;
+ getProcessLogger()->warning("invalid config file entry: \"" + line + "\"");
+ return;
}
- while((idx = value.find("\\ ")) != string::npos)
+ else if(key.length() == 0)
{
- value.replace(idx, 2, " ");
+ return;
}
if(converter)