Commit 6d1810e1 authored by Tiago Peixoto's avatar Tiago Peixoto

Sync with boost 1.40

Fix compilation warnings with boost 1.40, remove unnecessary files, fix
autoconf macros and link with "boost_graph".

This also raises the minimum boost version to 1.40.
parent 3f400d2a
......@@ -156,7 +156,7 @@ AC_PYTHON_DEVEL([2.5])
[LDFLAGS="${LDFLAGS} ${PYTHON_LDFLAGS}"]
dnl boost
AX_BOOST_BASE([1.33.1])
AX_BOOST_BASE([1.40.0])
AX_BOOST_PYTHON
if test "$BOOST_PYTHON_LIB" = ""; then
AC_MSG_ERROR([No usable boost::python found])
......@@ -169,6 +169,10 @@ AX_BOOST_REGEX
if test "$BOOST_REGEX_LIB" = ""; then
AC_MSG_ERROR([No usable boost::regex found])
fi
AX_BOOST_GRAPH
if test "$BOOST_GRAPH_LIB" = ""; then
AC_MSG_ERROR([No usable boost::graph found])
fi
[CPPFLAGS="${CPPFLAGS} ${BOOST_CPPFLAGS}"]
dnl Checks for header files.
......@@ -276,7 +280,7 @@ AC_SUBST(MOD_DIR)
# default LIBADD flags for submodules
[MOD_LIBADD="${PYTHON_LDFLAGS} ${BOOST_IOSTREAMS_LIB} -l${BOOST_PYTHON_LIB} \
${BOOST_REGEX_LIB} ${OPENMP_LDFLAGS} -lexpat"]
${BOOST_REGEX_LIB} -l${BOOST_GRAPH_LIB} ${OPENMP_LDFLAGS} -lexpat"]
AC_SUBST(MOD_LIBADD)
# needed for typeinfo objects to work across DSO boundaries.
......
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_boost_graph.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_GRAPH
#
# DESCRIPTION
#
# This macro checks to see if the Boost.Graph library is installed. It
# also attempts to guess the currect library name using several attempts.
# It tries to build the library name using a user supplied name or suffix
# and then just the raw library.
#
# If the library is found, HAVE_BOOST_GRAPH is defined and
# BOOST_GRAPH_LIB is set to the name of the library.
#
# This macro calls AC_SUBST(BOOST_GRAPH_LIB).
#
# In order to ensure that the Graph headers are specified on the include
# path, this macro requires AX_GRAPH to be called.
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Michael Tindal
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Macro Archive. When you make and
# distribute a modified version of the Autoconf Macro, you may extend this
# special exception to the GPL to apply to your modified version as well.
AC_DEFUN([AX_BOOST_GRAPH],
[AC_CACHE_CHECK(whether the Boost::Graph library is available,
ac_cv_boost_graph,
[AC_LANG_SAVE
AC_LANG_CPLUSPLUS
CPPFLAGS_SAVE=$CPPFLAGS
if test "x$GRAPH_INCLUDE_DIR" != "x"; then
CPPFLAGS="-I$GRAPH_INCLUDE_DIR $CPPFLAGS"
fi
AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[
#include <boost/graph/adjacency_list.hpp>
using namespace boost;
adjacency_list<> g;
]],
[[return 0;]]),
ac_cv_boost_graph=yes, ac_cv_boost_graph=no)
AC_LANG_RESTORE
CPPFLAGS="$CPPFLAGS_SAVE"
])
if test "$ac_cv_boost_graph" = "yes"; then
AC_DEFINE(HAVE_BOOST_GRAPH,,[define if the Boost::Graph library is available])
ax_graph_lib=boost_graph
AC_ARG_WITH([boost-graph],AS_HELP_STRING([--with-boost-graph],[specify the boost graph library or suffix to use]),
[if test "x$with_boost_graph" != "xno"; then
ax_graph_lib=$with_boost_graph
ax_boost_graph_lib=boost_graph-$with_boost_graph
fi])
for ax_lib in $ax_graph_lib $ax_boost_graph_lib boost_graph boost_graph-mt boost_graph-mt-py2.5; do
AC_CHECK_LIB($ax_lib, exit, [BOOST_GRAPH_LIB=$ax_lib break])
done
AC_SUBST(BOOST_GRAPH_LIB)
fi
])dnl
......@@ -80,7 +80,7 @@ AC_DEFUN([AX_BOOST_IOSTREAMS],
AC_DEFINE(HAVE_BOOST_IOSTREAMS,,[define if the Boost::IOStreams library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
if test "x$ax_boost_user_iostreams_lib" = "x"; then
for libextension in `ls $BOOSTLIBDIR/libboost_iostreams*.{so,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_iostreams.*\)\.so.*$;\1;' -e 's;^lib\(boost_iostreams.*\)\.a*$;\1;'` ; do
for libextension in `ls $BOOSTLIBDIR/libboost_iostreams*.{so,a}* 2>/dev/null | sort -r | sed 's,.*/,,' | sed -e 's;^lib\(boost_iostreams.*\)\.so.*$;\1;' -e 's;^lib\(boost_iostreams.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_IOSTREAMS_LIB="-l$ax_lib"; AC_SUBST(BOOST_IOSTREAMS_LIB) link_iostreams="yes"; break],
......
......@@ -72,7 +72,7 @@ AC_DEFUN([AX_BOOST_REGEX],
AC_DEFINE(HAVE_BOOST_REGEX,,[define if the Boost::Regex library is available])
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
if test "x$ax_boost_user_regex_lib" = "x"; then
for libextension in `ls $BOOSTLIBDIR/libboost_regex*.{so,a}* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_regex.*\)\.so.*$;\1;' -e 's;^lib\(boost_regex.*\)\.a*$;\1;'` ; do
for libextension in `ls $BOOSTLIBDIR/libboost_regex*.{so,a}* 2>/dev/null | sort -r | sed 's,.*/,,' | sed -e 's;^lib\(boost_regex.*\)\.so.*$;\1;' -e 's;^lib\(boost_regex.*\)\.a*$;\1;'` ; do
ax_lib=${libextension}
AC_CHECK_LIB($ax_lib, exit,
[BOOST_REGEX_LIB="-l$ax_lib"; AC_SUBST(BOOST_REGEX_LIB) link_regex="yes"; break],
......
......@@ -22,10 +22,10 @@
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp>
#include <boost/property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/named_function_params.hpp>
#include <algorithm>
#include <boost/vector_property_map.hpp>
#include <boost/property_map/vector_property_map.hpp>
namespace boost {
......
......@@ -44,7 +44,7 @@
#include <boost/config.hpp>
#include <vector>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/named_function_params.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/type_traits/conversion_traits.hpp>
......
// Copyright 2004-9 Trustees of Indiana University
// 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)
//
// read_graphviz_new.hpp -
// Initialize a model of the BGL's MutableGraph concept and an associated
// collection of property maps using a graph expressed in the GraphViz
// DOT Language.
//
// Based on the grammar found at:
// http://www.graphviz.org/cvs/doc/info/lang.html
//
// Jeremiah rewrite used grammar found at:
// http://www.graphviz.org/doc/info/lang.html
// and page 34 or http://www.graphviz.org/pdf/dotguide.pdf
//
// See documentation for this code at:
// http://www.boost.org/libs/graph/doc/read-graphviz.html
//
// Author: Jeremiah Willcock
// Ronald Garcia
//
#ifndef BOOST_READ_GRAPHVIZ_NEW_HPP
#define BOOST_READ_GRAPHVIZ_NEW_HPP
#include <boost/ref.hpp>
#include <boost/dynamic_property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/detail/workaround.hpp>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <utility>
#include <map>
#include <iostream>
#include <cstdlib>
namespace boost {
namespace read_graphviz_detail {
typedef std::string node_name;
typedef std::string subgraph_name;
typedef std::map<std::string, std::string> properties;
struct node_and_port {
node_name name;
std::string angle; // Or empty if no angle
std::vector<std::string> location; // Up to two identifiers
friend inline bool operator==(const node_and_port& a, const node_and_port& b) {
return a.name == b.name &&
a.angle == b.angle &&
a.location == b.location;
}
friend inline bool operator<(const node_and_port& a, const node_and_port& b) {
if (a.name != b.name) return a.name < b.name;
if (a.angle != b.angle) return a.angle < b.angle;
return a.location < b.location;
}
};
struct edge_info {
node_and_port source;
node_and_port target;
properties props;
};
struct parser_result {
bool graph_is_directed;
bool graph_is_strict;
std::map<node_name, properties> nodes; // Global set
std::vector<edge_info> edges;
std::map<subgraph_name, properties> graph_props; // Root and subgraphs
};
// The actual parser, from libs/graph/src/read_graphviz_new.cpp
void parse_graphviz_from_string(const std::string& str, parser_result& result, bool want_directed);
// Translate from those results to a graph
void translate_results_to_graph(const parser_result& r, ::boost::detail::graph::mutate_graph* mg);
} // namespace read_graphviz_detail
// This is also in boost/graph/graphviz.hpp
namespace detail {
namespace graph {
BOOST_GRAPH_DECL bool read_graphviz(const std::string& str, boost::detail::graph::mutate_graph* mg);
} // end namespace graph
} // end namespace detail
template <typename MutableGraph>
bool read_graphviz(const std::string& str,
MutableGraph& graph, boost::dynamic_properties& dp,
std::string const& node_id = "node_id") {
boost::detail::graph::mutate_graph_impl<MutableGraph> mg(graph, dp, node_id);
return detail::graph::read_graphviz(str, &mg);
}
template <typename InputIter, typename MutableGraph>
bool read_graphviz(InputIter begin, InputIter end,
MutableGraph& graph, boost::dynamic_properties& dp,
std::string const& node_id = "node_id") {
return read_graphviz(std::string(begin, end), graph, dp, node_id);
}
} // namespace boost
#endif // BOOST_READ_GRAPHVIZ_NEW_HPP
// Copyright 2004-9 Trustees of Indiana University
// 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)
//
// read_graphviz_spirit.hpp -
// Initialize a model of the BGL's MutableGraph concept and an associated
// collection of property maps using a graph expressed in the GraphViz
// DOT Language.
//
// Based on the grammar found at:
// http://www.graphviz.org/cvs/doc/info/lang.html
//
// See documentation for this code at:
// http://www.boost.org/libs/graph/doc/read-graphviz.html
//
// Author: Ronald Garcia
//
#ifndef BOOST_READ_GRAPHVIZ_SPIRIT_HPP
#define BOOST_READ_GRAPHVIZ_SPIRIT_HPP
// Phoenix/Spirit set these limits to 3, but I need more.
#define PHOENIX_LIMIT 6
#define BOOST_SPIRIT_CLOSURE_LIMIT 6
#include <boost/spirit/include/classic_multi_pass.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_confix.hpp>
#include <boost/spirit/include/classic_distinct.hpp>
#include <boost/spirit/include/classic_lists.hpp>
#include <boost/spirit/include/classic_escape_char.hpp>
#include <boost/spirit/include/classic_attribute.hpp>
#include <boost/spirit/include/classic_dynamic.hpp>
#include <boost/spirit/include/classic_actor.hpp>
#include <boost/spirit/include/classic_closure.hpp>
#include <boost/spirit/include/phoenix1.hpp>
#include <boost/spirit/include/phoenix1_binders.hpp>
#include <boost/ref.hpp>
#include <boost/function/function2.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/dynamic_property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/detail/workaround.hpp>
#include <algorithm>
#include <exception> // for std::exception
#include <string>
#include <vector>
#include <set>
#include <utility>
#include <map>
#include <boost/graph/graphviz.hpp>
#include <boost/throw_exception.hpp>
namespace phoenix {
// Workaround: std::map::operator[] uses a different return type than all
// other standard containers. Phoenix doesn't account for that.
template <typename TK, typename T0, typename T1>
struct binary_operator<index_op, std::map<TK,T0>, T1>
{
typedef typename std::map<TK,T0>::mapped_type& result_type;
static result_type eval(std::map<TK,T0>& container, T1 const& index)
{ return container[index]; }
};
} // namespace phoenix
namespace boost {
namespace detail {
namespace graph {
/////////////////////////////////////////////////////////////////////////////
// Application-specific type definitions
/////////////////////////////////////////////////////////////////////////////
typedef std::set<edge_t> edges_t;
typedef std::set<node_t> nodes_t;
typedef std::set<id_t> ids_t;
typedef std::map<edge_t,ids_t> edge_map_t;
typedef std::map<node_t,ids_t> node_map_t;
typedef std::map<id_t,id_t> props_t;
typedef std::map<id_t,props_t> subgraph_props_t;
typedef boost::function2<void, id_t const&, id_t const&> actor_t;
typedef std::vector<edge_t> edge_stack_t;
typedef std::map<id_t,nodes_t> subgraph_nodes_t;
typedef std::map<id_t,edges_t> subgraph_edges_t;
/////////////////////////////////////////////////////////////////////////////
// Stack frames used by semantic actions
/////////////////////////////////////////////////////////////////////////////
struct id_closure : boost::spirit::classic::closure<id_closure, node_t> {
member1 name;
};
struct node_id_closure : boost::spirit::classic::closure<node_id_closure, node_t> {
member1 name;
};
struct attr_list_closure : boost::spirit::classic::closure<attr_list_closure, actor_t> {
member1 prop_actor;
};
struct property_closure : boost::spirit::classic::closure<property_closure, id_t, id_t> {
member1 key;
member2 value;
};
struct data_stmt_closure : boost::spirit::classic::closure<data_stmt_closure,
nodes_t,nodes_t,edge_stack_t,bool,node_t> {
member1 sources;
member2 dests;
member3 edge_stack;
member4 saw_node;
member5 active_node;
};
struct subgraph_closure : boost::spirit::classic::closure<subgraph_closure,
nodes_t, edges_t, node_t> {
member1 nodes;
member2 edges;
member3 name;
};
/////////////////////////////////////////////////////////////////////////////
// Grammar and Actions for the DOT Language
/////////////////////////////////////////////////////////////////////////////
// Grammar for a dot file.
struct dot_grammar : public boost::spirit::classic::grammar<dot_grammar> {
mutate_graph& graph_;
explicit dot_grammar(mutate_graph& graph) : graph_(graph) { }
template <class ScannerT>
struct definition {
definition(dot_grammar const& self) : self(self), subgraph_depth(0),
keyword_p("0-9a-zA-Z_") {
using namespace boost::spirit::classic;
using namespace phoenix;
// RG - Future Work
// - Handle multi-line strings using \ line continuation
// - Make keywords case insensitive
ID
= ( lexeme_d[((alpha_p | ch_p('_')) >> *(alnum_p | ch_p('_')))]
| real_p
| lexeme_d[confix_p('"', *c_escape_ch_p, '"')]
| comment_nest_p('<', '>')
)[ID.name = construct_<std::string>(arg1,arg2)]
;
a_list
= list_p( ID[(a_list.key = arg1),
(a_list.value = "true")
]
>> !( ch_p('=')
>> ID[a_list.value = arg1])
[phoenix::bind(&definition::call_prop_actor)
(var(*this),a_list.key,a_list.value)],!ch_p(','));
attr_list = +(ch_p('[') >> !a_list >> ch_p(']'));
// RG - disregard port id's for now.
port_location
= (ch_p(':') >> ID)
| (ch_p(':') >> ch_p('(') >> ID >> ch_p(',') >> ID >> ch_p(')'))
;
port_angle = ch_p('@') >> ID;
port
= port_location >> (!port_angle)
| port_angle >> (!port_location);
node_id
= ( ID[node_id.name = arg1] >> (!port) )
[phoenix::bind(&definition::memoize_node)(var(*this))];
graph_stmt
= (ID[graph_stmt.key = arg1] >>
ch_p('=') >>
ID[graph_stmt.value = arg1])
[phoenix::bind(&definition::call_graph_prop)
(var(*this),graph_stmt.key,graph_stmt.value)]
; // Graph property.
attr_stmt
= (as_lower_d[keyword_p("graph")]
>> attr_list(actor_t(phoenix::bind(&definition::default_graph_prop)
(var(*this),arg1,arg2))))
| (as_lower_d[keyword_p("node")]
>> attr_list(actor_t(phoenix::bind(&definition::default_node_prop)
(var(*this),arg1,arg2))))
| (as_lower_d[keyword_p("edge")]
>> attr_list(actor_t(phoenix::bind(&definition::default_edge_prop)
(var(*this),arg1,arg2))))
;
// edge_head is set depending on the graph type (directed/undirected)
edgeop = ch_p('-') >> ch_p(boost::ref(edge_head));
edgeRHS
= +( edgeop[(data_stmt.sources = data_stmt.dests),
(data_stmt.dests = construct_<nodes_t>())]
>> ( subgraph[data_stmt.dests = arg1]
| node_id[phoenix::bind(&definition::insert_node)
(var(*this),data_stmt.dests,arg1)]
)
[phoenix::bind(&definition::activate_edge)
(var(*this),data_stmt.sources,data_stmt.dests,
var(edges), var(default_edge_props))]
);
// To avoid backtracking, edge, node, and subgraph statements are
// processed as one nonterminal.
data_stmt
= ( subgraph[(data_stmt.dests = arg1),// will get moved in rhs
(data_stmt.saw_node = false)]
| node_id[(phoenix::bind(&definition::insert_node)
(var(*this),data_stmt.dests,arg1)),
(data_stmt.saw_node = true),
#ifdef BOOST_GRAPH_DEBUG
(std::cout << val("AcTive Node: ") << arg1 << "\n"),
#endif // BOOST_GRAPH_DEBUG
(data_stmt.active_node = arg1)]
) >> if_p(edgeRHS)[
!attr_list(
actor_t(phoenix::bind(&definition::edge_prop)
(var(*this),arg1,arg2)))
].else_p[
if_p(data_stmt.saw_node)[
!attr_list(
actor_t(phoenix::bind(&definition::node_prop)
(var(*this),arg1,arg2)))
] // otherwise it's a subgraph, nothing more to do.
];
stmt
= graph_stmt
| attr_stmt
| data_stmt
;
stmt_list = *( stmt >> !ch_p(';') );
subgraph
= !( as_lower_d[keyword_p("subgraph")]
>> (!ID[(subgraph.name = arg1),
(subgraph.nodes = (var(subgraph_nodes))[arg1]),
(subgraph.edges = (var(subgraph_edges))[arg1])])
)
>> ch_p('{')[++var(subgraph_depth)]
>> stmt_list
>> ch_p('}')[--var(subgraph_depth)]
[(var(subgraph_nodes))[subgraph.name] = subgraph.nodes]
[(var(subgraph_edges))[subgraph.name] = subgraph.edges]
| as_lower_d[keyword_p("subgraph")]
>> ID[(subgraph.nodes = (var(subgraph_nodes))[arg1]),
(subgraph.edges = (var(subgraph_edges))[arg1])]
;
the_grammar
= (!as_lower_d[keyword_p("strict")])
>> ( as_lower_d[keyword_p("graph")][
(var(edge_head) = '-'),
(phoenix::bind(&definition::check_undirected)(var(*this)))]
| as_lower_d[keyword_p("digraph")][
(var(edge_head) = '>'),
(phoenix::bind(&definition::check_directed)(var(*this)))]
)
>> (!ID) >> ch_p('{') >> stmt_list >> ch_p('}');
} // definition()
typedef boost::spirit::classic::rule<ScannerT> rule_t;
rule_t const& start() const { return the_grammar; }
//
// Semantic actions
//
void check_undirected() {
if(self.graph_.is_directed())
boost::throw_exception(boost::undirected_graph_error());
}
void check_directed() {
if(!self.graph_.is_directed())
boost::throw_exception(boost::directed_graph_error());
}
void memoize_node() {
id_t const& node = node_id.name();
props_t& node_props = default_node_props;
if(nodes.find(node) == nodes.end()) {
nodes.insert(node);
self.graph_.do_add_vertex(node);
node_map.insert(std::make_pair(node,ids_t()));
#ifdef BOOST_GRAPH_DEBUG
std::cout << "Add new node " << node << std::endl;
#endif // BOOST_GRAPH_DEBUG
// Set the default properties for this edge
// RG: Here I would actually set the properties
for(props_t::iterator i = node_props.begin();
i != node_props.end(); ++i) {
set_node_property(node,i->first,i->second);
}
if(subgraph_depth > 0) {
subgraph.nodes().insert(node);
// Set the subgraph's default properties as well
props_t& props = subgraph_node_props[subgraph.name()];
for(props_t::iterator i = props.begin(); i != props.end(); ++i) {
set_node_property(node,i->first,i->second);
}
}
} else {
#ifdef BOOST_GRAPH_DEBUG
std::cout << "See node " << node << std::endl;
#endif // BOOST_GRAPH_DEBUG
}
}
void activate_edge(nodes_t& sources, nodes_t& dests, edges_t& edges,