mirror of https://github.com/KLayout/klayout.git
236 lines
5.0 KiB
C++
236 lines
5.0 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2017 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 <cctype>
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
|