- fix: auto syntax check fail, if the file is not gbk and includes files encoded with utf8

- fix: running programs with input redirected can't exit at once.
This commit is contained in:
Roy Qu 2022-03-31 09:56:49 +08:00
parent c30164a58a
commit f0c0197380
13 changed files with 62 additions and 51 deletions

View File

@ -4,7 +4,7 @@ Red Panda C++ Version 1.0.2
- enhancement: better display when input with IM under column mode
- enhancement: better display current lines under column mode
- change: test to use utf-8 as the default encoding (prepare to use libclang to implement parser)
- fix: auto syntax check use wrong charset, if a file in editing is not encoded with ANSI encoding
- fix: auto syntax check fail, if the file is not gbk and includes files encoded with utf8
- enhancement: timeout for problem case test
- enhancement: slightly reduce start up time
- enhancement: use icon to indicate missing project files in the project view

View File

@ -181,6 +181,11 @@ Settings::PCompilerSet Compiler::compilerSet()
return pSettings->compilerSets().defaultSet();
}
QByteArray Compiler::pipedText()
{
return QByteArray();
}
void Compiler::processOutput(QString &line)
{
if (line == COMPILE_PROCESS_END) {
@ -276,7 +281,7 @@ void Compiler::stopCompile()
mStop = true;
}
QString Compiler::getCharsetArgument(const QByteArray& encoding)
QString Compiler::getCharsetArgument(const QByteArray& encoding, bool checkSyntax)
{
QString result;
if (compilerSet()->autoAddCharsetParams() && encoding != ENCODING_ASCII
@ -297,10 +302,14 @@ QString Compiler::getCharsetArgument(const QByteArray& encoding)
} else {
execEncodingName = compilerSetExecCharset;
}
if (encodingName!=execEncodingName)
if (checkSyntax) {
result += QString(" -finput-charset=%1")
.arg(encodingName);
} else if (encodingName!=execEncodingName) {
result += QString(" -finput-charset=%1 -fexec-charset=%2")
.arg(encodingName, execEncodingName);
}
}
return result;
}
@ -551,7 +560,7 @@ QString Compiler::parseFileIncludesForAutolink(
return result;
}
void Compiler::runCommand(const QString &cmd, const QString &arguments, const QString &workingDir, const QString& inputText)
void Compiler::runCommand(const QString &cmd, const QString &arguments, const QString &workingDir, const QByteArray& inputText)
{
QProcess process;
mStop = false;
@ -591,11 +600,17 @@ void Compiler::runCommand(const QString &cmd, const QString &arguments, const Q
});
process.start();
process.waitForStarted(5000);
if (!inputText.isEmpty())
process.write(inputText.toLocal8Bit());
process.closeWriteChannel();
if (!inputText.isEmpty()) {
process.write(inputText);
process.waitForFinished(0);
}
bool writeChannelClosed = false;
while (true) {
process.waitForFinished(1000);
if (process.bytesToWrite()==0 && !writeChannelClosed ) {
writeChannelClosed=true;
process.closeWriteChannel();
}
process.waitForFinished(100);
if (process.state()!=QProcess::Running) {
break;
}

View File

@ -62,9 +62,9 @@ protected:
protected:
virtual Settings::PCompilerSet compilerSet();
virtual bool prepareForCompile() = 0;
virtual QString pipedText() = 0;
virtual QByteArray pipedText();
virtual bool prepareForRebuild() = 0;
virtual QString getCharsetArgument(const QByteArray& encoding);
virtual QString getCharsetArgument(const QByteArray& encoding,bool onlyCheckSyntax);
virtual QString getCCompileArguments(bool checkSyntax);
virtual QString getCppCompileArguments(bool checkSyntax);
virtual QString getCIncludeArguments();
@ -77,7 +77,7 @@ protected:
PCppParser& parser);
void log(const QString& msg);
void error(const QString& msg);
void runCommand(const QString& cmd, const QString& arguments, const QString& workingDir, const QString& inputText=QString());
void runCommand(const QString& cmd, const QString& arguments, const QString& workingDir, const QByteArray& inputText=QByteArray());
protected:
bool mSilent;

View File

@ -178,13 +178,20 @@ void ExecutableRunner::run()
mProcess->waitForStarted(5000);
if (mProcess->state()==QProcess::Running && redirectInput()) {
mProcess->write(readFileToByteArray(redirectInputFilename()));
mProcess->waitForFinished(0);
}
bool writeChannelClosed = false;
while (true) {
if (mProcess->bytesToWrite()==0 && redirectInput() && !writeChannelClosed) {
writeChannelClosed=true;
mProcess->closeWriteChannel();
}
mProcess->waitForFinished(mWaitForFinishTime);
if (mProcess->state()!=QProcess::Running) {
break;
}
if (errorOccurred)
break;
if (mStop) {
mProcess->terminate();
if (mProcess->waitForFinished(1000)) {
@ -198,10 +205,6 @@ void ExecutableRunner::run()
}
break;
}
if (mProcess->bytesToWrite()==0 && redirectInput() && !writeChannelClosed) {
writeChannelClosed=true;
mProcess->closeWriteChannel();
}
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
if (mStartConsole && !mPausing && pBuf) {
if (strncmp(pBuf,"FINISHED",sizeof("FINISHED"))==0) {
@ -229,8 +232,6 @@ void ExecutableRunner::run()
}
}
#endif
if (errorOccurred)
break;
}
#ifdef Q_OS_WIN
if (pBuf)

