- enhancement: Import FPS (free problem set) files.

This commit is contained in:
Roy Qu 2022-12-11 19:47:43 +08:00
parent d07e9aeda0
commit b1ca0bb600
30 changed files with 1037 additions and 715 deletions

View File

@ -3,7 +3,13 @@ Red Panda C++ Version 2.6
- enhancement: Highlighter for makefiles
- fix: QSortFilterProxyModel not correctly cleared when exiting and project closed. (ASSERT fails in DEBUG mode.)
- enhancement: Windows installers now use UNICODE encoding.
- fix: can't correctly show code suggestions after "template <"
- fix: Can't correctly show code suggestions after "template <"
- enhancement: Better code completion support for macros
- fix: Paste not enabled when create a new file and system clipboard is empty.
- enhancement: Auto rebuild when project's compiler set changed.
- enhancement: When current file is the project's makefile, show project's compiler set in the toolbar.
- enhancement: Prevent error of "del" to stop make when rebuild project.
- enhancement: Import FPS (free problem set) files.
Red Panda C++ Version 2.5

View File

@ -1,4 +1,4 @@
QT += core gui printsupport network svg
QT += core gui printsupport network svg xml
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@ -97,6 +97,7 @@ SOURCES += \
parser/cpptokenizer.cpp \
parser/parserutils.cpp \
parser/statementmodel.cpp \
problems/freeprojectsetformat.cpp \
problems/ojproblemset.cpp \
problems/problemcasevalidator.cpp \
project.cpp \
@ -232,6 +233,7 @@ HEADERS += \
parser/cpptokenizer.h \
parser/parserutils.h \
parser/statementmodel.h \
problems/freeprojectsetformat.h \
problems/ojproblemset.h \
problems/problemcasevalidator.h \
project.h \

View File

@ -311,9 +311,9 @@ void ProjectCompiler::writeMakeClean(QFile &file)
{
writeln(file, "clean: clean-custom");
if (mProject->options().type == ProjectType::DynamicLib)
writeln(file, QString("\t${RM} $(CLEANOBJ) $(CLEAN_DEF) $(CLEAN_STATIC) > %1 2>&1").arg(NULL_FILE));
writeln(file, QString("\t-${RM} $(CLEANOBJ) $(CLEAN_DEF) $(CLEAN_STATIC) > %1 2>&1").arg(NULL_FILE));
else
writeln(file, QString("\t${RM} $(CLEANOBJ) > %1 2>&1").arg(NULL_FILE));
writeln(file, QString("\t-${RM} $(CLEANOBJ) > %1 2>&1").arg(NULL_FILE));
writeln(file);
}

View File

