Support new 'abi-corpus' native XML format (.abi)

* include/abg-reader.h (read_corpus_from_native_xml)
	(read_corpus_from_native_xml_file): Declare new entry points.
	* include/abg-writer.h (write_corpus_to_native_xml)
	(write_corpus_to_native_xml_file): Likewise.
	* src/abg-reader.cc (read_translation_unit_from_input): Renamed
	read_input into this.  Support new 'path' attribute for
	'abi-instr' XML element.
	(read_corpus_from_input): New static function.
	(read_translation_unit_from_file)
	(read_translation_unit_from_buffer)
	(read_translation_unit_from_istream): Update wrt read_input ->
	read_translation_unit_from_input.
	(read_corpus_from_native_xml, read_corpus_from_native_xml)
	(read_corpus_from_native_xml_file): Define new entry points.
	* src/abg-writer.cc (write_translation_unit): Write 'path'
	attribute into the 'abi-instr' xml element.
	(write_corpus_to_native_xml, write_corpus_to_native_xml_file):
	Define new entry points.
	* tools/abg-tools-utils.h (file_type::{FILE_TYPE_XML_CORPUS,
	FILE_TYPE_ZIP_CORPUS}): New enumerators.
	* tools/abg-tools-utils.cc (guess_file_type): Support detection of
	the new xml file format containing a document root 'abi-corpus'
	root element.
	* tools/bidiff.cc (main): Support diffing xml corpus-es and zip
	corpus-es.
	* tools/bidw.cc (main): Recognize elf files before reading them.
	* tools/bilint.cc (main): Support reading xml/zip corpus-es too.
	* tests/data/test-read-write/test[0-23].xml: Update 'path'
	attribute.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2014-01-07 14:12:26 +01:00
parent 4ca76c4658
commit 2c9fb3e70d
38 changed files with 421 additions and 75 deletions

View File

@ -72,6 +72,20 @@ read_corpus_from_file(corpus& corp, const string& path);
int
read_corpus_from_file(corpus& corp);
bool
read_corpus_from_native_xml(std::istream* in,
corpus& corp);
corpus_sptr
read_corpus_from_native_xml(std::istream* in);
bool
read_corpus_from_native_xml_file(corpus& corp,
const string& path);
corpus_sptr
read_corpus_from_native_xml_file(const string& path);
}//end xml_reader
}//end namespace abigail

View File

@ -53,6 +53,16 @@ write_corpus_to_archive(const corpus& corp);
bool
write_corpus_to_archive(const corpus_sptr corp);
bool
write_corpus_to_native_xml(const corpus_sptr corpus,
unsigned indent,
std::ostream& out);
bool
write_corpus_to_native_xml_file(const corpus_sptr corpus,
unsigned indent,
const string& path);
}// end namespace xml_writer
}// end namespace abigail

View File

