File indexing completed on 2024-12-01 09:55:31

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef __ktrader_parse_tree_h__
0009 #define __ktrader_parse_tree_h__
0010 
0011 #include <QMap>
0012 #include <QString>
0013 #include <QStringList>
0014 
0015 #include <kplugininfo.h>
0016 #include <kservice.h>
0017 
0018 namespace KTraderParse
0019 {
0020 class ParseTreeBase;
0021 
0022 /**
0023  * @internal
0024  * @return 0  => Does not match
0025  *         1  => Does match
0026  *         <0 => Error
0027  */
0028 int matchConstraint(const ParseTreeBase *_tree, const KService::Ptr &, const KService::List &);
0029 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90)
0030 int matchConstraintPlugin(const ParseTreeBase *_tree, const KPluginInfo &_info, const KPluginInfo::List &_list);
0031 #endif
0032 
0033 /**
0034  * @internal
0035  */
0036 struct KSERVICE_EXPORT PreferencesMaxima {
0037     PreferencesMaxima()
0038         : iMax(0)
0039         , iMin(0)
0040         , fMax(0)
0041         , fMin(0)
0042     {
0043     }
0044 
0045     enum Type { PM_ERROR, PM_INVALID_INT, PM_INVALID_DOUBLE, PM_DOUBLE, PM_INT };
0046 
0047     Type type;
0048     int iMax;
0049     int iMin;
0050     double fMax;
0051     double fMin;
0052 };
0053 
0054 /**
0055  * @internal
0056  */
0057 class ParseContext
0058 {
0059 public:
0060     /**
0061      * This is NOT a copy constructor.
0062      */
0063     explicit ParseContext(const ParseContext *_ctx)
0064         : service(_ctx->service)
0065         , maxima(_ctx->maxima)
0066         , offers(_ctx->offers)
0067 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90)
0068         , info(_ctx->info)
0069         , pluginOffers(_ctx->pluginOffers)
0070 #endif
0071     {
0072     }
0073     ParseContext(const KService::Ptr &_service, const KService::List &_offers, QMap<QString, PreferencesMaxima> &_m)
0074         : service(_service)
0075         , maxima(_m)
0076         , offers(_offers)
0077 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90)
0078         , info(KPluginInfo())
0079         , pluginOffers(KPluginInfo::List())
0080 #endif
0081     {
0082     }
0083 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90)
0084     ParseContext(const KPluginInfo &_info, const KPluginInfo::List &_offers, QMap<QString, PreferencesMaxima> &_m)
0085         : service(nullptr)
0086         , maxima(_m)
0087         , offers(KService::List())
0088         , info(_info)
0089         , pluginOffers(_offers)
0090     {
0091     }
0092 #endif
0093 
0094     bool initMaxima(const QString &_prop);
0095 
0096     QVariant property(const QString &_key) const;
0097 
0098     enum Type {
0099         T_STRING = 1,
0100         T_DOUBLE = 2,
0101         T_NUM = 3,
0102         T_BOOL = 4,
0103         T_STR_SEQ = 5,
0104         T_SEQ = 6,
0105     };
0106 
0107     QString str;
0108     int i;
0109     double f;
0110     bool b;
0111     QList<QVariant> seq;
0112     QStringList strSeq;
0113     Type type;
0114 
0115     KService::Ptr service;
0116 
0117     QMap<QString, PreferencesMaxima> &maxima;
0118     KService::List offers;
0119 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 90)
0120     KPluginInfo info;
0121     KPluginInfo::List pluginOffers;
0122 #endif
0123 };
0124 
0125 /**
0126  * @internal
0127  */
0128 class ParseTreeBase : public QSharedData
0129 {
0130 public:
0131     typedef QExplicitlySharedDataPointer<ParseTreeBase> Ptr;
0132     ParseTreeBase()
0133     {
0134     }
0135     virtual ~ParseTreeBase();
0136 
0137     virtual bool eval(ParseContext *_context) const = 0;
0138 };
0139 
0140 ParseTreeBase::Ptr parseConstraints(const QString &_constr);
0141 
0142 /**
0143  * @internal
0144  */
0145 class ParseTreeOR : public ParseTreeBase
0146 {
0147 public:
0148     ParseTreeOR(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2)
0149         : m_pLeft(_ptr1)
0150         , m_pRight(_ptr2)
0151     {
0152     }
0153 
0154     bool eval(ParseContext *_context) const override;
0155 
0156 protected:
0157     ParseTreeBase::Ptr m_pLeft;
0158     ParseTreeBase::Ptr m_pRight;
0159 };
0160 
0161 /**
0162  * @internal
0163  */
0164 class ParseTreeAND : public ParseTreeBase
0165 {
0166 public:
0167     ParseTreeAND(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2)
0168         : m_pLeft(_ptr1)
0169         , m_pRight(_ptr2)
0170     {
0171     }
0172 
0173     bool eval(ParseContext *_context) const override;
0174 
0175 protected:
0176     ParseTreeBase::Ptr m_pLeft;
0177     ParseTreeBase::Ptr m_pRight;
0178 };
0179 
0180 /**
0181  * @internal
0182  */
0183 class ParseTreeCMP : public ParseTreeBase
0184 {
0185 public:
0186     ParseTreeCMP(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, int _i)
0187         : m_pLeft(_ptr1)
0188         , m_pRight(_ptr2)
0189         , m_cmd(_i)
0190     {
0191     }
0192 
0193     bool eval(ParseContext *_context) const override;
0194 
0195 protected:
0196     ParseTreeBase::Ptr m_pLeft;
0197     ParseTreeBase::Ptr m_pRight;
0198     int m_cmd;
0199 };
0200 
0201 /**
0202  * @internal
0203  */
0204 class ParseTreeIN : public ParseTreeBase
0205 {
0206 public:
0207     ParseTreeIN(ParseTreeBase *ptr1, ParseTreeBase *ptr2, Qt::CaseSensitivity cs, bool substring = false)
0208         : m_pLeft(ptr1)
0209         , m_pRight(ptr2)
0210         , m_cs(cs)
0211         , m_substring(substring)
0212     {
0213     }
0214 
0215     bool eval(ParseContext *_context) const override;
0216 
0217 protected:
0218     ParseTreeBase::Ptr m_pLeft;
0219     ParseTreeBase::Ptr m_pRight;
0220     Qt::CaseSensitivity m_cs;
0221     bool m_substring;
0222 };
0223 
0224 /**
0225  * @internal
0226  */
0227 class ParseTreeMATCH : public ParseTreeBase
0228 {
0229 public:
0230     ParseTreeMATCH(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, Qt::CaseSensitivity cs)
0231         : m_pLeft(_ptr1)
0232         , m_pRight(_ptr2)
0233         , m_cs(cs)
0234     {
0235     }
0236 
0237     bool eval(ParseContext *_context) const override;
0238 
0239 protected:
0240     ParseTreeBase::Ptr m_pLeft;
0241     ParseTreeBase::Ptr m_pRight;
0242     Qt::CaseSensitivity m_cs;
0243 };
0244 
0245 /**
0246  * @internal
0247  *
0248  * A sub-sequence match is like a sub-string match except the characters
0249  * do not have to be contiguous. For example 'ct' is a sub-sequence of 'cat'
0250  * but not a sub-string. 'at' is both a sub-string and sub-sequence of 'cat'.
0251  * All sub-strings are sub-sequences.
0252  *
0253  * This is useful if you want to support a fuzzier search, say for instance
0254  * you are searching for `LibreOffice 6.0 Writer`, after typing `libre` you
0255  * see a list of all the LibreOffice apps, to narrow down that list you only
0256  * need to add `write` (so the search term is `librewrite`) instead of typing
0257  * out the entire app name until a distinguishing letter is reached.
0258  * It's also useful to allow the user to forget to type some characters.
0259  */
0260 class ParseTreeSubsequenceMATCH : public ParseTreeBase
0261 {
0262 public:
0263     ParseTreeSubsequenceMATCH(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, Qt::CaseSensitivity cs)
0264         : m_pLeft(_ptr1)
0265         , m_pRight(_ptr2)
0266         , m_cs(cs)
0267     {
0268     }
0269 
0270     bool eval(ParseContext *_context) const override;
0271 
0272 protected:
0273     ParseTreeBase::Ptr m_pLeft;
0274     ParseTreeBase::Ptr m_pRight;
0275     Qt::CaseSensitivity m_cs;
0276 };
0277 
0278 /**
0279  * @internal
0280  */
0281 class ParseTreeCALC : public ParseTreeBase
0282 {
0283 public:
0284     ParseTreeCALC(ParseTreeBase *_ptr1, ParseTreeBase *_ptr2, int _i)
0285         : m_pLeft(_ptr1)
0286         , m_pRight(_ptr2)
0287         , m_cmd(_i)
0288     {
0289     }
0290 
0291     bool eval(ParseContext *_context) const override;
0292 
0293 protected:
0294     ParseTreeBase::Ptr m_pLeft;
0295     ParseTreeBase::Ptr m_pRight;
0296     int m_cmd;
0297 };
0298 
0299 /**
0300  * @internal
0301  */
0302 class ParseTreeBRACKETS : public ParseTreeBase
0303 {
0304 public:
0305     explicit ParseTreeBRACKETS(ParseTreeBase *_ptr)
0306         : m_pLeft(_ptr)
0307     {
0308     }
0309 
0310     bool eval(ParseContext *_context) const override;
0311 
0312 protected:
0313     ParseTreeBase::Ptr m_pLeft;
0314 };
0315 
0316 /**
0317  * @internal
0318  */
0319 class ParseTreeNOT : public ParseTreeBase
0320 {
0321 public:
0322     explicit ParseTreeNOT(ParseTreeBase *_ptr)
0323         : m_pLeft(_ptr)
0324     {
0325     }
0326 
0327     bool eval(ParseContext *_context) const override;
0328 
0329 protected:
0330     ParseTreeBase::Ptr m_pLeft;
0331 };
0332 
0333 /**
0334  * @internal
0335  */
0336 class ParseTreeEXIST : public ParseTreeBase
0337 {
0338 public:
0339     explicit ParseTreeEXIST(const char *_id)
0340         : m_id(QString::fromUtf8(_id))
0341     {
0342     }
0343 
0344     bool eval(ParseContext *_context) const override;
0345 
0346 protected:
0347     QString m_id;
0348 };
0349 
0350 /**
0351  * @internal
0352  */
0353 class ParseTreeID : public ParseTreeBase
0354 {
0355 public:
0356     explicit ParseTreeID(const char *arg)
0357         : m_str(QString::fromUtf8(arg))
0358     {
0359     }
0360 
0361     bool eval(ParseContext *_context) const override;
0362 
0363 protected:
0364     QString m_str;
0365 };
0366 
0367 /**
0368  * @internal
0369  */
0370 class ParseTreeSTRING : public ParseTreeBase
0371 {
0372 public:
0373     explicit ParseTreeSTRING(const char *arg)
0374         : m_str(QString::fromUtf8(arg))
0375     {
0376     }
0377 
0378     bool eval(ParseContext *_context) const override;
0379 
0380 protected:
0381     QString m_str;
0382 };
0383 
0384 /**
0385  * @internal
0386  */
0387 class ParseTreeNUM : public ParseTreeBase
0388 {
0389 public:
0390     explicit ParseTreeNUM(int arg)
0391     {
0392         m_int = arg;
0393     }
0394 
0395     bool eval(ParseContext *_context) const override;
0396 
0397 protected:
0398     int m_int;
0399 };
0400 
0401 /**
0402  * @internal
0403  */
0404 class ParseTreeDOUBLE : public ParseTreeBase
0405 {
0406 public:
0407     explicit ParseTreeDOUBLE(double arg)
0408     {
0409         m_double = arg;
0410     }
0411 
0412     bool eval(ParseContext *_context) const override;
0413 
0414 protected:
0415     double m_double;
0416 };
0417 
0418 /**
0419  * @internal
0420  */
0421 class ParseTreeBOOL : public ParseTreeBase
0422 {
0423 public:
0424     explicit ParseTreeBOOL(bool arg)
0425     {
0426         m_bool = arg;
0427     }
0428 
0429     bool eval(ParseContext *_context) const override;
0430 
0431 protected:
0432     bool m_bool;
0433 };
0434 
0435 /**
0436  * @internal
0437  */
0438 class ParseTreeMAX2 : public ParseTreeBase
0439 {
0440 public:
0441     explicit ParseTreeMAX2(const char *_id)
0442         : m_strId(QString::fromUtf8(_id))
0443     {
0444     }
0445 
0446     bool eval(ParseContext *_context) const override;
0447 
0448 protected:
0449     QString m_strId;
0450 };
0451 
0452 /**
0453  * @internal
0454  */
0455 class ParseTreeMIN2 : public ParseTreeBase
0456 {
0457 public:
0458     explicit ParseTreeMIN2(const char *_id)
0459         : m_strId(QString::fromUtf8(_id))
0460     {
0461     }
0462 
0463     bool eval(ParseContext *_context) const override;
0464 
0465 protected:
0466     QString m_strId;
0467 };
0468 
0469 }
0470 
0471 #endif