@ -207,7 +207,7 @@ PSearchResultTreeItem CppRefacter::findOccurenceInFile(
QByteArray encoding;
editor.document()->loadFromFile(filename,ENCODING_AUTO_DETECT,encoding);
}
editor.setSyntaxer(syntaxerManager.getCppSyntaxer());
editor.setSyntaxer(syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP));
int posY = 0;
while (posY < editor.document()->count()) {
QString line = editor.document()->getString(posY);
@ -272,7 +272,7 @@ void CppRefacter::renameSymbolInFile(const QString &filename, const PStatement &
editor.document()->loadFromFile(filename,ENCODING_AUTO_DETECT,encoding);
}
QStringList newContents;
editor.setSyntaxer(syntaxerManager.getCppSyntaxer());
editor.setSyntaxer(syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP));
int posY = 0;
while (posY < editor.document()->count()) {
QString line = editor.document()->getString(posY);

View File

@ -111,7 +111,7 @@ Editor::Editor(QWidget *parent, const QString& filename,
syntaxer = syntaxerManager.getSyntaxer(mFilename);
} else {
mFileEncoding = ENCODING_ASCII;
syntaxer=syntaxerManager.getCppSyntaxer();
syntaxer=syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP);
}
if (syntaxer) {
@ -390,7 +390,7 @@ bool Editor::saveAs(const QString &name, bool fromProject){
setUseCodeFolding(false);
}
setSyntaxer(newSyntaxer);
if (!newSyntaxer || newSyntaxer->language() != QSynedit::ProgrammingLanguage::Cpp) {
if (!newSyntaxer || newSyntaxer->language() != QSynedit::ProgrammingLanguage::CPP) {
mSyntaxIssues.clear();
}
applyColorScheme(pSettings->editor().colorScheme());
@ -1037,7 +1037,7 @@ void Editor::onPreparePaintHighlightToken(int line, int aChar, const QString &to
if (CppTypeKeywords.contains(token)
||
(
syntaxer()->language()==QSynedit::ProgrammingLanguage::Cpp
syntaxer()->language()==QSynedit::ProgrammingLanguage::CPP
&&
((QSynedit::CppSyntaxer*)syntaxer().get())->customTypeKeywords().contains(token)
)
@ -1938,38 +1938,32 @@ QStringList Editor::getExpressionAtPosition(
const QSynedit::BufferCoord &pos)
{
QStringList result;
if (!syntaxer())
if (!syntaxer() || !parser())
return result;
int line = pos.line-1;
int ch = pos.ch-1;
int symbolMatchingLevel = 0;
LastSymbolType lastSymbolType=LastSymbolType::None;
QSynedit::PSyntaxer syntaxer;
if (isNew())
syntaxer = syntaxerManager.getCppSyntaxer();
else
syntaxer = syntaxerManager.getSyntaxer(mFilename);
if (!syntaxer)
return result;
QSynedit::CppSyntaxer syntaxer;
while (true) {
if (line>=document()->count() || line<0)
break;
QStringList tokens;
if (line==0) {
syntaxer->resetState();
syntaxer.resetState();
} else {
syntaxer->setState(document()->ranges(line-1));
syntaxer.setState(document()->ranges(line-1));
}
QString sLine = document()->getString(line);
syntaxer->setLine(sLine,line-1);
while (!syntaxer->eol()) {
int start = syntaxer->getTokenPos();
QString token = syntaxer->getToken();
syntaxer.setLine(sLine,line-1);
while (!syntaxer.eol()) {
int start = syntaxer.getTokenPos();
QString token = syntaxer.getToken();
int endPos = start + token.length()-1;
if (start>ch) {
break;
}
QSynedit::PTokenAttribute attr = syntaxer->getTokenAttribute();
QSynedit::PTokenAttribute attr = syntaxer.getTokenAttribute();
if ( (line == pos.line-1)
&& (start<=ch) && (ch<=endPos)) {
if (attr->tokenType() == QSynedit::TokenType::Comment
@ -1981,7 +1975,7 @@ QStringList Editor::getExpressionAtPosition(
&& attr->tokenType() != QSynedit::TokenType::Space){
tokens.append(token);
}
syntaxer->next();
syntaxer.next();
}
for (int i=tokens.count()-1;i>=0;i--) {
QString token = tokens[i];
@ -2657,7 +2651,7 @@ void Editor::initParser()
{
if (pSettings->codeCompletion().shareParser()) {
if (pSettings->codeCompletion().enabled()
&& (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::Cpp)
&& (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP)
) {
mParser = sharedParser(mUseCppSyntax?ParserLanguage::CPlusPlus:ParserLanguage::C);
}
@ -2677,7 +2671,7 @@ void Editor::initParser()
resetCppParser(mParser);
mParser->setEnabled(
pSettings->codeCompletion().enabled() &&
(syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::Cpp));
(syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP));
}
Editor::QuoteStatus Editor::getQuoteStatus()
@ -2809,7 +2803,7 @@ void Editor::reparse(bool resetParser)
return;
if (!syntaxer())
return;
if (syntaxer()->language() != QSynedit::ProgrammingLanguage::Cpp
if (syntaxer()->language() != QSynedit::ProgrammingLanguage::CPP
&& syntaxer()->language() != QSynedit::ProgrammingLanguage::GLSL)
return;
if (!mParser)
@ -3117,7 +3111,7 @@ void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeComple
QSet<QString> keywords;
if (syntaxer()) {
if (syntaxer()->language() != QSynedit::ProgrammingLanguage::Cpp ) {
if (syntaxer()->language() != QSynedit::ProgrammingLanguage::CPP ) {
keywords = syntaxer()->keywords();
} else {
if (mUseCppSyntax) {
@ -4569,7 +4563,7 @@ void Editor::checkSyntaxInBack()
return;
if (!syntaxer())
return;
if (syntaxer()->language()!=QSynedit::ProgrammingLanguage::Cpp)
if (syntaxer()->language()!=QSynedit::ProgrammingLanguage::CPP)
return;
pMainWindow->checkSyntaxInBack(this);
}
@ -4779,14 +4773,14 @@ void Editor::applySettings()
}
if (pSettings->editor().enableCustomCTypeKeywords()) {
if (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::Cpp) {
if (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP) {
QSet<QString> set;
foreach(const QString& s, pSettings->editor().customCTypeKeywords())
set.insert(s);
((QSynedit::CppSyntaxer*)(syntaxer().get()))->setCustomTypeKeywords(set);
}
} else {
if (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::Cpp) {
if (syntaxer() && syntaxer()->language() == QSynedit::ProgrammingLanguage::CPP) {
((QSynedit::CppSyntaxer*)(syntaxer().get()))->setCustomTypeKeywords(QSet<QString>());
}
}

View File

@ -35,6 +35,7 @@
#include "widgets/darkfusionstyle.h"
#include "widgets/lightfusionstyle.h"
#include "problems/problemcasevalidator.h"
#include "problems/freeprojectsetformat.h"
#include "widgets/ojproblempropertywidget.h"
#include "iconsmanager.h"
#include "widgets/newclassdialog.h"
@ -578,8 +579,7 @@ void MainWindow::updateEditorActions(const Editor *e)
ui->actionCut->setEnabled(true);
ui->actionFoldAll->setEnabled(e->document()->count()>0);
ui->actionIndent->setEnabled(!e->readOnly());
ui->actionPaste->setEnabled(!e->readOnly() && !QGuiApplication::clipboard()->text().isEmpty());
ui->actionPaste->setEnabled(!e->readOnly());
ui->actionRedo->setEnabled(e->canRedo());
ui->actionUndo->setEnabled(e->canUndo());
ui->actionSave->setEnabled(!e->readOnly());
@ -1545,7 +1545,12 @@ void MainWindow::updateCompilerSet()
Editor *e = mEditorList->getEditor();
if ( !e || e->inProject()) {
index = mProject->options().compilerSet;
} else if (e->syntaxer()
&& e->syntaxer()->language()==QSynedit::ProgrammingLanguage::Makefile
&& mProject->directory() == extractFileDir(e->filename())) {
index = mProject->options().compilerSet;
}
if (index < 0 || index>=mCompilerSet->count()) {
index = pSettings->compilerSets().defaultIndex();
}
@ -1710,6 +1715,7 @@ void MainWindow::updateActionIcons()
pIconsManager->setIcon(ui->btnRemoveProblem, IconsManager::ACTION_MISC_CROSS);
pIconsManager->setIcon(ui->btnSaveProblemSet, IconsManager::ACTION_FILE_SAVE_AS);
pIconsManager->setIcon(ui->btnLoadProblemSet, IconsManager::ACTION_FILE_OPEN_FOLDER);
pIconsManager->setIcon(ui->btnImportFPS, IconsManager::ACTION_CODE_BACK);
pIconsManager->setIcon(ui->btnAddProblemCase, IconsManager::ACTION_MISC_ADD);
pIconsManager->setIcon(ui->btnRemoveProblemCase, IconsManager::ACTION_MISC_REMOVE);
@ -5137,6 +5143,7 @@ void MainWindow::onCompilerSetChanged(int index)
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No) != QMessageBox::Yes) {
mCompilerSet->setCurrentIndex(mProject->options().compilerSet);
//ui->actionRebuild->trigger();
return;
}
mProject->setCompilerSet(index);
@ -6288,10 +6295,13 @@ void MainWindow::on_actionProject_options_triggered()
{
if (!mProject)
return;
// int oldCompilerSet = mProject->options().compilerSet;
QString oldName = mProject->name();
PSettingsDialog dialog = SettingsDialog::projectOptionDialog();
dialog->exec();
updateCompilerSet();
// if (oldCompilerSet != mProject->options().compilerSet)
// ui->actionRebuild->trigger();
}
@ -8898,3 +8908,24 @@ void MainWindow::on_actionGenerate_Assembly_triggered()
doGenerateAssembly();
}
void MainWindow::on_btnImportFPS_clicked()
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Import FPS Problem Set"),
QString(),
tr("FPS Problem Set Files (*.fps)"));
if (!fileName.isEmpty()) {
try {
QList<POJProblem> problems = importFreeProblemSet(fileName);
mOJProblemSetModel.addProblems(problems);
} catch (FileError& error) {
QMessageBox::critical(this,tr("Load Error"),
error.reason());
}
}
ui->lblProblemSet->setText(mOJProblemSetModel.name());
ui->lstProblemSet->setCurrentIndex(mOJProblemSetModel.index(0,0));
}

View File

@ -748,6 +748,8 @@ private slots:
void on_actionGenerate_Assembly_triggered();
void on_btnImportFPS_clicked();
private:
Ui::MainWindow *ui;
EditorList *mEditorList;

View File

@ -838,6 +838,17 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnImportFPS">
<property name="text">
<string>Import FPS Problem Set</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/058-prev.png</normaloff>:/icons/images/newlook24/058-prev.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">

View File

@ -416,7 +416,7 @@ PStatement CppParser::findStatementOf(const QString &fileName,
PEvalStatement CppParser::evalExpression(
const QString &fileName,
const QStringList &phraseExpression,
QStringList &phraseExpression,
const PStatement &currentScope)
{
QMutexLocker locker(&mMutex);
@ -3925,6 +3925,24 @@ QList<PStatement> CppParser::getListOfFunctions(const QString &fileName, int lin
return result;
}
PStatement CppParser::findMacro(const QString &phrase, const QString &fileName)
{
const StatementMap& statementMap =mStatementList.childrenStatements(nullptr);
if (statementMap.isEmpty())
return PStatement();
StatementList statements = statementMap.values(phrase);
PFileIncludes includes = mPreprocessor.includesList().value(fileName,PFileIncludes());
foreach (const PStatement& s, statements) {
if (s->kind == StatementKind::skPreprocessor) {
if (includes && !includes->includeFiles.contains(s->fileName)
&& !includes->includeFiles.contains(s->definitionFileName))
continue;
return s;
}
}
return PStatement();
}
PStatement CppParser::findMemberOfStatement(const QString &phrase,
const PStatement& scopeStatement)
{
@ -4017,7 +4035,7 @@ PStatement CppParser::findStatementInNamespace(const QString &name, const QStrin
}
PEvalStatement CppParser::doEvalExpression(const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
@ -4032,7 +4050,7 @@ PEvalStatement CppParser::doEvalExpression(const QString& fileName,
freeScoped);
}
PEvalStatement CppParser::doEvalPointerArithmetic(const QString &fileName, const QStringList &phraseExpression, int &pos, const PStatement &scope, const PEvalStatement &previousResult, bool freeScoped)
PEvalStatement CppParser::doEvalPointerArithmetic(const QString &fileName, QStringList &phraseExpression, int &pos, const PStatement &scope, const PEvalStatement &previousResult, bool freeScoped)
{
if (pos>=phraseExpression.length())
return PEvalStatement();
@ -4083,7 +4101,7 @@ PEvalStatement CppParser::doEvalPointerArithmetic(const QString &fileName, const
PEvalStatement CppParser::doEvalPointerToMembers(
const QString &fileName,
const QStringList &phraseExpression,
QStringList &phraseExpression,
int &pos,
const PStatement &scope,
const PEvalStatement &previousResult,
@ -4126,7 +4144,7 @@ PEvalStatement CppParser::doEvalPointerToMembers(
}
PEvalStatement CppParser::doEvalCCast(const QString &fileName,
const QStringList &phraseExpression,
QStringList &phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
@ -4258,7 +4276,7 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName,
}
PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
const QStringList &phraseExpression,
QStringList &phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
@ -4390,7 +4408,7 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName,
}
PEvalStatement CppParser::doEvalScopeResolution(const QString &fileName,
const QStringList &phraseExpression,
QStringList &phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
@ -4445,7 +4463,7 @@ PEvalStatement CppParser::doEvalScopeResolution(const QString &fileName,
}
PEvalStatement CppParser::doEvalTerm(const QString &fileName,
const QStringList &phraseExpression,
QStringList &phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
@ -4459,6 +4477,7 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
PEvalStatement result;
if (pos>=phraseExpression.length())
return result;
// qDebug()<<"eval term"<<phraseExpression[pos];
if (phraseExpression[pos]=="(") {
pos++;
result = doEvalExpression(fileName,phraseExpression,pos,scope,PEvalStatement(),freeScoped);
@ -4506,6 +4525,11 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
} else {
statement = findStatementInScope(phraseExpression[pos],previousResult->effectiveTypeStatement);
}
// if (!statement) {
// statement = findMacro(
// phraseExpression[pos],
// fileName);
// }
}
pos++;
if (statement && statement->kind == StatementKind::skConstructor) {
@ -4535,6 +4559,15 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
case StatementKind::skFunction:
result = doCreateEvalFunction(fileName,statement);
break;
case StatementKind::skPreprocessor:
//qDebug()<<"before"<<phraseExpression;
pos--;
if (expandMacro(phraseExpression,pos,statement)) {
//qDebug()<<"after"<<phraseExpression;
result = doEvalExpression(fileName,phraseExpression,pos,scope,previousResult,freeScoped);
} else
result = PEvalStatement();
break;
default:
result = PEvalStatement();
}
@ -4589,6 +4622,114 @@ PEvalStatement CppParser::doEvalTerm(const QString &fileName,
return result;
}
bool CppParser::expandMacro(QStringList &phraseExpression, int &pos, const PStatement &macro)
{
QString s;
if (macro->args.isEmpty()) {
s=macro->value;
phraseExpression.removeAt(pos);
} else {
QString args=macro->args.mid(1,macro->args.length()-2).trimmed(); // remove '(' ')'
if(args=="")
return false;
QStringList argList = args.split(',');
QList<bool> argUsed;
for (int i=0;i<argList.size();i++) {
argList[i]=argList[i].trimmed();
argUsed.append(false);
}
QList<PDefineArgToken> tokens = mPreprocessor.tokenizeValue(macro->value);
QString formatStr = "";
DefineArgTokenType lastTokenType=DefineArgTokenType::Other;
int index;
foreach (const PDefineArgToken& token, tokens) {
switch(token->type) {
case DefineArgTokenType::Identifier:
index = argList.indexOf(token->value);
if (index>=0) {
argUsed[index] = true;
if (lastTokenType == DefineArgTokenType::Sharp) {
formatStr+= "\"%"+QString("%1").arg(index+1)+"\"";
break;
} else {
formatStr+= "%"+QString("%1").arg(index+1);
break;
}
}
formatStr += token->value;
break;
case DefineArgTokenType::DSharp:
case DefineArgTokenType::Sharp:
break;
case DefineArgTokenType::Space:
case DefineArgTokenType::Symbol:
formatStr+=token->value;
break;
default:
break;
}
lastTokenType = token->type;
}
QStringList values;
int i;
int level=1;
QString current;
for (i=pos+2;i<phraseExpression.length();i++) {
if (phraseExpression[i]==')') {
level--;
if (level==0) {
values.append(current);
break;
}
} else if (phraseExpression[i]=='(') {
level++;
} else {
if (level==1 && phraseExpression[i]==',') {
values.append(current);
current.clear();
continue;
}
}
current+=phraseExpression[i];
}
if (level!=0)
return false;
if (values.length()!=argList.length())
return false;
s = formatStr;
for (int i=0;i<values.length();i++) {
if (argUsed[i]) {
QString argValue = values[i];
s=s.arg(argValue.trimmed());
}
}
for (int j=pos;j<=i;j++) {
phraseExpression.removeAt(pos);
}
}
QSynedit::CppSyntaxer syntaxer;
syntaxer.resetState();
syntaxer.setLine(s,0);
int i=0;
while (!syntaxer.eol()) {
QString token=syntaxer.getToken();
QSynedit::PTokenAttribute attr = syntaxer.getTokenAttribute();
switch(attr->tokenType()) {
case QSynedit::TokenType::Space:
case QSynedit::TokenType::Comment:
break;
default:
phraseExpression.insert(pos+i,token);
i++;
}
syntaxer.next();
}
return true;
}
PEvalStatement CppParser::doCreateEvalNamespace(const PStatement &namespaceStatement)
{
if (!namespaceStatement)

View File

@ -83,7 +83,7 @@ public:
* @return the statement of the evaluation result
*/
PEvalStatement evalExpression(const QString& fileName,
const QStringList& expression,
QStringList& expression,
const PStatement& currentScope);
PStatement findTypeDefinitionOf(const QString& fileName,
const QString& aType,
@ -239,6 +239,7 @@ private:
QList<PStatement> getListOfFunctions(const QString& fileName, int line,
const PStatement& statement,
const PStatement& scopeStatement);
PStatement findMacro(const QString& phrase, const QString& fileName);
PStatement findMemberOfStatement(
const QString& phrase,
const PStatement& scopeStatement);
@ -272,7 +273,7 @@ private:
* @return
*/
PEvalStatement doEvalExpression(const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
@ -280,47 +281,50 @@ private:
PEvalStatement doEvalPointerArithmetic(
const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
bool freeScoped);
PEvalStatement doEvalPointerToMembers(
const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
bool freeScoped);
PEvalStatement doEvalCCast(
const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
bool freeScoped);
PEvalStatement doEvalMemberAccess(
const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
bool freeScoped);
PEvalStatement doEvalScopeResolution(
const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
bool freeScoped);
PEvalStatement doEvalTerm(
const QString& fileName,
const QStringList& phraseExpression,
QStringList& phraseExpression,
int &pos,
const PStatement& scope,
const PEvalStatement& previousResult,
bool freeScoped);
bool expandMacro(QStringList& phraseExpression,int &pos,
const PStatement& macro);
PEvalStatement doCreateEvalNamespace(const PStatement& namespaceStatement);
PEvalStatement doCreateEvalType(const QString& fileName,const PStatement& typeStatement);

View File

@ -579,7 +579,6 @@ void CppPreprocessor::expandMacro(const QString &line, QString &newLine, QString
} else {
PDefine define = getDefine(word);
if (define && define->args=="" ) {
//newLine:=newLine+RemoveGCCAttributes(define^.Value);
if (define->value != word )
newLine += expandMacros(define->value,depth+1);
else

View File

@ -94,6 +94,8 @@ public:
const QList<QString> &projectIncludePathList() const;
void setOnGetFileStream(const GetFileStreamCallBack &newOnGetFileStream);
static QList<PDefineArgToken> tokenizeValue(const QString& value);
private:
void preprocessBuffer();
void skipToEndOfPreprocessor();
@ -128,44 +130,43 @@ private:
void invalidDefinesInFile(const QString& fileName);
void parseArgs(PDefine define);
QList<PDefineArgToken> tokenizeValue(const QString& value);
QStringList removeComments(const QStringList& text);
/*
* '_','a'..'z','A'..'Z','0'..'9'
*/
bool isWordChar(const QChar& ch);
static bool isWordChar(const QChar& ch);
/*
* 'A'..'Z', '0'..'9', 'a'..'z', '_', '*', '&', '~'
*/
bool isIdentChar(const QChar& ch);
static bool isIdentChar(const QChar& ch);
/*
* '\r','\n'
*/
bool isLineChar(const QChar& ch);
static bool isLineChar(const QChar& ch);
/*
* '\t' ' '
*/
bool isSpaceChar(const QChar& ch);
static bool isSpaceChar(const QChar& ch);
/*
* '+', '-', '*', '/', '!', '=', '<', '>', '&', '|', '^'
*/
bool isOperatorChar(const QChar& ch);
static bool isOperatorChar(const QChar& ch);
/*
* 'A'..'Z', 'a'..'z', '_'
*/
bool isMacroIdentChar(const QChar& ch);
static bool isMacroIdentChar(const QChar& ch);
/*
* '0'..'9'
*/
bool isDigit(const QChar& ch);
static bool isDigit(const QChar& ch);
/*
* '0'..'9','x',X','a'..'f','A'..'F','u','U','l','L'
*/
bool isNumberChar(const QChar& ch);
static bool isNumberChar(const QChar& ch);
QString lineBreak();

View File

@ -0,0 +1,91 @@
#include "freeprojectsetformat.h"
#include <QFile>
#include <QXmlStreamReader>
#
QList<POJProblem> importFreeProblemSet(const QString &filename)
{
QFile file(filename);
QList<POJProblem> problems;
if (!file.open(QFile::ReadOnly))
return problems;
QXmlStreamReader xml;
xml.setDevice(&file);
POJProblem currentProblem;
POJProblemCase currentCase;
QString currentText;
QString currentEleName;
while(!xml.atEnd()) {
xml.readNext();
switch (xml.tokenType()) {
case QXmlStreamReader::TokenType::StartElement:
currentEleName = xml.name().toString();
if (xml.name()=="item") {
currentProblem=std::make_shared<OJProblem>();
} else if (currentProblem &&
( xml.name()=="sample_input"
|| xml.name()=="test_input")) {
currentCase = std::make_shared<OJProblemCase>();
foreach (const QXmlStreamAttribute& attr, xml.attributes()) {
if (attr.name() == "name") {
currentCase->name = attr.value().toString();
break;
}
}
currentCase->name = QObject::tr("Problem Case %1").arg(currentProblem->cases.count()+1);
} else if (currentProblem &&
xml.name()=="time_limit") {
foreach (const QXmlStreamAttribute& attr, xml.attributes()) {
if (attr.name() == "unit" && attr.value()=="ms") {
currentEleName = xml.name().toString();
break;
}
}
} else if (currentProblem &&
xml.name()=="memory_limit") {
foreach (const QXmlStreamAttribute& attr, xml.attributes()) {
if (attr.name() == "unit" && attr.value()=="mb") {
currentEleName = xml.name().toString();
break;
}
}
}
break;
case QXmlStreamReader::TokenType::EndElement:
currentEleName.clear();
if (currentProblem && xml.name()=="item") {
problems.append(currentProblem);
currentProblem.reset();
}
break;
case QXmlStreamReader::TokenType::Characters:
if (currentCase &&
(
currentEleName=="test_input" ||
currentEleName=="sample_input")) {
currentCase->input = xml.text().toString();
} else if (currentCase && currentProblem &&
(
currentEleName=="test_output" ||
currentEleName=="sample_output")) {
currentCase->expected = xml.text().toString();
currentProblem->cases.append(currentCase);
currentCase.reset();
} else if (currentProblem && currentEleName=="description") {
currentProblem->description = xml.text().toString();
} else if (currentProblem && currentEleName=="hint") {
currentProblem->hint = xml.text().toString();
} else if (currentProblem && currentEleName=="title") {
currentProblem->name = xml.text().toString();
} else if (currentProblem && currentEleName=="time_limit") {
currentProblem->timeLimit = xml.text().toInt();
} else if (currentProblem && currentEleName=="memory_limit") {
currentProblem->memoryLimit = xml.text().toInt();
}
default:
break;
}
}
return problems;
}

View File

@ -0,0 +1,9 @@
#ifndef FREEPROJECTSETFORMAT_H
#define FREEPROJECTSETFORMAT_H
#include "ojproblemset.h"
QList<POJProblem> importFreeProblemSet(const QString& filename);
//void exportFreeProblemSet(const QList<POJProblem>& problems);
#endif // FREEPROJECTSETFORMAT_H

View File

@ -54,7 +54,10 @@ struct OJProblem {
QString name;
QString url;
QString description;
QString hint;
QString answerProgram;
int timeLimit; // ms
int memoryLimit; // mb
QVector<POJProblemCase> cases;
};

View File

@ -36,14 +36,14 @@ SyntaxerManager::SyntaxerManager()
QSynedit::PSyntaxer SyntaxerManager::getSyntaxer(QSynedit::ProgrammingLanguage language)
{
switch(language) {
case QSynedit::ProgrammingLanguage::Cpp:
return getCppSyntaxer();
case QSynedit::ProgrammingLanguage::Asssembly:
return getAsmSyntaxer();
case QSynedit::ProgrammingLanguage::CPP:
return std::make_shared<QSynedit::CppSyntaxer>();
case QSynedit::ProgrammingLanguage::Assembly:
return std::make_shared<QSynedit::ASMSyntaxer>();
case QSynedit::ProgrammingLanguage::Makefile:
return getMakefileSyntaxer();
return std::make_shared<QSynedit::MakefileSyntaxer>();
case QSynedit::ProgrammingLanguage::GLSL:
return getGLSLSyntaxer();
return std::make_shared<QSynedit::GLSLSyntaxer>();
default:
return QSynedit::PSyntaxer();
}
@ -59,15 +59,15 @@ QSynedit::PSyntaxer SyntaxerManager::getSyntaxer(const QString &filename)
|| suffix == "hxx" || suffix == "hh" || suffix == "C"
|| suffix == "CPP" || suffix =="H" || suffix == "c++"
|| suffix == "h++") {
return getCppSyntaxer();
return getSyntaxer(QSynedit::ProgrammingLanguage::CPP);
} else if (suffix == "vs" || suffix == "fs" || suffix == "frag") {
return getGLSLSyntaxer();
return getSyntaxer(QSynedit::ProgrammingLanguage::GLSL);
} else if (suffix == "s" || suffix == "asm") {
return getAsmSyntaxer();
return getSyntaxer(QSynedit::ProgrammingLanguage::Assembly);
} else if (basename.compare("makefile", Qt::CaseInsensitive)==0) {
return getMakefileSyntaxer();
return getSyntaxer(QSynedit::ProgrammingLanguage::Makefile);
} else if (suffix.isEmpty()) {
return getCppSyntaxer();
return getSyntaxer(QSynedit::ProgrammingLanguage::CPP);
}
return QSynedit::PSyntaxer();
}
@ -79,26 +79,6 @@ QSynedit::PSyntaxer SyntaxerManager::copy(QSynedit::PSyntaxer syntaxer)
return getSyntaxer(syntaxer->language());
}
QSynedit::PSyntaxer SyntaxerManager::getCppSyntaxer()
{
return std::make_shared<QSynedit::CppSyntaxer>();
}
QSynedit::PSyntaxer SyntaxerManager::getAsmSyntaxer()
{
return std::make_shared<QSynedit::ASMSyntaxer>();
}
QSynedit::PSyntaxer SyntaxerManager::getGLSLSyntaxer()
{
return std::make_shared<QSynedit::GLSLSyntaxer>();
}
QSynedit::PSyntaxer SyntaxerManager::getMakefileSyntaxer()
{
return std::make_shared<QSynedit::MakefileSyntaxer>();
}
void SyntaxerManager::applyColorScheme(QSynedit::PSyntaxer syntaxer, const QString &schemeName)
{
if (!syntaxer)

View File

@ -26,10 +26,6 @@ public:
QSynedit::PSyntaxer getSyntaxer(QSynedit::ProgrammingLanguage language);
QSynedit::PSyntaxer getSyntaxer(const QString& filename);
QSynedit::PSyntaxer copy(QSynedit::PSyntaxer syntaxer);
QSynedit::PSyntaxer getCppSyntaxer();
QSynedit::PSyntaxer getAsmSyntaxer();
QSynedit::PSyntaxer getGLSLSyntaxer();
QSynedit::PSyntaxer getMakefileSyntaxer();
void applyColorScheme(QSynedit::PSyntaxer syntaxer, const QString& schemeName);
};

View File

@ -106,7 +106,7 @@ TodoThread::TodoThread(const QStringList &files, QObject *parent): QThread(paren
void TodoThread::parseFile()
{
QSynedit::PSyntaxer syntaxer = syntaxerManager.getCppSyntaxer();
QSynedit::PSyntaxer syntaxer = syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP);
emit parseStarted();
doParseFile(mFilename,syntaxer);
emit parseFinished();
@ -114,7 +114,7 @@ void TodoThread::parseFile()
void TodoThread::parseFiles()
{
QSynedit::PSyntaxer highlighter = syntaxerManager.getCppSyntaxer();
QSynedit::PSyntaxer highlighter = syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP);
emit parseStarted();
foreach(const QString& filename,mFiles) {
doParseFile(filename,highlighter);

View File

@ -4732,6 +4732,14 @@
<source>Generate Assembly</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import FPS Problem Set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>FPS Problem Set Files (*.fps)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewClassDialog</name>
@ -6167,6 +6175,10 @@
<source>Reserve Word for Types</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Problem Case %1</source>
<translation type="unfinished">Caso do problema %1</translation>
</message>
</context>
<context>
<name>RegisterModel</name>

File diff suppressed because it is too large Load Diff

View File

@ -4573,6 +4573,14 @@
<source>Generate Assembly</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Import FPS Problem Set</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>FPS Problem Set Files (*.fps)</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewClassDialog</name>
@ -5904,6 +5912,10 @@
<source>Reserve Word for Types</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Problem Case %1</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RegisterModel</name>

View File

@ -540,7 +540,7 @@ void CodeCompletionPopup::filterList(const QString &member)
}
void CodeCompletionPopup::getCompletionFor(
const QStringList &ownerExpression,
QStringList ownerExpression,
const QString& memberOperator,
const QStringList& memberExpression,
const QString &fileName,
@ -808,7 +808,7 @@ void CodeCompletionPopup::getCompletionFor(
}
}
void CodeCompletionPopup::getCompletionForFunctionWithoutDefinition(const QString& preWord, const QStringList &ownerExpression, const QString &memberOperator, const QStringList &memberExpression, const QString &fileName, int line)
void CodeCompletionPopup::getCompletionForFunctionWithoutDefinition(const QString& preWord, QStringList ownerExpression, const QString &memberOperator, const QStringList &memberExpression, const QString &fileName, int line)
{
if(!mParser) {
return;

View File

@ -134,7 +134,7 @@ private:
void addStatement(const PStatement& statement, const QString& fileName, int line);
void filterList(const QString& member);
void getCompletionFor(
const QStringList& ownerExpression,
QStringList ownerExpression,
const QString& memberOperator,
const QStringList& memberExpression,
const QString& fileName,
@ -143,7 +143,7 @@ private:
void getCompletionForFunctionWithoutDefinition(
const QString& preWord,
const QStringList& ownerExpression,
QStringList ownerExpression,
const QString& memberOperator,
const QStringList& memberExpression,
const QString& fileName,

View File

@ -32,7 +32,7 @@ CPUDialog::CPUDialog(QWidget *parent) :
setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
setWindowFlag(Qt::WindowContextHelpButtonHint,false);
ui->setupUi(this);
ui->txtCode->setSyntaxer(syntaxerManager.getAsmSyntaxer());
ui->txtCode->setSyntaxer(syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::Assembly));
ui->txtCode->setReadOnly(true);
ui->txtCode->gutter().setShowLineNumbers(false);
ui->txtCode->setCaretUseTextColor(true);

View File

@ -68,13 +68,23 @@ QString OJProblemSetModel::exportFilename() const
return mProblemSet.exportFilename;
}
void OJProblemSetModel::addProblem(POJProblem problem)
void OJProblemSetModel::addProblem(const POJProblem& problem)
{
beginInsertRows(QModelIndex(), mProblemSet.problems.count(), mProblemSet.problems.count());
mProblemSet.problems.append(problem);
endInsertRows();
}
void OJProblemSetModel::addProblems(const QList<POJProblem> &problems)
{
if (problems.isEmpty())
return;
beginInsertRows(QModelIndex(), mProblemSet.problems.count(), mProblemSet.problems.count()+problems.count()-1);
foreach( const POJProblem& p, problems)
mProblemSet.problems.append(p);
endInsertRows();
}
POJProblem OJProblemSetModel::problem(int index)
{
return mProblemSet.problems[index];

View File

@ -80,7 +80,8 @@ public:
void rename(const QString& newName);
QString name() const;
QString exportFilename() const;
void addProblem(POJProblem problem);
void addProblem(const POJProblem& problem);
void addProblems(const QList<POJProblem> &problems);
POJProblem problem(int index);
void removeProblem(int index);
bool problemNameUsed(const QString& name);

View File

@ -1619,13 +1619,13 @@ int SynEdit::calcIndentSpaces(int line, const QString& lineText, bool addIndent)
matchingIndents = rangeAfterFirstToken.matchingIndents;
indentAdded = true;
l = startLine;
} else if (mSyntaxer->language() == ProgrammingLanguage::Cpp
} else if (mSyntaxer->language() == ProgrammingLanguage::CPP
&& trimmedLineText.startsWith('#')
&& attr == ((CppSyntaxer *)mSyntaxer.get())->preprocessorAttribute()) {
indentAdded = true;
indentSpaces=0;
l=0;
} else if (mSyntaxer->language() == ProgrammingLanguage::Cpp
} else if (mSyntaxer->language() == ProgrammingLanguage::CPP
&& mSyntaxer->isLastLineCommentNotFinished(rangePreceeding.state)
) {
// last line is a not finished comment,
@ -2906,7 +2906,7 @@ void SynEdit::doAddChar(QChar AChar)
if (mActiveSelectionMode==SelectionMode::Normal
&& mOptions.testFlag(eoAutoIndent)
&& mSyntaxer
&& mSyntaxer->language() == ProgrammingLanguage::Cpp
&& mSyntaxer->language() == ProgrammingLanguage::CPP
&& (oldCaretY<=mDocument->count()) ) {
//unindent if ':' at end of the line
@ -5479,7 +5479,7 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
int caretY=pos.line;
// step1: insert the first line of Value into current line
if (text.length()>1) {
if (!mUndoing && mSyntaxer && mSyntaxer->language()==ProgrammingLanguage::Cpp && mOptions.testFlag(eoAutoIndent)) {
if (!mUndoing && mSyntaxer && mSyntaxer->language()==ProgrammingLanguage::CPP && mOptions.testFlag(eoAutoIndent)) {
QString s = trimLeft(text[0]);
if (sLeftSide.isEmpty()) {
sLeftSide = GetLeftSpacing(calcIndentSpaces(caretY,s,true),true);
@ -5509,7 +5509,7 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
if (i==text.length()-1) {
str = sRightSide;
} else {
if (!mUndoing && mSyntaxer && mSyntaxer->language()==ProgrammingLanguage::Cpp && mOptions.testFlag(eoAutoIndent) && notInComment) {
if (!mUndoing && mSyntaxer && mSyntaxer->language()==ProgrammingLanguage::CPP && mOptions.testFlag(eoAutoIndent) && notInComment) {
str = GetLeftSpacing(calcIndentSpaces(caretY,"",true),true);
} else {
str = "";
@ -5519,7 +5519,7 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
str = text[i];
if (i==text.length()-1)
str += sRightSide;
if (!mUndoing && mSyntaxer && mSyntaxer->language()==ProgrammingLanguage::Cpp && mOptions.testFlag(eoAutoIndent) && notInComment) {
if (!mUndoing && mSyntaxer && mSyntaxer->language()==ProgrammingLanguage::CPP && mOptions.testFlag(eoAutoIndent) && notInComment) {
int indentSpaces = calcIndentSpaces(caretY,str,true);
str = GetLeftSpacing(indentSpaces,true)+trimLeft(str);
}

View File

@ -300,7 +300,7 @@ QString ASMSyntaxer::languageName()
ProgrammingLanguage ASMSyntaxer::language()
{
return ProgrammingLanguage::Asssembly;
return ProgrammingLanguage::Assembly;
}
QString ASMSyntaxer::getToken() const

View File

@ -1627,7 +1627,7 @@ QString CppSyntaxer::languageName()
ProgrammingLanguage CppSyntaxer::language()
{
return ProgrammingLanguage::Cpp;
return ProgrammingLanguage::CPP;
}
SyntaxerState CppSyntaxer::getState() const

View File

@ -81,8 +81,8 @@ enum class TokenType {
enum class ProgrammingLanguage {
DecideBySuffix,
Composition,
Asssembly,
Cpp,
Assembly,
CPP,
GLSL,
Makefile,
Custom