lyx_mirror/src/Trans.h
Jean-Marc Lasgouttes 8ea9c2da03 Avoid a couple copies in Trans::addDeadKeys().
Spotted by Coverity scan.
2024-09-12 17:24:32 +02:00

353 lines
5.9 KiB
C++

// -*- C++ -*-
/**
* \file Trans.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Lars Gullik Bjønnes
* \author Matthias Ettrich
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#ifndef TRANS_H
#define TRANS_H
#include "FuncCode.h"
#include "support/docstring.h"
#include <list>
#include <map>
namespace lyx {
class Cursor;
class Text;
class TransManager;
namespace support { class Lexer; }
///
enum tex_accent {
///
TEX_NOACCENT = 0,
///
TEX_ACUTE,
///
TEX_GRAVE,
///
TEX_MACRON,
///
TEX_TILDE,
///
TEX_PERISPOMENI,
///
TEX_UNDERBAR,
///
TEX_CEDILLA,
///
TEX_UNDERDOT,
///
TEX_CIRCUMFLEX,
///
TEX_CIRCLE,
///
TEX_TIE,
///
TEX_BREVE,
///
TEX_CARON,
// TEX_SPECIAL_CARON,
///
TEX_HUNGUML,
///
TEX_UMLAUT,
///
TEX_DOT,
///
TEX_OGONEK,
///
TEX_MAX_ACCENT = TEX_OGONEK
};
struct TeXAccent {
///
tex_accent accent;
/// UCS4 code point of this accent
char_type ucs4;
///
char const * name;
///
FuncCode action;
};
///
extern TeXAccent get_accent(FuncCode action);
///
struct Keyexc {
///
Keyexc() : c('\0'), combined(false), accent(TEX_NOACCENT) {}
/// character to make exception
char_type c;
/// exception data
docstring data;
/// Combination with another deadkey
bool combined;
/// The accent comined with
tex_accent accent;
};
///
typedef std::list<Keyexc> KmodException;
///
class KmodInfo {
public:
///
KmodInfo() : accent(TEX_NOACCENT) {}
///
KmodInfo(docstring const & d, tex_accent a, KmodException const & e)
: data(d), accent(a), exception_list(e) {}
///
docstring data;
///
tex_accent accent;
///
KmodException exception_list;
};
/////////////////////////////////////////////////////////////////////
//
// Trans: holds a .kmap file
//
/////////////////////////////////////////////////////////////////////
class Trans {
public:
///
Trans() {}
///
~Trans() { freeKeymap(); }
///
int load(std::string const & language);
///
bool isDefined() const;
///
std::string const & getName() const { return name_; }
///
docstring const process(char_type, TransManager &);
///
bool isAccentDefined(tex_accent, KmodInfo &) const;
private:
///
void addDeadkey(tex_accent, docstring const &);
///
void freeKeymap();
///
int load(support::Lexer &);
///
docstring const & match(char_type c);
///
void insertException(KmodException & exclist, char_type c,
docstring const & data, bool = false,
tex_accent = TEX_NOACCENT);
///
void freeException(KmodException & exclist);
///
std::string name_;
///
std::map<char_type, docstring> keymap_;
///
std::map<tex_accent, KmodInfo> kmod_list_;
};
///
inline docstring const & Trans::match(char_type c)
{
std::map<char_type, docstring>::iterator it = keymap_.find(c);
if (it != keymap_.end()) {
return it->second;
}
static docstring dummy;
return dummy;
}
/////////////////////////////////////////////////////////////////////
//
// TransState
//
/////////////////////////////////////////////////////////////////////
/// Translation state
class TransState {
public:
///
virtual ~TransState() {}
///
virtual docstring const normalkey(char_type) = 0;
///
virtual bool backspace() = 0;
///
virtual docstring const deadkey(char_type, KmodInfo const &) = 0;
///
static char_type const TOKEN_SEP;
};
/// Translation FSM
class TransFSMData {
protected:
///
virtual ~TransFSMData() {}
///
char_type deadkey_;
///
KmodInfo deadkey_info_;
///
char_type deadkey2_;
///
KmodInfo deadkey2_info_;
///
Keyexc comb_info_;
///
TransState * init_state_;
///
TransState * deadkey_state_;
///
TransState * combined_state_;
///
public:
///
TransFSMData();
///
TransState * currentState;
};
/// Init State
class TransInitState : virtual public TransFSMData, public TransState {
public:
///
TransInitState();
///
docstring const normalkey(char_type) override;
///
bool backspace() override { return true; }
///
docstring const deadkey(char_type, KmodInfo const &) override;
};
/// Deadkey State
class TransDeadkeyState : virtual public TransFSMData, public TransState {
public:
///
TransDeadkeyState();
///
docstring const normalkey(char_type) override;
///
bool backspace() override {
currentState = init_state_;
return false;
}
///
docstring const deadkey(char_type, KmodInfo const &) override;
};
/// Combined State
class TransCombinedState : virtual public TransFSMData, public TransState {
public:
///
TransCombinedState();
///
docstring const normalkey(char_type) override;
///
bool backspace() override {
// cancel the second deadkey
deadkey2_ = 0;
deadkey2_info_.accent = TEX_NOACCENT;
currentState = deadkey_state_;
return false;
}
///
docstring const deadkey(char_type, KmodInfo const &) override;
};
///
class TransFSM : virtual public TransFSMData,
public TransInitState,
public TransDeadkeyState,
public TransCombinedState {
public:
///
TransFSM();
};
/////////////////////////////////////////////////////////////////////
//
// TransManager
//
/////////////////////////////////////////////////////////////////////
class TransManager {
private:
///
TransFSM trans_fsm_;
///
Trans * active_;
///
Trans t1_;
///
Trans t2_;
///
static Trans default_;
///
void insert(docstring const &, Text *, Cursor & cur);
public:
///
TransManager();
///
int setPrimary(std::string const &);
///
int setSecondary(std::string const &);
///
void enablePrimary();
///
void enableSecondary();
///
void disableKeymap();
///
bool backspace() { return trans_fsm_.currentState->backspace(); }
///
void translateAndInsert(char_type, Text *, Cursor &);
///
docstring const deadkey(char_type c, KmodInfo const & t)
{ return trans_fsm_.currentState->deadkey(c, t); }
///
docstring const normalkey(char_type c)
{ return trans_fsm_.currentState->normalkey(c); }
///
void deadkey(char_type, tex_accent, Text *, Cursor &);
};
} // namespace lyx
#endif // TRANS_H