diff --git a/examples/cc/main.cpp b/examples/cc/main.cpp index ffbec77..373b008 100644 --- a/examples/cc/main.cpp +++ b/examples/cc/main.cpp @@ -1,96 +1,96 @@ /* (C) Copyright 2009 Jonathan Schmidt-Dominé This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define QT_NO_STL #include #include #include -#include +#include #include "dumptree.h" #include "ccparser.h" #include "lexer.h" using namespace cc; using namespace std; int main(int argc, char** argv) { if(argc == 1) { cerr << "Simply use some preprocessed C-code-files (output of gcc -E) as arguments" << endl; return -1; } for(int i = 1; i != argc; ++i) { ifstream filestr(argv[i]); char* contents; if(filestr.is_open()) { long size; filestr.ignore(10000); size = filestr.tellg(); filestr.close(); contents = new char[size+2]; filestr.open(argv[i]); filestr.read(contents, size); contents[size] = '\n'; contents[size+1] = '\0'; filestr.close(); } else { cerr << "File not found: " << argv[i] << endl; return -1; } KDevPG::TokenStream token_stream; Parser::memoryPoolType memory_pool; Parser parser; parser.setTokenStream(&token_stream); parser.setMemoryPool(&memory_pool); Lexer lexer(&parser, contents); int kind = Parser::Token_EOF; do { kind = lexer.yylex(); if ( !kind ) // when the lexer returns 0, the end of file is reached kind = Parser::Token_EOF; qDebug() << kind; Parser::Token &t = token_stream.push(); t.kind = kind; t.begin = lexer.tokenBegin(); t.end = lexer.tokenEnd(); } while ( kind != Parser::Token_EOF ); token_stream.rewind(0); parser.yylex(); DocumentAst *ast = 0; bool matched = parser.parseDocument(&ast); if(matched) { DumpTree dt; dt.dump(ast); } else { qDebug() << "Parsing failed"; } delete[] contents; } return 0; } diff --git a/kdev-pg/test/Op2main.cpp b/kdev-pg/test/Op2main.cpp index 5c0a48e..a80e8b9 100644 --- a/kdev-pg/test/Op2main.cpp +++ b/kdev-pg/test/Op2main.cpp @@ -1,31 +1,31 @@ #include "Op2parser.cpp" #include "Op2debugvisitor.h" #include "Op2tokenstream.h" -#include +#include #include using namespace Op2; int main(int argc, char **argv) { if(argc != 2) { kDebug() << "Usage: " << argv[0] << " filename"; return -1; } QFile file(argv[1]); file.open(QIODevice::ReadOnly); QString content = file.readAll(); Op2::TokenStream token_stream(content); Parser::memoryPoolType memory_pool; Parser parser; parser.setTokenStream(&token_stream); parser.setMemoryPool(&memory_pool); parser.yylex(); DocumentAst *doc; kDebug() << parser.parseDocument(&doc); DebugVisitor v(&token_stream, content); v.visitDocument(doc); } diff --git a/tests/benchmarks.cpp b/tests/benchmarks.cpp index 510a17b..ede59b0 100644 --- a/tests/benchmarks.cpp +++ b/tests/benchmarks.cpp @@ -1,361 +1,361 @@ /* Copyright 2009 Milian Wolff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "benchmarks.h" #include #include #include #include -#include +#include #include "../include/kdev-pg-location-table.h" #include #include using namespace std; namespace KDevPG { class BenchmarkLocationTable : public LocationTable { public: BenchmarkLocationTable() : LocationTable(), m_lastLine(0) { /// number of lines in each table const int lines = 12500; /// every i-th line has i chars, which gets reset each \p charResetLine line. const int charResetLine = 160; tableMaxOffset = 0; for ( int i = 0; i < lines; ++i ) { tableMaxOffset += tableMaxOffset % charResetLine + 1; newline(tableMaxOffset); } } /** * Implements a bisection algorithm / binary search * for the offset. * * Should perform pretty good for any kind of usage, but potentially not * as good as positionAtWithMemory for linear access. */ void positionAtQtBisection(qint64 offset, qint64 *line, qint64 *column) const { if ( offset < 0 ) { *line = -1; *column = -1; return; } else if ( offset > lines[currentLine - 1] ) { *line = currentLine - 1; *column = offset - lines[currentLine - 1]; return; } qint64 i = -1; // search relative to last line (next line and the one after that) if ( m_lastLine + 1 < currentLine && lines[m_lastLine] <= offset ) { if ( lines[m_lastLine + 1] > offset ) { // last matched line matches again i = m_lastLine; } else if ( m_lastLine + 2 < currentLine && lines[m_lastLine + 2] > offset ) { // next line relative to last matched matches i = m_lastLine + 1; } } if ( i == -1 ) { // fallback to binary search qint64 *it = std::lower_bound(lines, lines + currentLine, offset); Q_ASSERT(it != lines + currentLine); if (*it != offset) { --it; } *line = it - lines; *column = offset - *it; } else { *line = i; *column = offset - lines[i]; } m_lastLine = *line; } /** * Uses old algorithm as written by Roberto Raggi in r687144 (kdevelop-pg/include/kdev-pg-location-table.h) */ void positionAtSTLBisection(qint64 offset, qint64 *line, qint64 *column) const { if ( offset < 0 ) { *line = -1; *column = -1; return; } else if ( offset > lines[currentLine - 1] ) { *line = currentLine - 1; *column = offset - lines[currentLine - 1]; return; } qint64 i = -1; // search relative to last line (next line and the one after that) if ( m_lastLine + 1 < currentLine && lines[m_lastLine] <= offset ) { if ( lines[m_lastLine + 1] > offset ) { // last matched line matches again i = m_lastLine; } else if ( m_lastLine + 2 < currentLine && lines[m_lastLine + 2] > offset ) { // next line relative to last matched matches i = m_lastLine + 1; } } if ( i == -1 ) { // fallback to binary search qint64 *it = std::lower_bound(lines, lines + currentLine, offset); Q_ASSERT(it != lines + currentLine); if (*it != offset) { --it; } *line = it - lines; *column = offset - *it; } else { *line = i; *column = offset - lines[i]; } m_lastLine = *line; } qint64 tableMaxOffset; private: mutable qint64 m_lastLine; }; void Benchmarks::initTestCase() { srand ( time(nullptr) ); } void Benchmarks::positionAt() { QFETCH(int, algorithm); QFETCH(int, access); BenchmarkLocationTable table; qint64 line; qint64 column; switch ( algorithm) { case CurrentPositionAt: { switch ( access ) { case LinearAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(i, &line, &column); } } break; } case RandomAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(rand() % table.tableMaxOffset, &line, &column); } } break; } default: qFatal("unexpected access type"); break; } break; } case QtBinaryPositionAt: { switch ( access ) { case LinearAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtQtBisection(i, &line, &column); } } break; } case RandomAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtQtBisection(rand() % table.tableMaxOffset, &line, &column); } } break; } default: qFatal("unexpected access type"); break; } break; } case STLBinaryPositionAt: { switch ( access ) { case LinearAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtSTLBisection(i, &line, &column); } } break; } case RandomAccess: { QBENCHMARK { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAtSTLBisection(rand() % table.tableMaxOffset, &line, &column); } } break; } default: qFatal("unexpected access type"); break; } break; } } } void Benchmarks::positionAt_data() { QTest::addColumn("algorithm"); QTest::addColumn("access"); QTest::newRow("current, linear") << (int) CurrentPositionAt << (int) LinearAccess; QTest::newRow("current, random") << (int) CurrentPositionAt << (int) RandomAccess; QTest::newRow("qt binary, linear") << (int) QtBinaryPositionAt << (int) LinearAccess; QTest::newRow("qt binary, random") << (int) QtBinaryPositionAt << (int) RandomAccess; QTest::newRow("stl binary, linear") << (int) STLBinaryPositionAt << (int) LinearAccess; QTest::newRow("stl binary, random") << (int) STLBinaryPositionAt << (int) RandomAccess; } void Benchmarks::verifyPositionAt() { QFETCH(int, algorithm); QFETCH(int, access); BenchmarkLocationTable table; qint64 oldLine; qint64 oldColumn; qint64 newLine; qint64 newColumn; switch ( algorithm) { case QtBinaryPositionAt: { switch ( access ) { case LinearAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(i, &oldLine, &oldColumn); table.positionAtQtBisection(i, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } // special cases // underflow table.positionAt(-5, &oldLine, &oldColumn); table.positionAtQtBisection(-5, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); // overflow table.positionAt(table.tableMaxOffset + 10, &oldLine, &oldColumn); table.positionAtQtBisection(table.tableMaxOffset + 10, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); break; } case RandomAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { qint64 offset = rand() % table.tableMaxOffset; table.positionAt(offset, &oldLine, &oldColumn); table.positionAtQtBisection(offset, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } break; } default: qFatal("unexpected access type"); break; } break; } case STLBinaryPositionAt: { switch ( access ) { case LinearAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { table.positionAt(i, &oldLine, &oldColumn); table.positionAtSTLBisection(i, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } // special cases // underflow table.positionAt(-5, &oldLine, &oldColumn); table.positionAtSTLBisection(-5, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); // overflow table.positionAt(table.tableMaxOffset + 10, &oldLine, &oldColumn); table.positionAtSTLBisection(table.tableMaxOffset + 10, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); break; } case RandomAccess: { for ( qint64 i = 0; i < table.tableMaxOffset; i += 10 ) { qint64 offset = rand() % table.tableMaxOffset; table.positionAt(offset, &oldLine, &oldColumn); table.positionAtSTLBisection(offset, &newLine, &newColumn); QCOMPARE(newLine, oldLine); QCOMPARE(newColumn, oldColumn); } break; } default: qFatal("unexpected access type"); break; } break; } default: qFatal("unexpected algorithm"); break; } } void Benchmarks::verifyPositionAt_data() { QTest::addColumn("algorithm"); QTest::addColumn("access"); QTest::newRow("qt binary, linear") << (int) QtBinaryPositionAt << (int) LinearAccess; QTest::newRow("qt binary, random") << (int) QtBinaryPositionAt << (int) RandomAccess; QTest::newRow("stl binary, linear") << (int) STLBinaryPositionAt << (int) LinearAccess; QTest::newRow("stl binary, random") << (int) STLBinaryPositionAt << (int) RandomAccess; } } QTEST_MAIN(KDevPG::Benchmarks)