LTP GCOV extension - code coverage report
Current view: directory - usr/include/tagcoll-2.0.11/tagcoll - expression.h
Test: lcov.info
Date: 2008-08-14 Instrumented lines: 10
Code covered: 100.0 % Executed lines: 10

       1                 : #ifndef TAGCOLL_EXPRESSION_H
       2                 : #define TAGCOLL_EXPRESSION_H
       3                 : 
       4                 : /*
       5                 :  * Expression that can match tagsets
       6                 :  * 
       7                 :  * Copyright (C) 2003,2004,2005,2006  Enrico Zini <enrico@debian.org>
       8                 :  *
       9                 :  * This library is free software; you can redistribute it and/or
      10                 :  * modify it under the terms of the GNU Lesser General Public
      11                 :  * License as published by the Free Software Foundation; either
      12                 :  * version 2.1 of the License, or (at your option) any later version.
      13                 :  *
      14                 :  * This library is distributed in the hope that it will be useful,
      15                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17                 :  * Lesser General Public License for more details.
      18                 :  *
      19                 :  * You should have received a copy of the GNU Lesser General Public
      20                 :  * License along with this library; if not, write to the Free Software
      21                 :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
      22                 :  */
      23                 : 
      24                 : #include <string>
      25                 : #include <set>
      26                 : #include <map>
      27                 : #include <wibble/singleton.h>
      28                 : #include <wibble/mixin.h>
      29                 : 
      30                 : namespace tagcoll
      31                 : {
      32                 : 
      33                 : class TagexprContext;
      34                 : 
      35                 : /**
      36                 :  * Interface for parsed tag expressions
      37                 :  */
      38                 : class ExpressionImpl
      39                 : {
      40                 : protected:
      41                 :         int _ref;
      42                 : 
      43                 : public:
      44                 :         ExpressionImpl() : _ref(0) {}
      45                 :         virtual ~ExpressionImpl() {}
      46                 : 
      47                 :         /// Increment the reference count for this object
      48              10 :         void ref() throw () { ++_ref; }
      49                 : 
      50                 :         /// Decrement the reference count for this object, returning true when it
      51                 :         /// reaches 0
      52              22 :         bool unref() throw () { return --_ref == 0; }
      53                 : 
      54                 :         /**
      55                 :          * Provide a string representation of this expression
      56                 :          */
      57                 :         virtual std::string format() const = 0;
      58                 : 
      59                 :         /**
      60                 :          * Evaluates the expression on a recursive context
      61                 :          *
      62                 :          * \see TagexprContext
      63                 :          */
      64                 :         virtual bool eval(const TagexprContext& context) const = 0;
      65                 : 
      66                 :         /**
      67                 :          * Evaluates the expression on a set of tags
      68                 :          *
      69                 :          * \return
      70                 :          *   true if the expression matches the tags, false otherwise
      71                 :          */
      72                 :         virtual bool eval(const std::set<std::string>& tags) const = 0;
      73                 : 
      74                 :         /**
      75                 :          * Return a clone of this tag expression
      76                 :          */
      77                 :         //virtual Tagexpr* clone() const = 0;
      78                 : };
      79                 : 
      80                 : class Expression
      81                 : {
      82                 : protected:
      83                 :         ExpressionImpl* m_impl;
      84                 : 
      85                 :         Expression(ExpressionImpl* impl) : m_impl(impl) { m_impl->ref(); }
      86                 : 
      87                 :         const ExpressionImpl* impl() const { return m_impl; }
      88                 :         ExpressionImpl* impl() { return m_impl; }
      89                 : 
      90                 : public:
      91                 :         Expression();
      92                 :         Expression(const std::string& expr);
      93                 : 
      94                 :         Expression(const Expression& e)
      95                 :         {
      96                 :                 if (e.m_impl)
      97                 :                         e.m_impl->ref();
      98                 :                 m_impl = e.m_impl;
      99                 :         }
     100              12 :         ~Expression() { if (m_impl->unref()) delete m_impl; }
     101                 : 
     102              10 :         Expression& operator=(const Expression& e)
     103                 :         {
     104              10 :                 if (e.m_impl)
     105              10 :                         e.m_impl->ref();  // Do it early to correctly handle the case of x = x;
     106              10 :                 if (m_impl && m_impl->unref())
     107              10 :                         delete m_impl;
     108              10 :                 m_impl = e.m_impl;
     109              10 :                 return *this;
     110                 :         }
     111                 : 
     112                 :         Expression operator and (const Expression& e);
     113                 :         Expression operator or (const Expression& e);
     114                 :         Expression operator not ();
     115                 : 
     116                 :         template<typename Tags>
     117                 :         bool operator()(const Tags& tags) const
     118                 :         {
     119                 :                 std::set<std::string> stags;
     120                 :                 for (typename Tags::const_iterator i = tags.begin();
     121                 :                                 i != tags.end(); ++i)
     122                 :                         stags.insert(*i);
     123                 :                 return m_impl->eval(stags);
     124                 :         }
     125                 :         bool operator()(const std::set<std::string>& tags) const { return m_impl->eval(tags); }
     126                 : 
     127                 :         bool operator()(const TagexprContext& context) const { return m_impl->eval(context); }
     128                 : 
     129                 :         std::string format() const { return m_impl->format(); }
     130                 : 
     131                 :         static Expression matchTag(const std::string& pattern);
     132                 : };
     133                 : 
     134                 : /**
     135                 :  * Context for evaluating expressions of derived tags.
     136                 :  *
     137                 :  * A derived tag is a tag which is automatically inferred when a tag expression
     138                 :  * is matched on a tagset.
     139                 :  *
     140                 :  * TagexprContext allows the inference engine to distinguish between a normal
     141                 :  * tag or a derived tag.
     142                 :  *
     143                 :  * This class is mainly used to support DerivedTags and has probably little
     144                 :  * applications elsewhere.
     145                 :  */
     146                 : class TagexprContext
     147                 : {
     148                 : protected:
     149                 :         const std::set<std::string>& tags;
     150                 :         const std::map<std::string, Expression>& derivedTags;
     151                 :         // Tags "visited" during tag evaluation: used to break circular loops
     152                 :         mutable std::set<std::string> seen;
     153                 : 
     154                 : public:
     155                 :         /**
     156                 :          * Create a context for recursive tagset evaluation
     157                 :          *
     158                 :          * Evaluation happens using a derivation table, which can list a tag as an
     159                 :          * alias for another tag expression.  Whenever a tag is matched for
     160                 :          * equality with a derived tag, the match is performed with the derived tag
     161                 :          * expression instead.
     162                 :          * 
     163                 :          * \param tags
     164                 :          *   The tags to evaluate
     165                 :          * \param derivedTags
     166                 :          *   The table of derived tags to use in the evaluation
     167                 :          */
     168                 :         TagexprContext(const std::set<std::string>& tags, const std::map<std::string, Expression>& derivedTags)
     169                 :                 : tags(tags), derivedTags(derivedTags) {}
     170                 : 
     171                 :         /**
     172                 :          * Evaluates the input tags on the contents to see if they contain the
     173                 :          * given tag, or if they match its associated tag expression if tag is a
     174                 :          * derived tag
     175                 :          */
     176                 :         bool eval(const std::string& tag) const;
     177                 : };
     178                 : 
     179                 : };
     180                 : 
     181                 : // vim:set ts=4 sw=4:
     182                 : #endif

Generated by: LTP GCOV extension version 1.6