Adding property_tree

[SVN r37680]
This commit is contained in:
Marcin Kalicinski
2007-05-12 22:02:53 +00:00
commit f4105f823f
83 changed files with 18450 additions and 0 deletions

96
.gitattributes vendored Normal file
View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

View File

@@ -0,0 +1,80 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
// This example shows what need to be done to customize data_type of ptree.
//
// It creates my_ptree type, which is a basic_ptree having boost::any as its data
// container (instead of std::string that standard ptree has).
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/any.hpp>
#include <list>
#include <string>
#include <iostream>
// Custom translator that works with boost::any instead of std::string
struct my_translator
{
// Custom extractor - converts data from boost::any to T
template<class Ptree, class T>
bool get_value(const Ptree &pt, T &value) const
{
value = boost::any_cast<T>(pt.data());
return true; // Success
}
// Custom inserter - converts data from T to boost::any
template<class Ptree, class T>
bool put_value(Ptree &pt, const T &value) const
{
pt.data() = value;
return true;
}
};
int main()
{
using namespace boost::property_tree;
// Property_tree with boost::any as data type
// Key comparison: std::less<std::string>
// Key type: std::string
// Path type: path
// Data type: boost::any
// Translator type: my_translator
typedef basic_ptree<std::less<std::string>, std::string, path, boost::any, my_translator> my_ptree;
my_ptree pt;
// Put/get int value
pt.put("int value", 3);
int int_value = pt.get<int>("int value");
std::cout << "Int value: " << int_value << "\n";
// Put/get string value
pt.put<std::string>("string value", "foo bar");
std::string string_value = pt.get<std::string>("string value");
std::cout << "String value: " << string_value << "\n";
// Put/get list<int> value
int list_data[] = { 1, 2, 3, 4, 5 };
pt.put<std::list<int> >("list value", std::list<int>(list_data, list_data + sizeof(list_data) / sizeof(*list_data)));
std::list<int> list_value = pt.get<std::list<int> >("list value");
std::cout << "List value: ";
for (std::list<int>::iterator it = list_value.begin(); it != list_value.end(); ++it)
std::cout << *it << ' ';
std::cout << '\n';
}

109
examples/debug_settings.cpp Normal file
View File

@@ -0,0 +1,109 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
//#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>
struct debug_settings
{
std::string m_file; // log filename
int m_level; // debug level
std::set<std::string> m_modules; // modules where logging is enabled
void load(const std::string &filename);
void save(const std::string &filename);
};
void debug_settings::load(const std::string &filename)
{
// Create empty property tree object
using boost::property_tree::ptree;
ptree pt;
// Load XML file and put its contents in property tree.
// No namespace qualification is needed, because of Koenig
// lookup on the second argument. If reading fails, exception
// is thrown.
read_xml(filename, pt);
// Get filename and store it in m_file variable. Note that
// we specify a path to the value using notation where keys
// are separated with dots (different separator may be used
// if keys themselves contain dots). If debug.filename key is
// not found, exception is thrown.
m_file = pt.get<std::string>("debug.filename");
// Get debug level and store it in m_level variable. This is
// another version of get method: if debug.level key is not
// found, it will return default value (specified by second
// parameter) instead of throwing. Type of the value extracted
// is determined by type of second parameter, so we can simply
// write get(...) instead of get<int>(...).
m_level = pt.get("debug.level", 0);
// Iterate over debug.modules section and store all found
// modules in m_modules set. get_child() function returns a
// reference to child at specified path; if there is no such
// child, it throws. Property tree iterator can be used in
// the same way as standard container iterator. Category
// is bidirectional_iterator.
//BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))
// m_modules.insert(v.second.data());
}
void debug_settings::save(const std::string &filename)
{
// Create empty property tree object
using boost::property_tree::ptree;
ptree pt;
// Put log filename in property tree
pt.put("debug.filename", m_file);
// Put debug level in property tree
pt.put("debug.level", m_level);
// Iterate over modules in set and put them in property
// tree. Note that put function places new key at the
// end of list of keys. This is fine in most of the
// situations. If you want to place item at some other
// place (i.e. at front or somewhere in the middle),
// this can be achieved using combination of insert
// and put_value functions
//BOOST_FOREACH(const std::string &name, m_modules)
// pt.put("debug.modules.module", name, true);
// Write property tree to XML file
write_xml(filename, pt);
}
int main()
{
try
{
debug_settings ds;
ds.load("debug_settings.xml");
ds.save("debug_settings_out.xml");
std::cout << "Success\n";
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what() << "\n";
}
return 0;
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<debug>
<filename>debug.log</filename>
<modules>
<module>Finance</module>
<module>Admin</module>
<module>HR</module>
</modules>
<level>2</level>
</debug>

View File

@@ -0,0 +1,71 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <iostream>
#include <iomanip>
#include <string>
using namespace boost::property_tree;
// Process settings using empty ptree trick. Note that it is considerably simpler
// than version which does not use the "trick"
void process_settings(const std::string &filename)
{
ptree pt;
read_info(filename, pt);
const ptree &settings = pt.get_child("settings", empty_ptree<ptree>());
std::cout << "\n Processing " << filename << std::endl;
std::cout << " Setting 1 is " << settings.get("setting1", 0) << std::endl;
std::cout << " Setting 2 is " << settings.get("setting2", 0.0) << std::endl;
std::cout << " Setting 3 is " << settings.get("setting3", "default") << std::endl;
}
// Process settings not using empty ptree trick. This one must duplicate much of the code.
void process_settings_without_trick(const std::string &filename)
{
ptree pt;
read_info(filename, pt);
if (boost::optional<ptree &> settings = pt.get_child_optional("settings"))
{
std::cout << "\n Processing " << filename << std::endl;
std::cout << " Setting 1 is " << settings.get().get("setting1", 0) << std::endl;
std::cout << " Setting 2 is " << settings.get().get("setting2", 0.0) << std::endl;
std::cout << " Setting 3 is " << settings.get().get("setting3", "default") << std::endl;
}
else
{
std::cout << "\n Processing " << filename << std::endl;
std::cout << " Setting 1 is " << 0 << std::endl;
std::cout << " Setting 2 is " << 0.0 << std::endl;
std::cout << " Setting 3 is " << "default" << std::endl;
}
}
int main()
{
try
{
std::cout << "Processing settings with empty-ptree-trick:\n";
process_settings("settings_fully-existent.info");
process_settings("settings_partially-existent.info");
process_settings("settings_non-existent.info");
std::cout << "\nProcessing settings without empty-ptree-trick:\n";
process_settings_without_trick("settings_fully-existent.info");
process_settings_without_trick("settings_partially-existent.info");
process_settings_without_trick("settings_non-existent.info");
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what() << "\n";
}
return 0;
}

View File

@@ -0,0 +1,152 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
/* This is grammar of INFO file format written in form of boost::spirit rules.
For simplicity, it does not parse #include directive. Note that INFO parser
included in property_tree library does not use Spirit.
*/
//#define BOOST_SPIRIT_DEBUG // uncomment to enable debug output
#include <boost/spirit.hpp>
struct info_grammar: public boost::spirit::grammar<info_grammar>
{
template<class Scanner>
struct definition
{
boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> chr, qchr, escape_seq;
boost::spirit::rule<Scanner> string, qstring, cstring, key, value, entry, info;
definition(const info_grammar &self)
{
using namespace boost::spirit;
escape_seq = chset_p("0abfnrtv\"\'\\");
chr = (anychar_p - space_p - '\\' - '{' - '}' - '#' - '"') | ('\\' >> escape_seq);
qchr = (anychar_p - '"' - '\n' - '\\') | ('\\' >> escape_seq);
string = lexeme_d[+chr];
qstring = lexeme_d['"' >> *qchr >> '"'];
cstring = lexeme_d['"' >> *qchr >> '"' >> '\\'];
key = string | qstring;
value = string | qstring | (+cstring >> qstring) | eps_p;
entry = key >> value >> !('{' >> *entry >> '}');
info = *entry >> end_p;
// Debug nodes
BOOST_SPIRIT_DEBUG_NODE(escape_seq);
BOOST_SPIRIT_DEBUG_NODE(chr);
BOOST_SPIRIT_DEBUG_NODE(qchr);
BOOST_SPIRIT_DEBUG_NODE(string);
BOOST_SPIRIT_DEBUG_NODE(qstring);
BOOST_SPIRIT_DEBUG_NODE(key);
BOOST_SPIRIT_DEBUG_NODE(value);
BOOST_SPIRIT_DEBUG_NODE(entry);
BOOST_SPIRIT_DEBUG_NODE(info);
}
const boost::spirit::rule<Scanner> &start() const
{
return info;
}
};
};
void info_parse(const char *s)
{
using namespace boost::spirit;
// Parse and display result
info_grammar g;
parse_info<const char *> pi = parse(s, g, space_p | comment_p(";"));
std::cout << "Parse result: " << (pi.hit ? "Success" : "Failure") << "\n";
}
int main()
{
// Sample data 1
const char *data1 =
"\n"
"key1 data1\n"
"{\n"
"\tkey data\n"
"}\n"
"key2 \"data2 \" {\n"
"\tkey data\n"
"}\n"
"key3 \"data\"\n"
"\t \"3\" {\n"
"\tkey data\n"
"}\n"
"\n"
"\"key4\" data4\n"
"{\n"
"\tkey data\n"
"}\n"
"\"key.5\" \"data.5\" { \n"
"\tkey data \n"
"}\n"
"\"key6\" \"data\"\n"
"\t \"6\" {\n"
"\tkey data\n"
"}\n"
" \n"
"key1 data1\n"
"{\n"
"\tkey data\n"
"}\n"
"key2 \"data2 \" {\n"
"\tkey data\n"
"}\n"
"key3 \"data\"\n"
"\t \"3\" {\n"
"\tkey data\n"
"}\n"
"\n"
"\"key4\" data4\n"
"{\n"
"\tkey data\n"
"}\n"
"\"key.5\" \"data.5\" {\n"
"\tkey data\n"
"}\n"
"\"key6\" \"data\"\n"
"\t \"6\" {\n"
"\tkey data\n"
"}\n"
"\\\\key\\t7 data7\\n\\\"data7\\\"\n"
"{\n"
"\tkey data\n"
"}\n"
"\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n"
"{\n"
"\tkey data\n"
"}\n"
"\n";
// Sample data 2
const char *data2 =
"key1\n"
"key2\n"
"key3\n"
"key4\n";
// Parse sample data
info_parse(data1);
info_parse(data2);
}

View File

@@ -0,0 +1,6 @@
settings
{
setting1 15
setting2 9.876
setting3 Alice in Wonderland
}

View File

@@ -0,0 +1,6 @@
;settings // non-existent
;{
; setting1 15
; setting2 9.876
; setting3 Alice in Wonderland
;}

View File

@@ -0,0 +1,6 @@
settings
{
setting1 15
;setting2 9.876 // non-existent
;setting3 Alice in Wonderland // non-existent
}

134
examples/speed_test.cpp Normal file
View File

@@ -0,0 +1,134 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#define _HAS_ITERATOR_DEBUGGING 0
#include <boost/property_tree/ptree.hpp>
#include <boost/format.hpp>
#include <boost/shared_array.hpp>
#include <iostream>
#include <ctime>
#include <algorithm>
using namespace std;
using namespace boost;
using namespace boost::property_tree;
string dummy;
vector<string> keys;
vector<string> shuffled_keys;
void prepare_keys(int size)
{
// Prepare keys
keys.clear();
for (int i = 0; i < size; ++i)
keys.push_back((format("%d") % i).str());
shuffled_keys = keys;
srand(0);
random_shuffle(shuffled_keys.begin(), shuffled_keys.end());
}
void clock_push_back(int size)
{
prepare_keys(size);
int max_repeats = 1000000 / size;
shared_array<ptree> pt_array(new ptree[max_repeats]);
int n = 0;
clock_t t1 = clock(), t2;
do
{
if (n >= max_repeats)
break;
ptree &pt = pt_array[n];
for (int i = 0; i < size; ++i)
pt.push_back(ptree::value_type(shuffled_keys[i], empty_ptree<ptree>()));
t2 = clock();
++n;
} while (t2 - t1 < CLOCKS_PER_SEC);
cout << " push_back (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n";
}
void clock_find(int size)
{
prepare_keys(size);
ptree pt;
for (int i = 0; i < size; ++i)
pt.push_back(ptree::value_type(keys[i], ptree("data")));
int n = 0;
clock_t t1 = clock(), t2;
do
{
for (int i = 0; i < size; ++i)
pt.find(shuffled_keys[i]);
t2 = clock();
++n;
} while (t2 - t1 < CLOCKS_PER_SEC);
cout << " find (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n";
}
void clock_erase(int size)
{
prepare_keys(size);
int max_repeats = 100000 / size;
shared_array<ptree> pt_array(new ptree[max_repeats]);
ptree pt;
for (int n = 0; n < max_repeats; ++n)
for (int i = 0; i < size; ++i)
pt_array[n].push_back(ptree::value_type(keys[i], ptree("data")));
int n = 0;
clock_t t1 = clock(), t2;
do
{
if (n >= max_repeats)
break;
ptree &pt = pt_array[n];
for (int i = 0; i < size; ++i)
pt.erase(shuffled_keys[i]);
t2 = clock();
++n;
} while (t2 - t1 < CLOCKS_PER_SEC);
cout << " erase (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n";
}
int main()
{
// push_back
clock_push_back(10);
clock_push_back(100);
clock_push_back(1000);
// erase
clock_erase(10);
clock_erase(100);
clock_erase(1000);
// find
clock_find(10);
clock_find(100);
clock_find(1000);
}

View File

@@ -0,0 +1,106 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_EXCEPTIONS_IMPLEMENTATION_HPP_INCLUDED
namespace boost { namespace property_tree
{
namespace detail
{
// Default path-to-string converter; this is overridden for default path
template<class P>
std::string path_to_string(const P &path)
{
return std::string("<cannot convert path to string>");
}
// Helper for preparing what string in ptree_bad_path exception
template<class P>
std::string prepare_bad_path_what(const std::string &what, const P &path)
{
using namespace detail; // To allow correct resolution of path_to_string()
return what + " (" + path_to_string(path) + ")";
}
// Default data-to-string converter; this is overridden for default data (string)
template<class D>
std::string data_to_string(const D &data)
{
return std::string("<cannot convert data to string>");
}
// Helper for preparing what string in ptree_bad_data exception
template<class D>
std::string prepare_bad_data_what(const std::string &what, const D &data)
{
using namespace detail; // To allow correct resolution of data_to_string()
return what + " (" + data_to_string(data) + ")";
}
}
///////////////////////////////////////////////////////////////////////////
// ptree_error
inline ptree_error::ptree_error(const std::string &what):
std::runtime_error(what)
{
}
inline ptree_error::~ptree_error() throw()
{
}
///////////////////////////////////////////////////////////////////////////
// ptree_bad_data
template<class D>
ptree_bad_data::ptree_bad_data(const std::string &what, const D &data):
ptree_error(detail::prepare_bad_data_what(what, data)),
m_data(data)
{
}
inline ptree_bad_data::~ptree_bad_data() throw()
{
}
template<class D>
D ptree_bad_data::data()
{
return boost::any_cast<D>(m_data);
}
///////////////////////////////////////////////////////////////////////////
// ptree_bad_path
template<class P>
ptree_bad_path::ptree_bad_path(const std::string &what, const P &path):
ptree_error(detail::prepare_bad_path_what(what, path)),
m_path(path)
{
}
inline ptree_bad_path::~ptree_bad_path() throw()
{
}
template<class P>
P ptree_bad_path::path()
{
return boost::any_cast<P>(m_path);
}
} }
#endif

View File

@@ -0,0 +1,88 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_FILE_PARSER_ERROR_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <string>
namespace boost { namespace property_tree
{
//! File parse error
class file_parser_error: public ptree_error
{
public:
///////////////////////////////////////////////////////////////////////
// Construction & destruction
// Construct error
file_parser_error(const std::string &message,
const std::string &filename,
unsigned long line):
ptree_error(format_what(message, filename, line)),
m_message(message), m_filename(filename), m_line(line)
{
}
~file_parser_error() throw()
// gcc 3.4.2 complains about lack of throw specifier on compiler generated dtor
{
}
///////////////////////////////////////////////////////////////////////
// Data access
// Get error message (without line and file - use what() to get full message)
std::string message()
{
return m_message;
}
// Get error filename
std::string filename()
{
return m_filename;
}
// Get error line number
unsigned long line()
{
return m_line;
}
private:
std::string m_message;
std::string m_filename;
unsigned long m_line;
// Format error message to be returned by std::runtime_error::what()
std::string format_what(const std::string &message,
const std::string &filename,
unsigned long line)
{
std::stringstream stream;
if (line > 0)
stream << (filename.empty() ? "<unspecified file>" : filename.c_str()) <<
'(' << line << "): " << message;
else
stream << (filename.empty() ? "<unspecified file>" : filename.c_str()) <<
": " << message;
return stream.str();
}
};
} }
#endif

View File

@@ -0,0 +1,32 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_ERROR_HPP_INCLUDED
#include <boost/property_tree/detail/file_parser_error.hpp>
#include <string>
namespace boost { namespace property_tree { namespace info_parser
{
class info_parser_error: public file_parser_error
{
public:
info_parser_error(const std::string &message,
const std::string &filename,
unsigned long line):
file_parser_error(message, filename, line)
{
}
};
} } }
#endif

View File

@@ -0,0 +1,373 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_READ_HPP_INCLUDED
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/detail/info_parser_error.hpp"
#include "boost/property_tree/detail/info_parser_utils.hpp"
#include <iterator>
#include <string>
#include <stack>
#include <fstream>
#include <cctype>
namespace boost { namespace property_tree { namespace info_parser
{
// Expand known escape sequences
template<class It>
std::basic_string<typename std::iterator_traits<It>::value_type>
expand_escapes(It b, It e)
{
typedef typename std::iterator_traits<It>::value_type Ch;
std::basic_string<Ch> result;
while (b != e)
{
if (*b == Ch('\\'))
{
++b;
if (b == e)
{
BOOST_PROPERTY_TREE_THROW(info_parser_error("character expected after backslash", "", 0));
}
else if (*b == Ch('0')) result += Ch('\0');
else if (*b == Ch('a')) result += Ch('\a');
else if (*b == Ch('b')) result += Ch('\b');
else if (*b == Ch('f')) result += Ch('\f');
else if (*b == Ch('n')) result += Ch('\n');
else if (*b == Ch('r')) result += Ch('\r');
else if (*b == Ch('t')) result += Ch('\t');
else if (*b == Ch('v')) result += Ch('\v');
else if (*b == Ch('"')) result += Ch('"');
else if (*b == Ch('\'')) result += Ch('\'');
else if (*b == Ch('\\')) result += Ch('\\');
else
BOOST_PROPERTY_TREE_THROW(info_parser_error("unknown escape sequence", "", 0));
}
else
result += *b;
++b;
}
return result;
}
// Advance pointer past whitespace
template<class Ch>
void skip_whitespace(const Ch *&text)
{
using namespace std;
while (isspace(*text))
++text;
}
// Extract word (whitespace delimited) and advance pointer accordingly
template<class Ch>
std::basic_string<Ch> read_word(const Ch *&text)
{
using namespace std;
skip_whitespace(text);
const Ch *start = text;
while (!isspace(*text) && *text != Ch(';') && *text != Ch('\0'))
++text;
return expand_escapes(start, text);
}
// Extract line (eol delimited) and advance pointer accordingly
template<class Ch>
std::basic_string<Ch> read_line(const Ch *&text)
{
using namespace std;
skip_whitespace(text);
const Ch *start = text;
while (*text != Ch('\0') && *text != Ch(';'))
++text;
while (text > start && isspace(*(text - 1)))
--text;
return expand_escapes(start, text);
}
// Extract string (inside ""), and advance pointer accordingly
// Set need_more_lines to true if \ continuator found
template<class Ch>
std::basic_string<Ch> read_string(const Ch *&text, bool *need_more_lines)
{
skip_whitespace(text);
if (*text == Ch('\"'))
{
// Skip "
++text;
// Find end of string, but skip escaped "
bool escaped = false;
const Ch *start = text;
while ((escaped || *text != Ch('\"')) && *text != Ch('\0'))
{
escaped = (!escaped && *text == Ch('\\'));
++text;
}
// If end of string found
if (*text == Ch('\"'))
{
std::basic_string<Ch> result = expand_escapes(start, text++);
skip_whitespace(text);
if (*text == Ch('\\'))
{
if (!need_more_lines)
BOOST_PROPERTY_TREE_THROW(info_parser_error("unexpected \\", "", 0));
++text;
skip_whitespace(text);
if (*text == Ch('\0') || *text == Ch(';'))
*need_more_lines = true;
else
BOOST_PROPERTY_TREE_THROW(info_parser_error("expected end of line after \\", "", 0));
}
else
if (need_more_lines)
*need_more_lines = false;
return result;
}
else
BOOST_PROPERTY_TREE_THROW(info_parser_error("unexpected end of line", "", 0));
}
else
BOOST_PROPERTY_TREE_THROW(info_parser_error("expected \"", "", 0));
}
// Extract key
template<class Ch>
std::basic_string<Ch> read_key(const Ch *&text)
{
skip_whitespace(text);
if (*text == Ch('\"'))
return read_string(text, NULL);
else
return read_word(text);
}
// Extract data
template<class Ch>
std::basic_string<Ch> read_data(const Ch *&text, bool *need_more_lines)
{
skip_whitespace(text);
if (*text == Ch('\"'))
return read_string(text, need_more_lines);
else
{
*need_more_lines = false;
return read_word(text);
}
}
// Build ptree from info stream
template<class Ptree>
void read_info_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
const std::string &filename,
int include_depth)
{
// Character type
typedef typename Ptree::key_type::value_type Ch;
// Possible parser states
enum state_t {
s_key, // Parser expects key
s_data, // Parser expects data
s_data_cont // Parser expects data continuation
};
unsigned long line_no = 0;
state_t state = s_key; // Parser state
Ptree *last = NULL; // Pointer to last created ptree
std::basic_string<Ch> line; // Define line here to minimize reallocations
// Initialize ptree stack (used to handle nesting)
std::stack<Ptree *> stack;
stack.push(&pt); // Push root ptree on stack initially
try
{
// While there are characters in the stream
while (stream.good())
{
// Read one line from stream
++line_no;
std::getline(stream, line);
if (!stream.good() && !stream.eof())
BOOST_PROPERTY_TREE_THROW(info_parser_error("read error", "", 0));
const Ch *text = line.c_str();
// If directive found
skip_whitespace(text);
if (*text == Ch('#'))
{
// Determine directive type
++text; // skip #
std::basic_string<Ch> directive = read_word(text);
if (directive == convert_chtype<Ch, char>("include")) // #include
{
if (include_depth > 100)
BOOST_PROPERTY_TREE_THROW(info_parser_error("include depth too large, probably recursive include", "", 0));
std::basic_string<Ch> s = read_string(text, NULL);
std::string inc_name = convert_chtype<char, Ch>(s.c_str());
std::basic_ifstream<Ch> inc_stream(inc_name.c_str());
if (!inc_stream.good())
BOOST_PROPERTY_TREE_THROW(info_parser_error("cannot open include file " + inc_name, "", 0));
read_info_internal(inc_stream, *stack.top(), inc_name, include_depth + 1);
}
else // Unknown directive
BOOST_PROPERTY_TREE_THROW(info_parser_error("unknown directive", "", 0));
// Directive must be followed by end of line
skip_whitespace(text);
if (*text != Ch('\0'))
BOOST_PROPERTY_TREE_THROW(info_parser_error("expected end of line", "", 0));
// Go to next line
continue;
}
// While there are characters left in line
while (1)
{
// Stop parsing on end of line or comment
skip_whitespace(text);
if (*text == Ch('\0') || *text == Ch(';'))
{
if (state == s_data) // If there was no data set state to s_key
state = s_key;
break;
}
// Process according to current parser state
switch (state)
{
// Parser expects key
case s_key:
{
if (*text == Ch('{')) // Brace opening found
{
if (!last)
BOOST_PROPERTY_TREE_THROW(info_parser_error("unexpected {", "", 0));
stack.push(last);
last = NULL;
++text;
}
else if (*text == Ch('}')) // Brace closing found
{
if (stack.size() <= 1)
BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched }", "", 0));
stack.pop();
last = NULL;
++text;
}
else // Key text found
{
std::basic_string<Ch> key = read_key(text);
last = &stack.top()->push_back(std::make_pair(key, Ptree()))->second;
state = s_data;
}
}; break;
// Parser expects data
case s_data:
{
// Last ptree must be defined because we are going to add data to it
BOOST_ASSERT(last);
if (*text == Ch('{')) // Brace opening found
{
stack.push(last);
last = NULL;
++text;
state = s_key;
}
else if (*text == Ch('}')) // Brace closing found
{
if (stack.size() <= 1)
BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched }", "", 0));
stack.pop();
last = NULL;
++text;
state = s_key;
}
else // Data text found
{
bool need_more_lines;
std::basic_string<Ch> data = read_data(text, &need_more_lines);
last->data() = data;
state = need_more_lines ? s_data_cont : s_key;
}
}; break;
// Parser expects continuation of data after \ on previous line
case s_data_cont:
{
// Last ptree must be defined because we are going to update its data
BOOST_ASSERT(last);
if (*text == Ch('\"')) // Continuation must start with "
{
bool need_more_lines;
std::basic_string<Ch> data = read_string(text, &need_more_lines);
last->put_value(last->template get_value<std::basic_string<Ch> >() + data);
state = need_more_lines ? s_data_cont : s_key;
}
else
BOOST_PROPERTY_TREE_THROW(info_parser_error("expected \" after \\ in previous line", "", 0));
}; break;
// Should never happen
default:
BOOST_ASSERT(0);
}
}
}
// Check if stack has initial size, otherwise some {'s have not been closed
if (stack.size() != 1)
BOOST_PROPERTY_TREE_THROW(info_parser_error("unmatched {", "", 0));
}
catch (info_parser_error &e)
{
// If line undefined rethrow error with correct filename and line
if (e.line() == 0)
{
BOOST_PROPERTY_TREE_THROW(info_parser_error(e.message(), filename, line_no));
}
else
BOOST_PROPERTY_TREE_THROW(e);
}
}
} } }
#endif

View File

@@ -0,0 +1,32 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_CHCONV_HPP_INCLUDED
#include <string>
namespace boost { namespace property_tree { namespace info_parser
{
template<class ChDest, class ChSrc>
std::basic_string<ChDest> convert_chtype(const ChSrc *text)
{
std::basic_string<ChDest> result;
while (*text)
{
result += ChDest(*text);
++text;
}
return result;
}
} } }
#endif

View File

@@ -0,0 +1,147 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/detail/info_parser_utils.hpp"
#include <string>
namespace boost { namespace property_tree { namespace info_parser
{
template<class Ch>
void write_info_indent(std::basic_ostream<Ch> &stream,
int indent,
const info_writer_settings<Ch> &settings
)
{
stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
}
// Create necessary escape sequences from illegal characters
template<class Ch>
std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
{
std::basic_string<Ch> result;
typename std::basic_string<Ch>::const_iterator b = s.begin();
typename std::basic_string<Ch>::const_iterator e = s.end();
while (b != e)
{
if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
else if (*b == Ch('\a')) result += Ch('\\'), result += Ch('a');
else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
else if (*b == Ch('\v')) result += Ch('\\'), result += Ch('v');
else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
else
result += *b;
++b;
}
return result;
}
template<class Ch>
bool is_simple_key(const std::basic_string<Ch> &key)
{
const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
return !key.empty() && key.find_first_of(chars) == key.npos;
}
template<class Ch>
bool is_simple_data(const std::basic_string<Ch> &data)
{
const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
return !data.empty() && data.find_first_of(chars) == data.npos;
}
template<class Ptree>
void write_info_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
int indent,
const info_writer_settings<typename Ptree::key_type::value_type> &settings)
{
// Character type
typedef typename Ptree::key_type::value_type Ch;
// Write data
if (indent >= 0)
{
if (!pt.data().empty())
{
std::basic_string<Ch> data = create_escapes(pt.template get_value<std::basic_string<Ch> >());
if (is_simple_data(data))
stream << Ch(' ') << data << Ch('\n');
else
stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n');
}
else if (pt.empty())
stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
else
stream << Ch('\n');
}
// Write keys
if (!pt.empty())
{
// Open brace
if (indent >= 0)
{
write_info_indent( stream, indent, settings);
stream << Ch('{') << Ch('\n');
}
// Write keys
typename Ptree::const_iterator it = pt.begin();
for (; it != pt.end(); ++it)
{
// Output key
std::basic_string<Ch> key = create_escapes(it->first);
write_info_indent( stream, indent+1, settings);
if (is_simple_key(key))
stream << key;
else
stream << Ch('\"') << key << Ch('\"');
// Output data and children
write_info_helper(stream, it->second, indent + 1, settings);
}
// Close brace
if (indent >= 0)
{
write_info_indent( stream, indent, settings);
stream << Ch('}') << Ch('\n');
}
}
}
// Write ptree to info stream
template<class Ptree>
void write_info_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
const std::string &filename,
const info_writer_settings<typename Ptree::key_type::value_type> &settings)
{
write_info_helper(stream, pt, -1, settings);
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename, 0));
}
} } }
#endif

View File

@@ -0,0 +1,40 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
// Copyright (C) 2007 Alexey Baskakov
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITER_SETTINGS_HPP_INCLUDED
#include <string>
namespace boost { namespace property_tree { namespace info_parser
{
template <class Ch>
class info_writer_settings
{
public:
info_writer_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4):
indent_char(indent_char),
indent_count(indent_count)
{
}
Ch indent_char;
int indent_count;
};
template <class Ch>
info_writer_settings<Ch> info_writer_make_settings(Ch indent_char = Ch(' '), unsigned indent_count = 4)
{
return info_writer_settings<Ch>(indent_char, indent_count);
}
} } }
#endif

View File

@@ -0,0 +1,33 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_ERROR_HPP_INCLUDED
#include <boost/property_tree/detail/file_parser_error.hpp>
#include <string>
namespace boost { namespace property_tree { namespace json_parser
{
//! Json parser error
class json_parser_error: public file_parser_error
{
public:
json_parser_error(const std::string &message,
const std::string &filename,
unsigned long line):
file_parser_error(message, filename, line)
{
}
};
} } }
#endif

View File

