aboutsummaryrefslogtreecommitdiff
path: root/xsd-frontend/transformations/schema-per-type.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-12-15 22:23:46 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-02-25 13:39:56 +0300
commit949a9f572341b6cd07690f0b78b1b1941d320055 (patch)
treea4b9a32fb5a4cd6a46a17718cc854697df49c920 /xsd-frontend/transformations/schema-per-type.cxx
parent061b59ec50c40e8757c5e9237f45a2c7ade36d62 (diff)
Switch to build2
Diffstat (limited to 'xsd-frontend/transformations/schema-per-type.cxx')
-rw-r--r--xsd-frontend/transformations/schema-per-type.cxx473
1 files changed, 0 insertions, 473 deletions
diff --git a/xsd-frontend/transformations/schema-per-type.cxx b/xsd-frontend/transformations/schema-per-type.cxx
deleted file mode 100644
index d8c8e3c..0000000
--- a/xsd-frontend/transformations/schema-per-type.cxx
+++ /dev/null
@@ -1,473 +0,0 @@
-// file : xsd-frontend/transformations/schema-per-type.cxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <strings.h> // strcasecmp
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include <sstream>
-#include <iostream>
-
-#include <xsd-frontend/semantic-graph.hxx>
-#include <xsd-frontend/traversal.hxx>
-
-#include <xsd-frontend/transformations/schema-per-type.hxx>
-
-using std::wcerr;
-using std::endl;
-
-namespace XSDFrontend
-{
- typedef Transformations::SchemaPerType::Failed Failed;
- typedef std::vector<SemanticGraph::Schema*> Schemas;
- typedef std::map<SemanticGraph::Type*, SemanticGraph::Schema*> TypeSchemaMap;
-
- // Compare file paths case-insensitively.
- //
- struct FileComparator
- {
- bool
- operator() (NarrowString const& x, NarrowString const& y) const
- {
- return strcasecmp (x.c_str (), y.c_str ()) < 0;
- }
- };
-
- typedef std::set<NarrowString, FileComparator> FileSet;
-
- namespace
- {
- // Go into included and imported schemas while making sure
- // we don't process the same stuff more than once.
- //
- struct Uses: Traversal::Includes,
- Traversal::Imports,
- Traversal::Implies
- {
- Uses (Schemas& schemas, SemanticGraph::Schema*& xsd)
- : schemas_ (schemas), xsd_ (xsd)
- {
- xsd_ = 0;
- }
-
- virtual void
- traverse (SemanticGraph::Includes& i)
- {
- SemanticGraph::Schema& s (i.schema ());
-
- if (!s.context ().count ("xsd-frontend-schema-per-type-seen"))
- {
- schemas_.push_back (&s);
- s.context ().set ("xsd-frontend-schema-per-type-seen", true);
- Traversal::Includes::traverse (i);
- }
- }
-
- virtual void
- traverse (SemanticGraph::Imports& i)
- {
- SemanticGraph::Schema& s (i.schema ());
-
- if (!s.context ().count ("xsd-frontend-schema-per-type-seen"))
- {
- schemas_.push_back (&s);
- s.context ().set ("xsd-frontend-schema-per-type-seen", true);
- Traversal::Imports::traverse (i);
- }
- }
-
- virtual void
- traverse (SemanticGraph::Implies& i)
- {
- if (xsd_ == 0)
- xsd_ = &i.schema ();
- }
-
- private:
- Schemas& schemas_;
- SemanticGraph::Schema*& xsd_;
- };
-
- void
- process_schema (SemanticGraph::Schema& s,
- SemanticGraph::Schema& root,
- SemanticGraph::Schema& xsd,
- TypeSchemaMap& tsm,
- FileSet& file_set,
- bool fat_type_file,
- Transformations::SchemaPerTypeTranslator& trans)
- {
- using namespace SemanticGraph;
-
- Path xsd_path ("XMLSchema.xsd");
- Namespace& ns (dynamic_cast<Namespace&> (s.names_begin ()->named ()));
-
- // We should be careful with iterator caching since we are going to
- // remove some of the nodes.
- //
- for (Scope::NamesIterator i (ns.names_begin ()); i != ns.names_end ();)
- {
- Nameable& n (i->named ());
-
- if (n.is_a<Type> ())
- {
- String name (n.name ());
-
- // Remove from the namespace.
- //
- Scope::NamesIterator tmp (i++);
- root.delete_edge (ns, n, *tmp);
-
- // Add a new schema node.
- //
- Path path;
- String tn (trans.translate_type (ns.name (), name));
- String wbase (tn ? tn : name);
-
- try
- {
- NarrowString base (wbase.to_narrow ());
-
- // Escape directory separators unless they came from the
- // translator.
- //
- if (!tn)
- {
- for (NarrowString::iterator i (base.begin ()), e (base.end ());
- i != e; ++i)
- {
- if (*i == '/' || *i == '\\')
- *i = '_';
- }
- }
-
- // Make sure it is unique.
- //
- NarrowString file_name (base);
-
- for (unsigned long i (1);
- file_set.find (file_name) != file_set.end ();
- ++i)
- {
- std::ostringstream os;
- os << i;
- file_name = base + os.str ();
- }
-
- file_set.insert (file_name);
- file_name += ".xsd";
-
- try
- {
- path = Path (file_name);
- }
- catch (InvalidPath const&)
- {
- wcerr << "error: '" << file_name.c_str () << "' is not a valid "
- << "filesystem path" << endl;
-
- wcerr << "info: use type to file name translation mechanism "
- << "to resolve this" << endl;
-
- throw Failed ();
- }
- }
- catch (NonRepresentable const&)
- {
- wcerr << "error: '" << wbase << "' cannot be represented as a "
- << "narrow string" << endl;
-
- wcerr << "info: use type to file name translation mechanism "
- << "to resolve this" << endl;
-
- throw Failed ();
- }
-
- Type& t (dynamic_cast<Type&> (n));
-
- Schema& ts (root.new_node<Schema> (path, 1, 1));
- root.new_edge<Implies> (ts, xsd, xsd_path);
-
- Namespace& tns (root.new_node<Namespace> (path, 1, 1));
- root.new_edge<Names> (ts, tns, ns.name ());
- root.new_edge<Names> (tns, n, name);
-
- // If we are generating fat type files, then also move the global
- // elements this type classifies to the new schema.
- //
- if (fat_type_file)
- {
- for (Type::ClassifiesIterator j (t.classifies_begin ());
- j != t.classifies_end (); ++j)
- {
- Instance& e (j->instance ());
-
- // We can only move a global element from the same namespace.
- //
- if (e.is_a<Element> () &&
- e.scope ().is_a<Namespace> () &&
- e.scope ().name () == ns.name ())
- {
- Names& n (e.named ());
- String name (n.name ());
-
- // Watch out for the iterator validity: the edge we are
- // about to remove can be from the same list we are
- // currently iterating.
- //
- if (i != ns.names_end () && &*i == &n)
- ++i;
-
- root.delete_edge (n.scope (), e, n);
- root.new_edge<Names> (tns, e, name);
- }
- }
- }
-
- // Add include to the original schema and enter into the
- // type-schema map.
- //
- root.new_edge<Includes> (s, ts, path);
- tsm[&t] = &ts;
-
- // Also mark this schema as "type schema" in case someone
- // needs to distinguish between the two kinds.
- //
- ts.context ().set ("type-schema", true);
- }
- else
- ++i;
- }
- }
-
- struct Type: Traversal::List,
- Traversal::Complex,
- Traversal::Member
- {
- Type (SemanticGraph::Schema& schema,
- SemanticGraph::Schema& root,
- char const* by_value_key,
- TypeSchemaMap& tsm)
- : schema_ (schema),
- root_ (root),
- by_value_key_ (by_value_key),
- tsm_ (tsm)
- {
- *this >> names_ >> *this;
- }
-
- virtual void
- traverse (SemanticGraph::List& l)
- {
- // Treat item type as base type since it is impossible
- // to create recursive constructs using list.
- //
- SemanticGraph::Type& t (l.argumented ().type ());
- set_dep (t, false);
- }
-
- virtual void
- traverse (SemanticGraph::Complex& c)
- {
- if (c.inherits_p ())
- set_dep (c.inherits ().base (), false);
-
- Traversal::Complex::names (c);
- }
-
- virtual void
- traverse (SemanticGraph::Member& m)
- {
- SemanticGraph::Type& t (m.type ());
-
- bool weak (
- by_value_key_ == 0 ||
- !t.context ().count (by_value_key_) ||
- !t.context ().get<bool> (by_value_key_));
-
- set_dep (t, weak);
- }
-
- private:
- void
- set_dep (SemanticGraph::Type& t, bool weak)
- {
- using namespace SemanticGraph;
-
- TypeSchemaMap::iterator i (tsm_.find (&t));
-
- // If a type is not present in the map then it must be
- // a built-in type.
- //
- if (i == tsm_.end ())
- return;
-
- // Check if we already saw this type. Theoretically, it could
- // be that we need to upgrade the type of include from weak to
- // strong. But because inheritance is handled first, the type
- // in the set will already be with the right type.
- //
- if (type_set_.find (&t) != type_set_.end ())
- return;
-
- type_set_.insert (&t);
-
- Schema& s (*i->second);
- Path path (s.used_begin ()->path ());
- SemanticGraph::Uses* u;
-
- if (s.names_begin ()->name () == schema_.names_begin ()->name ())
- u = &root_.new_edge<Includes> (schema_, s, path);
- else
- u = &root_.new_edge<Imports> (schema_, s, path);
-
- if (weak)
- u->context().set ("weak", true);
- }
-
- private:
- SemanticGraph::Schema& schema_;
- SemanticGraph::Schema& root_;
- char const* by_value_key_;
- TypeSchemaMap& tsm_;
- std::set<SemanticGraph::Type*> type_set_;
-
- Traversal::Names names_;
- };
- }
-
- namespace Transformations
- {
- SchemaPerType::
- SchemaPerType (SchemaPerTypeTranslator& trans,
- bool fat,
- char const* key)
- : fat_type_file_ (fat), by_value_key_ (key), trans_ (trans)
- {
- }
-
- Schemas SchemaPerType::
- transform (SemanticGraph::Schema& root)
- {
- // Collect initial schema nodes.
- //
- Schemas schemas;
- SemanticGraph::Schema* xsd;
-
- {
- Traversal::Schema schema;
- Uses uses (schemas, xsd);
-
- schema >> uses >> schema;
-
- // Some twisted schemas do recusive inclusions.
- //
- root.context ().set ("xsd-frontend-schema-per-type-seen", true);
-
- schema.dispatch (root);
- }
-
- // wcerr << schemas.size () << " initial schema nodes" << endl;
-
- // Add the schema file names to the file set.
- //
- FileSet file_set;
-
- for (Schemas::iterator i (schemas.begin ()); i != schemas.end (); ++i)
- {
- // This path was already normalized by the parser.
- //
- SemanticGraph::Path const& path (
- (*i)->context ().get<SemanticGraph::Path> ("absolute-path"));
-
- // Translate the schema file name.
- //
- NarrowString abs_path;
-
- // Try to use the portable representation of the path. If that
- // fails, fall back to the native representation.
- //
- try
- {
- abs_path = path.posix_string ();
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- abs_path = path.string ();
- }
-
- NarrowString tf (trans_.translate_schema (abs_path));
- NarrowString file (tf ? tf : path.leaf ().string ());
-
- size_t p (file.rfind ('.'));
- NarrowString ext (
- p != NarrowString::npos ? NarrowString (file, p) : "");
-
- NarrowString base (
- p != NarrowString::npos ? NarrowString (file, 0, p) : file);
-
- // Make sure it is unique.
- //
- NarrowString new_name (base);
-
- for (unsigned long n (1);
- file_set.find (new_name) != file_set.end ();
- ++n)
- {
- std::ostringstream os;
- os << n;
- new_name = base + os.str ();
- }
-
- file_set.insert (new_name);
- new_name += ext;
-
- try
- {
- (*i)->context ().set ("renamed", SemanticGraph::Path (new_name));
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- wcerr << "error: '" << new_name.c_str () << "' is not a valid "
- << "filesystem path" << endl;
-
- wcerr << "info: use schema file name translation mechanism "
- << "to resolve this" << endl;
-
- throw Failed ();
- }
- }
-
- // Process each schema node.
- //
- TypeSchemaMap tsm;
-
- for (Schemas::iterator i (schemas.begin ()); i != schemas.end (); ++i)
- {
- process_schema (**i, root, *xsd, tsm, file_set, fat_type_file_, trans_);
- }
-
- // wcerr << tsm.size () << " type schema nodes" << endl;
-
- // Establish include/import dependencies. While at it add the
- // new schemas to the list which we will return.
- //
- for (TypeSchemaMap::iterator i (tsm.begin ()); i != tsm.end (); ++i)
- {
- SemanticGraph::Schema& s (*i->second);
- Type t (s, root, by_value_key_, tsm);
- t.dispatch (*i->first);
- schemas.push_back (&s);
- }
-
- return schemas;
- }
-
- SchemaPerTypeTranslator::
- ~SchemaPerTypeTranslator ()
- {
- }
- }
-}