// file : cli/context.cxx // author : Boris Kolpackov // copyright : Copyright (c) 2009 Code Synthesis Tools CC // license : MIT; see accompanying LICENSE file #include "context.hxx" using namespace std; namespace { char const* keywords[] = { "NULL", "and", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "class", "compl", "const", "const_cast", "continue", "default", "delete", "do", "double", "dynamic_cast", "else", "end_eq", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", "short", "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", "this", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" }; } context:: context (ostream& os_, semantics::cli_unit& unit_, options_type const& ops) : data_ (new (shared) data), os (os_), unit (unit_), options (ops), inl (data_->inl_), opt_prefix (options.option_prefix ()), opt_sep (options.option_separator ()), reserved_name_map (options.reserved_name ()), keyword_set (data_->keyword_set_) { if (!options.suppress_inline ()) data_->inl_ = "inline "; for (size_t i (0); i < sizeof (keywords) / sizeof (char*); ++i) data_->keyword_set_.insert (keywords[i]); } context:: context (context& c) : data_ (c.data_), os (c.os), unit (c.unit), options (c.options), inl (c.inl), opt_prefix (c.opt_prefix), opt_sep (c.opt_sep), reserved_name_map (c.reserved_name_map), keyword_set (c.keyword_set) { } string context:: escape (string const& name) const { typedef string::size_type size; string r; size n (name.size ()); // In most common cases we will have that many characters. // r.reserve (n); for (size i (0); i < n; ++i) { char c (name[i]); if (i == 0) { if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) r = (c >= '0' && c <= '9') ? "cxx_" : "cxx"; } if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) r += '_'; else r += c; } if (r.empty ()) r = "cxx"; // Custom reserved words. // reserved_name_map_type::const_iterator i (reserved_name_map.find (r)); if (i != reserved_name_map.end ()) { if (!i->second.empty ()) return i->second; else r += L'_'; } // Keywords // if (keyword_set.find (r) != keyword_set.end ()) { r += '_'; // Re-run custom words. // i = reserved_name_map.find (r); if (i != reserved_name_map.end ()) { if (!i->second.empty ()) return i->second; else r += L'_'; } } return r; } // namespace // void namespace_:: pre (type& ns) { string name (ns.name ()); if (!name.empty ()) os << "namespace " << escape (name) << "{"; } void namespace_:: post (type& ns) { if (!ns.name ().empty ()) os << "}"; }