@@ -0,0 +1,316 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_READ_HPP_INCLUDED
//#define BOOST_SPIRIT_DEBUG
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/ptree_utils.hpp>
#include <boost/property_tree/detail/json_parser_error.hpp>
#include <boost/spirit.hpp>
#include <string>
#include <locale>
#include <istream>
#include <vector>
#include <algorithm>
namespace boost { namespace property_tree { namespace json_parser
{
///////////////////////////////////////////////////////////////////////
// Json parser context
template<class Ptree>
struct context
{
typedef typename Ptree::key_type::value_type Ch;
typedef std::basic_string<Ch> Str;
typedef typename std::vector<Ch>::iterator It;
Str string;
Str name;
Ptree root;
std::vector<Ptree *> stack;
struct a_object_s
{
context &c;
a_object_s(context &c): c(c) { }
void operator()(Ch) const
{
if (c.stack.empty())
c.stack.push_back(&c.root);
else
{
Ptree *parent = c.stack.back();
Ptree *child = &parent->push_back(std::make_pair(c.name, Ptree()))->second;
c.stack.push_back(child);
c.name.clear();
}
}
};
struct a_object_e
{
context &c;
a_object_e(context &c): c(c) { }
void operator()(Ch) const
{
BOOST_ASSERT(c.stack.size() >= 1);
c.stack.pop_back();
}
};
struct a_name
{
context &c;
a_name(context &c): c(c) { }
void operator()(It, It) const
{
c.name.swap(c.string);
c.string.clear();
}
};
struct a_string_val
{
context &c;
a_string_val(context &c): c(c) { }
void operator()(It, It) const
{
BOOST_ASSERT(c.stack.size() >= 1);
c.stack.back()->push_back(std::make_pair(c.name, Ptree(c.string)));
c.name.clear();
c.string.clear();
}
};
struct a_literal_val
{
context &c;
a_literal_val(context &c): c(c) { }
void operator()(It b, It e) const
{
BOOST_ASSERT(c.stack.size() >= 1);
c.stack.back()->push_back(std::make_pair(c.name, Str(b, e)));
c.name.clear();
c.string.clear();
}
};
struct a_char
{
context &c;
a_char(context &c): c(c) { }
void operator()(It b, It e) const
{
c.string += *b;
}
};
struct a_escape
{
context &c;
a_escape(context &c): c(c) { }
void operator()(Ch ch) const
{
switch (ch)
{
case Ch('\"'): c.string += Ch('\"'); break;
case Ch('\\'): c.string += Ch('\\'); break;
case Ch('0'): c.string += Ch('\0'); break;
case Ch('b'): c.string += Ch('\b'); break;
case Ch('f'): c.string += Ch('\f'); break;
case Ch('n'): c.string += Ch('\n'); break;
case Ch('r'): c.string += Ch('\r'); break;
case Ch('t'): c.string += Ch('\t'); break;
default: BOOST_ASSERT(0);
}
}
};
struct a_unicode
{
context &c;
a_unicode(context &c): c(c) { }
void operator()(unsigned long u) const
{
u = (std::min)(u, static_cast<unsigned long>((std::numeric_limits<Ch>::max)()));
c.string += Ch(u);
}
};
};
///////////////////////////////////////////////////////////////////////
// Json grammar
template<class Ptree>
struct json_grammar: public boost::spirit::grammar<json_grammar<Ptree> >
{
typedef context<Ptree> Context;
typedef typename Ptree::key_type::value_type Ch;
mutable Context c;
template<class Scanner>
struct definition
{
boost::spirit::rule<Scanner> root, object, member, array, item, value, string, number;
boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> character, escape;
definition(const json_grammar &self)
{
using namespace boost::spirit;
// Assertions
assertion<std::string> expect_object("expected object");
assertion<std::string> expect_eoi("expected end of input");
assertion<std::string> expect_objclose("expected ',' or '}'");
assertion<std::string> expect_arrclose("expected ',' or ']'");
assertion<std::string> expect_name("expected object name");
assertion<std::string> expect_colon("expected ':'");
assertion<std::string> expect_value("expected value");
assertion<std::string> expect_escape("invalid escape sequence");
// JSON grammar rules
root
= expect_object(object)
>> expect_eoi(end_p)
;
object
= ch_p('{')[typename Context::a_object_s(self.c)]
>> (ch_p('}')[typename Context::a_object_e(self.c)]
| (list_p(member, ch_p(','))
>> expect_objclose(ch_p('}')[typename Context::a_object_e(self.c)])
)
)
;
member
= expect_name(string[typename Context::a_name(self.c)])
>> expect_colon(ch_p(':'))
>> expect_value(value)
;
array
= ch_p('[')[typename Context::a_object_s(self.c)]
>> (ch_p(']')[typename Context::a_object_e(self.c)]
| (list_p(item, ch_p(','))
>> expect_arrclose(ch_p(']')[typename Context::a_object_e(self.c)])
)
)
;
item
= expect_value(value)
;
value
= string[typename Context::a_string_val(self.c)]
| (number | str_p("true") | "false" | "null")[typename Context::a_literal_val(self.c)]
| object
| array
;
number
= strict_real_p
| int_p
;
string
= +(lexeme_d[confix_p('\"', *character, '\"')])
;
character
= (anychar_p - "\\" - "\"")[typename Context::a_char(self.c)]
| ch_p("\\") >> expect_escape(escape)
;
escape
= chset_p(detail::widen<Ch>("\"\\0bfnrt").c_str())[typename Context::a_escape(self.c)]
| 'u' >> uint_parser<unsigned long, 16, 4, 4>()[typename Context::a_unicode(self.c)]
;
// Debug
BOOST_SPIRIT_DEBUG_RULE(root);
BOOST_SPIRIT_DEBUG_RULE(object);
BOOST_SPIRIT_DEBUG_RULE(member);
BOOST_SPIRIT_DEBUG_RULE(array);
BOOST_SPIRIT_DEBUG_RULE(item);
BOOST_SPIRIT_DEBUG_RULE(value);
BOOST_SPIRIT_DEBUG_RULE(string);
BOOST_SPIRIT_DEBUG_RULE(number);
BOOST_SPIRIT_DEBUG_RULE(escape);
BOOST_SPIRIT_DEBUG_RULE(character);
}
const boost::spirit::rule<Scanner> &start() const
{
return root;
}
};
};
template<class It, class Ch>
unsigned long count_lines(It begin, It end)
{
return static_cast<unsigned long>(std::count(begin, end, Ch('\n')) + 1);
}
template<class Ptree>
void read_json_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
const std::string &filename)
{
using namespace boost::spirit;
typedef typename Ptree::key_type::value_type Ch;
typedef typename std::vector<Ch>::iterator It;
// Load data into vector
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
std::istreambuf_iterator<Ch>());
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(json_parser_error("read error", filename, 0));
// Prepare grammar
json_grammar<Ptree> g;
// Parse
try
{
parse_info<It> pi = parse(v.begin(), v.end(), g,
space_p | comment_p("//") | comment_p("/*", "*/"));
if (!pi.hit || !pi.full)
BOOST_PROPERTY_TREE_THROW((parser_error<std::string, It>(v.begin(), "syntax error")));
}
catch (parser_error<std::string, It> &e)
{
BOOST_PROPERTY_TREE_THROW(json_parser_error(e.descriptor, filename, count_lines<It, Ch>(v.begin(), e.where)));
}
// Swap grammar context root and pt
pt.swap(g.c.root);
}
} } }
#endif

View File

@@ -0,0 +1,164 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_JSON_PARSER_WRITE_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/next_prior.hpp>
#include <string>
#include <ostream>
#include <iomanip>
namespace boost { namespace property_tree { namespace json_parser
{
// Create necessary escape sequences from illegal characters
template<class Ch>
std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s,
const std::locale &loc)
{
std::basic_string<Ch> result;
typename std::basic_string<Ch>::const_iterator b = s.begin();
typename std::basic_string<Ch>::const_iterator e = s.end();
while (b != e)
{
if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
else
{
if (std::isprint(*b, loc))
result += *b;
else
{
const char *hexdigits = "0123456789ABCDEF";
unsigned long u = (std::min)(static_cast<unsigned long>(*b), 0xFFFFul);
int d1 = u / 4096; u -= d1 * 4096;
int d2 = u / 256; u -= d2 * 256;
int d3 = u / 16; u -= d3 * 16;
int d4 = u;
result += Ch('\\'); result += Ch('u');
result += Ch(hexdigits[d1]); result += Ch(hexdigits[d2]);
result += Ch(hexdigits[d3]); result += Ch(hexdigits[d4]);
}
}
++b;
}
return result;
}
template<class Ptree>
void write_json_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
int indent)
{
typedef typename Ptree::key_type::value_type Ch;
typedef typename std::basic_string<Ch> Str;
// Value or object or array
if (indent > 0 && pt.empty())
{
// Write value
Str data = create_escapes(pt.template get_value<Str>(), stream.getloc());
stream << Ch('"') << data << Ch('"');
}
else if (indent > 0 && pt.count(Str()) == pt.size())
{
// Write array
stream << Ch('[') << Ch('\n');
typename Ptree::const_iterator it = pt.begin();
for (; it != pt.end(); ++it)
{
stream << Str(4 * (indent + 1), Ch(' '));
write_json_helper(stream, it->second, indent + 1);
if (boost::next(it) != pt.end())
stream << Ch(',');
stream << Ch('\n');
}
stream << Str(4 * indent, Ch(' ')) << Ch(']');
}
else
{
// Write object
stream << Ch('{') << Ch('\n');
typename Ptree::const_iterator it = pt.begin();
for (; it != pt.end(); ++it)
{
stream << Str(4 * (indent + 1), Ch(' '));
stream << Ch('"') << create_escapes(it->first, stream.getloc()) << Ch('"') << Ch(':');
if (it->second.empty())
stream << Ch(' ');
else
stream << Ch('\n') << Str(4 * (indent + 1), Ch(' '));
write_json_helper(stream, it->second, indent + 1);
if (boost::next(it) != pt.end())
stream << Ch(',');
stream << Ch('\n');
}
stream << Str(4 * indent, Ch(' ')) << Ch('}');
}
}
// Verify if ptree does not contain information that cannot be written to json
template<class Ptree>
bool verify_json(const Ptree &pt, int depth)
{
typedef typename Ptree::key_type::value_type Ch;
typedef typename std::basic_string<Ch> Str;
// Root ptree cannot have data
if (depth == 0 && !pt.template get_value<Str>().empty())
return false;
// Ptree cannot have both children and data
if (!pt.template get_value<Str>().empty() && !pt.empty())
return false;
// Check children
typename Ptree::const_iterator it = pt.begin();
for (; it != pt.end(); ++it)
if (!verify_json(it->second, depth + 1))
return false;
// Success
return true;
}
// Write ptree to json stream
template<class Ptree>
void write_json_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
const std::string &filename)
{
if (!verify_json(pt, 0))
BOOST_PROPERTY_TREE_THROW(json_parser_error("ptree contains data that cannot be represented in JSON format", filename, 0));
write_json_helper(stream, pt, 0);
stream << std::endl;
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(json_parser_error("write error", filename, 0));
}
} } }
#endif

View File

@@ -0,0 +1,181 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_PATH_IMPLEMENTATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_PATH_IMPLEMENTATION_HPP_INCLUDED
namespace boost { namespace property_tree
{
namespace detail
{
// Path-to-string converter for basic_path
template<class Key>
std::string path_to_string(const basic_path<Key> &path)
{
return path.to_string();
}
}
///////////////////////////////////////////////////////////////////////
// Free functions
inline path operator /(const path &p1, const path &p2)
{
return path(p1) /= p2;
}
inline wpath operator /(const wpath &p1, const wpath &p2)
{
return wpath(p1) /= p2;
}
///////////////////////////////////////////////////////////////////////
// Construction & destruction
template<class Key>
basic_path<Key>::basic_path()
{
}
template<class Key>
basic_path<Key>::basic_path(const Key &path, char_type separator)
{
parse(path.begin(), path.end(), separator);
}
template<class Key>
basic_path<Key>::basic_path(const char_type *path, char_type separator)
{
parse(path, path + std::char_traits<char_type>::length(path), separator);
}
///////////////////////////////////////////////////////////////////////
// Path manipulation
template<class Key>
basic_path<Key> &basic_path<Key>::operator /=(const basic_path<Key> &rhs)
{
for (typename std::vector<Key>::const_iterator it = rhs.m_path.begin(); it != rhs.m_path.end(); ++it)
m_path.push_back(*it);
return *this;
}
template<class Key>
std::string basic_path<Key>::to_string() const
{
std::string s;
for (typename std::vector<Key>::const_iterator it = m_path.begin(); it != m_path.end(); ++it)
{
if (it == m_path.begin())
s += detail::narrow(it->c_str());
else
s += '.', s += detail::narrow(it->c_str());
}
return s;
}
///////////////////////////////////////////////////////////////////////
// Operations
template<class Key>
template<class C, class D, class X>
basic_ptree<C, Key, basic_path<Key>, D, X> *
basic_path<Key>::get_child(basic_ptree<C, Key, basic_path<Key>, D, X> &root) const
{
typedef basic_ptree<C, Key, basic_path<Key>, D, X> ptree_type;
ptree_type *pt = &root;
for (typename std::vector<Key>::const_iterator it = m_path.begin(); it != m_path.end(); ++it)
{
typename ptree_type::iterator it_child = pt->find(*it);
if (it_child == pt->end())
return 0;
else
pt = &(it_child->second);
}
return pt;
}
template<class Key>
template<class C, class D, class X>
const basic_ptree<C, Key, basic_path<Key>, D, X> *
basic_path<Key>::get_child(const basic_ptree<C, Key, basic_path<Key>, D, X> &root) const
{
typedef basic_ptree<C, Key, basic_path<Key>, D, X> ptree_type;
basic_path<Key> *nc_this = const_cast<basic_path<Key> *>(this);
ptree_type &nc_root = const_cast<ptree_type &>(root);
return nc_this->get_child(nc_root);
}
template<class Key>
template<class C, class D, class X>
basic_ptree<C, Key, basic_path<Key>, D, X> *
basic_path<Key>::put_child(basic_ptree<C, Key, basic_path<Key>, D, X> &root,
const basic_ptree<C, Key, basic_path<Key>, D, X> &child,
bool do_not_replace) const
{
if (m_path.empty())
{
return 0;
}
else
{
typedef basic_ptree<C, Key, basic_path<Key>, D, X> ptree_type;
typedef typename std::vector<Key>::const_iterator path_iterator;
ptree_type *pt = &root;
for (path_iterator it = m_path.begin(), end = m_path.end() - 1; it != end; ++it)
{
typename ptree_type::iterator it_child = pt->find(*it);
if (it_child == pt->end())
pt = &pt->push_back(typename ptree_type::value_type(*it, empty_ptree<ptree_type>()))->second;
else
pt = &it_child->second;
}
if (do_not_replace)
return &pt->push_back(typename ptree_type::value_type(m_path.back(), child))->second;
else
{
typename ptree_type::iterator it = pt->find(m_path.back());
if (it == pt->end())
return &pt->push_back(typename ptree_type::value_type(m_path.back(), child))->second;
else
{
it->second = child;
return &it->second;
}
}
}
}
///////////////////////////////////////////////////////////////////////
// Internal
template<class Key>
template<class RanIt>
void basic_path<Key>::parse(RanIt begin, RanIt end, char_type separator)
{
m_path.reserve(8);
while (1)
{
RanIt it = std::find(begin, end, separator);
m_path.push_back(Key(begin, it));
if (it == end)
break;
begin = it + 1;
}
}
} }
#endif

View File