@ -409,7 +409,8 @@ private:
};
static int advance_cursor(read_context&);
static bool read_input(read_context&, translation_unit&);
static bool read_translation_unit_from_input(read_context&,
translation_unit&);
static bool read_location(read_context&, location&);
static bool read_location(read_context&, xmlNodePtr, location&);
static bool read_visibility(xmlNodePtr, decl_base::visibility&);
@ -597,7 +598,9 @@ advance_cursor(read_context& ctxt)
return status;
}
/// Parse the input xml document associated to the current context.
/// Parse the input XML document containing a translation_unit,
/// represented by an 'abi-instr' element node, associated to the current
/// context.
///
/// @param ctxt the current input context
///
@ -605,8 +608,8 @@ advance_cursor(read_context& ctxt)
///
/// @return true upon successful parsing, false otherwise.
static bool
read_input(read_context& ctxt,
translation_unit& tu)
read_translation_unit_from_input(read_context& ctxt,
translation_unit& tu)
{
xml::reader_sptr reader = ctxt.get_reader();
if (!reader)
@ -626,6 +629,10 @@ read_input(read_context& ctxt,
tu.set_address_size(address_size);
}
xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(reader, "path");
if (path_str)
tu.set_path(reinterpret_cast<char*>(path_str.get()));
// We are at global scope, as we've just seen the top-most
// "abi-instr" element.
ctxt.push_decl(tu.get_global_scope());
@ -655,6 +662,48 @@ read_input(read_context& ctxt,
return false;
}
/// Parse the input XML document containing an ABI corpus, represented
/// by an 'abi-corpus' element node, associated to the current
/// context.
///
/// @param ctxt the current input context.
///
/// @param corp the corpus resulting from the parsing. This is set
/// iff the function returns true.
///
/// @return true upon successful parsing, false otherwise.
static bool
read_corpus_from_input(read_context& ctxt,
corpus& corp)
{
xml::reader_sptr reader = ctxt.get_reader();
if (!reader)
return false;
// The document must start with the abi-corpus node.
int status = advance_cursor (ctxt);
if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
BAD_CAST("abi-corpus")))
return false;
xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(reader, "path");
if (path_str)
corp.set_path(reinterpret_cast<char*>(path_str.get()));
bool is_ok;
do
{
translation_unit_sptr tu(new translation_unit(""));
is_ok = read_translation_unit_from_input(ctxt, *tu);
if (is_ok)
corp.add(tu);
}
while (is_ok);
return true;
}
/// Parse an ABI instrumentation file (in XML format) at a given path.
///
/// @param input_file a path to the file containing the xml document
@ -668,7 +717,7 @@ read_translation_unit_from_file(const string& input_file,
translation_unit& tu)
{
read_context read_ctxt(xml::new_reader_from_file(input_file));
return read_input(read_ctxt, tu);
return read_translation_unit_from_input(read_ctxt, tu);
}
/// Parse an ABI instrumentation file (in XML format) at a given path.
@ -697,13 +746,13 @@ read_translation_unit_from_buffer(const string& buffer,
translation_unit& tu)
{
read_context read_ctxt(xml::new_reader_from_buffer(buffer));
return read_input(read_ctxt, tu);
return read_translation_unit_from_input(read_ctxt, tu);
}
/// This function is called by #read_input. It handles the current
/// xml element node of the reading context. The result of the
/// "handling" is to build the representation of the xml node and tied
/// it to the current translation unit.
/// This function is called by @ref read_translation_unit_from_input.
/// It handles the current xml element node of the reading context.
/// The result of the "handling" is to build the representation of the
/// xml node and tied it to the current translation unit.
///
/// @param ctxt the current parsing context.
///
@ -2721,7 +2770,7 @@ read_translation_unit_from_istream(istream* in,
translation_unit& tu)
{
read_context read_ctxt(xml::new_reader_from_istream(in));
return read_input(read_ctxt, tu);
return read_translation_unit_from_input(read_ctxt, tu);
}
/// De-serialize a translation unit from an ABI Instrumentation xml
@ -2924,6 +2973,80 @@ read_corpus_from_file(const string& path)
return corp;
}
/// De-serialize an ABI corpus from an input XML document which root
/// node is 'abi-corpus'.
///
/// @param in the input stream to read the XML document from.
///
/// @param corp the corpus de-serialized from the parsing. This is
/// set iff the function returns true.
///
/// @return true upon successful parsing, false otherwise.
bool
read_corpus_from_native_xml(std::istream* in,
corpus& corp)
{
read_context read_ctxt(xml::new_reader_from_istream(in));
return read_corpus_from_input(read_ctxt, corp);
}
/// De-serialize an ABI corpus from an input XML document which root
/// node is 'abi-corpus'.
///
/// @param in the input stream to read the XML document from.
///
/// @return the resulting corpus de-serialized from the parsing. This
/// is non-null iff the parsing resulted in a valid corpus.
corpus_sptr
read_corpus_from_native_xml(std::istream* in)
{
corpus_sptr corp(new corpus(""));
if (read_corpus_from_native_xml(in, *corp))
return corp;
return corpus_sptr();
}
/// De-serialize an ABI corpus from an XML document file which root
/// node is 'abi-corpus'.
///
/// @param path the path to the input file to read the XML document
/// from.
///
/// @param corp the corpus de-serialized from the parsing. This is
/// set iff the function returns true.
///
/// @return true upon successful parsing, false otherwise.
bool
read_corpus_from_native_xml_file(corpus& corp,
const string& path)
{
read_context read_ctxt(xml::new_reader_from_file(path));
return read_corpus_from_input(read_ctxt, corp);
}
/// De-serialize an ABI corpus from an XML document file which root
/// node is 'abi-corpus'.
///
/// @param path the path to the input file to read the XML document
/// from.
///
/// @return the resulting corpus de-serialized from the parsing. This
/// is non-null if the parsing successfully resulted in a corpus.
corpus_sptr
read_corpus_from_native_xml_file(const string& path)
{
corpus_sptr corp(new corpus(""));
if (read_corpus_from_native_xml_file(*corp, path))
{
if (corp->get_path().empty())
corp->set_path(path);
return corp;
}
return corpus_sptr();
}
}//end namespace xml_reader
}//end namespace abigail

