From 471dd0d96d4b07b7990e38b00d2a0b5d5bc179bb Mon Sep 17 00:00:00 2001 From: paulc Date: Fri, 3 Jun 2011 12:26:53 +0000 Subject: [PATCH] New YSTRING macro that creates an ad-hoc static const String to speed up comparations and conversions from literal strings. On unsupported compilers the literal string is returned unchanged. git-svn-id: http://voip.null.ro/svn/yate@4423 acf43c95-373e-0410-b603-e72c3f656dc1 --- configure.in | 17 +++++- engine/Array.cpp | 2 +- engine/Channel.cpp | 136 +++++++++++++++++++++--------------------- engine/Cipher.cpp | 2 +- engine/DataBlock.cpp | 20 +++---- engine/DataFormat.cpp | 8 +-- engine/Evaluator.cpp | 4 +- engine/HashList.cpp | 2 +- engine/Message.cpp | 2 +- engine/Mime.cpp | 12 ++-- engine/NamedList.cpp | 2 +- engine/ObjList.cpp | 2 +- engine/Plugin.cpp | 2 +- engine/Socket.cpp | 2 +- engine/String.cpp | 6 +- yateclass.h | 27 ++++++--- 16 files changed, 137 insertions(+), 109 deletions(-) diff --git a/configure.in b/configure.in index 0813ff79..9b2e6e86 100644 --- a/configure.in +++ b/configure.in @@ -90,6 +90,21 @@ AC_TRY_LINK([],[],[ld_unresolved_symbols=yes],[GCC_UNRESOLVED_SYMBOLS=""]) CFLAGS="$SAVE_CFLAGS" AC_MSG_RESULT([$ld_unresolved_symbols]) +# Check if { instruction } blocks can return a value +HAVE_BLOCK_RETURN=no +AC_ARG_ENABLE(strings,AC_HELP_STRING([--enable-strings],[Create static Strings (default: yes)]),want_strings=$enableval,want_strings=yes) +if [[ "x$want_strings" = "xyes" ]]; then +AC_MSG_CHECKING([if instruction blocks return values]) +AC_TRY_COMPILE([],[return ({static int ret = 1; ret;});],HAVE_BLOCK_RETURN="yes") +AC_MSG_RESULT([$HAVE_BLOCK_RETURN]) +fi +if [[ "x$HAVE_BLOCK_RETURN" = "xyes" ]]; then +HAVE_BLOCK_RETURN="-DHAVE_BLOCK_RETURN" +else +HAVE_BLOCK_RETURN="" +fi +AC_SUBST(HAVE_BLOCK_RETURN) + # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC @@ -1239,7 +1254,7 @@ fi INSTALL_D="install -D" CFLAGS=`echo "$CFLAGS" | sed 's/\(^\| *\)-g[[0-9]]*//' | sed 's/[[[:space:]]]\{2,\}/ /g'` -MODULE_CFLAGS="-fno-exceptions -fPIC $HAVE_GCC_FORMAT_CHECK" +MODULE_CFLAGS="-fno-exceptions -fPIC $HAVE_GCC_FORMAT_CHECK $HAVE_BLOCK_RETURN" MODULE_CPPFLAGS="-fno-check-new $RTTI_OPT $MODULE_CFLAGS" MODULE_LDRELAX="-export-dynamic -shared" MODULE_SYMBOLS="-Wl,--retain-symbols-file,/dev/null" diff --git a/engine/Array.cpp b/engine/Array.cpp index bae51ab7..c984d042 100644 --- a/engine/Array.cpp +++ b/engine/Array.cpp @@ -52,7 +52,7 @@ Array::~Array() void* Array::getObject(const String& name) const { - if (name == "Array") + if (name == YSTRING("Array")) return const_cast(this); return RefObject::getObject(name); } diff --git a/engine/Channel.cpp b/engine/Channel.cpp index 8a04af49..06c3ac09 100644 --- a/engine/Channel.cpp +++ b/engine/Channel.cpp @@ -93,7 +93,7 @@ Mutex& CallEndpoint::commonMutex() void* CallEndpoint::getObject(const String& name) const { - if (name == "CallEndpoint") + if (name == YSTRING("CallEndpoint")) return const_cast(this); return RefObject::getObject(name); } @@ -348,9 +348,9 @@ Channel::~Channel() void* Channel::getObject(const String& name) const { - if (name == "Channel") + if (name == YSTRING("Channel")) return const_cast(this); - if (name == "MessageNotifier") + if (name == YSTRING("MessageNotifier")) return static_cast(const_cast(this)); return CallEndpoint::getObject(name); } @@ -502,7 +502,7 @@ void Channel::status(const char* newstat) { Lock lock(mutex()); m_status = newstat; - if (!m_answered && (m_status == "answered")) { + if (!m_answered && (m_status == YSTRING("answered"))) { m_maxcall = 0; m_answered = true; } @@ -515,13 +515,13 @@ const char* Channel::direction() const void Channel::setMaxcall(const Message* msg) { - int tout = msg ? msg->getIntValue("maxcall") : 0; + int tout = msg ? msg->getIntValue(YSTRING("maxcall")) : 0; if (tout > 0) maxcall(Time::now() + tout*(u_int64_t)1000); else maxcall(0); if (msg) { - tout = msg->getIntValue("timeout",-1); + tout = msg->getIntValue(YSTRING("timeout"),-1); if (tout > 0) timeout(Time::now() + tout*(u_int64_t)1000); else if (tout == 0) @@ -572,7 +572,7 @@ Message* Channel::message(const char* name, const NamedList* original, const cha Message* msg = message(name,minimal,data); if (original) { if (!params) - params = original->getValue("copyparams"); + params = original->getValue(YSTRING("copyparams")); if (!null(params)) msg->copyParams(*original,params); } @@ -602,7 +602,7 @@ bool Channel::msgProgress(Message& msg) { status("progressing"); if (m_billid.null()) - m_billid = msg.getValue("billid"); + m_billid = msg.getValue(YSTRING("billid")); return true; } @@ -610,7 +610,7 @@ bool Channel::msgRinging(Message& msg) { status("ringing"); if (m_billid.null()) - m_billid = msg.getValue("billid"); + m_billid = msg.getValue(YSTRING("billid")); return true; } @@ -620,7 +620,7 @@ bool Channel::msgAnswered(Message& msg) m_answered = true; status("answered"); if (m_billid.null()) - m_billid = msg.getValue("billid"); + m_billid = msg.getValue(YSTRING("billid")); return true; } @@ -655,21 +655,21 @@ bool Channel::msgUpdate(Message& msg) bool Channel::msgMasquerade(Message& msg) { if (m_billid.null()) - m_billid = msg.getValue("billid"); - if (msg == "call.answered") { + m_billid = msg.getValue(YSTRING("billid")); + if (msg == YSTRING("call.answered")) { Debug(this,DebugInfo,"Masquerading answer operation [%p]",this); m_maxcall = 0; m_status = "answered"; } - else if (msg == "call.progress") { + else if (msg == YSTRING("call.progress")) { Debug(this,DebugInfo,"Masquerading progress operation [%p]",this); status("progressing"); } - else if (msg == "call.ringing") { + else if (msg == YSTRING("call.ringing")) { Debug(this,DebugInfo,"Masquerading ringing operation [%p]",this); status("ringing"); } - else if (msg == "chan.dtmf") { + else if (msg == YSTRING("chan.dtmf")) { // add sequence, stop the message if it was a disallowed DTMF duplicate if (dtmfSequence(msg) && m_driver && !m_driver->m_dtmfDups) { Debug(this,DebugNote,"Stopping duplicate '%s' DTMF '%s' [%p]", @@ -748,7 +748,7 @@ bool Channel::callPrerouted(Message& msg, bool handled) { status("prerouted"); // accept a new billid at this stage - String* str = msg.getParam("billid"); + String* str = msg.getParam(YSTRING("billid")); if (str) m_billid = *str; return true; @@ -758,7 +758,7 @@ bool Channel::callRouted(Message& msg) { status("routed"); if (m_billid.null()) - m_billid = msg.getValue("billid"); + m_billid = msg.getValue(YSTRING("billid")); return true; } @@ -769,21 +769,21 @@ void Channel::callAccept(Message& msg) if (tout > 0) timeout(Time::now() + tout*(u_int64_t)1000); if (m_billid.null()) - m_billid = msg.getValue("billid"); - m_targetid = msg.getValue("targetid"); - String detect = msg.getValue("tonedetect_in"); + m_billid = msg.getValue(YSTRING("billid")); + m_targetid = msg.getValue(YSTRING("targetid")); + String detect = msg.getValue(YSTRING("tonedetect_in")); if (detect && detect.toBoolean(true)) { if (detect.toBoolean(false)) detect = "tone/*"; toneDetect(detect); } - if (msg.getBoolValue("autoanswer")) + if (msg.getBoolValue(YSTRING("autoanswer"))) msgAnswered(msg); - else if (msg.getBoolValue("autoring")) + else if (msg.getBoolValue(YSTRING("autoring"))) msgRinging(msg); - else if (msg.getBoolValue("autoprogress")) + else if (msg.getBoolValue(YSTRING("autoprogress"))) msgProgress(msg); - else if (m_targetid.null() && msg.getBoolValue("autoanswer",true)) { + else if (m_targetid.null() && msg.getBoolValue(YSTRING("autoanswer"),true)) { // no preference exists in the message so issue a notice Debug(this,DebugNote,"Answering now call %s because we have no targetid [%p]", id().c_str(),this); @@ -793,7 +793,7 @@ void Channel::callAccept(Message& msg) void Channel::callConnect(Message& msg) { - String detect = msg.getValue("tonedetect_out"); + String detect = msg.getValue(YSTRING("tonedetect_out")); if (detect && detect.toBoolean(true)) { if (detect.toBoolean(false)) detect = "tone/*"; @@ -809,11 +809,11 @@ void Channel::callRejected(const char* error, const char* reason, const Message* bool Channel::dtmfSequence(Message& msg) { - if ((msg != "chan.dtmf") || msg.getParam("sequence")) + if ((msg != YSTRING("chan.dtmf")) || msg.getParam(YSTRING("sequence"))) return false; bool duplicate = false; - const String* detected = msg.getParam("detected"); - const String* text = msg.getParam("text"); + const String* detected = msg.getParam(YSTRING("detected")); + const String* text = msg.getParam(YSTRING("text")); Lock lock(mutex()); unsigned int seq = m_dtmfSeq; if (text && detected && @@ -945,7 +945,7 @@ Module::~Module() void* Module::getObject(const String& name) const { - if (name == "Module") + if (name == YSTRING("Module")) return const_cast(this); return Plugin::getObject(name); } @@ -1065,11 +1065,11 @@ bool Module::msgRoute(Message& msg) bool Module::msgCommand(Message& msg) { - const NamedString* line = msg.getParam("line"); + const NamedString* line = msg.getParam(YSTRING("line")); if (line) return commandExecute(msg.retValue(),*line); - if (msg.getParam("partline") || msg.getParam("partword")) - return commandComplete(msg,msg.getValue("partline"),msg.getValue("partword")); + if (msg.getParam(YSTRING("partline")) || msg.getParam(YSTRING("partword"))) + return commandComplete(msg,msg.getValue(YSTRING("partline")),msg.getValue(YSTRING("partword"))); return false; } @@ -1080,7 +1080,7 @@ bool Module::commandExecute(String& retVal, const String& line) bool Module::commandComplete(Message& msg, const String& partLine, const String& partWord) { - if ((partLine == "debug") || (partLine == "status")) + if ((partLine == YSTRING("debug")) || (partLine == YSTRING("status"))) itemComplete(msg.retValue(),name(),partWord); return false; } @@ -1097,7 +1097,7 @@ bool Module::itemComplete(String& itemList, const String& item, const String& pa void Module::msgStatus(Message& msg) { String mod, par, det; - bool details = msg.getBoolValue("details",true); + bool details = msg.getBoolValue(YSTRING("details"),true); lock(); statusModule(mod); statusParams(par); @@ -1144,7 +1144,7 @@ bool Module::received(Message &msg, int id) return msgRoute(msg); } - String dest = msg.getValue("module"); + String dest = msg.getValue(YSTRING("module")); if (id == Status) { if (dest == name()) { @@ -1212,7 +1212,7 @@ Driver::Driver(const char* name, const char* type) void* Driver::getObject(const String& name) const { - if (name == "Driver") + if (name == YSTRING("Driver")) return const_cast(this); return Module::getObject(name); } @@ -1282,7 +1282,7 @@ bool Driver::received(Message &msg, int id) } case Status: // check if it's a channel status request - dest = msg.getValue("module"); + dest = msg.getValue(YSTRING("module")); if (dest.startsWith(m_prefix)) break; case Level: @@ -1293,18 +1293,18 @@ bool Driver::received(Message &msg, int id) dropAll(msg); return false; case Execute: - dest = msg.getValue("callto"); + dest = msg.getValue(YSTRING("callto")); break; case Drop: case Masquerade: case Locate: - dest = msg.getValue("id"); + dest = msg.getValue(YSTRING("id")); break; default: - dest = msg.getValue("peerid"); + dest = msg.getValue(YSTRING("peerid")); // if this channel is not the peer, try to match it as target if (!dest.startsWith(m_prefix)) - dest = msg.getValue("targetid"); + dest = msg.getValue(YSTRING("targetid")); break; } XDebug(DebugAll,"id=%d prefix='%s' dest='%s'",id,m_prefix.c_str(),dest.c_str()); @@ -1322,7 +1322,7 @@ bool Driver::received(Message &msg, int id) if (!canAccept(false)) return false; if (dest.startSkip(m_prefix,false) || - (dest.startSkip("line/",false) && hasLine(msg.getValue("line")))) + (dest.startSkip("line/",false) && hasLine(msg.getValue(YSTRING("line"))))) return msgExecute(msg,dest); return false; } @@ -1360,8 +1360,8 @@ bool Driver::received(Message &msg, int id) case Update: return chan->msgUpdate(msg); case Masquerade: - msg = msg.getValue("message"); - msg.clearParam("message"); + msg = msg.getValue(YSTRING("message")); + msg.clearParam(YSTRING("message")); msg.userData(chan); if (chan->msgMasquerade(msg)) return true; @@ -1378,7 +1378,7 @@ bool Driver::received(Message &msg, int id) void Driver::dropAll(Message &msg) { - const char* reason = msg.getValue("reason"); + const char* reason = msg.getValue(YSTRING("reason")); lock(); ListIterator iter(m_chans); for (;;) { @@ -1423,12 +1423,12 @@ bool Driver::hasLine(const String& line) const bool Driver::msgRoute(Message& msg) { - String called = msg.getValue("called"); + String called = msg.getValue(YSTRING("called")); if (called.null()) return false; - String line = msg.getValue("line"); + String line = msg.getValue(YSTRING("line")); if (line.null()) - line = msg.getValue("account"); + line = msg.getValue(YSTRING("account")); if (line && hasLine(line)) { // asked to route to a line we have locally msg.setParam("line",line); @@ -1473,7 +1473,7 @@ void Driver::statusDetail(String& str) bool Driver::commandComplete(Message& msg, const String& partLine, const String& partWord) { bool ok = false; - bool listChans = String(msg.getValue("complete")) == "channels"; + bool listChans = String(msg.getValue(YSTRING("complete"))) == YSTRING("channels"); if (listChans && (partWord.null() || name().startsWith(partWord))) msg.retValue().append(name(),"\t"); else @@ -1515,10 +1515,10 @@ bool Driver::setDebug(Message& msg, const String& target) void Driver::loadLimits() { - timeout(Engine::config().getIntValue("telephony","timeout")); - maxRoute(Engine::config().getIntValue("telephony","maxroute")); - maxChans(Engine::config().getIntValue("telephony","maxchans")); - dtmfDups(Engine::config().getBoolValue("telephony","dtmfdups")); + timeout(Engine::config().getIntValue(YSTRING("telephony"),"timeout")); + maxRoute(Engine::config().getIntValue(YSTRING("telephony"),"maxroute")); + maxChans(Engine::config().getIntValue(YSTRING("telephony"),"maxchans")); + dtmfDups(Engine::config().getBoolValue(YSTRING("telephony"),"dtmfdups")); } unsigned int Driver::nextid() @@ -1555,12 +1555,12 @@ bool Router::route() DDebug(m_driver,DebugAll,"Routing thread for '%s' [%p]",m_id.c_str(),this); RefPointer chan; - String tmp(m_msg->getValue("callto")); + String tmp(m_msg->getValue(YSTRING("callto"))); bool ok = !tmp.null(); if (ok) m_msg->retValue() = tmp; else { - if (*m_msg == "call.preroute") { + if (*m_msg == YSTRING("call.preroute")) { ok = Engine::dispatch(m_msg); m_driver->lock(); chan = m_driver->find(m_id); @@ -1569,10 +1569,10 @@ bool Router::route() Debug(m_driver,DebugInfo,"Connection '%s' vanished while prerouting!",m_id.c_str()); return false; } - bool dropCall = ok && ((m_msg->retValue() == "-") || (m_msg->retValue() == "error")); + bool dropCall = ok && ((m_msg->retValue() == YSTRING("-")) || (m_msg->retValue() == YSTRING("error"))); if (dropCall) - chan->callRejected(m_msg->getValue("error","unknown"), - m_msg->getValue("reason"),m_msg); + chan->callRejected(m_msg->getValue(YSTRING("error"),"unknown"), + m_msg->getValue(YSTRING("reason")),m_msg); else dropCall = !chan->callPrerouted(*m_msg,ok); if (dropCall) { @@ -1600,23 +1600,23 @@ bool Router::route() m_msg->userData(chan); if (ok) { - if ((m_msg->retValue() == "-") || (m_msg->retValue() == "error")) - chan->callRejected(m_msg->getValue("error","unknown"), + if ((m_msg->retValue() == YSTRING("-")) || (m_msg->retValue() == YSTRING("error"))) + chan->callRejected(m_msg->getValue(YSTRING("error"),"unknown"), m_msg->getValue("reason"),m_msg); - else if (m_msg->getIntValue("antiloop",1) <= 0) - chan->callRejected(m_msg->getValue("error","looping"), - m_msg->getValue("reason","Call is looping"),m_msg); + else if (m_msg->getIntValue(YSTRING("antiloop"),1) <= 0) + chan->callRejected(m_msg->getValue(YSTRING("error"),"looping"), + m_msg->getValue(YSTRING("reason"),"Call is looping"),m_msg); else if (chan->callRouted(*m_msg)) { *m_msg = "call.execute"; m_msg->setParam("callto",m_msg->retValue()); - m_msg->clearParam("error"); + m_msg->clearParam(YSTRING("error")); m_msg->retValue().clear(); ok = Engine::dispatch(m_msg); if (ok) chan->callAccept(*m_msg); else { - const char* error = m_msg->getValue("error","noconn"); - const char* reason = m_msg->getValue("reason","Could not connect to target"); + const char* error = m_msg->getValue(YSTRING("error"),"noconn"); + const char* reason = m_msg->getValue(YSTRING("reason"),"Could not connect to target"); Message m(s_disconnected); chan->complete(m); m.setParam("error",error); @@ -1630,8 +1630,8 @@ bool Router::route() } } else - chan->callRejected(m_msg->getValue("error","noroute"), - m_msg->getValue("reason","No route to call target"),m_msg); + chan->callRejected(m_msg->getValue(YSTRING("error"),"noroute"), + m_msg->getValue(YSTRING("reason"),"No route to call target"),m_msg); // dereference again if the channel is dynamic if (m_driver->varchan()) diff --git a/engine/Cipher.cpp b/engine/Cipher.cpp index df85698f..efc6526c 100644 --- a/engine/Cipher.cpp +++ b/engine/Cipher.cpp @@ -38,7 +38,7 @@ Cipher::~Cipher() void* Cipher::getObject(const String& name) const { - if (name == "Cipher") + if (name == YSTRING("Cipher")) return const_cast(this); return GenObject::getObject(name); } diff --git a/engine/DataBlock.cpp b/engine/DataBlock.cpp index e7376e82..b046ab03 100644 --- a/engine/DataBlock.cpp +++ b/engine/DataBlock.cpp @@ -64,7 +64,7 @@ DataBlock::~DataBlock() void* DataBlock::getObject(const String& name) const { - if (name == "DataBlock") + if (name == YSTRING("DataBlock")) return const_cast(this); return GenObject::getObject(name); } @@ -208,32 +208,32 @@ bool DataBlock::convert(const DataBlock& src, const String& sFormat, } unsigned sl = 0, dl = 0; void *ctable = 0; - if (sFormat == "slin") { + if (sFormat == YSTRING("slin")) { sl = 2; dl = 1; - if (dFormat == "alaw") + if (dFormat == YSTRING("alaw")) ctable = s2a; - else if (dFormat == "mulaw") + else if (dFormat == YSTRING("mulaw")) ctable = s2u; } - else if (sFormat == "alaw") { + else if (sFormat == YSTRING("alaw")) { sl = 1; - if (dFormat == "mulaw") { + if (dFormat == YSTRING("mulaw")) { dl = 1; ctable = a2u; } - else if (dFormat == "slin") { + else if (dFormat == YSTRING("slin")) { dl = 2; ctable = a2s; } } - else if (sFormat == "mulaw") { + else if (sFormat == YSTRING("mulaw")) { sl = 1; - if (dFormat == "alaw") { + if (dFormat == YSTRING("alaw")) { dl = 1; ctable = u2a; } - else if (dFormat == "slin") { + else if (dFormat == YSTRING("slin")) { dl = 2; ctable = u2s; } diff --git a/engine/DataFormat.cpp b/engine/DataFormat.cpp index 987ace29..8422d7aa 100644 --- a/engine/DataFormat.cpp +++ b/engine/DataFormat.cpp @@ -467,7 +467,7 @@ void DataConsumer::destroyed() void* DataConsumer::getObject(const String& name) const { - if (name == "DataConsumer") + if (name == YSTRING("DataConsumer")) return const_cast(this); return DataNode::getObject(name); } @@ -692,7 +692,7 @@ void DataSource::synchronize(unsigned long tStamp) void* DataSource::getObject(const String& name) const { - if (name == "DataSource") + if (name == YSTRING("DataSource")) return const_cast(this); return DataNode::getObject(name); } @@ -725,7 +725,7 @@ void DataEndpoint::destroyed() void* DataEndpoint::getObject(const String& name) const { - if (name == "DataEndpoint") + if (name == YSTRING("DataEndpoint")) return const_cast(this); return RefObject::getObject(name); } @@ -1137,7 +1137,7 @@ DataTranslator::~DataTranslator() void* DataTranslator::getObject(const String& name) const { - if (name == "DataTranslator") + if (name == YSTRING("DataTranslator")) return const_cast(this); return DataConsumer::getObject(name); } diff --git a/engine/Evaluator.cpp b/engine/Evaluator.cpp index 998355ca..c4a7f18c 100644 --- a/engine/Evaluator.cpp +++ b/engine/Evaluator.cpp @@ -668,7 +668,7 @@ bool ExpEvaluator::runFunction(ObjList& stack, const ExpOperation& oper) { DDebug(DebugAll,"runFunction(%p,'%s' %ld) ext=%p", &stack,oper.name().c_str(),oper.number(),(void*)m_extender); - if (oper.name() == "chr") { + if (oper.name() == YSTRING("chr")) { String res; for (long int i = oper.number(); i; i--) { ExpOperation* o = popOne(stack); @@ -680,7 +680,7 @@ bool ExpEvaluator::runFunction(ObjList& stack, const ExpOperation& oper) stack.append(new ExpOperation(res)); return true; } - if (oper.name() == "now") { + if (oper.name() == YSTRING("now")) { if (oper.number()) return gotError("Function expects no arguments"); stack.append(new ExpOperation(Time::secNow())); diff --git a/engine/HashList.cpp b/engine/HashList.cpp index 9f8953eb..f39a2b6e 100644 --- a/engine/HashList.cpp +++ b/engine/HashList.cpp @@ -48,7 +48,7 @@ HashList::~HashList() void* HashList::getObject(const String& name) const { - if (name == "HashList") + if (name == YSTRING("HashList")) return const_cast(this); return GenObject::getObject(name); } diff --git a/engine/Message.cpp b/engine/Message.cpp index 5389e9da..914cabab 100644 --- a/engine/Message.cpp +++ b/engine/Message.cpp @@ -58,7 +58,7 @@ Message::~Message() void* Message::getObject(const String& name) const { - if (name == "Message") + if (name == YSTRING("Message")) return const_cast(this); return NamedList::getObject(name); } diff --git a/engine/Mime.cpp b/engine/Mime.cpp index d1a148f2..fd57d593 100644 --- a/engine/Mime.cpp +++ b/engine/Mime.cpp @@ -94,7 +94,7 @@ MimeHeaderLine::~MimeHeaderLine() void* MimeHeaderLine::getObject(const String& name) const { - if (name == "MimeHeaderLine") + if (name == YSTRING("MimeHeaderLine")) return const_cast(this); return NamedString::getObject(name); } @@ -316,7 +316,7 @@ MimeAuthLine::MimeAuthLine(const MimeAuthLine& original, const char* newName) void* MimeAuthLine::getObject(const String& name) const { - if (name == "MimeAuthLine") + if (name == YSTRING("MimeAuthLine")) return const_cast(this); return MimeHeaderLine::getObject(name); } @@ -444,11 +444,11 @@ MimeBody* MimeBody::build(const char* buf, int len, const MimeHeaderLine& type) return 0; String what = type; what.toLower(); - if (what == "application/sdp") + if (what == YSTRING("application/sdp")) return new MimeSdpBody(type,buf,len); - if ((what == "application/dtmf-relay") || (what == "message/sipfrag")) + if ((what == YSTRING("application/dtmf-relay")) || (what == YSTRING("message/sipfrag"))) return new MimeLinesBody(type,buf,len); - if (what.startsWith("text/") || (what == "application/dtmf")) + if (what.startsWith("text/") || (what == YSTRING("application/dtmf"))) return new MimeStringBody(type,buf,len); if (what.startsWith("multipart/")) return new MimeMultipartBody(type,buf,len); @@ -592,7 +592,7 @@ MimeMultipartBody::MimeMultipartBody(const MimeMultipartBody& original) // Find object by class name, descend into parts void* MimeMultipartBody::getObject(const String& name) const { - if (name == "MimeMultipartBody") + if (name == YSTRING("MimeMultipartBody")) return const_cast(this); void* res = MimeBody::getObject(name); if (res) diff --git a/engine/NamedList.cpp b/engine/NamedList.cpp index 2ccd9b07..d46efedb 100644 --- a/engine/NamedList.cpp +++ b/engine/NamedList.cpp @@ -60,7 +60,7 @@ NamedList& NamedList::operator=(const NamedList& value) void* NamedList::getObject(const String& name) const { - if (name == "NamedList") + if (name == YSTRING("NamedList")) return const_cast(this); return String::getObject(name); } diff --git a/engine/ObjList.cpp b/engine/ObjList.cpp index f5a81762..ce23caeb 100644 --- a/engine/ObjList.cpp +++ b/engine/ObjList.cpp @@ -47,7 +47,7 @@ ObjList::~ObjList() void* ObjList::getObject(const String& name) const { - if (name == "ObjList") + if (name == YSTRING("ObjList")) return const_cast(this); return GenObject::getObject(name); } diff --git a/engine/Plugin.cpp b/engine/Plugin.cpp index d1d8373b..c8684d0c 100644 --- a/engine/Plugin.cpp +++ b/engine/Plugin.cpp @@ -41,7 +41,7 @@ Plugin::~Plugin() void* Plugin::getObject(const String& name) const { - if (name == "Plugin") + if (name == YSTRING("Plugin")) return const_cast(this); return GenObject::getObject(name); } diff --git a/engine/Socket.cpp b/engine/Socket.cpp index 545f5b21..2bca539e 100644 --- a/engine/Socket.cpp +++ b/engine/Socket.cpp @@ -390,7 +390,7 @@ SocketFilter::~SocketFilter() void* SocketFilter::getObject(const String& name) const { - if (name == "SocketFilter") + if (name == YSTRING("SocketFilter")) return const_cast(this); return GenObject::getObject(name); } diff --git a/engine/String.cpp b/engine/String.cpp index e03f8e0a..588716d6 100644 --- a/engine/String.cpp +++ b/engine/String.cpp @@ -1317,7 +1317,7 @@ int String::fixUtf8(const char* replace, unsigned int maxSeq, bool overlong) void* String::getObject(const String& name) const { - if (name == "String") + if (name == YSTRING("String")) return const_cast(this); return GenObject::getObject(name); } @@ -1441,7 +1441,7 @@ const String& NamedString::toString() const void* NamedString::getObject(const String& name) const { - if (name == "NamedString") + if (name == YSTRING("NamedString")) return (void*)this; return String::getObject(name); } @@ -1476,7 +1476,7 @@ GenObject* NamedPointer::takeData() void* NamedPointer::getObject(const String& name) const { - if (name == "NamedPointer") + if (name == YSTRING("NamedPointer")) return (void*)this; void* p = NamedString::getObject(name); if (p) diff --git a/yateclass.h b/yateclass.h index 968e3ad4..bef23e31 100644 --- a/yateclass.h +++ b/yateclass.h @@ -202,6 +202,12 @@ namespace TelEngine { #define FORMAT_CHECK(f) #endif +#ifdef HAVE_BLOCK_RETURN +#define YSTRING(s) (*({static const String str(s);&str;})) +#else +#define YSTRING(s) (s) +#endif + /** * Abort execution (and coredump if allowed) if the abort flag is set. * This function may not return. @@ -574,6 +580,13 @@ class String; class Mutex; #if 0 /* for documentation generator */ +/** + * Macro to create a local static String if supported by compiler, use with caution + * @param string Literal constant string + * @return A const String& if supported, literal string if not supported + */ +constant YSTRING(const char* string); + /** * Macro to create a GenObject class from a base class and implement @ref GenObject::getObject * @param type Class that is declared @@ -639,17 +652,17 @@ void YNOCOPY(class type); #define YCLASS(type,base) \ public: virtual void* getObject(const String& name) const \ -{ return (name == #type) ? const_cast(this) : base::getObject(name); } +{ return (name == YSTRING(#type)) ? const_cast(this) : base::getObject(name); } #define YCLASS2(type,base1,base2) \ public: virtual void* getObject(const String& name) const \ -{ if (name == #type) return const_cast(this); \ +{ if (name == YSTRING(#type)) return const_cast(this); \ void* tmp = base1::getObject(name); \ return tmp ? tmp : base2::getObject(name); } #define YCLASS3(type,base1,base2,base3) \ public: virtual void* getObject(const String& name) const \ -{ if (name == #type) return const_cast(this); \ +{ if (name == YSTRING(#type)) return const_cast(this); \ void* tmp = base1::getObject(name); \ if (tmp) return tmp; \ tmp = base2::getObject(name); \ @@ -657,23 +670,23 @@ public: virtual void* getObject(const String& name) const \ #define YCLASSIMP(type,base) \ void* type::getObject(const String& name) const \ -{ return (name == #type) ? const_cast(this) : base::getObject(name); } +{ return (name == YSTRING(#type)) ? const_cast(this) : base::getObject(name); } #define YCLASSIMP2(type,base1,base2) \ void* type::getObject(const String& name) const \ -{ if (name == #type) return const_cast(this); \ +{ if (name == YSTRING(#type)) return const_cast(this); \ void* tmp = base1::getObject(name); \ return tmp ? tmp : base2::getObject(name); } #define YCLASSIMP3(type,base1,base2,base3) \ void* type::getObject(const String& name) const \ -{ if (name == #type) return const_cast(this); \ +{ if (name == YSTRING(#type)) return const_cast(this); \ void* tmp = base1::getObject(name); \ if (tmp) return tmp; \ tmp = base2::getObject(name); \ return tmp ? tmp : base3::getObject(name); } -#define YOBJECT(type,pntr) (static_cast(GenObject::getObject(#type,pntr))) +#define YOBJECT(type,pntr) (static_cast(GenObject::getObject(YSTRING(#type),pntr))) #define YNOCOPY(type) private: \ type(const type&); \