@@ -0,0 +1,658 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_IMPLEMENTATION_HPP_INCLUDED
//////////////////////////////////////////////////////////////////////////////
// Debug macros
#ifdef BOOST_PROPERTY_TREE_DEBUG
// Increment instances counter
#define BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT() \
{ \
typedef boost::detail::lightweight_mutex::scoped_lock lock; \
lock l(debug_mutex); \
++debug_instances_count; \
}
// Decrement instances counter
#define BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT() \
{ \
typedef boost::detail::lightweight_mutex::scoped_lock lock; \
lock l(debug_mutex); \
BOOST_ASSERT(debug_instances_count > 0); \
--debug_instances_count; \
}
#else // BOOST_PROPERTY_TREE_DEBUG
#define BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT() static_cast<void>(0)
#define BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT() static_cast<void>(0)
#endif // BOOST_PROPERTY_TREE_DEBUG
namespace boost { namespace property_tree
{
///////////////////////////////////////////////////////////////////////////
// Construction & destruction
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X>::basic_ptree()
{
BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
}
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X>::basic_ptree(const data_type &rhs):
m_data(rhs)
{
BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
}
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X>::basic_ptree(const basic_ptree<C, K, P, D, X> &rhs)
{
m_data = rhs.m_data;
insert(end(), rhs.begin(), rhs.end());
BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT();
}
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X>::~basic_ptree()
{
BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT();
}
///////////////////////////////////////////////////////////////////////////
// Iterator access
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::begin()
{
return m_container.begin();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::const_iterator
basic_ptree<C, K, P, D, X>::begin() const
{
return m_container.begin();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::end()
{
return m_container.end();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::const_iterator
basic_ptree<C, K, P, D, X>::end() const
{
return m_container.end();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::reverse_iterator
basic_ptree<C, K, P, D, X>::rbegin()
{
return m_container.rbegin();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::const_reverse_iterator
basic_ptree<C, K, P, D, X>::rbegin() const
{
return m_container.rbegin();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::reverse_iterator
basic_ptree<C, K, P, D, X>::rend()
{
return m_container.rend();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::const_reverse_iterator
basic_ptree<C, K, P, D, X>::rend() const
{
return m_container.rend();
}
///////////////////////////////////////////////////////////////////////////
// Data access
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::size_type
basic_ptree<C, K, P, D, X>::size() const
{
return m_container.size();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::size_type
basic_ptree<C, K, P, D, X>::max_size() const
{
return m_container.max_size();
}
template<class C, class K, class P, class D, class X>
bool basic_ptree<C, K, P, D, X>::empty() const
{
return m_container.empty();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::data_type &
basic_ptree<C, K, P, D, X>::data()
{
return m_data;
}
template<class C, class K, class P, class D, class X>
const typename basic_ptree<C, K, P, D, X>::data_type &
basic_ptree<C, K, P, D, X>::data() const
{
return m_data;
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::value_type &
basic_ptree<C, K, P, D, X>::front()
{
return m_container.front();
}
template<class C, class K, class P, class D, class X>
const typename basic_ptree<C, K, P, D, X>::value_type &
basic_ptree<C, K, P, D, X>::front() const
{
return m_container.front();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::value_type &
basic_ptree<C, K, P, D, X>::back()
{
return m_container.back();
}
template<class C, class K, class P, class D, class X>
const typename basic_ptree<C, K, P, D, X>::value_type &
basic_ptree<C, K, P, D, X>::back() const
{
return m_container.back();
}
///////////////////////////////////////////////////////////////////////////
// Operators
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::operator =(const basic_ptree<C, K, P, D, X> &rhs)
{
if (&rhs != this)
{
clear();
data() = rhs.data();
insert(end(), rhs.begin(), rhs.end());
}
return *this;
}
template<class C, class K, class P, class D, class X>
bool basic_ptree<C, K, P, D, X>::operator ==(const basic_ptree<C, K, P, D, X> &rhs) const
{
// Data and sizes must be equal
if (size() != rhs.size() || data() != rhs.data())
return false;
// Keys and children must be equal
C comp;
const_iterator it = begin();
const_iterator it_rhs = rhs.begin();
const_iterator it_end = end();
for (; it != it_end; ++it, ++it_rhs)
if (comp(it->first, it_rhs->first)
|| comp(it_rhs->first, it->first)
|| it->second != it_rhs->second)
{
return false;
}
// Equal
return true;
}
template<class C, class K, class P, class D, class X>
bool basic_ptree<C, K, P, D, X>::operator !=(const basic_ptree<C, K, P, D, X> &rhs) const
{
return !operator ==(rhs);
}
///////////////////////////////////////////////////////////////////////////
// Container operations
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::find(const key_type &key)
{
C comp;
for (iterator it = begin(); it != end(); ++it)
if (!comp(it->first, key) && !comp(key, it->first))
return it;
return end();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::const_iterator
basic_ptree<C, K, P, D, X>::find(const key_type &key) const
{
C comp;
for (const_iterator it = begin(); it != end(); ++it)
if (!comp(it->first, key) && !comp(key, it->first))
return it;
return end();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::size_type
basic_ptree<C, K, P, D, X>::count(const key_type &key) const
{
C comp;
size_type count = 0;
for (const_iterator it = begin(); it != end(); ++it)
if (!comp(it->first, key) && !comp(key, it->first))
++count;
return count;
}
template<class C, class K, class P, class D, class X>
void basic_ptree<C, K, P, D, X>::clear()
{
m_data = data_type();
m_container.clear();
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::insert(iterator where,
const value_type &value)
{
return m_container.insert(where, value);
}
template<class C, class K, class P, class D, class X>
template<class It>
void basic_ptree<C, K, P, D, X>::insert(iterator where, It first, It last)
{
for (; first != last; ++first, ++where)
where = insert(where, value_type(first->first, first->second));
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::erase(iterator where)
{
return m_container.erase(where);
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::size_type
basic_ptree<C, K, P, D, X>::erase(const key_type &key)
{
C comp;
size_type count = 0;
iterator it = m_container.begin();
while (it != m_container.end())
{
if (!comp(it->first, key) && !comp(key, it->first))
{
it = erase(it);
++count;
}
else
++it;
}
return count;
}
template<class C, class K, class P, class D, class X>
template<class It>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::erase(It first, It last)
{
while (first != last)
first = erase(first);
return first;
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::push_front(const value_type &value)
{
return insert(begin(), value);
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::iterator
basic_ptree<C, K, P, D, X>::push_back(const value_type &value)
{
return insert(end(), value);
}
template<class C, class K, class P, class D, class X>
void basic_ptree<C, K, P, D, X>::pop_front()
{
erase(begin());
}
template<class C, class K, class P, class D, class X>
void basic_ptree<C, K, P, D, X>::pop_back()
{
iterator last = end();
--last;
erase(last);
}
template<class C, class K, class P, class D, class X>
void basic_ptree<C, K, P, D, X>::swap(basic_ptree<C, K, P, D, X> &rhs)
{
m_data.swap(rhs.m_data);
m_container.swap(rhs.m_container);
}
template<class C, class K, class P, class D, class X>
void basic_ptree<C, K, P, D, X>::reverse()
{
m_container.reverse();
}
template<class C, class K, class P, class D, class X>
template<class SortTr>
void basic_ptree<C, K, P, D, X>::sort(SortTr tr)
{
m_container.sort(tr);
}
///////////////////////////////////////////////////////////////////////////
// ptree operations
// Get child ptree
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::get_child(const path_type &path)
{
self_type *child = path.get_child(*this);
if (child)
return *child;
else
BOOST_PROPERTY_TREE_THROW(ptree_bad_path("path does not exist", path));
}
// Get child ptree
template<class C, class K, class P, class D, class X>
const basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::get_child(const path_type &path) const
{
self_type *nc_this = const_cast<self_type *>(this);
return nc_this->get_child(path);
}
// Get child ptree
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::get_child(const path_type &path,
basic_ptree<C, K, P, D, X> &default_value)
{
self_type *child = path.get_child(*this);
if (child)
return *child;
else
return default_value;
}
// Get child ptree
template<class C, class K, class P, class D, class X>
const basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::get_child(const path_type &path,
const basic_ptree<C, K, P, D, X> &default_value) const
{
self_type *nc_this = const_cast<self_type *>(this);
self_type &nc_default_value = const_cast<self_type &>(default_value);
return nc_this->get_child(path, nc_default_value);
}
// Get child ptree
template<class C, class K, class P, class D, class X>
optional<basic_ptree<C, K, P, D, X> &>
basic_ptree<C, K, P, D, X>::get_child_optional(const path_type &path)
{
self_type *child = path.get_child(*this);
if (child)
return optional<self_type &>(*child);
else
return optional<self_type &>();
}
// Get child ptree
template<class C, class K, class P, class D, class X>
optional<const basic_ptree<C, K, P, D, X> &>
basic_ptree<C, K, P, D, X>::get_child_optional(const path_type &path) const
{
self_type *nc_this = const_cast<self_type *>(this);
optional<self_type &> tmp = nc_this->get_child_optional(path);
if (tmp)
return optional<const self_type &>(tmp.get());
else
return optional<const self_type &>();
}
// Put child ptree
template<class C, class K, class P, class D, class X>
basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::put_child(const path_type &path,
const basic_ptree<C, K, P, D, X> &value,
bool do_not_replace)
{
self_type *child = path.put_child(*this, value, do_not_replace);
if (child)
return *child;
else
BOOST_PROPERTY_TREE_THROW(ptree_bad_path("path does not exist", path));
}
// Get value from data of ptree
template<class C, class K, class P, class D, class X>
template<class Type>
Type basic_ptree<C, K, P, D, X>::get_value(const translator_type &x) const
{
BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false); // Disallow pointer types, they are unsafe
Type value;
if (x.get_value(*this, value))
return value;
else
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of data into type \"") +
typeid(Type).name() + "\" failed", data()));
}
// Get value from data of ptree
template<class C, class K, class P, class D, class X>
template<class Type>
Type basic_ptree<C, K, P, D, X>::get_value(const Type &default_value,
const translator_type &x) const
{
BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false); // Disallow pointer types, they are unsafe
Type value;
if (x.get_value(*this, value))
return value;
else
return default_value;
}
// Get value from data of ptree
template<class C, class K, class P, class D, class X>
template<class CharType>
std::basic_string<CharType>
basic_ptree<C, K, P, D, X>::get_value(const CharType *default_value,
const translator_type &x) const
{
return get_value(std::basic_string<CharType>(default_value), x);
}
// Get value from data of ptree
template<class C, class K, class P, class D, class X>
template<class Type>
optional<Type>
basic_ptree<C, K, P, D, X>::get_value_optional(const translator_type &x) const
{
BOOST_STATIC_ASSERT(boost::is_pointer<Type>::value == false); // Disallow pointer types, they are unsafe
Type value;
if (x.get_value(*this, value))
return optional<Type>(value);
else
return optional<Type>();
}
// Get value from data of child ptree
template<class C, class K, class P, class D, class X>
template<class Type>
Type basic_ptree<C, K, P, D, X>::get(const path_type &path,
const translator_type &x) const
{
return get_child(path).get_value<Type>(x);
}
// Get value from data of child ptree
template<class C, class K, class P, class D, class X>
template<class Type>
Type basic_ptree<C, K, P, D, X>::get(const path_type &path,
const Type &default_value,
const translator_type &x) const
{
if (optional<Type> result = get_optional<Type>(path, x))
return *result;
else
return default_value;
}
// Get value from data of child ptree
template<class C, class K, class P, class D, class X>
template<class CharType>
std::basic_string<CharType>
basic_ptree<C, K, P, D, X>::get(const path_type &path,
const CharType *default_value,
const translator_type &x) const
{
return get(path, std::basic_string<CharType>(default_value), x);
}
// Get value from data of child ptree
template<class C, class K, class P, class D, class X>
template<class Type>
optional<Type>
basic_ptree<C, K, P, D, X>::get_optional(const path_type &path,
const translator_type &x) const
{
if (optional<const basic_ptree<C, K, P, D, X> &> child = get_child_optional(path))
return child.get().get_value_optional<Type>(x);
else
return optional<Type>();
}
// Put value in data of ptree
template<class C, class K, class P, class D, class X>
template<class Type>
void basic_ptree<C, K, P, D, X>::put_value(const Type &value, const translator_type &x)
{
if (!x.put_value(*this, value))
BOOST_PROPERTY_TREE_THROW(ptree_bad_data(std::string("conversion of type \"") + typeid(Type).name() +
"\" into data failed", boost::any()));
}
// Put value in data of child ptree
template<class C, class K, class P, class D, class X>
template<class Type>
basic_ptree<C, K, P, D, X> &
basic_ptree<C, K, P, D, X>::put(const path_type &path,
const Type &value,
bool do_not_replace,
const translator_type &x)
{
optional<self_type &> child;
if (!do_not_replace && (child = get_child_optional(path)))
{
child.get().put_value(value, x);
return *child;
}
else
{
self_type &child2 = put_child(path, empty_ptree<self_type>(), do_not_replace);
child2.put_value(value, x);
return child2;
}
}
////////////////////////////////////////////////////////////////////////////
// Debugging
#ifdef BOOST_PROPERTY_TREE_DEBUG
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::size_type
basic_ptree<C, K, P, D, X>::debug_get_instances_count()
{
empty_ptree<basic_ptree<C, K, P, D, X> >(); // Make sure empty ptree exists
return debug_instances_count - 1; // Do not count empty ptree
}
template<class C, class K, class P, class D, class X>
typename basic_ptree<C, K, P, D, X>::size_type
basic_ptree<C, K, P, D, X>::debug_instances_count;
template<class C, class K, class P, class D, class X>
boost::detail::lightweight_mutex
basic_ptree<C, K, P, D, X>::debug_mutex;
#endif
///////////////////////////////////////////////////////////////////////////
// Free functions
template<class Ptree>
inline const Ptree &empty_ptree()
{
static Ptree pt;
return pt;
}
template<class C, class K, class P, class D, class X>
inline void swap(basic_ptree<C, K, P, D, X> &pt1, basic_ptree<C, K, P, D, X> &pt2)
{
pt1.swap(pt2);
}
} }
// Undefine debug macros
#ifdef BOOST_PROPERTY_TREE_DEBUG
# undef BOOST_PROPERTY_TREE_DEBUG_INCREMENT_INSTANCES_COUNT
# undef BOOST_PROPERTY_TREE_DEBUG_DECREMENT_INSTANCES_COUNT
#endif
#endif

View File

@@ -0,0 +1,87 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_PTREE_UTILS_HPP_INCLUDED
#include <string>
#include <algorithm>
#include <locale>
namespace boost { namespace property_tree { namespace detail
{
template<class T>
struct less_nocase
{
typedef typename T::value_type Ch;
std::locale m_locale;
inline bool operator()(Ch c1, Ch c2) const
{
return std::toupper(c1, m_locale) < std::toupper(c2, m_locale);
}
inline bool operator()(const T &t1, const T &t2) const
{
return std::lexicographical_compare(t1.begin(), t1.end(), t2.begin(), t2.end(), *this);
}
};
// Naively convert narrow string to another character type
template<class Ch>
std::basic_string<Ch> widen(const char *text)
{
std::basic_string<Ch> result;
while (*text)
{
result += Ch(*text);
++text;
}
return result;
}
// Naively convert string to narrow character type
template<class Ch>
std::string narrow(const Ch *text)
{
std::locale loc;
std::string result;
while (*text)
{
if (*text < 0 || *text > (std::numeric_limits<char>::max)())
result += '*';
else
result += char(*text);
++text;
}
return result;
}
// Remove trailing and leading spaces
template<class Ch>
std::basic_string<Ch> trim(const std::basic_string<Ch> &s,
const std::locale &loc = std::locale())
{
typename std::basic_string<Ch>::const_iterator first = s.begin();
typename std::basic_string<Ch>::const_iterator end = s.end();
while (first != end && std::isspace(*first, loc))
++first;
if (first == end)
return std::basic_string<Ch>();
typename std::basic_string<Ch>::const_iterator last = end;
do --last; while (std::isspace(*last, loc));
if (first != s.begin() || last + 1 != end)
return std::basic_string<Ch>(first, last + 1);
else
return s;
}
} } }
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,277 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_TRANSLATOR_IMPLEMENTATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_TRANSLATOR_IMPLEMENTATION_HPP_INCLUDED
namespace boost { namespace property_tree
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////
// Helpers
// Data-to-string converter for std::string
inline std::string data_to_string(const std::string &data)
{
return data;
}
// Data-to-string converter for std::basic_string<Ch>
template<class Ch>
std::string data_to_string(const std::basic_string<Ch> &data)
{
return narrow(data.c_str());
}
template<class T>
struct array_to_pointer_decay
{
typedef T type;
};
template<class T, std::size_t N>
struct array_to_pointer_decay<T[N]>
{
typedef const T *type;
};
////////////////////////////////////////////////////////////////////////////
// Extractor
// Various specializations of extractors and inserters are provided to:
// 1. Optimize use of strings by copying them directly instead through stringstream
// 2. Optimize use of native char (i.e the same char as used by data string) by copying
// it directly instead of through stringstream
// 3. Treat signed and unsigned chars as integers, not as characters, i.e.
// pt.put_value(signed char(65)) produces data equal to "65", instead of "A".
// Only plain char is treated as a character type, i.e pt.put_value(char(65)) will
// produce "A"
// 4. Allow recognizing various bool strings (0, 1, true, false)
template<class Ch, class T>
struct extractor
{
inline bool operator()(const std::basic_string<Ch> &data,
T &extracted,
const std::locale &loc) const
{
std::basic_istringstream<Ch> stream(data);
stream.imbue(loc);
stream >> extracted;
if (!stream.eof())
stream >> std::ws;
return stream.eof() && !stream.fail() && !stream.bad();
}
};
template<class Ch>
struct extractor<Ch, std::basic_string<Ch> >
{
inline bool operator()(const std::basic_string<Ch> &data,
std::basic_string<Ch> &extracted,
const std::locale &loc) const
{
extracted = data;
return true;
}
};
template<class Ch>
struct extractor<Ch, Ch>
{
inline bool operator()(const std::basic_string<Ch> &data,
Ch &extracted,
const std::locale &loc) const
{
if (data.size() == 1)
{
extracted = data[0];
return true;
}
else
return false;
}
};
template<class Ch>
struct extractor<Ch, signed char>
{
inline bool operator()(const std::basic_string<Ch> &data,
signed char &extracted,
const std::locale &loc) const
{
std::basic_istringstream<Ch> stream(data);
stream.imbue(loc);
int tmp;
stream >> tmp;
if (!stream.eof())
stream >> std::ws;
if (stream.eof() && !stream.fail() && !stream.bad())
{
extracted = static_cast<signed char>(tmp);
return true;
}
else
return false;
}
};
template<class Ch>
struct extractor<Ch, unsigned char>
{
inline bool operator()(const std::basic_string<Ch> &data,
unsigned char &extracted,
const std::locale &loc) const
{
std::basic_istringstream<Ch> stream(data);
stream.imbue(loc);
unsigned int tmp;
stream >> tmp;
if (!stream.eof())
stream >> std::ws;
if (stream.eof() && !stream.fail() && !stream.bad())
{
extracted = static_cast<unsigned char>(tmp);
return true;
}
else
return false;
}
};
template<class Ch>
struct extractor<Ch, bool>
{
inline bool operator()(const std::basic_string<Ch> &data,
bool &extracted,
const std::locale &loc) const
{
std::basic_istringstream<Ch> stream(data);
stream.imbue(loc);
bool tmp;
stream >> std::boolalpha >> tmp;
if (!stream.eof())
stream >> std::ws;
if (stream.eof() && !stream.fail() && !stream.bad())
{
extracted = tmp;
return true;
}
else
{
std::basic_istringstream<Ch> stream2(data);
stream2.imbue(loc);
bool tmp;
stream2 >> tmp;
if (!stream2.eof())
stream >> std::ws;
if (stream2.eof() && !stream2.fail() && !stream2.bad())
{
extracted = tmp;
return true;
}
}
return false;
}
};
////////////////////////////////////////////////////////////////////////////
// Inserter
template<class Ch, class T>
struct inserter
{
inline bool operator()(std::basic_string<Ch> &data,
const T &to_insert,
const std::locale &loc) const
{
typedef typename detail::array_to_pointer_decay<T>::type T2;
std::basic_ostringstream<Ch> stream;
stream.imbue(loc);
if (std::numeric_limits<T2>::is_specialized
&& !std::numeric_limits<T2>::is_exact)
stream.precision(std::numeric_limits<T2>::digits10 + 1);
stream << std::boolalpha << to_insert;
data = stream.str();
return !stream.fail() && !stream.bad();
}
};
template<class Ch>
struct inserter<Ch, signed char>
{
inline bool operator()(std::basic_string<Ch> &data,
const signed char &to_insert,
const std::locale &loc) const
{
return detail::inserter<Ch, int>()(data, static_cast<int>(to_insert), loc);
}
};
template<class Ch>
struct inserter<Ch, unsigned char>
{
inline bool operator()(std::basic_string<Ch> &data,
const unsigned char &to_insert,
const std::locale &loc) const
{
return detail::inserter<Ch, unsigned int>()(data, static_cast<unsigned int>(to_insert), loc);
}
};
template<class Ch>
struct inserter<Ch, std::basic_string<Ch> >
{
inline bool operator()(std::basic_string<Ch> &data,
const std::basic_string<Ch> &to_insert,
const std::locale &loc) const
{
data = to_insert;
return true;
}
};
}
inline translator::translator()
{
}
inline translator::translator(const std::locale &loc):
m_locale(loc)
{
}
template<class Ptree, class T>
bool translator::get_value(const Ptree &pt, T &value) const
{
typedef typename Ptree::data_type::value_type Ch;
return detail::extractor<Ch, T>()(pt.data(), value, m_locale);
}
template<class Ptree, class T>
bool translator::put_value(Ptree &pt, const T &value) const
{
typedef typename Ptree::data_type::value_type Ch;
// Make sure that no pointer other than char_type * is allowed
BOOST_STATIC_ASSERT((is_pointer<T>::value == false ||
is_same<Ch, typename remove_const<typename remove_pointer<T>::type>::type>::value == true));
return detail::inserter<Ch, T>()(pt.data(), value, m_locale);
}
} }
#endif

View File

@@ -0,0 +1,33 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_ERROR_HPP_INCLUDED
#include <boost/property_tree/detail/file_parser_error.hpp>
#include <string>
namespace boost { namespace property_tree { namespace xml_parser
{
//! Xml parser error
class xml_parser_error: public file_parser_error
{
public:
xml_parser_error(const std::string &message,
const std::string &filename,
unsigned long line):
file_parser_error(message, filename, line)
{
}
};
} } }
#endif

View File

@@ -0,0 +1,26 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_FLAGS_HPP_INCLUDED
namespace boost { namespace property_tree { namespace xml_parser
{
static const int no_concat_text = 1; // Text elements should be put in separate keys, not concatenated in parent data
static const int no_comments = 2; // Comments should be omitted
inline bool validate_flags(int flags)
{
return (flags & ~(no_concat_text | no_comments)) == 0;
}
} } }
#endif

View File

@@ -0,0 +1,106 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2006-2007 Alexey Baskakov
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
// PugiXML-based parser. To enable it define
// BOOST_PROPERTY_TREE_XML_PARSER_PUGIXML before including xml_parser.hpp file.
//
// PugiXML library has to be obtained separately.
// Check it out at http://code.google.com/p/pugixml/
//
// This module is derived from an example shipped as part of
// the PugiXML documentation. This example contains the following notice:
// Copyright (C) 2006, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_PUGIXML_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_PUGIXML_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_flags.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <pugixml.hpp>
namespace boost { namespace property_tree { namespace xml_parser
{
template<class Ptree>
void read_xml_node( pugi::xml_node node, Ptree &pt, int flags)
{
typedef typename Ptree::key_type::value_type Ch;
switch ( node.type() )
{
case pugi::node_element:
{
Ptree &tmp = pt.push_back(std::make_pair( node.name(), Ptree()))->second;
for ( pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute() )
tmp.put( xmlattr<Ch>() + "." + attr.name(), attr.value());
for ( pugi::xml_node child = node.first_child(); child; child = child.next_sibling())
read_xml_node(child, tmp, flags);
}
break;
case pugi::node_pcdata:
{
if (flags & no_concat_text)
pt.push_back(std::make_pair(xmltext<Ch>(), Ptree( node.value() )));
else
pt.data() += node.value();
}
break;
case pugi::node_comment:
{
if (!(flags & no_comments))
pt.push_back(std::make_pair(xmlcomment<Ch>(), Ptree( node.value() )));
}
break;
default:
// skip other types
break;
}
}
template<class Ptree>
void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags,
const std::string &filename)
{
typedef typename Ptree::key_type::value_type Ch;
// Create and load document from stream
stream.unsetf(std::ios::skipws);
if (!stream.good())
throw xml_parser_error("read error", filename, 0);
std::vector<Ch> buf;
std::copy(std::istream_iterator<Ch>(stream), std::istream_iterator<Ch>(), std::back_inserter(buf));
buf.push_back(0); // zero-terminate
unsigned int pugi_flags = pugi::parse_w3c;
if ( flags & no_comments )
pugi_flags = pugi_flags & ~pugi::parse_comments;
pugi::xml_parser parser(&buf[0], pugi_flags);
pugi::xml_node doc = parser.document();
// Create ptree from nodes
Ptree local;
for ( pugi::xml_node child = doc.first_child(); child; child = child.next_sibling())
read_xml_node( child, local, flags );
// Swap local and result ptrees
pt.swap(local);
}
} } }
#endif

View File

@@ -0,0 +1,82 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_PUGXML_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_PUGXML_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_flags.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <boost/property_tree/detail/pugxml.hpp>
namespace boost { namespace property_tree { namespace xml_parser
{
template<class Ptree>
void read_xml_node(pug::xml_node node, Ptree &pt, int flags)
{
typedef typename Ptree::key_type::value_type Ch;
if (node.type() == pug::node_element ||
node.type() == pug::node_document)
{
Ptree &tmp = pt.push_back(std::make_pair(node.name(), empty_ptree<Ptree>()))->second;
for (pug::xml_node::attribute_iterator it = node.attributes_begin(); it != node.attributes_end(); ++it)
tmp.put(xmlattr<Ch>() + Ch('.') + it->name(), it->value());
for (pug::xml_node::child_iterator it = node.children_begin(); it != node.children_end(); ++it)
read_xml_node(*it, tmp, flags);
}
else if (node.type() == pug::node_pcdata)
{
if (flags & no_concat_text)
pt.push_back(std::make_pair(xmltext<Ch>(), Ptree(node.value())));
else
pt.data() += node.value();
}
else if (node.type() == pug::node_comment)
{
if (!(flags & no_comments))
pt.push_back(std::make_pair(xmlcomment<Ch>(), Ptree(node.value())));
}
}
template<class Ptree>
void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags,
const std::string &filename)
{
typedef typename Ptree::key_type::value_type Ch;
// Load data into vector
std::vector<Ch> data(std::istreambuf_iterator<Ch>(stream.rdbuf()),
std::istreambuf_iterator<Ch>());
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename, 0));
data.push_back(Ch('\0'));
// Parse
pug::xml_parser parser;
if (parser.parse(&data.front()))
{
Ptree local;
pug::xml_node doc = parser.document();
for (pug::xml_node::child_iterator it = doc.children_begin(); it != doc.children_end(); ++it)
read_xml_node(*it, local, flags);
local.swap(pt);
}
else
BOOST_PROPERTY_TREE_THROW(xml_parser_error("parse error", filename, 0));
}
} } }
#endif

View File

@@ -0,0 +1,117 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2007 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_flags.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <boost/property_tree/detail/rapidxml.hpp>
namespace boost { namespace property_tree { namespace xml_parser
{
template<class Ptree, class Ch>
void read_xml_node(rapidxml::xml_node<Ch> *node, Ptree &pt, int flags)
{
switch (node->type())
{
// Element nodes
case rapidxml::node_element:
{
// Create node
Ptree &pt_node = pt.push_back(std::make_pair(node->name(), Ptree()))->second;
// Copy attributes
if (node->first_attribute())
{
Ptree &pt_attr_root = pt_node.push_back(std::make_pair(xmlattr<Ch>(), Ptree()))->second;
for (rapidxml::xml_attribute<Ch> *attr = node->first_attribute(); attr; attr = attr->next_attribute())
{
Ptree &pt_attr = pt_attr_root.push_back(std::make_pair(attr->name(), Ptree()))->second;
pt_attr.data() = attr->value();
}
}
// Copy children
for (rapidxml::xml_node<Ch> *child = node->first_child(); child; child = child->next_sibling())
read_xml_node(child, pt_node, flags);
}
break;
// Data nodes
case rapidxml::node_data:
{
if (flags & no_concat_text)
pt.push_back(std::make_pair(xmltext<Ch>(), Ptree(node->value())));
else
pt.data() += node->value();
}
break;
// Comment nodes
case rapidxml::node_comment:
{
if (!(flags & no_comments))
pt.push_back(std::make_pair(xmlcomment<Ch>(), Ptree(node->value())));
}
break;
default:
// Skip other node types
break;
}
}
template<class Ptree>
void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags,
const std::string &filename)
{
typedef typename Ptree::key_type::value_type Ch;
// Load data into vector
stream.unsetf(std::ios::skipws);
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
std::istreambuf_iterator<Ch>());
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename, 0));
v.push_back(0); // zero-terminate
try
{
// Parse using appropriate flags
using namespace rapidxml;
xml_document<Ch> doc;
if (flags & no_comments)
doc.parse<parse_normalize_whitespace>(&v.front());
else
doc.parse<parse_normalize_whitespace | parse_comment_nodes>(&v.front());
// Create ptree from nodes
Ptree local;
for (rapidxml::xml_node<Ch> *child = doc.first_child(); child; child = child->next_sibling())
read_xml_node(child, local, flags);
// Swap local and result ptrees
pt.swap(local);
}
catch (rapidxml::parse_error &e)
{
long line = static_cast<long>(std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
BOOST_PROPERTY_TREE_THROW(xml_parser_error(e.what(), filename, line));
}
}
} } }
#endif

View File

@@ -0,0 +1,733 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// Based on XML grammar by Daniel C. Nuffer
// http://spirit.sourceforge.net/repository/applications/xml.zip
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_SPIRIT_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_SPIRIT_HPP_INCLUDED
//#define BOOST_SPIRIT_DEBUG
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_flags.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <boost/spirit.hpp>
#include <boost/spirit/iterator/position_iterator.hpp>
#include <string>
#include <locale>
#include <istream>
#include <vector>
namespace boost { namespace property_tree { namespace xml_parser
{
// XML parser context
template<class Ptree>
struct context
{
typedef typename Ptree::key_type::value_type Ch;
typedef std::basic_string<Ch> Str;
typedef typename Ptree::path_type Path;
typedef boost::spirit::position_iterator<typename std::vector<Ch>::const_iterator> It;
int flags;
std::vector<Ptree *> stack;
///////////////////////////////////////////////////////////////////////
// Actions
struct a_key_s
{
context &c;
a_key_s(context &c): c(c) { }
void operator()(It b, It e) const
{
if (c.stack.empty())
BOOST_PROPERTY_TREE_THROW(xml_parser_error("xml parse error",
detail::narrow(b.get_position().file.c_str()),
b.get_position().line));
Str name(b, e);
Ptree *child = &c.stack.back()->push_back(std::make_pair(name, Ptree()))->second;
c.stack.push_back(child);
}
};
struct a_key_e
{
context &c;
a_key_e(context &c): c(c) { }
void operator()(It b, It e) const
{
if (c.stack.size() <= 1)
BOOST_PROPERTY_TREE_THROW(xml_parser_error("xml parse error",
detail::narrow(b.get_position().file.c_str()),
b.get_position().line));
c.stack.pop_back();
}
};
struct a_content
{
context &c;
a_content(context &c): c(c) { }
void operator()(It b, It e) const
{
Str s = decode_char_entities(detail::trim(condense(Str(b, e))));
if (!s.empty())
{
if (c.flags & no_concat_text)
c.stack.back()->push_back(std::make_pair(xmltext<Ch>(), Ptree(s)));
else
c.stack.back()->put_value(c.stack.back()->template get_value<std::basic_string<Ch> >() + s);
}
}
};
struct a_attr_key
{
context &c;
a_attr_key(context &c): c(c) { }
void operator()(It b, It e) const
{
Path p(xmlattr<Ch>());
p /= Str(b, e);
c.stack.back()->put_child(p, empty_ptree<Ptree>());
}
};
struct a_attr_data
{
context &c;
a_attr_data(context &c): c(c) { }
void operator()(It b, It e) const
{
Ptree &attr = c.stack.back()->get_child(xmlattr<Ch>());
attr.back().second.put_value(Str(b + 1, e - 1));
}
};
struct a_comment
{
context &c;
a_comment(context &c): c(c) { }
void operator()(It b, It e) const
{
c.stack.back()->push_back(std::make_pair(xmlcomment<Ch>(), Ptree(Str(b, e))));
}
};
};
///////////////////////////////////////////////////////////////////////
// Grammar
template<class Ptree>
struct xml_grammar: public boost::spirit::grammar<xml_grammar<Ptree> >
{
typedef context<Ptree> context_t;
mutable context_t c;
template<class ScannerT>
struct definition
{
typedef typename ScannerT::value_t char_t;
typedef boost::spirit::chset<char_t> chset_t;
boost::spirit::rule<ScannerT>
prolog, element, Misc, PEReference, Reference, PITarget, CData,
doctypedecl, XMLDecl, SDDecl, VersionInfo, EncodingDecl, VersionNum,
Eq, DeclSep, ExternalID, markupdecl, NotationDecl, EntityDecl,
AttlistDecl, elementdecl, TextDecl, extSubsetDecl, conditionalSect,
EmptyElemTag, STag, content, ETag, Attribute, contentspec, Mixed,
children, choice, seq, cp, AttDef, AttType, DefaultDecl, StringType,
TokenizedType, EnumeratedType, NotationType, Enumeration, EntityValue,
AttValue, SystemLiteral, PubidLiteral, CharDataChar, CharData, Comment,
PI, CDSect, extSubset, includeSect, ignoreSect, ignoreSectContents,
Ignore, CharRef, EntityRef, GEDecl, PEDecl, EntityDef, PEDef,
NDataDecl, extParsedEnt, EncName, PublicID, document, S, Name, Names,
Nmtoken, Nmtokens, STagB, STagE1, STagE2;
definition(const xml_grammar &self)
{
using namespace boost::spirit;
// XML Char sets
chset_t Char("\x9\xA\xD\x20-\x7F");
chset_t Sch("\x20\x9\xD\xA");
chset_t Letter("\x41-\x5A\x61-\x7A");
chset_t Digit("0-9");
chset_t XDigit("0-9A-Fa-f");
chset_t Extender("\xB7");
chset_t NameChar =
Letter
| Digit
| (char_t)'.'
| (char_t)'-'
| (char_t)'_'
| (char_t)':'
| Extender;
document =
prolog >> element >> *Misc
;
S =
+(Sch)
;
Name =
(Letter | '_' | ':')
>> *(NameChar)
;
Names =
Name >> *(S >> Name)
;
Nmtoken =
+NameChar
;
Nmtokens =
Nmtoken >> *(S >> Nmtoken)
;
EntityValue =
'"' >> *( (anychar_p - (chset_t(detail::widen<char_t>("%&\"").c_str())))
| PEReference
| Reference)
>> '"'
| '\'' >> *( (anychar_p - (chset_t("%&'")))
| PEReference
| Reference)
>> '\''
;
AttValue =
'"' >> *( (anychar_p - (chset_t("<&\"")))
| Reference)
>> '"'
| '\'' >> *( (anychar_p - (chset_t("<&'")))
| Reference)
>> '\''
;
SystemLiteral=
('"' >> *(anychar_p - '"') >> '"')
| ('\'' >> *(anychar_p - '\'') >> '\'')
;
chset_t PubidChar("\x20\xD\xA'a-zA-Z0-9()+,./:=?;!*#@$_%-");
PubidLiteral =
'"' >> *PubidChar >> '"'
| '\'' >> *(PubidChar - '\'') >> '\''
;
CharDataChar =
//anychar_p - (chset_t("<&"))
anychar_p - (chset_t("<"))
;
CharData =
*(CharDataChar - "]]>")
;
Comment =
"<!--" >>
(
*(
(Char - '-')
| ('-' >> (Char - '-'))
)
)[typename context_t::a_comment(self.c)]
>> "-->"
;
PI =
"<?" >> PITarget >> !(S >> (*(Char - "?>"))) >> "?>"
;
PITarget =
Name - (as_lower_d["xml"])
;
CDSect =
"<![CDATA[" >> CData >> "]]>"
;
CData =
*(Char - "]]>")
;
prolog =
!XMLDecl >> *Misc >> !(doctypedecl >> *Misc)
;
XMLDecl =
"<?xml" >> VersionInfo >> !EncodingDecl >> !SDDecl
>> !S >> "?>"
;
VersionInfo =
S >> "version" >> Eq >>
(
'\'' >> VersionNum >> '\''
| '"' >> VersionNum >> '"'
)
;
Eq =
!S >> '=' >> !S
;
chset_t VersionNumCh("a-zA-Z0-9_.:-");
VersionNum =
+(VersionNumCh)
;
Misc =
Comment
| PI
| S
;
doctypedecl =
"<!DOCTYPE" >> S >> Name >> !(S >> ExternalID) >> !S >>
!(
'[' >> *(markupdecl | DeclSep) >> ']' >> !S
)
>> '>'
;
DeclSep =
PEReference
| S
;
markupdecl =
elementdecl
| AttlistDecl
| EntityDecl
| NotationDecl
| PI
| Comment
;
extSubset =
!TextDecl >> extSubsetDecl
;
extSubsetDecl =
*(
markupdecl
| conditionalSect
| DeclSep
)
;
SDDecl =
S >> "standalone" >> Eq >>
(
('\'' >> (str_p("yes") | "no") >> '\'')
| ('"' >> (str_p("yes") | "no") >> '"')
)
;
/*
element =
EmptyElemTag
| STag >> content >> ETag
;
*/
element =
STagB >> (STagE2 | (STagE1 >> content >> ETag))[typename context_t::a_key_e(self.c)]
;
STag =
'<' >> Name >> *(S >> Attribute) >> !S >> '>'
;
STagB =
'<'
>> Name[typename context_t::a_key_s(self.c)]
>> *(S >> Attribute)
>> !S
;
STagE1 =
ch_p(">")
;
STagE2 =
str_p("/>")
;
Attribute =
Name[typename context_t::a_attr_key(self.c)]
>> Eq
>> AttValue[typename context_t::a_attr_data(self.c)]
;
ETag =
"</" >> Name >> !S >> '>'
;
content =
!(CharData[typename context_t::a_content(self.c)]) >>
*(
(
element
// | Reference
| CDSect
| PI
| Comment
) >>
!(CharData[typename context_t::a_content(self.c)])
)
;
EmptyElemTag =
'<' >> Name >> *(S >> Attribute) >> !S >> "/>"
;
elementdecl =
"<!ELEMENT" >> S >> Name >> S >> contentspec >> !S >> '>'
;
contentspec =
str_p("EMPTY")
| "ANY"
| Mixed
| children
;
children =
(choice | seq) >> !(ch_p('?') | '*' | '+')
;
cp =
(Name | choice | seq) >> !(ch_p('?') | '*' | '+')
;
choice =
'(' >> !S >> cp
>> +(!S >> '|' >> !S >> cp)
>> !S >> ')'
;
seq =
'(' >> !S >> cp >>
*(!S >> ',' >> !S >> cp)
>> !S >> ')'
;
Mixed =
'(' >> !S >> "#PCDATA"
>> *(!S >> '|' >> !S >> Name)
>> !S >> ")*"
| '(' >> !S >> "#PCDATA" >> !S >> ')'
;
AttlistDecl =
"<!ATTLIST" >> S >> Name >> *AttDef >> !S >> '>'
;
AttDef =
S >> Name >> S >> AttType >> S >> DefaultDecl
;
AttType =
StringType
| TokenizedType
| EnumeratedType
;
StringType =
str_p("CDATA")
;
TokenizedType =
longest_d[
str_p("ID")
| "IDREF"
| "IDREFS"
| "ENTITY"
| "ENTITIES"
| "NMTOKEN"
| "NMTOKENS"
]
;
EnumeratedType =
NotationType
| Enumeration
;
NotationType =
"NOTATION" >> S >> '(' >> !S >> Name
>> *(!S >> '|' >> !S >> Name)
>> !S >> ')'
;
Enumeration =
'(' >> !S >> Nmtoken
>> *(!S >> '|' >> !S >> Nmtoken)
>> !S >> ')'
;
DefaultDecl =
str_p("#REQUIRED")
| "#IMPLIED"
| !("#FIXED" >> S) >> AttValue
;
conditionalSect =
includeSect
| ignoreSect
;
includeSect =
"<![" >> !S >> "INCLUDE" >> !S
>> '[' >> extSubsetDecl >> "]]>"
;
ignoreSect =
"<![" >> !S >> "IGNORE" >> !S
>> '[' >> *ignoreSectContents >> "]]>"
;
ignoreSectContents =
Ignore >> *("<![" >> ignoreSectContents >> "]]>" >> Ignore)
;
Ignore =
*(Char - (str_p("<![") | "]]>"))
;
CharRef =
"&#" >> +Digit >> ';'
| "&#x" >> +XDigit >> ';'
;
Reference =
EntityRef
| CharRef
;
EntityRef =
'&' >> Name >> ';'
;
PEReference =
'%' >> Name >> ';'
;
EntityDecl =
GEDecl
| PEDecl
;
GEDecl =
"<!ENTITY" >> S >> Name >> S >> EntityDef >> !S >> '>'
;
PEDecl =
"<!ENTITY" >> S >> '%' >> S >> Name >> S >> PEDef
>> !S >> '>'
;
EntityDef =
EntityValue
| ExternalID >> !NDataDecl
;
PEDef =
EntityValue
| ExternalID
;
ExternalID =
"SYSTEM" >> S >> SystemLiteral
| "PUBLIC" >> S >> PubidLiteral >> S >> SystemLiteral
;
NDataDecl =
S >> "NDATA" >> S >> Name
;
TextDecl =
"<?xml" >> !VersionInfo >> EncodingDecl >> !S >> "?>"
;
extParsedEnt =
!TextDecl >> content
;
EncodingDecl =
S >> "encoding" >> Eq
>> ( '"' >> EncName >> '"'
| '\'' >> EncName >> '\''
)
;
EncName =
Letter >> *(Letter | Digit | '.' | '_' | '-')
;
NotationDecl =
"<!NOTATION" >> S >> Name >> S
>> (ExternalID | PublicID) >> !S >> '>'
;
PublicID =
"PUBLIC" >> S >> PubidLiteral
;
BOOST_SPIRIT_DEBUG_RULE(document);
BOOST_SPIRIT_DEBUG_RULE(prolog);
BOOST_SPIRIT_DEBUG_RULE(element);
BOOST_SPIRIT_DEBUG_RULE(Misc);
BOOST_SPIRIT_DEBUG_RULE(PEReference);
BOOST_SPIRIT_DEBUG_RULE(Reference);
BOOST_SPIRIT_DEBUG_RULE(PITarget);
BOOST_SPIRIT_DEBUG_RULE(CData);
BOOST_SPIRIT_DEBUG_RULE(doctypedecl);
BOOST_SPIRIT_DEBUG_RULE(XMLDecl);
BOOST_SPIRIT_DEBUG_RULE(SDDecl);
BOOST_SPIRIT_DEBUG_RULE(VersionInfo);
BOOST_SPIRIT_DEBUG_RULE(EncodingDecl);
BOOST_SPIRIT_DEBUG_RULE(VersionNum);
BOOST_SPIRIT_DEBUG_RULE(Eq);
BOOST_SPIRIT_DEBUG_RULE(DeclSep);
BOOST_SPIRIT_DEBUG_RULE(ExternalID);
BOOST_SPIRIT_DEBUG_RULE(markupdecl);
BOOST_SPIRIT_DEBUG_RULE(NotationDecl);
BOOST_SPIRIT_DEBUG_RULE(EntityDecl);
BOOST_SPIRIT_DEBUG_RULE(AttlistDecl);
BOOST_SPIRIT_DEBUG_RULE(elementdecl);
BOOST_SPIRIT_DEBUG_RULE(TextDecl);
BOOST_SPIRIT_DEBUG_RULE(extSubsetDecl);
BOOST_SPIRIT_DEBUG_RULE(conditionalSect);
BOOST_SPIRIT_DEBUG_RULE(EmptyElemTag);
BOOST_SPIRIT_DEBUG_RULE(STag);
BOOST_SPIRIT_DEBUG_RULE(content);
BOOST_SPIRIT_DEBUG_RULE(ETag);
BOOST_SPIRIT_DEBUG_RULE(Attribute);
BOOST_SPIRIT_DEBUG_RULE(contentspec);
BOOST_SPIRIT_DEBUG_RULE(Mixed);
BOOST_SPIRIT_DEBUG_RULE(children);
BOOST_SPIRIT_DEBUG_RULE(choice);
BOOST_SPIRIT_DEBUG_RULE(seq);
BOOST_SPIRIT_DEBUG_RULE(cp);
BOOST_SPIRIT_DEBUG_RULE(AttDef);
BOOST_SPIRIT_DEBUG_RULE(AttType);
BOOST_SPIRIT_DEBUG_RULE(DefaultDecl);
BOOST_SPIRIT_DEBUG_RULE(StringType);
BOOST_SPIRIT_DEBUG_RULE(TokenizedType);
BOOST_SPIRIT_DEBUG_RULE(EnumeratedType);
BOOST_SPIRIT_DEBUG_RULE(NotationType);
BOOST_SPIRIT_DEBUG_RULE(Enumeration);
BOOST_SPIRIT_DEBUG_RULE(EntityValue);
BOOST_SPIRIT_DEBUG_RULE(AttValue);
BOOST_SPIRIT_DEBUG_RULE(SystemLiteral);
BOOST_SPIRIT_DEBUG_RULE(PubidLiteral);
BOOST_SPIRIT_DEBUG_RULE(CharDataChar);
BOOST_SPIRIT_DEBUG_RULE(CharData);
BOOST_SPIRIT_DEBUG_RULE(Comment);
BOOST_SPIRIT_DEBUG_RULE(PI);
BOOST_SPIRIT_DEBUG_RULE(CDSect);
BOOST_SPIRIT_DEBUG_RULE(extSubset);
BOOST_SPIRIT_DEBUG_RULE(includeSect);
BOOST_SPIRIT_DEBUG_RULE(ignoreSect);
BOOST_SPIRIT_DEBUG_RULE(ignoreSectContents);
BOOST_SPIRIT_DEBUG_RULE(Ignore);
BOOST_SPIRIT_DEBUG_RULE(CharRef);
BOOST_SPIRIT_DEBUG_RULE(EntityRef);
BOOST_SPIRIT_DEBUG_RULE(GEDecl);
BOOST_SPIRIT_DEBUG_RULE(PEDecl);
BOOST_SPIRIT_DEBUG_RULE(EntityDef);
BOOST_SPIRIT_DEBUG_RULE(PEDef);
BOOST_SPIRIT_DEBUG_RULE(NDataDecl);
BOOST_SPIRIT_DEBUG_RULE(extParsedEnt);
BOOST_SPIRIT_DEBUG_RULE(EncName);
BOOST_SPIRIT_DEBUG_RULE(PublicID);
BOOST_SPIRIT_DEBUG_RULE(document);
BOOST_SPIRIT_DEBUG_RULE(S);
BOOST_SPIRIT_DEBUG_RULE(Name);
BOOST_SPIRIT_DEBUG_RULE(Names);
BOOST_SPIRIT_DEBUG_RULE(Nmtoken);
BOOST_SPIRIT_DEBUG_RULE(Nmtokens);
BOOST_SPIRIT_DEBUG_RULE(STagB);
BOOST_SPIRIT_DEBUG_RULE(STagE1);
BOOST_SPIRIT_DEBUG_RULE(STagE2);
}
const boost::spirit::rule<ScannerT> &start() const
{
return document;
}
};
};
template<class Ptree>
void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags,
const std::string &filename)
{
typedef typename Ptree::key_type::value_type Ch;
typedef boost::spirit::position_iterator<typename std::vector<Ch>::const_iterator> It;
BOOST_ASSERT(validate_flags(flags));
// Load data into vector
std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
std::istreambuf_iterator<Ch>());
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename, 0));
// Initialize iterators
It begin(v.begin(), v.end());
It end;
begin.set_position(detail::widen<Ch>(filename.c_str()));
// Prepare grammar
Ptree local;
xml_grammar<Ptree> g;
g.c.stack.push_back(&local); // Push root ptree on context stack
g.c.flags = flags;
// Parse into local
boost::spirit::parse_info<It> result = boost::spirit::parse(begin, end, g);
if (!result.full || g.c.stack.size() != 1)
BOOST_PROPERTY_TREE_THROW(xml_parser_error("xml parse error",
detail::narrow(result.stop.get_position().file.c_str()),
result.stop.get_position().line));
// Swap local and pt
pt.swap(local);
}
} } }
#endif

