Skip to content

Commit 403fcb2

Browse files
committed
#3867 Print script errors to disk when external editor is used
1 parent a1f682b commit 403fcb2

File tree

2 files changed

+115
-12
lines changed

2 files changed

+115
-12
lines changed

indra/newview/llpreviewscript.cpp

Lines changed: 109 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include "llslider.h"
5454
#include "lltooldraganddrop.h"
5555
#include "llfilesystem.h"
56+
#include "lllogchat.h"
5657

5758
#include "llagent.h"
5859
#include "llmenugl.h"
@@ -415,7 +416,6 @@ LLScriptEdCore::LLScriptEdCore(
415416
mLastHelpToken(NULL),
416417
mLiveHelpHistorySize(0),
417418
mEnableSave(false),
418-
mLiveFile(NULL),
419419
mLive(live),
420420
mContainer(container),
421421
mHasScriptData(false),
@@ -447,7 +447,6 @@ LLScriptEdCore::~LLScriptEdCore()
447447
}
448448
}
449449

450-
delete mLiveFile;
451450
if (mSyntaxIDConnection.connected())
452451
{
453452
mSyntaxIDConnection.disconnect();
@@ -730,13 +729,13 @@ bool LLScriptEdCore::writeToFile(const std::string& filename)
730729
void LLScriptEdCore::sync()
731730
{
732731
// Sync with external editor.
733-
if (mLiveFile)
732+
if (mContainer->mLiveFile)
734733
{
735-
std::string tmp_file = mLiveFile->filename();
734+
std::string tmp_file = mContainer->mLiveFile->filename();
736735
llstat s;
737736
if (LLFile::stat(tmp_file, &s) == 0) // file exists
738737
{
739-
mLiveFile->ignoreNextUpdate();
738+
mContainer->mLiveFile->ignoreNextUpdate();
740739
writeToFile(tmp_file);
741740
}
742741
}
@@ -1121,7 +1120,11 @@ void LLScriptEdCore::doSave( bool close_after_save )
11211120

11221121
void LLScriptEdCore::openInExternalEditor()
11231122
{
1124-
delete mLiveFile; // deletes file
1123+
if (mContainer->mLiveFile)
1124+
{
1125+
// If already open in an external editor, just return
1126+
return;
1127+
}
11251128

11261129
// Generate a suitable filename
11271130
std::string script_name = mScriptName;
@@ -1144,8 +1147,8 @@ void LLScriptEdCore::openInExternalEditor()
11441147
}
11451148

11461149
// Start watching file changes.
1147-
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1));
1148-
mLiveFile->addToEventTimer();
1150+
mContainer->mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1));
1151+
mContainer->mLiveFile->addToEventTimer();
11491152

