mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-14 05:54:50 +00:00
Initial implementation of serialization of basic types and namespaces.
* src/Makefile.am: Add abg-writer.{h,cc} and abg-config.{h,cc}. * src/abg-config.{h,cc}: New files. * src/abg-corpus.h (abi_corpus::decls_type): New typedef. (abi_corpus::{add,get_decls,get_loc_mgr}): Fix style. (abi_corpus::is_empty): Declare new function. * src/abg-corpus.cc (abi_corpus::add): really add the declaration to the corpus. (abi_corpus::is_empty): Define new function. * src/abg-ir.{h,cc} (location_manager::expand_location): Consti-fy this function. * src/abg-reader.cc (read_file): Add a corpus parameter. * src/abg-serialize.cc: Delete this file. * src/abg-writer.h (write_to_ostream): Rename write into this. Make it take a corpus and an ostream as parameters. * abg-writer.cc: New file.
This commit is contained in:
parent
8e225db39a
commit
a80b09f912
@ -9,14 +9,17 @@ $(h)/abg-reader.h \
|
||||
$(h)/abg-corpus.h \
|
||||
$(h)/abg-libxml-utils.h \
|
||||
$(h)/abg-hash.h \
|
||||
$(h)/abg-writer.h
|
||||
$(h)/abg-writer.h \
|
||||
$(h)/abg-config.h
|
||||
|
||||
libabigail_la_SOURCES = $(headers) \
|
||||
$(h)/abg-ir.cc \
|
||||
$(h)/abg-reader.cc \
|
||||
$(h)/abg-corpus.cc \
|
||||
$(h)/abg-libxml-utils.cc \
|
||||
$(h)/abg-hash.cc
|
||||
$(h)/abg-hash.cc \
|
||||
$(h)/abg-writer.cc \
|
||||
$(h)/abg-config.cc
|
||||
|
||||
libabigail_la_LDFLAGS=@ABIGAIL_LIBS@ -Wl,--as-needed
|
||||
|
||||
|
51
src/abg-config.cc
Normal file
51
src/abg-config.cc
Normal file
@ -0,0 +1,51 @@
|
||||
// -*- mode: C++ -*-
|
||||
|
||||
#include "abg-config.h"
|
||||
|
||||
namespace abigail
|
||||
{
|
||||
config::config()
|
||||
: m_format_minor(0),
|
||||
m_format_major(1),// The version number of the serialization
|
||||
// format.
|
||||
m_xml_element_indent(2)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned char
|
||||
config::get_format_minor_version_number() const
|
||||
{
|
||||
return m_format_minor;
|
||||
}
|
||||
|
||||
void
|
||||
config::set_format_minor_version_number(unsigned char v)
|
||||
{
|
||||
m_format_minor = v;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
config::get_format_major_version_number() const
|
||||
{
|
||||
return m_format_major;
|
||||
}
|
||||
|
||||
void
|
||||
config::set_format_major_version_number(unsigned char v)
|
||||
{
|
||||
m_format_major= v;
|
||||
}
|
||||
|
||||
unsigned
|
||||
config::get_xml_element_indent() const
|
||||
{
|
||||
return m_xml_element_indent;
|
||||
}
|
||||
|
||||
void
|
||||
config::set_xml_element_indent(unsigned indent)
|
||||
{
|
||||
m_xml_element_indent = indent;
|
||||
}
|
||||
|
||||
}//end namespace abigail
|
41
src/abg-config.h
Normal file
41
src/abg-config.h
Normal file
@ -0,0 +1,41 @@
|
||||
// -*- Mode: C++ -*-
|
||||
#ifndef __ABG_CONFIG_H__
|
||||
#define __ABG_CONFIG_H__
|
||||
|
||||
namespace abigail
|
||||
{
|
||||
|
||||
/// This type abstracts the configuration information of the library.
|
||||
class config
|
||||
{
|
||||
public:
|
||||
config();
|
||||
|
||||
unsigned char
|
||||
get_format_minor_version_number() const;
|
||||
|
||||
void
|
||||
set_format_minor_version_number(unsigned char);
|
||||
|
||||
unsigned char
|
||||
get_format_major_version_number() const;
|
||||
|
||||
|
||||
void
|
||||
set_format_major_version_number(unsigned char);
|
||||
|
||||
unsigned
|
||||
get_xml_element_indent() const;
|
||||
|
||||
void
|
||||
set_xml_element_indent(unsigned);
|
||||
|
||||
private:
|
||||
unsigned char m_format_minor;
|
||||
unsigned char m_format_major;
|
||||
unsigned m_xml_element_indent;
|
||||
};//end class config
|
||||
|
||||
}//end namespace abigail
|
||||
|
||||
#endif //__ABG_CONFIG_H__
|
@ -13,7 +13,7 @@ abi_corpus::abi_corpus(const std::string& name)
|
||||
void
|
||||
abi_corpus::add(const shared_ptr<decl_base> declaration)
|
||||
{
|
||||
m_members;
|
||||
m_members.push_back(declaration);
|
||||
}
|
||||
|
||||
const std::list<shared_ptr<decl_base> >&
|
||||
@ -34,4 +34,10 @@ abi_corpus::get_loc_mgr()
|
||||
return m_loc_mgr;
|
||||
}
|
||||
|
||||
bool
|
||||
abi_corpus::is_empty() const
|
||||
{
|
||||
return m_members.empty();
|
||||
}
|
||||
|
||||
}//end namespace abigail
|
||||
|
@ -18,12 +18,24 @@ class abi_corpus
|
||||
abi_corpus();
|
||||
|
||||
public:
|
||||
typedef std::list<shared_ptr<decl_base> > decls_type;
|
||||
|
||||
abi_corpus(const std::string& name);
|
||||
|
||||
void add(const shared_ptr<decl_base> declaration);
|
||||
const std::list<shared_ptr<decl_base> >& get_decls() const;
|
||||
location_manager& get_loc_mgr();
|
||||
const location_manager& get_loc_mgr() const;
|
||||
void
|
||||
add(const shared_ptr<decl_base> declaration);
|
||||
|
||||
const std::list<shared_ptr<decl_base> >&
|
||||
get_decls() const;
|
||||
|
||||
location_manager&
|
||||
get_loc_mgr();
|
||||
|
||||
const location_manager&
|
||||
get_loc_mgr() const;
|
||||
|
||||
bool
|
||||
is_empty() const;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
|
@ -94,7 +94,6 @@ location_manager::create_new_location(const std::string& file_path,
|
||||
m_priv->locs.end(),
|
||||
l);
|
||||
|
||||
unsigned opaque = 0;
|
||||
if (i == m_priv->locs.end())
|
||||
{
|
||||
m_priv->locs.push_back(l);
|
||||
@ -127,7 +126,7 @@ void
|
||||
location_manager::expand_location(const location location,
|
||||
std::string& path,
|
||||
unsigned& line,
|
||||
unsigned& column)
|
||||
unsigned& column) const
|
||||
{
|
||||
expanded_location &l = m_priv->locs[location.m_value];
|
||||
path = l.m_path;
|
||||
|
@ -20,7 +20,7 @@ using std::string;
|
||||
namespace abigail
|
||||
{
|
||||
/// \brief The source location of a token.
|
||||
///
|
||||
///
|
||||
/// This represents the location of a token coming from a given ABI
|
||||
/// Corpus. This location is actually an abstraction of cursor in the
|
||||
/// table of all the locations of all the tokens of the ABI Corpus.
|
||||
@ -78,7 +78,7 @@ public:
|
||||
expand_location(const location location,
|
||||
std::string& path,
|
||||
unsigned& line,
|
||||
unsigned& column);
|
||||
unsigned& column) const;
|
||||
};
|
||||
|
||||
class scope_decl;
|
||||
|
@ -129,7 +129,7 @@ static bool handle_type_decl(read_context&, abi_corpus&);
|
||||
static bool handle_namespace_decl(read_context&, abi_corpus&);
|
||||
|
||||
bool
|
||||
read_file(string& file_path,
|
||||
read_file(const string& file_path,
|
||||
abi_corpus& corpus)
|
||||
{
|
||||
read_context read_ctxt(xml::new_reader_from_file(file_path));
|
||||
|
@ -8,7 +8,7 @@ namespace abigail
|
||||
{
|
||||
namespace reader
|
||||
{
|
||||
bool read_file(std::string& file_path,
|
||||
bool read_file(const std::string& file_path,
|
||||
abi_corpus& abi_corpus);
|
||||
|
||||
}// end namespace reader
|
||||
|
297
src/abg-writer.cc
Normal file
297
src/abg-writer.cc
Normal file
@ -0,0 +1,297 @@
|
||||
// -*- mode: C++ -*-
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <tr1/memory>
|
||||
#include "abg-writer.h"
|
||||
#include "abg-config.h"
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::dynamic_pointer_cast;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::list;
|
||||
|
||||
namespace abigail
|
||||
{
|
||||
namespace writer
|
||||
{
|
||||
|
||||
class id_manager
|
||||
{
|
||||
|
||||
unsigned long long
|
||||
get_new_id()
|
||||
{
|
||||
return ++m_cur_id;
|
||||
}
|
||||
|
||||
public:
|
||||
id_manager()
|
||||
: m_cur_id(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Return a unique string representing a numerical id.
|
||||
string
|
||||
get_id()
|
||||
{
|
||||
ostringstream o;
|
||||
o << get_new_id();
|
||||
return o.str();
|
||||
}
|
||||
|
||||
/// Return a unique string representing a numerical ID, prefixed by
|
||||
/// #prefix.
|
||||
///
|
||||
/// \param prefix the prefix of the returned unique id.
|
||||
string
|
||||
get_id_with_prefix(const string& prefix)
|
||||
{
|
||||
ostringstream o;
|
||||
o << prefix << get_new_id();
|
||||
return o.str();
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned long long m_cur_id;
|
||||
};//end class id_manager
|
||||
|
||||
class write_context
|
||||
{
|
||||
|
||||
write_context();
|
||||
|
||||
public:
|
||||
|
||||
write_context(ostream& os)
|
||||
: m_ostream(os)
|
||||
{
|
||||
}
|
||||
|
||||
const config&
|
||||
get_config() const
|
||||
{
|
||||
return m_config;
|
||||
}
|
||||
|
||||
ostream&
|
||||
get_ostream()
|
||||
{
|
||||
return m_ostream;
|
||||
}
|
||||
|
||||
id_manager&
|
||||
get_id_manager()
|
||||
{
|
||||
return m_id_manager;
|
||||
}
|
||||
|
||||
private:
|
||||
id_manager m_id_manager;
|
||||
config m_config;
|
||||
ostream& m_ostream;
|
||||
};//end write_context
|
||||
|
||||
static bool write_corpus(const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
static bool write_decl(const shared_ptr<decl_base>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
static bool write_type_decl(const shared_ptr<type_decl>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
static bool write_namespace_decl(const shared_ptr<namespace_decl>,
|
||||
const abi_corpus&,
|
||||
write_context&,
|
||||
unsigned);
|
||||
|
||||
/// Serialize an abi corpus into an output stream.
|
||||
///
|
||||
/// \param corpus the corpus to serialize
|
||||
///
|
||||
/// \param out the output stream.
|
||||
///
|
||||
/// \return true upon successful completion, false otherwise.
|
||||
bool
|
||||
write_to_ostream(const abi_corpus& corpus,
|
||||
ostream &out)
|
||||
{
|
||||
write_context ctxt(out);
|
||||
|
||||
return write_corpus(corpus, ctxt, /*indent=*/0);
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an of decl_base into an output stream.
|
||||
///
|
||||
/// \param decl, the pointer to decl_base to serialize
|
||||
///
|
||||
/// \param corpus the abi corpus the decl belongs to.
|
||||
///
|
||||
/// \param ctxt the context of the serialization. It contains e.g, the
|
||||
/// output stream to serialize to.
|
||||
///
|
||||
/// \param indent how many indentation spaces to use during the
|
||||
/// serialization.
|
||||
///
|
||||
/// \return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
write_decl(const shared_ptr<decl_base> decl,
|
||||
const abi_corpus& corpus,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
|
||||
corpus, ctxt, indent))
|
||||
return true;
|
||||
if (write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
|
||||
corpus, ctxt, indent))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Serialize an abi corpus into an output stream.
|
||||
///
|
||||
/// \param a corpus the abi corpus to serialize.
|
||||
///
|
||||
/// \param ctxt the context of the serialization. It contains e.g,
|
||||
/// the output stream to serialize to.
|
||||
///
|
||||
/// \param indent how many indentation spaces to use during the
|
||||
/// serialization.
|
||||
///
|
||||
/// \return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
write_corpus(const abi_corpus& corpus, write_context& ctxt, unsigned indent)
|
||||
{
|
||||
ostream &o = ctxt.get_ostream();
|
||||
const config &c = ctxt.get_config();
|
||||
|
||||
for (unsigned i = 0; i < indent; ++i)
|
||||
o << ' ';
|
||||
|
||||
o << "<abi-instr version='"
|
||||
<< c.get_format_major_version_number()
|
||||
<< "." << c.get_format_minor_version_number()
|
||||
<< "'";
|
||||
|
||||
if (corpus.is_empty())
|
||||
{
|
||||
o << "/>";
|
||||
return true;
|
||||
}
|
||||
|
||||
for (abi_corpus::decls_type::const_iterator i = corpus.get_decls().begin();
|
||||
i != corpus.get_decls().end();
|
||||
++i)
|
||||
{
|
||||
o << "\n";
|
||||
write_decl(*i, corpus, ctxt,
|
||||
indent + c.get_xml_element_indent());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a pointer to an instance of basic type declaration, into
|
||||
/// an output stream.
|
||||
///
|
||||
/// \param d the basic type declaration to serialize.
|
||||
///
|
||||
/// \param corpus the instance of abi corpus the declaration belongs
|
||||
/// to.
|
||||
///
|
||||
/// \param ctxt the context of the serialization. It contains e.g, the
|
||||
/// output stream to serialize to.
|
||||
///
|
||||
/// \param indent how many indentation spaces to use during the
|
||||
/// serialization.
|
||||
///
|
||||
/// \return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
write_type_decl(const shared_ptr<type_decl> d,
|
||||
const abi_corpus& corpus,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
ostream &o = ctxt.get_ostream();
|
||||
|
||||
for (unsigned i = 0; i < indent; ++i)
|
||||
o << ' ';
|
||||
|
||||
o << "<type-decl name='" << d->get_name() << "'"
|
||||
<< "xml:id='"
|
||||
<< ctxt.get_id_manager().get_id_with_prefix("type-decl-")
|
||||
<< "'";
|
||||
|
||||
size_t size_in_bits = d->get_size_in_bits();
|
||||
if (size_in_bits)
|
||||
o << " size-in-bits='" << size_in_bits << "'";
|
||||
size_t alignment_in_bits = d->get_alignment_in_bits();
|
||||
if (alignment_in_bits)
|
||||
o << " alignment-in-bits='" << alignment_in_bits << "'";
|
||||
|
||||
location loc = d->get_location();
|
||||
if (loc)
|
||||
{
|
||||
string path;
|
||||
unsigned line = 0, column = 0;
|
||||
corpus.get_loc_mgr().expand_location(loc, path, line, column);
|
||||
o << " filepath='" << path << "'"
|
||||
<< " line='" << line << "'"
|
||||
<< " column='" << column << "'";
|
||||
}
|
||||
o<< "/>";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Serialize a namespace declaration int an output stream.
|
||||
///
|
||||
/// \param decl the namespace declaration to serialize.
|
||||
///
|
||||
/// \param corpus the instance of abi corpus the declaration belongs
|
||||
/// to.
|
||||
///
|
||||
/// \param ctxt the context of the serialization. It contains e.g, the
|
||||
/// output stream to serialize to.
|
||||
///
|
||||
/// \param indent how many indentation spaces to use during the
|
||||
/// serialization.
|
||||
///
|
||||
/// \return true upon successful completion, false otherwise.
|
||||
static bool
|
||||
write_namespace_decl(const shared_ptr<namespace_decl> decl,
|
||||
const abi_corpus& corpus,
|
||||
write_context& ctxt,
|
||||
unsigned indent)
|
||||
{
|
||||
ostream &o = ctxt.get_ostream();
|
||||
const config &c = ctxt.get_config();
|
||||
|
||||
for (unsigned i = 0; i < indent; ++i)
|
||||
o << ' ';
|
||||
|
||||
o << "<namespace-decl name='" << decl->get_name() << "'>";
|
||||
|
||||
for (list<shared_ptr<decl_base> >::const_iterator i =
|
||||
decl->get_member_decls ().begin();
|
||||
i != decl->get_member_decls ().end();
|
||||
++i)
|
||||
{
|
||||
o << "\n";
|
||||
write_decl(*i, corpus, ctxt,
|
||||
indent + c.get_xml_element_indent());
|
||||
}
|
||||
|
||||
o << "</namespace-decl-name>";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}//end namespace writer
|
||||
}//end namespace abigail
|
@ -3,13 +3,18 @@
|
||||
#ifndef __ABG_WRITER_H__
|
||||
#define __ABG_WRITER_H__
|
||||
|
||||
#include "abg-ir.h"
|
||||
#include <ostream>
|
||||
#include "abg-corpus.h"
|
||||
|
||||
namespace abigail
|
||||
{
|
||||
namespace writer
|
||||
{
|
||||
bool write(const namespace_decl ns);
|
||||
}//writer
|
||||
}
|
||||
|
||||
bool write_to_ostream(const abi_corpus& corpus,
|
||||
std::ostream& out);
|
||||
|
||||
}//end namespace writer
|
||||
|
||||
}// end namespace abigail
|
||||
#endif //__ABG_WRITER_H__
|
||||
|
Loading…
Reference in New Issue
Block a user