diff --git a/oRTP b/oRTP index 706f0b59f..ce8c19753 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 706f0b59f818a69c673053e831fa1f19a855f80b +Subproject commit ce8c19753495b4ad16a6c5df2bf2bf235443f762 diff --git a/tools/Makefile.am b/tools/Makefile.am index 169fda781..fb6253465 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -59,7 +59,9 @@ lpc2xml_test_LDADD=\ $(top_builddir)/coreapi/liblinphone.la \ liblpc2xml.la -lp_gen_wrappers_SOURCES=genwrappers.cc +lp_gen_wrappers_SOURCES=genwrappers.cc \ + software-desc.cc software-desc.hh \ + generator.cc generator.hh lp_gen_wrappers_LDADD= \ $(LIBXML2_LIBS) diff --git a/tools/generator.cc b/tools/generator.cc new file mode 100644 index 000000000..dddefb09a --- /dev/null +++ b/tools/generator.cc @@ -0,0 +1,284 @@ +/* +linphone +Copyright (C) 2013 Belledonne Communications SARL +Simon Morlat (simon.morlat@linphone.org) + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#include + +#include "generator.hh" + +#ifdef WIN32 +#include +#endif + + +CplusplusGenerator::CplusplusGenerator(){ +} + +void CplusplusGenerator::generate(Project *proj){ + list classes=proj->getClasses(); + mCurProj=proj; +#ifndef WIN32 + mkdir(proj->getName().c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH); +#else + _mkdir(proj->getName().c_str()); +#endif + for_each(classes.begin(),classes.end(),bind1st(mem_fun(&CplusplusGenerator::writeClass),this)); +} + +void CplusplusGenerator::writeClass(Class *klass){ + ostringstream filename; + + if (klass->getType()!=Type::Class) return; + filename<getName()<<"/"<getName()<<".hh"; + mOutfile.open(filename.str().c_str()); + if (!mOutfile.is_open()){ + cerr<<"Could not write into "< &methods=klass->getMethods(); + mCurClass=klass; + mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<"<getName().empty()) + mOutfile<<"namespace "<getName()<<"{"<getName()<<"{"<getName().empty()) + mOutfile<<"} //end of namespace "<getName()<getType(); + + if (type->getBasicType()==Type::Class){ + if (arg->isConst()){ + mOutfile<<"const "; + } + mOutfile<getName(); + if (arg->isPointer()) + mOutfile<<"*"; + }else if (type->getBasicType()==Type::Integer){ + mOutfile<<"int"; + }else if (type->getBasicType()==Type::Enum){ + mOutfile<getName(); + }else if (type->getBasicType()==Type::String){ + if (!isReturn) + mOutfile<<"const std::string &"; + else + mOutfile<<"std::string"; + }else if (type->getBasicType()==Type::Void){ + mOutfile<<"void"; + }else if (type->getBasicType()==Type::Boolean){ + mOutfile<<"bool"; + } + if (!isReturn && !arg->getName().empty()) + mOutfile<<" "<getName(); +} + +void CplusplusGenerator::writeTabs(int ntabs){ + int i; + for(i=0;i100 && comment[i]==' ')){ + mOutfile<getReturnArg(); + const list &args=method->getArgs(); + list::const_iterator it; + + writeTabs(1); + mOutfile<<"/**"<getHelp(),1); + mOutfile<getName()<<"("; + + for(it=args.begin();it!=args.end();++it){ + if (it!=args.begin()) mOutfile<<", "; + writeArgument(*it); + } + mOutfile<<")"; + if (method->isConst()) mOutfile<<"const"; + mOutfile<<";"< classes=proj->getClasses(); + mCurProj=proj; +#ifndef WIN32 + unlink(proj->getName().c_str()); + mkdir(proj->getName().c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH); +#else + _mkdir(proj->getName().c_str()); +#endif + for_each(classes.begin(),classes.end(),bind1st(mem_fun(&JavascriptGenerator::writeClass),this)); +} + +void JavascriptGenerator::writeClass(Class *klass){ + ostringstream filename; + + if (klass->getType()!=Type::Class) return; + filename<getName()<<"/"<getName()<<".js"; + mOutfile.open(filename.str().c_str()); + if (!mOutfile.is_open()){ + cerr<<"Could not write into "< &methods=klass->getMethods(); + mCurClass=klass; + mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<getName().empty()) + // mOutfile<<"namespace "<getName()<<"{"<getHelp()<getName()< properties=klass->getProperties(); + for_each(properties.begin(),properties.end(),bind1st(mem_fun(&JavascriptGenerator::writeProperty),this)); + mOutfile<getName().empty()) + // mOutfile<<"} //end of namespace "<getName()<getBasicType()){ + case Type::Float: + case Type::Integer: + mOutfile<<"number"; + break; + case Type::String: + mOutfile<<"string"; + break; + case Type::Boolean: + mOutfile<<"boolean"; + break; + case Type::Class: + case Type::Enum: + mOutfile<<"external:"<getName(); + break; + case Type::Void: + mOutfile<<"void"; + break; + case Type::Callback: + break; + } +} + +void JavascriptGenerator::writeArgument(Argument *arg, bool isReturn){ + if (!isReturn){ + mOutfile<<" * @param {"; + writeType(arg->getType()); + mOutfile<<"} "<getName()<<" - "<getHelp()<getType()); + mOutfile<<"} "<getHelp()<100 && comment[i]==' ')){ + mOutfile<getHelp(),0); + mOutfile<getType()); + mOutfile<<"} external:"<getName()<<"#"<getName()<getAttribute()==Property::ReadOnly) + mOutfile<<" * @readonly"<getReturnArg(); + const list &args=method->getArgs(); + list::const_iterator it; + + if (method->getPropertyBehaviour()!=Method::None) return; + if (method->getName()=="ref" || method->getName()=="unref") return; + + mOutfile<<"/**"<getHelp(),0); + mOutfile<getName()<<"#"<getName()< + +#include "software-desc.hh" + +class OutputGenerator{ +public: + virtual void generate(Project *proj)=0; +}; + +class CplusplusGenerator : public OutputGenerator{ +public: + CplusplusGenerator(); + virtual void generate(Project *proj); +private: + void writeClass(Class *klass); + void writeArgument(Argument *arg, bool isReturn=false); + void writeTabs(int ntabs); + void writeHelpComment(const std::string &comment, int ntabs); + void writeMethod(Method *method); + ofstream mOutfile; + Project *mCurProj; + Class *mCurClass; +}; + +class JavascriptGenerator : public OutputGenerator{ +public: + JavascriptGenerator(); + virtual void generate(Project *proj); +private: + void writeClass(Class *klass); + void writeType(Type *type); + void writeArgument(Argument *arg, bool isReturn=false); + void writeTabs(int ntabs); + void writeHelpComment(const std::string &comment, int ntabs); + void writeProperty(Property *prop); + void writeMethod(Method *method); + ofstream mOutfile; + Project *mCurProj; + Class *mCurClass; +}; + + +#endif diff --git a/tools/genwrappers.cc b/tools/genwrappers.cc index 55a30e396..6bc1dfb5f 100644 --- a/tools/genwrappers.cc +++ b/tools/genwrappers.cc @@ -18,632 +18,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "software-desc.hh" +#include "generator.hh" + #include #include #include #include #include -#include #include -#include -#include -#include - -#include -#include -using namespace::std; - - -class Type{ -public: - enum BasicType{ - Void, - Boolean, - Integer, - Float, - String, - Enum, - Class, - Callback - }; - static const char *sBasicTypeNames[]; - static Type* addType(BasicType bt, const string &name){ - Type* ret; - if ((ret=mTypes[name])==0){ - //cout<<"Adding new "<mBasic=bt; - } - return ret; - } - static Type *getType(const std::string &tname){ - if (strstr(tname.c_str(),"char")!=0 && strchr(tname.c_str(),'*')!=0){ - return &sStringType; - }else if (tname.find("int")==0){ - return &sIntegerType; - }else if (tname.find("float")==0){ - return &sFloatType; - }else if (tname.find("bool_t")==0){ - return &sBooleanType; - }else if (tname.find("void")!=string::npos){ - return &sVoidType; - }else if (tname.find("enum")==0){ - return addType(Enum,tname.c_str()+strlen("enum ")); - }else{/*an object?*/ - - string tmp=tname; - size_t pos; - - /*really ugly and slow*/ - - pos=tmp.find('*'); - if (pos!=string::npos) - tmp.erase(pos,1); - - pos=tmp.find("const"); - if (pos!=string::npos) - tmp.erase(pos,strlen("const")); - - while ((pos=tmp.find(' '))!=string::npos){ - tmp.erase(pos,1); - } - return addType(Class,tmp); - } - cerr<<"Unhandled type name"< mTypes; -}; - -Type Type::sStringType(Type::String); -Type Type::sIntegerType(Type::Integer); -Type Type::sVoidType(Type::Void); -Type Type::sBooleanType(Type::Boolean); -Type Type::sFloatType(Type::Float); -std::map Type::mTypes; -const char *Type::sBasicTypeNames[]={ - "Void", - "Boolean", - "Integer", - "Float", - "String", - "Enum", - "Class", - "Callback", - "undef", - "undef" -}; - - -class Argument{ -public: - Argument(Type *type, const string &argname, bool isConst, bool isPointer) : mType(type), mName(argname), mConst(isConst), mPointer(isPointer){ - if (!isPointer) mConst=false; - } - Type *getType()const{ - return mType; - } - bool isConst()const{ - return mConst; - } - const string &getName()const{ - return mName; - } - bool isPointer()const{ - return mPointer; - } - const string &getHelp()const{ - return mHelp; - } - void setHelp(const string &help){ - mHelp=help; - } -private: - - Type *mType; - string mName; - string mHelp; - bool mConst; - bool mPointer; -}; - -class Method{ -public: - enum PropertyBehaviour{ - None, - Read, - Write - }; - Method(const std::string &uid, Argument* return_arg, const std::string &name, const list &args, bool isConst, bool isStatic){ - mUid=uid; - mReturn=return_arg; - mName=name; - mArgs=args; - mConst=isConst; - mStatic=isStatic; - analyseProperties(); - } - void setHelp(const std::string &help){ - mHelp=help; - } - Argument *getReturnArg()const{ - return mReturn; - } - const string &getName()const{ - return mName; - } - const list &getArgs()const { - return mArgs; - } - bool isConst()const{ - return mConst; - } - bool isStatic()const{ - return mStatic; - } - const string &getHelp(){ - return mHelp; - } - PropertyBehaviour getPropertyBehaviour()const{ - return mPropertyBehaviour; - } - const string &getPropertyName()const{ - return mPropertyName; - } -private: - void analyseProperties(){ - size_t enabled_pos; - mPropertyBehaviour=None; - - if (mName.find("get")==0 && mArgs.size()==0){ - mPropertyName=mName.substr(3,string::npos); - if (!mPropertyName.empty()){ - mPropertyName[0]=tolower(mPropertyName[0]); - mPropertyBehaviour=Read; - } - }else if (mName.find("enable")==0 && mArgs.size()==1){ - mPropertyName=mName.substr(6,string::npos); - if (!mPropertyName.empty()){ - mPropertyName[0]=tolower(mPropertyName[0]); - mPropertyBehaviour=Write; - } - }else if (mName.find("set")==0 && mArgs.size()==1){ - mPropertyName=mName.substr(3,string::npos); - if (!mPropertyName.empty()){ - mPropertyName[0]=tolower(mPropertyName[0]); - mPropertyBehaviour=Write; - } - }else if ((enabled_pos=mName.rfind("Enabled"))!=string::npos && mArgs.size()==0){ - size_t goodpos=mName.size()-7; - if (enabled_pos==goodpos){ - mPropertyName=mName.substr(0,goodpos); - if (!mPropertyName.empty()){ - mPropertyBehaviour=Read; - } - } - } - if (mPropertyBehaviour==None) - mPropertyName=""; - } - string mUid; - Argument *mReturn; - string mName; - list mArgs; - string mHelp; - string mPropertyName; /*if it can be a property*/ - PropertyBehaviour mPropertyBehaviour; - bool mConst; - bool mStatic; -}; - -class Property{ -public: - enum Attribute{ - ReadOnly, - ReadWrite - }; - Property(Attribute attr, const string &name, Type *type, const string &help) : mAttr(attr), mName(name), mType(type), mHelp(help){ - } - const string &getName()const{ - return mName; - } - const string &getHelp()const{ - return mHelp; - } - void setHelp(const string &help){ - mHelp=help; - } - Attribute getAttribute()const{ - return mAttr; - } - void setAttribute(Attribute attr){ - mAttr=attr; - } - Type* getType()const{ - return mType; - } -private: - Attribute mAttr; - string mName; - Type *mType; - string mHelp; -}; - -/*actually a class or an enum*/ -class Class{ -public: - Class(const std::string &name): mName(name){ - } - Type::BasicType getType(){ - return Type::getType(mName)->getBasicType(); - } - void addMethod(Method *method){ - if (mMethods.find(method->getName())==mMethods.end()) - mMethods.insert(make_pair(method->getName(),method)); - } - void setHelp(const std::string &help){ - mHelp=help; - } - const list getMethods()const{ - list ret; - map::const_iterator it; - for(it=mMethods.begin();it!=mMethods.end();++it){ - ret.push_back((*it).second); - } - return ret; - } - const string &getName()const{ - return mName; - } - const string &getHelp()const{ - return mHelp; - } - const list getProperties(){ - list ret; - map::const_iterator it; - for(it=mProperties.begin();it!=mProperties.end();++it){ - ret.push_back((*it).second); - } - return ret; - } - void computeProperties(){ - map::const_iterator it; - Property *prop; - for (it=mMethods.begin();it!=mMethods.end();++it){ - Method *m=(*it).second; - if (m->getPropertyBehaviour()==Method::Read){ - prop=mProperties[m->getPropertyName()]; - if (prop==NULL){ - prop=new Property(Property::ReadOnly,m->getPropertyName(),m->getReturnArg()->getType(), m->getHelp()); - mProperties[m->getPropertyName()]=prop; - } - }else if (m->getPropertyBehaviour()==Method::Write){ - prop=mProperties[m->getPropertyName()]; - if (prop==NULL){ - prop=new Property(Property::ReadWrite,m->getPropertyName(),m->getArgs().front()->getType(), m->getHelp()); - mProperties[m->getPropertyName()]=prop; - }else{ - prop->setHelp(m->getHelp()); - prop->setAttribute(Property::ReadWrite); - } - } - } - } -private: - map mMethods; - map mProperties; - string mName; - string mHelp; -}; - -class Project{ -public: - Project(const string &name="wrapper") : mName(name){ - } - Class *getClass(const std::string &name){ - Class *ret; - if ((ret=mClasses[name])==NULL){ - ret=mClasses[name]=new Class(name); - } - return ret; - } - list getClasses()const{ - list ret; - map::const_iterator it; - for(it=mClasses.begin();it!=mClasses.end();++it){ - ret.push_back((*it).second); - } - return ret; - } - const string &getName()const{ - return mName; - } - void analyse(){ - list classes=getClasses(); - for_each(classes.begin(),classes.end(),mem_fun(&Class::computeProperties)); - } -private: - map mClasses; - string mName; -}; - -class OutputGenerator{ -public: - virtual void generate(Project *proj)=0; -}; - -class CplusplusGenerator : public OutputGenerator{ -public: - CplusplusGenerator(){ - } - virtual void generate(Project *proj){ - list classes=proj->getClasses(); - mCurProj=proj; -#ifndef WIN32 - mkdir(proj->getName().c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH); -#else - _mkdir(proj->getName().c_str()); -#endif - for_each(classes.begin(),classes.end(),bind1st(mem_fun(&CplusplusGenerator::writeClass),this)); - } -private: - void writeClass(Class *klass){ - ostringstream filename; - - if (klass->getType()!=Type::Class) return; - filename<getName()<<"/"<getName()<<".hh"; - mOutfile.open(filename.str().c_str()); - if (!mOutfile.is_open()){ - cerr<<"Could not write into "< &methods=klass->getMethods(); - mCurClass=klass; - mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<"<getName().empty()) - mOutfile<<"namespace "<getName()<<"{"<getName()<<"{"<getName().empty()) - mOutfile<<"} //end of namespace "<getName()<getType(); - - if (type->getBasicType()==Type::Class){ - if (arg->isConst()){ - mOutfile<<"const "; - } - mOutfile<getName(); - if (arg->isPointer()) - mOutfile<<"*"; - }else if (type->getBasicType()==Type::Integer){ - mOutfile<<"int"; - }else if (type->getBasicType()==Type::Enum){ - mOutfile<getName(); - }else if (type->getBasicType()==Type::String){ - if (!isReturn) - mOutfile<<"const std::string &"; - else - mOutfile<<"std::string"; - }else if (type->getBasicType()==Type::Void){ - mOutfile<<"void"; - }else if (type->getBasicType()==Type::Boolean){ - mOutfile<<"bool"; - } - if (!isReturn && !arg->getName().empty()) - mOutfile<<" "<getName(); - } - void writeTabs(int ntabs){ - int i; - for(i=0;i100 && comment[i]==' ')){ - mOutfile<getReturnArg(); - const list &args=method->getArgs(); - list::const_iterator it; - - writeTabs(1); - mOutfile<<"/**"<getHelp(),1); - mOutfile<getName()<<"("; - - for(it=args.begin();it!=args.end();++it){ - if (it!=args.begin()) mOutfile<<", "; - writeArgument(*it); - } - mOutfile<<")"; - if (method->isConst()) mOutfile<<"const"; - mOutfile<<";"< classes=proj->getClasses(); - mCurProj=proj; -#ifndef WIN32 - unlink(proj->getName().c_str()); - mkdir(proj->getName().c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH); -#else - _mkdir(proj->getName().c_str()); -#endif - for_each(classes.begin(),classes.end(),bind1st(mem_fun(&JavascriptGenerator::writeClass),this)); - } -private: - void writeClass(Class *klass){ - ostringstream filename; - - if (klass->getType()!=Type::Class) return; - filename<getName()<<"/"<getName()<<".js"; - mOutfile.open(filename.str().c_str()); - if (!mOutfile.is_open()){ - cerr<<"Could not write into "< &methods=klass->getMethods(); - mCurClass=klass; - mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<getName().empty()) - // mOutfile<<"namespace "<getName()<<"{"<getHelp()<getName()< properties=klass->getProperties(); - for_each(properties.begin(),properties.end(),bind1st(mem_fun(&JavascriptGenerator::writeProperty),this)); - mOutfile<getName().empty()) - // mOutfile<<"} //end of namespace "<getName()<getBasicType()){ - case Type::Float: - case Type::Integer: - mOutfile<<"number"; - break; - case Type::String: - mOutfile<<"string"; - break; - case Type::Boolean: - mOutfile<<"boolean"; - break; - case Type::Class: - case Type::Enum: - mOutfile<<"external:"<getName(); - break; - case Type::Void: - mOutfile<<"void"; - break; - case Type::Callback: - break; - } - } - void writeArgument(Argument *arg, bool isReturn=false){ - if (!isReturn){ - mOutfile<<" * @param {"; - writeType(arg->getType()); - mOutfile<<"} "<getName()<<" - "<getHelp()<getType()); - mOutfile<<"} "<getHelp()<100 && comment[i]==' ')){ - mOutfile<getHelp(),0); - mOutfile<getType()); - mOutfile<<"} external:"<getName()<<"#"<getName()<getAttribute()==Property::ReadOnly) - mOutfile<<" * @readonly"<getReturnArg(); - const list &args=method->getArgs(); - list::const_iterator it; - - if (method->getPropertyBehaviour()!=Method::None) return; - if (method->getName()=="ref" || method->getName()=="unref") return; - - mOutfile<<"/**"<getHelp(),0); - mOutfile<getName()<<"#"<getName()< Type::mTypes; +const char *Type::sBasicTypeNames[]={ + "Void", + "Boolean", + "Integer", + "Float", + "String", + "Enum", + "Class", + "Callback", + "undef", + "undef" +}; diff --git a/tools/software-desc.hh b/tools/software-desc.hh new file mode 100644 index 000000000..bf01ed202 --- /dev/null +++ b/tools/software-desc.hh @@ -0,0 +1,369 @@ +/* +linphone +Copyright (C) 2013 Belledonne Communications SARL +Simon Morlat (simon.morlat@linphone.org) + +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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef software_desc_hh +#define software_desc_hh + +#include +#include +#include +#include + +#include +#include +#include + + +using namespace::std; + + +class Type{ +public: + enum BasicType{ + Void, + Boolean, + Integer, + Float, + String, + Enum, + Class, + Callback + }; + static const char *sBasicTypeNames[]; + static Type* addType(BasicType bt, const string &name){ + Type* ret; + if ((ret=mTypes[name])==0){ + //cout<<"Adding new "<mBasic=bt; + } + return ret; + } + static Type *getType(const std::string &tname){ + if (strstr(tname.c_str(),"char")!=0 && strchr(tname.c_str(),'*')!=0){ + return &sStringType; + }else if (tname.find("int")==0){ + return &sIntegerType; + }else if (tname.find("float")==0){ + return &sFloatType; + }else if (tname.find("bool_t")==0){ + return &sBooleanType; + }else if (tname.find("void")!=string::npos){ + return &sVoidType; + }else if (tname.find("enum")==0){ + return addType(Enum,tname.c_str()+strlen("enum ")); + }else{/*an object?*/ + + string tmp=tname; + size_t pos; + + /*really ugly and slow*/ + + pos=tmp.find('*'); + if (pos!=string::npos) + tmp.erase(pos,1); + + pos=tmp.find("const"); + if (pos!=string::npos) + tmp.erase(pos,strlen("const")); + + while ((pos=tmp.find(' '))!=string::npos){ + tmp.erase(pos,1); + } + return addType(Class,tmp); + } + cerr<<"Unhandled type name"< mTypes; +}; + + + +class Argument{ +public: + Argument(Type *type, const string &argname, bool isConst, bool isPointer) : mType(type), mName(argname), mConst(isConst), mPointer(isPointer){ + if (!isPointer) mConst=false; + } + Type *getType()const{ + return mType; + } + bool isConst()const{ + return mConst; + } + const string &getName()const{ + return mName; + } + bool isPointer()const{ + return mPointer; + } + const string &getHelp()const{ + return mHelp; + } + void setHelp(const string &help){ + mHelp=help; + } +private: + + Type *mType; + string mName; + string mHelp; + bool mConst; + bool mPointer; +}; + +class Method{ +public: + enum PropertyBehaviour{ + None, + Read, + Write + }; + Method(const std::string &uid, Argument* return_arg, const std::string &name, const list &args, bool isConst, bool isStatic){ + mUid=uid; + mReturn=return_arg; + mName=name; + mArgs=args; + mConst=isConst; + mStatic=isStatic; + analyseProperties(); + } + void setHelp(const std::string &help){ + mHelp=help; + } + Argument *getReturnArg()const{ + return mReturn; + } + const string &getName()const{ + return mName; + } + const list &getArgs()const { + return mArgs; + } + bool isConst()const{ + return mConst; + } + bool isStatic()const{ + return mStatic; + } + const string &getHelp(){ + return mHelp; + } + PropertyBehaviour getPropertyBehaviour()const{ + return mPropertyBehaviour; + } + const string &getPropertyName()const{ + return mPropertyName; + } +private: + void analyseProperties(){ + size_t enabled_pos; + mPropertyBehaviour=None; + + if (mName.find("get")==0 && mArgs.size()==0){ + mPropertyName=mName.substr(3,string::npos); + if (!mPropertyName.empty()){ + mPropertyName[0]=tolower(mPropertyName[0]); + mPropertyBehaviour=Read; + } + }else if (mName.find("enable")==0 && mArgs.size()==1){ + mPropertyName=mName.substr(6,string::npos); + if (!mPropertyName.empty()){ + mPropertyName[0]=tolower(mPropertyName[0]); + mPropertyBehaviour=Write; + } + }else if (mName.find("set")==0 && mArgs.size()==1){ + mPropertyName=mName.substr(3,string::npos); + if (!mPropertyName.empty()){ + mPropertyName[0]=tolower(mPropertyName[0]); + mPropertyBehaviour=Write; + } + }else if ((enabled_pos=mName.rfind("Enabled"))!=string::npos && mArgs.size()==0){ + size_t goodpos=mName.size()-7; + if (enabled_pos==goodpos){ + mPropertyName=mName.substr(0,goodpos); + if (!mPropertyName.empty()){ + mPropertyBehaviour=Read; + } + } + } + if (mPropertyBehaviour==None) + mPropertyName=""; + } + string mUid; + Argument *mReturn; + string mName; + list mArgs; + string mHelp; + string mPropertyName; /*if it can be a property*/ + PropertyBehaviour mPropertyBehaviour; + bool mConst; + bool mStatic; +}; + +class Property{ +public: + enum Attribute{ + ReadOnly, + ReadWrite + }; + Property(Attribute attr, const string &name, Type *type, const string &help) : mAttr(attr), mName(name), mType(type), mHelp(help){ + } + const string &getName()const{ + return mName; + } + const string &getHelp()const{ + return mHelp; + } + void setHelp(const string &help){ + mHelp=help; + } + Attribute getAttribute()const{ + return mAttr; + } + void setAttribute(Attribute attr){ + mAttr=attr; + } + Type* getType()const{ + return mType; + } +private: + Attribute mAttr; + string mName; + Type *mType; + string mHelp; +}; + +/*actually a class or an enum*/ +class Class{ +public: + Class(const std::string &name): mName(name){ + } + Type::BasicType getType(){ + return Type::getType(mName)->getBasicType(); + } + void addMethod(Method *method){ + if (mMethods.find(method->getName())==mMethods.end()) + mMethods.insert(make_pair(method->getName(),method)); + } + void setHelp(const std::string &help){ + mHelp=help; + } + const list getMethods()const{ + list ret; + map::const_iterator it; + for(it=mMethods.begin();it!=mMethods.end();++it){ + ret.push_back((*it).second); + } + return ret; + } + const string &getName()const{ + return mName; + } + const string &getHelp()const{ + return mHelp; + } + const list getProperties(){ + list ret; + map::const_iterator it; + for(it=mProperties.begin();it!=mProperties.end();++it){ + ret.push_back((*it).second); + } + return ret; + } + void computeProperties(){ + map::const_iterator it; + Property *prop; + for (it=mMethods.begin();it!=mMethods.end();++it){ + Method *m=(*it).second; + if (m->getPropertyBehaviour()==Method::Read){ + prop=mProperties[m->getPropertyName()]; + if (prop==NULL){ + prop=new Property(Property::ReadOnly,m->getPropertyName(),m->getReturnArg()->getType(), m->getHelp()); + mProperties[m->getPropertyName()]=prop; + } + }else if (m->getPropertyBehaviour()==Method::Write){ + prop=mProperties[m->getPropertyName()]; + if (prop==NULL){ + prop=new Property(Property::ReadWrite,m->getPropertyName(),m->getArgs().front()->getType(), m->getHelp()); + mProperties[m->getPropertyName()]=prop; + }else{ + prop->setHelp(m->getHelp()); + prop->setAttribute(Property::ReadWrite); + } + } + } + } +private: + map mMethods; + map mProperties; + string mName; + string mHelp; +}; + +class Project{ +public: + Project(const string &name="wrapper") : mName(name){ + } + Class *getClass(const std::string &name){ + Class *ret; + if ((ret=mClasses[name])==NULL){ + ret=mClasses[name]=new Class(name); + } + return ret; + } + list getClasses()const{ + list ret; + map::const_iterator it; + for(it=mClasses.begin();it!=mClasses.end();++it){ + ret.push_back((*it).second); + } + return ret; + } + const string &getName()const{ + return mName; + } + void analyse(){ + list classes=getClasses(); + for_each(classes.begin(),classes.end(),mem_fun(&Class::computeProperties)); + } +private: + map mClasses; + string mName; +}; + +#endif