diff options
| author | Jörg Frings-Fürst <jff@merkur> | 2014-05-18 16:08:14 +0200 | 
|---|---|---|
| committer | Jörg Frings-Fürst <jff@merkur> | 2014-05-18 16:08:14 +0200 | 
| commit | a15cf65c44d5c224169c32ef5495b68c758134b7 (patch) | |
| tree | 3419f58fc8e1b315ba8171910ee044c5d467c162 /xsd/examples/cxx/tree/compression | |
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'xsd/examples/cxx/tree/compression')
| -rw-r--r-- | xsd/examples/cxx/tree/compression/README | 48 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/compressed-format-target.cxx | 157 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/compressed-format-target.hxx | 96 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/compressed-input-source.cxx | 215 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/compressed-input-source.hxx | 132 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/driver.cxx | 125 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/library.xml.gz | bin | 0 -> 486 bytes | |||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/library.xsd | 73 | ||||
| -rw-r--r-- | xsd/examples/cxx/tree/compression/makefile | 117 | 
9 files changed, 963 insertions, 0 deletions
| diff --git a/xsd/examples/cxx/tree/compression/README b/xsd/examples/cxx/tree/compression/README new file mode 100644 index 0000000..f163970 --- /dev/null +++ b/xsd/examples/cxx/tree/compression/README @@ -0,0 +1,48 @@ +This example shows how to compress an XML document during serialization  +and decompress it during parsing. The example uses the compression  +functionality provided by the zlib library[1] which needs to be installed +in order to build and run this example. It should also be fairly straight- +forward to modify the code in this example to use other compression  +libraries. + +[1] http://www.zlib.net + +The example consists of the following files: + +library.xsd +  XML Schema which describes a library of books. + +library.xml.gz +  Sample XML instance document compressed using the gzip format. + +compressed-format-target.hxx +compressed-format-target.cxx +  Implementation of the Xerces-C++ XMLFormatTarget interface with the on- +  the-fly compression support. You can use it in your application to add +  XML compression. + +compressed-input-source.hxx +compressed-input-source.cxx +  Implementation of the Xerces-C++ InputSource interface with the on-the- +  fly decompression support. You can use it in your application to add +  XML decompression. + +library.hxx +library.cxx +  C++ types that represent the given vocabulary and a set of parsing +  functions that convert XML instance documents to a tree-like in-memory +  object model. These are generated by XSD from library.xsd. + +driver.cxx +  Driver for the example. It first creates the compressed_input_source  +  object and passes it to one of the parsing functions that constructs  +  the object model from the compressed input file. It then prints the  +  content of the object model to STDERR. Finally, the driver creates the  +  compressed_format_target object and passes it to one of the serialization +  functions which converts the object model back to the compressed XML. + +To run the example on the sample XML document simply execute: + +$ ./driver library.xml.gz + +The serialization output is written to the out.xml.gz file. diff --git a/xsd/examples/cxx/tree/compression/compressed-format-target.cxx b/xsd/examples/cxx/tree/compression/compressed-format-target.cxx new file mode 100644 index 0000000..b4a8a85 --- /dev/null +++ b/xsd/examples/cxx/tree/compression/compressed-format-target.cxx @@ -0,0 +1,157 @@ +// file      : examples/cxx/tree/compression/compressed-format-target.cxx +// author    : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#include <ostream> +#include <cstring> // std::memcpy + +#include "compressed-format-target.hxx" + +using namespace std; + +// +// compression_failure +// + +const char* compression_failure:: +what () const throw () +{ +  return "compression failure"; +} + +// +// compressed_format_target +// + +compressed_format_target:: +compressed_format_target (ostream& os, compression_type t) +    : os_ (os), closed_ (false), n_ (0) +  { +    zs_.zalloc = Z_NULL; +    zs_.zfree  = Z_NULL; +    zs_.opaque = Z_NULL; + +    int window = 0; + +    switch (t) +    { +    case raw: +      { +        window = -15; +        break; +      } +    case zlib: +      { +        window = 15; +        break; +      } +    case gzip: +      { +        window = 16 + 15; +        break; +      } +    } + +    int r (deflateInit2 (&zs_, +                         Z_DEFAULT_COMPRESSION, +                         Z_DEFLATED, +                         window, +                         8, +                         Z_DEFAULT_STRATEGY)); +    if (r != Z_OK) +      throw compression_failure (r); +  } + +compressed_format_target:: +~compressed_format_target () +{ +  try +  { +    // Close the free the compression stream. +    // +    if (!closed_) +      close (); +  } +  catch (...) +  { +  } + +  deflateEnd (&zs_); +} + +void compressed_format_target:: +writeChars (const XMLByte* const buf, +#if _XERCES_VERSION >= 30000 +            const XMLSize_t size, +#else +            const unsigned int size, +#endif +            xercesc::XMLFormatter* const) +{ +  // Flush the buffer if the block is too large or if we don't have +  // any space left. +  // +  if ((size >= buf_size_ / 8 || n_ + size > buf_size_) && n_ != 0) +  { +    write (in_, n_); +    n_ = 0; +  } + +  if (size < buf_size_ / 8) +  { +    memcpy (in_ + n_, reinterpret_cast<const char*> (buf), size); +    n_ += size; +  } +  else +    write (reinterpret_cast<const char*> (buf), size); +} + + +void compressed_format_target:: +flush () +{ +  if (n_ != 0) +  { +    write (in_, n_); +    n_ = 0; +  } + +  if (!os_.fail ()) +    os_.flush (); +} + +void compressed_format_target:: +close () +{ +  write (in_, n_, true); +  n_ = 0; + +  if (!os_.fail ()) +    os_.flush (); + +  closed_ = true; +} + +void compressed_format_target:: +write (const char* buf, size_t size, bool flush) +{ +  zs_.next_in = reinterpret_cast<Bytef*> (const_cast<char*> (buf)); +  zs_.avail_in = static_cast<uInt> (size); + +  do +  { +    zs_.next_out = reinterpret_cast<Bytef*> (out_); +    zs_.avail_out = buf_size_; + +    int r (deflate (&zs_, flush ? Z_FINISH : Z_NO_FLUSH)); + +    if (r != Z_OK && r != Z_BUF_ERROR && r != Z_STREAM_END) +      throw compression_failure (r); + +    size_t n (buf_size_ - zs_.avail_out); + +    if (!os_.fail () && n > 0) +      os_.write (out_, static_cast<streamsize> (n)); + +  } while (zs_.avail_out == 0); +} diff --git a/xsd/examples/cxx/tree/compression/compressed-format-target.hxx b/xsd/examples/cxx/tree/compression/compressed-format-target.hxx new file mode 100644 index 0000000..5d12e81 --- /dev/null +++ b/xsd/examples/cxx/tree/compression/compressed-format-target.hxx @@ -0,0 +1,96 @@ +// file      : examples/cxx/tree/compression/compressed-format-target.hxx +// author    : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#ifndef COMPRESSED_FORMAT_TARGET_HXX +#define COMPRESSED_FORMAT_TARGET_HXX + +#include <zlib.h> + +#include <iosfwd> +#include <cstddef>   // std::size_t +#include <exception> + +#include <xercesc/framework/XMLFormatter.hpp> + +struct compression_failure: std::exception +{ +  explicit +  compression_failure (int code) +      : code_ (code) +  { +  } + +  int +  code () const +  { +    return code_; +  } + +  const char* +  message () const +  { +    return zError (code_); +  } + +  virtual const char* +  what () const throw (); + +private: +  int code_; +}; + +// Xerces-C++ XMLFormatTarget interface implementation with on-the-fly, +// zlib-based compression. +// +class compressed_format_target: public xercesc::XMLFormatTarget +{ +public: +  enum compression_type +  { +    raw, +    zlib, +    gzip +  }; + +  compressed_format_target (std::ostream&, compression_type); + +  virtual +  ~compressed_format_target (); + +  virtual void +  writeChars (const XMLByte* const buf, +#if _XERCES_VERSION >= 30000 +              const XMLSize_t size, +#else +              const unsigned int size, +#endif +              xercesc::XMLFormatter* const); + +  virtual void +  flush (); + +  // Close the compressed stream by writing out the zlib or gzip trailer. +  // This function is automatically called from the destructor but you +  // may want to call it explicitly to be able to catch any exceptions +  // that it might throw. +  // +  void +  close (); + +private: +  void +  write (const char* buf, std::size_t size, bool flush = false); + +private: +  std::ostream& os_; +  z_stream zs_; +  bool closed_; + +  static const std::size_t buf_size_ = 65536; +  char in_[buf_size_]; +  char out_[buf_size_]; +  size_t n_; +}; + +#endif // COMPRESSED_FORMAT_TARGET_HXX diff --git a/xsd/examples/cxx/tree/compression/compressed-input-source.cxx b/xsd/examples/cxx/tree/compression/compressed-input-source.cxx new file mode 100644 index 0000000..22d09ff --- /dev/null +++ b/xsd/examples/cxx/tree/compression/compressed-input-source.cxx @@ -0,0 +1,215 @@ +// file      : examples/cxx/tree/compression/compressed-input-source.cxx +// author    : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#include <istream> + +#include <xsd/cxx/xml/string.hxx> + +#include "compressed-input-source.hxx" + +using namespace std; +using namespace xercesc; +namespace xml = xsd::cxx::xml; + +// +// decompression_failure +// + +const char* decompression_failure:: +what () const throw () +{ +  return "decompression failure"; +} + +// +// compressed_input_source +// + +compressed_input_source:: +compressed_input_source (istream& is, compression_type t) +    : is_ (&is), type_ (t) +{ +} + +compressed_input_source:: +compressed_input_source (istream& is, +                         compression_type t, +                         const string& sysid) +    : InputSource (xml::string (sysid).c_str ()), is_ (&is), type_ (t) +{ +} + +compressed_input_source:: +compressed_input_source (istream& is, +                         compression_type t, +                         const string& sysid, +                         const string& pubid) +    : xercesc::InputSource (xml::string (sysid).c_str (), +                            xml::string (pubid).c_str ()), +      is_ (&is), +      type_ (t) +{ +} + +BinInputStream* compressed_input_source:: +makeStream () const +{ +  if (is_ == 0) +    throw copy (); + +  istream& is (*is_); +  is_ = 0; +  return new compressed_input_stream ( +    is, static_cast<compressed_input_stream::compression_type> (type_)); +} + +// +// compressed_input_stream +// + +compressed_input_stream:: +compressed_input_stream (istream& is, compression_type t) +    : is_ (is), end_ (false), pos_ (0) +{ +  zs_.zalloc = Z_NULL; +  zs_.zfree  = Z_NULL; +  zs_.opaque = Z_NULL; +  zs_.next_in = Z_NULL; +  zs_.avail_in = 0; + +  int window = 0; + +  switch (t) +  { +  case raw: +    { +      window = -15; +      break; +    } +  case zlib: +    { +      window = 15; +      break; +    } +  case gzip: +    { +      window = 16 + 15; +      break; +    } +  } + +  int r (inflateInit2 (&zs_, window)); + +  if (r != Z_OK) +    throw decompression_failure (r); +} + +compressed_input_stream:: +~compressed_input_stream () +{ +  inflateEnd (&zs_); +} + +#if _XERCES_VERSION >= 30000 +XMLFilePos compressed_input_stream:: +curPos () const +{ +  return static_cast<XMLFilePos> (pos_); +} +#else +unsigned int compressed_input_stream:: +curPos () const +{ +  return static_cast<unsigned int> (pos_); +} +#endif + +#if _XERCES_VERSION >= 30000 +XMLSize_t compressed_input_stream:: +readBytes (XMLByte* const buf, const XMLSize_t size) +#else +unsigned int compressed_input_stream:: +readBytes (XMLByte* const buf, const unsigned int size) +#endif +{ +  if (end_) +    return 0; + +  // Keep calling inflate() until we fill up the buffer or reach the +  // end of stream. If we run out of input data, call the underlying +  // stream for more. +  // +  zs_.next_out = reinterpret_cast<Bytef*> (buf); +  zs_.avail_out = static_cast<uInt> (size); + +  int r; + +  do +  { +    if (zs_.avail_in == 0) +    { +      zs_.avail_in = static_cast<uInt> (read ()); +      zs_.next_in = reinterpret_cast<Bytef*> (const_cast<char*> (in_)); + +      if (zs_.avail_in == 0) +        throw decompression_failure (Z_DATA_ERROR); +    } + +    r = inflate (&zs_, Z_NO_FLUSH); + +    if (r != Z_OK && r != Z_STREAM_END) +      throw decompression_failure (r); + +  } while (r != Z_STREAM_END && zs_.avail_out != 0); + +  if (r == Z_STREAM_END) +    end_ = true; + +  size_t n (size - zs_.avail_out); +  pos_ += n; + +#if _XERCES_VERSION >= 30000 +  return static_cast<XMLSize_t> (n); +#else +  return static_cast<unsigned int> (n); +#endif +} + +#if _XERCES_VERSION >= 30000 +const XMLCh* compressed_input_stream:: +getContentType () const +{ +  return 0; +} +#endif + +size_t compressed_input_stream:: +read () +{ +  // Some implementations don't clear gcount if you call read() on a +  // stream that is in the eof state. +  // +  if (is_.eof ()) +    return 0; + +  // Unset the exception failbit while we are working with the stream. +  // +  ios_base::iostate old (is_.exceptions ()); +  is_.exceptions (old & ~ios_base::failbit); + +  is_.read (in_, static_cast<streamsize> (buf_size_)); + +  // Clear the fail bit if it was caused by eof and restore the original +  // exception state. If there are any pending errors then the exception +  // will be thrown now. +  // +  if (is_.fail () && is_.eof ()) +    is_.clear (is_.rdstate () & ~ios_base::failbit); + +  is_.exceptions (old); + +  // Make sure that if we failed, we won't be called again. +  // +  return !is_.fail () ? static_cast<size_t> (is_.gcount ()) : 0; +} diff --git a/xsd/examples/cxx/tree/compression/compressed-input-source.hxx b/xsd/examples/cxx/tree/compression/compressed-input-source.hxx new file mode 100644 index 0000000..680d39f --- /dev/null +++ b/xsd/examples/cxx/tree/compression/compressed-input-source.hxx @@ -0,0 +1,132 @@ +// file      : examples/cxx/tree/compression/compressed-input-source.hxx +// author    : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#ifndef COMPRESSED_INPUT_SOURCE_HXX +#define COMPRESSED_INPUT_SOURCE_HXX + +#include <zlib.h> + +#include <iosfwd> +#include <string> +#include <cstddef>   // std::size_t +#include <exception> + +#include <xercesc/sax/InputSource.hpp> +#include <xercesc/util/BinInputStream.hpp> + +struct decompression_failure: std::exception +{ +  explicit +  decompression_failure (int code) +      : code_ (code) +  { +  } + +  int +  code () const +  { +    return code_; +  } + +  const char* +  message () const +  { +    return zError (code_); +  } + +  virtual const char* +  what () const throw (); + +private: +  int code_; +}; + +// Xerces-C++ InputSource interface implementation with on-the-fly, zlib- +// based decompression. +// +class compressed_input_source: public xercesc::InputSource +{ +public: +  enum compression_type +  { +    raw, +    zlib, +    gzip +  }; + +  compressed_input_source (std::istream&, compression_type); + +  compressed_input_source (std::istream&, +                           compression_type, +                           const std::string& system_id); + +  compressed_input_source (std::istream&, +                           compression_type, +                           const std::string& system_id, +                           const std::string& public_id); + +  struct copy {}; + +  // Throws the copy exception if this function is called more than once. +  // +  virtual xercesc::BinInputStream* +  makeStream () const; + +private: +  mutable std::istream* is_; +  compression_type type_; +}; + +// Xerces-C++ BinInputStream interface implementation with on-the-fly, zlib- +// based decompression. +// +class compressed_input_stream: public xercesc::BinInputStream +{ +public: +  enum compression_type +  { +    raw, +    zlib, +    gzip +  }; + +  compressed_input_stream (std::istream&, compression_type); + +  virtual +  ~compressed_input_stream (); + +#if _XERCES_VERSION >= 30000 +  virtual XMLFilePos +  curPos () const; + +  virtual XMLSize_t +  readBytes (XMLByte* const buf, const XMLSize_t size); + +  virtual const XMLCh* +  getContentType () const; + +#else + +  virtual unsigned int +  readBytes (XMLByte* const buf, const unsigned int size); + +  virtual unsigned int +  curPos () const; +#endif + +private: +  std::size_t +  read (); + +private: +  std::istream& is_; +  z_stream zs_; +  bool end_; + +  static const std::size_t buf_size_ = 65536; +  char in_[buf_size_]; +  std::size_t pos_; // Current decompressed stream position. +}; + +#endif // COMPRESSED_INPUT_SOURCE_HXX diff --git a/xsd/examples/cxx/tree/compression/driver.cxx b/xsd/examples/cxx/tree/compression/driver.cxx new file mode 100644 index 0000000..db285cf --- /dev/null +++ b/xsd/examples/cxx/tree/compression/driver.cxx @@ -0,0 +1,125 @@ +// file      : examples/cxx/tree/compression/driver.cxx +// author    : Boris Kolpackov <boris@codesynthesis.com> +// copyright : not copyrighted - public domain + +#include <memory>   // std::auto_ptr +#include <fstream> +#include <iostream> + +#include <xercesc/util/PlatformUtils.hpp> + +#include "library.hxx" + +#include "compressed-input-source.hxx" +#include "compressed-format-target.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ +  if (argc != 2) +  { +    cerr << "usage: " << argv[0] << " library.xml" << endl; +    return 1; +  } + +  int r (0); + +  // We need to initialize the Xerces-C++ runtime because we are +  // using the Xerces-C++ input/output interfaces. +  // +  xercesc::XMLPlatformUtils::Initialize (); + +  try +  { +    using namespace library; + +    // Read in the XML file and obtain its object model. +    // +    ifstream ifs; +    ifs.exceptions (ifstream::badbit | ifstream::failbit); +    ifs.open (argv[1], ifstream::in | ifstream::binary); + +    compressed_input_source cis (ifs, compressed_input_source::gzip, argv[1]); + +    std::auto_ptr<catalog> c ( +      catalog_ (cis, xml_schema::flags::dont_initialize)); + + +    // Let's print what we've got. +    // +    for (catalog::book_const_iterator bi (c->book ().begin ()); +         bi != c->book ().end (); +         ++bi) +    { +      cerr << endl +           << "ID           : " << bi->id () << endl +           << "ISBN         : " << bi->isbn () << endl +           << "Title        : " << bi->title () << endl +           << "Genre        : " << bi->genre () << endl; + +      for (book::author_const_iterator ai (bi->author ().begin ()); +           ai != bi->author ().end (); +           ++ai) +      { +        cerr << "Author       : " << ai->name () << endl; +        cerr << "  Born       : " << ai->born () << endl; + +        if (ai->died ()) +          cerr << "  Died       : " << *ai->died () << endl; + +        if (ai->recommends ()) +          cerr << "  Recommends : " << (*ai->recommends ())->title () << endl; +      } + +      cerr  << "Available    : " << std::boolalpha << bi->available () << endl; +    } + +    // Prepare namespace mapping and schema location information. +    // +    xml_schema::namespace_infomap map; + +    map["lib"].name = "http://www.codesynthesis.com/library"; +    map["lib"].schema = "library.xsd"; + +    ofstream ofs; +    ofs.exceptions (ofstream::badbit | ofstream::failbit | ofstream::eofbit); +    ofs.open ("out.xml.gz", ofstream::out | ofstream::binary); + +    compressed_format_target cft (ofs, compressed_format_target::gzip); + +    // Write it out. +    // +    catalog_ (cft, *c, map, "UTF-8", xml_schema::flags::dont_initialize); + +    // Write out the compression stream trailer. If we don't do this +    // explicitly, it will be done automatically in the cft's destructor +    // but then any exceptions that might be throws will be ignored. +    // +    cft.close(); +  } +  catch (const xml_schema::exception& e) +  { +    cerr << e << endl; +    r = 1; +  } +  catch (const compression_failure& e) +  { +    cerr << "compression failure: " << e.message () << endl; +    r = 1; +  } +  catch (const decompression_failure& e) +  { +    cerr << "decompression failure: " << e.message () << endl; +    r = 1; +  } +  catch (const ios_base::failure&) +  { +    cerr << "file open or read/write failure" << endl; +    r = 1; +  } + +  xercesc::XMLPlatformUtils::Terminate (); +  return r; +} diff --git a/xsd/examples/cxx/tree/compression/library.xml.gz b/xsd/examples/cxx/tree/compression/library.xml.gzBinary files differ new file mode 100644 index 0000000..dd71159 --- /dev/null +++ b/xsd/examples/cxx/tree/compression/library.xml.gz diff --git a/xsd/examples/cxx/tree/compression/library.xsd b/xsd/examples/cxx/tree/compression/library.xsd new file mode 100644 index 0000000..0451b36 --- /dev/null +++ b/xsd/examples/cxx/tree/compression/library.xsd @@ -0,0 +1,73 @@ +<?xml version="1.0"?> + +<!-- + +file      : examples/cxx/tree/compression/library.xsd +author    : Boris Kolpackov <boris@codesynthesis.com> +copyright : not copyrighted - public domain + +--> + +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" +            xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension" +            xmlns:lib="http://www.codesynthesis.com/library" +            targetNamespace="http://www.codesynthesis.com/library"> + +  <xsd:simpleType name="isbn"> +    <xsd:restriction base="xsd:unsignedInt"/> +  </xsd:simpleType> + +  <xsd:complexType name="title"> +    <xsd:simpleContent> +      <xsd:extension base="xsd:string"> +        <xsd:attribute name="lang" type="xsd:language"/> +      </xsd:extension> +    </xsd:simpleContent> +  </xsd:complexType> + +  <xsd:simpleType name="genre"> +    <xsd:restriction base="xsd:string"> +      <xsd:enumeration value="romance"/> +      <xsd:enumeration value="fiction"/> +      <xsd:enumeration value="horror"/> +      <xsd:enumeration value="history"/> +      <xsd:enumeration value="philosophy"/> +    </xsd:restriction> +  </xsd:simpleType> + +  <xsd:complexType name="person"> +    <xsd:sequence> +      <xsd:element name="name" type="xsd:string"/> +      <xsd:element name="born" type="xsd:date"/> +      <xsd:element name="died" type="xsd:date" minOccurs="0"/> +    </xsd:sequence> +  </xsd:complexType> + +  <xsd:complexType name="author"> +    <xsd:complexContent> +      <xsd:extension base="lib:person"> +	<xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib:book"/> +      </xsd:extension> +    </xsd:complexContent> +  </xsd:complexType> + +  <xsd:complexType name="book"> +    <xsd:sequence> +      <xsd:element name="isbn" type="lib:isbn"/> +      <xsd:element name="title" type="lib:title"/> +      <xsd:element name="genre" type="lib:genre"/> +      <xsd:element name="author" type="lib:author" maxOccurs="unbounded"/> +    </xsd:sequence> +    <xsd:attribute name="available" type="xsd:boolean" default="true"/> +    <xsd:attribute name="id" type="xsd:ID" use="required"/> +  </xsd:complexType> + +  <xsd:complexType name="catalog"> +    <xsd:sequence> +      <xsd:element name="book" type="lib:book" maxOccurs="unbounded"/> +    </xsd:sequence> +  </xsd:complexType> + +  <xsd:element name="catalog" type="lib:catalog"/> + +</xsd:schema> diff --git a/xsd/examples/cxx/tree/compression/makefile b/xsd/examples/cxx/tree/compression/makefile new file mode 100644 index 0000000..30188c1 --- /dev/null +++ b/xsd/examples/cxx/tree/compression/makefile @@ -0,0 +1,117 @@ +# file      : examples/cxx/tree/compression/makefile +# author    : Boris Kolpackov <boris@codesynthesis.com> +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make + +xsd := library.xsd +cxx := driver.cxx compressed-input-source.cxx compressed-format-target.cxx + +obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o)) +dep := $(obj:.o=.o.d) + +driver   := $(out_base)/driver +install  := $(out_base)/.install +dist     := $(out_base)/.dist +dist-win := $(out_base)/.dist-win +clean    := $(out_base)/.clean + + +# Import. +# +$(call import,\ +  $(scf_root)/import/libxerces-c/stub.make,\ +  l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) + +ifeq ($(filter $(MAKECMDGOALS),dist dist-win install),) +$(call import,\ +  $(scf_root)/import/libz/stub.make,\ +  l: z.l,cpp-options: z.l.cpp-options) +endif + +# Build. +# +$(driver): $(obj) $(xerces_c.l) $(z.l) + +$(obj) $(dep): cpp_options := -I$(src_root)/libxsd +$(obj) $(dep): $(xerces_c.l.cpp-options) $(z.l.cpp-options) + +genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx) +gen  := $(addprefix $(out_base)/,$(genf)) + +$(gen): xsd := $(out_root)/xsd/xsd +$(gen): xsd_options := --generate-ostream --generate-serialization +$(gen): $(out_root)/xsd/xsd + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Install & Dist. +# +dist-common := $(out_base)/.dist-common + +$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base)) + +$(install): +	$(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README) +	$(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx) +	$(call install-data,$(src_base)/compressed-format-target.hxx,$(install_doc_dir)/xsd/$(path)/compressed-format-target.hxx) +	$(call install-data,$(src_base)/compressed-format-target.cxx,$(install_doc_dir)/xsd/$(path)/compressed-format-target.cxx) +	$(call install-data,$(src_base)/compressed-input-source.hxx,$(install_doc_dir)/xsd/$(path)/compressed-input-source.hxx) +	$(call install-data,$(src_base)/compressed-input-source.cxx,$(install_doc_dir)/xsd/$(path)/compressed-input-source.cxx) +	$(call install-data,$(src_base)/library.xsd,$(install_doc_dir)/xsd/$(path)/library.xsd) +	$(call install-data,$(src_base)/library.xml.gz,$(install_doc_dir)/xsd/$(path)/library.xml.gz) + +$(dist-common): +	$(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx) +	$(call install-data,$(src_base)/compressed-format-target.hxx,$(dist_prefix)/$(path)/compressed-format-target.hxx) +	$(call install-data,$(src_base)/compressed-format-target.cxx,$(dist_prefix)/$(path)/compressed-format-target.cxx) +	$(call install-data,$(src_base)/compressed-input-source.hxx,$(dist_prefix)/$(path)/compressed-input-source.hxx) +	$(call install-data,$(src_base)/compressed-input-source.cxx,$(dist_prefix)/$(path)/compressed-input-source.cxx) +	$(call install-data,$(src_base)/library.xsd,$(dist_prefix)/$(path)/library.xsd) +	$(call install-data,$(src_base)/library.xml.gz,$(dist_prefix)/$(path)/library.xml.gz) + +$(dist): $(dist-common) +	$(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README) + +$(dist-win): $(dist-common) +	$(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt) +	$(call message,,unix2dos $(dist_prefix)/$(path)/README.txt) + + +# Clean. +# +$(clean): $(driver).o.clean                            \ +  $(addsuffix .cxx.clean,$(obj))                       \ +  $(addsuffix .cxx.clean,$(dep))                       \ +  $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) +	$(call message,rm $$1,rm -f $$1,$(out_base)/out.xml.gz) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver out.xml.gz $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(bld_root)/install.make) +$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile) | 