View File

@@ -0,0 +1,143 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_TINYXML_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_TINYXML_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_flags.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <tinyxml.h>
namespace boost { namespace property_tree { namespace xml_parser
{
#ifdef TIXML_USE_STL
template<class Ptree>
void read_xml_node(TiXmlNode *node, Ptree &pt, int flags)
{
typedef typename Ptree::key_type::value_type Ch;
if (TiXmlElement *elem = node->ToElement())
{
Ptree &tmp = pt.push_back(std::make_pair(elem->Value(), Ptree()))->second;
for (TiXmlAttribute *attr = elem->FirstAttribute(); attr; attr = attr->Next())
tmp.put(xmlattr<Ch>() + Ch('.') + attr->Name(), attr->Value());
for (TiXmlNode *child = node->FirstChild(); child; child = child->NextSibling())
read_xml_node(child, tmp, flags);
}
else if (TiXmlText *text = node->ToText())
{
if (flags & no_concat_text)
pt.push_back(std::make_pair(xmltext<Ch>(), Ptree(text->Value())));
else
pt.data() += text->Value();
}
else if (TiXmlComment *comment = node->ToComment())
{
if (!(flags & no_comments))
pt.push_back(std::make_pair(xmlcomment<Ch>(), Ptree(comment->Value())));
}
}
template<class Ptree>
void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags,
const std::string &filename)
{
// Create and load document from stream
TiXmlDocument doc;
stream >> doc;
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename, 0));
if (doc.Error())
BOOST_PROPERTY_TREE_THROW(xml_parser_error(doc.ErrorDesc(), filename, doc.ErrorRow()));
// Create ptree from nodes
Ptree local;
for (TiXmlNode *child = doc.FirstChild(); child; child = child->NextSibling())
read_xml_node(child, local, flags);
// Swap local and result ptrees
pt.swap(local);
}
#else
template<class Ptree>
void read_xml_node(TiXmlNode *node, Ptree &pt, int flags)
{
typedef typename Ptree::key_type::value_type Ch;
if (TiXmlElement *elem = node->ToElement())
{
Ptree &tmp = pt.push_back(std::make_pair(elem->Value(), Ptree()))->second;
for (TiXmlAttribute *attr = elem->FirstAttribute(); attr; attr = attr->Next())
tmp.put(xmlattr<Ch>() + Ch('.') + attr->Name(), attr->Value());
for (TiXmlNode *child = node->FirstChild(); child; child = child->NextSibling())
read_xml_node(child, tmp, flags);
}
else if (TiXmlText *text = node->ToText())
{
if (flags & no_concat_text)
pt.push_back(std::make_pair(xmltext<Ch>(), Ptree(text->Value())));
else
pt.data() += text->Value();
}
else if (TiXmlComment *comment = node->ToComment())
{
if (!(flags & no_comments))
pt.push_back(std::make_pair(xmlcomment<Ch>(), Ptree(comment->Value())));
}
}
template<class Ptree>
void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags,
const std::string &filename)
{
// Load data into vector
typedef typename Ptree::key_type::value_type Ch;
std::vector<Ch> data(std::istreambuf_iterator<Ch>(stream.rdbuf()),
std::istreambuf_iterator<Ch>());
if (!stream.good())
BOOST_PROPERTY_TREE_THROW(xml_parser_error("read error", filename, 0));
data.push_back(Ch('\0'));
// Create and load document
TiXmlDocument doc;
doc.Parse(&data.front());
if (doc.Error())
BOOST_PROPERTY_TREE_THROW(xml_parser_error(doc.ErrorDesc(), filename, doc.ErrorRow()));
// Create ptree from nodes
Ptree local;
for (TiXmlNode *child = doc.FirstChild(); child; child = child->NextSibling())
read_xml_node(child, local, flags);
// Swap local and result ptrees
pt.swap(local);
}
#endif
} } }
#endif

View File

@@ -0,0 +1,124 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_UTILS_HPP_INCLUDED
#include <boost/property_tree/detail/ptree_utils.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_writer_settings.hpp>
#include <string>
#include <algorithm>
#include <locale>
namespace boost { namespace property_tree { namespace xml_parser
{
template<class Ch>
std::basic_string<Ch> condense(const std::basic_string<Ch> &s)
{
std::basic_string<Ch> r;
std::locale loc;
bool space = false;
typename std::basic_string<Ch>::const_iterator end = s.end();
for (typename std::basic_string<Ch>::const_iterator it = s.begin();
it != end; ++it)
{
if (isspace(*it, loc) || *it == Ch('\n'))
{
if (!space)
r += Ch(' '), space = true;
}
else
r += *it, space = false;
}
return r;
}
template<class Ch>
std::basic_string<Ch> encode_char_entities(const std::basic_string<Ch> &s)
{
typedef typename std::basic_string<Ch> Str;
Str r;
typename Str::const_iterator end = s.end();
for (typename Str::const_iterator it = s.begin(); it != end; ++it)
{
switch (*it)
{
case Ch('<'): r += detail::widen<Ch>("&lt;"); break;
case Ch('>'): r += detail::widen<Ch>("&gt;"); break;
case Ch('&'): r += detail::widen<Ch>("&amp;"); break;
case Ch('"'): r += detail::widen<Ch>("&quot;"); break;
case Ch('\''): r += detail::widen<Ch>("&apos;"); break;
default: r += *it; break;
}
}
return r;
}
template<class Ch>
std::basic_string<Ch> decode_char_entities(const std::basic_string<Ch> &s)
{
typedef typename std::basic_string<Ch> Str;
Str r;
typename Str::const_iterator end = s.end();
for (typename Str::const_iterator it = s.begin(); it != end; ++it)
{
if (*it == Ch('&'))
{
typename Str::const_iterator semicolon = std::find(it + 1, end, Ch(';'));
if (semicolon == end)
BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0));
Str ent(it + 1, semicolon);
if (ent == detail::widen<Ch>("lt")) r += Ch('<');
else if (ent == detail::widen<Ch>("gt")) r += Ch('>');
else if (ent == detail::widen<Ch>("amp")) r += Ch('&');
else if (ent == detail::widen<Ch>("quot")) r += Ch('"');
else if (ent == detail::widen<Ch>("apos")) r += Ch('\'');
else
BOOST_PROPERTY_TREE_THROW(xml_parser_error("invalid character entity", "", 0));
it = semicolon;
}
else
r += *it;
}
return r;
}
template<class Ch>
const std::basic_string<Ch> &xmldecl()
{
static std::basic_string<Ch> s = detail::widen<Ch>("<?xml>");
return s;
}
template<class Ch>
const std::basic_string<Ch> &xmlattr()
{
static std::basic_string<Ch> s = detail::widen<Ch>("<xmlattr>");
return s;
}
template<class Ch>
const std::basic_string<Ch> &xmlcomment()
{
static std::basic_string<Ch> s = detail::widen<Ch>("<xmlcomment>");
return s;
}
template<class Ch>
const std::basic_string<Ch> &xmltext()
{
static std::basic_string<Ch> s = detail::widen<Ch>("<xmltext>");
return s;
}
} } }
#endif

View File

@@ -0,0 +1,176 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_utils.hpp>
#include <string>
#include <ostream>
#include <iomanip>
namespace boost { namespace property_tree { namespace xml_parser
{
template<class Ch>
void write_xml_indent(std::basic_ostream<Ch> &stream,
int indent,
const xml_writer_settings<Ch> & settings
)
{
stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
}
template<class Ch>
void write_xml_comment(std::basic_ostream<Ch> &stream,
const std::basic_string<Ch> &s,
int indent,
const xml_writer_settings<Ch> & settings
)
{
typedef typename std::basic_string<Ch> Str;
write_xml_indent(stream,indent,settings);
stream << Ch('<') << Ch('!') << Ch('-') << Ch('-');
stream << s;
stream << Ch('-') << Ch('-') << Ch('>') << std::endl;
}
template<class Ch>
void write_xml_text(std::basic_ostream<Ch> &stream,
const std::basic_string<Ch> &s,
int indent,
bool separate_line,
const xml_writer_settings<Ch> & settings
)
{
if (separate_line)
write_xml_indent(stream,indent,settings);
stream << encode_char_entities(s);
if (separate_line)
stream << Ch('\n');
}
template<class Ptree>
void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const std::basic_string<typename Ptree::key_type::value_type> &key,
const Ptree &pt,
int indent,
const xml_writer_settings<typename Ptree::key_type::value_type> & settings)
{
typedef typename Ptree::key_type::value_type Ch;
typedef typename std::basic_string<Ch> Str;
typedef typename Ptree::const_iterator It;
// Find if elements present
bool has_elements = false;
bool has_attrs_only = pt.data().empty();
for (It it = pt.begin(), end = pt.end(); it != end; ++it)
{
if (it->first != xmlattr<Ch>() )
{
has_attrs_only = false;
if (it->first != xmltext<Ch>())
{
has_elements = true;
break;
}
}
}
// Write element
if (pt.data().empty() && pt.empty()) // Empty key
{
if (indent >= 0)
{
write_xml_indent(stream,indent,settings);
stream << Ch('<') << key <<
Ch('/') << Ch('>') << std::endl;
}
}
else // Nonempty key
{
// Write opening tag, attributes and data
if (indent >= 0)
{
// Write opening brace and key
write_xml_indent(stream,indent,settings);
stream << Ch('<') << key;
// Write attributes
if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Ch>()))
for (It it = attribs.get().begin(); it != attribs.get().end(); ++it)
stream << Ch(' ') << it->first << Ch('=') <<
Ch('"') << it->second.template get_value<std::basic_string<Ch> >() << Ch('"');
if ( has_attrs_only )
{
// Write closing brace
stream << Ch('/') << Ch('>') << std::endl;
}
else
{
// Write closing brace
stream << Ch('>');
// Break line if needed
if (has_elements)
stream << Ch('\n');
}
}
// Write data text, if present
if (!pt.data().empty())
write_xml_text(stream, pt.template get_value<std::basic_string<Ch> >(), indent + 1, has_elements, settings);
// Write elements, comments and texts
for (It it = pt.begin(); it != pt.end(); ++it)
{
if (it->first == xmlattr<Ch>())
continue;
else if (it->first == xmlcomment<Ch>())
write_xml_comment(stream, it->second.template get_value<std::basic_string<Ch> >(), indent + 1, settings);
else if (it->first == xmltext<Ch>())
write_xml_text(stream, it->second.template get_value<std::basic_string<Ch> >(), indent + 1, has_elements, settings);
else
write_xml_element(stream, it->first, it->second, indent + 1, settings);
}
// Write closing tag
if (indent >= 0 && !has_attrs_only)
{
if (has_elements)
write_xml_indent(stream,indent,settings);
stream << Ch('<') << Ch('/') << key << Ch('>') << std::endl;
}
}
}
template<class Ptree>
void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
const std::string &filename,
const xml_writer_settings<typename Ptree::key_type::value_type> & settings)
{
typedef typename Ptree::key_type::value_type Ch;
typedef typename std::basic_string<Ch> Str;
stream << detail::widen<Ch>("<?xml version=\"1.0\" encoding=\"")
<< settings.encoding
<< detail::widen<Ch>("\"?>\n");
write_xml_element(stream, Str(), pt, -1, settings);
if (!stream)
BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0));
}
} } }
#endif

View File

@@ -0,0 +1,60 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2007 Marcin Kalicinski
// Copyright (C) 2007 Alexey Baskakov
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITER_SETTINGS_HPP_INCLUDED
#include <string>
#include <boost/property_tree/detail/ptree_utils.hpp>
namespace boost { namespace property_tree { namespace xml_parser
{
// Naively convert narrow string to another character type
template<class Ch>
std::basic_string<Ch> widen(const char *text)
{
std::basic_string<Ch> result;
while (*text)
{
result += Ch(*text);
++text;
}
return result;
}
//! Xml writer settings
template<class Ch>
class xml_writer_settings
{
public:
xml_writer_settings(Ch indent_char = Ch(' '),
typename std::basic_string<Ch>::size_type indent_count = 4,
const std::basic_string<Ch> &encoding = widen<Ch>("utf-8"))
: indent_char(indent_char)
, indent_count(indent_count)
, encoding(encoding)
{
}
const Ch indent_char;
const typename std::basic_string<Ch>::size_type indent_count;
const std::basic_string<Ch> encoding;
};
template <class Ch>
xml_writer_settings<Ch> xml_writer_make_settings(Ch indent_char, typename std::basic_string<Ch>::size_type indent_count, const Ch *encoding)
{
return xml_writer_settings<Ch>(indent_char, indent_count, encoding);
}
} } }
#endif

View File

@@ -0,0 +1,115 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_INFO_PARSER_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/info_parser_error.hpp>
#include <boost/property_tree/detail/info_parser_writer_settings.hpp>
#include <boost/property_tree/detail/info_parser_read.hpp>
#include <boost/property_tree/detail/info_parser_write.hpp>
#include <istream>
namespace boost { namespace property_tree { namespace info_parser
{
// Read info from stream
template<class Ptree, class Ch>
void read_info(std::basic_istream<Ch> &stream,
Ptree &pt)
{
Ptree local;
read_info_internal(stream, local, std::string(), 0);
pt.swap(local);
}
// Read info from stream with default
template<class Ptree, class Ch>
void read_info(std::basic_istream<Ch> &stream,
Ptree &pt,
const Ptree &default_ptree)
{
try
{
read_info(stream, pt);
}
catch (file_parser_error &)
{
pt = default_ptree;
}
}
// Read info from file
template<class Ptree>
void read_info(const std::string &filename,
Ptree &pt,
const std::locale &loc = std::locale())
{
std::basic_ifstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(info_parser_error("cannot open file for reading", filename, 0));
stream.imbue(loc);
Ptree local;
read_info_internal(stream, local, filename, 0);
pt.swap(local);
}
// Read info from file with default
template<class Ptree>
void read_info(const std::string &filename,
Ptree &pt,
const Ptree &default_ptree,
const std::locale &loc = std::locale())
{
try
{
read_info(filename, pt, loc);
}
catch (file_parser_error &)
{
pt = default_ptree;
}
}
// Write info to stream
template<class Ptree, class Ch>
void write_info(std::basic_ostream<Ch> &stream,
const Ptree &pt,
const info_writer_settings<Ch> &settings=info_writer_settings<Ch>())
{
write_info_internal(stream, pt, std::string(), settings);
}
// Write info to file
template<class Ptree>
void write_info(const std::string &filename,
const Ptree &pt,
const std::locale &loc = std::locale(),
const info_writer_settings<typename Ptree::key_type::value_type> &settings = info_writer_make_settings<typename Ptree::key_type::value_type>())
{
std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(info_parser_error("cannot open file for writing", filename, 0));
stream.imbue(loc);
write_info_internal(stream, pt, filename, settings);
}
} } }
namespace boost { namespace property_tree
{
using info_parser::info_parser_error;
using info_parser::read_info;
using info_parser::write_info;
using info_parser::info_writer_settings;
using info_parser::info_writer_make_settings;
} }
#endif

View File

@@ -0,0 +1,196 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_INI_PARSER_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_INI_PARSER_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/ptree_utils.hpp>
#include <boost/property_tree/detail/file_parser_error.hpp>
#include <fstream>
#include <string>
#include <sstream>
#include <stdexcept>
#include <locale>
namespace boost { namespace property_tree { namespace ini_parser
{
static const int skip_ini_validity_check = 1; // Skip check if ptree is a valid ini
inline bool validate_flags(int flags)
{
return (flags & ~skip_ini_validity_check) == 0;
}
//! Ini parser error
class ini_parser_error: public file_parser_error
{
public:
ini_parser_error(const std::string &message,
const std::string &filename,
unsigned long line):
file_parser_error(message, filename, line)
{
}
};
//! Read ini from stream
template<class Ptree>
void read_ini(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt)
{
typedef typename Ptree::key_type::value_type Ch;
typedef std::basic_string<Ch> Str;
Ptree local;
unsigned long line_no = 0;
Ptree *section = 0;
Str line;
// For all lines
while (stream.good())
{
// Get line from stream
++line_no;
std::getline(stream, line);
if (!stream.good() && !stream.eof())
BOOST_PROPERTY_TREE_THROW(ini_parser_error("read error", "", line_no));
// If line is non-empty
line = detail::trim(line, stream.getloc());
if (!line.empty())
{
// Comment, section or key?
if (line[0] == Ch(';'))
{
// Ignore comments
}
else if (line[0] == Ch('['))
{
typename Str::size_type end = line.find(Ch(']'));
if (end == Str::npos)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("unmatched '['", "", line_no));
Str key = detail::trim(line.substr(1, end - 1), stream.getloc());
if (local.find(key) != local.end())
BOOST_PROPERTY_TREE_THROW(ini_parser_error("duplicate section name", "", line_no));
section = &local.push_back(std::make_pair(key, Ptree()))->second;
}
else
{
if (!section)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("section expected", "", line_no));
typename Str::size_type eqpos = line.find(Ch('='));
if (eqpos == Str::npos)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("'=' character not found in line", "", line_no));
if (eqpos == 0)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("key expected", "", line_no));
Str key = detail::trim(line.substr(0, eqpos), stream.getloc());
Str data = detail::trim(line.substr(eqpos + 1, Str::npos), stream.getloc());
if (section->find(key) != section->end())
BOOST_PROPERTY_TREE_THROW(ini_parser_error("duplicate key name", "", line_no));
section->push_back(std::make_pair(key, Ptree(data)));
}
}
}
// Swap local ptree with result ptree
pt.swap(local);
}
//! Read ini from file
template<class Ptree>
void read_ini(const std::string &filename,
Ptree &pt,
const std::locale &loc = std::locale())
{
std::basic_ifstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("cannot open file", filename, 0));
stream.imbue(loc);
try {
read_ini(stream, pt);
}
catch (ini_parser_error &e) {
BOOST_PROPERTY_TREE_THROW(ini_parser_error(e.message(), filename, e.line()));
}
}
//! Write ini to stream
template<class Ptree>
void write_ini(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
int flags = 0)
{
typedef typename Ptree::key_type::value_type Ch;
typedef std::basic_string<Ch> Str;
BOOST_ASSERT(validate_flags(flags));
// Verify if ptree is not too rich to be saved as ini
if (!(flags & skip_ini_validity_check))
for (typename Ptree::const_iterator it = pt.begin(), end = pt.end(); it != end; ++it)
{
if (!it->second.data().empty())
BOOST_PROPERTY_TREE_THROW(ini_parser_error("ptree has data on root level keys", "", 0));
if (pt.count(it->first) > 1)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("duplicate section name", "", 0));
for (typename Ptree::const_iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; ++it2)
{
if (!it2->second.empty())
BOOST_PROPERTY_TREE_THROW(ini_parser_error("ptree is too deep", "", 0));
if (it->second.count(it2->first) > 1)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("duplicate key name", "", 0));
}
}
// Write ini
for (typename Ptree::const_iterator it = pt.begin(), end = pt.end(); it != end; ++it)
{
stream << Ch('[') << it->first << Ch(']') << Ch('\n');
for (typename Ptree::const_iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; ++it2)
stream << it2->first << Ch('=') << it2->second.template get_value<std::basic_string<Ch> >() << Ch('\n');
}
}
// Write ini to file
template<class Ptree>
void write_ini(const std::string &filename,
const Ptree &pt,
int flags = 0,
const std::locale &loc = std::locale())
{
std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(ini_parser_error("cannot open file", filename, 0));
stream.imbue(loc);
try {
write_ini(stream, pt, flags);
}
catch (ini_parser_error &e) {
BOOST_PROPERTY_TREE_THROW(ini_parser_error(e.message(), filename, e.line()));
}
}
} } }
namespace boost { namespace property_tree
{
using ini_parser::ini_parser_error;
using ini_parser::read_ini;
using ini_parser::write_ini;
} }
#endif

View File

@@ -0,0 +1,76 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_JSON_PARSER_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/json_parser_read.hpp>
#include <boost/property_tree/detail/json_parser_write.hpp>
#include <boost/property_tree/detail/json_parser_error.hpp>
#include <fstream>
#include <string>
#include <locale>
namespace boost { namespace property_tree { namespace json_parser
{
// Read json from stream
template<class Ptree>
void read_json(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt)
{
read_json_internal(stream, pt, std::string());
}
// Read json from file
template<class Ptree>
void read_json(const std::string &filename,
Ptree &pt,
const std::locale &loc = std::locale())
{
std::basic_ifstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(json_parser_error("cannot open file", filename, 0));
stream.imbue(loc);
read_json_internal(stream, pt, filename);
}
// Write json to stream
template<class Ptree>
void write_json(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt)
{
write_json_internal(stream, pt, std::string());
}
// Write json to file
template<class Ptree>
void write_json(const std::string &filename,
const Ptree &pt,
const std::locale &loc = std::locale())
{
std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(json_parser_error("cannot open file", filename, 0));
stream.imbue(loc);
write_json_internal(stream, pt, filename);
}
} } }
namespace boost { namespace property_tree
{
using json_parser::read_json;
using json_parser::write_json;
using json_parser::json_parser_error;
} }
#endif

View File

@@ -0,0 +1,325 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_PTREE_HPP_INCLUDED
#include <boost/property_tree/ptree_fwd.hpp> // Must be the first include, because of config.hpp
#include <boost/assert.hpp>
#include <boost/optional.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/any.hpp>
#include <boost/throw_exception.hpp>
#ifdef BOOST_PROPERTY_TREE_DEBUG
# include <boost/detail/lightweight_mutex.hpp> // For syncing debug instances counter
#endif
#include <functional> // for std::less
#include <limits>
#include <list>
#include <sstream>
#include <stdexcept>
#include <utility> // for std::pair
#include <vector>
#include <cstdlib>
// Throwing macro to avoid no return warnings portably
#define BOOST_PROPERTY_TREE_THROW(e) { throw_exception(e); std::exit(1); }
namespace boost { namespace property_tree
{
template<class C, class K, class P, class D, class X>
class basic_ptree
{
private:
// Internal types
typedef basic_ptree<C, K, P, D, X> self_type;
public:
// Basic types
typedef C key_compare;
typedef K key_type;
typedef P path_type;
typedef D data_type;
typedef X translator_type;
typedef std::pair<key_type, self_type> value_type;
private:
// Internal types
typedef std::list<value_type> container_type;
public:
// Container-related types
typedef typename container_type::size_type size_type;
typedef typename container_type::iterator iterator;
typedef typename container_type::const_iterator const_iterator;
typedef typename container_type::reverse_iterator reverse_iterator;
typedef typename container_type::const_reverse_iterator const_reverse_iterator;
public:
///////////////////////////////////////////////////////////////////////////
// Construction & destruction
basic_ptree();
explicit basic_ptree(const data_type &data);
basic_ptree(const self_type &rhs);
~basic_ptree();
///////////////////////////////////////////////////////////////////////////
// Iterator access
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
///////////////////////////////////////////////////////////////////////////
// Data access
size_type size() const;
size_type max_size() const;
bool empty() const;
data_type &data();
const data_type &data() const;
value_type &front();
const value_type &front() const;
value_type &back();
const value_type &back() const;
///////////////////////////////////////////////////////////////////////////
// Operators
self_type &operator =(const self_type &rhs);
bool operator ==(const self_type &rhs) const;
bool operator !=(const self_type &rhs) const;
///////////////////////////////////////////////////////////////////////////
// Container operations
iterator find(const key_type &key);
const_iterator find(const key_type &key) const;
size_type count(const key_type &key) const;
void clear();
iterator insert(iterator where, const value_type &value);
template<class It> void insert(iterator where, It first, It last);
iterator erase(iterator where);
size_type erase(const key_type &key);
template<class It> iterator erase(It first, It last);
iterator push_front(const value_type &value);
iterator push_back(const value_type &value);
void pop_front();
void pop_back();
void swap(self_type &rhs);
void reverse();
template<class SortTr> void sort(SortTr tr);
///////////////////////////////////////////////////////////////////////////
// ptree operations
// Get child ptree with default separator
self_type &get_child(const path_type &path);
const self_type &get_child(const path_type &path) const;
self_type &get_child(const path_type &path, self_type &default_value);
const self_type &get_child(const path_type &path, const self_type &default_value) const;
optional<self_type &> get_child_optional(const path_type &path);
optional<const self_type &> get_child_optional(const path_type &path) const;
// Put child ptree with default separator
self_type &put_child(const path_type &path, const self_type &value, bool do_not_replace = false);
// Get value from data of ptree
template<class Type> Type get_value(const translator_type &x = translator_type()) const;
template<class Type> Type get_value(const Type &default_value, const translator_type &x = translator_type()) const;
template<class CharType> std::basic_string<CharType> get_value(const CharType *default_value, const translator_type &x = translator_type()) const;
template<class Type> optional<Type> get_value_optional(const translator_type &x = translator_type()) const;
// Get value from data of child ptree (default path separator)
template<class Type> Type get(const path_type &path, const translator_type &x = translator_type()) const;
template<class Type> Type get(const path_type &path, const Type &default_value, const translator_type &x = translator_type()) const;
template<class CharType> std::basic_string<CharType> get(const path_type &path, const CharType *default_value, const translator_type &x = translator_type()) const;
template<class Type> optional<Type> get_optional(const path_type &path, const translator_type &x = translator_type()) const;
// Put value in data of ptree
template<class Type> void put_value(const Type &value, const translator_type &x = translator_type());
// Put value in data of child ptree (default path separator)
template<class Type> self_type &put(const path_type &path, const Type &value, bool do_not_replace = false, const translator_type &x = translator_type());
private:
data_type m_data;
container_type m_container;
////////////////////////////////////////////////////////////////////////////
// Debugging
#ifdef BOOST_PROPERTY_TREE_DEBUG
private:
static boost::detail::lightweight_mutex debug_mutex; // Mutex for syncing instances counter
static size_type debug_instances_count; // Total number of instances of this ptree class
public:
static size_type debug_get_instances_count();
#endif
};
///////////////////////////////////////////////////////////////////////////
// basic_path class template
template<class Key>
class basic_path
{
private:
typedef typename Key::value_type char_type;
public:
///////////////////////////////////////////////////////////////////////
// Construction & destruction
basic_path();
basic_path(const Key &path, char_type separator = char_type('.'));
basic_path(const char_type *path, char_type separator = char_type('.'));
///////////////////////////////////////////////////////////////////////
// Path manipulation
basic_path<Key> &operator /=(const basic_path<Key> &rhs);
std::string to_string() const;
///////////////////////////////////////////////////////////////////////
// Operations
template<class C, class D, class X>
basic_ptree<C, Key, basic_path<Key>, D, X> *get_child(basic_ptree<C, Key, basic_path<Key>, D, X> &root) const;
template<class C, class D, class X>
const basic_ptree<C, Key, basic_path<Key>, D, X> *get_child(const basic_ptree<C, Key, basic_path<Key>, D, X> &root) const;
template<class C, class D, class X>
basic_ptree<C, Key, basic_path<Key>, D, X> *put_child(basic_ptree<C, Key, basic_path<Key>, D, X> &root,
const basic_ptree<C, Key, basic_path<Key>, D, X> &child,
bool do_not_replace) const;
private:
std::vector<Key> m_path;
///////////////////////////////////////////////////////////////////////
// Internal
template<class RanIt> void parse(RanIt begin, RanIt end, char_type separator);
};
///////////////////////////////////////////////////////////////////////////
// translator class
class translator
{
public:
translator();
translator(const std::locale &loc);
template<class Ptree, class T> bool get_value(const Ptree &pt, T &value) const;
template<class Ptree, class T> bool put_value(Ptree &pt, const T &value) const;
private:
std::locale m_locale;
};
///////////////////////////////////////////////////////////////////////////
// exceptions
// Base error class
class ptree_error: public std::runtime_error
{
public:
ptree_error(const std::string &what);
~ptree_error() throw();
};
// Bad data
class ptree_bad_data: public ptree_error
{
public:
template<class T> ptree_bad_data(const std::string &what, const T &data);
~ptree_bad_data() throw();
template<class T> T data();
private:
boost::any m_data;
};
// Bad path
class ptree_bad_path: public ptree_error
{
public:
template<class T> ptree_bad_path(const std::string &what, const T &path);
~ptree_bad_path() throw();
template<class T> T path();
private:
boost::any m_path;
};
} }
// Include implementations
#include <boost/property_tree/detail/ptree_implementation.hpp>
#include <boost/property_tree/detail/exceptions_implementation.hpp>
#include <boost/property_tree/detail/path_implementation.hpp>
#include <boost/property_tree/detail/translator_implementation.hpp>
#endif