View File

@ -641,13 +641,16 @@ write_translation_unit(const translation_unit& tu,
if (tu.get_address_size() != 0)
o << " address-size='" << static_cast<int>(tu.get_address_size()) << "'";
if (!tu.get_path().empty())
o << " path='" << tu.get_path() << "'";
if (tu.is_empty())
{
o << "/>";
return true;
}
else
o << ">";
o << ">";
typedef scope_decl::declarations declarations;
typedef typename declarations::const_iterator const_iterator;
@ -1784,6 +1787,90 @@ bool
write_corpus_to_archive(const corpus_sptr corp)
{return write_corpus_to_archive(*corp);}
/// Serialize an ABI corpus to a single native xml document. The root
/// note of the resulting XML document is 'abi-corpus'.
///
/// @param corpus the corpus to serialize.
///
/// @param indent the number of white space indentation to use.
///
/// @param out the output stream to serialize the ABI corpus to.
bool
write_corpus_to_native_xml(const corpus_sptr corpus,
unsigned indent,
std::ostream& out)
{
if (!corpus)
return false;
write_context ctxt(out);
do_indent_to_level(ctxt, indent, 0);
out << "<abi-corpus";
if (!corpus->get_path().empty())
out << " path='" << corpus->get_path() << "'";
if (corpus->is_empty())
{
out << "/>\n";
return true;
}
out << ">\n";
for (translation_units::const_iterator i =
corpus->get_translation_units().begin();
i != corpus->get_translation_units().end();
++i)
write_translation_unit(**i, ctxt, indent + 2);
do_indent_to_level(ctxt, indent, 0);
out << "</abi-corpus>\n";
return true;
}
/// Serialize an ABI corpus to a single native xml document. The root
/// note of the resulting XML document is 'abi-corpus'.
///
/// @param corpus the corpus to serialize.
///
/// @param indent the number of white space indentation to use.
///
/// @param out the output file to serialize the ABI corpus to.
bool
write_corpus_to_native_xml_file(const corpus_sptr corpus,
unsigned indent,
const string& path)
{
bool result = true;
try
{
ofstream of(path, std::ios_base::trunc);
if (!of.is_open())
{
cerr << "failed to access " << path << "\n";
return false;
}
if (!write_corpus_to_native_xml(corpus, indent, of))
{
cerr << "failed to access " << path << "\n";
result = false;
}
of.close();
}
catch(...)
{
cerr << "failed to write to " << path << "\n";
result = false;
}
return result;
}
} //end namespace xml_writer
// <Debugging routines>

View File

