1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
#ifndef SYNTAXCHECK_H
#define SYNTAXCHECK_H
#include "mostQtHeaders.h"
#include "smallUsefulFunctions.h"
#include "qdocumentline_p.h"
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <QQueue>
class LatexDocument;
/*!
* \brief store information on open environments
*/
class Environment
{
public:
Environment(): id(-1), excessCol(0), dlh(0), ticket(0), level(0) {} ///< constructor
QString name; ///< name of environment, partially an alias is used, e.g. math instead of '$'
QString origName; ///< original name of environment if alias is used, otherwise empty
int id; ///< mostly unused, contains the number of columns for tabular-environments
int excessCol; ///< number of unused tabular-columns if columns are strechted over several text lines
QDocumentLineHandle *dlh; ///< linehandle of starting line
int ticket;
int level; ///< command level (see tokens) in order to handle nested commands like \shortstack
bool operator ==(const Environment &env) const
{
return (name == env.name) && (id == env.id) && (excessCol == env.excessCol) && (origName == env.origName) && (level == env.level);
}
bool operator !=(const Environment &env) const
{
return (name != env.name) || (id != env.id) || (excessCol != env.excessCol) || (origName != env.origName) || (level != env.level);
}
};
typedef QStack<Environment> StackEnvironment;
Q_DECLARE_METATYPE(StackEnvironment)
class SyntaxCheck : public SafeThread
{
Q_OBJECT
public:
/*!
* \brief type of error
*/
enum ErrorType {
ERR_none, ///< no error
ERR_unrecognizedCommand, ///< command unknown
ERR_unrecognizedMathCommand, ///< unknown command for math environment
ERR_unrecognizedTabularCommand, ///< unknown command for tabular environment
ERR_TabularCommandOutsideTab, ///< tabular command outside tabular (e.g. \hline)
ERR_MathCommandOutsideMath, ///< math command outside of math env
ERR_TabbingCommandOutside, ///< tabbing command outside of tabbing env
ERR_tooManyCols, ///< tabular has more columns in line than in definition
ERR_tooLittleCols, ///< tabular has fewer columns in line than in definition
ERR_missingEndOfLine, ///< unused
ERR_closingUnopendEnv, ///< end{env} without corrresponding begin{env}
ERR_EnvNotClosed, ///< end{env} missing
ERR_unrecognizedKey, ///< in key/value argument, an unknown key is used
ERR_unrecognizedKeyValues ///< in key/value argument, an unknown value is used for a key
};
/*!
* \brief info which is queued for syntaxchecking
*/
struct SyntaxLine {
StackEnvironment prevEnv; ///< environmentstack at start of line
TokenStack stack; ///< tokenstack at start of line (open arguments)
int ticket; ///< ticket number
bool clearOverlay; ///< clear syntax overlay, sometimes not necessary as it was done somewhere else
QDocumentLineHandle *dlh; ///< linehandle
};
/*!
* \brief structure to describe an syntax error
*/
struct Error {
QPair<int, int> range; ///< start,stop of error marker
ErrorType type; ///< type of error
};
typedef QList<Error > Ranges;
explicit SyntaxCheck(QObject *parent = 0);
void putLine(QDocumentLineHandle *dlh, StackEnvironment previous, TokenStack stack, bool clearOverlay = false);
void stop();
void setErrFormat(int errFormat);
QString getErrorAt(QDocumentLineHandle *dlh, int pos, StackEnvironment previous, TokenStack stack);
int verbatimFormat; ///< format number for verbatim text (LaTeX)
void waitForQueueProcess();
static int containsEnv(const LatexParser &parser, const QString &name, const StackEnvironment &envs, const int id = -1);
int topEnv(const QString &name, const StackEnvironment &envs, const int id = -1);
bool checkCommand(const QString &cmd, const StackEnvironment &envs);
static bool equalEnvStack(StackEnvironment env1, StackEnvironment env2);
bool queuedLines();
void setLtxCommands(const LatexParser &cmds);
void markUnclosedEnv(Environment env);
signals:
void checkNextLine(QDocumentLineHandle *dlh, bool clearOverlay, int ticket); ///< enqueue next line for syntax checking as context has changed
protected:
void run();
void checkLine(const QString &line, Ranges &newRanges, StackEnvironment &activeEnv, QDocumentLineHandle *dlh, int ticket);
void checkLine(const QString &line, Ranges &newRanges, StackEnvironment &activeEnv, QDocumentLineHandle *dlh, TokenList tl, TokenStack stack, int ticket);
private:
QQueue<SyntaxLine> mLines;
QSemaphore mLinesAvailable;
QMutex mLinesLock;
bool stopped;
int syntaxErrorFormat;
LatexParser *ltxCommands;
LatexParser newLtxCommands;
bool newLtxCommandsAvailable;
QMutex mLtxCommandLock;
bool stackContainsDefinition(const TokenStack &stack) const;
};
#endif // SYNTAXCHECK_H
|