File indexing completed on 2024-05-05 08:52:03

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <KOpeningHours/OpeningHours>
0008 
0009 #include <QCoreApplication>
0010 #include <QCommandLineParser>
0011 #include <QFile>
0012 
0013 #include <cstring>
0014 #include <iostream>
0015 
0016 using namespace KOpeningHours;
0017 
0018 int main(int argc, char **argv)
0019 {
0020     QCoreApplication app(argc, argv);
0021     QCommandLineParser parser;
0022     parser.addHelpOption();
0023     parser.addVersionOption();
0024 
0025     QCommandLineOption verifyNormalizationOpt({QStringLiteral("verify-normalization")}, QStringLiteral("verify normalized expression themselves have valid syntax"));
0026     parser.addOption(verifyNormalizationOpt);
0027     parser.addPositionalArgument(QStringLiteral("expression"), QStringLiteral("OSM opening hours expression, omit for using stdin."));
0028     parser.process(app);
0029 
0030     const auto verifyNormalization = parser.isSet(verifyNormalizationOpt);
0031     if (parser.positionalArguments().isEmpty()) {
0032         OpeningHours oh;
0033         QFile in;
0034         in.open(stdin, QFile::ReadOnly);
0035         int total = 0;
0036         int normalized = 0;
0037         int simplified = 0;
0038         int errors = 0;
0039         char line[4096];
0040         while (!in.atEnd()) {
0041             auto size = in.readLine(line, sizeof(line));
0042             if (size <= 1) {
0043                 continue;
0044             }
0045             --size; // trailing linebreak
0046             ++total;
0047             oh.setExpression(line, size);
0048             if (oh.error() == OpeningHours::SyntaxError) {
0049                 std::cerr << "Syntax error: " << QByteArray(line, size).constData() << std::endl;
0050                 ++errors;
0051             } else {
0052                 const auto n = oh.normalizedExpression();
0053                 if (verifyNormalization) {
0054                     oh.setExpression(n);
0055                     if (oh.error() == OpeningHours::SyntaxError) {
0056                         std::cerr << "Syntax error in normalized expression! " << QByteArray(line, size).constData() << " normalized: " << n.constData() << std::endl;
0057                     }
0058                 }
0059                 if (n.size() != size || std::strncmp(line, n.constData(), size) != 0) {
0060                     ++normalized;
0061                     std::cerr << "Expression " << QByteArray(line, size).constData() << " normalized to " << n.constData() << std::endl;
0062                 }
0063                 const auto simplifiedExpr = oh.simplifiedExpression();
0064                 if (n != simplifiedExpr) {
0065                     ++simplified;
0066                     std::cerr << "Expression " << n.constData() << " simplified to " << simplifiedExpr.constData() << std::endl;
0067                 }
0068             }
0069         }
0070 
0071         std::cerr << total << " expressions checked, "
0072                   << errors << " invalid, "
0073                   << normalized << " not in normal form, "
0074                   << simplified << " can be simplified" << std::endl;
0075         return errors;
0076     } else {
0077         OpeningHours oh(parser.positionalArguments().at(0).toUtf8());
0078         std::cout << oh.normalizedExpression().constData() << std::endl;
0079         return oh.error() != OpeningHours::SyntaxError ? 0 : 1;
0080     }
0081 }