/* KLayout Layout Viewer Copyright (C) 2006-2016 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "gsiDecl.h" #include namespace gsi { // -------------------------------------------------------------------------------- // Implementation of MethodBase MethodBase::MethodBase (const std::string &name, const std::string &doc, bool c, bool s) : m_doc (doc), m_const (c), m_static (s), m_protected (false), m_argsize (0) { reset_called (); parse_name (name); } MethodBase::MethodBase (const std::string &name, const std::string &doc) : m_doc (doc), m_const (false), m_static (false), m_protected (false), m_argsize (0) { reset_called (); parse_name (name); } bool MethodBase::compatible_with_num_args (unsigned int nargs) const { if (nargs > (unsigned int) (std::distance (begin_arguments (), end_arguments ()))) { return false; } else { for (MethodBase::argument_iterator a = begin_arguments (); a != end_arguments () && (! a->spec () || ! a->spec ()->has_default ()); ++a) { if (nargs == 0) { return false; } --nargs; } return true; } } void MethodBase::check_no_args () const { if (end_arguments () != begin_arguments ()) { throw NoArgumentsAllowedException (); } } void MethodBase::check_num_args (unsigned int num) const { if (! compatible_with_num_args (num)) { throw NeedsArgumentsException (num, std::distance (begin_arguments (), end_arguments ())); } } void MethodBase::check_return_type (const ArgType &a) const { if (m_ret_type != a) { throw IncompatibleReturnTypeException (a, m_ret_type); } } void MethodBase::parse_name (const std::string &name) { const char *n = name.c_str (); if (*n == '*' && n[1]) { m_protected = true; ++n; } while (*n) { m_method_synonyms.push_back (MethodSynonym ()); if ((*n == '#' || *n == ':') && n[1]) { if (*n == '#') { m_method_synonyms.back ().deprecated = true; } else { m_method_synonyms.back ().is_getter = true; } ++n; } bool any = false; while (*n && (*n != '|' || !any)) { if (*n == '\\' && n[1]) { ++n; } m_method_synonyms.back ().name += *n; any = true; if (isalnum (*n) || *n == '_') { ++n; if (*n == '?' && (n[1] == '|' || !n[1])) { ++n; m_method_synonyms.back ().is_predicate = true; } else if (*n == '=' && (n[1] == '|' || !n[1])) { ++n; m_method_synonyms.back ().is_setter = true; } } else { ++n; } } if (*n == '|') { ++n; } } } std::string MethodBase::to_string () const { std::string res; if (is_static ()) { res += "static "; } res += ret_type ().to_string (); res += " "; if (m_method_synonyms.size () == 1) { res += names (); } else { res += "{" + names() + "}"; } res += "("; for (argument_iterator a = begin_arguments (); a != end_arguments (); ++a) { if (a != begin_arguments ()) { res += ", "; } res += a->to_string (); } res += ")"; if (is_const ()) { res += " const"; } return res; } std::string MethodBase::names () const { std::string res; for (synonym_iterator s = m_method_synonyms.begin (); s != m_method_synonyms.end (); ++s) { if (s != m_method_synonyms.begin ()) { res += "|"; } res += s->name; if (s->is_setter) { res += "="; } else if (s->is_predicate) { res += "?"; } } return res; } std::string MethodBase::combined_name () const { std::string res; if (m_protected) { res += "*"; } for (synonym_iterator s = m_method_synonyms.begin (); s != m_method_synonyms.end (); ++s) { if (s != m_method_synonyms.begin ()) { res += "|"; } if (s->is_getter) { res += ":"; } if (s->deprecated) { res += "#"; } for (const char *n = s->name.c_str (); *n; ++n) { if (*n == '*' || *n == '#' || *n == '\\' || *n == '|' || *n == ':' || *n == '=' || *n == '?') { res += "\\"; } res += *n; } if (s->is_setter) { res += "="; } else if (s->is_predicate) { res += "?"; } } return res; } const std::string & MethodBase::primary_name () const { if (m_method_synonyms.empty ()) { static const std::string empty_name; return empty_name; } else { return m_method_synonyms.front ().name; } } }