View File

@@ -0,0 +1,54 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_PTREE_FWD_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/property_tree/detail/ptree_utils.hpp>
#include <functional> // for std::less
namespace boost { namespace property_tree
{
///////////////////////////////////////////////////////////////////////////
// Classes
template<class C, class K, class P, class D, class X> class basic_ptree;
template<class Key> class basic_path;
class translator;
class ptree_error;
class ptree_bad_data;
class ptree_bad_path;
///////////////////////////////////////////////////////////////////////////
// Typedefs
typedef basic_path<std::string> path;
typedef basic_path<std::wstring> wpath;
typedef basic_ptree<std::less<std::string>, std::string, path, std::string, translator> ptree;
typedef basic_ptree<detail::less_nocase<std::string>, std::string, path, std::string, translator> iptree;
#ifndef BOOST_NO_CWCHAR
typedef basic_ptree<std::less<std::wstring>, std::wstring, wpath, std::wstring, translator> wptree;
typedef basic_ptree<detail::less_nocase<std::wstring>, std::wstring, wpath, std::wstring, translator> wiptree;
#endif
///////////////////////////////////////////////////////////////////////////
// Free functions
template<class C, class K, class P, class D, class X> void swap(basic_ptree<C, K, P, D, X> &pt1, basic_ptree<C, K, P, D, X> &pt2);
template<class Ptree> const Ptree &empty_ptree();
path operator /(const path &p1, const path &p2);
wpath operator /(const wpath &p1, const wpath &p2);
} }
#endif

View File

@@ -0,0 +1,66 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_PTREE_SERIALIZATION_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/collections_save_imp.hpp>
#include <boost/serialization/collections_load_imp.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/utility.hpp>
namespace boost { namespace property_tree
{
///////////////////////////////////////////////////////////////////////////
// boost::serialization support
template<class Archive, class C, class K, class P, class D, class X>
inline void save(Archive &ar,
const basic_ptree<C, K, P, D, X> &t,
const unsigned int file_version)
{
serialization::stl::save_collection<Archive, basic_ptree<C, K, P, D, X> >(ar, t);
ar << serialization::make_nvp("data", t.data());
}
template<class Archive, class C, class K, class P, class D, class X>
inline void load(Archive &ar,
basic_ptree<C, K, P, D, X> &t,
const unsigned int file_version)
{
// Load children
boost::serialization::stl::load_collection
<
Archive,
basic_ptree<C, K, P, D, X>,
boost::serialization::stl::archive_input_seq<Archive, basic_ptree<C, K, P, D, X> >,
boost::serialization::stl::no_reserve_imp<basic_ptree<C, K, P, D, X> >
>(ar, t);
// Load data (must be after load_collection, as it calls clear())
ar >> serialization::make_nvp("data", t.data());
}
template<class Archive, class C, class K, class P, class D, class X>
inline void serialize(Archive &ar,
basic_ptree<C, K, P, D, X> &t,
const unsigned int file_version)
{
boost::serialization::split_free(ar, t, file_version);
}
} }
#endif

View File

@@ -0,0 +1,98 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
#define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/detail/xml_parser_write.hpp>
#include <boost/property_tree/detail/xml_parser_error.hpp>
#include <boost/property_tree/detail/xml_parser_writer_settings.hpp>
#include <boost/property_tree/detail/xml_parser_flags.hpp>
// Include proper parser
#if defined(BOOST_PROPERTY_TREE_XML_PARSER_TINYXML)
#include <boost/property_tree/detail/xml_parser_read_tinyxml.hpp>
#elif defined(BOOST_PROPERTY_TREE_XML_PARSER_PUGXML)
#include <boost/property_tree/detail/xml_parser_read_pugxml.hpp>
#elif defined(BOOST_PROPERTY_TREE_XML_PARSER_PUGIXML)
#include <boost/property_tree/detail/xml_parser_read_pugixml.hpp>
#elif defined(BOOST_PROPERTY_TREE_XML_PARSER_SPIRIT)
#include <boost/property_tree/detail/xml_parser_read_spirit.hpp>
#else
#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
#endif
#include <fstream>
#include <string>
#include <locale>
namespace boost { namespace property_tree { namespace xml_parser
{
// Read XML from stream
template<class Ptree>
void read_xml(std::basic_istream<typename Ptree::key_type::value_type> &stream,
Ptree &pt,
int flags = 0)
{
read_xml_internal(stream, pt, flags, std::string());
}
// Read XML from file
template<class Ptree>
void read_xml(const std::string &filename,
Ptree &pt,
int flags = 0,
const std::locale &loc = std::locale())
{
BOOST_ASSERT(validate_flags(flags));
std::basic_ifstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(xml_parser_error("cannot open file", filename, 0));
stream.imbue(loc);
read_xml_internal(stream, pt, flags, filename);
}
// Write XML to stream
template<class Ptree>
void write_xml(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
const Ptree &pt,
const xml_writer_settings<typename Ptree::key_type::value_type> & settings = xml_writer_settings<typename Ptree::key_type::value_type>() )
{
write_xml_internal(stream, pt, std::string(), settings);
}
// Write XML to file
template<class Ptree>
void write_xml(const std::string &filename,
const Ptree &pt,
const std::locale &loc = std::locale(),
const xml_writer_settings<typename Ptree::key_type::value_type> & settings = xml_writer_settings<typename Ptree::key_type::value_type>())
{
std::basic_ofstream<typename Ptree::key_type::value_type> stream(filename.c_str());
if (!stream)
BOOST_PROPERTY_TREE_THROW(xml_parser_error("cannot open file", filename, 0));
stream.imbue(loc);
write_xml_internal(stream, pt, filename, settings);
}
} } }
namespace boost { namespace property_tree
{
using xml_parser::read_xml;
using xml_parser::write_xml;
using xml_parser::xml_parser_error;
using xml_parser::xml_writer_settings;
using xml_parser::xml_writer_make_settings;
} }
#endif

12
index.html Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!--
<head>
<meta http-equiv="refresh" content="0; URL=doc/index.html">
</head>
-->
<body>
<p>
Docs for Property Tree library not available yet.</p>
</body>
</html>

17
test/Jamfile.v2 Normal file
View File

@@ -0,0 +1,17 @@
subproject libs/property_tree/test ;
# bring in rules for testing
import testing ;
# Make tests run by default.
DEPENDS all : property_tree ;
{
test-suite "property_tree"
: [ run test_property_tree.cpp ]
[ run test_info_parser.cpp ]
[ run test_json_parser.cpp ]
[ run test_ini_parser.cpp ]
[ run test_xml_parser_rapidxml.cpp ]
;
}

View File

@@ -0,0 +1,5 @@
all:
clean:
rm -f *_dbg.exe
rm -f *_rel.exe

View File

@@ -0,0 +1,80 @@
CCINCLUDE=-I../../../../../boost -I../../../..
all: test
-include Makefile
test: build
./ptree_dbg.exe
./ptree_rel.exe
./cmdline_dbg.exe
./cmdline_rel.exe
./ini_dbg.exe
./ini_rel.exe
./info_dbg.exe
./info_rel.exe
./json_dbg.exe
./json_rel.exe
./xml_dbg.exe
./xml_rel.exe
./multi_module_dbg.exe
./multi_module_rel.exe
./example_custom_data_type_dbg.exe
./example_custom_data_type_rel.exe
./example_debug_settings_dbg.exe
./example_debug_settings_rel.exe
./example_empty_ptree_trick_dbg.exe
./example_empty_ptree_trick_rel.exe
./example_info_grammar_spirit_dbg.exe
./example_info_grammar_spirit_rel.exe
build: debug release
debug: ptree_dbg.exe cmdline_dbg.exe ini_dbg.exe info_dbg.exe json_dbg.exe xml_dbg.exe multi_module_dbg.exe example_custom_data_type_dbg.exe example_debug_settings_dbg.exe example_empty_ptree_trick_dbg.exe example_info_grammar_spirit_dbg.exe
release: ptree_rel.exe cmdline_rel.exe ini_rel.exe info_rel.exe json_rel.exe xml_rel.exe multi_module_rel.exe example_custom_data_type_rel.exe example_debug_settings_rel.exe example_empty_ptree_trick_rel.exe example_info_grammar_spirit_rel.exe
ptree_dbg.exe: ../test_property_tree.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
ptree_rel.exe: ../test_property_tree.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
cmdline_dbg.exe: ../test_cmdline_parser.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
cmdline_rel.exe: ../test_cmdline_parser.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
ini_dbg.exe: ../test_ini_parser.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
ini_rel.exe: ../test_ini_parser.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
info_dbg.exe: ../test_info_parser.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
info_rel.exe: ../test_info_parser.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
json_dbg.exe: ../test_json_parser.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
json_rel.exe: ../test_json_parser.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
xml_dbg.exe: ../test_xml_parser_spirit.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
xml_rel.exe: ../test_xml_parser_spirit.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
multi_module_dbg.exe: ../test_multi_module1.cpp ../test_multi_module2.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $? -o $@ $(EXTLIBS)
multi_module_rel.exe: ../test_multi_module1.cpp ../test_multi_module2.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $? -o $@ $(EXTLIBS)
example_custom_data_type_dbg.exe: ../../examples/custom_data_type.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_custom_data_type_rel.exe: ../../examples/custom_data_type.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_debug_settings_dbg.exe: ../../examples/debug_settings.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_debug_settings_rel.exe: ../../examples/debug_settings.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_empty_ptree_trick_dbg.exe: ../../examples/empty_ptree_trick.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_empty_ptree_trick_rel.exe: ../../examples/empty_ptree_trick.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_info_grammar_spirit_dbg.exe: ../../examples/info_grammar_spirit.cpp
$(CC) $(CFLAGSDBG) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)
example_info_grammar_spirit_rel.exe: ../../examples/info_grammar_spirit.cpp
$(CC) $(CFLAGSREL) $(CCINCLUDE) $(EXTINCLUDE) $< -o $@ $(EXTLIBS)

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<debug>
<filename>debug.log</filename>
<modules>
<module>Finance</module>
<module>Admin</module>
<module>HR</module>
</modules>
<level>2</level>
</debug>

View File

@@ -0,0 +1,6 @@
CC=g++
CFLAGSREL=-Wall -pedantic -ftemplate-depth-255 -O3
CFLAGSDBG=-Wall -pedantic -ftemplate-depth-255 -O0
INCLUDE=-I../../../../../boost -I../../../..
-include Makefile-Common

View File

@@ -0,0 +1,6 @@
CC=icc
CFLAGSREL=-O3 -static
CFLAGSDBG=-O0 -static
INCLUDE=-I../../../../../boost -I../../../..
-include Makefile-Common

View File

@@ -0,0 +1,330 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="sandbox"
ProjectGUID="{85FA9AEF-966B-4D93-9431-F507754B0431}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="1"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="detail"
>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\exceptions_implementation.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\file_parser_error.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\info_parser_error.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\info_parser_read.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\info_parser_utils.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\info_parser_write.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\json_parser_error.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\json_parser_read.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\json_parser_write.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\path_implementation.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\ptree_implementation.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\ptree_utils.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\pugxml.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\rapidxml.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\translator_implementation.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_error.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_flags.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_read_pugixml.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_read_pugxml.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_read_rapidxml.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_read_spirit.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_read_tinyxml.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_utils.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_write.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\detail\xml_parser_writer_settings.hpp"
>
</File>
</Filter>
<File
RelativePath="..\..\..\..\boost\property_tree\cmdline_parser.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\info_parser.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\ini_parser.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\json_parser.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\ptree.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\ptree_fwd.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\ptree_serialization.hpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\registry_parser.hpp"
>
</File>
<File
RelativePath="..\sandbox.cpp"
>
</File>
<File
RelativePath="..\..\..\..\boost\property_tree\xml_parser.hpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,6 @@
settings
{
setting1 15
setting2 9.876
setting3 Alice in Wonderland
}

View File

@@ -0,0 +1,6 @@
;settings // non-existent
;{
; setting1 15
; setting2 9.876
; setting3 Alice in Wonderland
;}

View File

