summaryrefslogtreecommitdiff
path: root/indra/llxml
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llxml')
-rw-r--r--indra/llxml/CMakeLists.txt6
-rw-r--r--indra/llxml/llcontrol.cpp70
-rw-r--r--indra/llxml/llcontrol.h17
-rw-r--r--indra/llxml/llxmlnode.cpp8
-rw-r--r--indra/llxml/llxmlparser.cpp4
-rw-r--r--indra/llxml/tests/llcontrol_test.cpp2
6 files changed, 75 insertions, 32 deletions
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index 03ac4bc9f2..ffb819a29f 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -32,12 +32,16 @@ target_link_libraries( llxml
llmath
llcommon
ll::expat
- ll::SDL
+ ll::SDL3
)
target_include_directories( llxml INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
include(LibraryInstall)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llxml REUSE_FROM llprecompiled)
+endif ()
+
# tests
if (LL_TESTS)
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index bb590ebd76..eccf672e46 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -157,6 +157,12 @@ LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
{
if ((persist != PERSIST_NO) && mComment.empty())
{
+ std::string error_string =
+ "Second Life failed to initialize settings. Setting " + mName + " is invalid. "
+ "Either settings' files were supplied incorrectly or default files were corrupted."
+ "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
+ "contact https://support.secondlife.com if issue persists after reinstall.";
+ LLError::LLUserWarningMsg::show(error_string);
LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL;
}
//Push back versus setValue'ing here, since we don't want to call a signal yet
@@ -186,20 +192,6 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value)
storable_value = false;
}
}
- else if (TYPE_LLSD == type() && value.isString())
- {
- LLPointer<LLSDNotationParser> parser = new LLSDNotationParser;
- LLSD result;
- std::stringstream value_stream(value.asString());
- if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE)
- {
- storable_value = result;
- }
- else
- {
- storable_value = value;
- }
- }
else
{
storable_value = value;
@@ -393,10 +385,11 @@ static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs)
void LLControlGroup::cleanup()
{
+ LL_PROFILE_ZONE_SCOPED;
if(mSettingsProfile && getCount.size() != 0)
{
std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE);
- LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */
+ LLFILE* out = LLFile::fopen(file, LLFILE_MODE("w")); /* Flawfinder: ignore */
if(!out)
{
LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL;
@@ -728,6 +721,30 @@ void LLControlGroup::setLLSD(std::string_view name, const LLSD& val)
set(name, val);
}
+bool LLControlVariable::setValueFromNotation(const std::string& notation, bool saved_value)
+{
+ if (mType == TYPE_LLSD)
+ {
+ LLPointer<LLSDNotationParser> parser = new LLSDNotationParser;
+ LLSD result;
+ std::stringstream value_stream(notation);
+ S32 parse_count = parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED);
+ if (parse_count != LLSDParser::PARSE_FAILURE)
+ {
+ setValue(result, saved_value);
+ return true;
+ }
+ LL_WARNS("Controls") << "Failed to parse LLSD notation for control '"
+ << mName << "': " << notation << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Controls") << "setValueFromNotation() called on non-LLSD control '"
+ << mName << "' (type " << LLControlGroup::typeEnumToString(mType) << "); ignoring." << LL_ENDL;
+ }
+ return false;
+}
+
void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val)
{
if (name.empty())
@@ -755,6 +772,7 @@ void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val)
// Returns number of controls loaded, so 0 if failure
U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as)
{
+ LL_PROFILE_ZONE_SCOPED;
std::string name;
LLXmlTree xml_controls;
@@ -952,6 +970,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require
U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only)
{
+ LL_PROFILE_ZONE_SCOPED;
LLSD settings;
int num_saved = 0;
for (ctrl_name_table_t::iterator iter = mNameTable.begin();
@@ -987,8 +1006,9 @@ U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only
return num_saved;
}
-U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values)
+U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values, bool error_when_no_comment)
{
+ LL_PROFILE_ZONE_SCOPED;
LLSD settings;
llifstream infile;
infile.open(filename.c_str());
@@ -1102,10 +1122,26 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
}
}
+ std::string comment = control_map["Comment"].asString();
+ if (!error_when_no_comment
+ && !set_default_values
+ && comment.empty())
+ {
+ // Only error for default settings that should remind the developer to provide comments
+ // and otherwise indicate a problem with viewer's files.
+ // But permit this minor transgression in user's files.
+ // Otherwise user might have a hard time figuring out source of the error or how to fix it.
+ // Instead make setting to not persist so that unrecognized invalid settings won't be saved
+ // for the next run.
+ persist = LLControlVariable::PERSIST_NO;
+ comment = "Comment not provided, setting won't persist";
+ LL_WARNS() << "Control " << name << " is missing a comment value. Setting will be marked as PERSIST_NO" << LL_ENDL;
+ }
+
declareControl(name,
typeStringToEnum(control_map["Type"].asString()),
control_map["Value"],
- control_map["Comment"].asString(),
+ comment,
persist,
hidefromsettingseditor
);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 4f54a9d705..7f28c71232 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -28,15 +28,17 @@
#define LL_LLCONTROL_H
#include "llboost.h"
-#include "llevent.h"
#include "llstring.h"
+#include "llpointer.h"
#include "llrect.h"
#include "llrefcount.h"
#include "llinstancetracker.h"
+#include "llstl.h"
+#include <functional>
+#include <unordered_map>
#include <vector>
-#include <boost/bind.hpp>
#include <boost/signals2.hpp>
class LLVector3;
@@ -125,6 +127,7 @@ public:
void setPersist(ePersist);
void setHiddenFromSettingsEditor(bool hide);
void setComment(const std::string& comment);
+ bool setValueFromNotation(const std::string& notation, bool saved_value = true);
private:
void firePropertyChanged(const LLSD &pPreviousValue)
@@ -165,7 +168,7 @@ class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
LOG_CLASS(LLControlGroup);
protected:
- typedef std::map<std::string, LLControlVariablePtr, std::less<> > ctrl_name_table_t;
+ using ctrl_name_table_t = std::unordered_map<std::string, LLControlVariablePtr, ll::string_hash, std::equal_to<>>;
ctrl_name_table_t mNameTable;
static const std::string mTypeString[TYPE_COUNT];
@@ -278,7 +281,7 @@ public:
// as the given type.
U32 loadFromFileLegacy(const std::string& filename, bool require_declaration = true, eControlType declare_as = TYPE_STRING);
U32 saveToFile(const std::string& filename, bool nondefault_only);
- U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true);
+ U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true, bool error_when_no_comment = true);
void resetToDefaults();
void incrCount(std::string_view name);
@@ -319,7 +322,7 @@ public:
{
if(!group.controlExists(name))
{
- LL_ERRS() << "Control named " << name << "not found." << LL_ENDL;
+ LL_ERRS() << "Control named " << name << " not found." << LL_ENDL;
}
bindToControl(group, name);
@@ -341,7 +344,7 @@ private:
// Add a listener to the controls signal...
// NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last
mConnection = controlp->getSignal()->connect(0,
- boost::bind(&LLControlCache<T>::handleValueChange, this, _2)
+ std::bind(&LLControlCache<T>::handleValueChange, this, std::placeholders::_2)
);
mType = controlp->type();
}
@@ -400,7 +403,7 @@ public:
}
operator const T&() const { return mCachedControlPtr->getValue(); }
- operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); }
+ operator std::function<const T&()> () const { return std::function<const T&()>(*this); }
const T& operator()() { return mCachedControlPtr->getValue(); }
private:
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 8a2c36a307..77743fe0c2 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -29,7 +29,7 @@
#include <iostream>
#include <map>
-#if LL_SDL
+#if LL_SDL_WINDOW
#include <SDL_rwops.h>
#endif
@@ -1285,7 +1285,7 @@ bool LLXMLNode::getAttributeU8(const char* name, U8& value )
bool LLXMLNode::getAttributeS8(const char* name, S8& value )
{
LLXMLNodePtr node;
- S32 val;
+ S32 val{};
if (!(getAttribute(name, node) && node->getIntValue(1, &val)))
{
return false;
@@ -1297,7 +1297,7 @@ bool LLXMLNode::getAttributeS8(const char* name, S8& value )
bool LLXMLNode::getAttributeU16(const char* name, U16& value )
{
LLXMLNodePtr node;
- U32 val;
+ U32 val{};
if (!(getAttribute(name, node) && node->getUnsignedValue(1, &val)))
{
return false;
@@ -1309,7 +1309,7 @@ bool LLXMLNode::getAttributeU16(const char* name, U16& value )
bool LLXMLNode::getAttributeS16(const char* name, S16& value )
{
LLXMLNodePtr node;
- S32 val;
+ S32 val{};
if (!(getAttribute(name, node) && node->getIntValue(1, &val)))
{
return false;
diff --git a/indra/llxml/llxmlparser.cpp b/indra/llxml/llxmlparser.cpp
index e2c7d17e2a..8afd412cda 100644
--- a/indra/llxml/llxmlparser.cpp
+++ b/indra/llxml/llxmlparser.cpp
@@ -72,7 +72,7 @@ bool LLXmlParser::parseFile(const std::string &path)
bool success = true;
- LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
+ LLFILE* file = LLFile::fopen(path, LLFILE_MODE("rb")); /* Flawfinder: ignore */
if( !file )
{
mAuxErrorString = llformat( "Couldn't open file %s", path.c_str());
@@ -388,7 +388,7 @@ int main()
{
char buf[1024];
- LLFILE* file = LLFile::fopen("test.xml", "rb");
+ LLFILE* file = LLFile::fopen("test.xml", LLFILE_MODE("rb"));
if( !file )
{
return 1;
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index 4192e029c5..e15117fc29 100644
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -69,7 +69,7 @@ namespace tut
LLFile::remove(filename);
}
LLFile::remove(mTestConfigFile);
- LLFile::rmdir(mTestConfigDir);
+ LLFile::remove(mTestConfigDir);
}
void writeSettingsFile(const LLSD& config)
{