File indexing completed on 2024-12-15 04:56:12

0001 /*
0002  * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org>
0003  *
0004  *   This program is free software; you can redistribute it and/or modify
0005  *   it under the terms of the GNU General Public License as published by
0006  *   the Free Software Foundation; either version 2 of the License, or
0007  *   (at your option) any later version.
0008  *
0009  *   This program is distributed in the hope that it will be useful,
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *   GNU General Public License for more details.
0013  *
0014  *   You should have received a copy of the GNU General Public License
0015  *   along with this program; if not, write to the
0016  *   Free Software Foundation, Inc.,
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
0018  */
0019 
0020 #include "module.h"
0021 
0022 #include "modules/list.h"
0023 #include "modules/check.h"
0024 #include "modules/print.h"
0025 #include "modules/json.h"
0026 
0027 #include <QCoreApplication>
0028 
0029 #include <iostream>
0030 
0031 namespace HAWD
0032 {
0033 
0034 QVector<Module> Module::s_modules;
0035 
0036 Module::Syntax::Syntax()
0037 {
0038 }
0039 
0040 Module::Syntax::Syntax(const QString &k, std::function<bool(const QStringList &, State &)> l, bool e)
0041     : keyword(k),
0042       lambda(l),
0043       eventDriven(e)
0044 {
0045 }
0046 
0047 Module::Module()
0048 {
0049 }
0050 
0051 void Module::loadModules()
0052 {
0053     addModule(List());
0054     addModule(Check());
0055     addModule(CheckAll());
0056     addModule(Print());
0057     addModule(Json());
0058 //    addModule(Annotate());
0059 //    addModule(Remove());
0060 }
0061 
0062 void Module::printCommands()
0063 {
0064     for (const Module &module: s_modules) {
0065         printSyntax(1, module.syntax(), module.description());
0066     }
0067 }
0068 
0069 void Module::printSyntax(uint indent, const Syntax &syntax, const QString &description)
0070 {
0071     const std::string indentation(indent, '\t');
0072     std::cout << indentation;
0073 
0074     if (indent < 2) {
0075         std::cout << "hawd ";
0076     }
0077 
0078     std::cout << syntax.keyword.toStdString();
0079 
0080     if (!description.isEmpty()) {
0081         std::cout << ": " << description.toStdString();
0082     }
0083 
0084     std::cout << std::endl;
0085 
0086     for (const Syntax &child: syntax.children) {
0087         printSyntax(indent + 1, child);
0088     }
0089 }
0090 
0091 void Module::addModule(const Module &module)
0092 {
0093     s_modules.append(module);
0094 }
0095 
0096 QVector<Module> Module::modules()
0097 {
0098     return s_modules;
0099 }
0100 
0101 bool Module::match(const QStringList &commands, State &state)
0102 {
0103     for (const Module &module: s_modules) {
0104         if (module.matches(commands, state)) {
0105             return true;
0106         }
0107     }
0108 
0109     return false;
0110 }
0111 
0112 Module::Syntax Module::syntax() const
0113 {
0114     return m_syntax;
0115 }
0116 
0117 void Module::setSyntax(const Syntax &syntax)
0118 {
0119     m_syntax = syntax;
0120 }
0121 
0122 QString Module::description() const
0123 {
0124     return m_description;
0125 }
0126 
0127 void Module::setDescription(const QString &description)
0128 {
0129     m_description = description;
0130 }
0131 
0132 bool Module::matches(const QStringList &commands, State &state) const
0133 {
0134     if (commands.isEmpty()) {
0135         return false;
0136     }
0137 
0138     QStringListIterator commandIt(commands);
0139 
0140     if (commandIt.next() != m_syntax.keyword) {
0141         return false;
0142     }
0143 
0144     QVectorIterator<Syntax> syntaxIt(m_syntax.children);
0145     const Syntax *syntax = &m_syntax;
0146     QStringList tailCommands;
0147     while (commandIt.hasNext() && syntaxIt.hasNext()) {
0148         const QString word = commandIt.next();
0149         while (syntaxIt.hasNext()) {
0150             const Syntax &child = syntaxIt.next();
0151             if (word == child.keyword) {
0152                 syntax = &child;
0153                 syntaxIt = child.children;
0154             }
0155         }
0156 
0157         if (!syntaxIt.hasNext()) {
0158             tailCommands << word;
0159             break;
0160         }
0161     }
0162 
0163     if (syntax && syntax->lambda) {
0164         while (commandIt.hasNext()) {
0165             tailCommands << commandIt.next();
0166         }
0167 
0168         bool rv = syntax->lambda(tailCommands, state);
0169         if (rv && syntax->eventDriven) {
0170             return QCoreApplication::instance()->exec();
0171         }
0172 
0173         return rv;
0174     }
0175 
0176     return false;
0177 }
0178 
0179 } // namespace HAWD