From e990ea0cef935f9a0ea7d8615e8d8b5a23147255 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 20 Sep 2013 10:08:16 +0200 Subject: [PATCH 1/7] wrapper generator in progress --- COPYING | 12 +- coreapi/address.c | 10 +- coreapi/help/Doxyfile.in | 2 +- coreapi/linphonecall.c | 21 +- coreapi/linphonecore.h | 22 +- mediastreamer2 | 2 +- tools/Makefile.am | 2 +- tools/genwrappers.cc | 615 ++++++++++++++++++++++++++++++++++++--- 8 files changed, 612 insertions(+), 74 deletions(-) diff --git a/COPYING b/COPYING index d60c31a97..b18ab0474 100644 --- a/COPYING +++ b/COPYING @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -278,7 +278,7 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS - + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest diff --git a/coreapi/address.c b/coreapi/address.c index 7f1971abe..15f3a4062 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -171,13 +171,15 @@ void linphone_address_destroy(LinphoneAddress *u){ sal_address_unref(u); } +/** + * Get port number as an integer value. + */ +/** + * Get port number, 0 if not present. + */ int linphone_address_get_port(const LinphoneAddress *u) { -#ifdef USE_BELLESIP return sal_address_get_port(u); -#else - return sal_address_get_port_int(u); -#endif } /** @} */ diff --git a/coreapi/help/Doxyfile.in b/coreapi/help/Doxyfile.in index dce1804b2..27068c53d 100644 --- a/coreapi/help/Doxyfile.in +++ b/coreapi/help/Doxyfile.in @@ -190,7 +190,7 @@ EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = . INCLUDE_FILE_PATTERNS = *.h -PREDEFINED = DOXYGEN +PREDEFINED = DOXYGEN MS2_PUBLIC= LINPHONE_PUBLIC= EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 335e49dc7..cf6233546 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1203,16 +1203,31 @@ void _linphone_call_params_copy(LinphoneCallParams *ncp, const LinphoneCallParam if (cp->custom_headers) ncp->custom_headers=sal_custom_header_clone(cp->custom_headers); } +/** + * @ingroup call_control + * Set requested level of privacy for the call. + * \xmlonly javascript \endxmlonly + * @param params the call parameters to be modified + * @param LinphonePrivacy to configure privacy + * */ void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy) { params->privacy=privacy; } + +/** + * @ingroup call_control + * Get requested level of privacy for the call. + * @param params the call parameters + * @return Privacy mode + * */ LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params) { return params->privacy; } - - - +/** + * @ingroup call_control + * @return string value of LinphonePrivacy enum + **/ const char* linphone_privacy_to_string(LinphonePrivacy privacy) { switch(privacy) { case LinphonePrivacyDefault: return "LinphonePrivacyDefault"; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 57bab7181..a7d8cc793 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -182,9 +182,6 @@ const char *linphone_address_get_scheme(const LinphoneAddress *u); LINPHONE_PUBLIC const char *linphone_address_get_display_name(const LinphoneAddress* u); LINPHONE_PUBLIC const char *linphone_address_get_username(const LinphoneAddress *u); LINPHONE_PUBLIC const char *linphone_address_get_domain(const LinphoneAddress *u); -/** - * Get port number as an integer value, -1 if not set. - */ LINPHONE_PUBLIC int linphone_address_get_port(const LinphoneAddress *u); LINPHONE_PUBLIC void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name); LINPHONE_PUBLIC void linphone_address_set_username(LinphoneAddress *uri, const char *username); @@ -371,24 +368,9 @@ typedef enum _LinphonePrivacy { * */ typedef unsigned int LinphonePrivacyMask; -/** - * @ingroup call_control - * @return string value of LinphonePrivacy enum - * */ -const char* linphone_privacy_to_string(LinphonePrivacy privacy); -/** - * @ingroup call_control - * Set requested level of privacy for the call. - * @param params the call parameters to be modified - * @param LinphonePrivacy to configure privacy - * */ + +LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); LINPHONE_PUBLIC void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy); -/** - * @ingroup call_control - * Get requested level of privacy for the call. - * @param params the call parameters - * @return Privacy mode - * */ LINPHONE_PUBLIC LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params); diff --git a/mediastreamer2 b/mediastreamer2 index ac5233ae1..56128aa7e 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ac5233ae16394d59cf4d9783a229f2adc2111b12 +Subproject commit 56128aa7e5e613708cd8a35beb5d2643dc4dae67 diff --git a/tools/Makefile.am b/tools/Makefile.am index 9f8233a80..169fda781 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -12,7 +12,7 @@ COMMON_CFLAGS=\ $(STRICT_OPTIONS) \ $(LIBXML2_CFLAGS) -AM_CXXFLAGS=$(LIBXML2_CFLAGS) +AM_CXXFLAGS=$(LIBXML2_CFLAGS) $(STRICT_OPTIONS) EXTRA_DIST=xml2lpc_jni.cc lpc2xml_jni.cc diff --git a/tools/genwrappers.cc b/tools/genwrappers.cc index c506f6f71..3508937db 100644 --- a/tools/genwrappers.cc +++ b/tools/genwrappers.cc @@ -23,9 +23,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#include +#include #include #include +#include +#include +#include using namespace::std; @@ -33,19 +38,41 @@ using namespace::std; class Type{ public: enum BasicType{ + Void, + Boolean, Integer, + Float, String, - Klass + Enum, + Class }; + static Type* addType(BasicType bt, const string &name){ + Type* ret; + if ((ret=mTypes[name])==0){ + cout<<"Adding new "<<(bt==Enum ? "enum" : "class")<<" type '"<mBasic=Enum; + } + 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 (strcmp(tname.c_str(),"int")==0){ + }else if (tname.find("int")==0){ return &sIntegerType; - }else{ - Type* ret; + }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; - ssize_t pos; + size_t pos; /*really ugly and slow*/ @@ -60,19 +87,17 @@ public: while ((pos=tmp.find(' '))!=string::npos){ tmp.erase(pos,1); } - - if ((ret=mTypes[tmp])==0){ - cout<<"Adding new class type '"< 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; class Argument{ public: - Argument(Type *type, const string &argname, bool isConst) : mType(type), mName(argname), mConst(isConst){ + 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; + } private: - bool mConst; + Type *mType; string mName; string mHelp; + bool mConst; + bool mPointer; }; class Method{ public: - Method(const std::string &uid, Argument* return_arg, const std::string &name, const list &args){ + 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){ - mMethods.push_back(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: - list mMethods; + 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){ @@ -145,8 +347,280 @@ public: } 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 + 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()<<"{"<getName()<getHelp()< 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; + } + } + 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(),1); + mOutfile<getName()<<"#"<getName()<getBasicType()<<" "<getName()< args; + string help; for (cur_node = node->children; cur_node != NULL ; cur_node = cur_node->next){ if (strcmp((const char*)cur_node->name,"name")==0){ @@ -265,19 +754,42 @@ static void parseFunction(Project *proj, xmlNode *node){ name=(const char*)content; xmlFree(content); }else if (strcmp((const char*)cur_node->name,"param")==0){ - if (first_arg==NULL){ - first_arg=parseArgument(cur_node); - } + Argument *a=parseArgument(cur_node,false); + if (a) args.push_back(a); + else return; + }else if (strcmp((const char*)cur_node->name,"detaileddescription")==0){ + help=findChildContent(cur_node,"para"); } } + retarg=parseArgument(node,true); + if (!retarg){ + cerr<<"Could not parse return argument of function "<getType()->getBasicType()!=Type::Class) return; className=first_arg->getType()->getName(); methodName=extractMethodName(name,className); - if (!methodName.empty()){ + if (!methodName.empty() && methodName!="destroy"){ cout<<"Found "<isConst(),false); + method->setHelp(help); + proj->getClass(className)->addMethod(method); + delete first_arg; + } +} + +static void parseTypedef(Project *proj, xmlNode *node){ + string typecontent=findChildContent(node,"type"); + string name=findChildContent(node,"name"); + if (typecontent.find("enum")==0){ + Type::addType(Type::Enum,name); } } @@ -293,9 +805,13 @@ static void parseMemberDef(Project *proj, xmlNode *node){ return; kind=xmlGetProp(node,(const xmlChar*)"kind"); - //cout<<"Kind="<<(const char*)kind< files; + list::iterator it; LIBXML_TEST_VERSION for(i=1;ianalyse(); + gen->generate(proj); return 0; -} \ No newline at end of file +} From e8a786380d57a5302dc795ab2a82c30678727abe Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 20 Sep 2013 16:04:35 +0200 Subject: [PATCH 2/7] genwrappers works quite well --- coreapi/linphonecore.h | 36 +++---- tools/genwrappers.cc | 220 ++++++++++++++++++++++++++++------------- 2 files changed, 168 insertions(+), 88 deletions(-) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index a7d8cc793..fcf04e2c7 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -957,9 +957,9 @@ typedef void (*NotifyPresenceReceivedCb)(struct _LinphoneCore *lc, LinphoneFrien * */ typedef void (*NewSubscribtionRequestCb)(struct _LinphoneCore *lc, LinphoneFriend *lf, const char *url); /** Callback prototype */ -typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, const char *username); +typedef void (*AuthInfoRequestedCb)(struct _LinphoneCore *lc, const char *realm, const char *username); /** Callback prototype */ -typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl); +typedef void (*CallLogUpdatedCb)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl); /** * Callback prototype * @deprecated use #MessageReceived instead. @@ -969,7 +969,7 @@ typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog * @param from #LinphoneAddress from * @param message incoming message * */ -typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message); +typedef void (*TextMessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message); /** * Chat message callback prototype * @@ -977,18 +977,18 @@ typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, co * @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room. * @param LinphoneChatMessage incoming message * */ -typedef void (*MessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message); +typedef void (*MessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message); /** Callback prototype */ -typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf); +typedef void (*DtmfReceivedCb)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf); /** Callback prototype */ -typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to); +typedef void (*ReferReceivedCb)(struct _LinphoneCore *lc, const char *refer_to); /** Callback prototype */ -typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf); +typedef void (*BuddyInfoUpdatedCb)(struct _LinphoneCore *lc, LinphoneFriend *lf); /** Callback prototype for in progress transfers. The new_call_state is the state of the call resulting of the transfer, at the other party. */ -typedef void (*LinphoneTransferStateChanged)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state); +typedef void (*LinphoneTransferStateChangedCb)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state); /** Callback prototype for receiving quality statistics for calls*/ -typedef void (*CallStatsUpdated)(struct _LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats); +typedef void (*CallStatsUpdatedCb)(struct _LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats); /** Callback prototype for receiving info messages*/ typedef void (*LinphoneInfoReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg); @@ -1002,15 +1002,15 @@ typedef struct _LinphoneVTable{ LinphoneCallStateCb call_state_changed;/** A text message has been received */ + TextMessageReceivedCb text_received; /** @deprecated, use #message_received instead
A text message has been received */ } LinphoneCoreVTable; /** diff --git a/tools/genwrappers.cc b/tools/genwrappers.cc index 3508937db..55a30e396 100644 --- a/tools/genwrappers.cc +++ b/tools/genwrappers.cc @@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include + using namespace::std; @@ -44,15 +45,17 @@ public: Float, String, Enum, - Class + Class, + Callback }; + static const char *sBasicTypeNames[]; static Type* addType(BasicType bt, const string &name){ Type* ret; if ((ret=mTypes[name])==0){ - cout<<"Adding new "<<(bt==Enum ? "enum" : "class")<<" type '"<mBasic=Enum; + }else if (bt!=Class){ + ret->mBasic=bt; } return ret; } @@ -117,6 +120,19 @@ 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: @@ -138,6 +154,9 @@ public: const string &getHelp()const{ return mHelp; } + void setHelp(const string &help){ + mHelp=help; + } private: Type *mType; @@ -499,6 +518,7 @@ public: list 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()); @@ -524,8 +544,8 @@ private: //if (!mCurProj->getName().empty()) // mOutfile<<"namespace "<getName()<<"{"<getName()<getHelp()<getName()< properties=klass->getProperties(); @@ -556,6 +576,8 @@ private: case Type::Void: mOutfile<<"void"; break; + case Type::Callback: + break; } } void writeArgument(Argument *arg, bool isReturn=false){ @@ -607,7 +629,7 @@ private: if (method->getName()=="ref" || method->getName()=="unref") return; mOutfile<<"/**"<getHelp(),1); + writeHelpComment(method->getHelp(),0); mOutfile<getName()<<"#"<getName()<children; cur_node != NULL ; cur_node = cur_node->next){ - if (strcmp((const char*)cur_node->name,(const char*)element_name)==0){ - return cur_node; - } - } - return NULL; -} - static bool isSpace(const char *str){ for(;*str!='\0';++str){ if (!isspace(*str)) return false; @@ -641,35 +652,78 @@ static bool isSpace(const char *str){ return true; } -static string findChildContent(xmlNode *a_node, const char *element_name){ - xmlNode *node=findChild(a_node,element_name); - string res; - if (node) { - xmlChar *text=xmlNodeGetContent(node); - if (!isSpace((const char*)text)) - res=(char*)text; - xmlFree(text); +class XmlNode{ +public: + XmlNode(const xmlNode *node=NULL) : mNode(node){ } - return res; -} + XmlNode getChild(const string &name)const{ + if (mNode==NULL) return XmlNode(); + xmlNode *it; + for(it=mNode->children;it!=NULL;it=it->next){ + if (xmlStrcmp(it->name,(const xmlChar*)name.c_str())==0) + return XmlNode(it); + } + return XmlNode(); + } + XmlNode getChildRecursive(const string &name)const{ + if (mNode==NULL) return XmlNode(); + xmlNode *it; + //find in direct children + for(it=mNode->children;it!=NULL;it=it->next){ + if (xmlStrcmp(it->name,(const xmlChar*)name.c_str())==0) + return XmlNode(it); + } + //recurse into children + for(it=mNode->children;it!=NULL;it=it->next){ + XmlNode res=XmlNode(it).getChildRecursive(name); + if (!res.isNull()) return res; + } + return XmlNode(); + } + list getChildren(const string &name)const{ + xmlNode *it; + list nodes; + + if (mNode==NULL) return nodes; + for(it=mNode->children;it!=NULL;it=it->next){ + if (xmlStrcmp(it->name,(const xmlChar*)name.c_str())==0) + nodes.push_back(XmlNode(it)); + } + if (nodes.empty()) cerr<<"getChildren() no "<content; + if (!isSpace(text)) return string(text); + } + return ""; + } + string getProp(const string &propname)const{ + if (mNode==NULL) return ""; + xmlChar *value; + value=xmlGetProp((xmlNode*)mNode,(const xmlChar*)propname.c_str()); + if (value) return string((const char*)value); + return ""; + } + bool isNull()const{ + return mNode==NULL; + } +private: + const xmlNode *mNode; +}; -#define nullOrEmpty(p) (p==NULL || *p=='\0') - -static Argument *parseArgument(xmlNode *node, bool isReturn){ - string name=findChildContent(node,"declname"); +static Argument *parseArgument(XmlNode node, bool isReturn){ + string name=node.getChild("declname").getText(); Type *type=NULL; - xmlNode *typenode=findChild(node,"type"); - string typecontent=findChildContent(node,"type"); + string typecontent=node.getChild("type").getText(); bool isConst=false; bool isPointer=false; - if (!typenode) { - cout<<"Cannot find type from node."<getBasicType()<<" "<getName()<getBasicType()<<" "<getName()< args; string help; + XmlNode funcnode(node); + XmlNode parameterlist; + list params; + list paramsHelp; + list::iterator it,helpit; - for (cur_node = node->children; cur_node != NULL ; cur_node = cur_node->next){ - if (strcmp((const char*)cur_node->name,"name")==0){ - xmlChar *content=xmlNodeGetContent(cur_node); - name=(const char*)content; - xmlFree(content); - }else if (strcmp((const char*)cur_node->name,"param")==0){ - Argument *a=parseArgument(cur_node,false); - if (a) args.push_back(a); - else return; - }else if (strcmp((const char*)cur_node->name,"detaileddescription")==0){ - help=findChildContent(cur_node,"para"); + name=funcnode.getChild("name").getText(); + params=funcnode.getChildren("param"); + parameterlist=funcnode.getChild("detaileddescription").getChildRecursive("parameterlist"); + if (parameterlist.isNull()) cerr<<"parameterlist not found"<setHelp(item.getChild("parameterdescription").getChild("para").getText()); + }else cerr<<"Undocumented parameter "<getName()<<" in function "<getType()->getName(); methodName=extractMethodName(name,className); if (!methodName.empty() && methodName!="destroy"){ - cout<<"Found "<isConst(),false); method->setHelp(help); @@ -786,32 +865,33 @@ static void parseFunction(Project *proj, xmlNode *node){ } static void parseTypedef(Project *proj, xmlNode *node){ - string typecontent=findChildContent(node,"type"); - string name=findChildContent(node,"name"); + XmlNode tdef(node); + string typecontent=tdef.getChild("type").getText(); + string name=tdef.getChild("name").getText(); if (typecontent.find("enum")==0){ Type::addType(Type::Enum,name); - } + }else if (typecontent.find("void(*")==0){ + // callbacks function, not really well parsed by doxygen + Type::addType(Type::Callback,name); + }else + proj->getClass(name)->setHelp(getHelpBody(node)); } static void parseMemberDef(Project *proj, xmlNode *node){ + XmlNode member(node); string brief; string detailed; - const xmlChar *kind; + string kind; - brief=findChildContent(node,"briefdescription"); - detailed=findChildContent(node,"detaileddescription"); - - if (brief.empty() && detailed.empty()) + if (member.getChild("briefdescription").getText().empty() && + member.getChild("detaileddescription").getChild("para").getText().empty()) return; - kind=xmlGetProp(node,(const xmlChar*)"kind"); - if (kind){ - //cout<<"Kind="<<(const char*)kind< Date: Fri, 20 Sep 2013 17:40:27 +0200 Subject: [PATCH 3/7] fix issue with window id management --- coreapi/linphonecore.c | 61 ++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index eb6993b95..5dfbd37a9 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4891,26 +4891,33 @@ float linphone_core_get_static_picture_fps(LinphoneCore *lc) { * @ingroup media_parameters **/ unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc){ + if (lc->video_window_id) { + /* case where the video id was previously set by the app*/ + return lc->video_window_id; + }else{ #ifdef VIDEO_ENABLED - LinphoneCall *call=linphone_core_get_current_call (lc); - if (call && call->videostream) - return video_stream_get_native_window_id(call->videostream); - if (lc->previewstream) - return video_stream_get_native_window_id(lc->previewstream); + /*case where it was not set but we want to get the one automatically created by mediastreamer2 (desktop versions only)*/ + LinphoneCall *call=linphone_core_get_current_call (lc); + if (call && call->videostream) + return video_stream_get_native_window_id(call->videostream); #endif - return lc->video_window_id; + } + return 0; } -/**@ingroup media_parameters +/** + * @ingroup media_parameters * Set the native video window id where the video is to be displayed. * If not set the core will create its own window. **/ void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id){ -#ifdef VIDEO_ENABLED - LinphoneCall *call=linphone_core_get_current_call(lc); lc->video_window_id=id; - if (call!=NULL && call->videostream){ - video_stream_set_native_window_id(call->videostream,id); +#ifdef VIDEO_ENABLED + { + LinphoneCall *call=linphone_core_get_current_call(lc); + if (call!=NULL && call->videostream){ + video_stream_set_native_window_id(call->videostream,id); + } } #endif } @@ -4921,14 +4928,20 @@ void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id * @ingroup media_parameters **/ unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc){ + if (lc->preview_window_id){ + /*case where the id was set by the app previously*/ + return lc->preview_window_id; + }else{ + /*case where we want the id automatically created by mediastreamer2 (desktop versions only)*/ #ifdef VIDEO_ENABLED - LinphoneCall *call=linphone_core_get_current_call (lc); - if (call && call->videostream) - return video_stream_get_native_preview_window_id(call->videostream); - if (lc->previewstream) - return video_preview_get_native_window_id(lc->previewstream); + LinphoneCall *call=linphone_core_get_current_call(lc); + if (call && call->videostream) + return video_stream_get_native_preview_window_id(call->videostream); + if (lc->previewstream) + return video_preview_get_native_window_id(lc->previewstream); #endif - return lc->preview_window_id; + } + return 0; } /** @@ -4938,13 +4951,15 @@ unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc) * If not set the core will create its own window. **/ void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long id){ -#ifdef VIDEO_ENABLED - LinphoneCall *call=linphone_core_get_current_call(lc); lc->preview_window_id=id; - if (call!=NULL && call->videostream){ - video_stream_set_native_preview_window_id(call->videostream,id); - }else if (lc->previewstream){ - video_preview_set_native_window_id(lc->previewstream,id); +#ifdef VIDEO_ENABLED + { + LinphoneCall *call=linphone_core_get_current_call(lc); + if (call!=NULL && call->videostream){ + video_stream_set_native_preview_window_id(call->videostream,id); + }else if (lc->previewstream){ + video_preview_set_native_window_id(lc->previewstream,id); + } } #endif } From 2fd37f338d8c2ef1ce34446c2aadabdf524ef707 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 20 Sep 2013 17:50:38 +0200 Subject: [PATCH 4/7] RTCP fix --- coreapi/linphonecall.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index cf6233546..3135ea09a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1684,7 +1684,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna stream->rtp_addr[0]!='\0' ? stream->rtp_addr : call->resultdesc->addr, stream->rtp_port, stream->rtcp_addr[0]!='\0' ? stream->rtcp_addr : call->resultdesc->addr, - linphone_core_rtcp_enabled(lc) ? (stream->rtcp_port) : 0, + linphone_core_rtcp_enabled(lc) ? (stream->rtcp_port ? stream->rtcp_port : stream->rtp_port+1) : 0, used_pt, linphone_core_get_audio_jittcomp(lc), playfile, @@ -1806,7 +1806,8 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna video_stream_set_device_rotation(call->videostream, lc->device_rotation); video_stream_start(call->videostream, call->video_profile, rtp_addr, vstream->rtp_port, - rtcp_addr, linphone_core_rtcp_enabled(lc) ? (vstream->rtcp_port) : 0, + rtcp_addr, + linphone_core_rtcp_enabled(lc) ? (vstream->rtcp_port ? vstream->rtcp_port : vstream->rtp_port+1) : 0, used_pt, linphone_core_get_video_jittcomp(lc), cam); video_stream_set_rtcp_information(call->videostream, cname,rtcp_tool); } From f8ead1facbda0de1b03eb29031f9d13e0f7d569c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 23 Sep 2013 15:25:23 +0200 Subject: [PATCH 5/7] fixes around opengl display for androdi --- coreapi/linphonecore.c | 32 ++++++++++++++++++++++++++++++-- coreapi/linphonecore_jni.cc | 8 ++++++-- mediastreamer2 | 2 +- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 5dfbd37a9..308e6b425 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4905,12 +4905,37 @@ unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc){ return 0; } +/* unsets the video id for all calls (indeed it may be kept by filters or videostream object itself by paused calls)*/ +static void unset_video_window_id(LinphoneCore *lc, bool_t preview, unsigned long id){ + LinphoneCall *call; + MSList *elem; + + if (id!=0 && id!=-1) { + ms_error("Invalid use of unset_video_window_id()"); + return; + } +#ifdef VIDEO_ENABLED + for(elem=lc->calls;elem!=NULL;elem=elem->next){ + call=(LinphoneCall *) elem->data; + if (call->videostream){ + if (preview) + video_stream_set_native_preview_window_id(call->videostream,id); + else + video_stream_set_native_window_id(call->videostream,id); + } + } +#endif +} + /** * @ingroup media_parameters * Set the native video window id where the video is to be displayed. - * If not set the core will create its own window. + * For MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given. **/ void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id){ + if (id==0 || id==(unsigned long)-1){ + unset_video_window_id(lc,FALSE,id); + } lc->video_window_id=id; #ifdef VIDEO_ENABLED { @@ -4948,9 +4973,12 @@ unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc) * @ingroup media_parameters * Set the native window id where the preview video (local camera) is to be displayed. * This has to be used in conjonction with linphone_core_use_preview_window(). - * If not set the core will create its own window. + * MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given. **/ void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long id){ + if (id==0 || id==(unsigned long)-1){ + unset_video_window_id(lc,TRUE,id); + } lc->preview_window_id=id; #ifdef VIDEO_ENABLED { diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index b243d25d9..d647b94c1 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -2379,9 +2379,11 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* jobject oldWindow = (jobject) linphone_core_get_native_video_window_id((LinphoneCore*)lc); if (obj != NULL) { obj = env->NewGlobalRef(obj); - } + ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): NewGlobalRef(%p)",obj); + }else ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): setting to NULL"); linphone_core_set_native_video_window_id((LinphoneCore*)lc,(unsigned long)obj); if (oldWindow != NULL) { + ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): DeleteGlobalRef(%p)",oldWindow); env->DeleteGlobalRef(oldWindow); } } @@ -2393,9 +2395,11 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(JNIEn jobject oldWindow = (jobject) linphone_core_get_native_preview_window_id((LinphoneCore*)lc); if (obj != NULL) { obj = env->NewGlobalRef(obj); - } + ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): NewGlobalRef(%p)",obj); + }else ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): setting to NULL"); linphone_core_set_native_preview_window_id((LinphoneCore*)lc,(unsigned long)obj); if (oldWindow != NULL) { + ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): DeleteGlobalRef(%p)",oldWindow); env->DeleteGlobalRef(oldWindow); } } diff --git a/mediastreamer2 b/mediastreamer2 index 56128aa7e..def761ec9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 56128aa7e5e613708cd8a35beb5d2643dc4dae67 +Subproject commit def761ec9d8bdbeee5dd7d1ba343675bfc999989 From c6a96174d0fd12c9364412ffbad81c43efc3641e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 23 Sep 2013 17:14:25 +0200 Subject: [PATCH 6/7] split genwrappers into several smaller pieces --- oRTP | 2 +- tools/Makefile.am | 4 +- tools/generator.cc | 284 +++++++++++++++++++ tools/generator.hh | 66 +++++ tools/genwrappers.cc | 622 +---------------------------------------- tools/software-desc.cc | 40 +++ tools/software-desc.hh | 369 ++++++++++++++++++++++++ 7 files changed, 767 insertions(+), 620 deletions(-) create mode 100644 tools/generator.cc create mode 100644 tools/generator.hh create mode 100644 tools/software-desc.cc create mode 100644 tools/software-desc.hh 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 From e2e4e5918f5c2e757c54ca9edaff2c35c737db82 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 24 Sep 2013 11:36:24 +0200 Subject: [PATCH 7/7] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index def761ec9..214f82f89 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit def761ec9d8bdbeee5dd7d1ba343675bfc999989 +Subproject commit 214f82f8942f9d1c419f038dbd33b36b65e2a1e6