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