Logo Search packages:      
Sourcecode: kdeadmin version File versions

configparser.h

/* This file is part of the KDE Linux Kernel Configurator
   Copyright (c) 2001 Malte Starostik <malte@kde.org>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
 
   This program 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
    General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

// $Id: configparser.h,v 1.18 2003/07/26 21:15:33 mueller Exp $

#ifndef _CONFIGPARSER_H_
#define _CONFIGPARSER_H_

#include <qptrlist.h>
#include <qmap.h>
#include <qptrstack.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qvaluelist.h>
#include <qregexp.h>
#include <kdebug.h>

class QTextStream;

namespace Config
{
      // In the following, all parameters passed to the constructors
      // that are pointers will be either deleted immediately in the
      // constructor or claimed by the new object and deleted later.
      class Node;
      class VariableNode;
      class RootNode;

      typedef QPtrList<Node> NodeList;
      typedef QPtrList<VariableNode> VariableList;
      typedef QMap<QString, QString> SymbolTable;

      class RuleFile
      {
      public:
            RuleFile(const QString &file);
            virtual ~RuleFile();

            const QString &name() const { return m_name; }
            const QString &data() const { return m_data; }
            int line() const { return m_line; }
            void nextLine() { m_line++; m_column = m_tokenLength = 0; }
            int pos() const { return m_column; }
            int tokenLength() const { return m_tokenLength; }
            void addPos(int offset) { m_column += m_tokenLength = offset; }
            void *buffer() const { return m_buffer; }
            void setBuffer(void *buffer) { m_buffer = buffer; }
            QString currentLine() const;
             
      private:
            QString m_name;
            QString m_data;
            int m_line;
            int m_column;
            int m_tokenLength;
            void *m_buffer;
      };

      class ErrorInfo
      {
      public:
            ErrorInfo() {};
            ErrorInfo(const QString &message);

            const QString &message() const { return m_message; }
            const QString &file() const { return m_file; }
            const QString &text() const { return m_text; }
            int line() const { return m_line; }
            int pos() const { return m_pos; }
            int length() const { return m_length; }

      private:
            QString m_message;
            QString m_file;
            QString m_text;
            int m_line;
            int m_pos;
            int m_length;
      };
   
      typedef QValueList<ErrorInfo> ErrorList;

      class Parser
      {
      public:
            Parser();
            virtual ~Parser();

            bool parseConfig(const QString &kernelRoot, const QString &arch);
            QStringList availableArchs(const QString &root) const;
            const QString &kernelRoot() const { return m_kernelRoot; }
            const QString &arch() const { return m_arch; }

            bool readConfig(const QString &file);
            bool writeConfig(const QString &file) const;
            bool writeHeader(const QString &file) const;
            void apply() const;
            const QString &symbol(const QString &name) const;
            void setSymbol(const QString &name, const QString &value);
            void unsetSymbol(const QString &name);

            bool pushInclude(const QString &file);
            bool popInclude();
            RuleFile *currentFile() const { return m_ruleStack.top(); }

            void addError(const ErrorInfo &info) { m_errors.append(info); }
            const ErrorList &errors() const { return m_errors; }

            QString helpText(const QString &symbol);

            RootNode *root() const { return m_root; }
            void setRoot(Config::RootNode *root);

            static Parser *self() { return s_self; }
   
      private:
            void makeHTMLLinks(QString &text, const QString &regexp,
                  const QString &prefix = QString::null) const;
             
      private:
            static Parser *s_self;

            QString m_kernelRoot;
            QString m_arch;
            RootNode *m_root;
            SymbolTable m_symbols;
            QPtrStack<RuleFile> m_ruleStack;
            ErrorList m_errors;
            QStringList m_help;
            QString m_helpTemplate;
      };

      class Node
      {
      public:
            enum Type
            {
                  Variable,
                  DependencyList,
                  Define,
                  Unset,
                  Input,
                  Choice,
                  // ExpressionNode and subclasses
                  Expression,
                  // TextNodeBase derived classes
                  MainMenuName,
                  Comment,
                  Text,
                  // BranchNodeBase derived classes
                  Root,
                  Menu,
                  If
            };
            virtual ~Node() {};
            virtual Type type() const = 0;
            virtual void initialize() {};
            virtual void apply() const {};
            virtual void write(QTextStream &) const {};
            virtual void writeHeader(QTextStream &) const {};
      };

      class VariableNode : public Node
      {
      public:
            VariableNode(QString *value) : m_value(*value) { delete value; }
            virtual ~VariableNode() {};

            virtual Type type() const { return Variable; }

            const QString &value() const;

      private:
            QString m_value;
      };

      class DependencyListNode : public Node
      {
      public:
            DependencyListNode(VariableList *values) : m_values(values) {};
            virtual ~DependencyListNode() { delete m_values; }

            virtual Type type() const { return DependencyList; }

            bool hasValue(const QString &value) const;

      private:
            VariableList *m_values;
      };

      class DefineNode : public Node
      {
      public:
            enum DefineType { Bool, Int, Hex, String, Tristate };

            DefineNode(DefineType type, QString *symbol, VariableNode *value)
                  : m_type(type), m_symbol(*symbol), m_value(value) { delete symbol; }
            virtual ~DefineNode() { delete m_value; }

            virtual Type type() const { return Define; }
            virtual void apply() const
            {
                  Parser::self()->setSymbol(m_symbol, m_value->value());
            }
            virtual void write(QTextStream &str) const;
            virtual void writeHeader(QTextStream &) const;

      private:
            DefineType m_type;
            QString m_symbol;
            VariableNode *m_value;
      };

      class UnsetNode : public Node
      {
      public:
            UnsetNode(QStringList *symbols)
                  : m_symbols(*symbols) { delete symbols; }
            virtual ~UnsetNode() {};

            virtual Type type() const { return Unset; }
            virtual void apply() const;

      private:
            QStringList m_symbols;
      };

      class InputNode : public Node
      {
      public:
            enum InputType { Bool, Hex, Int, String, Tristate };
            InputNode(QString *prompt, QString *symbol,
                  VariableNode *defValue, DependencyListNode *dependencies)
                  : m_prompt(*prompt), m_symbol(*symbol),
                    m_default(defValue),
                    m_dependencies(dependencies)
            {
                  delete prompt;
                  delete symbol;
            }
            virtual ~InputNode() { delete m_default; delete m_dependencies; }

            virtual Type type() const { return Input; }
            virtual void initialize();
            virtual void apply() const {
                  Parser::self()->setSymbol(m_symbol, value());
            }
            virtual void write(QTextStream &str) const;

            const QString &prompt() const { return m_prompt; }
            const QString &symbol() const { return m_symbol; }
            virtual bool isAvailable() const;
            virtual InputType inputType() const = 0;
            virtual QString value() const = 0;
            void setValue(const QString &value);

      protected:
            virtual void internalSetValue(const QString &value) = 0;

      private:
            QString m_prompt;
            QString m_symbol;
            QString m_value;
            VariableNode *m_default;

      protected:
            DependencyListNode *m_dependencies;
      };

      class BoolInputNode : public InputNode
      {
      public:
            BoolInputNode(QString *prompt, QString *symbol,
                  DependencyListNode *dependencies = 0)
                  : InputNode(prompt, symbol, 0, dependencies) {};
            virtual ~BoolInputNode() {};

            virtual void writeHeader(QTextStream &) const;

            virtual InputType inputType() const { return Bool; }
            virtual QString value() const;
            virtual void internalSetValue(const QString &value);

            void toggle();

      protected:
            bool m_value;
      };

      class RestricedBoolInputNode : public BoolInputNode
      {
      public:
            RestricedBoolInputNode(QString *prompt, QString *symbol,
                  DependencyListNode *dependencies = 0)
                  : BoolInputNode(prompt, symbol, dependencies) {};
            virtual ~RestricedBoolInputNode() {};

            virtual bool isAvailable() const;
      };

      class IntInputNode : public InputNode
      {
      public:
            IntInputNode(QString *prompt, QString *symbol, VariableNode *defValue,
                  DependencyListNode *dependencies = 0)
                  : InputNode(prompt, symbol, defValue, dependencies) {};
            virtual ~IntInputNode() { }

            virtual void writeHeader(QTextStream &) const;

            virtual InputType inputType() const { return Int; }
            virtual QString value() const;
            virtual void internalSetValue(const QString &value);

      protected:
            int m_value;
      };
   
      class HexInputNode : public IntInputNode
      {
      public:
            HexInputNode(QString *prompt, QString *symbol, VariableNode *defValue,
                  DependencyListNode *dependencies = 0)
                  : IntInputNode(prompt, symbol, defValue, dependencies) {};
            virtual ~HexInputNode() {};

            virtual void writeHeader(QTextStream &) const;

            virtual InputType inputType() const { return Hex; }
            virtual QString value() const;
            virtual void internalSetValue(const QString &value);
      };

      class StringInputNode : public InputNode
      {
      public:
            StringInputNode(QString *prompt, QString *symbol,
                  VariableNode *defValue, DependencyListNode *dependencies = 0)
                  : InputNode(prompt, symbol, defValue, dependencies) {};
            virtual ~StringInputNode() {};

            virtual void write(QTextStream &str) const;
            virtual void writeHeader(QTextStream &) const;

            virtual InputType inputType() const { return String; }
            virtual QString value() const;
            virtual void internalSetValue(const QString &value);

      private:
            QString m_value;
      };

      class TristateInputNode : public InputNode
      {
      public:
            TristateInputNode(QString *prompt, QString *symbol,
                  DependencyListNode *dependencies = 0)
                  : InputNode(prompt, symbol, 0, dependencies) {};
            virtual ~TristateInputNode() {};

            virtual void writeHeader(QTextStream &) const;

            virtual InputType inputType() const { return Tristate; }
            virtual QString value() const;
            virtual void internalSetValue(const QString &value);

            void advance();

      private:
            enum { No, Yes, Module } m_value;
      };
   
      class ChoiceNode : public Node
      {
      public:
            ChoiceNode(QString *prompt, const QStringList &labels,
                  const QStringList &symbols, int defIndex)
                  : m_prompt(*prompt), m_labels(labels), m_symbols(symbols),
                    m_defaultIndex(defIndex) { delete prompt; }
            virtual ~ChoiceNode() {};

            virtual Type type() const { return Choice; }
            virtual void initialize();
            virtual void apply() const;
            virtual void write(QTextStream &str) const;
            virtual void writeHeader(QTextStream &) const;

            const QString &prompt() const { return m_prompt; }
            const QStringList &labels() const { return m_labels; }
            const QStringList &symbols() const { return m_symbols; }
            int index() const { return m_index; }
            void setIndex(int index) { m_index = index; }

      private:
            QString m_prompt;
            QStringList m_labels;
            QStringList m_symbols;
            int m_defaultIndex;
            int m_index;
      };

      class ExpressionNode : public Node
      {
      public:
            virtual Type type() const { return Expression; }
            virtual bool evaluate() const = 0;
      };

      class NotExpressionNode : public ExpressionNode
      {
      public:
            NotExpressionNode(ExpressionNode *expression)
                  : m_expression(expression) {};
            virtual ~NotExpressionNode() { delete m_expression; }

            virtual bool evaluate() const { return !m_expression->evaluate(); }

      private:
            ExpressionNode *m_expression;
      };

      class AndExpressionNode : public ExpressionNode
      {
      public:
            AndExpressionNode(ExpressionNode *exp1, ExpressionNode *exp2)
                  : m_exp1(exp1), m_exp2(exp2) {};
            virtual ~AndExpressionNode() { delete m_exp1; delete m_exp2; }

            virtual bool evaluate() const { return m_exp1->evaluate() && m_exp2->evaluate(); }

      private:
            ExpressionNode *m_exp1;
            ExpressionNode *m_exp2;
      };

      class OrExpressionNode : public ExpressionNode
      {
      public:
            OrExpressionNode(ExpressionNode *exp1, ExpressionNode *exp2)
                  : m_exp1(exp1), m_exp2(exp2) {};
            virtual ~OrExpressionNode() { delete m_exp1; delete m_exp2; }

            virtual bool evaluate() const { return m_exp1->evaluate() || m_exp2->evaluate(); }

      private:
            ExpressionNode *m_exp1;
            ExpressionNode *m_exp2;
      };

      class ImplicitExpressionNode : public ExpressionNode
      {
      public:
            ImplicitExpressionNode(VariableNode *v)
                  : m_v(v) {};
            virtual ~ImplicitExpressionNode() { delete m_v; }

            virtual bool evaluate() const
            {
                  return !m_v->value().isEmpty() && !m_v->value().isNull();
            }

      private:
            VariableNode *m_v;
      };

      class EqualityExpressionNode : public ExpressionNode
      {
      public:
            EqualityExpressionNode(VariableNode *v1, VariableNode *v2)
                  : m_v1(v1), m_v2(v2) {};
            virtual ~EqualityExpressionNode() { delete m_v1; delete m_v2; }

            virtual bool evaluate() const
            {
                  return m_v1->value() == m_v2->value();
            }

      private:
            VariableNode *m_v1;
            VariableNode *m_v2;
      };

      class UnequalityExpressionNode : public ExpressionNode
      {
      public:
            UnequalityExpressionNode(VariableNode *v1, VariableNode *v2)
                  : m_v1(v1), m_v2(v2) {};
            virtual ~UnequalityExpressionNode() { delete m_v1; delete m_v2; }

            virtual bool evaluate() const
            {
                  return m_v1->value() != m_v2->value();
            }

      private:
            VariableNode *m_v1;
            VariableNode *m_v2;
      };

      class TextNodeBase : public Node
      {
      public:
            TextNodeBase(QString *text) : m_text(*text) { delete text; }
            virtual ~TextNodeBase() {};

            const QString &text() const { return m_text; }

      private:
            QString m_text;
      };

      class MainMenuNameNode : public TextNodeBase
      {
      public:
            MainMenuNameNode(QString *text) : TextNodeBase(text) {};
            virtual ~MainMenuNameNode() {};

            virtual Type type() const { return MainMenuName; }
      };

      class CommentNode : public TextNodeBase
      {
      public:
            CommentNode(QString *text) : TextNodeBase(text) {};
            virtual ~CommentNode() {};

            virtual Type type() const { return Comment; }
      };

      class TextNode : public TextNodeBase
      {
      public:
            TextNode(QString *text) : TextNodeBase(text) {};
            virtual ~TextNode() {};

            virtual Type type() const { return Text; }
      };

      class BranchNodeBase : public Node
      {
      public:
            virtual void initialize();
            virtual NodeList *children() const = 0;

            virtual void apply() const;
            virtual void write(QTextStream &str) const;
            virtual void writeHeader(QTextStream &) const;
      };

      class RootNode : public BranchNodeBase
      {
      public:
            RootNode(MainMenuNameNode *name, NodeList *children)
                  : m_name(name), m_children(children) {};
            virtual ~RootNode() { delete m_name; delete m_children; }

            virtual Type type() const { return Root; }
            virtual void write(QTextStream &str) const;
            virtual void writeHeader(QTextStream &) const;

            virtual NodeList *children() const { return m_children; }
            const MainMenuNameNode *name() const { return m_name; }

      public:
            MainMenuNameNode *m_name;
            NodeList *m_children;
      };

      class MenuNode : public BranchNodeBase
      {
      public:
            MenuNode(CommentNode *comment, NodeList *children)
                  : m_comment(comment), m_children(children) {};
            virtual ~MenuNode() { delete m_comment; delete m_children; }

            virtual Type type() const { return Menu; }
            virtual void write(QTextStream &str) const;
            virtual void writeHeader(QTextStream &) const;

            virtual NodeList *children() const { return m_children; }
            const CommentNode *comment() const { return m_comment; }

      private:
            CommentNode *m_comment;
            NodeList *m_children;
      };

      class IfNode : public BranchNodeBase
      {
      public:
            IfNode(ExpressionNode *condition, NodeList *trueChildren,
                  NodeList *falseChildren = 0)
                  : m_condition(condition), m_trueChildren(trueChildren),
                    m_falseChildren(falseChildren) {};
            virtual ~IfNode()
            {
                  delete m_condition;
                  delete m_trueChildren;
                  delete m_falseChildren;
            }

            virtual Type type() const { return If; }
            virtual void initialize();
            virtual NodeList *children() const
            {
                  return m_condition->evaluate() ? m_trueChildren : m_falseChildren;
            }

      private:
            ExpressionNode *m_condition;
            NodeList *m_trueChildren;
            NodeList *m_falseChildren;
      };
}

#endif
// vim: ts=4 sw=4 noet

Generated by  Doxygen 1.6.0   Back to index