@@ -0,0 +1,6 @@
settings
{
setting1 15
;setting2 9.876 // non-existent
;setting3 Alice in Wonderland // non-existent
}

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="test_example_custom_data_type"
ProjectGUID="{87516DC2-FDF4-4ECC-8713-D6D955100D86}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\examples\custom_data_type.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="test_example_debug_settings"
ProjectGUID="{16D41CBD-3C58-4631-B4D4-29A42E47D619}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\examples\debug_settings.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="test_example_empty_ptree_trick"
ProjectGUID="{A242FE56-D039-4CEC-9FD3-AACABEA684C9}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\examples\empty_ptree_trick.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="test_info_grammar_spirit"
ProjectGUID="{305891FE-2572-4F6A-A52B-3A1964A3CA76}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\..\examples\info_grammar_spirit.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="test_info_parser"
ProjectGUID="{03A81E3E-895A-4E1D-A42C-EB155A2868E1}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\test_info_parser.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="test_ini_parser"
ProjectGUID="{20D5FE87-9284-4B1A-8505-7B913474C4AA}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\test_ini_parser.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="test_json_parser"
ProjectGUID="{CDDC4697-F51B-4B9A-A029-C2EB5271848F}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\test_json_parser.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,193 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="test_multi_module"
ProjectGUID="{4B88BAC5-5CA8-403A-83E7-0F758405AB2D}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\test_multi_module1.cpp"
>
</File>
<File
RelativePath="..\test_multi_module2.cpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,194 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="test_property_tree"
ProjectGUID="{DB0C18AA-BBA4-4DBF-A76E-92B642E45A74}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="2"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\test_property_tree.cpp"
>
</File>
<File
RelativePath="..\test_property_tree.hpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,197 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="test_xml_parser"
ProjectGUID="{02D60AE7-3C50-45BB-AB12-ECCB22F1B9AF}"
RootNamespace="test_property_tree"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(ProjectName)/$(ConfigurationName)"
IntermediateDirectory="$(ProjectName)/$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
ExceptionHandling="2"
RuntimeLibrary="0"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="..\test_xml_parser_common.hpp"
>
</File>
<File
RelativePath="..\test_xml_parser_rapidxml.cpp"
>
</File>
<File
RelativePath="..\xml_parser_test_data.hpp"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,80 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_property_tree", "test_property_tree.vcproj", "{DB0C18AA-BBA4-4DBF-A76E-92B642E45A74}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_ini_parser", "test_ini_parser.vcproj", "{20D5FE87-9284-4B1A-8505-7B913474C4AA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_info_parser", "test_info_parser.vcproj", "{03A81E3E-895A-4E1D-A42C-EB155A2868E1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_xml_parser", "test_xml_parser.vcproj", "{02D60AE7-3C50-45BB-AB12-ECCB22F1B9AF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox", "sandbox.vcproj", "{85FA9AEF-966B-4D93-9431-F507754B0431}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_json_parser", "test_json_parser.vcproj", "{CDDC4697-F51B-4B9A-A029-C2EB5271848F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_example_custom_data_type", "test_example_custom_data_type.vcproj", "{87516DC2-FDF4-4ECC-8713-D6D955100D86}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_example_debug_settings", "test_example_debug_settings.vcproj", "{16D41CBD-3C58-4631-B4D4-29A42E47D619}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_example_empty_ptree_trick", "test_example_empty_ptree_trick.vcproj", "{A242FE56-D039-4CEC-9FD3-AACABEA684C9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_info_grammar_spirit", "test_info_grammar_spirit.vcproj", "{305891FE-2572-4F6A-A52B-3A1964A3CA76}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_multi_module", "test_multi_module.vcproj", "{4B88BAC5-5CA8-403A-83E7-0F758405AB2D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DB0C18AA-BBA4-4DBF-A76E-92B642E45A74}.Debug|Win32.ActiveCfg = Debug|Win32
{DB0C18AA-BBA4-4DBF-A76E-92B642E45A74}.Debug|Win32.Build.0 = Debug|Win32
{DB0C18AA-BBA4-4DBF-A76E-92B642E45A74}.Release|Win32.ActiveCfg = Release|Win32
{DB0C18AA-BBA4-4DBF-A76E-92B642E45A74}.Release|Win32.Build.0 = Release|Win32
{20D5FE87-9284-4B1A-8505-7B913474C4AA}.Debug|Win32.ActiveCfg = Debug|Win32
{20D5FE87-9284-4B1A-8505-7B913474C4AA}.Debug|Win32.Build.0 = Debug|Win32
{20D5FE87-9284-4B1A-8505-7B913474C4AA}.Release|Win32.ActiveCfg = Release|Win32
{20D5FE87-9284-4B1A-8505-7B913474C4AA}.Release|Win32.Build.0 = Release|Win32
{03A81E3E-895A-4E1D-A42C-EB155A2868E1}.Debug|Win32.ActiveCfg = Debug|Win32
{03A81E3E-895A-4E1D-A42C-EB155A2868E1}.Debug|Win32.Build.0 = Debug|Win32
{03A81E3E-895A-4E1D-A42C-EB155A2868E1}.Release|Win32.ActiveCfg = Release|Win32
{03A81E3E-895A-4E1D-A42C-EB155A2868E1}.Release|Win32.Build.0 = Release|Win32
{02D60AE7-3C50-45BB-AB12-ECCB22F1B9AF}.Debug|Win32.ActiveCfg = Debug|Win32
{02D60AE7-3C50-45BB-AB12-ECCB22F1B9AF}.Debug|Win32.Build.0 = Debug|Win32
{02D60AE7-3C50-45BB-AB12-ECCB22F1B9AF}.Release|Win32.ActiveCfg = Release|Win32
{02D60AE7-3C50-45BB-AB12-ECCB22F1B9AF}.Release|Win32.Build.0 = Release|Win32
{85FA9AEF-966B-4D93-9431-F507754B0431}.Debug|Win32.ActiveCfg = Debug|Win32
{85FA9AEF-966B-4D93-9431-F507754B0431}.Debug|Win32.Build.0 = Debug|Win32
{85FA9AEF-966B-4D93-9431-F507754B0431}.Release|Win32.ActiveCfg = Release|Win32
{85FA9AEF-966B-4D93-9431-F507754B0431}.Release|Win32.Build.0 = Release|Win32
{CDDC4697-F51B-4B9A-A029-C2EB5271848F}.Debug|Win32.ActiveCfg = Debug|Win32
{CDDC4697-F51B-4B9A-A029-C2EB5271848F}.Debug|Win32.Build.0 = Debug|Win32
{CDDC4697-F51B-4B9A-A029-C2EB5271848F}.Release|Win32.ActiveCfg = Release|Win32
{CDDC4697-F51B-4B9A-A029-C2EB5271848F}.Release|Win32.Build.0 = Release|Win32
{87516DC2-FDF4-4ECC-8713-D6D955100D86}.Debug|Win32.ActiveCfg = Debug|Win32
{87516DC2-FDF4-4ECC-8713-D6D955100D86}.Debug|Win32.Build.0 = Debug|Win32
{87516DC2-FDF4-4ECC-8713-D6D955100D86}.Release|Win32.ActiveCfg = Release|Win32
{87516DC2-FDF4-4ECC-8713-D6D955100D86}.Release|Win32.Build.0 = Release|Win32
{16D41CBD-3C58-4631-B4D4-29A42E47D619}.Debug|Win32.ActiveCfg = Debug|Win32
{16D41CBD-3C58-4631-B4D4-29A42E47D619}.Debug|Win32.Build.0 = Debug|Win32
{16D41CBD-3C58-4631-B4D4-29A42E47D619}.Release|Win32.ActiveCfg = Release|Win32
{16D41CBD-3C58-4631-B4D4-29A42E47D619}.Release|Win32.Build.0 = Release|Win32
{A242FE56-D039-4CEC-9FD3-AACABEA684C9}.Debug|Win32.ActiveCfg = Debug|Win32
{A242FE56-D039-4CEC-9FD3-AACABEA684C9}.Debug|Win32.Build.0 = Debug|Win32
{A242FE56-D039-4CEC-9FD3-AACABEA684C9}.Release|Win32.ActiveCfg = Release|Win32
{A242FE56-D039-4CEC-9FD3-AACABEA684C9}.Release|Win32.Build.0 = Release|Win32
{305891FE-2572-4F6A-A52B-3A1964A3CA76}.Debug|Win32.ActiveCfg = Debug|Win32
{305891FE-2572-4F6A-A52B-3A1964A3CA76}.Debug|Win32.Build.0 = Debug|Win32
{305891FE-2572-4F6A-A52B-3A1964A3CA76}.Release|Win32.ActiveCfg = Release|Win32
{305891FE-2572-4F6A-A52B-3A1964A3CA76}.Release|Win32.Build.0 = Release|Win32
{4B88BAC5-5CA8-403A-83E7-0F758405AB2D}.Debug|Win32.ActiveCfg = Debug|Win32
{4B88BAC5-5CA8-403A-83E7-0F758405AB2D}.Debug|Win32.Build.0 = Debug|Win32
{4B88BAC5-5CA8-403A-83E7-0F758405AB2D}.Release|Win32.ActiveCfg = Release|Win32
{4B88BAC5-5CA8-403A-83E7-0F758405AB2D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

7
test/custom-build/vc.mak Normal file
View File

@@ -0,0 +1,7 @@
CC=cl
CFLAGSREL=-O2 -Ox -EHsc -DBOOST_DISABLE_WIN32 -nologo
CFLAGSDBG=-EHsc -DBOOST_DISABLE_WIN32 -nologo
EXTINCLUDE=
EXTLIBS=
-include Makefile-Common

13
test/sandbox.cpp Normal file
View File

@@ -0,0 +1,13 @@
#define _CRT_SECURE_NO_DEPRECATE
//#define BOOST_PROPERTY_TREE_XML_PARSER_PUGXML
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <iostream>
int main()
{
using namespace boost::property_tree;
ptree pt;
read_xml("simple_all.xml", pt);
write_info(std::cout, pt);
}

View File

@@ -0,0 +1,116 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
#include <boost/property_tree/cmdline_parser.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <vector>
#include <string>
namespace
{
// Test arguments
char *argv[] =
{
"c:\\program.exe",
"-Isrc/include1",
" file2.cc ",
"/L src/lib1",
"-Lsrc/lib2",
"/ooutput",
"file1.cc",
"-g",
"-",
"/",
" /Isrc/include2 ",
" file3.cc ",
"-I src/include3 "
};
// Test arguments count
const int argc = sizeof(argv) / sizeof(*argv);
}
template<class Ptree>
void test_cmdline_parser()
{
using namespace boost::property_tree;
typedef typename Ptree::key_type::value_type Ch;
typedef std::basic_string<Ch> Str;
// Prepare arguments of proper char type
std::vector<Ch *> p;
std::vector<Str> strings;
strings.reserve(argc);
for (int i = 0; i < argc; ++i)
{
strings.push_back(detail::widen<Ch>(argv[i]));
p.push_back(const_cast<Ch *>(strings.back().c_str()));
}
Ptree pt1;
read_cmdline<Ptree>(argc, &p.front(), detail::widen<Ch>("-/"), pt1);
// Check indices
BOOST_CHECK(pt1.template get_optional<Str>(detail::widen<Ch>("L.0")).get() == detail::widen<Ch>("src/lib1"));
BOOST_CHECK(pt1.template get_optional<Str>(detail::widen<Ch>("L.1")).get() == detail::widen<Ch>("src/lib2"));
BOOST_CHECK(!pt1.template get_optional<Str>(detail::widen<Ch>("L.2")));
BOOST_CHECK(pt1.template get_optional<Str>(detail::widen<Ch>(".0")).get() == detail::widen<Ch>("c:\\program.exe"));
BOOST_CHECK(pt1.template get_optional<Str>(detail::widen<Ch>(".1")).get() == detail::widen<Ch>("file2.cc"));
BOOST_CHECK(pt1.template get_optional<Str>(detail::widen<Ch>(".2")).get() == detail::widen<Ch>("file1.cc"));
BOOST_CHECK(pt1.template get_optional<Str>(detail::widen<Ch>(".3")).get() == detail::widen<Ch>("file3.cc"));
BOOST_CHECK(!pt1.template get_optional<Str>(detail::widen<Ch>(".4")));
// Check total sizes
//std::cerr << total_size(pt1) << " " << total_data_size(pt1) << " " << total_keys_size(pt1) << "\n";
BOOST_CHECK(total_size(pt1) == 21);
BOOST_CHECK(total_data_size(pt1) == 130);
BOOST_CHECK(total_keys_size(pt1) == 19);
Ptree pt2;
read_cmdline<Ptree>(argc, &p.front(), detail::widen<Ch>("-"), pt2);
// Check indices
BOOST_CHECK(pt2.template get_optional<Str>(detail::widen<Ch>("L.0")).get() == detail::widen<Ch>("src/lib2"));
BOOST_CHECK(!pt2.template get_optional<Str>(detail::widen<Ch>("L.1")));
// Check total sizes
//std::cerr << total_size(pt2) << " " << total_data_size(pt2) << " " << total_keys_size(pt2) << "\n";
BOOST_CHECK(total_size(pt2) == 19);
BOOST_CHECK(total_data_size(pt2) == 135);
BOOST_CHECK(total_keys_size(pt2) == 17);
Ptree pt3;
read_cmdline<Ptree>(argc, &p.front(), detail::widen<Ch>("/"), pt3);
// Check indices
BOOST_CHECK(pt3.template get_optional<Str>(detail::widen<Ch>("L.0")).get() == detail::widen<Ch>("src/lib1"));
BOOST_CHECK(!pt3.template get_optional<Str>(detail::widen<Ch>("L.1")));
// Check total sizes
//std::cerr << total_size(pt3) << " " << total_data_size(pt3) << " " << total_keys_size(pt3) << "\n";
BOOST_CHECK(total_size(pt3) == 19);
BOOST_CHECK(total_data_size(pt3) == 149);
BOOST_CHECK(total_keys_size(pt3) == 17);
}
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_cmdline_parser<ptree>();
#ifndef BOOST_NO_CWCHAR
test_cmdline_parser<wptree>();
#endif
return 0;
}

249
test/test_info_parser.cpp Normal file
View File

@@ -0,0 +1,249 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
#include <boost/property_tree/info_parser.hpp>
///////////////////////////////////////////////////////////////////////////////
// Test data
const char *ok_data_1 =
";Test file for info_parser\n"
"\n"
"key1 data1\n"
"{\n"
"\tkey data\n"
"}\n"
"#include \"testok1_inc.info\"\n"
"key2 \"data2 \" {\n"
"\tkey data\n"
"}\n"
"#\tinclude \"testok1_inc.info\"\n"
"key3 \"data\"\n"
"\t \"3\" {\n"
"\tkey data\n"
"}\n"
"\t#include \"testok1_inc.info\"\n"
"\n"
"\"key4\" data4\n"
"{\n"
"\tkey data\n"
"}\n"
"#include \"testok1_inc.info\"\n"
"\"key.5\" \"data.5\" { \n"
"\tkey data \n"
"}\n"
"#\tinclude \"testok1_inc.info\"\n"
"\"key6\" \"data\"\n"
"\t \"6\" {\n"
"\tkey data\n"
"}\n"
"\t#include \"testok1_inc.info\"\n"
" \n"
"key1 data1; comment\n"
"{; comment\n"
"\tkey data; comment\n"
"}; comment\n"
"#include \"testok1_inc.info\"\n"
"key2 \"data2 \" {; comment\n"
"\tkey data; comment\n"
"}; comment\n"
"#\tinclude \"testok1_inc.info\"\n"
"key3 \"data\"; comment\n"
"\t \"3\" {; comment\n"
"\tkey data; comment\n"
"}; comment\n"
"\t#include \"testok1_inc.info\"\n"
"\n"
"\"key4\" data4; comment\n"
"{; comment\n"
"\tkey data; comment\n"
"}; comment\n"
"#include \"testok1_inc.info\"\n"
"\"key.5\" \"data.5\" {; comment\n"
"\tkey data; comment\n"
"}; comment\n"
"#\tinclude \"testok1_inc.info\"\n"
"\"key6\" \"data\"; comment\n"
"\t \"6\" {; comment\n"
"\tkey data; comment\n"
"}; comment\n"
"\t#include \"testok1_inc.info\"\n"
"\\\\key\\t7 data7\\n\\\"data7\\\"\n"
"{\n"
"\tkey data\n"
"}\n"
"\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n"
"{\n"
"\tkey data\n"
"}\n"
"\n";
const char *ok_data_1_inc =
";Test file for info_parser\n"
"\n"
"inc_key inc_data ;;; comment\\";
const char *ok_data_2 =
"";
const char *ok_data_3 =
"key1 \"\"\n"
"key2 \"\"\n"
"key3 \"\"\n"
"key4 \"\"\n";
const char *ok_data_4 =
"key1 data key2 data";
const char *ok_data_5 =
"key { key \"\" key \"\" }\n";
const char *ok_data_6 =
"\"key with spaces\" \"data with spaces\"\n"
"\"key with spaces\" \"multiline data\"\\\n"
"\"cont\"\\\n"
"\"cont\"";
const char *error_data_1 =
";Test file for info_parser\n"
"#include \"bogus_file\"\n"; // Nonexistent include file
const char *error_data_2 =
";Test file for info_parser\n"
"key \"data with bad escape: \\q\"\n"; // Bad escape
const char *error_data_3 =
";Test file for info_parser\n"
"{\n"; // Opening brace without key
const char *error_data_4 =
";Test file for info_parser\n"
"}\n"; // Closing brace without opening brace
const char *error_data_5 =
";Test file for info_parser\n"
"key data\n"
"{\n"
""; // No closing brace
struct ReadFunc
{
template<class Ptree>
void operator()(const std::string &filename, Ptree &pt) const
{
boost::property_tree::read_info(filename, pt);
}
};
struct WriteFunc
{
template<class Ptree>
void operator()(const std::string &filename, const Ptree &pt) const
{
boost::property_tree::write_info(filename, pt);
}
};
template<class Ptree>
void test_info_parser()
{
using namespace boost::property_tree;
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_1, ok_data_1_inc,
"testok1.info", "testok1_inc.info", "testok1out.info", 45, 240, 192
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_2, NULL,
"testok2.info", NULL, "testok2out.info", 1, 0, 0
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_3, NULL,
"testok3.info", NULL, "testok3out.info", 5, 0, 16
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_4, NULL,
"testok4.info", NULL, "testok4out.info", 3, 8, 8
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_5, NULL,
"testok5.info", NULL, "testok5out.info", 4, 0, 9
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_6, NULL,
"testok6.info", NULL, "testok6out.info", 3, 38, 30
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, info_parser_error>
(
ReadFunc(), WriteFunc(), error_data_1, NULL,
"testerr1.info", NULL, "testerr1out.info", 2
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, info_parser_error>
(
ReadFunc(), WriteFunc(), error_data_2, NULL,
"testerr2.info", NULL, "testerr2out.info", 2
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, info_parser_error>
(
ReadFunc(), WriteFunc(), error_data_3, NULL,
"testerr3.info", NULL, "testerr3out.info", 2
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, info_parser_error>
(
ReadFunc(), WriteFunc(), error_data_4, NULL,
"testerr4.info", NULL, "testerr4out.info", 2
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, info_parser_error>
(
ReadFunc(), WriteFunc(), error_data_5, NULL,
"testerr5.info", NULL, "testerr5out.info", 4
);
// Test read with default ptree
{
Ptree pt, default_pt;
pt.put_value(1);
default_pt.put_value(2);
BOOST_CHECK(pt != default_pt);
read_info("nonexisting file.nonexisting file", pt, default_pt);
BOOST_CHECK(pt == default_pt);
}
}
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_info_parser<ptree>();
test_info_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
test_info_parser<wptree>();
test_info_parser<wiptree>();
#endif
return 0;
}

198
test/test_ini_parser.cpp Normal file
View File

@@ -0,0 +1,198 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
#include <boost/property_tree/ini_parser.hpp>
#include <sstream>
///////////////////////////////////////////////////////////////////////////////
// Test data
// Correct data
const char *ok_data_1 =
"\n"
"; Comment\n"
"[Section1]\n"
"\t \t; Comment\n"
" Key1=Data1\n"
" \n"
" Key2 = Data2\n"
"Key 3 = Data 3 \n"
"Key4=Data4\n"
"[Section2] ;Comment\n"
"\t \t; Comment\n"
" \t [ Section 3 ];Comment \n";
// Correct data
const char *ok_data_2 =
"[Section1]\n"
"Key1=Data1"; // No eol
// Correct data
const char *ok_data_3 =
"";
// Correct data
const char *ok_data_4 =
";Comment";
// Erroneous data
const char *error_data_1 =
"[Section1]\n"
"Key1\n" // No equals sign
"Key2=Data2";
// Erroneous data
const char *error_data_2 =
"Key1=Data1\n" // No section
"Key2=Data2\n";
// Erroneous data
const char *error_data_3 =
"[Section1]\n"
"Key1=Data1\n"
"=Data2\n"; // No key
struct ReadFunc
{
template<class Ptree>
void operator()(const std::string &filename, Ptree &pt) const
{
boost::property_tree::read_ini(filename, pt);
}
};
struct WriteFunc
{
template<class Ptree>
void operator()(const std::string &filename, const Ptree &pt) const
{
boost::property_tree::write_ini(filename, pt);
}
};
void test_erroneous_write(const boost::property_tree::ptree &pt)
{
using namespace boost::property_tree;
std::stringstream stream;
try
{
write_ini(stream, pt);
BOOST_ERROR("No required exception thrown");
}
catch (ini_parser_error &e)
{
(void)e;
}
catch (...)
{
BOOST_ERROR("Wrong exception type thrown");
}
}
template<class Ptree>
void test_ini_parser()
{
using namespace boost::property_tree;
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_1, NULL,
"testok1.ini", NULL, "testok1out.ini", 8, 21, 42
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_2, NULL,
"testok2.ini", NULL, "testok2out.ini", 3, 5, 12
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_3, NULL,
"testok3.ini", NULL, "testok3out.ini", 1, 0, 0
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_4, NULL,
"testok4.ini", NULL, "testok4out.ini", 1, 0, 0
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
(
ReadFunc(), WriteFunc(), error_data_1, NULL,
"testerr1.ini", NULL, "testerr1out.ini", 2
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
(
ReadFunc(), WriteFunc(), error_data_2, NULL,
"testerr2.ini", NULL, "testerr2out.ini", 1
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
(
ReadFunc(), WriteFunc(), error_data_3, NULL,
"testerr3.ini", NULL, "testerr3out.ini", 3
);
}
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_ini_parser<ptree>();
test_ini_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
test_ini_parser<wptree>();
test_ini_parser<wiptree>();
#endif
///////////////////////////////////////////////////////////////////////////
// Too rich property tree tests
// Test too deep ptrees
{
ptree pt;
pt.put_child("section.key.bogus", empty_ptree<ptree>());
test_erroneous_write(pt);
}
// Test data in sections
{
ptree pt;
pt.put("section", 1);
test_erroneous_write(pt);
}
// Test duplicate sections
{
ptree pt;
pt.push_back(std::make_pair("section", ptree()));
pt.push_back(std::make_pair("section", ptree()));
test_erroneous_write(pt);
}
// Test duplicate keys
{
ptree pt;
ptree &child = pt.put_child("section", empty_ptree<ptree>());
child.push_back(std::make_pair("key", ptree()));
child.push_back(std::make_pair("key", ptree()));
test_erroneous_write(pt);
}
return 0;
}

384
test/test_json_parser.cpp Normal file
View File

@@ -0,0 +1,384 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
#include <boost/property_tree/json_parser.hpp>
///////////////////////////////////////////////////////////////////////////////
// Test data
const char *ok_data_1 =
"{}";
const char *ok_data_2 =
" \t {\n"
" \t \"name 0\" : \"value\", \t // comment \n"
" \t \"name 1\" : \"\", // comment \n"
" \t \"name 2\" : true, // comment \n"
" \t \"name 3\" : false, // comment \n"
" \t \"name 4\" : null, // comment \n"
" \t \"name 5\" : 0, // comment \n"
" \t \"name 6\" : -5, // comment \n"
" \t \"name 7\" : 1.1, // comment \n"
" \t \"name 8\" : -956.45e+4, // comment \n"
" \t \"name 8\" : 5956.45E-11, // comment \n"
" \t \"name 9\" : [1,2,3,4], // comment \n"
" \t \"name 10\" : {\"a\":\"b\"} // comment \n"
" \t } // comment \n";
const char *ok_data_3 =
"{\"a\":{\"b\":\"c\"}}";
const char *ok_data_4 =
"{\"a\":[{\"b\":\"c\"},{\"d\":\"e\"},1,2,3,4],\"f\":null}";
const char *ok_data_5 =
"{/* \n\n//{}//{}{\n{//\n}//{}{\n */}";
const char *ok_data_6 =
"{\"menu\": {\n"
" \"header\": \"SVG Viewer\",\n"
" \"items\": [\n"
" {\"id\": \"Open\"},\n"
" {\"id\": \"OpenNew\", \"label\": \"Open New\"},\n"
" null,\n"
" {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"},\n"
" {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"},\n"
" {\"id\": \"OriginalView\", \"label\": \"Original View\"},\n"
" null,\n"
" {\"id\": \"Quality\"},\n"
" {\"id\": \"Pause\"},\n"
" {\"id\": \"Mute\"},\n"
" null,\n"
" {\"id\": \"Find\", \"label\": \"Find...\"},\n"
" {\"id\": \"FindAgain\", \"label\": \"Find Again\"},\n"
" {\"id\": \"Copy\"},\n"
" {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"},\n"
" {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"},\n"
" {\"id\": \"ViewSVG\", \"label\": \"View SVG\"},\n"
" {\"id\": \"ViewSource\", \"label\": \"View Source\"},\n"
" {\"id\": \"SaveAs\", \"label\": \"Save As\"},\n"
" null,\n"
" {\"id\": \"Help\"},\n"
" {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"}\n"
" ]\n"
"}}\n";
const char *ok_data_7 =
"{\"web-app\": {\n"
" \"servlet\": [ // Defines the CDSServlet\n"
" {\n"
" \"servlet-name\": \"cofaxCDS\",\n"
" \"servlet-class\": \"org.cofax.cds.CDSServlet\",\n"
" \"init-param\": {\n"
" \"configGlossary:installationAt\": \"Philadelphia, PA\",\n"
" \"configGlossary:adminEmail\": \"ksm@pobox.com\",\n"
" \"configGlossary:poweredBy\": \"Cofax\",\n"
" \"configGlossary:poweredByIcon\": \"/images/cofax.gif\",\n"
" \"configGlossary:staticPath\": \"/content/static\",\n"
" \"templateProcessorClass\": \"org.cofax.WysiwygTemplate\",\n"
" \"templateLoaderClass\": \"org.cofax.FilesTemplateLoader\",\n"
" \"templatePath\": \"templates\",\n"
" \"templateOverridePath\": \"\",\n"
" \"defaultListTemplate\": \"listTemplate.htm\",\n"
" \"defaultFileTemplate\": \"articleTemplate.htm\",\n"
" \"useJSP\": false,\n"
" \"jspListTemplate\": \"listTemplate.jsp\",\n"
" \"jspFileTemplate\": \"articleTemplate.jsp\",\n"
" \"cachePackageTagsTrack\": 200,\n"
" \"cachePackageTagsStore\": 200,\n"
" \"cachePackageTagsRefresh\": 60,\n"
" \"cacheTemplatesTrack\": 100,\n"
" \"cacheTemplatesStore\": 50,\n"
" \"cacheTemplatesRefresh\": 15,\n"
" \"cachePagesTrack\": 200,\n"
" \"cachePagesStore\": 100,\n"
" \"cachePagesRefresh\": 10,\n"
" \"cachePagesDirtyRead\": 10,\n"
" \"searchEngineListTemplate\": \"forSearchEnginesList.htm\",\n"
" \"searchEngineFileTemplate\": \"forSearchEngines.htm\",\n"
" \"searchEngineRobotsDb\": \"WEB-INF/robots.db\",\n"
" \"useDataStore\": true,\n"
" \"dataStoreClass\": \"org.cofax.SqlDataStore\",\n"
" \"redirectionClass\": \"org.cofax.SqlRedirection\",\n"
" \"dataStoreName\": \"cofax\",\n"
" \"dataStoreDriver\": \"com.microsoft.jdbc.sqlserver.SQLServerDriver\",\n"
" \"dataStoreUrl\": \"jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon\",\n"
" \"dataStoreUser\": \"sa\",\n"
" \"dataStorePassword\": \"dataStoreTestQuery\",\n"
" \"dataStoreTestQuery\": \"SET NOCOUNT ON;select test='test';\",\n"
" \"dataStoreLogFile\": \"/usr/local/tomcat/logs/datastore.log\",\n"
" \"dataStoreInitConns\": 10,\n"
" \"dataStoreMaxConns\": 100,\n"
" \"dataStoreConnUsageLimit\": 100,\n"
" \"dataStoreLogLevel\": \"debug\",\n"
" \"maxUrlLength\": 500}},\n"
" {\n"
" \"servlet-name\": \"cofaxEmail\",\n"
"\n \"servlet-class\": \"org.cofax.cds.EmailServlet\",\n"
" \"init-param\": {\n"
" \"mailHost\": \"mail1\",\n"
" \"mailHostOverride\": \"mail2\"}},\n"
" {\n"
" \"servlet-name\": \"cofaxAdmin\",\n"
" \"servlet-class\": \"org.cofax.cds.AdminServlet\"},\n"
" \n"
" {\n"
" \"servlet-name\": \"fileServlet\",\n"
" \"servlet-class\": \"org.cofax.cds.FileServlet\"},\n"
" {\n"
" \"servlet-name\": \"cofaxTools\",\n"
" \"servlet-class\": \"org.cofax.cms.CofaxToolsServlet\",\n"
" \"init-param\": {\n"
" \"templatePath\": \"toolstemplates/\",\n"
" \"log\": 1,\n"
" \"logLocation\": \"/usr/local/tomcat/logs/CofaxTools.log\",\n"
" \"logMaxSize\": \"\",\n"
" \"dataLog\": 1,\n"
" \"dataLogLocation\": \"/usr/local/tomcat/logs/dataLog.log\",\n"
" \"dataLogMaxSize\": \"\",\n"
" \"removePageCache\": \"/content/admin/remove?cache=pages&id=\",\n"
" \"removeTemplateCache\": \"/content/admin/remove?cache=templates&id=\",\n"
" \"fileTransferFolder\": \"/usr/local/tomcat/webapps/content/fileTransferFolder\",\n"
" \"lookInContext\": 1,\n"
" \"adminGroupID\": 4,\n"
" \"betaServer\": true}}],\n"
" \"servlet-mapping\": {\n"
" \"cofaxCDS\": \"/\",\n"
" \"cofaxEmail\": \"/cofaxutil/aemail/*\",\n"
" \"cofaxAdmin\": \"/admin/*\",\n"
" \"fileServlet\": \"/static/*\",\n"
" \"cofaxTools\": \"/tools/*\"},\n"
" \n"
" \"taglib\": {\n"
" \"taglib-uri\": \"cofax.tld\",\n"
" \"taglib-location\": \"/WEB-INF/tlds/cofax.tld\"}}}\n";
const char *ok_data_8 =
"{\"widget\": {\n"
" \"debug\": \"on\",\n"
" \"window\": {\n"
" \"title\": \"Sample Konfabulator Widget\", \"name\": \"main_window\", \"width\": 500, \"height\": 500\n"
" }, \"image\": { \n"
" \"src\": \"Images/Sun.png\",\n"
" \"name\": \"sun1\", \"hOffset\": 250, \"vOffset\": 250, \"alignment\": \"center\"\n"
" }, \"text\": {\n"
" \"data\": \"Click Here\",\n"
" \"size\": 36,\n"
" \"style\": \"bold\", \"name\": \"text1\", \"hOffset\": 250, \"vOffset\": 100, \"alignment\": \"center\",\n"
" \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"\n"
" }\n"
"}} \n";
const char *ok_data_9 =
"{\"menu\": {\n"
" \"id\": \"file\",\n"
" \"value\": \"File:\",\n"
" \"popup\": {\n"
" \"menuitem\": [\n"
" {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"},\n"
" {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"},\n"
"\n {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}\n"
" ]\n"
" }\n"
"}}\n";
const char *ok_data_10 =
"{\n"
" \"glossary\": {\n"
" \"title\": \"example glossary\",\n"
" \"GlossDiv\": {\n"
" \"title\": \"S\",\n"
" \"GlossList\": [{\n"
" \"ID\": \"SGML\",\n"
" \"SortAs\": \"SGML\",\n"
" \"GlossTerm\": \"Standard Generalized Markup Language\",\n"
" \"Acronym\": \"SGML\",\n"
" \"Abbrev\": \"ISO 8879:1986\",\n"
" \"GlossDef\": \n"
"\"A meta-markup language, used to create markup languages such as DocBook.\",\n"
" \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"]\n"
" }]\n"
" }\n"
" }\n"
"}\n";
const char *ok_data_11 =
"{\n"
" \"data\" : [\n"
" {\n"
" \"First Name\" : \"Bob\",\n"
" \"Last Name\" : \"Smith\",\n"
" \"Email\" : \"bsmith@someurl.com\",\n"
" \"Phone\" : \"(555) 555-1212\"\n"
" },\n"
" {\n"
" \"First Name\" : \"Jan\",\n"
" \"Last Name\" : \"Smith\",\n"
" \"Email\" : \"jsmith@someurl.com\",\n"
" \"Phone\" : \"(555) 555-3434\"\n"
" },\n"
" {\n"
" \"First Name\" : \"Sue\",\n"
" \"Last Name\" : \"Smith\",\n"
" \"Email\" : \"ssmith@someurl.com\",\n"
" \"Phone\" : \"(555) 555-5656\"\n"
" }\n"
" ]\n"
"}\n";
const char *ok_data_12 =
"{\" \\\" \\\\ \\0 \\b \\f \\n \\r \\t \" : \"multi\" \"-\" \"string\"}";
const char *error_data_1 =
""; // No root object
const char *error_data_2 =
"{\n\"a\":1\n"; // Unclosed object brace
const char *error_data_3 =
"{\n\"a\":\n[1,2,3,4\n}"; // Unclosed array brace
const char *error_data_4 =
"{\n\"a\"\n}"; // No object
struct ReadFunc
{
template<class Ptree>
void operator()(const std::string &filename, Ptree &pt) const
{
boost::property_tree::read_json(filename, pt);
}
};
struct WriteFunc
{
template<class Ptree>
void operator()(const std::string &filename, const Ptree &pt) const
{
boost::property_tree::write_json(filename, pt);
}
};
template<class Ptree>
void test_json_parser()
{
using namespace boost::property_tree;
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_1, NULL,
"testok1.json", NULL, "testok1out.json", 1, 0, 0
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_2, NULL,
"testok2.json", NULL, "testok2out.json", 18, 50, 74
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_3, NULL,
"testok3.json", NULL, "testok3out.json", 3, 1, 2
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_4, NULL,
"testok4.json", NULL, "testok4out.json", 11, 10, 4
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_5, NULL,
"testok5.json", NULL, "testok5out.json", 1, 0, 0
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_6, NULL,
"testok6.json", NULL, "testok6out.json", 56, 265, 111
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_7, NULL,
"testok7.json", NULL, "testok7out.json", 87, 1046, 1216
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_8, NULL,
"testok8.json", NULL, "testok8out.json", 23, 149, 125
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_9, NULL,
"testok9.json", NULL, "testok9out.json", 15, 54, 60
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_10, NULL,
"testok10.json", NULL, "testok10out.json", 17, 162, 85
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_11, NULL,
"testok11.json", NULL, "testok11out.json", 17, 120, 91
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_12, NULL,
"testok12.json", NULL, "testok12out.json", 2, 12, 19
);
generic_parser_test_error<ptree, ReadFunc, WriteFunc, json_parser_error>
(
ReadFunc(), WriteFunc(), error_data_1, NULL,
"testerr1.json", NULL, "testerr1out.json", 1
);
generic_parser_test_error<ptree, ReadFunc, WriteFunc, json_parser_error>
(
ReadFunc(), WriteFunc(), error_data_2, NULL,
"testerr2.json", NULL, "testerr2out.json", 3
);
generic_parser_test_error<ptree, ReadFunc, WriteFunc, json_parser_error>
(
ReadFunc(), WriteFunc(), error_data_3, NULL,
"testerr3.json", NULL, "testerr3out.json", 4
);
generic_parser_test_error<ptree, ReadFunc, WriteFunc, json_parser_error>
(
ReadFunc(), WriteFunc(), error_data_4, NULL,
"testerr4.json", NULL, "testerr4out.json", 3
);
}
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_json_parser<ptree>();
test_json_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
test_json_parser<wptree>();
test_json_parser<wiptree>();
#endif
return 0;
}

View File

@@ -0,0 +1,21 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
void f();
int main()
{
f();
}

View File

@@ -0,0 +1,18 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
void f()
{
}

263
test/test_property_tree.cpp Normal file
View File

@@ -0,0 +1,263 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
#include <boost/any.hpp>
#include <list>
#include <cmath>
// If using VC, disable some warnings that trip in boost::serialization bowels
#ifdef BOOST_MSVC
#pragma warning(disable:4267) // Narrowing conversion
#pragma warning(disable:4996) // Deprecated functions
#endif
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/property_tree/ptree_serialization.hpp>
// Predicate for sorting keys
template<class Ptree>
struct SortPred
{
bool operator()(const typename Ptree::value_type &v1,
const typename Ptree::value_type &v2) const
{
return v1.first < v2.first;
}
};
// Predicate for sorting keys in reverse
template<class Ptree>
struct SortPredRev
{
bool operator()(const typename Ptree::value_type &v1,
const typename Ptree::value_type &v2) const
{
return v1.first > v2.first;
}
};
// Custom translator that works with boost::any instead of std::string
struct MyTranslator
{
// Custom extractor - converts data from boost::any to T
template<class Ptree, class T>
bool get_value(const Ptree &pt, T &value) const
{
value = boost::any_cast<T>(pt.data());
return true; // Success
}
// Custom inserter - converts data from T to boost::any
template<class Ptree, class T>
bool put_value(Ptree &pt, const T &value) const
{
pt.data() = value;
return true;
}
};
// Include char tests, case sensitive
#define CHTYPE char
#define T(s) s
#define PTREE boost::property_tree::ptree
#define NOCASE 0
#define WIDECHAR 0
# include "test_property_tree.hpp"
#undef CHTYPE
#undef T
#undef PTREE
#undef NOCASE
#undef WIDECHAR
// Include wchar_t tests, case sensitive
#ifndef BOOST_NO_CWCHAR
# define CHTYPE wchar_t
# define T(s) L ## s
# define PTREE boost::property_tree::wptree
# define NOCASE 0
# define WIDECHAR 1
# include "test_property_tree.hpp"
# undef CHTYPE
# undef T
# undef PTREE
# undef NOCASE
# undef WIDECHAR
#endif
// Include char tests, case insensitive
#define CHTYPE char
#define T(s) s
#define PTREE boost::property_tree::iptree
#define NOCASE 1
# define WIDECHAR 0
# include "test_property_tree.hpp"
#undef CHTYPE
#undef T
#undef PTREE
#undef NOCASE
#undef WIDECHAR
// Include wchar_t tests, case insensitive
#ifndef BOOST_NO_CWCHAR
# define CHTYPE wchar_t
# define T(s) L ## s
# define PTREE boost::property_tree::wiptree
# define NOCASE 1
# define WIDECHAR 1
# include "test_property_tree.hpp"
# undef CHTYPE
# undef T
# undef PTREE
# undef NOCASE
# undef WIDECHAR
#endif
int test_main(int, char *[])
{
using namespace boost::property_tree;
// char tests, case sensitive
{
ptree *pt = 0;
test_debug(pt);
test_constructor_destructor_assignment(pt);
test_insertion(pt);
test_erasing(pt);
test_clear(pt);
test_pushpop(pt);
test_container_iteration(pt);
test_swap(pt);
test_sort_reverse(pt);
test_case(pt);
test_comparison(pt);
test_front_back(pt);
test_get_put(pt);
test_get_child_put_child(pt);
test_path_separator(pt);
test_path(pt);
test_precision(pt);
test_locale(pt);
test_custom_data_type(pt);
test_empty_size_max_size(pt);
test_ptree_bad_path(pt);
test_ptree_bad_data(pt);
test_serialization(pt);
test_bool(pt);
test_char(pt);
test_leaks(pt); // must be a final test
}
// wchar_t tests, case sensitive
#ifndef BOOST_NO_CWCHAR
{
wptree *pt = 0;
test_debug(pt);
test_constructor_destructor_assignment(pt);
test_insertion(pt);
test_erasing(pt);
test_clear(pt);
test_pushpop(pt);
test_container_iteration(pt);
test_swap(pt);
test_sort_reverse(pt);
test_case(pt);
test_comparison(pt);
test_front_back(pt);
test_get_put(pt);
test_get_child_put_child(pt);
test_path_separator(pt);
test_path(pt);
test_precision(pt);
test_locale(pt);
test_custom_data_type(pt);
test_empty_size_max_size(pt);
test_ptree_bad_path(pt);
test_ptree_bad_data(pt);
test_serialization(pt);
test_bool(pt);
test_char(pt);
test_leaks(pt); // must be a final test
}
#endif
// char tests, case insensitive
{
iptree *pt = 0;
test_debug(pt);
test_constructor_destructor_assignment(pt);
test_insertion(pt);
test_erasing(pt);
test_clear(pt);
test_pushpop(pt);
test_container_iteration(pt);
test_swap(pt);
test_sort_reverse(pt);
test_case(pt);
test_comparison(pt);
test_front_back(pt);
test_get_put(pt);
test_get_child_put_child(pt);
test_path_separator(pt);
test_path(pt);
test_precision(pt);
test_locale(pt);
test_custom_data_type(pt);
test_empty_size_max_size(pt);
test_ptree_bad_path(pt);
test_ptree_bad_data(pt);
test_serialization(pt);
test_bool(pt);
test_char(pt);
test_leaks(pt); // must be a final test
}
// wchar_t tests, case insensitive
#ifndef BOOST_NO_CWCHAR
{
wiptree *pt = 0;
test_debug(pt);
test_constructor_destructor_assignment(pt);
test_insertion(pt);
test_erasing(pt);
test_clear(pt);
test_pushpop(pt);
test_container_iteration(pt);
test_swap(pt);
test_sort_reverse(pt);
test_case(pt);
test_comparison(pt);
test_front_back(pt);
test_get_put(pt);
test_get_child_put_child(pt);
test_path_separator(pt);
test_path(pt);
test_precision(pt);
test_locale(pt);
test_custom_data_type(pt);
test_empty_size_max_size(pt);
test_ptree_bad_path(pt);
test_ptree_bad_data(pt);
test_serialization(pt);
test_bool(pt);
test_char(pt);
test_leaks(pt); // must be a final test
}
#endif
return 0;
}

1263
test/test_property_tree.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
// Only test registry parser if we have windows platform
#ifdef BOOST_WINDOWS
#include <boost/property_tree/registry_parser.hpp>
#include <boost/property_tree/info_parser.hpp>
///////////////////////////////////////////////////////////////////////////////
// Test data
const char *data_1 =
"root\n"
"{\n"
" subkey1 \"default value 1\"\n"
" subkey2 \"default value 2\"\n"
" \\\\values\n"
" {\n"
" REG_NONE \"\"\n"
" REG_BINARY \"de ad be ef\"\n"
" REG_DWORD 1234567890\n"
" REG_QWORD 12345678901234567890\n"
" REG_SZ \"some text\"\n"
" REG_EXPAND_SZ \"some other text\"\n"
" }\n"
" \\\\types\n"
" {\n"
" REG_NONE 0\n"
" REG_BINARY 3\n"
" REG_DWORD 4\n"
" REG_QWORD 11\n"
" REG_SZ 1\n"
" REG_EXPAND_SZ 2\n"
" }\n"
"}\n";
template<class Ptree>
void test_registry_parser()
{
using namespace boost::property_tree;
typedef typename Ptree::key_type::value_type Ch;
typedef std::basic_string<Ch> Str;
// Delete test registry key
RegDeleteKeyA(HKEY_CURRENT_USER, "boost ptree test");
// Get test ptree
Ptree pt;
std::basic_stringstream<Ch> stream(detail::widen<Ch>(data_1));
read_info(stream, pt);
try
{
// Write to registry, read back and compare contents
Ptree pt2;
write_registry(HKEY_CURRENT_USER, detail::widen<Ch>("boost ptree test"), pt);
read_registry(HKEY_CURRENT_USER, detail::widen<Ch>("boost ptree test"), pt2);
BOOST_CHECK(pt == pt2);
// Test binary translation
Str s = pt2.template get<Str>(detail::widen<Ch>("root.\\values.REG_BINARY"));
std::vector<BYTE> bin = registry_parser::translate(REG_BINARY, s);
BOOST_REQUIRE(bin.size() == 4);
BOOST_CHECK(*reinterpret_cast<DWORD *>(&bin.front()) == 0xEFBEADDE);
Str s2 = registry_parser::translate<Ch>(REG_BINARY, bin);
BOOST_CHECK(s == s2);
}
catch (std::exception &e)
{
BOOST_ERROR(e.what());
}
// Delete test registry key
RegDeleteKeyA(HKEY_CURRENT_USER, "boost ptree test");
}
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_registry_parser<ptree>();
//test_registry_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
//test_registry_parser<wptree>();
//test_registry_parser<wiptree>();
#endif
return 0;
}
#else
int test_main(int argc, char *argv[])
{
return 0;
}
#endif

227
test/test_utils.hpp Normal file
View File

@@ -0,0 +1,227 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2005 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef BOOST_PROPERTY_TREE_TEST_UTILS_INCLUDED
#define BOOST_PROPERTY_TREE_TEST_UTILS_INCLUDED
#define BOOST_PROPERTY_TREE_DEBUG // Enable ptree debugging
#include <boost/property_tree/ptree.hpp>
// Do not deprecate insecure CRT calls on VC8
#if (defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) && !defined(_CRT_SECURE_NO_DEPRECATE))
# define _CRT_SECURE_NO_DEPRECATE
#endif
#include <boost/test/minimal.hpp>
#include <boost/property_tree/detail/ptree_utils.hpp>
#include <fstream>
template<class Ptree>
typename Ptree::size_type total_size(const Ptree &pt)
{
typename Ptree::size_type size = 1;
for (typename Ptree::const_iterator it = pt.begin(); it != pt.end(); ++it)
size += total_size(it->second);
return size;
}
template<class Ptree>
typename Ptree::size_type total_keys_size(const Ptree &pt)
{
typename Ptree::size_type size = 0;
for (typename Ptree::const_iterator it = pt.begin(); it != pt.end(); ++it)
{
size += it->first.size();
size += total_keys_size(it->second);
}
return size;
}
template<class Ptree>
typename Ptree::size_type total_data_size(const Ptree &pt)
{
typename Ptree::size_type size = pt.data().size();
for (typename Ptree::const_iterator it = pt.begin(); it != pt.end(); ++it)
size += total_data_size(it->second);
return size;
}
template<class Ch>
class test_file
{
public:
test_file(const char *test_data, const char *filename)
{
if (test_data && filename)
{
name = filename;
std::basic_ofstream<Ch> stream(name.c_str());
while (*test_data)
{
stream << Ch(*test_data);
++test_data;
}
BOOST_CHECK(stream.good());
}
}
~test_file()
{
if (!name.empty())
remove(name.c_str());
}
private:
std::string name;
};
template<class Ptree>
Ptree get_test_ptree()
{
using namespace boost::property_tree;
typedef typename Ptree::key_type::value_type Ch;
Ptree pt;
pt.put_value(detail::widen<Ch>("data0"));
pt.put(detail::widen<Ch>("key1"), detail::widen<Ch>("data1"));
pt.put(detail::widen<Ch>("key1.key"), detail::widen<Ch>("data2"));
pt.put(detail::widen<Ch>("key2"), detail::widen<Ch>("data3"));
pt.put(detail::widen<Ch>("key2.key"), detail::widen<Ch>("data4"));
return pt;
}
// Generic test for file parser
template<class Ptree, class ReadFunc, class WriteFunc>
void generic_parser_test(Ptree &pt,
ReadFunc rf,
WriteFunc wf,
const char *test_data_1,
const char *test_data_2,
const char *filename_1,
const char *filename_2,
const char *filename_out)
{
using namespace boost::property_tree;
typedef typename Ptree::key_type::value_type Ch;
// Create test files
test_file<Ch> file_1(test_data_1, filename_1);
test_file<Ch> file_2(test_data_2, filename_2);
test_file<Ch> file_out("", filename_out);
rf(filename_1, pt); // Read file
wf(filename_out, pt); // Write file
Ptree pt2;
rf(filename_out, pt2); // Read file again
// Compare original with read
BOOST_CHECK(pt == pt2);
}
// Generic test for file parser with expected success
template<class Ptree, class ReadFunc, class WriteFunc>
void generic_parser_test_ok(ReadFunc rf,
WriteFunc wf,
const char *test_data_1,
const char *test_data_2,
const char *filename_1,
const char *filename_2,
const char *filename_out,
unsigned int total_size,
unsigned int total_data_size,
unsigned int total_keys_size)
{
using namespace boost::property_tree;
std::cerr << "(progress) Starting generic parser test with test file \"" << filename_1 << "\"\n";
// Make sure no instances exist
BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
try
{
// Read file
Ptree pt;
generic_parser_test<Ptree, ReadFunc, WriteFunc>(pt, rf, wf,
test_data_1, test_data_2,
filename_1, filename_2, filename_out);
// Determine total sizes
typename Ptree::size_type actual_total_size = ::total_size(pt);
typename Ptree::size_type actual_data_size = ::total_data_size(pt);
typename Ptree::size_type actual_keys_size = ::total_keys_size(pt);
if (actual_total_size != total_size ||
actual_data_size != total_data_size ||
actual_keys_size != total_keys_size)
std::cerr << "Sizes: " << (unsigned)::total_size(pt) << ", " << (unsigned)::total_data_size(pt) << ", " << (unsigned)::total_keys_size(pt) << "\n";
// Check total sizes
BOOST_CHECK(actual_total_size == total_size);
BOOST_CHECK(actual_data_size == total_data_size);
BOOST_CHECK(actual_keys_size == total_keys_size);
}
catch (std::runtime_error &e)
{
BOOST_ERROR(e.what());
}
// Test for leaks
BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
}
// Generic test for file parser with expected error
template<class Ptree, class ReadFunc, class WriteFunc, class Error>
void generic_parser_test_error(ReadFunc rf,
WriteFunc wf,
const char *test_data_1,
const char *test_data_2,
const char *filename_1,
const char *filename_2,
const char *filename_out,
unsigned long expected_error_line)
{
std::cerr << "(progress) Starting generic parser test with test file \"" << filename_1 << "\"\n";
// Make sure no instances exist
BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
{
// Create ptree as a copy of test ptree (to test if read failure does not damage ptree)
Ptree pt(get_test_ptree<Ptree>());
try
{
generic_parser_test<Ptree, ReadFunc, WriteFunc>(pt, rf, wf,
test_data_1, test_data_2,
filename_1, filename_2, filename_out);
BOOST_ERROR("No required exception thrown");
}
catch (Error &e)
{
BOOST_CHECK(e.line() == expected_error_line); // Test line number
BOOST_CHECK(pt == get_test_ptree<Ptree>()); // Test if error damaged contents
}
catch (...)
{
BOOST_ERROR("Invalid exception type thrown");
throw;
}
}
// Test for leaks
BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
}
#endif

