File: buildmanager.h

package info (click to toggle)
texstudio 2.12.14%2Bdebian-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 48,048 kB
  • sloc: cpp: 97,886; xml: 10,243; ansic: 8,127; sh: 158; makefile: 33
file content (320 lines) | stat: -rw-r--r-- 12,698 bytes parent folder | download
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#ifndef BUILDMANAGER_H
#define BUILDMANAGER_H

#include "mostQtHeaders.h"

class ProcessX;

struct PreviewSource {
	QString text;
	int fromLine, toLine;
	bool atCursor;
	PreviewSource(): fromLine(0), toLine(0), atCursor(false) {}
	PreviewSource(const QString &text, int fromLine, int toLine, bool atCursor):
		text(text), fromLine(fromLine), toLine(toLine), atCursor(atCursor) {}
};

enum LatexCompileResult {
	LCR_NORMAL = 0,
	LCR_ERROR,
	LCR_RERUN,
	LCR_RERUN_WITH_BIBLIOGRAPHY
};
Q_DECLARE_METATYPE(LatexCompileResult)


enum RunCommandFlag {
	RCF_SHOW_STDOUT = 1,    //bibliography command (=> show stdout)
	RCF_COMPILES_TEX = 4, //latex command, show the log
	RCF_RERUNNABLE = 8,   //rerun if there are errors (usually RCF_RERUNNABLE is set iff RCF_COMPILES_TEX is set, except for latexmk)
	RCF_RERUN = 16,
	RCF_CHANGE_PDF = 32,    //pdflatex (=> lock pdf)
	RCF_SINGLE_INSTANCE = 64,//viewer (=> start only once)
	RCF_WAITFORFINISHED = 128
};
Q_DECLARE_FLAGS(RunCommandFlags, RunCommandFlag)

struct CommandToRun {
	QString command;
	QString parentCommand;
	RunCommandFlags flags;
	CommandToRun();
	CommandToRun(const QString &cmd);
};

struct ExpandedCommands {
	QString primaryCommand;
	QList<CommandToRun> commands;
};

typedef QString (*GuessCommandLineFunc) ();
struct CommandInfo {
	CommandInfo();
	QString id;
	QString commandLine;

	QString defaultArgs;
	QString displayName;
	bool user;
	bool meta;
	bool rerunCompiler;

	QStringList metaSuggestionList;
	QStringList simpleDescriptionList;

	QString guessCommandLine() const;
	//sets a command (accepts tr("<unknown>"))
	void setCommandLine(const QString &newCmd);

	QString getPrettyCommand() const;
	QString getBaseName() const { return baseName; }
    QString getProgramName() const;
    QString getProgramNameUnquoted() const;
private:
	friend class BuildManager;
	QString baseName;
	GuessCommandLineFunc guessFunc;
	QString deprecatedConfigName;
public:
	static QString getProgramName(const QString &commandLine);
	static QString getProgramNameUnquoted(const QString &commandLine);
};

struct ExpandingOptions {
	ExpandingOptions(const QFileInfo &mainFile, const QFileInfo &currentFile = QFileInfo(), const int currentLine = 0);
	const QFileInfo mainFile;
	const QFileInfo currentFile;
	const int currentLine;
	int nestingDeep;
	bool canceled;
	struct ParameterOverride {
		QList<QPair<QString, QString> > replace;
		QStringList append;
		QStringList remove;
		bool removeAll;
	};
	ParameterOverride override;
};

typedef QHash<QString, CommandInfo> CommandMapping;

class ConfigManagerInterface;

class BuildManager: public QObject
{
	Q_OBJECT

public:
	BuildManager();
	~BuildManager();

	static const QString TXS_CMD_PREFIX;
	static const QString CMD_LATEX, CMD_PDFLATEX, CMD_XELATEX, CMD_LUALATEX, CMD_LATEXMK;
	static const QString CMD_VIEW_DVI, CMD_VIEW_PS, CMD_VIEW_PDF, CMD_VIEW_LOG;
	static const QString CMD_DVIPNG, CMD_DVIPS, CMD_DVIPDF, CMD_PS2PDF, CMD_GS, CMD_MAKEINDEX, CMD_TEXINDY, CMD_MAKEGLOSSARIES, CMD_METAPOST, CMD_ASY, CMD_BIBTEX, CMD_BIBTEX8, CMD_BIBER, CMD_SVN, CMD_SVNADMIN;
	static const QString CMD_COMPILE, CMD_VIEW, CMD_BIBLIOGRAPHY, CMD_INDEX, CMD_GLOSSARY, CMD_QUICK, CMD_RECOMPILE_BIBLIOGRAPHY;
	static const QString CMD_VIEW_PDF_INTERNAL, CMD_INTERNAL_PRE_COMPILE, CMD_CONDITIONALLY_RECOMPILE_BIBLIOGRAPHY;