@ -1,3 +1,3 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test0.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
</abi-instr>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test1.xml'>
<namespace-decl name='foo'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
</namespace-decl>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test10.xml'>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-2'/>
<pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test11.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<namespace-decl name='ns0'>
<function-template-decl id='fn-tmpl-id-2'>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test12.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<namespace-decl name='ns0'>
<namespace-decl name='ns1'>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test13.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<namespace-decl name='ns0'>
<namespace-decl name='ns1'>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test14.xml'>
<type-decl name='int' size-in-bits='32' id='type-id-1'/>
<class-decl name='S' size-in-bits='8' alignment-in-bits='8' visibility='default' id='type-id-2'>
<member-template access='public'>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test15.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<class-template-decl id='class-tmpl-id-2'>
<template-type-parameter id='type-id-3' name='T'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test16.xml'>
<class-decl name='S' size-in-bits='8' alignment-in-bits='8' visibility='default' id='type-id-1'>
<member-template access='public'>
<class-template-decl id='class-tmpl-id-2'>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test17.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-2'/>
<type-decl name='unsigned int' size-in-bits='32' alignment-in-bits='32' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test18.xml'>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
<class-decl name='S' visibility='default' is-declaration-only='yes' id='type-id-2'/>
<pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test19.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<class-decl name='B0' size-in-bits='32' alignment-in-bits='32' visibility='default' filepath='../../prtests/test9.cc' line='1' column='7' id='type-id-2'>
<data-member access='private' layout-offset-in-bits='0'>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test2.xml'>
<namespace-decl name='foo'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
</namespace-decl>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test20.xml'>
<type-decl name='void' alignment-in-bits='8' id='type-id-1'/>
<function-decl name='foo' mangled-name='_Z3foov' filepath='../../prtests/test9.cc' line='78' column='1' visibility='default' binding='global' size-in-bits='8' alignment-in-bits='8'>
<return type-id='type-id-1'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test21.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<class-decl name='S' visibility='default' is-declaration-only='yes' id='type-id-2'/>
<pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test22.xml'>
<type-decl name='long long int' size-in-bits='64' alignment-in-bits='64' id='type-id-1'/>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-2'/>
<type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0' address-size='64'>
<abi-instr version='1.0' address-size='64' path='data/test-read-write/test23.xml'>
<type-decl name='long long int' size-in-bits='64' alignment-in-bits='64' id='type-id-1'/>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-2'/>
<type-decl name='long int' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test3.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<qualified-type-def type-id='type-id-1' const='yes' id='type-id-2'/>
<qualified-type-def type-id='type-id-1' volatile='yes' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test4.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
</abi-instr>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test5.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<reference-type-def kind='lvalue' type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
</abi-instr>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test6.xml'>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
<enum-decl name='enum_foo' id='type-id-2'>
<underlying-type type-id='type-id-1'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test7.xml'>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
<typedef-decl name='tchar' type-id='type-id-1' id='type-id-2'/>
</abi-instr>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test8.xml'>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
<var-decl name='foo' type-id='type-id-1' mangled-name='blabla' visibility='default' binding='global'/>
</abi-instr>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='data/test-read-write/test9.xml'>
<type-decl name='char' size-in-bits='8' alignment-in-bits='8' id='type-id-1'/>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-2'/>
<pointer-type-def type-id='type-id-2' size-in-bits='64' alignment-in-bits='64' id='type-id-3'/>

View File

@ -1,3 +1,3 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='test0.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
</abi-instr>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='test1.xml'>
<namespace-decl name='foo'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
</namespace-decl>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='test2.xml'>
<namespace-decl name='foo'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
</namespace-decl>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='test3.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<qualified-type-def type-id='type-id-1' const='yes' id='type-id-2'/>
<qualified-type-def type-id='type-id-1' volatile='yes' id='type-id-3'/>

View File

@ -1,4 +1,4 @@
<abi-instr version='1.0'>
<abi-instr version='1.0' path='test4.xml'>
<type-decl name='int' size-in-bits='32' alignment-in-bits='32' id='type-id-1'/>
<pointer-type-def type-id='type-id-1' size-in-bits='64' alignment-in-bits='64' id='type-id-2'/>
</abi-instr>

View File

@ -256,6 +256,26 @@ guess_file_type(istream& in)
&& buf[10] == ' ')
return FILE_TYPE_NATIVE_BI;
if (buf[0] == '<'
&& buf[1] == 'a'
&& buf[2] == 'b'
&& buf[3] == 'i'
&& buf[4] == '-'
&& buf[5] == 'c'
&& buf[6] == 'o'
&& buf[7] == 'r'
&& buf[8] == 'p'
&& buf[9] == 'u'
&& buf[10] == 's'
&& buf[11] == ' ')
return FILE_TYPE_XML_CORPUS;
if (buf[0] == 'P'
&& buf[1] == 'K'
&& buf[2] == 0x03
&& buf[3] == 0x04)
return FILE_TYPE_ZIP_CORPUS;
return FILE_TYPE_UNKNOWN;
}

View File

@ -51,6 +51,12 @@ enum file_type
/// An elf file. Read this kind of file should yield an
/// abigail::corpus type.
FILE_TYPE_ELF,
// A native xml file format representing a corpus of one or several
// translation units.
FILE_TYPE_XML_CORPUS,
// A zip file, possibly containing a corpus of one of several
// translation units.
FILE_TYPE_ZIP_CORPUS,
};
file_type guess_file_type(std::istream& in);