View File

@@ -0,0 +1,79 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifndef TEST_XML_PARSER_COMMON_HPP_INCLUDED
#define TEST_XML_PARSER_COMMON_HPP_INCLUDED
#include "test_utils.hpp"
#include <boost/property_tree/xml_parser.hpp>
#include "xml_parser_test_data.hpp"
struct ReadFunc
{
template<class Ptree>
void operator()(const std::string &filename, Ptree &pt) const
{
boost::property_tree::read_xml(filename, pt);
}
};
struct WriteFunc
{
template<class Ptree>
void operator()(const std::string &filename, const Ptree &pt) const
{
boost::property_tree::write_xml(filename, pt);
}
};
template<class Ptree>
void test_xml_parser()
{
using namespace boost::property_tree;
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_1, NULL,
"testok1.xml", NULL, "testok1out.xml", 2, 0, 5
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_2, NULL,
"testok2.xml", NULL, "testok2out.xml", 5, 15, 7
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_3, NULL,
"testok3.xml", NULL, "testok3out.xml", 787, 31346, 3831
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_4, NULL,
"testok4.xml", NULL, "testok4out.xml", 5, 2, 20
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, xml_parser_error>
(
ReadFunc(), WriteFunc(), error_data_1, NULL,
"testerr1.xml", NULL, "testerr1out.xml", 1
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, xml_parser_error>
(
ReadFunc(), WriteFunc(), error_data_2, NULL,
"testerr2.xml", NULL, "testerr2out.xml", 2
);
}
#endif

View File

@@ -0,0 +1,25 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#define _CRT_SECURE_NO_DEPRECATE
#define BOOST_PROPERTY_TREE_XML_PARSER_PUGXML
#include "test_xml_parser_common.hpp"
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_xml_parser<ptree>();
//test_xml_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
//test_xml_parser<wptree>();
//test_xml_parser<wiptree>();
#endif
return 0;
}

View File

@@ -0,0 +1,23 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include "test_xml_parser_common.hpp"
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_xml_parser<ptree>();
test_xml_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
test_xml_parser<wptree>();
test_xml_parser<wiptree>();
#endif
return 0;
}

View File

@@ -0,0 +1,24 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#define BOOST_PROPERTY_TREE_XML_PARSER_SPIRIT
#include "test_xml_parser_common.hpp"
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_xml_parser<ptree>();
test_xml_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
test_xml_parser<wptree>();
test_xml_parser<wiptree>();
#endif
return 0;
}

View File

@@ -0,0 +1,26 @@
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2005 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#ifdef _DEBUG
#pragma comment( lib, "tinyxmld_STL.lib" )
#else
#pragma comment( lib, "tinyxml_STL.lib" )
#endif
#define BOOST_PROPERTY_TREE_XML_PARSER_TINYXML
#include "test_xml_parser_common.hpp"
int test_main(int argc, char *argv[])
{
using namespace boost::property_tree;
test_xml_parser<ptree>();
test_xml_parser<iptree>();
return 0;
}

View File

