diff options
author | Joe George <joe@zeroc.com> | 2017-02-13 18:48:57 -0500 |
---|---|---|
committer | Joe George <joe@zeroc.com> | 2017-02-13 18:48:57 -0500 |
commit | dc5678e6988bad79336033518f8f2378f7c34cb2 (patch) | |
tree | f1b7d00d8bfde31297c4473d62ace3d05031b985 /cpp/src/slice2php/Main.cpp | |
parent | Connection wizard dialog becomes readonly (diff) | |
parent | ICE-7506 - Update copyright to 2017 (diff) | |
download | ice-dc5678e6988bad79336033518f8f2378f7c34cb2.tar.bz2 ice-dc5678e6988bad79336033518f8f2378f7c34cb2.tar.xz ice-dc5678e6988bad79336033518f8f2378f7c34cb2.zip |
Merge remote-tracking branch 'origin/3.6'
Diffstat (limited to 'cpp/src/slice2php/Main.cpp')
-rw-r--r-- | cpp/src/slice2php/Main.cpp | 1935 |
1 files changed, 0 insertions, 1935 deletions
diff --git a/cpp/src/slice2php/Main.cpp b/cpp/src/slice2php/Main.cpp deleted file mode 100644 index a948a8ad746..00000000000 --- a/cpp/src/slice2php/Main.cpp +++ /dev/null @@ -1,1935 +0,0 @@ -// ********************************************************************** -// -// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. -// -// This copy of Ice is licensed to you under the terms described in the -// ICE_LICENSE file included in this distribution. -// -// ********************************************************************** - -#include <IceUtil/DisableWarnings.h> -#include <IceUtil/CtrlCHandler.h> -#include <IceUtil/IceUtil.h> -#include <IceUtil/InputUtil.h> -#include <IceUtil/Options.h> -#include <IceUtil/OutputUtil.h> -#include <IceUtil/StringUtil.h> -#include <IceUtil/Mutex.h> -#include <IceUtil/MutexPtrLock.h> -#include <IceUtil/ConsoleUtil.h> -#include <Slice/Checksum.h> -#include <Slice/Preprocessor.h> -#include <Slice/FileTracker.h> -#include <Slice/PHPUtil.h> -#include <Slice/Parser.h> -#include <Slice/Util.h> -#include <cstring> -#include <climits> - -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef _WIN32 -# include <direct.h> -#else -# include <unistd.h> -#endif - -using namespace std; -using namespace Slice; -using namespace Slice::PHP; -using namespace IceUtilInternal; - -namespace -{ - -// -// Get the fully-qualified name of the given definition. If a suffix is provided, -// it is prepended to the definition's unqualified name. If the nameSuffix -// is provided, it is appended to the container's name. -// -string -getAbsolute(const ContainedPtr& cont, bool ns, const string& pfx = std::string(), const string& suffix = std::string()) -{ - return scopedToName(cont->scope() + pfx + cont->name() + suffix, ns); -} - -} - -// -// CodeVisitor generates the PHP mapping for a translation unit. -// -class CodeVisitor : public ParserVisitor -{ -public: - - CodeVisitor(IceUtilInternal::Output&, bool); - - virtual void visitClassDecl(const ClassDeclPtr&); - virtual bool visitClassDefStart(const ClassDefPtr&); - virtual bool visitExceptionStart(const ExceptionPtr&); - virtual bool visitStructStart(const StructPtr&); - virtual void visitSequence(const SequencePtr&); - virtual void visitDictionary(const DictionaryPtr&); - virtual void visitEnum(const EnumPtr&); - virtual void visitConst(const ConstPtr&); - -private: - - void startNamespace(const ContainedPtr&); - void endNamespace(); - - // - // Return the PHP name for the given Slice type. When using namespaces, - // this name is a relative (unqualified) name, otherwise this name is the - // flattened absolute name. - // - string getName(const ContainedPtr&, const string& = string()); - - // - // Return the PHP variable for the given object's type. - // - string getTypeVar(const ContainedPtr&, const string& = string()); - - // - // Emit the array for a Slice type. - // - void writeType(const TypePtr&); - - // - // Write a default value for a given type. - // - void writeDefaultValue(const DataMemberPtr&); - - struct MemberInfo - { - string fixedName; - bool inherited; - DataMemberPtr dataMember; - }; - typedef list<MemberInfo> MemberInfoList; - - // - // Write a member assignment statement for a constructor. - // - void writeAssign(const MemberInfo&); - - // - // Write constant value. - // - void writeConstantValue(const TypePtr&, const SyntaxTreeBasePtr&, const string&); - - // - // Write constructor parameters with default values. - // - void writeConstructorParams(const MemberInfoList&); - - // - // Convert an operation mode into a string. - // - string getOperationMode(Slice::Operation::Mode, bool); - - void collectClassMembers(const ClassDefPtr&, MemberInfoList&, bool); - void collectExceptionMembers(const ExceptionPtr&, MemberInfoList&, bool); - - Output& _out; - bool _ns; // Using namespaces? - list<string> _moduleStack; // TODO: Necessary? - set<string> _classHistory; // TODO: Necessary? -}; - -// -// CodeVisitor implementation. -// -CodeVisitor::CodeVisitor(Output& out, bool ns) : - _out(out), - _ns(ns) -{ -} - -void -CodeVisitor::visitClassDecl(const ClassDeclPtr& p) -{ - // - // Handle forward declarations. - // - string scoped = p->scoped(); - if(_classHistory.count(scoped) == 0) - { - startNamespace(p); - - string type = getTypeVar(p); - _out << sp << nl << "global " << type << ';'; - - bool isInterface = p->isInterface(); - if(!p->isLocal() && (isInterface || p->definition()->allOperations().size() > 0)) - { - _out << nl << "global " << type << "Prx;"; - } - _out << nl << "if(!isset(" << type << "))"; - _out << sb; - _out << nl << type << " = IcePHP_declareClass('" << scoped << "');"; - if(!p->isLocal() && (isInterface || p->definition()->allOperations().size() > 0)) - { - _out << nl << type << "Prx = IcePHP_declareProxy('" << scoped << "');"; - } - _out << eb; - - endNamespace(); - - _classHistory.insert(scoped); // Avoid redundant declarations. - } -} - -bool -CodeVisitor::visitClassDefStart(const ClassDefPtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return false; - } - - string scoped = p->scoped(); - string name = getName(p); - string type = getTypeVar(p); - string abs = getAbsolute(p, _ns); - string prxName = getName(p, "Prx"); - string prxType = getTypeVar(p, "Prx"); - string prxAbs = getAbsolute(p, _ns, "", "Prx"); - ClassList bases = p->bases(); - ClassDefPtr base; - OperationList ops = p->operations(); - DataMemberList members = p->dataMembers(); - bool isInterface = p->isInterface(); - bool isAbstract = isInterface || p->allOperations().size() > 0; // Don't use isAbstract() - see bug 3739 - - startNamespace(p); - - _out << sp << nl << "global " << type << ';'; - if(!p->isLocal() && isAbstract) - { - _out << nl << "global " << prxType << ';'; - } - - // - // Define the class. - // - if(isInterface) - { - if(p->isLocal()) - { - _out << nl << "interface " << name; - if(bases.empty()) - { - if(!p->isLocal()) - { - _out << " extends " << scopedToName("::Ice::Object", _ns); - } - } - else - { - _out << " extends "; - for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) - { - if(q != bases.begin()) - { - _out << ", "; - } - _out << getAbsolute(*q, _ns); - } - } - _out << sb; - for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli) - { - _out << nl << "public function " << fixIdent((*oli)->name()) << '('; - ParamDeclList params = (*oli)->parameters(); - for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q) - { - if(q != params.begin()) - { - _out << ", "; - } - _out << '$' << fixIdent((*q)->name()); - } - _out << ");"; - } - - _out << eb; - } - } - else - { - _out << nl; - _out << "class " << name; - if(!bases.empty() && !bases.front()->isInterface()) - { - base = bases.front(); - bases.pop_front(); - } - if(base) - { - _out << " extends " << getAbsolute(base, _ns); - } - else - { - if(!p->isLocal()) - { - _out << " extends " << scopedToName("::Ice::Value", _ns); - } - } - - // - // Value objects don't implement any interfaces. - // - if(p->isLocal() && !bases.empty()) - { - _out << " implements "; - for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) - { - if(q != bases.begin()) - { - _out << ", "; - } - _out << getAbsolute(*q, _ns); - } - } - - _out << sb; - - // - // __construct - // - _out << nl << "public function __construct("; - MemberInfoList allMembers; - collectClassMembers(p, allMembers, false); - writeConstructorParams(allMembers); - _out << ")"; - _out << sb; - if(base) - { - _out << nl << "parent::__construct("; - int count = 0; - for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q) - { - if(q->inherited) - { - if(count) - { - _out << ", "; - } - _out << '$' << q->fixedName; - ++count; - } - } - _out << ");"; - } - { - for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q) - { - if(!q->inherited) - { - writeAssign(*q); - } - } - } - _out << eb; - - if(!p->isLocal()) - { - // - // ice_ice - // - _out << sp << nl << "public function ice_id()"; - _out << sb; - _out << nl << "return '" << scoped << "';"; - _out << eb; - - // - // ice_staticId - // - _out << sp << nl << "public static function ice_staticId()"; - _out << sb; - _out << nl << "return '" << scoped << "';"; - _out << eb; - } - - // - // __toString - // - _out << sp << nl << "public function __toString()"; - _out << sb; - _out << nl << "global " << type << ';'; - _out << nl << "return IcePHP_stringify($this, " << type << ");"; - _out << eb; - - if(!members.empty()) - { - _out << sp; - bool isProtected = p->hasMetaData("protected"); - for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) - { - _out << nl; - if(isProtected || (*q)->hasMetaData("protected")) - { - _out << "protected "; - } - else - { - _out << "public "; - } - _out << "$" << fixIdent((*q)->name()) << ";"; - } - } - - _out << eb; // End of class. - } - - // - // Define the proxy class. - // - if(!p->isLocal() && isAbstract) - { - _out << sp << nl << "class " << prxName << "Helper"; - _out << sb; - - _out << sp << nl << "public static function checkedCast($proxy, $facetOrContext=null, $context=null)"; - _out << sb; - _out << nl << "return $proxy->ice_checkedCast('" << scoped << "', $facetOrContext, $context);"; - _out << eb; - - _out << sp << nl << "public static function uncheckedCast($proxy, $facet=null)"; - _out << sb; - _out << nl << "return $proxy->ice_uncheckedCast('" << scoped << "', $facet);"; - _out << eb; - - _out << sp << nl << "public static function ice_staticId()"; - _out << sb; - _out << nl << "return '" << scoped << "';"; - _out << eb; - - _out << eb; - } - - if(_classHistory.count(scoped) == 0 && p->canBeCyclic()) - { - // - // Emit a forward declaration for the class in case a data member refers to this type. - // - _out << sp << nl << type << " = IcePHP_declareClass('" << scoped << "');"; - if(!p->isLocal() && isAbstract) - { - _out << nl << prxType << " = IcePHP_declareProxy('" << scoped << "');"; - } - } - - // - // Emit the type information. - // - const bool preserved = p->hasMetaData("preserve-slice") || p->inheritsMetaData("preserve-slice"); - _out << sp << nl << type << " = IcePHP_defineClass('" << scoped << "', '" << escapeName(abs) << "', " - << p->compactId() << ", " << (preserved ? "true" : "false") << ", " - << (isInterface ? "true" : "false") << ", "; - if(!base || (isInterface && !p->isLocal())) - { - _out << "$Ice__t_Value"; - } - else - { - _out << getTypeVar(base); - } - _out << ", "; - // - // Members - // - // Data members are represented as an array: - // - // ('MemberName', MemberType, Optional, Tag) - // - // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type. - // - if(!members.empty()) - { - _out << "array("; - for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) - { - if(q != members.begin()) - { - _out << ','; - } - _out.inc(); - _out << nl << "array('" << fixIdent((*q)->name()) << "', "; - writeType((*q)->type()); - _out << ", " << ((*q)->optional() ? "true" : "false") << ", " - << ((*q)->optional() ? (*q)->tag() : 0) << ')'; - _out.dec(); - } - _out << ')'; - } - else - { - _out << "null"; - } - _out << ");"; - - if(!p->isLocal() && isAbstract) - { - _out << sp << nl << prxType << " = IcePHP_defineProxy('" << scoped << "', "; - if(!base || base->allOperations().empty()) - { - _out << "$Ice__t_ObjectPrx"; - } - else - { - _out << getTypeVar(base, "Prx"); - } - _out << ", "; - // - // Interfaces - // - if(!bases.empty()) - { - _out << "array("; - for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q) - { - if(q != bases.begin()) - { - _out << ", "; - } - _out << getTypeVar(*q, "Prx"); - } - _out << ')'; - } - else - { - _out << "null"; - } - _out << ");"; - - // - // Define each operation. The arguments to IcePHP_defineOperation are: - // - // $ClassType, 'opName', Mode, SendMode, FormatType, (InParams), (OutParams), ReturnParam, (Exceptions) - // - // where InParams and OutParams are arrays of type descriptions, and Exceptions - // is an array of exception type ids. - // - if(!ops.empty()) - { - _out << sp; - for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli) - { - ParamDeclList params = (*oli)->parameters(); - ParamDeclList::iterator t; - int count; - - _out << nl << "IcePHP_defineOperation(" << prxType << ", '" << (*oli)->name() << "', " - << getOperationMode((*oli)->mode(), _ns) << ", " << getOperationMode((*oli)->sendMode(), _ns) - << ", " << static_cast<int>((*oli)->format()) << ", "; - for(t = params.begin(), count = 0; t != params.end(); ++t) - { - if(!(*t)->isOutParam()) - { - if(count == 0) - { - _out << "array("; - } - else if(count > 0) - { - _out << ", "; - } - _out << "array("; - writeType((*t)->type()); - if((*t)->optional()) - { - _out << ", " << (*t)->tag(); - } - _out << ')'; - ++count; - } - } - if(count > 0) - { - _out << ')'; - } - else - { - _out << "null"; - } - _out << ", "; - for(t = params.begin(), count = 0; t != params.end(); ++t) - { - if((*t)->isOutParam()) - { - if(count == 0) - { - _out << "array("; - } - else if(count > 0) - { - _out << ", "; - } - _out << "array("; - writeType((*t)->type()); - if((*t)->optional()) - { - _out << ", " << (*t)->tag(); - } - _out << ')'; - ++count; - } - } - if(count > 0) - { - _out << ')'; - } - else - { - _out << "null"; - } - _out << ", "; - TypePtr returnType = (*oli)->returnType(); - if(returnType) - { - // - // The return type has the same format as an in/out parameter: - // - // Type, Optional?, OptionalTag - // - _out << "array("; - writeType(returnType); - if((*oli)->returnIsOptional()) - { - _out << ", " << (*oli)->returnTag(); - } - _out << ')'; - } - else - { - _out << "null"; - } - _out << ", "; - ExceptionList exceptions = (*oli)->throws(); - if(!exceptions.empty()) - { - _out << "array("; - for(ExceptionList::iterator u = exceptions.begin(); u != exceptions.end(); ++u) - { - if(u != exceptions.begin()) - { - _out << ", "; - } - _out << getTypeVar(*u); - } - _out << ')'; - } - else - { - _out << "null"; - } - _out << ");"; - } - } - } - - endNamespace(); - - if(_classHistory.count(scoped) == 0) - { - _classHistory.insert(scoped); // Avoid redundant declarations. - } - - return false; -} - -bool -CodeVisitor::visitExceptionStart(const ExceptionPtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return false; - } - - string scoped = p->scoped(); - string name = getName(p); - string type = getTypeVar(p); - string abs = getAbsolute(p, _ns); - - startNamespace(p); - - _out << sp << nl << "global " << type << ';'; - _out << nl << "class " << name << " extends "; - ExceptionPtr base = p->base(); - string baseName; - if(base) - { - baseName = getAbsolute(base, _ns); - _out << baseName; - } - else if(p->isLocal()) - { - _out << scopedToName("::Ice::LocalException", _ns); - } - else - { - _out << scopedToName("::Ice::UserException", _ns); - } - _out << sb; - - DataMemberList members = p->dataMembers(); - - // - // __construct - // - _out << nl << "public function __construct("; - MemberInfoList allMembers; - collectExceptionMembers(p, allMembers, false); - writeConstructorParams(allMembers); - _out << ")"; - _out << sb; - if(base) - { - _out << nl << "parent::__construct("; - int count = 0; - for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q) - { - if(q->inherited) - { - if(count) - { - _out << ", "; - } - _out << '$' << q->fixedName; - ++count; - } - } - _out << ");"; - } - for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q) - { - if(!q->inherited) - { - writeAssign(*q); - } - } - _out << eb; - - // - // ice_id - // - _out << sp << nl << "public function ice_id()"; - _out << sb; - _out << nl << "return '" << scoped << "';"; - _out << eb; - - // - // __toString - // - _out << sp << nl << "public function __toString()"; - _out << sb; - _out << nl << "global " << type << ';'; - _out << nl << "return IcePHP_stringifyException($this, " << type << ");"; - _out << eb; - - if(!members.empty()) - { - _out << sp; - for(DataMemberList::iterator dmli = members.begin(); dmli != members.end(); ++dmli) - { - _out << nl << "public $" << fixIdent((*dmli)->name()) << ";"; - } - } - - _out << eb; - - // - // Emit the type information. - // - const bool preserved = p->hasMetaData("preserve-slice") || p->inheritsMetaData("preserve-slice"); - _out << sp << nl << type << " = IcePHP_defineException('" << scoped << "', '" << escapeName(abs) << "', " - << (preserved ? "true" : "false") << ", "; - if(!base) - { - _out << "null"; - } - else - { - _out << getTypeVar(base); - } - _out << ", "; - // - // Data members are represented as an array: - // - // ('MemberName', MemberType, Optional, Tag) - // - // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type. - // - if(!members.empty()) - { - _out << "array("; - for(DataMemberList::iterator dmli = members.begin(); dmli != members.end(); ++dmli) - { - if(dmli != members.begin()) - { - _out << ','; - } - _out.inc(); - _out << nl << "array('" << fixIdent((*dmli)->name()) << "', "; - writeType((*dmli)->type()); - _out << ", " << ((*dmli)->optional() ? "true" : "false") << ", " - << ((*dmli)->optional() ? (*dmli)->tag() : 0) << ')'; - _out.dec(); - } - _out << ')'; - } - else - { - _out << "null"; - } - _out << ");"; - - endNamespace(); - - return false; -} - -bool -CodeVisitor::visitStructStart(const StructPtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return false; - } - - string scoped = p->scoped(); - string name = getName(p); - string type = getTypeVar(p); - string abs = getAbsolute(p, _ns); - MemberInfoList memberList; - - { - DataMemberList members = p->dataMembers(); - for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) - { - memberList.push_back(MemberInfo()); - memberList.back().fixedName = fixIdent((*q)->name()); - memberList.back().inherited = false; - memberList.back().dataMember = *q; - } - } - - startNamespace(p); - - _out << sp << nl << "global " << type << ';'; - - _out << nl << "class " << name; - _out << sb; - _out << nl << "public function __construct("; - writeConstructorParams(memberList); - _out << ")"; - _out << sb; - for(MemberInfoList::iterator r = memberList.begin(); r != memberList.end(); ++r) - { - writeAssign(*r); - } - _out << eb; - - // - // __toString - // - _out << sp << nl << "public function __toString()"; - _out << sb; - _out << nl << "global " << type << ';'; - _out << nl << "return IcePHP_stringify($this, " << type << ");"; - _out << eb; - - if(!memberList.empty()) - { - _out << sp; - for(MemberInfoList::iterator r = memberList.begin(); r != memberList.end(); ++r) - { - _out << nl << "public $" << r->fixedName << ';'; - } - } - - _out << eb; - - // - // Emit the type information. - // - _out << sp << nl << type << " = IcePHP_defineStruct('" << scoped << "', '" << escapeName(abs) << "', array("; - // - // Data members are represented as an array: - // - // ('MemberName', MemberType) - // - // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type. - // - for(MemberInfoList::iterator r = memberList.begin(); r != memberList.end(); ++r) - { - if(r != memberList.begin()) - { - _out << ", "; - } - _out.inc(); - _out << nl << "array('" << r->fixedName << "', "; - writeType(r->dataMember->type()); - _out << ')'; - _out.dec(); - } - _out << "));"; - endNamespace(); - - return false; -} - -void -CodeVisitor::visitSequence(const SequencePtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return; - } - - string type = getTypeVar(p); - TypePtr content = p->type(); - - startNamespace(p); - - // - // Emit the type information. - // - string scoped = p->scoped(); - _out << sp << nl << "global " << type << ';'; - _out << sp << nl << "if(!isset(" << type << "))"; - _out << sb; - _out << nl << type << " = IcePHP_defineSequence('" << scoped << "', "; - writeType(content); - _out << ");"; - _out << eb; - - endNamespace(); -} - -void -CodeVisitor::visitDictionary(const DictionaryPtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return; - } - - TypePtr keyType = p->keyType(); - BuiltinPtr b = BuiltinPtr::dynamicCast(keyType); - - const UnitPtr unit = p->unit(); - const DefinitionContextPtr dc = unit->findDefinitionContext(p->file()); - assert(dc); - if(b) - { - switch(b->kind()) - { - case Slice::Builtin::KindBool: - case Slice::Builtin::KindByte: - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindLong: - case Slice::Builtin::KindString: - // - // These types are acceptable as dictionary keys. - // - break; - - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - { - dc->warning(InvalidMetaData, p->file(), p->line(), "dictionary key type not supported in PHP"); - break; - } - - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - case Slice::Builtin::KindValue: - assert(false); - } - } - else if(!EnumPtr::dynamicCast(keyType)) - { - dc->warning(InvalidMetaData, p->file(), p->line(), "dictionary key type not supported in PHP"); - } - - string type = getTypeVar(p); - - startNamespace(p); - - // - // Emit the type information. - // - string scoped = p->scoped(); - _out << sp << nl << "global " << type << ';'; - _out << sp << nl << "if(!isset(" << type << "))"; - _out << sb; - _out << nl << type << " = IcePHP_defineDictionary('" << scoped << "', "; - writeType(p->keyType()); - _out << ", "; - writeType(p->valueType()); - _out << ");"; - _out << eb; - - endNamespace(); -} - -void -CodeVisitor::visitEnum(const EnumPtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return; - } - - string scoped = p->scoped(); - string name = getName(p); - string type = getTypeVar(p); - string abs = getAbsolute(p, _ns); - EnumeratorList enums = p->enumerators(); - - startNamespace(p); - - _out << sp << nl << "global " << type << ';'; - _out << nl << "class " << name; - _out << sb; - - { - long i = 0; - for(EnumeratorList::iterator q = enums.begin(); q != enums.end(); ++q, ++i) - { - _out << nl << "const " << fixIdent((*q)->name()) << " = " << (*q)->value() << ';'; - } - } - - _out << eb; - - // - // Emit the type information. - // - _out << sp << nl << type << " = IcePHP_defineEnum('" << scoped << "', array("; - for(EnumeratorList::iterator q = enums.begin(); q != enums.end(); ++q) - { - if(q != enums.begin()) - { - _out << ", "; - } - _out << "'" << (*q)->name() << "', " << (*q)->value(); - } - _out << "));"; - - endNamespace(); -} - -void -CodeVisitor::visitConst(const ConstPtr& p) -{ - // - // Do not generate any code for php:internal types, those are provided by - // IcePHP C++ extension. - // - StringList metadata = p->getMetaData(); - if(find(metadata.begin(), metadata.end(), "php:internal") != metadata.end()) - { - return; - } - - string name = getName(p); - string type = getTypeVar(p); - string abs = getAbsolute(p, _ns); - - startNamespace(p); - - _out << sp << nl << "if(!defined('" << escapeName(abs) << "'))"; - _out << sb; - if(_ns) - { - _out << sp << nl << "define(__NAMESPACE__ . '\\\\" << name << "', "; - } - else - { - _out << sp << nl << "define('" << name << "', "; - } - - writeConstantValue(p->type(), p->valueType(), p->value()); - - _out << ");"; - _out << eb; - - endNamespace(); -} - -void -CodeVisitor::startNamespace(const ContainedPtr& cont) -{ - if(_ns) - { - string scope = cont->scope(); - scope = scope.substr(2); // Removing leading '::' - scope = scope.substr(0, scope.length() - 2); // Removing trailing '::' - _out << sp << nl << "namespace " << scopedToName(scope, true); - _out << sb; - } -} - -void -CodeVisitor::endNamespace() -{ - if(_ns) - { - _out << eb; - } -} - -string -CodeVisitor::getTypeVar(const ContainedPtr& p, const string& suffix) -{ - return "$" + getAbsolute(p, false, "_t_", suffix); -} - -string -CodeVisitor::getName(const ContainedPtr& p, const string& suffix) -{ - if(_ns) - { - return fixIdent(p->name() + suffix); - } - else - { - return getAbsolute(p, false, "", suffix); - } -} - -void -CodeVisitor::writeType(const TypePtr& p) -{ - BuiltinPtr builtin = BuiltinPtr::dynamicCast(p); - if(builtin) - { - switch(builtin->kind()) - { - case Builtin::KindBool: - { - _out << "$IcePHP__t_bool"; - break; - } - case Builtin::KindByte: - { - _out << "$IcePHP__t_byte"; - break; - } - case Builtin::KindShort: - { - _out << "$IcePHP__t_short"; - break; - } - case Builtin::KindInt: - { - _out << "$IcePHP__t_int"; - break; - } - case Builtin::KindLong: - { - _out << "$IcePHP__t_long"; - break; - } - case Builtin::KindFloat: - { - _out << "$IcePHP__t_float"; - break; - } - case Builtin::KindDouble: - { - _out << "$IcePHP__t_double"; - break; - } - case Builtin::KindString: - { - _out << "$IcePHP__t_string"; - break; - } - case Builtin::KindObject: - case Builtin::KindValue: - { - _out << "$Ice__t_Value"; - break; - } - case Builtin::KindObjectProxy: - { - _out << "$Ice__t_ObjectPrx"; - break; - } - case Builtin::KindLocalObject: - { - _out << "$Ice__t_LocalObject"; - break; - } - } - return; - } - - ProxyPtr prx = ProxyPtr::dynamicCast(p); - if(prx) - { - ClassDefPtr def = prx->_class()->definition(); - if(def->isInterface() || def->allOperations().size() > 0) - { - _out << getTypeVar(prx->_class(), "Prx"); - } - else - { - _out << "$Ice__t_ObjectPrx"; - } - return; - } - - ContainedPtr cont = ContainedPtr::dynamicCast(p); - assert(cont); - _out << getTypeVar(cont); -} - -void -CodeVisitor::writeDefaultValue(const DataMemberPtr& m) -{ - TypePtr p = m->type(); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(p); - if(builtin) - { - switch(builtin->kind()) - { - case Builtin::KindBool: - { - _out << "false"; - break; - } - case Builtin::KindByte: - case Builtin::KindShort: - case Builtin::KindInt: - case Builtin::KindLong: - { - _out << "0"; - break; - } - case Builtin::KindFloat: - case Builtin::KindDouble: - { - _out << "0.0"; - break; - } - case Builtin::KindString: - { - _out << "''"; - break; - } - case Builtin::KindObject: - case Builtin::KindObjectProxy: - case Builtin::KindLocalObject: - case Builtin::KindValue: - { - _out << "null"; - break; - } - } - return; - } - - EnumPtr en = EnumPtr::dynamicCast(p); - if(en) - { - EnumeratorList enums = en->enumerators(); - _out << getAbsolute(en, _ns) << "::" << fixIdent(enums.front()->name()); - return; - } - - // - // PHP does not allow the following construct: - // - // function foo($theStruct=new MyStructType) - // - // Instead we use null as the default value and allocate an instance in - // the constructor. - // - if(StructPtr::dynamicCast(p)) - { - _out << "null"; - return; - } - - _out << "null"; -} - -void -CodeVisitor::writeAssign(const MemberInfo& info) -{ - StructPtr st = StructPtr::dynamicCast(info.dataMember->type()); - if(st) - { - _out << nl << "$this->" << info.fixedName << " = is_null($" << info.fixedName << ") ? new " - << getAbsolute(st, _ns) << " : $" << info.fixedName << ';'; - } - else - { - _out << nl << "$this->" << info.fixedName << " = $" << info.fixedName << ';'; - } -} - -void -CodeVisitor::writeConstantValue(const TypePtr& type, const SyntaxTreeBasePtr& valueType, const string& value) -{ - ConstPtr constant = ConstPtr::dynamicCast(valueType); - if(constant) - { - _out << getAbsolute(constant, _ns); - } - else - { - Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type); - Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type); - if(b) - { - switch(b->kind()) - { - case Slice::Builtin::KindBool: - case Slice::Builtin::KindByte: - case Slice::Builtin::KindShort: - case Slice::Builtin::KindInt: - case Slice::Builtin::KindFloat: - case Slice::Builtin::KindDouble: - { - _out << value; - break; - } - case Slice::Builtin::KindLong: - { - IceUtil::Int64 l; - IceUtilInternal::stringToInt64(value, l); - // - // The platform's 'long' type may not be 64 bits, so we store 64-bit - // values as a string. - // - if(sizeof(IceUtil::Int64) > sizeof(long) && (l < LONG_MIN || l > LONG_MAX)) - { - _out << "'" << value << "'"; - } - else - { - _out << value; - } - break; - } - case Slice::Builtin::KindString: - { - // PHP 7.x also supports an EC6UCN-like notation, see: - // https://wiki.php.net/rfc/unicode_escape - // - _out << "\"" << toStringLiteral(value, "\f\n\r\t\v\x1b", "$", Octal, 0) << "\""; - break; - } - case Slice::Builtin::KindObject: - case Slice::Builtin::KindObjectProxy: - case Slice::Builtin::KindLocalObject: - case Slice::Builtin::KindValue: - assert(false); - } - } - else if(en) - { - EnumeratorPtr lte = EnumeratorPtr::dynamicCast(valueType); - assert(lte); - _out << getAbsolute(en, _ns) << "::" << fixIdent(lte->name()); - } - else - { - assert(false); // Unknown const type. - } - } -} - -void -CodeVisitor::writeConstructorParams(const MemberInfoList& members) -{ - for(MemberInfoList::const_iterator p = members.begin(); p != members.end(); ++p) - { - if(p != members.begin()) - { - _out << ", "; - } - _out << '$' << p->fixedName << "="; - - const DataMemberPtr member = p->dataMember; - if(member->defaultValueType()) - { - writeConstantValue(member->type(), member->defaultValueType(), member->defaultValue()); - } - else if(member->optional()) - { - _out << "Ice_Unset"; - } - else - { - writeDefaultValue(member); - } - } -} - -string -CodeVisitor::getOperationMode(Slice::Operation::Mode mode, bool /*ns*/) -{ - ostringstream ostr; - ostr << static_cast<int>(mode); - return ostr.str(); -} - -void -CodeVisitor::collectClassMembers(const ClassDefPtr& p, MemberInfoList& allMembers, bool inherited) -{ - ClassList bases = p->bases(); - if(!bases.empty() && !bases.front()->isInterface()) - { - collectClassMembers(bases.front(), allMembers, true); - } - - DataMemberList members = p->dataMembers(); - - for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) - { - MemberInfo m; - m.fixedName = fixIdent((*q)->name()); - m.inherited = inherited; - m.dataMember = *q; - allMembers.push_back(m); - } -} - -void -CodeVisitor::collectExceptionMembers(const ExceptionPtr& p, MemberInfoList& allMembers, bool inherited) -{ - ExceptionPtr base = p->base(); - if(base) - { - collectExceptionMembers(base, allMembers, true); - } - - DataMemberList members = p->dataMembers(); - - for(DataMemberList::iterator q = members.begin(); q != members.end(); ++q) - { - MemberInfo m; - m.fixedName = fixIdent((*q)->name()); - m.inherited = inherited; - m.dataMember = *q; - allMembers.push_back(m); - } -} - -static void -generate(const UnitPtr& un, bool all, bool checksum, bool ns, const vector<string>& includePaths, Output& out) -{ - if(!all) - { - vector<string> paths = includePaths; - for(vector<string>::iterator p = paths.begin(); p != paths.end(); ++p) - { - *p = fullPath(*p); - } - - StringList includes = un->includeFiles(); - if(!includes.empty()) - { - if(ns) - { - out << sp; - out << nl << "namespace"; - out << sb; - } - for(StringList::const_iterator q = includes.begin(); q != includes.end(); ++q) - { - string file = changeInclude(*q, paths); - out << nl << "require_once '" << file << ".php';"; - } - if(ns) - { - out << eb; - } - } - } - - CodeVisitor codeVisitor(out, ns); - un->visit(&codeVisitor, false); - - if(checksum) - { - ChecksumMap checksums = createChecksums(un); - if(!checksums.empty()) - { - out << sp; - if(ns) - { - out << "namespace"; // Global namespace. - out << sb; - } - for(ChecksumMap::const_iterator p = checksums.begin(); p != checksums.end(); ++p) - { - out << nl << "$Ice_sliceChecksums[\"" << p->first << "\"] = \""; - ostringstream str; - str.flags(ios_base::hex); - str.fill('0'); - for(vector<unsigned char>::const_iterator q = p->second.begin(); q != p->second.end(); ++q) - { - str << static_cast<int>(*q); - } - out << str.str() << "\";"; - } - if(ns) - { - out << eb; - } - } - } - - out << nl; // Trailing newline. -} - -static void -printHeader(IceUtilInternal::Output& out) -{ - static const char* header = - "// **********************************************************************\n" - "//\n" - "// Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved.\n" - "//\n" - "// This copy of Ice is licensed to you under the terms described in the\n" - "// ICE_LICENSE file included in this distribution.\n" - "//\n" - "// **********************************************************************\n" - ; - - out << header; - out << "//\n"; - out << "// Ice version " << ICE_STRING_VERSION << "\n"; - out << "//\n"; -} - -namespace -{ - -IceUtil::Mutex* globalMutex = 0; -bool interrupted = false; - -class Init -{ -public: - - Init() - { - globalMutex = new IceUtil::Mutex; - } - - ~Init() - { - delete globalMutex; - globalMutex = 0; - } -}; - -Init init; - -} - -static void -interruptedCallback(int /*signal*/) -{ - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); - - interrupted = true; -} - -static void -usage(const string& n) -{ - consoleErr << "Usage: " << n << " [options] slice-files...\n"; - consoleErr << - "Options:\n" - "-h, --help Show this message.\n" - "-v, --version Display the Ice version.\n" - "--validate Validate command line options.\n" - "-DNAME Define NAME as 1.\n" - "-DNAME=DEF Define NAME as DEF.\n" - "-UNAME Remove any definition for NAME.\n" - "-IDIR Put DIR in the include file search path.\n" - "-E Print preprocessor output on stdout.\n" - "--output-dir DIR Create files in the directory DIR.\n" - "--depend Generate Makefile dependencies.\n" - "--depend-xml Generate dependencies in XML format.\n" - "--depend-file FILE Write dependencies to FILE instead of standard output.\n" - "-d, --debug Print debug messages.\n" - "--all Generate code for Slice definitions in included files.\n" - "--checksum Generate checksums for Slice definitions.\n" - "--no-namespace Do not use PHP namespaces (deprecated).\n" - "--ice Allow reserved Ice prefix in Slice identifiers\n" - " deprecated: use instead [[\"ice-prefix\"]] metadata.\n" - "--underscore Allow underscores in Slice identifiers\n" - " deprecated: use instead [[\"underscore\"]] metadata.\n" - ; -} - -int -compile(const vector<string>& argv) -{ - IceUtilInternal::Options opts; - opts.addOpt("h", "help"); - opts.addOpt("v", "version"); - opts.addOpt("", "validate"); - opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); - opts.addOpt("E"); - opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg); - opts.addOpt("", "depend"); - opts.addOpt("", "depend-xml"); - opts.addOpt("", "depend-file", IceUtilInternal::Options::NeedArg, ""); - opts.addOpt("d", "debug"); - opts.addOpt("", "ice"); - opts.addOpt("", "underscore"); - opts.addOpt("", "all"); - opts.addOpt("", "checksum"); - opts.addOpt("n", "no-namespace"); - - bool validate = find(argv.begin(), argv.end(), "--validate") != argv.end(); - - vector<string> args; - try - { - args = opts.parse(argv); - } - catch(const IceUtilInternal::BadOptException& e) - { - consoleErr << argv[0] << ": error: " << e.reason << endl; - if(!validate) - { - usage(argv[0]); - } - return EXIT_FAILURE; - } - - if(opts.isSet("help")) - { - usage(argv[0]); - return EXIT_SUCCESS; - } - - if(opts.isSet("version")) - { - consoleErr << ICE_STRING_VERSION << endl; - return EXIT_SUCCESS; - } - - vector<string> cppArgs; - vector<string> optargs = opts.argVec("D"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-D" + *i); - } - - optargs = opts.argVec("U"); - for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) - { - cppArgs.push_back("-U" + *i); - } - - vector<string> includePaths = opts.argVec("I"); - for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i) - { - cppArgs.push_back("-I" + Preprocessor::normalizeIncludePath(*i)); - } - - bool preprocess = opts.isSet("E"); - - string output = opts.optArg("output-dir"); - - bool depend = opts.isSet("depend"); - - bool dependxml = opts.isSet("depend-xml"); - - string dependFile = opts.optArg("depend-file"); - - bool debug = opts.isSet("debug"); - - bool ice = opts.isSet("ice"); - - bool underscore = opts.isSet("underscore"); - - bool all = opts.isSet("all"); - - bool checksum = opts.isSet("checksum"); - - bool ns = !opts.isSet("no-namespace"); - - if(args.empty()) - { - consoleErr << argv[0] << ": error: no input file" << endl; - if(!validate) - { - usage(argv[0]); - } - return EXIT_FAILURE; - } - - if(depend && dependxml) - { - consoleErr << argv[0] << ": error: cannot specify both --depend and --depend-xml" << endl; - if(!validate) - { - usage(argv[0]); - } - return EXIT_FAILURE; - } - - if(validate) - { - return EXIT_SUCCESS; - } - - int status = EXIT_SUCCESS; - - IceUtil::CtrlCHandler ctrlCHandler; - ctrlCHandler.setCallback(interruptedCallback); - - ostringstream os; - if(dependxml) - { - os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<dependencies>" << endl; - } - - for(vector<string>::const_iterator i = args.begin(); i != args.end(); ++i) - { - // - // Ignore duplicates. - // - vector<string>::iterator p = find(args.begin(), args.end(), *i); - if(p != i) - { - continue; - } - - if(depend || dependxml) - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2PHP__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } - - UnitPtr u = Unit::createUnit(false, false, ice, underscore); - int parseStatus = u->parse(*i, cppHandle, debug); - u->destroy(); - - if(parseStatus == EXIT_FAILURE) - { - return EXIT_FAILURE; - } - - if(!icecpp->printMakefileDependencies(os, depend ? Preprocessor::PHP : Preprocessor::SliceXML, - includePaths, "-D__SLICE2PHP__")) - { - return EXIT_FAILURE; - } - - if(!icecpp->close()) - { - return EXIT_FAILURE; - } - } - else - { - PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs); - FILE* cppHandle = icecpp->preprocess(false, "-D__SLICE2PHP__"); - - if(cppHandle == 0) - { - return EXIT_FAILURE; - } - - if(preprocess) - { - char buf[4096]; - while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != ICE_NULLPTR) - { - if(fputs(buf, stdout) == EOF) - { - return EXIT_FAILURE; - } - } - if(!icecpp->close()) - { - return EXIT_FAILURE; - } - } - else - { - UnitPtr u = Unit::createUnit(false, all, ice, underscore); - int parseStatus = u->parse(*i, cppHandle, debug); - - if(!icecpp->close()) - { - u->destroy(); - return EXIT_FAILURE; - } - - if(parseStatus == EXIT_FAILURE) - { - status = EXIT_FAILURE; - } - else - { - string base = icecpp->getBaseName(); - string::size_type pos = base.find_last_of("/\\"); - if(pos != string::npos) - { - base.erase(0, pos + 1); - } - - string file = base + ".php"; - if(!output.empty()) - { - file = output + '/' + file; - } - - try - { - IceUtilInternal::Output out; - out.open(file.c_str()); - if(!out) - { - ostringstream os; - os << "cannot open`" << file << "': " << strerror(errno); - throw FileException(__FILE__, __LINE__, os.str()); - } - FileTracker::instance()->addFile(file); - - out << "<?php\n"; - printHeader(out); - printGeneratedHeader(out, base + ".ice"); - - // - // Generate the PHP mapping. - // - generate(u, all, checksum, ns, includePaths, out); - - out << "?>\n"; - out.close(); - } - catch(const Slice::FileException& ex) - { - // If a file could not be created, then cleanup any - // created files. - FileTracker::instance()->cleanup(); - u->destroy(); - consoleErr << argv[0] << ": error: " << ex.reason() << endl; - return EXIT_FAILURE; - } - catch(const string& err) - { - FileTracker::instance()->cleanup(); - consoleErr << argv[0] << ": error: " << err << endl; - status = EXIT_FAILURE; - } - } - - u->destroy(); - } - } - - { - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(globalMutex); - - if(interrupted) - { - FileTracker::instance()->cleanup(); - return EXIT_FAILURE; - } - } - } - - if(dependxml) - { - os << "</dependencies>\n"; - } - - if(depend || dependxml) - { - writeDependencies(os.str(), dependFile); - } - - return status; -} - -#ifdef _WIN32 -int wmain(int argc, wchar_t* argv[]) -#else -int main(int argc, char* argv[]) -#endif -{ - vector<string> args = Slice::argvToArgs(argc, argv); - try - { - return compile(args); - } - catch(const std::exception& ex) - { - consoleErr << args[0] << ": error:" << ex.what() << endl; - return EXIT_FAILURE; - } - catch(const std::string& msg) - { - consoleErr << args[0] << ": error:" << msg << endl; - return EXIT_FAILURE; - } - catch(const char* msg) - { - consoleErr << args[0] << ": error:" << msg << endl; - return EXIT_FAILURE; - } - catch(...) - { - consoleErr << args[0] << ": error:" << "unknown exception" << endl; - return EXIT_FAILURE; - } -} |