diff options
author | Mark Spruiell <mes@zeroc.com> | 2009-01-15 14:45:04 -0800 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2009-01-15 14:45:04 -0800 |
commit | cd75146bcf4be80cbd8b1a541e1e4dda4828a463 (patch) | |
tree | 7d9b5152c47a2ad8c6c7b0ab126f579a19102e9b /php/src/IcePHP/Profile.cpp | |
parent | - Fixed errorDetection test (diff) | |
download | ice-cd75146bcf4be80cbd8b1a541e1e4dda4828a463.tar.bz2 ice-cd75146bcf4be80cbd8b1a541e1e4dda4828a463.tar.xz ice-cd75146bcf4be80cbd8b1a541e1e4dda4828a463.zip |
- bug 3566 - PHP redefinition errors
- suppressing Slice warnings in PHP slicing/objects test
Diffstat (limited to 'php/src/IcePHP/Profile.cpp')
-rw-r--r-- | php/src/IcePHP/Profile.cpp | 291 |
1 files changed, 187 insertions, 104 deletions
diff --git a/php/src/IcePHP/Profile.cpp b/php/src/IcePHP/Profile.cpp index e9119c44df6..e0ffef78661 100644 --- a/php/src/IcePHP/Profile.cpp +++ b/php/src/IcePHP/Profile.cpp @@ -316,7 +316,7 @@ static const char* _coreTypes = // Parse the Slice files that define the types and operations available to a PHP script. // static bool -parseSlice(const string& argStr, Slice::UnitPtr& unit, bool& suppressWarnings TSRMLS_DC) +parseSlice(const string& argStr, vector<Slice::UnitPtr>& units, bool& suppressWarnings TSRMLS_DC) { vector<string> args; try @@ -397,36 +397,34 @@ parseSlice(const string& argStr, Slice::UnitPtr& unit, bool& suppressWarnings TS bool ignoreRedefs = false; bool all = true; - unit = Slice::Unit::createUnit(ignoreRedefs, all, ice, caseSensitive); - bool status = true; for(vector<string>::iterator p = files.begin(); p != files.end(); ++p) { + Slice::UnitPtr unit = Slice::Unit::createUnit(ignoreRedefs, all, ice, caseSensitive); Slice::Preprocessor icecpp("icecpp", *p, cppArgs); FILE* cppHandle = icecpp.preprocess(false); if(cppHandle == 0) { - status = false; - break; + return false; } int parseStatus = unit->parse(*p, cppHandle, debug); if(!icecpp.close()) { - status = false; - break; + return false; } if(parseStatus == EXIT_FAILURE) { - status = false; - break; + return false; } + + units.push_back(unit); } - return status; + return true; } static bool @@ -476,98 +474,100 @@ createProfile(const string& name, const string& config, const string& options, c properties->parseCommandLineOptions("", args); } - Slice::UnitPtr unit; - bool suppressWarnings = false; - if(!slice.empty()) - { - if(!parseSlice(slice, unit, suppressWarnings TSRMLS_CC)) - { - return false; - } - } - else - { - // - // We must be allowed to obtain builtin types, as well as create Ice::Identity if necessary. - // - unit = Slice::Unit::createUnit(false, false, true, false); - } + // + // We create a Unit for each Slice file. + // + vector<Slice::UnitPtr> units; // - // Create the Slice definition for Ice::Identity if it doesn't exist. The PHP class will - // be created automatically by CodeVisitor. + // Even if the profile specifies no Slice files, we still need to obtain builtin + // types as well as create types such as Ice::Identity. // - string scoped = "::Ice::Identity"; - Slice::TypeList l = unit->lookupTypeNoBuiltin(scoped, false); - if(l.empty()) { - Slice::ContainedList c = unit->lookupContained("Ice", false); - Slice::ModulePtr module; - if(c.empty()) - { - module = unit->createModule("Ice"); - } - else + Slice::UnitPtr unit = Slice::Unit::createUnit(false, false, true, false); + + // + // Create the Slice definition for Ice::Identity if it doesn't exist. The PHP class will + // be created automatically by CodeVisitor. + // + string scoped = "::Ice::Identity"; + Slice::TypeList l = unit->lookupTypeNoBuiltin(scoped, false); + if(l.empty()) { - module = Slice::ModulePtr::dynamicCast(c.front()); - if(!module) + Slice::ContainedList c = unit->lookupContained("Ice", false); + Slice::ModulePtr module; + if(c.empty()) + { + module = unit->createModule("Ice"); + } + else { - php_error_docref(0 TSRMLS_CC, E_ERROR, "the symbol `::Ice' is defined in Slice but is not a module"); - return false; + module = Slice::ModulePtr::dynamicCast(c.front()); + if(!module) + { + php_error_docref(0 TSRMLS_CC, E_ERROR, + "the symbol `::Ice' is defined in Slice but is not a module"); + return false; + } } + Slice::StructPtr identity = module->createStruct("Identity", false); + Slice::TypePtr str = unit->builtin(Slice::Builtin::KindString); + identity->createDataMember("category", str); + identity->createDataMember("name", str); } - Slice::StructPtr identity = module->createStruct("Identity", false); - Slice::TypePtr str = unit->builtin(Slice::Builtin::KindString); - identity->createDataMember("category", str); - identity->createDataMember("name", str); - } - // - // Create the Slice definition for Ice::EndpointSelectionType if it doesn't exist. The PHP class will - // be created automatically by CodeVisitor. - // - scoped = "::Ice::EndpointSelectionType"; - l = unit->lookupTypeNoBuiltin(scoped, false); - if(l.empty()) - { - Slice::ContainedList c = unit->lookupContained("Ice", false); - Slice::ModulePtr module; - if(c.empty()) - { - module = unit->createModule("Ice"); - } - else + // + // Create the Slice definition for Ice::EndpointSelectionType if it doesn't exist. The PHP class will + // be created automatically by CodeVisitor. + // + scoped = "::Ice::EndpointSelectionType"; + l = unit->lookupTypeNoBuiltin(scoped, false); + if(l.empty()) { - module = Slice::ModulePtr::dynamicCast(c.front()); - if(!module) + Slice::ContainedList c = unit->lookupContained("Ice", false); + Slice::ModulePtr module; + if(c.empty()) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "the symbol `::Ice' is defined in Slice but is not a module"); - return false; + module = unit->createModule("Ice"); } + else + { + module = Slice::ModulePtr::dynamicCast(c.front()); + if(!module) + { + php_error_docref(0 TSRMLS_CC, E_ERROR, + "the symbol `::Ice' is defined in Slice but is not a module"); + return false; + } + } + Slice::EnumPtr en = module->createEnum("EndpointSelectionType", false); + Slice::EnumeratorList el; + el.push_back(module->createEnumerator("Random")); + el.push_back(module->createEnumerator("Ordered")); + en->setEnumerators(el); } - Slice::EnumPtr en = module->createEnum("EndpointSelectionType", false); - Slice::EnumeratorList el; - el.push_back(module->createEnumerator("Random")); - el.push_back(module->createEnumerator("Ordered")); - en->setEnumerators(el); + + units.push_back(unit); + } + + bool suppressWarnings = false; + if(!slice.empty() && !parseSlice(slice, units, suppressWarnings TSRMLS_CC)) + { + return false; } // - // Descend the parse tree to create PHP code. + // Descend the parse trees to generate PHP code. // ostringstream out; Profile::ClassMap classes; - CodeVisitor visitor(out, classes, suppressWarnings TSRMLS_CC); - unit->visit(&visitor, false); - - Profile* profile = new Profile; - profile->name = name; - profile->unit = unit; - profile->code = out.str(); - profile->classes = classes; - profile->properties = properties; + for(vector<Slice::UnitPtr>::const_iterator q = units.begin(); q != units.end(); ++ q) + { + CodeVisitor visitor(out, classes, suppressWarnings TSRMLS_CC); + (*q)->visit(&visitor, false); + } - _profiles[name] = profile; + _profiles[name] = new Profile(name, units, out.str(), classes, properties); return true; } @@ -722,9 +722,83 @@ IcePHP::profileShutdown(TSRMLS_D) { for(map<string, Profile*>::iterator p = _profiles.begin(); p != _profiles.end(); ++p) { + p->second->destroy(TSRMLS_C); + delete p->second; + } + + _profiles.clear(); + + return true; +} + +IcePHP::Profile::Profile(const string& name, const vector<Slice::UnitPtr>& units, const string& code, + const ClassMap& classes, const Ice::PropertiesPtr& properties) : + _name(name), _units(units), _code(code), _classes(classes), _properties(properties) +{ +} + +string +IcePHP::Profile::name() const +{ + return _name; +} + +string +IcePHP::Profile::code() const +{ + return _code; +} + +const IcePHP::Profile::ClassMap& +IcePHP::Profile::classes() const +{ + return _classes; +} + +Ice::PropertiesPtr +IcePHP::Profile::properties() const +{ + return _properties; +} + +Slice::TypePtr +IcePHP::Profile::lookupType(const string& id) const +{ + for(vector<Slice::UnitPtr>::const_iterator p = _units.begin(); p != _units.end(); ++p) + { + Slice::TypeList l = (*p)->lookupType(id, false); + if(!l.empty()) + { + return l.front(); + } + } + + return 0; +} + +Slice::ExceptionPtr +IcePHP::Profile::lookupException(const string& id) const +{ + for(vector<Slice::UnitPtr>::const_iterator p = _units.begin(); p != _units.end(); ++p) + { + Slice::ExceptionPtr ex = (*p)->lookupException(id, false); + if(ex) + { + return ex; + } + } + + return 0; +} + +void +IcePHP::Profile::destroy(TSRMLS_D) +{ + for(vector<Slice::UnitPtr>::iterator p = _units.begin(); p != _units.end(); ++p) + { try { - p->second->unit->destroy(); + (*p)->destroy(); } catch(const IceUtil::Exception& ex) { @@ -733,13 +807,7 @@ IcePHP::profileShutdown(TSRMLS_D) php_error_docref(0 TSRMLS_CC, E_ERROR, "error while destroying Slice parse tree:\n%s\n", ostr.str().c_str()); } - - delete p->second; } - - _profiles.clear(); - - return true; } static bool @@ -814,9 +882,9 @@ do_load(const string& name, const Ice::StringSeq& args TSRMLS_DC) // // Compile the user-defined types. // - if(zend_eval_string(const_cast<char*>(profile->code.c_str()), 0, "__slice" TSRMLS_CC) == FAILURE) + if(zend_eval_string(const_cast<char*>(profile->code().c_str()), 0, "__slice" TSRMLS_CC) == FAILURE) { - php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create Slice types:\n%s\n", profile->code.c_str()); + php_error_docref(0 TSRMLS_CC, E_ERROR, "unable to create Slice types:\n%s\n", profile->code().c_str()); return false; } @@ -824,7 +892,7 @@ do_load(const string& name, const Ice::StringSeq& args TSRMLS_DC) // Make a copy of the profile's properties, and include any command-line arguments. // Ice::PropertiesPtr properties = Ice::createProperties(); - properties->parseCommandLineOptions("", profile->properties->getCommandLineOptions()); + properties->parseCommandLineOptions("", profile->properties()->getCommandLineOptions()); properties->parseCommandLineOptions("", args); ICE_G(properties) = new Ice::PropertiesPtr(properties); @@ -923,7 +991,7 @@ ZEND_FUNCTION(Ice_dumpProfile) } ostringstream out; - out << "Ice profile: " << profile->name << endl; + out << "Ice profile: " << profile->name() << endl; Ice::PropertyDict props = (*properties)->getPropertiesForPrefix(""); if(!props.empty()) @@ -939,10 +1007,11 @@ ZEND_FUNCTION(Ice_dumpProfile) out << endl << "Ice configuration properties: <none>" << endl; } - if(!profile->code.empty()) + string code = profile->code(); + if(!code.empty()) { out << endl << "PHP code for Slice types:" << endl << endl; - out << profile->code; + out << code; } else { @@ -986,6 +1055,8 @@ IcePHP::CodeVisitor::visitClassDefStart(const Slice::ClassDefPtr& p) if(p->isInterface()) { + _out << "if(!interface_exists(\"" << flat << "\"))" << endl; + _out << "{" << endl; _out << "interface " << flat; if(!bases.empty()) { @@ -1006,6 +1077,8 @@ IcePHP::CodeVisitor::visitClassDefStart(const Slice::ClassDefPtr& p) } else { + _out << "if(!class_exists(\"" << flat << "\"))" << endl; + _out << "{" << endl; if(p->isAbstract()) { _out << "abstract "; @@ -1097,6 +1170,7 @@ void IcePHP::CodeVisitor::visitClassDefEnd(const Slice::ClassDefPtr& p) { _out << '}' << endl; + _out << '}' << endl; // interface_exists/class_exists } bool @@ -1105,6 +1179,8 @@ IcePHP::CodeVisitor::visitExceptionStart(const Slice::ExceptionPtr& p) string flat = flatten(p->scoped()); Slice::ExceptionPtr base = p->base(); + _out << "if(!class_exists(\"" << flat << "\"))" << endl; + _out << "{" << endl; _out << "class " << flat << " extends "; string baseName; if(!base) @@ -1169,6 +1245,7 @@ void IcePHP::CodeVisitor::visitExceptionEnd(const Slice::ExceptionPtr& p) { _out << '}' << endl; + _out << '}' << endl; // class_exists } bool @@ -1176,6 +1253,8 @@ IcePHP::CodeVisitor::visitStructStart(const Slice::StructPtr& p) { string flat = flatten(p->scoped()); + _out << "if(!class_exists(\"" << flat << "\"))" << endl; + _out << "{" << endl; _out << "class " << flatten(p->scoped()) << endl; _out << '{' << endl; @@ -1208,6 +1287,7 @@ void IcePHP::CodeVisitor::visitStructEnd(const Slice::StructPtr& p) { _out << '}' << endl; + _out << '}' << endl; // class_exists } void @@ -1283,6 +1363,8 @@ IcePHP::CodeVisitor::visitEnum(const Slice::EnumPtr& p) { string flat = flatten(p->scoped()); + _out << "if(!class_exists(\"" << flat << "\"))" << endl; + _out << "{" << endl; _out << "class " << flat << endl; _out << '{' << endl; @@ -1299,6 +1381,7 @@ IcePHP::CodeVisitor::visitEnum(const Slice::EnumPtr& p) } _out << '}' << endl; + _out << '}' << endl; // class_exists } void @@ -1308,9 +1391,12 @@ IcePHP::CodeVisitor::visitConst(const Slice::ConstPtr& p) Slice::TypePtr type = p->type(); string value = p->value(); + _out << "if(!defined(\"" << flat << "\"))" << endl; + _out << "{" << endl; _out << "define(\"" << flat << "\", "; Slice::BuiltinPtr b = Slice::BuiltinPtr::dynamicCast(type); + Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type); if(b) { switch(b->kind()) @@ -1400,13 +1486,8 @@ IcePHP::CodeVisitor::visitConst(const Slice::ConstPtr& p) case Slice::Builtin::KindLocalObject: assert(false); } - - _out << ");" << endl; - return; } - - Slice::EnumPtr en = Slice::EnumPtr::dynamicCast(type); - if(en) + else if(en) { string::size_type colon = value.rfind(':'); if(colon != string::npos) @@ -1419,12 +1500,14 @@ IcePHP::CodeVisitor::visitConst(const Slice::ConstPtr& p) { if((*q)->name() == value) { - _out << flatten(en->scoped()) << "::" << fixIdent(value) << ");" << endl; - return; + _out << flatten(en->scoped()) << "::" << fixIdent(value); + break; } } - assert(false); // No match found. } + + _out << ");" << endl; + _out << "}" << endl; // defined } string |