11501153
// Open it in external editor.
11511154
{
@@ -1420,8 +1423,8 @@ void LLLiveLSLEditor::updateExperiencePanel()
14201423
{
14211424
mExperienceEnabled->setToolTip(getString("experience_enabled"));
14221425
mExperienceEnabled->setEnabled(getIsModifiable());
1423-
mExperiences->setVisible(true);
14241426
mExperienceEnabled->set(true);
1427+
mExperiences->setVisible(true);
14251428
mViewProfileButton->setToolTip(getString("show_experience_profile"));
14261429
buildExperienceList();
14271430
}
@@ -1541,10 +1544,21 @@ void LLLiveLSLEditor::receiveExperienceIds(LLSD result, LLHandle<LLLiveLSLEditor
15411544

15421545
LLScriptEdContainer::LLScriptEdContainer(const LLSD& key) :
15431546
LLPreview(key)
1544-
, mScriptEd(NULL)
1547+
, mScriptEd(nullptr)
1548+
, mLiveFile(nullptr)
1549+
, mLiveLogFile(nullptr)
15451550
{
15461551
}
15471552

1553+
LLScriptEdContainer::~LLScriptEdContainer()
1554+
{
1555+
delete mLiveFile;
1556+
mLiveFile = nullptr;
1557+
1558+
delete mLiveLogFile;
1559+
mLiveLogFile = nullptr;
1560+
}
1561+
15481562
std::string LLScriptEdContainer::getTmpFileName(const std::string& script_name)
15491563
{
15501564
// Take script inventory item id (within the object inventory)
@@ -1569,6 +1583,60 @@ std::string LLScriptEdContainer::getTmpFileName(const std::string& script_name)
15691583
}
15701584
}
15711585

1586+
std::string LLScriptEdContainer::getErrorLogFileName(const std::string& script_path)
1587+
{
1588+
if (script_path.empty())
1589+
{
1590+
return std::string();
1591+
}
1592+
1593+
return script_path + ".log";
1594+
}
1595+
1596+
bool LLScriptEdContainer::logErrorsToFile(const LLSD& compile_errors)
1597+
{
1598+
if (!isOpenInExternalEditor())
1599+
{
1600+
return false;
1601+
}
1602+
1603+
std::string script_path = getTmpFileName(mScriptEd->mScriptName);
1604+
std::string log_path = getErrorLogFileName(script_path);
1605+
1606+
llofstream file(log_path.c_str());
1607+
if (!file.is_open())
1608+
{
1609+
LL_WARNS() << "Unable to open error log file: " << log_path << LL_ENDL;
1610+
return false;
1611+
}
1612+
1613+
// Write timestamp
1614+
std::string timestamp = LLLogChat::timestamp2LogString(0, true);
1615+
file << "// " << timestamp << "\n\n";
1616+
1617+
// Write errors
1618+
for (LLSD::array_const_iterator line = compile_errors.beginArray();
1619+
line < compile_errors.endArray();
1620+
line++)
1621+
{
1622+
std::string error_message = line->asString();
1623+
LLStringUtil::stripNonprintable(error_message);
1624+
file << error_message << "\n";
1625+
}
1626+
1627+
file.close();
1628+
1629+
// Create a log file handler if we don't already have one,
1630+
// this is needed to delete the temporary log file properly
1631+
if (!mLiveLogFile && !log_path.empty())
1632+
{
1633+
// Empty callback since we don't need to react to file changes
1634+
mLiveLogFile = new LLLiveLSLFile(log_path, [](const std::string& filename) { return true; });
1635+
}
1636+
1637+
return true;
1638+
}
1639+
15721640
bool LLScriptEdContainer::onExternalChange(const std::string& filename)
15731641
{
15741642
if (!mScriptEd->loadScriptText(filename))
@@ -1692,6 +1760,15 @@ void LLPreviewLSL::callbackLSLCompileSucceeded()
16921760
LL_INFOS() << "LSL Bytecode saved" << LL_ENDL;
16931761
mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful"));
16941762
mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete"));
1763+
1764+
if (isOpenInExternalEditor())
1765+
{
1766+
LLSD success_msg;
1767+
success_msg.append(LLTrans::getString("CompileSuccessful"));
1768+
success_msg.append(LLTrans::getString("SaveComplete"));
1769+
logErrorsToFile(success_msg);
1770+
}
1771+
16951772
closeIfNeeded();
16961773
}
16971774

@@ -1711,6 +1788,12 @@ void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors)
17111788
row["columns"][0]["font"] = "OCRA";
17121789
mScriptEd->mErrorList->addElement(row);
17131790
}
1791+
1792+
if (isOpenInExternalEditor())
1793+
{
1794+
logErrorsToFile(compile_errors);
1795+
}
1796+
17141797
mScriptEd->selectFirstError();
17151798
closeIfNeeded();
17161799
}
@@ -2042,6 +2125,15 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id,
20422125
LL_DEBUGS() << "LSL Bytecode saved" << LL_ENDL;
20432126
mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful"));
20442127
mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete"));
2128+
2129+
if (isOpenInExternalEditor())
2130+
{
2131+
LLSD success_msg;
2132+
success_msg.append(LLTrans::getString("CompileSuccessful"));
2133+
success_msg.append(LLTrans::getString("SaveComplete"));
2134+
logErrorsToFile(success_msg);
2135+
}
2136+
20452137
mRunningCheckbox->set(is_script_running);
20462138
mIsSaving = false;
20472139
closeIfNeeded();
@@ -2051,6 +2143,7 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id,
20512143
void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)
20522144
{
20532145
LL_DEBUGS() << "Compile failed!" << LL_ENDL;
2146+
20542147
for(LLSD::array_const_iterator line = compile_errors.beginArray();
20552148
line < compile_errors.endArray();
20562149
line++)
@@ -2063,6 +2156,12 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)
20632156
row["columns"][0]["font"] = "OCRA";
20642157
mScriptEd->mErrorList->addElement(row);
20652158
}
2159+
2160+
if (isOpenInExternalEditor())
2161+
{
2162+
logErrorsToFile(compile_errors);
2163+
}
2164+
20662165
mScriptEd->selectFirstError();
20672166
mIsSaving = false;
20682167
closeIfNeeded();

indra/newview/llpreviewscript.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ class LLScriptEdCore : public LLPanel
194194
S32 mLiveHelpHistorySize;
195195
bool mEnableSave;
196196
bool mHasScriptData;
197-
LLLiveLSLFile* mLiveFile;
198197
LLUUID mAssociatedExperience;
199198
bool mScriptRemoved;
200199
bool mSaveDialogShown;
@@ -215,16 +214,21 @@ class LLScriptEdContainer : public LLPreview
215214

216215
public:
217216
LLScriptEdContainer(const LLSD& key);
218-
LLScriptEdContainer(const LLSD& key, const bool live);
217+
virtual ~LLScriptEdContainer();
219218

220219
bool handleKeyHere(KEY key, MASK mask);
221220

222221
protected:
223222
std::string getTmpFileName(const std::string& script_name);
223+
std::string getErrorLogFileName(const std::string& script_path);
224224
bool onExternalChange(const std::string& filename);
225225
virtual void saveIfNeeded(bool sync = true) = 0;
226+
bool logErrorsToFile(const LLSD& compile_errors);
227+
bool isOpenInExternalEditor() const { return mLiveFile != nullptr; }
226228

227229
LLScriptEdCore* mScriptEd;
230+
LLLiveLSLFile* mLiveFile = nullptr;
231+
LLLiveLSLFile* mLiveLogFile = nullptr;
228232
};
229233

230234
// Used to view and edit an LSL script from your inventory.

0 commit comments

Comments
 (0)