@@ -0,0 +1,743 @@
#ifndef XML_PARSER_TEST_DATA_HPP_INCLUDED
#define XML_PARSER_TEST_DATA_HPP_INCLUDED
///////////////////////////////////////////////////////////////////////////////
// Test data
// Correct
const char *ok_data_1 =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<start/>";
// Correct
const char *ok_data_2 =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<root>\n"
"<a>&lt;&gt;&amp;</a>\n"
"<b>1&lt;2&gt;3&amp;4</b>\n"
"<c> &lt; &gt; &amp; </c>\n"
"</root>\n";
// Correct
const char *ok_data_3 =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<!DOCTYPE spec PUBLIC \"-//W3C//DTD Specification::19990205//EN\" \"dtds/xmlspec.dtd\" [\n"
"<!ENTITY doc-type \"WD\">\n"
"<!ENTITY iso6.doc.date '29-May-1999'>\n"
"]>\n"
"<!--ArborText, Inc., 1988-1998, v.4002-->\n"
"<?Pub UDT _bookmark _target?>\n"
"<?Pub Inc?>\n"
"<?xml-stylesheet\n"
"href=\"file:///C|/Program%20Files/SoftQuad/XMetaL%201/display/xmlspec.css\"\n"
"type=\"text/css\"?>\n"
"<spec>\n"
"\n"
"<!-- Last edited: 27 May 1999 by bent -->\n"
"<header><?Pub Dtl?>\n"
" <title>XML Linking Language (XLink)</title>\n"
" <version>Version 1.0</version>\n"
" <w3c-designation>WD-xlink-19990527</w3c-designation>\n"
" <w3c-doctype>World Wide Web Consortium Working Draft</w3c-doctype>\n"
" <pubdate><day>29</day><month>May</month><year>1999</year></pubdate>\n"
" <notice>\n"
" <p>This draft is for public discussion.</p>\n"
" </notice>\n"
" <publoc><loc href=\"http://www.w3.org/XML/Group/1999/05/WD-xlink-current\">http://www.w3.org/XML/Group/1999/05/WD-xlink-current</loc></publoc>\n"
" <prevlocs>\n"
" <!--Check: was it actually August?-->\n"
" <loc href=\"http://www.w3.org/XML/Group/1999/05/WD-xlink-19990527\">http://www.w3.org/XML/Group/1999/05/WD-xlink-19990527</loc>\n"
" <loc href=\"http://www.w3.org/XML/Group/1999/05/WD-xlink-19990505\">http://www.w3.org/XML/Group/1999/05/WD-xlink-19990505</loc>\n"
" <loc href=\"http://www.w3.org/TR/1998/WD-xlink-19980303\">http://www.w3.org/TR/1998/WD-xlink-19980303</loc>\n"
" <loc href=\"http://www.w3.org/TR/WD-xml-link-970630\">http://www.w3.org/TR/WD-xml-link-970630</loc></prevlocs>\n"
"\n"
" <authlist>\n"
" <!--Updated author hrefs dorchard-->\n"
" <!-- Update Steve's email - bent --> \n"
" <author>\n"
" <name>Steve DeRose</name>\n"
" <affiliation>Inso Corp. and Brown University</affiliation>\n"
" <email href=\"mailto:Steven_DeRose@Brown.edu\">Steven_DeRose@Brown.edu</email>\n"
" </author>\n"
" <author>\n"
" <name>David Orchard</name>\n"
" <affiliation>IBM Corp.</affiliation>\n"
" <email href=\"mailto:dorchard@ca.ibm.com\">dorchard@ca.ibm.com</email>\n"
" </author>\n"
" <author>\n"
" <name>Ben Trafford</name>\n"
" <affiliation>Invited Expert</affiliation>\n"
" <email href=\"mailto:bent@exemplary.net\">bent@exemplary.net</email>\n"
" </author>\n"
" <!-- I suggest we move Eve and Tim down to the Acknowledgements section. We\n"
" also ought to add Gabe Beged-Dov there, as well. bent\n"
" how shall we cite Tim? sjd What about with an Acknowledgments section?\n"
" -elm <AUTHOR> <NAME>Tim Bray</NAME> <AFFILIATION>Textuality</AFFILIATION>\n"
" <EMAIL>tbray@textuality.com</EMAIL> </AUTHOR>-->\n"
" </authlist>\n"
"\n"
" <status>\n"
" <p>This is a W3C Working Draft for review by W3C members and other interested parties. It is a draft document and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use W3C Working Drafts as reference material or to cite them as other than \"work in progress\". A list of current W3C working drafts can be found at <loc href=\"http://www.w3.org/TR\">http://www.w3.org/TR</loc>.</p>\n"
" <p><emph>Note:</emph> Since working drafts are subject to frequent change, you are advised to reference the above URI, rather than the URIs for working drafts themselves. Some of the work remaining is described in <specref ref=\"unfinished\"/>. </p>\n"
" <p>This work is part of the W3C XML Activity (for current status, see <loc href=\"http://www.w3.org/MarkUp/SGML/Activity\">http://www.w3.org/XML/Activity </loc>). For information about the XPointer language which is expected to be used with XLink, see <loc href=\"http://www.w3.org/MarkUp/SGML/Activity\">http://www.w3.org/TR/WD-xptr</loc>.\n"
" </p>\n"
" <p>See <loc href=\"http://www.w3.org/TR/NOTE-xlink-principles\">http://www.w3.org/TR/NOTE-xlink-principles </loc> for additional background on the design principles informing XLink.</p>\n"
" <p>Also see <loc href=\"http://www.w3.org/TR/NOTE-xlink-req/\">http://www.w3.org/TR/NOTE-xlink-req/</loc> for the XLink requirements that this document attempts to satisfy.</p>\n"
" </status>\n"
"\n"
" <abstract>\n"
" <!-- edited the abstract for further clarity - bent -->\n"
" <p>This specification defines constructs that may be inserted into XML DTDs, schemas and document instances to describe links between objects. It uses XML syntax to create structures that can describe the simple unidirectional hyperlinks of today's HTML as well as more sophisticated links.</p>\n"
" </abstract>\n"
"\n"
" <pubstmt>\n"
" <p>Burlington, Seekonk, et al.: World-Wide Web Consortium, XML Working Group, 1998.</p>\n"
" </pubstmt>\n"
"\n"
" <sourcedesc>\n"
" <p>Created in electronic form.</p>\n"
" </sourcedesc>\n"
"\n"
" <langusage>\n"
" <language id=\"en\">English</language>\n"
" <language id=\"ebnf\">Extended Backus-Naur Form (formal grammar)</language>\n"
" </langusage>\n"
"\n"
" <revisiondesc>\n"
" <slist>\n"
" <sitem>1997-01-15 : Skeleton draft by TB</sitem>\n"
" <sitem>1997-01-24 : Fleshed out by sjd</sitem>\n"
" <sitem>1997-04-08 : Substantive draft</sitem>\n"
" <sitem>1997-06-30 : Public draft</sitem>\n"
" <sitem>1997-08-01 : Public draft</sitem>\n"
" <sitem>1997-08-05 : Prose/organization work by sjd</sitem>\n"
" <sitem>1997-10-14: Conformance and design principles; a bit of cleanup by elm</sitem>\n"
" <sitem>1997-11-07: Update for editorial issues per issues doc, by sjd.</sitem>\n"
" <sitem>1997-12-01: Update for editorial issues per issues doc in preparation for F2F meeting, by sjd.</sitem>\n"
" <sitem>1998-01-13: Editorial cleanup, addition of new design principles, by elm.</sitem>\n"
" <sitem>1998-02-27: Splitting out of XLink and XPointer, by elm.</sitem>\n"
" <sitem>1998-03-03: Moved most of the XPointer locator stuff here. elm</sitem>\n"
" <sitem>1999-04-24: Editorial rewrites to represent new ideas on XLink, especially the inclusion of arcs. bent</sitem>\n"
" <sitem>1999-05-05: Prose/organization work by dorchard. Moved much of the semantics section around, from: locators, link semantics, remote resource semantics, local resource semantics; to: resource semantics, locators, behavior semantics, link semantics, arc semantics</sitem>\n"
" <sitem>1999-05-12: Prose/organization work. Re-organized some of the sections, removed XML constructs from the document, added descriptive prose, edited document text for clarity. Rewrote the link recognition section. bent</sitem>\n"
" <sitem>1999-05-17: Further prose work. Added non-normative examples. Clarified arcs. bent</sitem>\n"
" <sitem>1999-05-23: Edited for grammar and clarity. bent</sitem>\n"
" <sitem>1999-05-27: Final once-over before sending to group. Fixed sjd's email address. bent</sitem>\n"
" </slist>\n"
" </revisiondesc>\n"
"</header>\n"
"\n"
"<body>\n"
" <div1><?Pub Dtl?>\n"
" <head>Introduction</head>\n"
" <p>This specification defines constructs that may be inserted into XML DTDs, schemas, and document instances to describe links between objects. A <termref def=\"dt-link\">link</termref>, as the term is used here, is an explicit relationship between two or more data objects or portions of data objects. This specification is concerned with the syntax used to assert link existence and describe link characteristics. Implicit (unasserted) relationships, for example that of one word to the next or that of a word in a text to its entry in an on-line dictionary are obviously important, but outside its scope.</p>\n"
" <p>Links are asserted by <xtermref href=\"WD-xml-lang.html#dt-element\">elements </xtermref> contained in <xtermref href=\"WD-xml-lang.html#dt-xml-doc\">XML document instances</xtermref>. The simplest case is very like an HTML <code>A</code> link, and has these characteristics:\n"
" <ulist>\n"
" <item><p>The link is expressed at one of its ends (similar to the <code>A</code> element in some document)</p></item>\n"
" <item><p>Users can only initiate travel from that end to the other</p></item>\n"
" <item><p>The link's effect on windows, frames, go-back lists, stylesheets in use, and so on is mainly determined by browsers, not by the link itself. For example, traveral of <code>A</code> links normally replaces the current view, perhaps with a user option to open a new window.</p></item>\n"
" <item><p>The link goes to only one destination (although a server may have great freedom in finding or dynamically creating that destination).</p></item>\n"
" </ulist>\n"
" </p>\n"
" <p>While this set of characteristics is already very powerful and obviously has proven itself highly useful and effective, each of these assumptions also limits the range of hypertext functionality. The linking model defined here provides ways to create links that go beyond each of these specific characteristics, thus providing features previously available mostly in dedicated hypermedia systems.\n"
" </p>\n"
"\n"
"<div2>\n"
" <head>Origin and Goals</head>\n"
" <p>Following is a summary of the design principles governing XLink:\n"
" <olist>\n"
" <item><p>XLink must be straightforwardly usable over the Internet. </p></item>\n"
" <item><p>XLink must be usable by a wide variety of link usage domains and classes of linking application software.</p></item>\n"
" <item><p>XLink must support HTML 4.0 linking constructs.</p></item>\n"
" <item><p>The XLink expression language must be XML.</p></item>\n"
" <item><p>The XLink design must be formal, concise, and illustrative.</p></item>\n"
" <item><p>XLinks must be human-readable and human-writable.</p></item>\n"
" <item><p>XLinks may reside within or outside the documents in which the\n"
" participating resources reside. </p></item>\n"
" <item><p>XLink must represent the abstract structure and significance of links.</p></item>\n"
" <item><p>XLink must be feasible to implement.</p></item>\n"
" <item><p>XLink must be informed by knowledge of established hypermedia systems and standards.</p></item>\n"
" </olist>\n"
" </p>\n"
"</div2>\n"
"<!--Changed the list of requirements to reflect current XLink requirements\n"
"document. bent-->\n"
"\n"
"<div2>\n"
" <head>Relationship to Existing Standards</head>\n"
" <p>Three standards have been especially influential:\n"
" <ulist>\n"
" <item><p><emph>HTML:</emph> Defines several SGML element types that represent links.</p></item>\n"
" <item><p><emph>HyTime:</emph> Defines inline and out-of-line link structures and some semantic features, including traversal control and presentation of objects. <!--Changed from \"placement of objects into a display or other space\" -elm-->\n"
" </p></item>\n"
" <item><p><emph>Text Encoding Initiative Guidelines (TEI P3):</emph> Provides structures for creating links, aggregate objects, and link collections out of them.</p></item>\n"
" </ulist>\n"
" </p>\n"
" <p>Many other linking systems have also informed this design, especially Dexter, FRESS, MicroCosm, and InterMedia.</p>\n"
"</div2>\n"
"\n"
"<div2>\n"
" <head>Terminology</head>\n"
" <p>The following basic terms apply in this document. <!--<IMG\n"
" SRC=\"local://./linkdiag.gif\">(figure to be inserted)-->\n"
" <glist>\n"
" <gitem>\n"
" <label><termdef id=\"dt-arc\" term=\"Arc\">arc</termdef></label>\n"
" <def><p>A symbolic representation of traversal behavior in links, especially the direction, context and timing of traversal.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-eltree\" term=\"Element Tree\">element tree</termdef></label>\n"
" <def><p>A representation of the relevant structure specified by the tags and attributes in an XML document, based on \"groves\" as defined in the ISO DSSSL standard. </p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-inline\" term=\"In-Line Link\">inline link</termdef></label>\n"
" <def><p>Abstractly, a <termref def=\"dt-link\">link</termref> which serves as one of its own <termref def=\"dt-resource\">resources</termref>. Concretely, a link where the content of the <termref def=\"dt-linkel\">linking element</termref> serves as a <termref def=\"dt-particip-resource\">participating resource</termref>.\n"
" HTML <code>A</code>, HyTime <code>clink</code>, and TEI <code>XREF</code>\n"
" are all inline links.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-link\" term=\"Link\">link</termdef></label>\n"
" <def><p>An explicit relationship between two or more data objects or portions of data objects.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-linkel\" term=\"Linking Element\">linking element </termdef></label>\n"
" <def><p>An <xtermref href=\"WD-xml-lang.html#dt-element\">element</xtermref> that asserts the existence and describes the characteristics of a <termref def=\"dt-link\"> link</termref>.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-local-resource\" term=\"Local Resource\">local resource</termdef></label>\n"
" <def><p>The content of an <termref def=\"dt-inline\">inline</termref>linking element. Note that the content of the linking element could be explicitly pointed to by means of a regular <termref def=\"dt-locator\">locator</termref> in the same linking element, in which case the resource is considered <termref def=\"dt-remote-resource\"> remote</termref>, not local.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-locator\" term=\"Locator\">locator</termdef> </label>\n"
" <def><p>Data, provided as part of a link, which identifies a\n"
" <termref def=\"dt-resource\">resource</termref>.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-multidir\" term=\"Multi-Directional Link\">multidirectional link</termdef></label>\n"
" <def><p>A <termref def=\"dt-link\">link</termref> whose <termref def=\"dt-traversal\"> traversal</termref> can be initiated from more than one of its <termref def=\"dt-particip-resource\"> participating resources</termref>. Note that being able to \"go back\" after following a one-directional link does not make the link multidirectional.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-outofline\" term=\"Out-of-line Link\">out-of-line link</termdef></label>\n"
" <def><p>A <termref def=\"dt-link\">link</termref> whose content does not serve as one of the link's <termref def=\"dt-particip-resource\">participating resources </termref>. Such links presuppose a notion like <termref def=\"dt-xlg\">extended link groups</termref>, which instruct application software where to look for links. Out-of-line links are generally required for supporting multidirectional <termref def=\"dt-traversal\">traversal</termref> and for allowing read-only resources to have outgoing links.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-parsedq\" term=\"Parsed\">parsed</termdef></label> <def><p>In the context of link behavior, a parsed link is any link whose content is transcluded into the document where the link originated. The use of the term \"parsed\" directly refers to the concept in XML of a\n"
" parsed entity.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-particip-resource\" term=\"Participating Resource\"> participating resource</termdef></label>\n"
" <def><p>A <termref def=\"dt-resource\">resource</termref> that belongs to a link. All resources are potential contributors to a link; participating resources are the actual contributors to a particular link.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-remote-resource\" term=\"Remote Resource\">remote resource</termdef></label>\n"
" <def><p>Any participating resource of a link that is pointed to with a locator. </p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-resource\" term=\"Resource\">resource</termdef></label>\n"
" <def><p>In the abstract sense, an addressable unit of information or service that is participating in a <termref def=\"dt-link\">link</termref>. Examples include files, images, documents, programs, and query results. Concretely, anything reachable by the use of a <termref def=\"dt-locator\">locator</termref> in some <termref def=\"dt-linkel\">linking element</termref>. Note that this term and its definition are taken from the basic specifications governing the World Wide Web. <!--Joel notes: need link here. bent asks: A link?-->\n"
" </p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-subresource\" term=\"sub-Resource\">sub-resource</termdef></label>\n"
" <def><p>A portion of a resource, pointed to as the precise destination of a link. As one example, a link might specify that an entire document be retrieved and displayed, but that some specific part(s) of it is the specific linked data, to be treated in an application-appropriate manner such as indication by highlighting, scrolling, etc.</p></def>\n"
" </gitem>\n"
" <gitem>\n"
" <label><termdef id=\"dt-traversal\" term=\"Traversal\">traversal</termdef></label>\n"
" <def><p>The action of using a <termref def=\"dt-link\">link</termref>; that is, of accessing a <termref def=\"dt-resource\">resource</termref>. Traversal may be initiated by a user action (for example, clicking on the displayed content of a <termref def=\"dt-linkel\">linking element</termref>) or occur under program control.</p></def>\n"
" </gitem>\n"
" </glist>\n"
" </p>\n"
"</div2>\n"
"\n"
"<div2>\n"
" <head>Notation</head>\n"
" <p>The formal grammar for <termref def=\"dt-locator\">locators</termref> is given using a simple Extended Backus-Naur Form (EBNF) location, as described in <xspecref href=\"http://www.w3.org/TR/REC-xml#sec-notation\">the XML specification</xspecref>.</p>\n"
" <!-- fixed link to XML spec - bent -->\n"
"</div2>\n"
"</div1>\n"
"\n"
"<div1 id=\"addressing\"><?Pub Dtl?>\n"
" <head>Locator Syntax</head>\n"
" <p>The locator for a <termref def=\"dt-resource\">resource</termref> is typically provided by means of a Uniform Resource Identifier, or URI. XPointers can be used in conjunction with the URI structure, as fragment identifiers, to specify a more precise sub-resource. </p>\n"
" <!-- Removed the discussion of queries from the previous paragraph, due to contention within the WG. bent -->\n"
" <p>A locator generally contains a URI, as described in IETF RFCs <bibref ref=\"rfc1738\"/> and <bibref ref=\"rfc1808\"/>. As these RFCs state, the URI may include a trailing <emph>query</emph> (marked by a leading \"<code>?</code>\"), and be followed by a \"<code>#</code>\" and a <emph>fragment identifier</emph>, with the query interpreted by the host providing the indicated resource, and the interpretation of the fragment identifier dependent on the data type of the indicated resource.</p>\n"
" <!--Is there some restriction on URNs having queries and/or fragment identifiers? Since these RFCs don't mention URIs explicitly, should the wording here lead from URLs to URIs more explicitly? -elm-->\n"
" <p>In order to locate XML documents and portions of documents, a locator value may contain either a <xtermref href=\"http://www.w3.org/Addressing/rfc1738.txt\"> URI</xtermref> or a fragment identifier, or both. Any fragment identifier for pointing into XML must be an <xtermref href=\"http://www.w3.org/TR/WD-xptr#dt-xpointer\"> XPointer</xtermref>.</p>\n"
" <p>Special syntax may be used to request the use of particular processing models in accessing the locator's resource. This is designed to reflect the realities of network operation, where it may or may not be desirable to exercise fine control over the distribution of work between local and remote processors. \n"
" <scrap id=\"locator\" lang=\"ebnf\">\n"
" <head>Locator</head>\n"
" <prod id=\"nt-locator\">\n"
" <lhs>Locator</lhs>\n"
" <rhs><nt def=\"nt-uri\">URI</nt></rhs>\n"
" <rhs>| <nt def=\"nt-connector\">Connector</nt> (<xnt href=\"http://www.w3.org/TR/WD-xptr\">XPointer</xnt> | <xnt href=\"WD-xml-lang.html#NT-Name\">Name</xnt>)</rhs>\n"
" <rhs>| <nt def=\"nt-uri\">URI</nt> <nt def=\"nt-connector\">Connector</nt> (<xnt href=\"http://www.w3.org/TR/WD-xptr\">XPointer</xnt> | <xnt href=\"WD-xml-lang.html#NT-Name\">Name</xnt>)</rhs>\n"
" </prod>\n"
" <prod id=\"nt-connector\">\n"
" <lhs>Connector</lhs><rhs>'#' | '|'</rhs>\n"
" </prod>\n"
" <prod id=\"nt-uri\">\n"
" <lhs>URI</lhs><rhs><xnt href=\"WD-xml-lang.html#NT-URLchar\">URIchar*</xnt></rhs>\n"
" </prod>\n"
" </scrap>\n"
" </p>\n"
" <p><termdef id=\"dt-designated\" term=\"Designated Resource\">In this discussion, the term <term>designated resource</term> refers to the resource which an entire locator serves to locate.</termdef> The following rules apply:\n"
" <ulist>\n"
" <item>\n"
" <p><termdef id=\"dt-containing-resource\" term=\"Containing Resource\"> The URI, if provided, locates a resource called the <term>containing resource</term>.</termdef></p>\n"
" </item>\n"
" <item>\n"
" <p>If the URI is not provided, the containing resource is considered to be the document in which the linking element is contained. \n"
" </p></item>\n"
" <item>\n"
" <p><termdef id=\"dt-sub-resource\" term=\"Sub-Resource\">If an XPointer is provided, the designated resource is a <term>sub-resource</term>\n"
" of the containing resource; otherwise the designated resource is the\n"
" containing resource.</termdef></p>\n"
" </item>\n"
" <!--Is this now incorrect, given the nature of the switch from here() to origin()? -elm \n"
" Oy, yes, i think so. it will require some fun wording, though, so i haven't fixed it yet here -sjd-->\n"
" <item>\n"
" <p>If the <nt def=\"nt-connector\">Connector</nt> is followed directly by a <xnt href=\"http://www.w3.org/TR/REC-xml#NT-Name\">Name</xnt>, the <xnt href=\"http://www.w3.org/TR/REC-xml#NT-Name\">Name</xnt> is shorthand for the XPointer\"<code>id(Name)</code>\"; that is, the sub-resource is the element in the containing resource that has an XML <xtermref href=\"http://www.w3.org/TR/REC-xml#sec-attrtypes\">ID attribute</xtermref> whose value <xtermref href=\"http://www.w3.org/TR/REC-xml#dt-match\">matches</xtermref> the <xnt href=\"http://www.w3.org/TR/REC-xml#NT-Name\">Name</xnt>. This shorthand is to encourage use of the robust <code>id</code> addressing mode.</p>\n"
" </item>\n"
" <!-- fixed links to the XML recommendation - bent -->\n"
" <item>\n"
" <p>If the connector is \"<code>#</code>\", this signals an intent that the containing resource is to be fetched as a whole from the host that provides it, and that the XPointer processing to extract the sub-resource\n"
" is to be performed on the client, that is to say on the same system where the linking element is recognized and processed.</p>\n"
" </item>\n"
" <item>\n"
" <p>If the connector is \"<code>|</code>\", no intent is signaled as to what processing model is to be used to go about accessing the designated resource.</p>\n"
" </item>\n"
" </ulist>\n"
" </p>\n"
" <p>Note that the definition of a URI includes an optional query component. </p>\n"
" <p>In the case where the URI contains a query (to be interpreted by the server), information providers and authors of server software are urged to use queries as follows: \n"
" <scrap id=\"querysyntax\" lang=\"ebnf\">\n"
" <head>Query</head>\n"
" <prod id=\"nt-query\">\n"
" <lhs>Query</lhs><rhs>'XML-XPTR=' (<xnt href=\"http://www.w3.org/TR/WD-xptr\"> XPointer</xnt> | <xnt href=\"http://www.w3.org/TR/REC-xml#NT-Name\">Name</xnt>)</rhs>\n"
" </prod>\n"
" </scrap>\n"
" </p>\n"
" <!-- fixed link to XML recommendation - bent -->\n"
"</div1>\n"
"\n"
"<div1><?Pub Dtl?>\n"
" <head>Link Recognition</head>\n"
" <p>The existence of a <termref def=\"dt-link\">link</termref> is asserted by a <termref def=\"dt-linkel\">linking element</termref>. Linking elements must be recognized reliably by application software in order to provide appropriate display and behavior. There are several ways link recognition could be accomplished: for example, reserving element type names, reserving attributes names, leaving the matter of recognition entirely up to stylesheets and application software, or using the XLink <xtermref href=\"http://www.w3.org/TR/REC-xml-names/\">namespace</xtermref> to specify element names and attribute names that would be recognized by namespace and XLink-aware processors. Using element and attribute names within the XLink namespace provides a balance between giving users control of their own markup language design and keeping the identification of linking elements simple and unambiguous.</p>\n"
" <p>The two approaches to identifying linking elements are relatively simple to implement. For example, here's how the HTML <code>A</code> element would be declared using attributes within the XLink namespace, and then how an element within the XLink namespace might do the same:\n"
" <eg>&lt;A xlink:type=\"simple\" xlink:href=\"http://www.w3.org/TR/wd-xlink/\"\n"
"xlink:title=\"The Xlink Working Draft\"&gt;The XLink Working Draft.&lt;/A&gt;</eg>\n"
" <eg>&lt;xlink:simple href=\"http://www.w3.org/TR/wd-xlink/\"\n"
"title=\"The XLink Working Draft\"&gt;The XLink Working Draft&lt;/xlink:simple&gt;</eg>\n"
" Any arbitrary element can be made into an XLink by using the <code>xlink:type</code> attribute. And, of course, the explicit XLink elements may be used, as well. This document will go on to describe the linking attributes that are associated with linking elements. It may be assumed by the reader that these attributes would require the <code>xlink</code> namespace prefix if they existed within an arbitrary element, or that they may be used directly if they exist within an explicit Xlink element.</p>\n"
" <!-- heavily modified this section to accomodate namespace-aware link recognition - bent -->\n"
"</div1>\n"
"\n"
"<!-- Rewrote this entire section. - bent -->\n"
"<div1>\n"
" <head>Linking Attributes</head>\n"
" <p>XLink has several attributes associated with the variety of links it may represent. These attributes define four main concepts: locators, arcs, behaviors, and semantics. <emph>Locators</emph> define where the actual resource is located. <emph>Arcs</emph> define the traversal of links. Where does the link come from? Where does it go to? All this information can be stored in the arc attributes. <emph>Behaviors</emph> define how the link is activated, and what the application should do with the resource being linked to. <emph>Semantics</emph> define useful information that the application may use, and enables the link for such specalized targets as constricted devices and accessibility software.</p>\n"
" \n"
" <div2 id=\"link-locators\">\n"
" <head>Locator Attributes</head>\n"
" <p>The only locator attribute at this time is <code>href</code>. This attribute must contain either a string in the form of a URI that defines the remote resource being linked to, a string containing a fragment identifier that links to a local resource, or a string containing a URI with a fragment identifier concacenated onto it.</p>\n"
" </div2>\n"
"\n"
" <div2 id=\"link-arcs\">\n"
" <head>Arc Attributes</head>\n"
" <p>Arcs contain two attributes, <code>from</code> and <code>to</code>. The <code>from</code> attribute may contain a string containing the content of a <code>role</code> attribute from the resource being linked from. The purpose of the <code>from</code> attribute is to define where this link is being actuated from.</p>\n"
" <p>The <code>to</code> attribute may contain a string containing the content of a <code>role</code> attribute from the resource being linked to. The purpose of the <code>to</code> attribute is to define where this link traverses to.</p>\n"
" <p>The application may use this information in a number of ways, especially in a complex hypertext system, but it is mainly useful in providing context for application behavior.</p>\n"
" <!-- I'm at a loss as to how to describe arcs more clearly than this. I don't want to devolve into discussions of directed graphs and n-ary links. -bent -->\n"
" </div2>\n"
"\n"
" <div2 id=\"link-behaviors\">\n"
" <head>Behavior Attributes</head>\n"
" <p>There are two attributes associated with behavior: <code>show</code> and <code>actuate</code>. The <code>show</code> attribute defines how the remote resource is to be revealed to the user. It has three options: <code>new</code>, <code>parsed</code>, and <code>replace</code>. The <code>new</code> option indicates that the remote resource should be shown in a new window (or other device context) without replacing the previous content. The <code>parsed</code> option, relating directly to the XML concept of a parsed entity, indicates that the content should be integrated into the document from which the link was actuated. The <code>replace</code> option is the one most commonly seen on the World Wide Web, where the document being linked from is entirely replaced by the object being linked to.</p>\n"
" <p>The <code>actuate</code> attribute defines how the link is initiated. It has two options: <code>user</code> and <code>auto</code>. The <code>user</code> option indicates that the link must be initiated by some sort of human-initiated selection, such as clicking on an HTML anchor. The <code>auto</code> option indicates that the link is automatically initiated when the application deems that the user has reached the link. It then follows the behavior set out in the <code>show</code> option.</p>\n"
" <!-- Something should be put here in terms of an example. Idea: \"A\" link versus automatically updating encyclopedia. -bent -->\n"
" </div2>\n"
"\n"
" <div2 id=\"link-semantics\">\n"
" <head>Semantic Attributes</head>\n"
" <p>There are two attributes associated with semantics, <code>role</code> and <code>title</code>. The <code>role</code> attribute is a generic string used to describe the function of the link's content. For example, a poem might have a link with a <code>role=\"stanza\"</code>. The <code>role</code> is also used as an identifier for the <code>from</code> and <code>to</code> attributes of arcs.</p>\n"
" <p>The <code>title</code> attribute is designed to provide human-readable text describing the link. It is very useful for those who have text-based applications, whether that be due to a constricted device that cannot display the link's content, or if it's being read by an application to a visually-impaired user, or if it's being used to create a table of links. The <code>title</code> attribute contains a simple, descriptive string.</p>\n"
" </div2>\n"
"</div1>\n"
"\n"
"<div1 id=\"linking-elements\">\n"
" <head>Linking Elements</head>\n"
" <p>There are several kinds of linking elements in XLink: <code>simple</code> links, <code>locators</code>, <code>arcs</code>, and <code>extended</code> links. These elements may be instantiated via element declarations from the XLink namespace, or they may be instantiated via attribute declarations from the XLink namespace. Both kinds of instantiation are described in the definition of each linking element.</p>\n"
" <p>The <code>simple</code> link is used to declare a link that approximates the functionality of the HTML <code>A</code> element. It has, however, a few added features to increase its value, including the potential declaration of semantics and behavior. The <code>locator</code> elements are used to define the resource being linked to. Some links may contain multiple locators, representing a choice of potential links to be traversed. The <code>arcs</code> are used to define the traversal semantics of the link. Finally, an <code>extended</code> linking element differs from a simple link in that it can connect any number of resources, not just one local resource (optionally) and one remote resource, and in that extended links are more often out-of-line than simple links.</p>\n"
"\n"
"<div2 id=\"simple-links\">\n"
" <head>Simple Links</head>\n"
" <p id=\"dt-simplelink\"><termdef id=\"dt-simpleline\" term=\"Simple Link\"><term>Simple links</term> can be used for purposes that approximate the functionality of a basic HTML <code>A</code> link, but they can also support a limited amount of additional functionality. Simple links have only one locator and thus, for convenience, combine the functions of a linking element and a locator into a single element.</termdef> As a result of this combination, the simple linking element offers both a locator attribute and all the behavior and semantic attributes.</p>\n"
" <p>The following are two examples of linking elements, each showing all the possible attributes that can be associated with a simple link. Here is the explicit XLink simple linking element.\n"
" <eg>&lt;!ELEMENT xlink:simple ANY&gt;\n"
"&lt;!ATTLIST xlink:slink\n"
" href CDATA #REQUIRED\n"
" role CDATA #IMPLIED\n"
" title CDATA #IMPLIED\n"
" show (new|parsed|replace) \"replace\"\n"
" actuate (user|auto) \"user\"\n"
"&gt;</eg>\n"
" And here is how to make an arbitrary element into a simple link.\n"
" <eg>&lt;!ELEMENT xlink:simple ANY&gt;\n"
"&lt;!ATTLIST foo\n"
" xlink:type (simple|extended|locator|arc) #FIXED \"simple\" \n"
" xlink:href CDATA #REQUIRED\n"
" xlink:role CDATA #IMPLIED\n"
" xlink:title CDATA #IMPLIED\n"
" xlink:show (new|parsed|replace) \"replace\"\n"
" xlink:actuate (user|auto) \"user\"\n"
"&gt;</eg>\n"
" Here is how the first example might look in a document:\n"
"<eg>&lt;xlink:simple href=\"http://www.w3.org/TR/wd-xlink\" role=\"working draft\" \n"
" title=\"The XLink Working Draft\" show=\"replace\" actuate=\"user\"&gt;\n"
"The XLink Working Draft.&lt;/xlink:simple&gt;</eg>\n"
"<eg>&lt;foo xlink:href=\"http://www.w3.org/TR/wd-xlink\" xlink:role=\"working draft\"\n"
" xlink:title=\"The XLink Working Draft\" xlink:show=\"new\" xlink:actuate=\"user\"&gt;\n"
"The XLink Working Draft.&lt;/foo&gt;</eg>\n"
" Alternately, a simple link could be as terse as this:\n"
"<eg>&lt;foo xlink:href=\"#stanza1\"&gt;The First Stanza.&lt;/foo&gt;</eg>\n"
" </p>\n"
" <p>\n"
" There are no constraints on the contents of a simple linking element. In\n"
" the sample declaration above, it is given a content model of <code>ANY</code>\n"
" to illustrate that any content model or declared content is acceptable. In\n"
" a valid document, every element that is significant to XLink must still conform\n"
" to the constraints expressed in its governing DTD.</p>\n"
" <p>Note that it is meaningful to have an out-of-line simple link, although\n"
" such links are uncommon. They are called \"one-ended\" and are typically used\n"
" to associate discrete semantic properties with locations. The properties might\n"
" be expressed by attributes on the link, the link's element type name, or in\n"
" some other way, and are not considered full-fledged resources of the link.\n"
" Most out-of-line links are extended links, as these have a far wider range\n"
" of uses.</p>\n"
"</div2>\n"
"\n"
"<div2 id=\"extended-link\">\n"
"<head>Extended Links</head>\n"
" <p><termdef id=\"dt-extendedlink\" term=\"Extended Link\">An <term>extended link</term> differs from a simple link in that it can connect any number of resources, not just one local resource (optionally) and one remote resource, and in that extended links are more often out-of-line than simple links.</termdef></p>\n"
" <p>These additional capabilities of extended links are required for: \n"
" <ulist>\n"
" <item>\n"
" <p>Enabling outgoing links in documents that cannot be modified to add an inline link</p>\n"
" </item>\n"
" <item>\n"
" <p>Creating links to and from resources in formats with no native support for embedded links (such as most multimedia formats)</p>\n"
" </item>\n"
" <item>\n"
" <p>Applying and filtering sets of relevant links on demand</p>\n"
" </item>\n"
" <item><p>Enabling other advanced hypermedia capabilities</p></item>\n"
" </ulist>\n"
" </p>\n"
" <p>Application software might be expected to provide traversal among all of a link's participating resources (subject to semantic constraints outside the scope of this specification) and to signal the fact that a given resource or sub-resource participates in one or more links when it is displayed (even though there is no markup at exactly that point to signal it).</p>\n"
" <p>A linking element for an extended link contains a series of <xtermref href=\"http://www.w3.org/TR/REC-xml/#dt-parentchild\">child elements</xtermref> that serve as locators and arcs. Because an extended link can have more than one remote resource, it separates out linking itself from the mechanisms used to locate each resource (whereas a simple link combines the two).</p>\n"
" <p>The <code>xlink:type</code> attribute value for an extended link must be <code> extended</code>, if the link is being instantiated on an arbitrary element. Note that extended links introduce variants of the <code>show</code> and <code>actuate</code> behavior attributes. These attributes, the <code>showdefault</code> and <code>actuatedefault</code> define the same behavior as their counterparts. However, in this case, they are considered to define the default behavior for all the linking elements that they contain.</p>\n"
" <p>However, when a linking element within an extended link has a <code>show</code> or <code>actuate</code> attribute of its own, that attribute overrides the defaults set on the extended linking element.</p>\n"
" <p>The extended linking element itself retains those attributes relevant to the link as a whole, and to its local resource if any. Following are two sample declaration for an extended link. The first is an example of the explicit XLink extended link:\n"
" \n"
"<eg>&lt;!ELEMENT xlink:extended ((xlink:arc | xlink:locator)*)>\n"
"&lt;!ATTLIST xlink:extended\n"
" role CDATA #IMPLIED\n"
" title CDATA #IMPLIED\n"
" showdefault (new|parsed|replace) #IMPLIED \n"
" actuatedefault (user|auto) #IMPLIED &gt;</eg>\n"
"\n"
" The second is an example of an arbitrary element being used an extended link:\n"
"\n"
"<eg>&lt;!ELEMENT foo ((xlink:arc | xlink:locator)*)>\n"
"&lt;!ATTLIST foo\n"
" xlink:type (simple|extended|locator|arc) #FIXED \"extended\"\n"
" xlink:role CDATA #IMPLIED\n"
" xlink:title CDATA #IMPLIED\n"
" xlink:showdefault (new|parsed|replace) #IMPLIED \n"
" xlink:actuatedefault (user|auto) #IMPLIED &gt;</eg>\n"
"\n"
" The following two examples demonstrate how each of the above might appear within a document instance. Note that the content of these examples would be other elements. For brevity's sake, they've been left blank. The first example shows how the link might appear, using an explicit XLink extended link:\n"
"\n"
"<eg>&lt;xlink:extended role=\"address book\" title=\"Ben's Address Book\" showdefault=\"replace\" actuatedefault=\"user\"&gt; ... &lt;/xlink:extended&gt;</eg>\n"
"\n"
" And the second shows how the link might appear, using an arbitrary element:\n"
"\n"
"<eg>&lt;foo xlink:type=\"extended\" xlink:role=\"address book\" xlink:title=\"Ben's Address Book\" xlink:showdefault=\"replace\" xlink:actuatedefault=\"user\"&gt; ... &lt;/foo&gt;</eg>\n"
" </p>\n"
"\n"
"</div2>\n"
"\n"
"<div2 id=\"xlink-arcs\">\n"
" <head>Arc Elements</head>\n"
" <p><termdef id=\"dt-arc\" term=\"Arc\">An <term>arc</term> is contained within an extended link for the purpose of defining traversal behavior.</termdef> More than one arc may be associated with a link. Otherwise, arc elements function exactly as the arc attributes might lead on to expect.</p>\n"
" <!-- More here? -bent -->\n"
"</div2>\n"
"\n"
"</div1>\n"
"<div1>\n"
"<head>Conformance</head>\n"
"<p>An element conforms to XLink if: <olist>\n"
"<item><p>The element has an <code>xml:link</code> attribute whose value is\n"
"one of the attribute values prescribed by this specification, and</p></item>\n"
"<item><p>the element and all of its attributes and content adhere to the\n"
"syntactic\n"
"requirements imposed by the chosen <code>xml:link</code> attribute value,\n"
"as prescribed in this specification.</p></item>\n"
"</olist></p>\n"
"<p>Note that conformance is assessed at the level of individual elements,\n"
"rather than whole XML documents, because XLink and non-XLink linking mechanisms\n"
"may be used side by side in any one document.</p>\n"
"<p>An application conforms to XLink if it interprets XLink-conforming elements\n"
"according to all required semantics prescribed by this specification and,\n"
"for any optional semantics it chooses to support, supports them in the way\n"
"prescribed. <!--If/when we split out the XLinkfunctionality\n"
"(e.g. inline links and out-of-line links), the\n"
"conformance language will have to address the different\n"
"levels of support. -elm--> </p>\n"
"</div1>\n"
"</body><back>\n"
"<div1 id=\"unfinished\">\n"
"<head>Unfinished Work</head>\n"
"<div2>\n"
"<head>Structured Titles</head>\n"
"<p>The simple title mechanism described in this draft is insufficient to cope\n"
"with internationalization or the use of multimedia in link titles. A future\n"
"version will provide a mechanism for the use of structured link titles.</p>\n"
"</div2>\n"
"</div1>\n"
"<div1>\n"
"<head>References</head>\n"
"<blist>\n"
"<bibl id=\"xptr\" key=\"XPTR\">Eve Maler and Steve DeRose, editors. <titleref>\n"
"XML Pointer Language (XPointer) V1.0</titleref>. ArborText, Inso, and Brown\n"
"University. Burlington, Seekonk, et al.: World Wide Web Consortium, 1998.\n"
"(See <loc href=\"http://www.w3.org/TR/WD-xptr\">http://www.w3.org/TR/WD-xptr\n"
" </loc>.)</bibl>\n"
"<bibl id=\"iso10744\" key=\"ISO/IEC 10744\">ISO (International Organization for\n"
"Standardization). <titleref>ISO/IEC 10744-1992 (E). Information technology\n"
"- Hypermedia/Time-based Structuring Language (HyTime).</titleref> [Geneva]:\n"
"International Organization for Standardization, 1992. <titleref>Extended\n"
"Facilities\n"
"Annex.</titleref> [Geneva]: International Organization for Standardization,\n"
"1996. (See <loc\n"
"href=\"http://www.ornl.gov/sgml/wg8/hytime/html/is10744r.html\">http://www.ornl.go\n"
"v/sgml/wg8/hytime/html/is10744r.html </loc> <!--p m-r says this link is\n"
"broken. elm --> ).</bibl>\n"
"<bibl id=\"rfc1738\" key=\"IETF RFC 1738\">IETF (Internet Engineering Task\n"
"Force). <titleref>\n"
"RFC 1738: Uniform Resource Locators</titleref>. 1991. (See <loc\n"
"href=\"http://www.w3.org/Addressing/rfc1738.txt\">\n"
"http://www.w3.org/Addressing/rfc1738.txt</loc>).</bibl>\n"
"<bibl id=\"rfc1808\" key=\"IETF RFC 1808\">IETF (Internet Engineering Task\n"
"Force). <titleref>\n"
"RFC 1808: Relative Uniform Resource Locators</titleref>. 1995. (See <loc\n"
"href=\"http://www.w3.org/Addressing/rfc1808.txt\">http://www.w3.org/Addressing/rfc\n"
"1808.txt </loc>).</bibl>\n"
"<bibl id=\"tei\" key=\"TEI\">C. M. Sperberg-McQueen and Lou Burnard, editors.\n"
"<titleref>\n"
"Guidelines for Electronic Text Encoding and Interchange</titleref>. Association\n"
"for Computers and the Humanities (ACH), Association for Computational\n"
"Linguistics\n"
"(ACL), and Association for Literary and Linguistic Computing (ALLC). Chicago,\n"
"Oxford: Text Encoding Initiative, 1994. <!-- add cite to DOM work --> </bibl>\n"
"<bibl id=\"chum\" key=\"CHUM\">]Steven J. DeRose and David G. Durand. 1995. \"The\n"
"TEI Hypertext Guidelines.\" In <titleref>Computing and the Humanities\n"
"</titleref>29(3).\n"
"Reprinted in <titleref>Text Encoding Initiative: Background and\n"
"Context</titleref>,\n"
"ed. Nancy Ide and Jean ronis <!-- fix this name -->, ISBN 0-7923-3704-2. </bibl>\n"
"</blist></div1>\n"
"</back></spec>\n"
"<?Pub *0000052575?>\n";
// Correct
const char *ok_data_4 =
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<!DOCTYPE rss [\n"
"<!--\n"
"\n"
" Rich Site Summary (RSS) 0.91 official DTD, proposed.\n"
" \n"
" RSS is an XML vocabulary for describing\n"
" metadata about websites, and enabling the display of\n"
" \"channels\" on the \"My Netscape\" website.\n"
" \n"
" RSS Info can be found at http://my.netscape.com/publish/\n"
" XML Info can be found at http://www.w3.org/XML/ \n"
" \n"
" copyright Netscape Communications, 1999\n"
"\n"
" Dan Libby - danda@netscape.com\n"
" \n"
" Based on RSS DTD originally created by\n"
" Lars Marius Garshol - larsga@ifi.uio.no.\n"
" $Id$\n"
" \n"
"-->\n"
"<!ELEMENT rss (channel)>\n"
"<!ATTLIST rss version CDATA #REQUIRED>\n"
"<!-- must be \"0.91\"> --><!ELEMENT channel (title | description | link \n"
"| language | item+ | rating? | image? | textinput? | copyright? | \n"
"pubDate? | lastBuildDate? | docs? | managingEditor? | webMaster? | \n"
"skipHours? | skipDays?)*>\n"
"<!ELEMENT title (#PCDATA)>\n"
"<!ELEMENT description (#PCDATA)>\n"
"<!ELEMENT link (#PCDATA)>\n"
"<!ELEMENT image (title | url | link | width? | height? | description?)*>\n"
"<!ELEMENT url (#PCDATA)>\n"
"<!ELEMENT item (title | link | description)*>\n"
"<!ELEMENT textinput (title | description | name | link)*>\n"
"<!ELEMENT name (#PCDATA)>\n"
"<!ELEMENT rating (#PCDATA)>\n"
"<!ELEMENT language (#PCDATA)>\n"
"<!ELEMENT width (#PCDATA)>\n"
"<!ELEMENT height (#PCDATA)>\n"
"<!ELEMENT copyright (#PCDATA)>\n"
"<!ELEMENT pubDate (#PCDATA)>\n"
"<!ELEMENT lastBuildDate (#PCDATA)>\n"
"<!ELEMENT docs (#PCDATA)>\n"
"<!ELEMENT managingEditor (#PCDATA)>\n"
"<!ELEMENT webMaster (#PCDATA)>\n"
"<!ELEMENT hour (#PCDATA)>\n"
"<!ELEMENT day (#PCDATA)>\n"
"<!ELEMENT skipHours (hour)+>\n"
"<!ELEMENT skipDays (day)+>\n"
"<!--\n"
" Copied from HTML 3.2 DTD, with modifications (removed CDATA)\n"
" http://www.w3.org/TR/REC-html32.html#dtd\n"
" =============== BEGIN ===================\n"
"-->\n"
"<!-- \n"
" Character Entities for ISO Latin-1\n"
" \n"
" (C) International Organization for Standardization 1986\n"
" Permission to copy in any form is granted for use with\n"
" conforming SGML systems and applications as defined in\n"
" ISO 8879, provided this notice is included in all copies.\n"
" This has been extended for use with HTML to cover the full\n"
" set of codes in the range 160-255 decimal.\n"
"-->\n"
"<!-- Character entity set. Typical invocation:\n"
" <!ENTITY % ISOlat1 PUBLIC\n"
" \"ISO 8879-1986//ENTITIES Added Latin 1//EN//HTML\">\n"
" %ISOlat1;\n"
"-->\n"
"<!ENTITY nbsp \"&#160;\"> <!-- no-break space -->\n"
"<!ENTITY iexcl \"&#161;\">\n"
"<!-- inverted exclamation mark --><!ENTITY cent \"&#162;\">\n"
"<!-- cent sign --><!ENTITY pound \"&#163;\">\n"
"<!-- pound sterling sign --><!ENTITY curren \"&#164;\">\n"
"<!-- general currency sign --><!ENTITY yen \"&#165;\">\n"
"<!-- yen sign --><!ENTITY brvbar \"&#166;\">\n"
"<!-- broken (vertical) bar --><!ENTITY sect \"&#167;\">\n"
"<!-- section sign --><!ENTITY uml \"&#168;\">\n"
"<!-- umlaut (dieresis) --><!ENTITY copy \"&#169;\">\n"
"<!-- copyright sign --><!ENTITY ordf \"&#170;\">\n"
"<!-- ordinal indicator, feminine --><!ENTITY laquo \"&#171;\">\n"
"<!-- angle quotation mark, left --><!ENTITY not \"&#172;\">\n"
"<!-- not sign --><!ENTITY shy \"&#173;\">\n"
"<!-- soft hyphen --><!ENTITY reg \"&#174;\">\n"
"<!-- registered sign --><!ENTITY macr \"&#175;\">\n"
"<!-- macron --><!ENTITY deg \"&#176;\">\n"
"<!-- degree sign --><!ENTITY plusmn \"&#177;\">\n"
"<!-- plus-or-minus sign --><!ENTITY sup2 \"&#178;\">\n"
"<!-- superscript two --><!ENTITY sup3 \"&#179;\">\n"
"<!-- superscript three --><!ENTITY acute \"&#180;\">\n"
"<!-- acute accent --><!ENTITY micro \"&#181;\">\n"
"<!-- micro sign --><!ENTITY para \"&#182;\">\n"
"<!-- pilcrow (paragraph sign) --><!ENTITY middot \"&#183;\">\n"
"<!-- middle dot --><!ENTITY cedil \"&#184;\">\n"
"<!-- cedilla --><!ENTITY sup1 \"&#185;\">\n"
"<!-- superscript one --><!ENTITY ordm \"&#186;\">\n"
"<!-- ordinal indicator, masculine --><!ENTITY raquo \"&#187;\">\n"
"<!-- angle quotation mark, right --><!ENTITY frac14 \"&#188;\">\n"
"<!-- fraction one-quarter --><!ENTITY frac12 \"&#189;\">\n"
"<!-- fraction one-half --><!ENTITY frac34 \"&#190;\">\n"
"<!-- fraction three-quarters --><!ENTITY iquest \"&#191;\">\n"
"<!-- inverted question mark --><!ENTITY Agrave \"&#192;\">\n"
"<!-- capital A, grave accent --><!ENTITY Aacute \"&#193;\">\n"
"<!-- capital A, acute accent --><!ENTITY Acirc \"&#194;\">\n"
"<!-- capital A, circumflex accent --><!ENTITY Atilde \"&#195;\">\n"
"<!-- capital A, tilde --><!ENTITY Auml \"&#196;\">\n"
"<!-- capital A, dieresis or umlaut mark --><!ENTITY Aring \"&#197;\">\n"
"<!-- capital A, ring --><!ENTITY AElig \"&#198;\">\n"
"<!-- capital AE diphthong (ligature) --><!ENTITY Ccedil \"&#199;\">\n"
"<!-- capital C, cedilla --><!ENTITY Egrave \"&#200;\">\n"
"<!-- capital E, grave accent --><!ENTITY Eacute \"&#201;\">\n"
"<!-- capital E, acute accent --><!ENTITY Ecirc \"&#202;\">\n"
"<!-- capital E, circumflex accent --><!ENTITY Euml \"&#203;\">\n"
"<!-- capital E, dieresis or umlaut mark --><!ENTITY Igrave \"&#204;\">\n"
"<!-- capital I, grave accent --><!ENTITY Iacute \"&#205;\">\n"
"<!-- capital I, acute accent --><!ENTITY Icirc \"&#206;\">\n"
"<!-- capital I, circumflex accent --><!ENTITY Iuml \"&#207;\">\n"
"<!-- capital I, dieresis or umlaut mark --><!ENTITY ETH \"&#208;\">\n"
"<!-- capital Eth, Icelandic --><!ENTITY Ntilde \"&#209;\">\n"
"<!-- capital N, tilde --><!ENTITY Ograve \"&#210;\">\n"
"<!-- capital O, grave accent --><!ENTITY Oacute \"&#211;\">\n"
"<!-- capital O, acute accent --><!ENTITY Ocirc \"&#212;\">\n"
"<!-- capital O, circumflex accent --><!ENTITY Otilde \"&#213;\">\n"
"<!-- capital O, tilde --><!ENTITY Ouml \"&#214;\">\n"
"<!-- capital O, dieresis or umlaut mark --><!ENTITY times \"&#215;\">\n"
"<!-- multiply sign --><!ENTITY Oslash \"&#216;\">\n"
"<!-- capital O, slash --><!ENTITY Ugrave \"&#217;\">\n"
"<!-- capital U, grave accent --><!ENTITY Uacute \"&#218;\">\n"
"<!-- capital U, acute accent --><!ENTITY Ucirc \"&#219;\">\n"
"<!-- capital U, circumflex accent --><!ENTITY Uuml \"&#220;\">\n"
"<!-- capital U, dieresis or umlaut mark --><!ENTITY Yacute \"&#221;\">\n"
"<!-- capital Y, acute accent --><!ENTITY THORN \"&#222;\">\n"
"<!-- capital THORN, Icelandic --><!ENTITY szlig \"&#223;\">\n"
"<!-- small sharp s, German (sz ligature) --><!ENTITY agrave \"&#224;\">\n"
"<!-- small a, grave accent --><!ENTITY aacute \"&#225;\">\n"
"<!-- small a, acute accent --><!ENTITY acirc \"&#226;\">\n"
"<!-- small a, circumflex accent --><!ENTITY atilde \"&#227;\">\n"
"<!-- small a, tilde --><!ENTITY auml \"&#228;\">\n"
"<!-- small a, dieresis or umlaut mark --><!ENTITY aring \"&#229;\">\n"
"<!-- small a, ring --><!ENTITY aelig \"&#230;\">\n"
"<!-- small ae diphthong (ligature) --><!ENTITY ccedil \"&#231;\">\n"
"<!-- small c, cedilla --><!ENTITY egrave \"&#232;\">\n"
"<!-- small e, grave accent --><!ENTITY eacute \"&#233;\">\n"
"<!-- small e, acute accent --><!ENTITY ecirc \"&#234;\">\n"
"<!-- small e, circumflex accent --><!ENTITY euml \"&#235;\">\n"
"<!-- small e, dieresis or umlaut mark --><!ENTITY igrave \"&#236;\">\n"
"<!-- small i, grave accent --><!ENTITY iacute \"&#237;\">\n"
"<!-- small i, acute accent --><!ENTITY icirc \"&#238;\">\n"
"<!-- small i, circumflex accent --><!ENTITY iuml \"&#239;\">\n"
"<!-- small i, dieresis or umlaut mark --><!ENTITY eth \"&#240;\">\n"
"<!-- small eth, Icelandic --><!ENTITY ntilde \"&#241;\">\n"
"<!-- small n, tilde --><!ENTITY ograve \"&#242;\">\n"
"<!-- small o, grave accent --><!ENTITY oacute \"&#243;\">\n"
"<!-- small o, acute accent --><!ENTITY ocirc \"&#244;\">\n"
"<!-- small o, circumflex accent --><!ENTITY otilde \"&#245;\">\n"
"<!-- small o, tilde --><!ENTITY ouml \"&#246;\">\n"
"<!-- small o, dieresis or umlaut mark --><!ENTITY divide \"&#247;\">\n"
"<!-- divide sign --><!ENTITY oslash \"&#248;\">\n"
"<!-- small o, slash --><!ENTITY ugrave \"&#249;\">\n"
"<!-- small u, grave accent --><!ENTITY uacute \"&#250;\">\n"
"<!-- small u, acute accent --><!ENTITY ucirc \"&#251;\">\n"
"<!-- small u, circumflex accent --><!ENTITY uuml \"&#252;\">\n"
"<!-- small u, dieresis or umlaut mark --><!ENTITY yacute \"&#253;\">\n"
"<!-- small y, acute accent --><!ENTITY thorn \"&#254;\">\n"
"<!-- small thorn, Icelandic --><!ENTITY yuml \"&#255;\">\n"
"<!-- small y, dieresis or umlaut mark --><!--\n"
" Copied from HTML 3.2 DTD, with modifications (removed CDATA)\n"
" http://www.w3.org/TR/REC-html32.html#dtd\n"
" ================= END ===================\n"
"-->\n"
"]>\n"
"<rss>\n"
"<channel>\n"
"<image/>\n"
"<title>PP</title>\n"
"</channel>\n"
"</rss>\n";
// Erroneous
const char *error_data_1 =
"a"; // bogus character
// Erroneous
const char *error_data_2 =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<start>"; // XML tag not closed
#endif