View File

@ -143,6 +143,13 @@ main(int argc, char* argv[])
case abigail::tools::FILE_TYPE_ELF:
c1 = abigail::dwarf_reader::read_corpus_from_elf(opts.file1);
break;
case abigail::tools::FILE_TYPE_XML_CORPUS:
c1 =
abigail::xml_reader::read_corpus_from_native_xml_file(opts.file1);
break;
case abigail::tools::FILE_TYPE_ZIP_CORPUS:
c1 = abigail::xml_reader::read_corpus_from_file(opts.file1);
break;
}
switch (t2_type)
@ -157,6 +164,13 @@ main(int argc, char* argv[])
case abigail::tools::FILE_TYPE_ELF:
c2 = abigail::dwarf_reader::read_corpus_from_elf(opts.file2);
break;
case abigail::tools::FILE_TYPE_XML_CORPUS:
c2 =
abigail::xml_reader::read_corpus_from_native_xml_file(opts.file2);
break;
case abigail::tools::FILE_TYPE_ZIP_CORPUS:
c2 = abigail::xml_reader::read_corpus_from_file(opts.file2);
break;
}
if (!t1 && !c1)

View File

@ -36,13 +36,13 @@
#include "abg-tools-utils.h"
#include "abg-corpus.h"
#include "abg-dwarf-reader.h"
#include "abg-writer.h"
using std::string;
using std::cerr;
using std::cout;
using std::ostream;
using std::ofstream;
using abigail::tools::check_file;
struct options
{
@ -105,9 +105,17 @@ main(int argc, char* argv[])
}
assert(!opts.in_file_path.empty());
if (!check_file(opts.in_file_path, cerr))
if (!abigail::tools::check_file(opts.in_file_path, cerr))
return 1;
abigail::tools::file_type type =
abigail::tools::guess_file_type(opts.in_file_path);
if (type != abigail::tools::FILE_TYPE_ELF)
{
cerr << opts.in_file_path << " is not an ELF file\n";
return 1;
}
using abigail::corpus;
using abigail::corpus_sptr;
using abigail::translation_units;
@ -120,16 +128,7 @@ main(int argc, char* argv[])
return 1;
}
cout << "for corpus " << corp->get_path() << ":\n";
for (translation_units::const_iterator it =
corp->get_translation_units().begin();
it != corp->get_translation_units().end();
++it)
{
cout << "translation unit: " << (*it)->get_path() << ":\n";
dump(*it, cout);
cout << "\n";
}
abigail::xml_writer::write_corpus_to_native_xml(corp, 0, cout);
return 0;
}

View File

