- 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 when input with IM under column mode
- enhancement: better display current lines 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) - 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: timeout for problem case test
- enhancement: slightly reduce start up time - enhancement: slightly reduce start up time
- enhancement: use icon to indicate missing project files in the project view - 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(); return pSettings->compilerSets().defaultSet();
} }
QByteArray Compiler::pipedText()
{
return QByteArray();
}
void Compiler::processOutput(QString &line) void Compiler::processOutput(QString &line)
{ {
if (line == COMPILE_PROCESS_END) { if (line == COMPILE_PROCESS_END) {
@ -276,7 +281,7 @@ void Compiler::stopCompile()
mStop = true; mStop = true;
} }
QString Compiler::getCharsetArgument(const QByteArray& encoding) QString Compiler::getCharsetArgument(const QByteArray& encoding, bool checkSyntax)
{ {
QString result; QString result;
if (compilerSet()->autoAddCharsetParams() && encoding != ENCODING_ASCII if (compilerSet()->autoAddCharsetParams() && encoding != ENCODING_ASCII
@ -297,9 +302,13 @@ QString Compiler::getCharsetArgument(const QByteArray& encoding)
} else { } else {
execEncodingName = compilerSetExecCharset; 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") result += QString(" -finput-charset=%1 -fexec-charset=%2")
.arg(encodingName, execEncodingName); .arg(encodingName, execEncodingName);
}
} }
return result; return result;
} }
@ -551,7 +560,7 @@ QString Compiler::parseFileIncludesForAutolink(
return result; 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; QProcess process;
mStop = false; mStop = false;
@ -591,11 +600,17 @@ void Compiler::runCommand(const QString &cmd, const QString &arguments, const Q
}); });
process.start(); process.start();
process.waitForStarted(5000); process.waitForStarted(5000);
if (!inputText.isEmpty()) if (!inputText.isEmpty()) {
process.write(inputText.toLocal8Bit()); process.write(inputText);
process.closeWriteChannel(); process.waitForFinished(0);
}
bool writeChannelClosed = false;
while (true) { while (true) {
process.waitForFinished(1000); if (process.bytesToWrite()==0 && !writeChannelClosed ) {
writeChannelClosed=true;
process.closeWriteChannel();
}
process.waitForFinished(100);
if (process.state()!=QProcess::Running) { if (process.state()!=QProcess::Running) {
break; break;
} }

View File

@ -62,9 +62,9 @@ protected:
protected: protected:
virtual Settings::PCompilerSet compilerSet(); virtual Settings::PCompilerSet compilerSet();
virtual bool prepareForCompile() = 0; virtual bool prepareForCompile() = 0;
virtual QString pipedText() = 0; virtual QByteArray pipedText();
virtual bool prepareForRebuild() = 0; 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 getCCompileArguments(bool checkSyntax);
virtual QString getCppCompileArguments(bool checkSyntax); virtual QString getCppCompileArguments(bool checkSyntax);
virtual QString getCIncludeArguments(); virtual QString getCIncludeArguments();
@ -77,7 +77,7 @@ protected:
PCppParser& parser); PCppParser& parser);
void log(const QString& msg); void log(const QString& msg);
void error(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: protected:
bool mSilent; bool mSilent;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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