add mp3 and ogg torrent url info to JamendoAlbum
[amarok.git] / src / expression.cpp
blob50c700274fd635ad47b68062c81d61537ead2d53
1 /*
2 Copyright (c) 2006 Gábor Lehel <illissius@gmail.com>
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.
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.
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.
20 #include "expression.h"
22 ExpressionParser::ExpressionParser( const QString &expression )
23 : m_expression( expression )
24 , m_state( ExpectMinus )
25 , m_haveGroup( false )
26 , m_inQuote( false )
27 , m_inOrGroup( false )
28 { }
30 ParsedExpression ExpressionParser::parse()
32 const uint length = m_expression.length();
33 for( uint pos = 0; pos < length; ++pos )
34 parseChar( m_expression.at( pos ) );
35 finishedToken();
36 finishedOrGroup();
37 return m_parsed;
40 ParsedExpression ExpressionParser::parse( const QString &expression ) //static
42 ExpressionParser p( expression );
43 return p.parse();
46 bool ExpressionParser::isAdvancedExpression( const QString &expression ) //static
48 return ( expression.contains( '"' ) ||
49 expression.contains( ':' ) ||
50 expression.contains( '-' ) ||
51 expression.contains( "AND" ) ||
52 expression.contains( "OR" ) );
55 /* PRIVATE */
57 void ExpressionParser::parseChar( const QChar &c )
59 if( m_inQuote && c != '"' )
60 m_string += c;
61 else if( c.isSpace() )
62 handleSpace( c );
63 else if( c == '-' )
64 handleMinus( c );
65 else if( c == ':' )
66 handleColon( c );
67 else if( c == '>' || c == '<' )
68 handleMod( c );
69 else if( c == '"' )
70 handleQuote( c );
71 else
72 handleChar( c );
75 void ExpressionParser::handleSpace( const QChar& )
77 if( m_state > ExpectMinus )
78 finishedToken();
81 void ExpressionParser::handleMinus( const QChar &c )
83 if( m_state == ExpectMinus )
85 m_element.negate = true;
86 m_state = ExpectField;
88 else
89 handleChar( c );
92 void ExpressionParser::handleColon( const QChar &c )
94 if( m_state <= ExpectField && !m_string.isEmpty() )
96 m_element.field = m_string;
97 m_string.clear();
98 m_state = ExpectMod;
100 else
101 handleChar( c );
104 void ExpressionParser::handleMod( const QChar &c )
106 if( m_state == ExpectMod )
108 m_element.match = ( c == '>' ) ? expression_element::More : expression_element::Less;
109 m_state = ExpectText;
111 else
112 handleChar( c );
115 void ExpressionParser::handleQuote( const QChar& )
117 if( m_inQuote )
119 finishedElement();
120 m_inQuote = false;
122 else
124 if( !m_string.isEmpty() )
125 finishedToken();
126 m_state = ExpectText;
127 m_inQuote = true;
131 void ExpressionParser::handleChar( const QChar &c )
133 m_string += c;
134 if( m_state <= ExpectField )
135 m_state = ExpectField;
136 else if( m_state <= ExpectText )
137 m_state = ExpectText;
140 void ExpressionParser::finishedToken()
142 enum { And, Or, Neither };
143 int s;
144 if( m_haveGroup || !m_element.field.isEmpty() )
145 s = Neither;
146 else if( m_string == "AND" )
147 s = And;
148 else if( m_string == "OR" )
149 s = Or;
150 else
151 s = Neither;
153 if( s == Neither )
154 finishedElement();
155 else
157 m_haveGroup = true;
159 if( s == Or )
160 m_inOrGroup = true;
161 else
162 finishedOrGroup();
164 m_string.clear();
165 m_state = ExpectMinus;
169 void ExpressionParser::finishedElement()
171 if( !m_inOrGroup )
172 finishedOrGroup();
173 m_inOrGroup = m_haveGroup = false;
174 m_element.text = m_string;
175 m_string.clear();
177 if( !m_element.text.isEmpty() || !m_element.field.isEmpty() )
178 m_or.append( m_element );
180 m_element = expression_element();
181 m_state = ExpectMinus;
184 void ExpressionParser::finishedOrGroup()
186 if( !m_or.isEmpty() )
187 m_parsed.append( m_or );
188 m_or.clear();
189 m_inOrGroup = false;