@ -36,7 +36,9 @@
#include <fstream>
#include "abg-tools-utils.h"
#include "abg-ir.h"
#include "abg-corpus.h"
#include "abg-reader.h"
#include "abg-dwarf-reader.h"
#include "abg-writer.h"
using std::string;
@ -46,18 +48,30 @@ using std::cout;
using std::ostream;
using std::ofstream;
using abigail::tools::check_file;
using abigail::tools::file_type;
using abigail::tools::guess_file_type;
using abigail::corpus;
using abigail::corpus_sptr;
using abigail::xml_reader::read_translation_unit_from_file;
using abigail::xml_reader::read_translation_unit_from_istream;
using abigail::xml_reader::read_corpus_from_file;
using abigail::xml_reader::read_corpus_from_native_xml;
using abigail::xml_reader::read_corpus_from_native_xml_file;
using abigail::dwarf_reader::read_corpus_from_elf;
using abigail::xml_writer::write_translation_unit;
using abigail::xml_writer::write_corpus_to_native_xml;
using abigail::xml_writer::write_corpus_to_archive;
struct options
{
string file_path;
bool read_from_stdin;
bool read_tu;
bool noout;
options()
: read_from_stdin(false),
read_tu(false),
noout(false)
{}
};//end struct options;
@ -65,11 +79,12 @@ struct options
void
display_usage(const string& prog_name, ostream& out)
{
out << "usage: " << prog_name << "[options] [<bi-file1>\n"
out << "usage: " << prog_name << "[options] [<abi-file1>\n"
<< " where options can be:\n"
<< " --help display this message\n"
<< " --noout do not display anything on stdout\n"
<< " --stdin|-- read bi-file content from stdin\n";
<< " --help display this message\n"
<< " --noout do not display anything on stdout\n"
<< " --stdin|-- read abi-file content from stdin\n"
<< " --tu expect a single translation unit file\n";
}
bool
@ -94,6 +109,8 @@ parse_command_line(int argc, char* argv[], options& opts)
return false;
else if (!strcmp(argv[i], "--stdin"))
opts.read_from_stdin = true;
else if (!strcmp(argv[i], "--tu"))
opts.read_tu = true;
else if (!strcmp(argv[i], "--noout"))
opts.noout = true;
else
@ -122,28 +139,58 @@ main(int argc, char* argv[])
if (!cin.good())
return true;
abigail::translation_unit_sptr tu =
read_translation_unit_from_istream(&cin);
if (!tu)
if (opts.read_tu)
{
cerr << "failed to read the ABI instrumentation from stdin\n";
return true;
}
abigail::translation_unit_sptr tu =
read_translation_unit_from_istream(&cin);
if (!opts.noout)
write_translation_unit(*tu, 0, cout);
return false;
if (!tu)
{
cerr << "failed to read the ABI instrumentation from stdin\n";
return true;
}
if (!opts.noout)
write_translation_unit(*tu, 0, cout);
return false;
}
else
{
corpus_sptr corp = read_corpus_from_native_xml(&cin);
if (!opts.noout)
write_corpus_to_native_xml(corp, /*indent=*/0, cout);
return false;
}
}
else if (!opts.file_path.empty())
{
if (!check_file(opts.file_path, cerr))
return true;
abigail::translation_unit_sptr tu =
read_translation_unit_from_file(opts.file_path);
abigail::translation_unit_sptr tu;
abigail::corpus_sptr corp;
file_type type = guess_file_type(opts.file_path);
if (!tu)
switch (type)
{
case abigail::tools::FILE_TYPE_UNKNOWN:
cerr << "Unknown file type given in input: " << opts.file_path;
return true;
case abigail::tools::FILE_TYPE_NATIVE_BI:
tu = read_translation_unit_from_file(opts.file_path);
break;
case abigail::tools::FILE_TYPE_ELF:
corp = read_corpus_from_elf(opts.file_path);
break;
case abigail::tools::FILE_TYPE_XML_CORPUS:
corp = read_corpus_from_native_xml_file(opts.file_path);
break;
case abigail::tools::FILE_TYPE_ZIP_CORPUS:
corp = read_corpus_from_file(opts.file_path);
break;
}
if (!tu && !corp)
{
cerr << "failed to read " << opts.file_path << "\n";
return true;
@ -161,15 +208,41 @@ main(int argc, char* argv[])
return true;
}
bool r = write_translation_unit(*tu, /*indent=*/0, of);
bool r;
if (tu)
r = write_translation_unit(*tu, /*indent=*/0, of);
else
{
if (type == abigail::tools::FILE_TYPE_XML_CORPUS)
r = write_corpus_to_native_xml(corp, /*indent=*/0, of);
else if (type == abigail::tools::FILE_TYPE_ZIP_CORPUS)
{
r = write_corpus_to_archive(*corp, ofile_name);
of.close();
}
else if (type == abigail::tools::FILE_TYPE_ELF)
r = write_corpus_to_native_xml(corp, /*indent=*/0,
opts.noout ? of : cout);
}
bool is_ok = r;
of.close();
if (!is_ok)
cerr << "failed to write the translation unit "
<< opts.file_path << " back\n";
{
string output =
(type == abigail::tools::FILE_TYPE_NATIVE_BI)
? "translation unit"
: "ABI corpus";
cerr << "failed to write the translation unit "
<< opts.file_path << " back\n";
}
if (is_ok)
if (is_ok
&& ((type == abigail::tools::FILE_TYPE_XML_CORPUS)
|| type == abigail::tools::FILE_TYPE_NATIVE_BI
|| type == abigail::tools::FILE_TYPE_ZIP_CORPUS))
{
string cmd = "diff -u " + opts.file_path + " " + ofile_name;
if (system(cmd.c_str()))