#include "support/debug.h"
#include "support/gettext.h"
#include "support/lstrings.h"
+#include "support/mutex.h"
#include "support/textutils.h"
#include "support/unicode.h"
CharInfo::CharInfo(
- docstring const textcommand, docstring const mathcommand,
- std::string const textpreamble, std::string const mathpreamble,
- std::string const tipashortcut, unsigned int flags)
+ docstring const & textcommand, docstring const & mathcommand,
+ std::string const & textpreamble, std::string const & mathpreamble,
+ std::string const & tipashortcut, unsigned int flags)
: textcommand_(textcommand), mathcommand_(mathcommand),
textpreamble_(textpreamble), mathpreamble_(mathpreamble),
tipashortcut_(tipashortcut), flags_(flags)
{
}
+
Encoding::Encoding(string const & n, string const & l, string const & g,
string const & i, bool f, bool u, Encoding::Package p)
: name_(n), latexName_(l), guiName_(g), iconvName_(i), fixedwidth_(f),
void Encoding::init() const
{
+ // Since the the constructor is the only method which sets complete_
+ // to false the test for complete_ is thread-safe without mutex.
+ if (complete_)
+ return;
+
+ static Mutex mutex;
+ Mutex::Locker lock(&mutex);
+
+ // We need to test again for complete_, since another thread could
+ // have set it to true while we were waiting for the lock and we must
+ // not modify an encoding which is already complete.
if (complete_)
return;
- start_encodable_ = 0;
+ // We do not make any member mutable so that it can be easily verified
+ // that all const methods are thread-safe: init() is the only const
+ // method which changes complete_, encodable_ and start_encodable_, and
+ // it uses a mutex to ensure thread-safety.
+ CharSet & encodable = const_cast<Encoding *>(this)->encodable_;
+ char_type & start_encodable = const_cast<Encoding *>(this)->start_encodable_;
+
+ start_encodable = 0;
// temporarily switch off lyxerr, since we will generate iconv errors
lyxerr.disable();
if (fixedwidth_) {
char_type const uc = ucs4[0];
CharInfoMap::const_iterator const it = unicodesymbols.find(uc);
if (it == unicodesymbols.end())
- encodable_.insert(uc);
+ encodable.insert(uc);
else if (!it->second.force()) {
if (forced_->empty() || forced_->find(uc) == forced_->end())
- encodable_.insert(uc);
+ encodable.insert(uc);
}
}
} else {
if (!eightbit.empty()) {
CharInfoMap::const_iterator const it = unicodesymbols.find(c);
if (it == unicodesymbols.end())
- encodable_.insert(c);
+ encodable.insert(c);
else if (!it->second.force()) {
if (forced_->empty() || forced_->find(c) == forced_->end())
- encodable_.insert(c);
+ encodable.insert(c);
}
}
}
}
lyxerr.enable();
- CharSet::iterator it = encodable_.find(start_encodable_);
- while (it != encodable_.end()) {
- encodable_.erase(it);
- ++start_encodable_;
- it = encodable_.find(start_encodable_);
+ CharSet::iterator it = encodable.find(start_encodable);
+ while (it != encodable.end()) {
+ encodable.erase(it);
+ ++start_encodable;
+ it = encodable.find(start_encodable);
}
- complete_ = true;
+ const_cast<Encoding *>(this)->complete_ = true;
}
}
-pair<docstring, docstring> Encoding::latexString(docstring const input, bool dryrun) const
+pair<docstring, docstring> Encoding::latexString(docstring const & input, bool dryrun) const
{
docstring result;
docstring uncodable;
|| (tmp.size() == prefix + 1 &&
!isAlphaASCII(tmp[1]) &&
(prefix == 1 || !isAlphaASCII(tmp[2])))
- || k == cmdend
+ || k == cmdend
|| !isAlphaASCII(cmd[k])
|| tmp[tmp.size() - 1] == '}'
) {
Encodings::fromLyXName(string const & name, bool allowUnsafe) const
{
EncodingList::const_iterator const it = encodinglist.find(name);
+ if (it == encodinglist.end())
+ return 0;
if (!allowUnsafe && it->second.unsafe())
return 0;
- return it != encodinglist.end() ? &it->second : 0;
+ return &it->second;
}
if (!symbolslex.next(true))
break;
string sflags = symbolslex.getString();
-
+
string tipashortcut;
int flags = 0;