diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Makefile | 1 | ||||
-rwxr-xr-x | cpp/src/Slice/CsUtil.cpp | 1000 | ||||
-rw-r--r-- | cpp/src/Slice/Makefile | 1 | ||||
-rwxr-xr-x | cpp/src/slice2cs/Gen.cpp | 776 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.h | 79 | ||||
-rw-r--r-- | cpp/src/slice2cs/Main.cpp | 252 | ||||
-rw-r--r-- | cpp/src/slice2cs/Makefile | 37 | ||||
-rw-r--r-- | cpp/src/slice2cs/slice2cs.dsp | 126 |
8 files changed, 2272 insertions, 0 deletions
diff --git a/cpp/src/Makefile b/cpp/src/Makefile index da6e5924a99..fb5f8da050c 100644 --- a/cpp/src/Makefile +++ b/cpp/src/Makefile @@ -20,6 +20,7 @@ SUBDIRS = IceUtil \ icecpp \ Slice \ slice2cpp \ + slice2cs \ slice2freeze \ slice2freezej \ slice2docbook \ diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp new file mode 100755 index 00000000000..195fb5f43f2 --- /dev/null +++ b/cpp/src/Slice/CsUtil.cpp @@ -0,0 +1,1000 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <Slice/CsUtil.h> +#include <IceUtil/Functional.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +#include <direct.h> +#endif + +#ifndef _WIN32 +#include <unistd.h> +#endif + +using namespace std; +using namespace Slice; +using namespace IceUtil; + +string +Slice::CsGenerator::fixGlobal(const ContainedPtr& p) +{ + string name; + if(p->scope() == "::" && (p->name() == "Microsoft" || p->name() == "System")) + { + name = "_cs_"; + } + name += p->name(); + return name; +} + +static string +lookupKwd(const string& name) +{ + // + // Keyword list. *Must* be kept in alphabetical order. + // + static const string keywordList[] = + { + "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", + "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", + "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "int", "interface", + "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "override", + "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", + "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", + "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while" + }; + bool found = binary_search(&keywordList[0], + &keywordList[sizeof(keywordList) / sizeof(*keywordList)], + name); + return found ? "@" + name : name; +} + +// +// Split a scoped name into its components and return the components as a list of (unscoped) identifiers. +// +static StringList +splitScopedName(const string& scoped) +{ + assert(scoped[0] == ':'); + StringList ids; + string::size_type next = 0; + string::size_type pos; + while((pos = scoped.find("::", next)) != string::npos) + { + pos += 2; + if(pos != scoped.size()) + { + string::size_type endpos = scoped.find("::", pos); + if(endpos != string::npos) + { + ids.push_back(scoped.substr(pos, endpos - pos)); + } + } + next = pos; + } + if(next != scoped.size()) + { + ids.push_back(scoped.substr(next)); + } + else + { + ids.push_back(""); + } + + return ids; +} + +// +// If the passed name is a scoped name, return the identical scoped name, +// but with all components that are C# keywords replaced by +// their "@"-prefixed version; otherwise, if the passed name is +// not scoped, but a C# keyword, return the "@"-prefixed name; +// otherwise, return the name unchanged. +// +string +Slice::CsGenerator::fixKwd(const string& name) +{ + if(name.empty()) + { + return name; + } + if(name[0] != ':') + { + return lookupKwd(name); + } + StringList ids = splitScopedName(name); + transform(ids.begin(), ids.end(), ids.begin(), ptr_fun(lookupKwd)); + stringstream result; + for(StringList::const_iterator i = ids.begin(); i != ids.end(); ++i) + { + if(i != ids.begin()) + { + result << '.'; + } + else + { + if(*i == "Microsoft" || *i == "System") + { + result << "_cs_" + *i; + } + else + { + result << *i; + } + } + } + return result.str(); +} + +string +Slice::CsGenerator::typeToString(const TypePtr& type) +{ + static const char* builtinTable[] = + { + "byte", + "bool", + "short", + "int", + "long", + "float", + "double", + "string", + "Ice.Object", + "Ice.ObjectPrx", + "Ice.LocalObject" + }; + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + return builtinTable[builtin->kind()]; + } + + ProxyPtr proxy = ProxyPtr::dynamicCast(type); + if(proxy) + { + return fixKwd(proxy->_class()->scoped() + "Prx"); + } + + ContainedPtr contained = ContainedPtr::dynamicCast(type); + if(contained) + { + return fixKwd(contained->scoped()); + } + + return "???"; +} + +#if 0 + +void +Slice::CsGenerator::writeMarshalUnmarshalCode(Output& out, + const string& scope, + const TypePtr& type, + const string& param, + bool marshal, + int& iter, + bool holder, + const list<string>& metaData, + const string& patchParams) +{ + string stream = marshal ? "__os" : "__is"; + string v; + if(holder) + { + v = param + ".value"; + } + else + { + v = param; + } + + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + switch(builtin->kind()) + { + case Builtin::KindByte: + { + if(marshal) + { + out << nl << stream << ".writeByte(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readByte();"; + } + break; + } + case Builtin::KindBool: + { + if(marshal) + { + out << nl << stream << ".writeBool(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readBool();"; + } + break; + } + case Builtin::KindShort: + { + if(marshal) + { + out << nl << stream << ".writeShort(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readShort();"; + } + break; + } + case Builtin::KindInt: + { + if(marshal) + { + out << nl << stream << ".writeInt(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readInt();"; + } + break; + } + case Builtin::KindLong: + { + if(marshal) + { + out << nl << stream << ".writeLong(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readLong();"; + } + break; + } + case Builtin::KindFloat: + { + if(marshal) + { + out << nl << stream << ".writeFloat(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readFloat();"; + } + break; + } + case Builtin::KindDouble: + { + if(marshal) + { + out << nl << stream << ".writeDouble(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readDouble();"; + } + break; + } + case Builtin::KindString: + { + if(marshal) + { + out << nl << stream << ".writeString(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readString();"; + } + break; + } + case Builtin::KindObject: + { + if(marshal) + { + out << nl << stream << ".writeObject(" << v << ");"; + } + else + { + if(holder) + { + out << nl << stream << ".readObject(" << param << ".getPatcher());"; + } + else + { + if(patchParams.empty()) + { + out << nl << stream << ".readObject(new Patcher());"; + } + else + { + out << nl << stream << ".readObject(" << patchParams << ");"; + } + } + } + break; + } + case Builtin::KindObjectProxy: + { + if(marshal) + { + out << nl << stream << ".writeProxy(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readProxy();"; + } + break; + } + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + return; + } + + ProxyPtr prx = ProxyPtr::dynamicCast(type); + if(prx) + { + string typeS = typeToString(type, TypeModeIn, scope); + if(marshal) + { + out << nl << typeS << "Helper.__write(" << stream << ", " << v << ");"; + } + else + { + out << nl << v << " = " << typeS << "Helper.__read(" << stream << ");"; + } + return; + } + + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); + if(cl) + { + if(marshal) + { + out << nl << stream << ".writeObject(" << v << ");"; + } + else + { + string typeS = typeToString(type, TypeModeIn, scope); + if(holder) + { + out << nl << stream << ".readObject(" << param << ".getPatcher());"; + } + else + { + if(patchParams.empty()) + { + out << nl << stream << ".readObject(new Patcher());"; + } + else + { + out << nl << stream << ".readObject(" << patchParams << ");"; + } + } + } + return; + } + + StructPtr st = StructPtr::dynamicCast(type); + if(st) + { + if(marshal) + { + out << nl << v << ".__write(" << stream << ");"; + } + else + { + string typeS = typeToString(type, TypeModeIn, scope); + out << nl << v << " = new " << typeS << "();"; + out << nl << v << ".__read(" << stream << ");"; + } + return; + } + + EnumPtr en = EnumPtr::dynamicCast(type); + if(en) + { + if(marshal) + { + out << nl << v << ".__write(" << stream << ");"; + } + else + { + string typeS = typeToString(type, TypeModeIn, scope); + out << nl << v << " = " << typeS << ".__read(" << stream << ");"; + } + return; + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + writeSequenceMarshalUnmarshalCode(out, scope, seq, v, marshal, iter, true, metaData); + return; + } + + ConstructedPtr constructed = ConstructedPtr::dynamicCast(type); + assert(constructed); + string typeS = getAbsolute(constructed->scoped(), scope); + if(marshal) + { + out << nl << typeS << "Helper.write(" << stream << ", " << v << ");"; + } + else + { + out << nl << v << " = " << typeS << "Helper.read(" << stream << ");"; + } +} + +void +Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out, + const string& scope, + const SequencePtr& seq, + const string& param, + bool marshal, + int& iter, + bool useHelper, + const list<string>& metaData) +{ + string stream = marshal ? "__os" : "__is"; + string v = param; + + // + // Check for metadata that overrides the default sequence + // mapping. If no metadata is found, we use a regular Java + // array. If metadata is found, the value of the metadata + // must be the name of a class which implements the + // java.util.List interface. + // + // There are two sources of metadata - that passed into + // this function (which most likely comes from a data + // member definition), and that associated with the type + // itself. If data member metadata is found, and does + // not match the type's metadata, then we cannot use + // the type's Helper class for marshalling - we must + // generate marshalling code inline. + // + string listType = findMetaData(metaData); + list<string> typeMetaData = seq->getMetaData(); + if(listType.empty()) + { + listType = findMetaData(typeMetaData); + } + else + { + string s = findMetaData(typeMetaData); + if(listType != s) + { + useHelper = false; + } + } + + // + // If we can use the sequence's helper, it's easy. + // + if(useHelper) + { + string typeS = getAbsolute(seq->scoped(), scope); + if(marshal) + { + out << nl << typeS << "Helper.write(" << stream << ", " << v << ");"; + } + else + { + out << nl << v << " = " << typeS << "Helper.read(" << stream << ");"; + } + return; + } + + // + // Determine sequence depth + // + int depth = 0; + TypePtr origContent = seq->type(); + SequencePtr s = SequencePtr::dynamicCast(origContent); + while(s) + { + // + // Stop if the inner sequence type has metadata. + // + string m = findMetaData(s->getMetaData()); + if(!m.empty()) + { + break; + } + depth++; + origContent = s->type(); + s = SequencePtr::dynamicCast(origContent); + } + string origContentS = typeToString(origContent, TypeModeIn, scope); + + if(!listType.empty()) + { + // + // Marshal/unmarshal a custom sequence type + // + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + if(b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy) + { + if(marshal) + { + out << nl << "if(" << v << " == null)"; + out << sb; + out << nl << stream << ".writeSize(0);"; + out << eb; + out << nl << "else"; + out << sb; + out << nl << stream << ".writeSize(" << v << ".size());"; + ostringstream o; + o << "__i" << iter; + string it = o.str(); + iter++; + out << nl << "java.util.Iterator " << it << " = " << v << ".iterator();"; + out << nl << "while(" << it << ".hasNext())"; + out << sb; + + switch(b->kind()) + { + case Builtin::KindByte: + { + out << nl << "java.lang.Byte __elem = (java.lang.Byte)" << it << ".next();"; + out << nl << stream << ".writeByte(__elem.byteValue());"; + break; + } + case Builtin::KindBool: + { + out << nl << "java.lang.Boolean __elem = (java.lang.Boolean)" << it << ".next();"; + out << nl << stream << ".writeBool(__elem.booleanValue());"; + break; + } + case Builtin::KindShort: + { + out << nl << "java.lang.Short __elem = (java.lang.Short)" << it << ".next();"; + out << nl << stream << ".writeShort(__elem.shortValue());"; + break; + } + case Builtin::KindInt: + { + out << nl << "java.lang.Integer __elem = (java.lang.Integer)" << it << ".next();"; + out << nl << stream << ".writeInt(__elem.intValue());"; + break; + } + case Builtin::KindLong: + { + out << nl << "java.lang.Long __elem = (java.lang.Long)" << it << ".next();"; + out << nl << stream << ".writeLong(__elem.longValue());"; + break; + } + case Builtin::KindFloat: + { + out << nl << "java.lang.Float __elem = (java.lang.Float)" << it << ".next();"; + out << nl << stream << ".writeFloat(__elem.floatValue());"; + break; + } + case Builtin::KindDouble: + { + out << nl << "java.lang.Double __elem = (java.lang.Double)" << it << ".next();"; + out << nl << stream << ".writeDouble(__elem.doubleValue());"; + break; + } + case Builtin::KindString: + { + out << nl << "java.lang.String __elem = (java.lang.String)" << it << ".next();"; + out << nl << stream << ".writeString(__elem);"; + break; + } + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + out << eb; // while + out << eb; + } + else + { + out << nl << v << " = new " << listType << "();"; + ostringstream o; + o << origContentS << "[]"; + int d = depth; + while(d--) + { + o << "[]"; + } + switch(b->kind()) + { + case Builtin::KindByte: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readByteSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(new java.lang.Byte(__seq" << iter << "[__i" << iter << "]));"; + out << eb; + iter++; + break; + } + case Builtin::KindBool: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readBoolSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(__seq" << iter << "[__i" << iter + << "] ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE);"; + out << eb; + iter++; + break; + } + case Builtin::KindShort: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readShortSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(new java.lang.Short(__seq" << iter << "[__i" << iter << "]));"; + out << eb; + iter++; + break; + } + case Builtin::KindInt: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readIntSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(new java.lang.Integer(__seq" << iter << "[__i" << iter << "]));"; + out << eb; + iter++; + break; + } + case Builtin::KindLong: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readLongSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(new java.lang.Long(__seq" << iter << "[__i" << iter << "]));"; + out << eb; + iter++; + break; + } + case Builtin::KindFloat: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readFloatSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(new java.lang.Float(__seq" << iter << "[__i" << iter << "]));"; + out << eb; + iter++; + break; + } + case Builtin::KindDouble: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readDoubleSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(new java.lang.Double(__seq" << iter << "[__i" << iter << "]));"; + out << eb; + iter++; + break; + } + case Builtin::KindString: + { + out << nl << o.str() << " __seq" << iter << " = " << stream << ".readStringSeq();"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __seq" << iter + << ".length; __i" << iter << "++)"; + out << sb; + out << nl << v << ".add(__seq" << iter << "[__i" << iter << "]);"; + out << eb; + iter++; + break; + } + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + } + } + else + { + string typeS = getAbsolute(seq->scoped(), scope); + if(marshal) + { + out << nl << "if(" << v << " == null)"; + out << sb; + out << nl << stream << ".writeSize(0);"; + out << eb; + out << nl << "else"; + out << sb; + out << nl << stream << ".writeSize(" << v << ".size());"; + ostringstream o; + o << "__i" << iter; + iter++; + string it = o.str(); + out << nl << "java.util.Iterator " << it << " = " << v << ".iterator();"; + out << nl << "while(" << it << ".hasNext())"; + out << sb; + out << nl << origContentS << " __elem = (" << origContentS << ")" << it << ".next();"; + writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", true, iter, false); + out << eb; // while + out << eb; // else + } + else + { + bool isObject = false; + BuiltinPtr builtin = BuiltinPtr::dynamicCast(origContent); + if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(origContent)) + { + isObject = true; + } + out << nl << v << " = new " << listType << "();"; + out << nl << "final int __len" << iter << " = " << stream << ".readSize();"; + if(isObject) + { + if(builtin) + { + out << nl << "final String __type" << iter << " = Ice.ObjectImpl.ice_staticId();"; + } + else + { + out << nl << "final String __type" << iter << " = " << origContentS << ".ice_staticId();"; + } + } + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __len" << iter << "; __i" << iter + << "++)"; + out << sb; + if(isObject) + { + // + // Add a null value to the list as a placeholder for the element. + // + out << nl << v << ".add(null);"; + ostringstream patchParams; + patchParams << "new IceInternal.ListPatcher(" << v << ", " << origContentS << ".class, __type" + << iter << ", __i" << iter << ')'; + writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", false, iter, false, + list<string>(), patchParams.str()); + } + else + { + out << nl << origContentS << " __elem;"; + writeMarshalUnmarshalCode(out, scope, seq->type(), "__elem", false, iter, false); + } + iter++; + if(!isObject) + { + out << nl << v << ".add(__elem);"; + } + out << eb; + } + } + } + else + { + BuiltinPtr b = BuiltinPtr::dynamicCast(seq->type()); + if(b && b->kind() != Builtin::KindObject && b->kind() != Builtin::KindObjectProxy) + { + switch(b->kind()) + { + case Builtin::KindByte: + { + if(marshal) + { + out << nl << stream << ".writeByteSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readByteSeq();"; + } + break; + } + case Builtin::KindBool: + { + if(marshal) + { + out << nl << stream << ".writeBoolSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readBoolSeq();"; + } + break; + } + case Builtin::KindShort: + { + if(marshal) + { + out << nl << stream << ".writeShortSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readShortSeq();"; + } + break; + } + case Builtin::KindInt: + { + if(marshal) + { + out << nl << stream << ".writeIntSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readIntSeq();"; + } + break; + } + case Builtin::KindLong: + { + if(marshal) + { + out << nl << stream << ".writeLongSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readLongSeq();"; + } + break; + } + case Builtin::KindFloat: + { + if(marshal) + { + out << nl << stream << ".writeFloatSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readFloatSeq();"; + } + break; + } + case Builtin::KindDouble: + { + if(marshal) + { + out << nl << stream << ".writeDoubleSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readDoubleSeq();"; + } + break; + } + case Builtin::KindString: + { + if(marshal) + { + out << nl << stream << ".writeStringSeq(" << v << ");"; + } + else + { + out << nl << v << " = " << stream << ".readStringSeq();"; + } + break; + } + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + assert(false); + break; + } + } + } + else + { + if(marshal) + { + out << nl << "if(" << v << " == null)"; + out << sb; + out << nl << stream << ".writeSize(0);"; + out << eb; + out << nl << "else"; + out << sb; + out << nl << stream << ".writeSize(" << v << ".length);"; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < " << v << ".length; __i" << iter + << "++)"; + out << sb; + ostringstream o; + o << v << "[__i" << iter << "]"; + iter++; + writeMarshalUnmarshalCode(out, scope, seq->type(), o.str(), true, iter, false); + out << eb; + out << eb; + } + else + { + bool isObject = false; + if((b && b->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(origContent)) + { + isObject = true; + } + out << nl << "final int __len" << iter << " = " << stream << ".readSize();"; + if(isObject) + { + if(b) + { + out << nl << "final String __type" << iter << " = Ice.ObjectImpl.ice_staticId();"; + } + else + { + out << nl << "final String __type" << iter << " = " << origContentS << ".ice_staticId();"; + } + } + out << nl << v << " = new " << origContentS << "[__len" << iter << "]"; + int d = depth; + while(d--) + { + out << "[]"; + } + out << ';'; + out << nl << "for(int __i" << iter << " = 0; __i" << iter << " < __len" << iter << "; __i" << iter + << "++)"; + out << sb; + ostringstream o; + o << v << "[__i" << iter << "]"; + ostringstream patchParams; + if(isObject) + { + patchParams << "new IceInternal.SequencePatcher(" << v << ", " << origContentS + << ".class, __type" << iter << ", __i" << iter << ')'; + writeMarshalUnmarshalCode(out, scope, seq->type(), o.str(), false, iter, false, + list<string>(), patchParams.str()); + } + else + { + writeMarshalUnmarshalCode(out, scope, seq->type(), o.str(), false, iter, false); + } + iter++; + out << eb; + } + } + } +} + +string +Slice::CsGenerator::findMetaData(const list<string>& metaData) +{ + static const string prefix = "cs:"; + for(list<string>::const_iterator q = metaData.begin(); q != metaData.end(); ++q) + { + if((*q).find(prefix) == 0) + { + return (*q).substr(prefix.size()); + } + } + + return ""; +} +#endif diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile index 2ccb6200575..95c20ea2f1d 100644 --- a/cpp/src/Slice/Makefile +++ b/cpp/src/Slice/Makefile @@ -25,6 +25,7 @@ OBJS = Scanner.o \ Grammar.o \ Parser.o \ CPlusPlusUtil.o \ + CsUtil.o \ JavaUtil.o \ Preprocessor.o diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp new file mode 100755 index 00000000000..e04680cc3f5 --- /dev/null +++ b/cpp/src/slice2cs/Gen.cpp @@ -0,0 +1,776 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <IceUtil/Functional.h> +#include <Gen.h> +#include <limits> +#include <IceUtil/Algorithm.h> +#include <IceUtil/Iterator.h> + +using namespace std; +using namespace Slice; + +// +// Don't use "using namespace IceUtil", or stupid VC++ 6.0 complains +// about ambigious symbols for constructs like +// "IceUtil::constMemFun(&Slice::Exception::isLocal)". +// +using IceUtil::Output; +using IceUtil::nl; +using IceUtil::sp; +using IceUtil::sb; +using IceUtil::eb; + +static string // Should be an anonymous namespace, but VC++ 6 can't handle that. +sliceModeToIceMode(const OperationPtr& op) +{ + string mode; + switch(op->mode()) + { + case Operation::Normal: + { + mode = "Ice.OperationMode.Normal"; + break; + } + case Operation::Nonmutating: + { + mode = "Ice.OperationMode.Nonmutating"; + break; + } + case Operation::Idempotent: + { + mode = "Ice.OperationMode.Idempotent"; + break; + } + default: + { + assert(false); + break; + } + } + return mode; +} + +Slice::CsVisitor::CsVisitor(Output& out) : _out(out) +{ +} + +Slice::CsVisitor::~CsVisitor() +{ +} + +Slice::Gen::Gen(const string& name, const string& base, const vector<string>& includePaths) : + _base(base), + _includePaths(includePaths) +{ + string file = base + ".cs"; + _out.open(file.c_str()); + if(!_out) + { + cerr << name << ": can't open `" << file << "' for writing: " << strerror(errno) << endl; + return; + } + printHeader(); + _out << nl << "// Generated from file `" << name << "'"; +} + +Slice::Gen::~Gen() +{ +} + +bool +Slice::Gen::operator!() const +{ + return !_out; +} + +void +Slice::Gen::generate(const UnitPtr& p) +{ + TypesVisitor typesVisitor(_out); + p->visit(&typesVisitor); +} + +void +Slice::Gen::printHeader() +{ + static const char* header = +"// **********************************************************************\n" +"//\n" +"// Copyright (c) 2003\n" +"// ZeroC, Inc.\n" +"// Billerica, MA, USA\n" +"//\n" +"// All Rights Reserved.\n" +"//\n" +"// Ice is free software; you can redistribute it and/or modify it under\n" +"// the terms of the GNU General Public License version 2 as published by\n" +"// the Free Software Foundation.\n" +"//\n" +"// **********************************************************************\n" + ; + + _out << header; + _out << "\n// Ice version " << ICE_STRING_VERSION; +} + +Slice::Gen::TypesVisitor::TypesVisitor(IceUtil::Output& out) : + CsVisitor(out) +{ +} + +bool +Slice::Gen::TypesVisitor::visitModuleStart(const ModulePtr& p) +{ + string name = fixKwd(fixGlobal(p)); + _out << sp << nl << "namespace " << name << nl << '{'; + + return true; +} + +void +Slice::Gen::TypesVisitor::visitModuleEnd(const ModulePtr& p) +{ + _out << sp << nl << '}'; +} + +void +Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) +{ + string name = fixKwd(fixGlobal(p)); + string s = typeToString(p->type()); + + _out << sp << nl << "public class " << name + << " : System.Collections.CollectionBase, System.ICloneable, System.IComparable"; + _out << sb; + + _out << nl << "public " << s << " this[int index]"; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "return (" << s << ")List[index];"; + _out << eb; + + _out << nl << "set"; + _out << sb; + _out << nl << "List[index] = value;"; + _out << eb; + _out << eb; + + _out << sp << nl << "public int"; + _out << nl << "Add(" << s << " value)"; + _out << sb; + _out << nl << "return List.Add(value);"; + _out << eb; + + _out << sp << nl << "public int"; + _out << nl << "IndexOf(" << s << " value)"; + _out << sb; + _out << nl << "return List.IndexOf(value);"; + _out << eb; + + _out << sp << nl << "public void"; + _out << nl << "Insert(int index, " << s << " value)"; + _out << sb; + _out << nl << "List.Insert(index, value);"; + _out << eb; + + _out << sp << nl << "public void"; + _out << nl << "Remove(" << s << " value)"; + _out << sb; + _out << nl << "List.Remove(value);"; + _out << eb; + + _out << sp << nl << "public bool"; + _out << nl << "Contains(" << s << " value)"; + _out << sb; + _out << nl << "return List.Contains(value);"; + _out << eb; + + _out << sp << nl << "public object"; + _out << nl << "Clone()"; + _out << sb; + _out << nl << name << " __ret = new "<< name << "();"; + _out << nl << "foreach(" << s << " __i in __ret)"; + _out << sb; + _out << nl << "__ret.Add(__i);"; + _out << eb; + _out << nl << "return __ret;"; + _out << eb; + + _out << sp << nl << "public int CompareTo(object other)"; + _out << sb; + _out << nl << "if(other == null)"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + _out << nl << "if(object.ReferenceEquals(this, other))"; + _out << sb; + _out << nl << "return 0;"; + _out << eb; + _out << nl << "if(!(other is " << name << "))"; + _out << sb; + _out << nl << "throw new System.ArgumentException(\"CompareTo: expected argument of type `" << name + << "'\", \"other\");"; + _out << eb; + _out << nl << name << " __other = (" << name << ")other;"; + _out << nl << "int __limit = System.Math.Min(this.Count, __other.Count);"; + _out << nl << "for(int __i = 0; __i < __limit; ++__i)"; + _out << sb; + _out << nl << "if(this[__i] < __other[__i])"; + _out << sb; + _out << nl << "return -1;"; + _out << eb; + _out << nl << "if(this[__i] > __other[__i])"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + _out << eb; + _out << nl << "return this.Count < __other.Count ? -1 : ((this.Count > __other.Count) ? 1 : 0);"; + _out << eb; + + _out << sp << nl << "public override int GetHashCode()"; + _out << sb; + _out << nl << "int hash = 0;"; + _out << nl << "for(int i = 0; i < Count; ++i)"; + _out << sb; + _out << nl << "hash = (hash << 5) ^ this[i].GetHashCode();"; + _out << eb; + _out << nl << "return hash;"; + _out << eb; + + _out << sp << nl << "public override bool Equals(object other)"; + _out << sb; + _out << nl << "return CompareTo(other) == 0;"; + _out << eb; + + _out << sp << nl << "public static bool Equals(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.CompareTo(rhs) == 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator==(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator!=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return !Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator<(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs != null : lhs.CompareTo(rhs) < 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator>(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? false : lhs.CompareTo(rhs) > 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator<=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? true : lhs.CompareTo(rhs) <= 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator>=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.CompareTo(rhs) >= 0;"; + _out << eb; + + _out << eb; +} + +bool +Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + ExceptionPtr base = p->base(); + + _out << sp << nl << "public class " << name << " : "; + if(base) + { + _out << fixKwd(base->scoped()); + } + else + { + _out << (p->isLocal() ? "Ice.LocalException" : "Ice.UserException"); + } + _out << sb; + + return true; +} + +void +Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + + DataMemberList dataMembers = p->dataMembers(); + DataMemberList::const_iterator q; + + _out << sp << nl << "public " << name << "() : base(\"" << name << "\")"; + _out << sb; + _out << eb; + + _out << sp << nl << "public " << name << "(string __m) : base(__m)"; + _out << sb; + _out << eb; + + _out << sp << nl << "public " << name << "(string __m, System.Exception __e) : base(__m, __e)"; + _out << sb; + _out << eb; + + _out << sp << nl << "public override int GetHashCode()"; + _out << sb; + _out << nl << "int hash = 0;"; + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixKwd((*q)->name()); + _out << nl << "hash = (hash << 5) ^ " << memberName << ".GetHashCode();"; + } + _out << nl << "return hash;"; + _out << eb; + + _out << sp << nl << "public override bool Equals(object other)"; + _out << sb; + _out << nl << "if(other == null)"; + _out << sb; + _out << nl << "return false;"; + _out << eb; + _out << nl << "if(object.ReferenceEquals(this, other))"; + _out << sb; + _out << nl << "return true;"; + _out << eb; + _out << nl << "if(!(other is " << name << "))"; + _out << sb; + _out << nl << "throw new System.ArgumentException(\"expected argument of type `" << name << "'\", \"other\");"; + _out << eb; + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixKwd((*q)->name()); + _out << nl << "if(this." << memberName << " != ((" << name << ")other)." << memberName << ")"; + _out << sb; + _out << nl << "return false;"; + _out << eb; + } + _out << nl << "return true;"; + _out << eb; + + _out << sp << nl << "public static bool Equals(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.Equals(rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator==(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator!=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return !Equals(lhs, rhs);"; + _out << eb; + + _out << eb; +} + +bool +Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + + _out << sp << nl << "public class " << name << " : System.ICloneable, System.IComparable"; + _out << sb; + + return true; +} + +void +Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + + DataMemberList dataMembers = p->dataMembers(); + DataMemberList::const_iterator q; + + _out << sp << nl << "public object Clone()"; + _out << sb; + _out << nl << name << " __ret = new " << name << "();"; + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixKwd((*q)->name()); + _out << nl << "__ret." << memberName << " = this." << memberName << ";"; + } + _out << nl << "return __ret;"; + _out << eb; + + _out << sp << nl << "public int CompareTo(object other)"; + _out << sb; + _out << nl << "if(other == null)"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + _out << nl << "if(object.ReferenceEquals(this, other))"; + _out << sb; + _out << nl << "return 0;"; + _out << eb; + _out << nl << "if(!(other is " << name << "))"; + _out << sb; + _out << nl << "throw new System.ArgumentException(\"expected argument of type `" << name << "'\", \"other\");"; + _out << eb; + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixKwd((*q)->name()); + _out << nl << "if(this." << memberName << " < ((" << name << ")other)." << memberName << ")"; + _out << sb; + _out << nl << "return -1;"; + _out << eb; + _out << nl << "if(this." << memberName << " > ((" << name << ")other)." << memberName << ")"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + } + _out << nl << "return 0;"; + _out << eb; + + _out << sp << nl << "public override int GetHashCode()"; + _out << sb; + _out << nl << "int hash = 0;"; + for(q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + string memberName = fixKwd((*q)->name()); + _out << nl << "hash = (hash << 5) ^ " << memberName << ".GetHashCode();"; + } + _out << nl << "return hash;"; + _out << eb; + + _out << sp << nl << "public override bool Equals(object other)"; + _out << sb; + _out << nl << "return CompareTo(other) == 0;"; + _out << eb; + + _out << sp << nl << "public static bool Equals(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.CompareTo(rhs) == 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator==(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator!=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return !Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator<(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs != null : lhs.CompareTo(rhs) < 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator>(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? false : lhs.CompareTo(rhs) > 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator<=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? true : lhs.CompareTo(rhs) <= 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator>=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.CompareTo(rhs) >= 0;"; + _out << eb; + + _out << eb; +} + +void +Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + string ks = typeToString(p->keyType()); + string vs = typeToString(p->valueType()); + + _out << sp << nl << "public class " << name + << " : System.Collections.DictionaryBase, System.ICloneable, System.IComparable"; + _out << sb; + + _out << nl << "public " << vs << " this[" << ks << " key]"; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "return (" << vs << ")Dictionary[key];"; + _out << eb; + + _out << nl << "set"; + _out << sb; + _out << nl << "Dictionary[key] = value;"; + _out << eb; + _out << eb; + + _out << sp << nl << "public System.Collections.ICollection Keys"; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "return Dictionary.Keys;"; + _out << eb; + _out << eb; + + _out << sp << nl << "public System.Collections.ICollection Values"; + _out << sb; + _out << nl << "get"; + _out << sb; + _out << nl << "return Dictionary.Values;"; + _out << eb; + _out << eb; + + _out << sp << nl << "public void"; + _out << nl << "Add(" << ks << " key, " << vs << " value)"; + _out << sb; + _out << nl << "Dictionary[key] = value;"; + _out << eb; + + _out << sp << nl << "public void"; + _out << nl << "Remove(" << ks << " key)"; + _out << sb; + _out << nl << "Dictionary.Remove(key);"; + _out << eb; + + _out << sp << nl << "public bool"; + _out << nl << "Contains(" << ks << " key)"; + _out << sb; + _out << nl << "return Dictionary.Contains(key);"; + _out << eb; + + _out << sp << nl << "public object"; + _out << nl << "Clone()"; + _out << sb; + _out << nl << name << " __ret = new " << name << "();"; + _out << nl << "foreach(System.Collections.DictionaryEntry __i in Dictionary)"; + _out << sb; + _out << nl << "__ret[(" << ks << ")__i.Key] = (" << vs << ")__i.Value;"; + _out << eb; + _out << nl << "return __ret;"; + _out << eb; + + _out << sp << nl << "public int CompareTo(object other)"; + _out << sb; + _out << nl << "if(other == null)"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + _out << nl << "if(object.ReferenceEquals(this, other))"; + _out << sb; + _out << nl << "return 0;"; + _out << eb; + _out << nl << "if(!(other is " << name << "))"; + _out << sb; + _out << nl << "throw new System.ArgumentException(\"CompareTo: expected argument of type `" << name + << "'\", \"other\");"; + _out << eb; + _out << nl << ks << "[] __klhs = new " << ks << "[Count];"; + _out << nl << "Keys.CopyTo(__klhs, 0);"; + _out << nl << "System.Array.Sort(__klhs);"; + _out << nl << ks << "[] __krhs = new " << ks << "[((" << name << ")other).Count];"; + _out << nl << "((" << name << ")other).Keys.CopyTo(__krhs, 0);"; + _out << nl << "System.Array.Sort(__krhs);"; + _out << nl << "int __limit = System.Math.Min(__klhs.Length, __krhs.Length);"; + _out << nl << "for(int __i = 0; __i < __limit; ++__i)"; + _out << sb; + _out << nl << "if(__klhs[__i] < __krhs[__i])"; + _out << sb; + _out << nl << "return -1;"; + _out << eb; + _out << nl << "if(__klhs[__i] > __krhs[__i])"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + _out << eb; + _out << nl << vs << "[] __vlhs = new " << vs << "[Count];"; + _out << nl << "Values.CopyTo(__vlhs, 0);"; + _out << nl << "System.Array.Sort(__vlhs);"; + _out << nl << vs << "[] __vrhs = new " << vs << "[((" << name << ")other).Count];"; + _out << nl << "((" << name << ")other).Values.CopyTo(__vrhs, 0);"; + _out << nl << "System.Array.Sort(__vrhs);"; + _out << nl << "for(int __i = 0; __i < __limit; ++__i)"; + _out << sb; + _out << nl << "if(__vlhs[__i] < __vrhs[__i])"; + _out << sb; + _out << nl << "return -1;"; + _out << eb; + _out << nl << "if(__vlhs[__i] > __vrhs[__i])"; + _out << sb; + _out << nl << "return 1;"; + _out << eb; + _out << eb; + _out << nl << "return __klhs.Length < __krhs.Length ? -1 : (__klhs.Length > __krhs.Length ? 1 : 0);"; + _out << eb; + + _out << sp << nl << "public override int GetHashCode()"; + _out << sb; + _out << nl << "int hash = 0;"; + _out << nl << "foreach(System.Collections.DictionaryEntry e in Dictionary)"; + _out << sb; + _out << nl << "hash = (hash << 5) ^ e.Key.GetHashCode();"; + _out << nl << "hash = (hash << 5) ^ e.Value.GetHashCode();"; + _out << eb; + _out << nl << "return hash;"; + _out << eb; + + _out << sp << nl << "public override bool Equals(object other)"; + _out << sb; + _out << nl << "return CompareTo(other) == 0;"; + _out << eb; + + _out << sp << nl << "public static bool Equals(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.CompareTo(rhs) == 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator==(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator!=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return !Equals(lhs, rhs);"; + _out << eb; + + _out << sp << nl << "public static bool operator<(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs != null : lhs.CompareTo(rhs) < 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator>(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? false : lhs.CompareTo(rhs) > 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator<=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? true : lhs.CompareTo(rhs) <= 0;"; + _out << eb; + + _out << sp << nl << "public static bool operator>=(" << name << " lhs, " << name << " rhs)"; + _out << sb; + _out << nl << "return lhs == null ? rhs == null : lhs.CompareTo(rhs) >= 0;"; + _out << eb; + + _out << eb; +} + +void +Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + EnumeratorList enumerators = p->getEnumerators(); + _out << sp << nl << "public enum " << name; + _out << sb; + EnumeratorList::const_iterator en = enumerators.begin(); + while(en != enumerators.end()) + { + _out << nl << fixKwd((*en)->name()); + if(++en != enumerators.end()) + { + _out << ','; + } + } + _out << eb; +} + +void +Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p) +{ + string name = fixKwd(fixGlobal(p)); + _out << sp << nl << "public class " << name; + _out << sb; + _out << sp << nl << "public const " << typeToString(p->type()) << " value = "; + BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type()); + if(bp && bp->kind() == Builtin::KindString) + { + // + // Expand strings into the basic source character set. We can't use isalpha() and the like + // here because they are sensitive to the current locale. + // + static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "_{}[]#()<>%:;,?*+=/^&|~!=,\\\"' \t"; + static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end()); + + _out << "\""; // Opening " + + ios_base::fmtflags originalFlags = _out.flags(); // Save stream state + streamsize originalWidth = _out.width(); + ostream::char_type originalFill = _out.fill(); + + const string val = p->value(); + for(string::const_iterator c = val.begin(); c != val.end(); ++c) + { + if(charSet.find(*c) == charSet.end()) + { + unsigned char uc = *c; // char may be signed, so make it positive + _out << "\\u"; // Print as unicode if not in basic source character set + _out.flags(ios_base::hex); + _out.width(4); + _out.fill('0'); + _out << static_cast<unsigned>(uc); + } + else + { + _out << *c; // Print normally if in basic source character set + } + } + + _out.fill(originalFill); // Restore stream state + _out.width(originalWidth); + _out.flags(originalFlags); + + _out << "\""; // Closing " + } + else if(bp && bp->kind() == Builtin::KindLong) + { + _out << p->value() << "L"; + } + else if(bp && bp->kind() == Builtin::KindFloat) + { + _out << p->value() << "F"; + } + else + { + EnumPtr ep = EnumPtr::dynamicCast(p->type()); + if(ep) + { + _out << fixKwd(typeToString(p->type())) << "." << fixKwd(p->value()); + } + else + { + _out << p->value(); + } + } + _out << ";"; + _out << eb; +} + +void +Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) +{ + _out << sp << nl << "public " << typeToString(p->type()) << " " << fixKwd(p->name()) << ";"; +} diff --git a/cpp/src/slice2cs/Gen.h b/cpp/src/slice2cs/Gen.h new file mode 100644 index 00000000000..b63f6dcf645 --- /dev/null +++ b/cpp/src/slice2cs/Gen.h @@ -0,0 +1,79 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#ifndef GEN_H +#define GEN_H + +#include <Slice/CsUtil.h> + +namespace Slice +{ + +class CsVisitor : public CsGenerator, public ParserVisitor +{ +public: + + CsVisitor(::IceUtil::Output&); + virtual ~CsVisitor(); + +protected: + + ::IceUtil::Output& _out; +}; + +class Gen : public ::IceUtil::noncopyable +{ +public: + + Gen(const std::string&, + const std::string&, + const std::vector<std::string>&); + ~Gen(); + + bool operator!() const; // Returns true if there was a constructor error + + void generate(const UnitPtr&); + +private: + + IceUtil::Output _out; + + std::string _base; + std::vector<std::string> _includePaths; + + void printHeader(); + + class TypesVisitor : public CsVisitor + { + public: + + TypesVisitor(::IceUtil::Output&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual void visitExceptionEnd(const ExceptionPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual void visitStructEnd(const StructPtr&); + virtual void visitSequence(const SequencePtr&); + virtual void visitDictionary(const DictionaryPtr&); + virtual void visitEnum(const EnumPtr&); + virtual void visitConst(const ConstPtr&); + virtual void visitDataMember(const DataMemberPtr&); + }; +}; + +} + +#endif diff --git a/cpp/src/slice2cs/Main.cpp b/cpp/src/slice2cs/Main.cpp new file mode 100644 index 00000000000..f2b644ce2ff --- /dev/null +++ b/cpp/src/slice2cs/Main.cpp @@ -0,0 +1,252 @@ +// ********************************************************************** +// +// Copyright (c) 2003 +// ZeroC, Inc. +// Billerica, MA, USA +// +// All Rights Reserved. +// +// Ice is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License version 2 as published by +// the Free Software Foundation. +// +// ********************************************************************** + +#include <Slice/Preprocessor.h> +#include <Gen.h> + +using namespace std; +using namespace Slice; + +void +usage(const char* n) +{ + cerr << "Usage: " << n << " [options] slice-files...\n"; + cerr << + "Options:\n" + "-h, --help Show this message.\n" + "-v, --version Display the Ice version.\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" + "--tie Generate TIE classes.\n" + "--impl Generate sample implementations.\n" + "--impl-tie Generate sample TIE implementations.\n" + "--depend Generate Makefile dependencies.\n" + "-d, --debug Print debug messages.\n" + "--ice Permit `Ice' prefix (for building Ice source code only)\n" + ; + // Note: --case-sensitive is intentionally not shown here! +} + +int +main(int argc, char* argv[]) +{ + string cppArgs; + vector<string> includePaths; + bool tie = false; + bool impl = false; + bool implTie = false; + bool debug = false; + bool ice = false; + bool caseSensitive = false; + bool depend = false; + + int idx = 1; + while(idx < argc) + { + if(strncmp(argv[idx], "-I", 2) == 0) + { + cppArgs += ' '; + cppArgs += argv[idx]; + + string path = argv[idx] + 2; + if(path.length()) + { + includePaths.push_back(path); + } + + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strncmp(argv[idx], "-D", 2) == 0 || + strncmp(argv[idx], "-U", 2) == 0) + { + cppArgs += ' '; + cppArgs += argv[idx]; + + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "-h") == 0 || + strcmp(argv[idx], "--help") == 0) + { + usage(argv[0]); + return EXIT_SUCCESS; + } + else if(strcmp(argv[idx], "-v") == 0 || + strcmp(argv[idx], "--version") == 0) + { + cout << ICE_STRING_VERSION << endl; + return EXIT_SUCCESS; + } + else if(strcmp(argv[idx], "-d") == 0 || + strcmp(argv[idx], "--debug") == 0) + { + debug = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "--ice") == 0) + { + ice = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "--case-sensitive") == 0) + { + caseSensitive = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "--tie") == 0) + { + tie = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "--impl") == 0) + { + impl = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "--impl-tie") == 0) + { + implTie = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(strcmp(argv[idx], "--depend") == 0) + { + depend = true; + for(int i = idx ; i + 1 < argc ; ++i) + { + argv[i] = argv[i + 1]; + } + --argc; + } + else if(argv[idx][0] == '-') + { + cerr << argv[0] << ": unknown option `" << argv[idx] << "'" + << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + else + { + ++idx; + } + } + + if(argc < 2) + { + cerr << argv[0] << ": no input file" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + if(impl && implTie) + { + cerr << argv[0] << ": cannot specify both --impl and --impl-tie" << endl; + usage(argv[0]); + return EXIT_FAILURE; + } + + int status = EXIT_SUCCESS; + + for(idx = 1 ; idx < argc ; ++idx) + { + if(depend) + { + Preprocessor icecpp(argv[0], argv[idx], cppArgs); + icecpp.printMakefileDependencies(); + } + else + { + Preprocessor icecpp(argv[0], argv[idx], cppArgs); + FILE* cppHandle = icecpp.preprocess(false); + + if(cppHandle == 0) + { + return EXIT_FAILURE; + } + + UnitPtr p = Unit::createUnit(false, false, ice, caseSensitive); + int parseStatus = p->parse(cppHandle, debug); + + if(!icecpp.close()) + { + return EXIT_FAILURE; + } + + if(parseStatus == EXIT_FAILURE) + { + status = EXIT_FAILURE; + } + else + { + Gen gen(argv[0], icecpp.getBaseName(), includePaths); + if(!gen) + { + p->destroy(); + return EXIT_FAILURE; + } + gen.generate(p); +#if 0 + if(tie) + { + gen.generateTie(p); + } + if(impl) + { + gen.generateImpl(p); + } + if(implTie) + { + gen.generateImplTie(p); + } +#endif + } + + p->destroy(); + } + } + + return status; +} diff --git a/cpp/src/slice2cs/Makefile b/cpp/src/slice2cs/Makefile new file mode 100644 index 00000000000..fefd659a3e0 --- /dev/null +++ b/cpp/src/slice2cs/Makefile @@ -0,0 +1,37 @@ +# ********************************************************************** +# +# Copyright (c) 2003 +# ZeroC, Inc. +# Billerica, MA, USA +# +# All Rights Reserved. +# +# Ice is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License version 2 as published by +# the Free Software Foundation. +# +# ********************************************************************** + +top_srcdir = ../.. + +NAME = $(top_srcdir)/bin/slice2cs + +TARGETS = $(NAME) + +OBJS = Gen.o \ + Main.o + +SRCS = $(OBJS:.o=.cpp) + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. $(CPPFLAGS) + +$(NAME): $(OBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) -lSlice $(BASELIBS) + +install:: all + $(INSTALL_PROGRAM) $(NAME) $(install_bindir) + +include .depend diff --git a/cpp/src/slice2cs/slice2cs.dsp b/cpp/src/slice2cs/slice2cs.dsp new file mode 100644 index 00000000000..513aff1e4a3 --- /dev/null +++ b/cpp/src/slice2cs/slice2cs.dsp @@ -0,0 +1,126 @@ +# Microsoft Developer Studio Project File - Name="slice2cs" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=slice2cs - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "slice2cs.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "slice2cs.mak" CFG="slice2cs - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "slice2cs - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "slice2cs - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "slice2cs - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I "." /I "../../include" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /machine:I386 /libpath:"../../lib"
+# SUBTRACT LINK32 /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=slice2cs
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "slice2cs - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I "." /I "../../include" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../lib"
+# SUBTRACT LINK32 /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=slice2cs
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "slice2cs - Win32 Release"
+# Name "slice2cs - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Gen.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Main.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Gen.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
|