View File

@ -54,7 +54,7 @@ bool FileCompiler::prepareForCompile()
}
}
mArguments += getCharsetArgument(mEncoding);
mArguments += getCharsetArgument(mEncoding, mOnlyCheckSyntax);
QString strFileType;
switch(fileType) {
case FileType::CSource:
@ -90,11 +90,6 @@ bool FileCompiler::prepareForCompile()
return true;
}
QString FileCompiler::pipedText()
{
return QString();
}
bool FileCompiler::prepareForRebuild()
{
QString exeName = getCompiledExecutableName(mFilename);

View File

@ -32,10 +32,6 @@ protected:
private:
QByteArray mEncoding;
// Compiler interface
protected:
QString pipedText() override;
// Compiler interface
protected:
bool prepareForRebuild() override;

View File

@ -92,10 +92,15 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
process.write(readFileToByteArray(problemCase->inputFileName));
else
process.write(problemCase->input.toUtf8());
process.waitForFinished(0);
}
elapsedTimer.start();
while (true) {
if (process.bytesToWrite()==0 && !writeChannelClosed) {
writeChannelClosed = true;
process.closeWriteChannel();
}
process.waitForFinished(mWaitForFinishTime);
if (process.state()!=QProcess::Running) {
break;
@ -113,10 +118,6 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
}
if (errorOccurred)
break;
if (process.bytesToWrite()==0 && !writeChannelClosed) {
writeChannelClosed = true;
process.closeWriteChannel();
}
readed = process.read(mBufferSize);
buffer += readed;
if (buffer.length()>=mBufferSize || noOutputTime > mOutputRefreshTime) {

View File

@ -461,11 +461,6 @@ void ProjectCompiler::setOnlyClean(bool newOnlyClean)
mOnlyClean = newOnlyClean;
}
QString ProjectCompiler::pipedText()
{
return QString();
}
bool ProjectCompiler::prepareForRebuild()
{
//we use make argument to clean

View File

@ -48,7 +48,6 @@ private:
bool mOnlyClean;
protected:
bool prepareForCompile() override;
QString pipedText() override;
bool prepareForRebuild() override;
};

View File

@ -24,7 +24,7 @@ Runner::Runner(const QString &filename, const QString &arguments, const QString
mFilename(filename),
mArguments(arguments),
mWorkDir(workDir),
mWaitForFinishTime(1000)
mWaitForFinishTime(100)
{
}

View File

@ -18,10 +18,11 @@
#include "compilermanager.h"
#include <QFile>
#include <QFileInfo>
#include <QTextCodec>
#include "../platform.h"
StdinCompiler::StdinCompiler(const QString &filename,const QByteArray& encoding, const QString& content,bool silent, bool onlyCheckSyntax):
Compiler(filename,silent,onlyCheckSyntax),
Compiler(filename,silent, onlyCheckSyntax),
mContent(content),
mEncoding(encoding)
{
@ -39,8 +40,9 @@ bool StdinCompiler::prepareForCompile()
if (fileType == FileType::Other)
fileType = FileType::CppSource;
QString strFileType;
if (mEncoding!=ENCODING_ASCII && (!mOnlyCheckSyntax || mEncoding != ENCODING_UTF8 ))
mArguments += getCharsetArgument(mEncoding);
if (mEncoding!=ENCODING_ASCII) {
mArguments += getCharsetArgument(mEncoding, mOnlyCheckSyntax);
}
switch(fileType) {
case FileType::CSource:
mArguments += " -x c - ";
@ -78,9 +80,17 @@ bool StdinCompiler::prepareForCompile()
return true;
}
QString StdinCompiler::pipedText()
QByteArray StdinCompiler::pipedText()
{
return mContent;
if (mEncoding == ENCODING_ASCII)
return mContent.toLatin1();
QTextCodec* codec = QTextCodec::codecForName(mEncoding);
if (codec) {
return codec->fromUnicode(mContent);
} else {
return mContent.toLocal8Bit();
}
}
bool StdinCompiler::prepareForRebuild()

View File

@ -35,7 +35,7 @@ private:
// Compiler interface
protected:
QString pipedText() override;
QByteArray pipedText() override;
// Compiler interface
protected:

View File

@ -1415,9 +1415,6 @@ void DebugReader::run()
break;
}
if (mStop) {
mProcess->closeReadChannel(QProcess::StandardOutput);
mProcess->closeReadChannel(QProcess::StandardError);
mProcess->closeWriteChannel();
mProcess->terminate();
mProcess->kill();
break;
@ -2401,17 +2398,19 @@ void DebugTarget::run()
mStartSemaphore.release(1);
if (mProcess->state()==QProcess::Running && !mInputFile.isEmpty()) {
mProcess->write(readFileToByteArray(mInputFile));
mProcess->waitForFinished(0);
}
bool writeChannelClosed = false;
while (true) {
if (mProcess->bytesToWrite()==0 && !writeChannelClosed) {
writeChannelClosed = true;
mProcess->closeWriteChannel();
}
while (true) {
mProcess->waitForFinished(1);
if (mProcess->state()!=QProcess::Running) {
break;
}
if (mStop) {
mProcess->closeReadChannel(QProcess::StandardOutput);
mProcess->closeReadChannel(QProcess::StandardError);
mProcess->closeWriteChannel();
mProcess->terminate();
mProcess->kill();
break;