	static QString chainCommands(const QString &a);
	static QString chainCommands(const QString &a, const QString &b);
	static QString chainCommands(const QString &a, const QString &b, const QString &c);
	static QString chainCommands(const QString &a, const QString &b, const QString &c, const QString &d);

	static QStringList splitOptions(const QString &s);
	static QString findFileInPath(QString fileName);
	static QString replaceEnvironmentVariables(const QString &s);
	static QString replaceEnvironmentVariables(const QString &s, const QHash<QString, QString> &variables, bool compareNamesToUpper);
	static QString resolvePaths(QString paths);
	static QStringList parseExtendedCommandLine(QString str, const QFileInfo &mainFile, const QFileInfo &currentFile = QFileInfo(), int currentLine = 0);
	static QString extractOutputRedirection(const QString &commandLine, QString &stdOut, QString &stdErr);
	ExpandedCommands expandCommandLine(const QString &str, ExpandingOptions &expandingOptions);
	RunCommandFlags getSingleCommandFlags(const QString &command) const;
	bool hasCommandLine(const QString &program);

	void registerOptions(ConfigManagerInterface &cmi);
	void readSettings(QSettings &settings);
	void saveSettings(QSettings &settings);

	void checkLatexConfiguration(bool &noWarnAgain);

	QAction *stopBuildAction()
	{
		return m_stopBuildAction;
	}

public slots:
    bool runCommand(const QString &unparsedCommandLine, const QFileInfo &mainFile, const QFileInfo &currentFile = QFileInfo(), int currentLine = 0, QString *buffer = nullptr, QTextCodec *codecForBuffer = nullptr);
	Q_INVOKABLE void killCurrentProcess();
private:
	bool checkExpandedCommands(const ExpandedCommands &expandedCommands);
    bool runCommandInternal(const ExpandedCommands &expandedCommands, const QFileInfo &mainFile, QString *buffer = nullptr, QTextCodec *codecForBuffer = nullptr);
public:
	//creates a process object with the given command line (after it is changed by an implcit call to parseExtendedCommandLine)
	//ProcessX* newProcess(const QString &unparsedCommandLine, const QString &mainFile, const QString &currentFile, int currentLine=0, bool singleInstance = false);
	//QList<ProcessX*> newProcesses(const QString &unparsedCommandLine, const QString &mainFile, const QString &currentFile, int currentLine=0, bool singleInstance = false);
    Q_INVOKABLE ProcessX *firstProcessOfDirectExpansion(const QString &command, const QFileInfo &mainfile, const QFileInfo &currentFile = QFileInfo(), int currentLine = 0, bool nonstop=false);

	Q_INVOKABLE ProcessX *newProcessInternal(const QString &fullCommandLine, const QFileInfo &mainFile, bool singleInstance = false);
public:
	Q_INVOKABLE bool waitForProcess(ProcessX *p);
	Q_INVOKABLE bool waitingForProcess() const;

	static QString createTemporaryFileName(); //don't forget to remove the file!

    void preview(const QString &preamble, const PreviewSource &source, const QString &masterFile, QTextCodec *outputCodec = nullptr);
	void clearPreviewPreambleCache();

	Q_INVOKABLE bool isCommandDirectlyDefined(const QString &id) const;
	CommandInfo getCommandInfo(const QString &id) const;
	QString editCommandList(const QString &list, const QString &excludeId = "");
	CommandMapping getAllCommands();
	QStringList getCommandsOrder();
	void setAllCommands(const CommandMapping &commands, const QStringList &userOrder);
	QString guessCompilerFromProgramMagicComment(const QString &program);
	QString guessViewerFromProgramMagicComment(const QString &program);

	int maxExpandingNestingDeep;

	int previewCompileTimeOut;

	int deprecatedQuickmode;
	QStringList deprecatedUserToolCommands, deprecatedUserToolNames;
	QStringList userToolOrder, userToolDisplayNames;
	enum Dvi2PngMode { DPM_DVIPNG, DPM_DVIPNG_FOLLOW, DPM_DVIPS_GHOSTSCRIPT, DPM_EMBEDDED_PDF};
	Dvi2PngMode dvi2pngMode;
	enum SaveFilesBeforeCompiling {SFBC_ALWAYS, SFBC_ONLY_CURRENT_OR_NAMED, SFBC_ONLY_NAMED};
	SaveFilesBeforeCompiling saveFilesBeforeCompiling;
	bool previewRemoveBeamer, previewPrecompilePreamble;
private slots:
	void singleInstanceCompleted(int status);
	void preamblePrecompileCompleted(int status);
	void latexPreviewCompleted(int status);
	void dvi2psPreviewCompleted(int status);
	void conversionPreviewCompleted(int status);
    void PreviewLatexCompleted(int status);
	void commandLineRequestedDefault(const QString &cmdId, QString *result, bool *user);
	void runInternalCommandThroughProcessX();
	void emitEndRunningSubCommandFromProcessX(int);
private:
	bool testAndRunInternalCommand(const QString &cmd, const QFileInfo &mainFile);
signals:
	void hideSplash();
	void processNotification(const QString &message);
    void clearLogs();
	void previewAvailable(const QString &filename, const PreviewSource &source);

