File indexing completed on 2024-04-21 03:45:28
0001 /* 0002 SPDX-FileCopyrightText: 2003-2006 Cies Breijs <cies AT kde DOT nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 0008 #include <iostream> 0009 0010 #include <QFile> 0011 #include <QDebug> 0012 #include <QApplication> 0013 #include <KAboutData> 0014 #include <KCrash> 0015 #include <KLocalizedString> 0016 #include <QCommandLineParser> 0017 #include <QCommandLineOption> 0018 0019 #include "mainwindow.h" // for gui mode 0020 0021 #include "interpreter/interpreter.h" // for non gui mode 0022 #include "interpreter/echoer.h" 0023 #include "interpreter/tokenizer.h" 0024 0025 #include "kturtle_version.h" 0026 0027 int main(int argc, char* argv[]) 0028 { 0029 KLocalizedString::setApplicationDomain(QByteArrayLiteral("kturtle")); 0030 0031 QApplication app(argc, argv); 0032 KCrash::initialize(); 0033 0034 KAboutData aboutData(QStringLiteral("kturtle"), i18n("KTurtle"), QLatin1String(KTURTLE_VERSION_STRING)); 0035 aboutData.setLicense(KAboutLicense::GPL); 0036 aboutData.setHomepage(i18n("https://edu.kde.org/kturtle")); 0037 aboutData.setShortDescription(i18n("KTurtle is an educational programming environment that aims to make learning how to program as easy as possible. To achieve this KTurtle makes all programming tools available from the user interface. The programming language used is TurtleScript which allows its commands to be translated.")); 0038 aboutData.setCopyrightStatement(i18n("(c) 2003-2009 Cies Breijs")); 0039 0040 aboutData.addAuthor(i18n("Cies Breijs"), i18n("Initiator and core developer"), QStringLiteral("cies@kde.nl")); 0041 aboutData.addAuthor(i18n("Niels Slot"), i18n("Core developer"), QStringLiteral("nielsslot@gmail.com")); 0042 aboutData.addAuthor(i18n("Mauricio Piacentini"), i18n("Core developer"), QStringLiteral("piacentini@kde.org")); 0043 0044 QCommandLineParser parser; 0045 0046 KAboutData::setApplicationData(aboutData); 0047 app.setWindowIcon(QIcon::fromTheme(QStringLiteral("kturtle"), app.windowIcon())); 0048 aboutData.setupCommandLine(&parser); 0049 0050 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("i") << QStringLiteral("input"), i18n("File or URL to open (in the GUI mode)"), QStringLiteral("URL or file"))); 0051 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("d") << QStringLiteral("dbus"), i18n("Starts KTurtle in D-Bus mode (without a GUI), good for automated unit test scripts"))); 0052 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("t") << QStringLiteral("test"), i18n("Starts KTurtle in testing mode (without a GUI), directly runs the specified local file"), QStringLiteral("file"))); 0053 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("l") << QStringLiteral("lang"), i18n("Specifies the localization language by a language code, defaults to \"en_US\" (only works in testing mode)"), QStringLiteral("code"))); 0054 // parser.addOption(QCommandLineOption(QStringList() << QLatin1String("k") << QLatin1String("tokenize"), i18n("Only tokenizes the turtle code (only works in testing mode)"))); 0055 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("p") << QStringLiteral("parse"), i18n("Translates turtle code to embeddable C++ example strings (for developers only)"), QStringLiteral("file"))); 0056 0057 parser.process(app); 0058 aboutData.processCommandLine(&parser); 0059 0060 if (!parser.isSet(QStringLiteral("test")) && !parser.isSet(QStringLiteral("parse")) && !parser.isSet(QStringLiteral("dbus"))) { 0061 0062 ///////////////// run in GUI mode ///////////////// 0063 if (app.isSessionRestored()) { 0064 kRestoreMainWindows<MainWindow>(); 0065 } else { 0066 MainWindow* mainWindow = new MainWindow(); 0067 mainWindow->show(); 0068 if (parser.isSet(QStringLiteral("input"))) mainWindow->open(parser.value(QStringLiteral("input"))); 0069 } 0070 // free some memory 0071 return app.exec(); // the mainwindow has WDestructiveClose flag; it will destroy itself. 0072 0073 } else if (parser.isSet(QStringLiteral("dbus"))) { 0074 0075 ///////////////// run in DBUS mode ///////////////// 0076 Translator::instance()->setLanguage(); 0077 new Interpreter(nullptr, true); 0078 0079 return app.exec(); 0080 0081 } else if (parser.isSet(QStringLiteral("parse"))) { 0082 0083 ///////////////// run in example PARSING mode ///////////////// 0084 QFile inputFile(parser.value(QStringLiteral("parse"))); 0085 if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { 0086 std::cout << "Could not open file: " << qPrintable(parser.value(QStringLiteral("parse"))) << std::endl; 0087 std::cout << "Exiting..." << std::endl; 0088 return 1; 0089 } 0090 0091 Translator::instance()->setLanguage(); 0092 0093 Tokenizer tokenizer; 0094 tokenizer.initialize(QString::fromUtf8(inputFile.readAll())); 0095 inputFile.close(); 0096 0097 const QStringList defaultLooks(Translator::instance()->allDefaultLooks()); 0098 QString result; 0099 Token* t; 0100 while ((t = tokenizer.getToken())->type() != Token::EndOfInput) { 0101 if (defaultLooks.contains(t->look())) 0102 result.append(QStringLiteral("@(%1)").arg(t->look())); 0103 else 0104 result.append(t->look()); 0105 if (t->type() == Token::EndOfLine) result.append(QLatin1Char('\n')); 0106 } 0107 0108 const auto splitLst{result.split(QLatin1Char('\n'))}; 0109 for (const QString &line : splitLst) std::cout << qPrintable(QStringLiteral("\"%1\"").arg(line)) << std::endl; 0110 std::cout << std::endl; 0111 0112 } else { 0113 0114 ///////////////// run without a gui ///////////////// 0115 std::cout << "KTurtle's interpreter in command line mode (version " << KTURTLE_VERSION_STRING << ")" << std::endl; 0116 std::cout << "(c) 2003-2009 Cies Breijs" << std::endl << std::endl; 0117 0118 QString fileString = parser.value(QStringLiteral("test")); 0119 QFile inputFile(fileString); 0120 0121 if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { 0122 std::cout << "Could not open input file: " << qPrintable(parser.value(QStringLiteral("test"))) << std::endl; 0123 std::cout << "Exiting..." << std::endl; 0124 return 1; 0125 } 0126 0127 QTextStream in(&inputFile); 0128 0129 // check for our magic identifier 0130 QString s; 0131 s = in.readLine(); 0132 if (s != KTURTLE_MAGIC_1_0) { 0133 std::cout << "The file you try to open is not a valid KTurtle script, or is incompatible with this version of KTurtle.\n"; 0134 return 1; 0135 } 0136 0137 if (parser.isSet(QStringLiteral("lang"))) { 0138 if (Translator::instance()->setLanguage(parser.value(QStringLiteral("lang")))) { 0139 std::cout << "Set localization to: " << parser.value(QStringLiteral("lang")).data() << std::endl; 0140 } else { 0141 std::cout << "Could not set localization to:" << parser.value(QStringLiteral("lang")).data() << std::endl; 0142 std::cout << "Exiting...\n"; 0143 return 1; 0144 } 0145 } else { 0146 Translator::instance()->setLanguage(); 0147 std::cout << "Using the default (en_US) localization." << std::endl; 0148 } 0149 0150 QString localizedScript; 0151 localizedScript = Translator::instance()->localizeScript(in.readAll()); 0152 0153 // /* if (parser.isSet("tokenize")) { 0154 // std::cout << "Tokenizing...\n" << std::endl; 0155 // QString code = inputFile.readAll(); 0156 // // for (int i = 0; i < code.length(); i++) //qDebug() << code.at(i); 0157 // Tokenizer tokenizer; 0158 // tokenizer.initialize(code); 0159 // Token* t; 0160 // while ((t = tokenizer.getToken())->type() != Token::EndOfInput) { 0161 // std::cout << "TOK> " 0162 // << qPrintable(QString("\"%1\"").arg(t->look()).leftJustified(15)) 0163 // << qPrintable(QString("[%1]").arg(QString::number(t->type())).rightJustified(5)) 0164 // << qPrintable(QString(" @ (%1,%2)").arg(t->startRow()).arg(t->startCol())) 0165 // << qPrintable(QString(" - (%1,%2)").arg(t->endRow()).arg(t->endCol())) 0166 // << std::endl; 0167 // } 0168 // return 0; 0169 // }*/ 0170 0171 // free some memory 0172 0173 // init the interpreter 0174 Interpreter* interpreter = new Interpreter(nullptr, true); // set testing to true 0175 interpreter->initialize(localizedScript); 0176 0177 // install the echoer 0178 (new Echoer())->connectAllSlots(interpreter->getExecuter()); 0179 0180 // the actual execution (limited to a certain amount of iterations to break endless loops) 0181 static const int MAX_ITERATION_STEPS = 20000; 0182 int i; 0183 for (i = 0; 0184 interpreter->state() != Interpreter::Finished && 0185 interpreter->state() != Interpreter::Aborted && 0186 interpreter->getErrorList()->isEmpty() && 0187 i < MAX_ITERATION_STEPS; 0188 i++) 0189 interpreter->interpret(); 0190 0191 if (i == MAX_ITERATION_STEPS) 0192 std::cout << "ERR> Iterated more than " << MAX_ITERATION_STEPS << " steps... Execution terminated." << std::endl; 0193 0194 } 0195 0196 return 0; 0197 }