• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

  • tdeio
  • tdeio
ktraderparsetree.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "ktraderparsetree.h"
21 
22 namespace TDEIO {
23 
24 bool ParseTreeOR::eval( ParseContext *_context ) const
25 {
26  ParseContext c1( _context );
27  ParseContext c2( _context );
28 
29 // don't evaluate both expressions but return immediately
30 // if the first one of them succeeds. Otherwise queries like
31 // ((not exist Blah) or (Blah == 'Foo')) do not work, because
32 // the evaluation of the second term ends up in a fatal error
33 // (Simon)
34 
35  if ( !m_pLeft->eval( &c1 ) )
36  return false;
37 
38  if ( c1.type != ParseContext::T_BOOL )
39  return false;
40 
41  _context->b = c1.b;
42  _context->type = ParseContext::T_BOOL;
43  if ( c1.b )
44  return true;
45 
46  if ( !m_pRight->eval( &c2 ) )
47  return false;
48 
49  if ( c2.type != ParseContext::T_BOOL )
50  return false;
51 
52  _context->b = ( c1.b || c2.b );
53  _context->type = ParseContext::T_BOOL;
54 
55  return true;
56 }
57 
58 bool ParseTreeAND::eval( ParseContext *_context ) const
59 {
60  _context->type = ParseContext::T_BOOL;
61 
62  ParseContext c1( _context );
63  ParseContext c2( _context );
64  if ( !m_pLeft->eval( &c1 ) )
65  return false;
66  if ( c1.type != ParseContext::T_BOOL )
67  return false;
68  if ( !c1.b )
69  {
70  _context->b = false;
71  return true;
72  }
73 
74  if ( !m_pRight->eval( &c2 ) )
75  return false;
76  if ( c2.type != ParseContext::T_BOOL )
77  return false;
78 
79  _context->b = ( c1.b && c2.b );
80 
81  return true;
82 }
83 
84 bool ParseTreeCALC::eval( ParseContext *_context ) const
85 {
86  ParseContext c1( _context );
87  ParseContext c2( _context );
88  if ( !m_pLeft->eval( &c1 ) )
89  return false;
90  if ( !m_pRight->eval( &c2 ) )
91  return false;
92 
93  // Bool extension
94  if ( c1.type != ParseContext::T_NUM && c1.type != ParseContext::T_DOUBLE && c1.type != ParseContext::T_BOOL )
95  return false;
96  // Bool extension
97  if ( c2.type != ParseContext::T_NUM && c2.type != ParseContext::T_DOUBLE && c2.type != ParseContext::T_BOOL )
98  return false;
99  // Bool extension
100  if ( c1.type == ParseContext::T_BOOL && c2.type == ParseContext::T_BOOL )
101  return false;
102 
106  if ( c1.type == ParseContext::T_NUM && c2.type == ParseContext::T_DOUBLE )
107  {
108  c1.type = ParseContext::T_DOUBLE;
109  c1.f = (double)c1.i;
110  }
111  else if ( c1.type == ParseContext::T_DOUBLE && c2.type == ParseContext::T_NUM )
112  {
113  c2.type = ParseContext::T_DOUBLE;
114  c2.f = (double)c2.i;
115  }
116  // Bool extension
117  else if ( c1.type == ParseContext::T_BOOL && c2.type == ParseContext::T_NUM )
118  {
119  c1.type = ParseContext::T_NUM;
120  if ( c1.b )
121  c1.i = 1;
122  else
123  c1.i = -1;
124  }
125  // Bool extension
126  else if ( c1.type == ParseContext::T_BOOL && c2.type == ParseContext::T_DOUBLE )
127  {
128  c1.type = ParseContext::T_DOUBLE;
129  if ( c1.b )
130  c1.f = 1.0;
131  else
132  c1.f = -1.0;
133  }
134  // Bool extension
135  else if ( c1.type == ParseContext::T_NUM && c2.type == ParseContext::T_BOOL )
136  {
137  c2.type = ParseContext::T_NUM;
138  if ( c2.b )
139  c2.i = 1;
140  else
141  c2.i = -1;
142  }
143  // Bool extension
144  else if ( c1.type == ParseContext::T_DOUBLE && c2.type == ParseContext::T_BOOL )
145  {
146  c2.type = ParseContext::T_DOUBLE;
147  if ( c2.b )
148  c2.f = 1.0;
149  else
150  c2.f = -1.0;
151  }
152 
153  _context->type = c1.type;
154 
158  switch( m_cmd )
159  {
160  case 1: /* Add */
161  if ( c1.type == ParseContext::T_DOUBLE )
162  {
163  _context->f = ( c1.f + c2.f );
164  return true;
165  }
166  if ( c1.type == ParseContext::T_NUM )
167  {
168  _context->i = ( c1.i + c2.i );
169  return true;
170  }
171  break;
172  case 2: /* Sub */
173  if ( c1.type == ParseContext::T_DOUBLE )
174  {
175  _context->f = ( c1.f - c2.f );
176  return true;
177  }
178  if ( c1.type == ParseContext::T_NUM )
179  {
180  _context->i = ( c1.i - c2.i );
181  return true;
182  }
183  break;
184  case 3: /* Mul */
185  if ( c1.type == ParseContext::T_DOUBLE )
186  {
187  //cout << "Double Mult" << endl;
188  _context->f = ( c1.f * c2.f );
189  return true;
190  }
191  if ( c1.type == ParseContext::T_NUM )
192  {
193  _context->i = ( c1.i * c2.i );
194  return true;
195  }
196  break;
197  case 4: /* Div */
198  if ( c1.type == ParseContext::T_DOUBLE )
199  {
200  _context->f = ( c1.f / c2.f );
201  return true;
202  }
203  if ( c1.type == ParseContext::T_NUM )
204  {
205  _context->i = ( c1.i / c2.i );
206  return true;
207  }
208  break;
209  }
210 
211  return false;
212 }
213 
214 bool ParseTreeCMP::eval( ParseContext *_context ) const
215 {
216  //cout << "CMP 1 cmd=" << m_cmd << endl;
217  ParseContext c1( _context );
218  ParseContext c2( _context );
219  if ( !m_pLeft->eval( &c1 ) )
220  return false;
221 
222  if ( !m_pRight->eval( &c2 ) )
223  return false;
224 
228  if ( c1.type == ParseContext::T_NUM && c2.type == ParseContext::T_DOUBLE )
229  {
230  c1.type = ParseContext::T_DOUBLE;
231  c1.f = (double)c1.i;
232  }
233  else if ( c1.type == ParseContext::T_DOUBLE && c2.type == ParseContext::T_NUM )
234  {
235  c2.type = ParseContext::T_DOUBLE;
236  c2.f = (double)c2.i;
237  }
238 
242  _context->type = ParseContext::T_BOOL;
243 
244  switch( m_cmd )
245  {
246  case 1: /* EQ */
247  if ( c1.type != c2.type )
248  {
249  _context->b = false;
250  return true;
251  }
252  if ( c1.type == ParseContext::T_STRING )
253  {
254  _context->b = ( c1.str == c2.str );
255  return true;
256  }
257  if ( c1.type == ParseContext::T_BOOL )
258  {
259  _context->b = ( c1.b == c2.b );
260  return true;
261  }
262  if ( c1.type == ParseContext::T_DOUBLE )
263  {
264  _context->b = ( c1.f == c2.f );
265  return true;
266  }
267  if ( c1.type == ParseContext::T_NUM )
268  {
269  _context->b = ( c1.i == c2.i );
270  return true;
271  }
272  break;
273  case 2: /* NEQ */
274  if ( c1.type != c2.type )
275  {
276  _context->b = true;
277  return true;
278  }
279  if ( c1.type == ParseContext::T_STRING )
280  {
281  _context->b = ( c1.str != c2.str );
282  return true;
283  }
284  if ( c1.type == ParseContext::T_BOOL )
285  {
286  _context->b = ( c1.b != c2.b );
287  return true;
288  }
289  if ( c1.type == ParseContext::T_DOUBLE )
290  {
291  _context->b = ( c1.f != c2.f );
292  return true;
293  }
294  if ( c1.type == ParseContext::T_NUM )
295  {
296  _context->b = ( c1.i != c2.i );
297  return true;
298  }
299  break;
300  case 3: /* GEQ */
301  if ( c1.type != c2.type )
302  {
303  _context->b = false;
304  return true;
305  }
306  if ( c1.type == ParseContext::T_DOUBLE )
307  {
308  _context->b = ( c1.f >= c2.f );
309  return true;
310  }
311  if ( c1.type == ParseContext::T_NUM )
312  {
313  _context->b = ( c1.i >= c2.i );
314  return true;
315  }
316  _context->b = false;
317  return true;
318 
319  case 4: /* LEQ */
320  if ( c1.type != c2.type )
321  {
322  _context->b = false;
323  return true;
324  }
325  if ( c1.type == ParseContext::T_DOUBLE )
326  {
327  _context->b = ( c1.f <= c2.f );
328  return true;
329  }
330  if ( c1.type == ParseContext::T_NUM )
331  {
332  _context->b = ( c1.i <= c2.i );
333  return true;
334  }
335  _context->b = false;
336  return true;
337 
338  case 5: /* < */
339  if ( c1.type != c2.type )
340  {
341  _context->b = false;
342  return true;
343  }
344  if ( c1.type == ParseContext::T_DOUBLE )
345  {
346  _context->b = ( c1.f < c2.f );
347  return true;
348  }
349  if ( c1.type == ParseContext::T_NUM )
350  {
351  _context->b = ( c1.i < c2.i );
352  return true;
353  }
354  _context->b = false;
355  return true;
356 
357  case 6: /* > */
358  if ( c1.type != c2.type )
359  {
360  _context->b = false;
361  return true;
362  }
363  if ( c1.type == ParseContext::T_DOUBLE )
364  {
365  _context->b = ( c1.f > c2.f );
366  return true;
367  }
368  if ( c1.type == ParseContext::T_NUM )
369  {
370  _context->b = ( c1.i > c2.i );
371  return true;
372  }
373  _context->b = false;
374  return true;
375 
376  }
377 
378  return false;
379 }
380 
381 bool ParseTreeNOT::eval( ParseContext *_context ) const
382 {
383  ParseContext c1( _context );
384  if ( !m_pLeft->eval( &c1 ) )
385  return false;
386  if ( c1.type != ParseContext::T_BOOL )
387  return false;
388 
389  _context->b = !c1.b;
390  _context->type = ParseContext::T_BOOL;
391 
392  return true;
393 }
394 
395 bool ParseTreeEXIST::eval( ParseContext *_context ) const
396 {
397  _context->type = ParseContext::T_BOOL;
398 
399  TQVariant prop = _context->service->property( m_id );
400  _context->b = prop.isValid();
401 
402  return true;
403 }
404 
405 bool ParseTreeMATCH::eval( ParseContext *_context ) const
406 {
407  _context->type = ParseContext::T_BOOL;
408 
409  ParseContext c1( _context );
410  ParseContext c2( _context );
411  if ( !m_pLeft->eval( &c1 ) )
412  return false;
413  if ( !m_pRight->eval( &c2 ) )
414  return false;
415  if ( c1.type != ParseContext::T_STRING || c2.type != ParseContext::T_STRING )
416  return false;
417 
418  _context->b = ( c2.str.find( c1.str ) != -1 );
419 
420  return true;
421 }
422 
423 bool ParseTreeIN::eval( ParseContext *_context ) const
424 {
425  _context->type = ParseContext::T_BOOL;
426 
427  ParseContext c1( _context );
428  ParseContext c2( _context );
429  if ( !m_pLeft->eval( &c1 ) )
430  return false;
431  if ( !m_pRight->eval( &c2 ) )
432  return false;
433 
434  if ( (c1.type == ParseContext::T_NUM) &&
435  (c2.type == ParseContext::T_SEQ) &&
436  ((*(c2.seq.begin())).type() == TQVariant::Int)) {
437 
438  TQValueList<TQVariant>::ConstIterator it = c2.seq.begin();
439  TQValueList<TQVariant>::ConstIterator end = c2.seq.end();
440  _context->b = false;
441  for (; it != end; it++)
442  if ((*it).type() == TQVariant::Int &&
443  (*it).toInt() == c1.i) {
444  _context->b = true;
445  break;
446  }
447  return true;
448  }
449 
450  if ( c1.type == ParseContext::T_DOUBLE &&
451  c2.type == ParseContext::T_SEQ &&
452  (*(c2.seq.begin())).type() == TQVariant::Double) {
453 
454  TQValueList<TQVariant>::ConstIterator it = c2.seq.begin();
455  TQValueList<TQVariant>::ConstIterator end = c2.seq.end();
456  _context->b = false;
457  for (; it != end; it++)
458  if ((*it).type() == TQVariant::Double &&
459  (*it).toDouble() == c1.i) {
460  _context->b = true;
461  break;
462  }
463  return true;
464  }
465 
466  if ( c1.type == ParseContext::T_STRING && c2.type == ParseContext::T_STR_SEQ )
467  {
468  _context->b = ( c2.strSeq.find( c1.str ) != c2.strSeq.end() );
469  return true;
470  }
471 
472  return false;
473 }
474 
475 bool ParseTreeID::eval( ParseContext *_context ) const
476 {
477  TQVariant prop = _context->service->property( m_str );
478  if ( !prop.isValid() )
479  return false;
480 
481  if ( prop.type() == TQVariant::String )
482  {
483  _context->str = prop.toString();
484  _context->type = ParseContext::T_STRING;
485  return true;
486  }
487 
488  if ( prop.type() == TQVariant::Int )
489  {
490  _context->i = prop.toInt();
491  _context->type = ParseContext::T_NUM;
492  return true;
493  }
494 
495  if ( prop.type() == TQVariant::Bool )
496  {
497  _context->b = prop.toBool();
498  _context->type = ParseContext::T_BOOL;
499  return true;
500  }
501 
502  if ( prop.type() == TQVariant::Double )
503  {
504  _context->f = prop.toDouble();
505  _context->type = ParseContext::T_DOUBLE;
506  return true;
507  }
508 
509  if ( prop.type() == TQVariant::List )
510  {
511  _context->seq = prop.toList();
512  _context->type = ParseContext::T_SEQ;
513  return true;
514  }
515 
516  if ( prop.type() == TQVariant::StringList )
517  {
518  _context->strSeq = prop.toStringList();
519  _context->type = ParseContext::T_STR_SEQ;
520  return true;
521  }
522 
523  // Value has unknown type
524  return false;
525 }
526 
527 bool ParseTreeMIN2::eval( ParseContext *_context ) const
528 {
529  _context->type = ParseContext::T_DOUBLE;
530 
531  TQVariant prop = _context->service->property( m_strId );
532  if ( !prop.isValid() )
533  return false;
534 
535  if ( !_context->initMaxima( m_strId ) )
536  return false;
537 
538  TQMap<TQString,PreferencesMaxima>::Iterator it = _context->maxima.find( m_strId );
539  if ( it == _context->maxima.end() )
540  return false;
541 
542  if ( prop.type() == TQVariant::Int && it.data().type == PreferencesMaxima::PM_INT )
543  {
544  _context->f = (double)( prop.toInt() - it.data().iMin ) /
545  (double)(it.data().iMax - it.data().iMin ) * (-2.0) + 1.0;
546  return true;
547  }
548  else if ( prop.type() == TQVariant::Double && it.data().type == PreferencesMaxima::PM_DOUBLE )
549  {
550  _context->f = ( prop.toDouble() - it.data().fMin ) / (it.data().fMax - it.data().fMin )
551  * (-2.0) + 1.0;
552  return true;
553  }
554 
555  return false;
556 }
557 
558 bool ParseTreeMAX2::eval( ParseContext *_context ) const
559 {
560  _context->type = ParseContext::T_DOUBLE;
561 
562  TQVariant prop = _context->service->property( m_strId );
563  if ( !prop.isValid() )
564  return false;
565 
566  // Create extrema
567  if ( !_context->initMaxima( m_strId ) )
568  return false;
569 
570  // Find extrema
571  TQMap<TQString,PreferencesMaxima>::Iterator it = _context->maxima.find( m_strId );
572  if ( it == _context->maxima.end() )
573  return false;
574 
575  if ( prop.type() == TQVariant::Int && it.data().type == PreferencesMaxima::PM_INT )
576  {
577  _context->f = (double)( prop.toInt() - it.data().iMin ) /
578  (double)(it.data().iMax - it.data().iMin ) * 2.0 - 1.0;
579  return true;
580  }
581  else if ( prop.type() == TQVariant::Double && it.data().type == PreferencesMaxima::PM_DOUBLE )
582  {
583  _context->f = ( prop.toDouble() - it.data().fMin ) /
584  (it.data().fMax - it.data().fMin ) * 2.0 - 1.0;
585  return true;
586  }
587 
588  return false;
589 }
590 
591 int matchConstraint( const ParseTreeBase *_tree, const KService::Ptr &_service,
592  const KServiceTypeProfile::OfferList& _list )
593 {
594  // Empty tree matches always
595  if ( !_tree )
596  return 1;
597 
598  TQMap<TQString,PreferencesMaxima> maxima;
599  ParseContext c( _service, _list, maxima );
600 
601  // Error during evaluation ?
602  if ( !_tree->eval( &c ) )
603  return -1;
604 
605  // Did we get a bool ?
606  if ( c.type != ParseContext::T_BOOL )
607  return -1;
608 
609  return ( c.b ? 1 : 0 );
610 }
611 
612 PreferencesReturn matchPreferences( const ParseTreeBase *_tree, const KService::Ptr &_service,
613  const KServiceTypeProfile::OfferList& _list )
614 {
615  // By default: error
616  PreferencesReturn ret;
617 
618  if ( !_tree )
619  return ret;
620 
621  TQMap<TQString,PreferencesMaxima> maxima;
622  ParseContext c( _service, _list, maxima );
623 
624  if ( !_tree->eval( &c ) )
625  return ret;
626 
627  // Did we get a numeric return value ?
628  if ( c.type == ParseContext::T_NUM )
629  {
630  ret.type = PreferencesReturn::PRT_DOUBLE;
631  ret.f = (double)c.i;
632  }
633  else if ( c.type == ParseContext::T_DOUBLE )
634  {
635  ret.type = PreferencesReturn::PRT_DOUBLE;
636  ret.f = c.f;
637  }
638 
639  return ret;
640 }
641 
642 bool ParseContext::initMaxima( const TQString& _prop )
643 {
644  // Is the property known ?
645  TQVariant prop = service->property( _prop );
646  if ( !prop.isValid() )
647  return false;
648 
649  // Numeric ?
650  if ( prop.type() != TQVariant::Int && prop.type() != TQVariant::Double )
651  return false;
652 
653  // Did we cache the result ?
654  TQMap<TQString,PreferencesMaxima>::Iterator it = maxima.find( _prop );
655  if ( it != maxima.end() )
656  return ( it.data().type == PreferencesMaxima::PM_DOUBLE ||
657  it.data().type == PreferencesMaxima::PM_INT );
658 
659  // Double or Int ?
660  PreferencesMaxima extrema;
661  if ( prop.type() == TQVariant::Int )
662  extrema.type = PreferencesMaxima::PM_INVALID_INT;
663  else
664  extrema.type = PreferencesMaxima::PM_INVALID_DOUBLE;
665 
666  // Iterate over all offers
667  KServiceTypeProfile::OfferList::ConstIterator oit = offers.begin();
668  for( ; oit != offers.end(); ++oit )
669  {
670  TQVariant p = (*oit).service()->property( _prop );
671  if ( p.isValid() )
672  {
673  // Determine new maximum/minimum
674  if ( extrema.type == PreferencesMaxima::PM_INVALID_INT )
675  {
676  extrema.type = PreferencesMaxima::PM_INT;
677  extrema.iMin = p.toInt();
678  extrema.iMax = p.toInt();
679  }
680  // Correct existing extrema
681  else if ( extrema.type == PreferencesMaxima::PM_INT )
682  {
683  if ( p.toInt() < extrema.iMin )
684  extrema.iMin = p.toInt();
685  if ( p.toInt() > extrema.iMax )
686  extrema.iMax = p.toInt();
687  }
688  // Determine new maximum/minimum
689  else if ( extrema.type == PreferencesMaxima::PM_INVALID_DOUBLE )
690  {
691  extrema.type = PreferencesMaxima::PM_DOUBLE;
692  extrema.fMin = p.toDouble();
693  extrema.fMax = p.toDouble();
694  }
695  // Correct existing extrema
696  else if ( extrema.type == PreferencesMaxima::PM_DOUBLE )
697  {
698  if ( p.toDouble() < it.data().fMin )
699  extrema.fMin = p.toDouble();
700  if ( p.toDouble() > it.data().fMax )
701  extrema.fMax = p.toDouble();
702  }
703  }
704  }
705 
706  // Cache the result
707  maxima.insert( _prop, extrema );
708 
709  // Did we succeed ?
710  return ( extrema.type == PreferencesMaxima::PM_DOUBLE ||
711  extrema.type == PreferencesMaxima::PM_INT );
712 }
713 
714 }
TDEIO
A namespace for TDEIO globals.
Definition: authinfo.h:29

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.9.1
This website is maintained by Timothy Pearson.