    void commandLineRequested(const QString &cmdId, QString *result, bool *user = nullptr);
	void runInternalCommand(const QString &cmdId, const QFileInfo &mainfile, const QString &options);

	void latexCompiled(LatexCompileResult *rerun);
	void beginRunningCommands(const QString &commandMain, bool latex, bool pdf, bool asyncPdf);
	void beginRunningSubCommand(ProcessX *p, const QString &commandMain, const QString &subCommand, const RunCommandFlags &flags);
	void endRunningSubCommand(ProcessX *p, const QString &commandMain, const QString &subCommand, const RunCommandFlags &flags);
	void endRunningCommands(const QString &commandMain, bool latex, bool pdf, bool asyncPdf);
private:

	void initDefaultCommandNames();
	void checkOSXElCapitanDeprecatedPaths(QSettings &settings, const QStringList &commands);

    CommandInfo &registerCommand(const QString &id, const QString &basename, const QString &displayName, const QString &args, const QString &oldConfig = "", GuessCommandLineFunc guessFunc = nullptr, bool user = false);
	CommandInfo &registerCommand(const QString &id, const QString &displayname, const QStringList &alternatives, const QString &oldConfig = "", const bool metaCommand = true, const QStringList simpleDescriptions = QStringList());
	Q_INVOKABLE QString getCommandLine(const QString &id, bool *user);
	friend class ProcessX;
	CommandMapping commands;
	QStringList internalCommands, commandSortingsOrder;
	QMap<QString, ProcessX *> runningCommands;
	QPointer<ProcessX> processWaitedFor;

	QStringList latexCommands, rerunnableCommands, pdfCommands, stdoutCommands, viewerCommands;
public:
	static int autoRerunLatex;
	static bool showLogInCaseOfCompileError;
	static bool m_replaceEnvironmentVariables;
	static bool m_interpetCommandDefinitionInMagicComment;
	static bool m_supportShellStyleLiteralQuotes;
	static bool singleViewerInstance;
	static QString autoRerunCommands;
	static QString additionalSearchPaths, additionalLogPaths, additionalPdfPaths;

	QString findFile(const QString &baseName, const QStringList &searchPaths);
	void addPreviewFileName(QString fn)
	{
		if (!previewFileNames.contains(fn))
			previewFileNames.append(fn);
	}

private:
	QAction *m_stopBuildAction;
	QStringList previewFileNames;
	QMap<QString, PreviewSource> previewFileNameToSource;
	QHash<QString, QString> preambleHash;
	void removePreviewFiles(QString elemName);
#ifdef Q_OS_WIN32
	unsigned long int pidInst;
	Q_INVOKABLE bool executeDDE(QString ddePseudoURL);
#endif
};

//#define PROFILE_PROCESSES
Q_DECLARE_METATYPE(ProcessX *)
//this process can handle dde and normal commands
class ProcessX: public QProcess
{
	Q_OBJECT

public:
    ProcessX(BuildManager *parent = nullptr, const QString &assignedCommand = "", const QString &fileToCompile = "");
	static QString reformatShellLiteralQuotes(QString cmd);
	void startCommand();
	bool waitForStarted(int timeOut = 30000);
	const QString &getFile();
	const QString &getCommandLine();
	bool showStdout() const;
	void setShowStdout(bool show);
	QString *getStdoutBuffer();
	void setStdoutBuffer(QString *buffer);
	void setStdoutCodec(QTextCodec *codec);
	bool showStderr() const;
	void setShowStderr(bool show);
	void setOverrideEnvironment(const QStringList &env);
	const QStringList &overrideEnvironment();

	Q_INVOKABLE int exitStatus() const;
	Q_INVOKABLE int exitCode() const;
	Q_INVOKABLE QString readAllStandardOutputStr();
	Q_INVOKABLE QString readAllStandardErrorStr();
	Q_INVOKABLE bool waitForFinished ( int msecs = 30000 );

	bool isRunning() const;
signals:
	void startedX();

	void processNotification(const QString &message);
	void standardOutputRead(const QString &data);
	void standardErrorRead(const QString &data);
private slots:
	void onStarted();
	void onError(QProcess::ProcessError error);
	void onFinished(int error);
#ifdef PROFILE_PROCESSES
	void finished();
#endif
	void readFromStandardOutput();
	void readFromStandardError(bool force = false);
private:
	friend class BuildManager;
	QString cmd;
	QString file;
	bool isStarted, ended, stderrEnabled, stdoutEnabled, stdoutEnabledOverrideOn;
	QString *stdoutBuffer;
	QTextCodec *stdoutCodec;
	QStringList overriddenEnvironment;
	QString subCommandName, subCommandPrimary;
	RunCommandFlags subCommandFlags;
#ifdef PROFILE_PROCESSES
	QTime time;
#endif
};


#endif // BUILDMANAGER_H