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
This commit is contained in:
paulc 2011-06-03 12:26:53 +00:00
parent f651c5f109
commit 471dd0d96d
16 changed files with 137 additions and 109 deletions

View File

@ -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"

View File

@ -52,7 +52,7 @@ Array::~Array()
void* Array::getObject(const String& name) const
{
if (name == "Array")
if (name == YSTRING("Array"))
return const_cast<Array*>(this);
return RefObject::getObject(name);
}

View File

@ -93,7 +93,7 @@ Mutex& CallEndpoint::commonMutex()
void* CallEndpoint::getObject(const String& name) const
{
if (name == "CallEndpoint")
if (name == YSTRING("CallEndpoint"))
return const_cast<CallEndpoint*>(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<Channel*>(this);
if (name == "MessageNotifier")
if (name == YSTRING("MessageNotifier"))
return static_cast<MessageNotifier*>(const_cast<Channel*>(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<Module*>(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<Driver*>(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<Channel> 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())

View File

@ -38,7 +38,7 @@ Cipher::~Cipher()
void* Cipher::getObject(const String& name) const
{
if (name == "Cipher")
if (name == YSTRING("Cipher"))
return const_cast<Cipher*>(this);
return GenObject::getObject(name);
}

View File

@ -64,7 +64,7 @@ DataBlock::~DataBlock()
void* DataBlock::getObject(const String& name) const
{
if (name == "DataBlock")
if (name == YSTRING("DataBlock"))
return const_cast<DataBlock*>(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;
}

View File

@ -467,7 +467,7 @@ void DataConsumer::destroyed()
void* DataConsumer::getObject(const String& name) const
{
if (name == "DataConsumer")
if (name == YSTRING("DataConsumer"))
return const_cast<DataConsumer*>(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<DataSource*>(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<DataEndpoint*>(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<DataTranslator*>(this);
return DataConsumer::getObject(name);
}

View File

@ -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()));

View File

@ -48,7 +48,7 @@ HashList::~HashList()
void* HashList::getObject(const String& name) const
{
if (name == "HashList")
if (name == YSTRING("HashList"))
return const_cast<HashList*>(this);
return GenObject::getObject(name);
}

View File

@ -58,7 +58,7 @@ Message::~Message()
void* Message::getObject(const String& name) const
{
if (name == "Message")
if (name == YSTRING("Message"))
return const_cast<Message*>(this);
return NamedList::getObject(name);
}

View File

@ -94,7 +94,7 @@ MimeHeaderLine::~MimeHeaderLine()
void* MimeHeaderLine::getObject(const String& name) const
{
if (name == "MimeHeaderLine")
if (name == YSTRING("MimeHeaderLine"))
return const_cast<MimeHeaderLine*>(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<MimeAuthLine*>(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<MimeMultipartBody*>(this);
void* res = MimeBody::getObject(name);
if (res)

View File

@ -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<NamedList*>(this);
return String::getObject(name);
}

View File

@ -47,7 +47,7 @@ ObjList::~ObjList()
void* ObjList::getObject(const String& name) const
{
if (name == "ObjList")
if (name == YSTRING("ObjList"))
return const_cast<ObjList*>(this);
return GenObject::getObject(name);
}

View File

@ -41,7 +41,7 @@ Plugin::~Plugin()
void* Plugin::getObject(const String& name) const
{
if (name == "Plugin")
if (name == YSTRING("Plugin"))
return const_cast<Plugin*>(this);
return GenObject::getObject(name);
}

View File

@ -390,7 +390,7 @@ SocketFilter::~SocketFilter()
void* SocketFilter::getObject(const String& name) const
{
if (name == "SocketFilter")
if (name == YSTRING("SocketFilter"))
return const_cast<SocketFilter*>(this);
return GenObject::getObject(name);
}

View File

@ -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<String*>(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)

View File

@ -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<type*>(this) : base::getObject(name); }
{ return (name == YSTRING(#type)) ? const_cast<type*>(this) : base::getObject(name); }
#define YCLASS2(type,base1,base2) \
public: virtual void* getObject(const String& name) const \
{ if (name == #type) return const_cast<type*>(this); \
{ if (name == YSTRING(#type)) return const_cast<type*>(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<type*>(this); \
{ if (name == YSTRING(#type)) return const_cast<type*>(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<type*>(this) : base::getObject(name); }
{ return (name == YSTRING(#type)) ? const_cast<type*>(this) : base::getObject(name); }
#define YCLASSIMP2(type,base1,base2) \
void* type::getObject(const String& name) const \
{ if (name == #type) return const_cast<type*>(this); \
{ if (name == YSTRING(#type)) return const_cast<type*>(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<type*>(this); \
{ if (name == YSTRING(#type)) return const_cast<type*>(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<type*>(GenObject::getObject(#type,pntr)))
#define YOBJECT(type,pntr) (static_cast<type*>(GenObject::getObject(YSTRING(#type),pntr)))
#define YNOCOPY(type) private: \
type(const type&); \