Commit e8cb0756 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Remove useless files.

parent fca153ee
/*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <sstream>
#include "generator.hh"
#ifdef _WIN32
#include <direct.h>
#define strncasecmp _strnicmp
#endif
string to_lower(const string &str){
string res=str;
for(string::iterator it=res.begin();it!=res.end();++it){
*it=tolower(*it);
}
return res;
}
CplusplusGenerator::CplusplusGenerator(){
}
void CplusplusGenerator::generate(Project *proj){
list<Class*> 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::writeEnumMember(ConstField *cf, bool isLast){
writeTabs(1);
mOutfile<<cf->getName()<<"="<<cf->getValue();
if (!isLast) mOutfile<<",";
if (!cf->getHelp().empty()) mOutfile<<"\t/**< "<<cf->getHelp()<<" */";
mOutfile<<endl;
}
void CplusplusGenerator::writeClass(Class *klass){
ostringstream filename;
filename<<mCurProj->getName()<<"/"<<klass->getName()<<".hh";
mOutfile.open(filename.str().c_str());
if (!mOutfile.is_open()){
cerr<<"Could not write into "<<filename.str()<<endl;
return;
}
list<Method*> methods=klass->getMethods();
list<ConstField*> constFields=klass->getConstFields();
mCurClass=klass;
mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<<endl;
mOutfile<<endl;
mOutfile<<"#include <string>"<<endl;
mOutfile<<endl;
if (!mCurProj->getName().empty())
mOutfile<<"namespace "<<mCurProj->getName()<<"{"<<endl<<endl;
if (klass->getType()==Type::Enum){
mOutfile<<"enum "<<klass->getName()<<"{"<<endl;
list<ConstField*>::iterator cfit,next;
for (cfit=constFields.begin();cfit!=constFields.end();){
ConstField *cf=*cfit;
writeEnumMember(cf,++cfit==constFields.end());
}
}else{
mOutfile<<"class "<<klass->getName()<<"{"<<endl;
mOutfile<<"public:"<<endl;
for_each(methods.begin(),methods.end(),bind1st(mem_fun(&CplusplusGenerator::writeMethod),this));
}
mOutfile<<"};"<<endl<<endl;
if (!mCurProj->getName().empty())
mOutfile<<"} //end of namespace "<<mCurProj->getName()<<endl;
mOutfile<<endl;
mOutfile.close();
}
void CplusplusGenerator::writeArgument(Argument *arg, bool isReturn){
Type *type=arg->getType();
if (type->getBasicType()==Type::Class){
if (arg->isConst()){
mOutfile<<"const ";
}
mOutfile<<type->getName();
if (arg->isPointer())
mOutfile<<"*";
}else if (type->getBasicType()==Type::Integer){
mOutfile<<"int";
}else if (type->getBasicType()==Type::Enum){
mOutfile<<type->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<<" "<<arg->getName();
}
void CplusplusGenerator::writeTabs(int ntabs){
int i;
for(i=0;i<ntabs;++i)
mOutfile<<"\t";
}
void CplusplusGenerator::writeHelpComment(const std::string &comment, int ntabs){
size_t i;
int curindex=0;
writeTabs(ntabs);
mOutfile<<" * ";
for(i=0;i<comment.size();i++,curindex++){
if (comment[i]=='\n' || (curindex>100 && comment[i]==' ')){
mOutfile<<endl;
writeTabs(ntabs);
mOutfile<<" * ";
curindex=0;
}else mOutfile<<comment[i];
}
}
void CplusplusGenerator::writeMethod(Method *method){
if (method->isCallback()) return;
Argument *retarg=method->getReturnArg();
const list<Argument*> &args=method->getArgs();
list<Argument*>::const_iterator it;
writeTabs(1);
mOutfile<<"/**"<<endl;
writeHelpComment(method->getHelp(),1);
mOutfile<<endl;
writeTabs(1);
mOutfile<<"**/"<<endl;
writeTabs(1);
writeArgument(retarg,true);
mOutfile<<" "<<method->getName()<<"(";
for(it=args.begin();it!=args.end();++it){
if (it!=args.begin()) mOutfile<<", ";
writeArgument(*it);
}
mOutfile<<")";
if (method->isConst()) mOutfile<<"const";
mOutfile<<";"<<endl;
mOutfile<<endl;
}
JavascriptGenerator::JavascriptGenerator(){
}
void JavascriptGenerator::generate(Project *proj){
list<Class*> classes=proj->getClasses();
mCurProj=proj;
#ifndef _WIN32
remove(to_lower(proj->getName()).c_str());
mkdir(to_lower(proj->getName()).c_str(),S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IROTH);
#else
_mkdir(to_lower(proj->getName()).c_str());
#endif
ostringstream filename;
/*write a file for the namespace*/
filename<<to_lower(mCurProj->getName())<<"/"<<to_lower(mCurProj->getName())<<".js";
mOutfile.open(filename.str().c_str());
if (!mOutfile.is_open()){
cerr<<"Could not write into "<<filename.str()<<endl;
return;
}
mOutfile<<"/**"<<endl;
mOutfile<<" * Namespace for non-external variables and objects."<<endl;
mOutfile<<" * @namespace "<<mCurProj->getName()<<endl;
mOutfile<<"**/"<<endl;
mOutfile<<"var "<<proj->getName()<<" = {};"<<endl;
mOutfile.close();
for_each(classes.begin(),classes.end(),bind1st(mem_fun(&JavascriptGenerator::writeEnum),this));
for_each(classes.begin(),classes.end(),bind1st(mem_fun(&JavascriptGenerator::writeClass),this));
}
string JavascriptGenerator::getEnumName(Class *klass){
string enum_name=klass->getName();
if (strncasecmp(enum_name.c_str(),mCurProj->getName().c_str(),mCurProj->getName().size())==0){
//since enum is part of the namespace, drop the namespace part of the enum if any.
enum_name.erase(0,mCurProj->getName().size());
}
return enum_name;
}
void JavascriptGenerator::writeEnum(Class *klass){
if (klass->getType()!=Type::Enum) return;
ostringstream filename;
list<ConstField*> members=klass->getConstFields();
list<ConstField*>::iterator it;
string enum_name=getEnumName(klass);
filename<<to_lower(mCurProj->getName())<<"/"<<to_lower(enum_name)<<".js";
mOutfile.open(filename.str().c_str());
if (!mOutfile.is_open()){
cerr<<"Could not write into "<<filename.str()<<endl;
return;
}
mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<<endl<<endl;
mOutfile<<"var "<<mCurProj->getName()<<" = "<<mCurProj->getName()<<" || {};"<<endl;
mOutfile<<"/**"<<endl;
writeHelpComment(klass->getHelp(),0);
mOutfile<<endl;
mOutfile<<" * "<<"@readonly"<<endl;
mOutfile<<" * "<<"@enum {number}"<<endl;
mOutfile<<"**/"<<endl;
mOutfile<<mCurProj->getName()<<"."<<enum_name<<" = {"<<endl;
string prefix=ConstField::getCommonPrefix(members);
size_t prefix_size=prefix.size();
for(it=members.begin();it!=members.end();){
ConstField *cf=(*it);
if (!cf->getHelp().empty()){
writeTabs(1);
mOutfile<<"/**"<<endl;
writeHelpComment(cf->getHelp(),1);
mOutfile<<endl;
writeTabs(1);
mOutfile<<"*/"<<endl;
}
writeTabs(1);
mOutfile<<cf->getName().substr(prefix_size,string::npos)<<" : "<<cf->getValue();
if (++it!=members.end()) mOutfile<<",";
mOutfile<<endl;
}
mOutfile<<"};"<<endl;
mOutfile << "/**" << endl;
mOutfile << " * Get the name of a value of the " << enum_name << " enum as a string." << endl;
mOutfile << " * @function linphone#get" << enum_name << "Text" << endl;
mOutfile << " * @param { number } value - One of the values of the " << enum_name << " enum." << endl;
mOutfile << "**/" << endl;
mOutfile << mCurProj->getName() << ".get" << enum_name << "Text = function(value) {" << endl;
mOutfile << "\tswitch (value) {" << endl;
for (it = members.begin(); it != members.end(); it++) {
ConstField *cf = *it;
mOutfile << "\tcase " << mCurProj->getName() << "." << enum_name << "." << cf->getName().substr(prefix_size, string::npos) << ":" << endl;
mOutfile << "\t\treturn \"" << cf->getName().substr(prefix_size, string::npos) << "\";" << endl;
}
mOutfile << "\tdefault:" << endl;
mOutfile << "\t\treturn \"?\";" << endl;
mOutfile << "\t}" << endl;
mOutfile << "};" << endl;
mOutfile.close();
}
void JavascriptGenerator::writeClass(Class *klass){
ostringstream filename;
if (klass->getType()==Type::Enum) {
return;
}
const list<Method*> &methods=klass->getMethods();
if (methods.empty()) return;//skip empty classes
filename<<to_lower(mCurProj->getName())<<"/"<<to_lower(klass->getName())<<".js";
mOutfile.open(filename.str().c_str());
if (!mOutfile.is_open()){
cerr<<"Could not write into "<<filename.str()<<endl;
return;
}
mCurClass=klass;
mOutfile<<"/* Wrapper generated by lp-gen-wrappers, do not edit*/"<<endl;
mOutfile<<endl;
//if (!mCurProj->getName().empty())
// mOutfile<<"namespace "<<mCurProj->getName()<<"{"<<endl<<endl;
mOutfile<<"/**"<<endl;
mOutfile<<" * "<<klass->getHelp()<<endl;
mOutfile<<" * @external "<<klass->getName()<<endl;
mOutfile<<"**/"<<endl;
list<Property*> properties=klass->getProperties();
for_each(properties.begin(),properties.end(),bind1st(mem_fun(&JavascriptGenerator::writeProperty),this));
mOutfile<<endl;
for_each(methods.begin(),methods.end(),bind1st(mem_fun(&JavascriptGenerator::writeMethod),this));
for_each(methods.begin(),methods.end(),bind1st(mem_fun(&JavascriptGenerator::writeEvent),this));
//if (!mCurProj->getName().empty())
// mOutfile<<"} //end of namespace "<<mCurProj->getName()<<endl;
mOutfile<<endl;
mOutfile.close();
}
void JavascriptGenerator::writeType(Type *type){
switch(type->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:
mOutfile<<"external:"<<type->getName();
break;
case Type::Enum:
mOutfile<<mCurProj->getName()<<"."<<getEnumName(mCurProj->getClass(type->getName()));
break;
case Type::Void:
mOutfile<<"void";
break;
case Type::Callback:
break;
case Type::Array:
mOutfile<<"Array.<Object>";
break;
}
}
void JavascriptGenerator::writeArgument(Argument *arg, ArgKind kind){
switch(kind){
case Normal:
mOutfile<<" * @param {";
writeType(arg->getType());
mOutfile<<"} "<<arg->getName()<<" - "<<arg->getHelp()<<endl;
break;
case Return:
mOutfile<<" * @returns {";
writeType(arg->getType());
mOutfile<<"} "<<arg->getHelp()<<endl;
break;
case PropertyArg:
mOutfile<<" * @property {";
writeType(arg->getType());
mOutfile<<"} "<<arg->getName()<<" - "<<arg->getHelp()<<endl;
break;
}
}
void JavascriptGenerator::writeTabs(int ntabs){
int i;
for(i=0;i<ntabs;++i)
mOutfile<<"\t";
}
void JavascriptGenerator::writeHelpComment(const std::string &comment, int ntabs){
size_t i;
int curindex=0;
writeTabs(ntabs);
mOutfile<<" * ";
for(i=0;i<comment.size();i++,curindex++){
if (comment[i]=='\n' || (curindex>100 && comment[i]==' ')){
mOutfile<<endl;
writeTabs(ntabs);
mOutfile<<" * ";
curindex=0;
}else mOutfile<<comment[i];
}
}
void JavascriptGenerator::writeProperty(Property *prop){
if (prop->getName()=="userData" || prop->getName()=="userPointer") return;
mOutfile<<"/**"<<endl;
writeHelpComment(prop->getHelp(),0);
mOutfile<<endl;
mOutfile<<" * @member {";
writeType(prop->getType());
mOutfile<<"} external:"<<mCurClass->getName()<<"#"<<prop->getName()<<endl;
if (prop->getAttribute()==Property::ReadOnly)
mOutfile<<" * @readonly"<<endl;
mOutfile<<"**/"<<endl;
}
void JavascriptGenerator::writeMethod(Method *method){
Argument *retarg=method->getReturnArg();
const list<Argument*> &args=method->getArgs();
list<Argument*>::const_iterator it;
if (method->isCallback()) return;
if (method->getPropertyBehaviour()!=Method::None) return;
if (method->getName()=="ref" || method->getName()=="unref") return;
mOutfile<<"/**"<<endl;
writeHelpComment(method->getHelp(),0);
mOutfile<<endl;
mOutfile<<" * @function external:"<<mCurClass->getName()<<"#"<<method->getName()<<endl;
for(it=args.begin();it!=args.end();++it){
writeArgument(*it);
}
writeArgument(retarg,Return);
mOutfile<<"**/"<<endl;
mOutfile<<endl;
}
string JavascriptGenerator::getEventHelp(const string &help){
size_t i=help.find("Callback");
if (i==string::npos){
i=help.find("callback");
if (i==string::npos) return help;
}
string res(help);
res.replace(i,8,"event");
return res;
}
void JavascriptGenerator::writeEvent(Method* event){
const list<Argument*> &args=event->getArgs();
list<Argument*>::const_iterator it;
if (!event->isCallback()) return;
mOutfile<<"/**"<<endl;
writeHelpComment(getEventHelp(event->getHelp()),0);
mOutfile<<endl;
mOutfile<<" * @event external:"<<mCurClass->getName()<<"#"<<event->getName()<<endl;
mOutfile<<" * @type {object}"<<endl;
for(it=args.begin();it!=args.end();++it){
writeArgument(*it,PropertyArg);
}
mOutfile<<"**/"<<endl;
mOutfile<<endl;
}
/*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef generator_hh
#define generator_hh
#include <fstream>
#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);
void writeEnumMember(ConstField *cf, bool isLast);
ofstream mOutfile;
Project *mCurProj;
Class *mCurClass;
};
class JavascriptGenerator : public OutputGenerator{
public:
JavascriptGenerator();
virtual void generate(Project *proj);
private:
void writeClass(Class *klass);
void writeEnum(Class *klass);
void writeType(Type *type);
enum ArgKind { Normal, Return, PropertyArg};
void writeArgument(Argument *arg, ArgKind kind=Normal);
void writeTabs(int ntabs);
void writeHelpComment(const std::string &comment, int ntabs);
void writeProperty(Property *prop);
void writeMethod(Method *method);
void writeEvent(Method *event);
string getEventHelp(const string &ref);
string getEnumName(Class *klass);
ofstream mOutfile;
Project *mCurProj;
Class *mCurClass;
};
string to_lower(const string &str);
#endif
/*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "software-desc.hh"
#include "generator.hh"
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
#include <cstdio>
#include <iostream>
#include <sstream>
static bool isSpace(const char *str){
for(;*str!='\0';++str){
if (!isspace(*str)) return false;
}
return true;
}
//Convenient class for examining node recursively
class XmlNode{
public:
XmlNode(const xmlNode *node=NULL) : mNode(node){
}
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<XmlNode> getChildren(const string &name)const{
xmlNode *it;
list<XmlNode> 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 "<<name<<" found"<<endl;
return nodes;
}
string getText()const{