1 // file      : xsd/cxx/parser/elements.cxx
2 // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 // license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 
5 #include <cxx/parser/elements.hxx>
6 
7 namespace CXX
8 {
9   namespace Parser
10   {
11     Context::
Context(std::wostream & o,SemanticGraph::Schema & root,SemanticGraph::Path const & path,options_type const & ops,StringLiteralMap const * map,Regex const * he,Regex const * ie,Regex const * hie)12     Context (std::wostream& o,
13              SemanticGraph::Schema& root,
14              SemanticGraph::Path const& path,
15              options_type const& ops,
16              StringLiteralMap const* map,
17              Regex const* he,
18              Regex const* ie,
19              Regex const* hie)
20         : CXX::Context (o, root, path, ops, map),
21           options (ops),
22           xml_parser (xml_parser_),
23           simple_base (simple_base_),
24           complex_base (complex_base_),
25           list_base (list_base_),
26           cout_inst (cout_inst_),
27           cerr_inst (cerr_inst_),
28           parser_map (parser_map_),
29           std_string_type (std_string_type_),
30           validation (validation_),
31           polymorphic (polymorphic_),
32           hxx_expr (he),
33           ixx_expr (ie),
34           hxx_impl_expr (hie),
35           xml_parser_ (ops.xml_parser ()),
36           validation_ ((ops.xml_parser () == "expat" ||
37                         ops.generate_validation ()) &&
38                        !ops.suppress_validation ()),
39           polymorphic_ (ops.generate_polymorphic ())
40     {
41       if (char_type == L"char")
42         std_string_type = L"::std::string";
43       else if (char_type == L"wchar_t")
44         std_string_type = L"::std::wstring";
45       else
46         std_string_type = L"::std::basic_string< " + char_type + L" >";
47 
48       String xs_ns (xs_ns_name ());
49 
50       string_type = xs_ns + L"::ro_string";
51       simple_base = xs_ns + L"::simple_content";
52       complex_base = xs_ns + L"::complex_content";
53       list_base = xs_ns + L"::list_base";
54 
55       cout_inst = (char_type == L"char" ? L"std::cout" : L"std::wcout");
56       cerr_inst = (char_type == L"char" ? L"std::cerr" : L"std::wcerr");
57 
58       if (polymorphic)
59         parser_map_ = xs_ns + L"::parser_map";
60     }
61 
62     Context::
Context(Context & c)63     Context (Context& c)
64         : CXX::Context (c),
65           options (c.options),
66           xml_parser (c.xml_parser),
67           simple_base (c.simple_base),
68           complex_base (c.complex_base),
69           list_base (c.list_base),
70           cout_inst (c.cout_inst),
71           cerr_inst (c.cerr_inst),
72           parser_map (c.parser_map),
73           std_string_type (c.std_string_type),
74           validation (c.validation),
75           polymorphic (c.polymorphic),
76           hxx_expr (c.hxx_expr),
77           ixx_expr (c.ixx_expr),
78           hxx_impl_expr (c.hxx_impl_expr)
79     {
80     }
81 
82     Context::
Context(Context & c,std::wostream & o)83     Context (Context& c, std::wostream& o)
84         : CXX::Context (c, o),
85           options (c.options),
86           xml_parser (c.xml_parser),
87           simple_base (c.simple_base),
88           complex_base (c.complex_base),
89           list_base (c.list_base),
90           cout_inst (c.cout_inst),
91           cerr_inst (c.cerr_inst),
92           parser_map (c.parser_map),
93           std_string_type (c.std_string_type),
94           validation (c.validation),
95           polymorphic (c.polymorphic),
96           hxx_expr (c.hxx_expr),
97           ixx_expr (c.ixx_expr),
98           hxx_impl_expr (c.hxx_impl_expr)
99     {
100     }
101 
102     Content::Value Context::
content(SemanticGraph::Complex & c)103     content (SemanticGraph::Complex& c)
104     {
105       using namespace SemanticGraph;
106 
107       if (c.mixed_p ())
108         return Content::mixed;
109 
110       if (c.inherits_p ())
111       {
112         Type& base (c.inherits ().base ());
113 
114         if (Complex* cb = dynamic_cast<Complex*> (&base))
115           return content (*cb);
116 
117         if (base.is_a<AnyType> ())
118           return Content::complex;
119 
120         // Everyhting else (built-in type and AnySimpleType) is simple
121         // content.
122         //
123         return Content::simple;
124       }
125       else
126         return Content::complex;
127     }
128 
129     bool Context::
anonymous(SemanticGraph::Type & t)130     anonymous (SemanticGraph::Type& t)
131     {
132       return t.context ().count ("anonymous");
133     }
134 
135     String const& Context::
ret_type(SemanticGraph::Type & t)136     ret_type (SemanticGraph::Type& t)
137     {
138       return t.context ().get<String> ("ret-type");
139     }
140 
141     String const& Context::
arg_type(SemanticGraph::Type & t)142     arg_type (SemanticGraph::Type& t)
143     {
144       return t.context ().get<String> ("arg-type");
145     }
146 
147     String const& Context::
post_name(SemanticGraph::Type & t)148     post_name (SemanticGraph::Type& t)
149     {
150       return t.context ().get<String> ("post");
151     }
152 
153     String const& Context::
eparser(SemanticGraph::Member & m)154     eparser (SemanticGraph::Member& m)
155     {
156       return m.context ().get<String> ("parser");
157     }
158 
159     String const& Context::
emember(SemanticGraph::Member & m)160     emember (SemanticGraph::Member& m)
161     {
162       return m.context ().get<String> ("member");
163     }
164 
165     String const& Context::
emember_map(SemanticGraph::Member & m)166     emember_map (SemanticGraph::Member& m)
167     {
168       return m.context ().get<String> ("member-map");
169     }
170 
171     String const& Context::
eimpl(SemanticGraph::Type & t)172     eimpl (SemanticGraph::Type& t)
173     {
174       return t.context ().get<String> ("impl");
175     }
176 
177     // Includes
178     //
179     void TypeForward::
traverse(SemanticGraph::Type & t)180     traverse (SemanticGraph::Type& t)
181     {
182       os << "class " << t.context ().get<String> (name_key_) << ";";
183     }
184 
185     void Includes::
traverse_(SemanticGraph::Uses & u)186     traverse_ (SemanticGraph::Uses& u)
187     {
188       // Support for weak (forward) inclusion used in the file-per-type
189       // compilation model.
190       //
191       SemanticGraph::Schema& s (u.schema ());
192       bool weak (u.context ().count ("weak"));
193 
194       if (weak && (type_ == header || type_ == impl_header))
195       {
196         // Generate forward declarations. We don't really need them
197         // in the impl files.
198         //
199         if (type_ == header)
200           schema_.dispatch (s);
201 
202         return;
203       }
204 
205       if (type_ == source && !weak)
206         return;
207 
208       SemanticGraph::Path path (
209         s.context ().count ("renamed")
210         ? s.context ().get<SemanticGraph::Path> ("renamed")
211         : u.path ());
212       path.normalize ();
213 
214       // Try to use the portable representation of the path. If that
215       // fails, fall back to the native representation.
216       //
217       NarrowString path_str;
218       try
219       {
220         path_str = path.posix_string ();
221       }
222       catch (SemanticGraph::InvalidPath const&)
223       {
224         path_str = path.string ();
225       }
226 
227       String inc_path;
228 
229       switch (type_)
230       {
231       case header:
232       case source:
233         {
234           inc_path = ctx_.hxx_expr->replace (path_str);
235           break;
236         }
237       case impl_header:
238         {
239           inc_path = ctx_.hxx_impl_expr->replace (path_str);
240           break;
241         }
242       }
243 
244       ctx_.os << "#include " << ctx_.process_include_path (inc_path) << endl
245               << endl;
246     }
247   }
248 }
249