Commit c71b1b6d authored by Kitty Barnett's avatar Kitty Barnett
Browse files

Merged with Catznip tip

--HG--
branch : Catznip
parents c0fccbaa 811f17a1
1f334f5215c4b614cb1a984a554271b40e96ef3b
\ No newline at end of file
76ec0711802c5a82394aa866e2c72d708314aab4
\ No newline at end of file
......@@ -540,6 +540,7 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
04538b8157c1f5cdacd9403f0a395452d4a93689 5.1.6-release
ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release
52422540bfe54b71155aa455360bee6e3ef1fd96 5.1.9-release
0000000000000000000000000000000000000000 v2start
0000000000000000000000000000000000000000 alpha-3
0000000000000000000000000000000000000000 fork to viewer-2-0
......@@ -1081,6 +1082,7 @@ ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
0000000000000000000000000000000000000000 5.1.5-release
0000000000000000000000000000000000000000 5.1.7-release
0000000000000000000000000000000000000000 5.1.8-release
0000000000000000000000000000000000000000 5.1.9-release
4f777ffb99fefdc6497c61385c22688ff149c659 SL-2.0.0
668851b2ef0f8cf8df07a0fba429e4a6c1e70abb SL-2.0.1
b03065d018b8a2e28b7de85b293a4c992cb4c12d SL-2.1.0
......@@ -1210,6 +1212,7 @@ ad0e15543836d64d6399d28b32852510435e344a SL-5.1.0
04538b8157c1f5cdacd9403f0a395452d4a93689 SL-5.1.6
ac3b1332ad4f55b7182a8cbcc1254535a0069f75 SL-5.1.7
23ea0fe36fadf009a60c080392ce80e4bf8af8d9 SL-5.1.8
52422540bfe54b71155aa455360bee6e3ef1fd96 SL-5.1.9
89532c8dfd5b6c29f1cb032665b44a74a52452e1 RLVa-1.3.0
7bc5039ccf0b36eafbf6ce33a52b5e26332aa04c RLVa-1.3.1
a563f7e215c7883c1cfd20908085687a0ed96284 RLVa-1.4.0
......
......@@ -1566,9 +1566,10 @@ BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
delete_and_clear_array(mCollisionVolumes);
mNumCollisionVolumes = 0;
mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
mCollisionVolumes = new(std::nothrow) LLAvatarJointCollisionVolume[num];
if (!mCollisionVolumes)
{
LL_WARNS() << "Failed to allocate collision volumes" << LL_ENDL;
return FALSE;
}
......
......@@ -103,7 +103,7 @@ LLWearableDictionary::LLWearableDictionary()
// [/SL:KB]
// addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_UNKNOWN, FALSE, FALSE));
addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
}
......
......@@ -265,9 +265,19 @@ BOOL LLVorbisDecodeState::initDecode()
mInFilep = NULL;
return FALSE;
}
mWAVBuffer.reserve(size_guess);
mWAVBuffer.resize(WAV_HEADER_SIZE);
try
{
mWAVBuffer.reserve(size_guess);
mWAVBuffer.resize(WAV_HEADER_SIZE);
}
catch (std::bad_alloc)
{
LL_WARNS("AudioEngine") << "Out of memory when trying to alloc buffer: " << size_guess << LL_ENDL;
delete mInFilep;
mInFilep = NULL;
return FALSE;
}
{
// write the .wav format header
......
......@@ -579,8 +579,15 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
else
{
anim_file_size = anim_file->getSize();
anim_data = new U8[anim_file_size];
success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/
anim_data = new(std::nothrow) U8[anim_file_size];
if (anim_data)
{
success = anim_file->read(anim_data, anim_file_size); /*Flawfinder: ignore*/
}
else
{
LL_WARNS() << "Failed to allocate buffer: " << anim_file_size << mID << LL_ENDL;
}
delete anim_file;
anim_file = NULL;
}
......
......@@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};
......@@ -156,7 +157,7 @@ LLAssetType::EType LLAssetType::lookup(const std::string& type_name)
return iter->first;
}
}
return AT_NONE;
return AT_UNKNOWN;
}
// static
......
......@@ -130,7 +130,7 @@ class LL_COMMON_API LLAssetType
// | 4. ADD TO LLViewerAssetType.cpp |
// | 5. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp |
// +*********************************************************+
AT_UNKNOWN = 255,
AT_NONE = -1
};
......
......@@ -40,6 +40,7 @@
# include <unistd.h>
#endif // !LL_WINDOWS
#include <vector>
#include "string.h"
#include "llapp.h"
#include "llapr.h"
......@@ -606,21 +607,16 @@ namespace LLError
mTags(new const char* [tag_count]),
mTagCount(tag_count)
{
for (int i = 0; i < tag_count; i++)
{
mTags[i] = tags[i];
}
switch (mLevel)
{
case LEVEL_DEBUG: mLevelString = "DEBUG:"; break;
case LEVEL_INFO: mLevelString = "INFO:"; break;
case LEVEL_WARN: mLevelString = "WARNING:"; break;
case LEVEL_ERROR: mLevelString = "ERROR:"; break;
default: mLevelString = "XXX:"; break;
case LEVEL_DEBUG: mLevelString = "DEBUG"; break;
case LEVEL_INFO: mLevelString = "INFO"; break;
case LEVEL_WARN: mLevelString = "WARNING"; break;
case LEVEL_ERROR: mLevelString = "ERROR"; break;
default: mLevelString = "XXX"; break;
};
mLocationString = llformat("%s(%d) :", abbreviateFile(mFile).c_str(), mLine);
mLocationString = llformat("%s(%d)", abbreviateFile(mFile).c_str(), mLine);
#if LL_WINDOWS
// DevStudio: __FUNCTION__ already includes the full class name
#else
......@@ -634,13 +630,23 @@ namespace LLError
mFunctionString = className(mClassInfo) + "::";
}
#endif
mFunctionString += std::string(mFunction) + ":";
const std::string tag_hash("#");
mFunctionString += std::string(mFunction);
for (int i = 0; i < tag_count; i++)
{
if (strchr(tags[i], ' '))
{
LL_ERRS() << "Space is not allowed in a log tag at " << mLocationString << LL_ENDL;
}
mTags[i] = tags[i];
}
mTagString.append("#");
// always construct a tag sequence; will be just a single # if no tag
for (size_t i = 0; i < mTagCount; i++)
{
mTagString.append(tag_hash);
mTagString.append(mTags[i]);
mTagString.append((i == mTagCount - 1) ? ";" : ",");
mTagString.append("#");
}
}
......@@ -981,7 +987,46 @@ namespace LLError
namespace
{
void writeToRecorders(const LLError::CallSite& site, const std::string& message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)
void addEscapedMessage(std::ostream& out, const std::string& message)
{
size_t written_out = 0;
size_t all_content = message.length();
size_t escape_char_index; // always relative to start of message
// Use find_first_of to find the next character in message that needs escaping
for ( escape_char_index = message.find_first_of("\\\n\r");
escape_char_index != std::string::npos && written_out < all_content;
// record what we've written this iteration, scan for next char that needs escaping
written_out = escape_char_index + 1, escape_char_index = message.find_first_of("\\\n\r", written_out)
)
{
// found a character that needs escaping, so write up to that with the escape prefix
// note that escape_char_index is relative to the start, not to the written_out offset
out << message.substr(written_out, escape_char_index - written_out) << '\\';
// write out the appropriate second character in the escape sequence
char found = message[escape_char_index];
switch ( found )
{
case '\\':
out << '\\';
break;
case '\n':
out << 'n';
break;
case '\r':
out << 'r';
break;
}
}
if ( written_out < all_content ) // if the loop above didn't write everything
{
// write whatever was left
out << message.substr(written_out, std::string::npos);
}
}
void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message, bool show_location = true, bool show_time = true, bool show_tags = true, bool show_level = true, bool show_function = true)
{
LLError::ELevel level = site.mLevel;
LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig();
......@@ -994,32 +1039,37 @@ namespace
std::ostringstream message_stream;
if (show_time && r->wantsTime() && s->mTimeFunction != NULL)
if (r->wantsTime() && s->mTimeFunction != NULL)
{
message_stream << s->mTimeFunction() << " ";
message_stream << s->mTimeFunction();
}
message_stream << " ";
if (show_level && r->wantsLevel())
{
message_stream << site.mLevelString << " ";
message_stream << site.mLevelString;
}
message_stream << " ";
if (show_tags && r->wantsTags())
if (r->wantsTags())
{
message_stream << site.mTagString;
}
message_stream << " ";
if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation))
if (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation)
{
message_stream << site.mLocationString << " ";
message_stream << site.mLocationString;
}
message_stream << " ";
if (show_function && r->wantsFunctionName())
{
message_stream << site.mFunctionString << " ";
message_stream << site.mFunctionString;
}
message_stream << " : ";
message_stream << message;
message_stream << escaped_message;
r->recordMessage(level, message_stream.str());
}
......@@ -1262,11 +1312,6 @@ namespace LLError
delete out;
}
if (site.mLevel == LEVEL_ERROR)
{
writeToRecorders(site, "error", true, true, true, false, false);
}
std::ostringstream message_stream;
if (site.mPrintOnce)
......@@ -1292,8 +1337,8 @@ namespace LLError
}
}
message_stream << message;
addEscapedMessage(message_stream, message);
writeToRecorders(site, message_stream.str());
if (site.mLevel == LEVEL_ERROR && s->mCrashFunction)
......
......@@ -146,11 +146,22 @@ const int LL_ERR_NOERR = 0;
will result in messages like:
WARN: LLFoo::doSomething: called with a big value for i: 283
WARN #FooBarTag# llcommon/llfoo(100) LLFoo::doSomething : called with a big value for i: 283
the syntax is:
<timestamp> SPACE <level> SPACE <tags> SPACE <location> SPACE <function> SPACE COLON SPACE <message>
where each SPACE is a single space character; note that if a field is empty (such as when no
tags are specified), all the SPACEs are still present.
The tags must be a single word (may not contain a space); if more than one tag is specified,
they are all surrounded by '#' ( #FooTag#BarTag# ).
Which messages are logged and which are suppressed can be controlled at run
time from the live file logcontrol.xml based on function, class and/or
source file. See etc/logcontrol-dev.xml for details.
time from the configuration file. The default configuration is in newview/app_settings/logcontrol.xml
A copy of that file named logcontrol-dev.xml can be made in the users personal settings
directory; that will override the installed default file. See the logcontrol.xml
file or http://wiki.secondlife.com/wiki/Logging_System_Overview for configuration details.
Lastly, logging is now very efficient in both compiled code and execution
when skipped. There is no need to wrap messages, even debugging ones, in
......
......@@ -610,7 +610,7 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
value = (uint64_t)(( uint8_t *)&value);
else
{
LL_WARNS("Unknown type returned from sysctl!") << LL_ENDL;
LL_WARNS() << "Unknown type returned from sysctl" << LL_ENDL;
}
}
......
......@@ -249,9 +249,10 @@ void LLThread::shutdown()
// This thread just wouldn't stop, even though we gave it time
//LL_WARNS() << "LLThread::~LLThread() exiting thread before clean exit!" << LL_ENDL;
// Put a stake in its heart.
delete mRecorder;
apr_thread_exit(mAPRThreadp, -1);
delete mRecorder;
mRecorder = NULL;
mStatus = STOPPED;
return;
}
mAPRThreadp = NULL;
......
......@@ -36,6 +36,26 @@
#include "../test/lltut.h"
enum LogFieldIndex
{
TIME_FIELD,
LEVEL_FIELD,
TAGS_FIELD,
LOCATION_FIELD,
FUNCTION_FIELD,
MSG_FIELD
};
static const char* FieldName[] =
{
"TIME",
"LEVEL",
"TAGS",
"LOCATION",
"FUNCTION",
"MSG"
};
namespace
{
#ifdef __clang__
......@@ -58,7 +78,7 @@ namespace tut
class TestRecorder : public LLError::Recorder
{
public:
TestRecorder() { mWantsTime = false; }
TestRecorder() { mWantsTime = false; mWantsTags = true; }
virtual ~TestRecorder() { }
virtual void recordMessage(LLError::ELevel level,
......@@ -133,13 +153,64 @@ namespace tut
ensure_equals("message count", countMessages(), expectedCount);
}
void ensure_message_contains(int n, const std::string& expectedText)
{
std::ostringstream test_name;
test_name << "testing message " << n;
ensure_contains(test_name.str(), message(n), expectedText);
}
std::string message_field(int msgnum, LogFieldIndex fieldnum)
{
std::ostringstream test_name;
test_name << "testing message " << msgnum << ", not enough messages";
tut::ensure(test_name.str(), msgnum < countMessages());
std::string msg(message(msgnum));
std::string field_value;
// find the start of the field; fields are separated by a single space
size_t scan = 0;
int on_field = 0;
while ( scan < msg.length() && on_field < fieldnum )
{
// fields are delimited by one space
if ( ' ' == msg[scan] )
{
if ( on_field < FUNCTION_FIELD )
{
on_field++;
}
// except function, which may have embedded spaces so ends with " : "
else if ( ( on_field == FUNCTION_FIELD )
&& ( ':' == msg[scan+1] && ' ' == msg[scan+2] )
)
{
on_field++;
scan +=2;
}
}
scan++;
}
size_t start_field = scan;
size_t fieldlen = 0;
if ( fieldnum < FUNCTION_FIELD )
{
fieldlen = msg.find(' ', start_field) - start_field;
}
else if ( fieldnum == FUNCTION_FIELD )
{
fieldlen = msg.find(" : ", start_field) - start_field;
}
else if ( MSG_FIELD == fieldnum ) // no delimiter, just everything to the end
{
fieldlen = msg.length() - start_field;
}
return msg.substr(start_field, fieldlen);
}
void ensure_message_field_equals(int msgnum, LogFieldIndex fieldnum, const std::string& expectedText)
{
std::ostringstream test_name;
test_name << "testing message " << msgnum << " field " << FieldName[fieldnum] << "\n message: \"" << message(msgnum) << "\"\n ";
ensure_equals(test_name.str(), message_field(msgnum, fieldnum), expectedText);
}
void ensure_message_does_not_contain(int n, const std::string& expectedText)
{
......@@ -162,8 +233,8 @@ namespace tut
LL_INFOS() << "test" << LL_ENDL;
LL_INFOS() << "bob" << LL_ENDL;
ensure_message_contains(0, "test");
ensure_message_contains(1, "bob");
ensure_message_field_equals(0, MSG_FIELD, "test");
ensure_message_field_equals(1, MSG_FIELD, "bob");
}
}
......@@ -171,11 +242,10 @@ namespace
{
void writeSome()
{
LL_DEBUGS() << "one" << LL_ENDL;
LL_INFOS() << "two" << LL_ENDL;
LL_WARNS() << "three" << LL_ENDL;
// fatal messages write out an additional "error" message
LL_ERRS() << "four" << LL_ENDL;
LL_DEBUGS("WriteTag","AnotherTag") << "one" << LL_ENDL;
LL_INFOS("WriteTag") << "two" << LL_ENDL;
LL_WARNS("WriteTag") << "three" << LL_ENDL;
LL_ERRS("WriteTag") << "four" << LL_ENDL;
}
};
......@@ -187,37 +257,41 @@ namespace tut
{
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
writeSome();
ensure_message_contains(0, "one");
ensure_message_contains(1, "two");
ensure_message_contains(2, "three");
ensure_message_contains(3, "error");
ensure_message_contains(4, "four");
ensure_message_count(5);
ensure_message_field_equals(0, MSG_FIELD, "one");
ensure_message_field_equals(0, LEVEL_FIELD, "DEBUG");
ensure_message_field_equals(0, TAGS_FIELD, "#WriteTag#AnotherTag#");
ensure_message_field_equals(1, MSG_FIELD, "two");
ensure_message_field_equals(1, LEVEL_FIELD, "INFO");
ensure_message_field_equals(1, TAGS_FIELD, "#WriteTag#");
ensure_message_field_equals(2, MSG_FIELD, "three");
ensure_message_field_equals(2, LEVEL_FIELD, "WARNING");
ensure_message_field_equals(2, TAGS_FIELD, "#WriteTag#");
ensure_message_field_equals(3, MSG_FIELD, "four");
ensure_message_field_equals(3, LEVEL_FIELD, "ERROR");
ensure_message_field_equals(3, TAGS_FIELD, "#WriteTag#");
ensure_message_count(4);
LLError::setDefaultLevel(LLError::LEVEL_INFO);
writeSome();
ensure_message_contains(5, "two");
ensure_message_contains(6, "three");
ensure_message_contains(7, "error");
ensure_message_contains(8, "four");
ensure_message_count(9);
ensure_message_field_equals(4, MSG_FIELD, "two");
ensure_message_field_equals(5, MSG_FIELD, "three");
ensure_message_field_equals(6, MSG_FIELD, "four");
ensure_message_count(7);
LLError::setDefaultLevel(LLError::LEVEL_WARN);
writeSome();
ensure_message_contains(9, "three");
ensure_message_contains(10, "error");
ensure_message_contains(11, "four");
ensure_message_count(12);
ensure_message_field_equals(7, MSG_FIELD, "three");
ensure_message_field_equals(8, MSG_FIELD, "four");
ensure_message_count(9);
LLError::setDefaultLevel(LLError::LEVEL_ERROR);
writeSome();
ensure_message_contains(12, "error");
ensure_message_contains(13, "four");
ensure_message_count(14);
ensure_message_field_equals(9, MSG_FIELD, "four");
ensure_message_count(10);
LLError::setDefaultLevel(LLError::LEVEL_NONE);
writeSome();
ensure_message_count(14);
ensure_message_count(10);
}
template<> template<>
......@@ -225,12 +299,11 @@ namespace tut
// error type string in output
{
writeSome();
ensure_message_contains(0, "DEBUG: ");
ensure_message_contains(1, "INFO: ");
ensure_message_contains(2, "WARNING: ");
ensure_message_does_not_contain(3, "ERROR");
ensure_message_contains(4, "ERROR: ");
ensure_message_count(5);
ensure_message_field_equals(0, LEVEL_FIELD, "DEBUG");
ensure_message_field_equals(1, LEVEL_FIELD, "INFO");
ensure_message_field_equals(2, LEVEL_FIELD, "WARNING");
ensure_message_field_equals(3, LEVEL_FIELD, "ERROR");
ensure_message_count(4);
}
template<> template<>
......@@ -280,7 +353,7 @@ namespace
{
std::ostringstream location;
location << LLError::abbreviateFile(__FILE__)
<< "(" << line << ") : ";
<< "(" << line << ")";
return location.str();
}
......@@ -321,7 +394,7 @@ namespace tut
writeReturningLocation();
ensure_message_does_not_contain(0, location);
ensure_message_contains(1, location);
ensure_message_field_equals(1, LOCATION_FIELD, location);
ensure_message_does_not_contain(2, location);
}
}
......@@ -496,13 +569,13 @@ namespace tut
void ErrorTestObject::test<7>()
{