2 This file is part of the KDE libraries
4 Copyright (c) 2002-2003 Oswald Buddenhagen <ossi@kde.org>
5 Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
23 #include "kmacroexpander_p.h"
26 #include <QtCore/QHash>
27 #include <QtCore/QStringList>
29 KMacroExpanderBase::KMacroExpanderBase( QChar c
) : d(new KMacroExpanderBasePrivate(c
))
33 KMacroExpanderBase::~KMacroExpanderBase()
39 KMacroExpanderBase::setEscapeChar( QChar c
)
45 KMacroExpanderBase::escapeChar() const
50 void KMacroExpanderBase::expandMacros( QString
&str
)
54 QChar
ec( d
->escapechar
);
58 for (pos
= 0; pos
< str
.length(); ) {
59 if (ec
!= QLatin1Char(0) ) {
60 if (str
.unicode()[pos
] != ec
)
62 if (!(len
= expandEscapedMacro( str
, pos
, rst
)))
65 if (!(len
= expandPlainMacro( str
, pos
, rst
)))
72 rsts
= rst
.join( QLatin1String(" ") );
74 str
.replace( pos
, len
, rsts
);
82 bool KMacroExpanderBase::expandMacrosShellQuote( QString
&str
)
85 return expandMacrosShellQuote( str
, pos
) && pos
== str
.length();
88 int KMacroExpanderBase::expandPlainMacro( const QString
&, int, QStringList
& )
89 { qFatal( "KMacroExpanderBase::expandPlainMacro called!" ); return 0; }
91 int KMacroExpanderBase::expandEscapedMacro( const QString
&, int, QStringList
& )
92 { qFatal( "KMacroExpanderBase::expandEscapedMacro called!" ); return 0; }
95 //////////////////////////////////////////////////
97 template <typename KT
, typename VT
>
98 class KMacroMapExpander
: public KMacroExpanderBase
{
101 KMacroMapExpander( const QHash
<KT
,VT
> &map
, QChar c
= QLatin1Char('%') ) :
102 KMacroExpanderBase( c
), macromap( map
) {}
105 virtual int expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
);
106 virtual int expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
);
109 QHash
<KT
,VT
> macromap
;
112 static QStringList
&operator+=( QStringList
&s
, const QString
&n
) { s
<< n
; return s
; }
117 isIdentifier( QChar c
)
119 return c
== QLatin1Char('_') ||
120 (c
>= QLatin1Char('A') && c
<= QLatin1Char('Z')) ||
121 (c
>= QLatin1Char('a') && c
<= QLatin1Char('z')) ||
122 (c
>= QLatin1Char('0') && c
<= QLatin1Char('9'));
127 template <typename VT
>
128 class KMacroMapExpander
<QChar
,VT
> : public KMacroExpanderBase
{
131 KMacroMapExpander( const QHash
<QChar
,VT
> &map
, QChar c
= QLatin1Char('%') ) :
132 KMacroExpanderBase( c
), macromap( map
) {}
135 virtual int expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
);
136 virtual int expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
);
139 QHash
<QChar
,VT
> macromap
;
142 template <typename VT
>
144 KMacroMapExpander
<QChar
,VT
>::expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
)
146 typename QHash
<QChar
,VT
>::const_iterator it
= macromap
.constFind(str
[pos
]);
147 if (it
!= macromap
.constEnd()) {
154 template <typename VT
>
156 KMacroMapExpander
<QChar
,VT
>::expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
)
158 if (str
[pos
+ 1] == escapeChar()) {
159 ret
+= QString( escapeChar() );
162 typename QHash
<QChar
,VT
>::const_iterator it
= macromap
.constFind(str
[pos
+1]);
163 if (it
!= macromap
.constEnd()) {
171 template <typename VT
>
172 class KMacroMapExpander
<QString
,VT
> : public KMacroExpanderBase
{
175 KMacroMapExpander( const QHash
<QString
,VT
> &map
, QChar c
= QLatin1Char('%') ) :
176 KMacroExpanderBase( c
), macromap( map
) {}
179 virtual int expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
);
180 virtual int expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
);
183 QHash
<QString
,VT
> macromap
;
186 template <typename VT
>
188 KMacroMapExpander
<QString
,VT
>::expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
)
190 if (isIdentifier( str
[pos
- 1] ))
193 for (sl
= 0; isIdentifier( str
[pos
+ sl
] ); sl
++)
197 typename QHash
<QString
,VT
>::const_iterator it
=
198 macromap
.constFind( str
.mid( pos
, sl
) );
199 if (it
!= macromap
.constEnd()) {
206 template <typename VT
>
208 KMacroMapExpander
<QString
,VT
>::expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
)
210 if (str
.length() <= pos
+ 1)
213 if (str
[pos
+ 1] == escapeChar()) {
214 ret
+= QString( escapeChar() );
218 if (str
[pos
+ 1] == QLatin1Char('{')) {
220 sl
= str
.indexOf(QLatin1Char('}'), rpos
);
228 for (sl
= 0; (rpos
+ sl
< str
.length()) && isIdentifier( str
[rpos
+ sl
] ); sl
++)
234 typename QHash
<QString
,VT
>::const_iterator it
=
235 macromap
.constFind( str
.mid( rpos
, sl
) );
236 if (it
!= macromap
.constEnd()) {
246 KCharMacroExpander::expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
)
248 if (expandMacro( str
[pos
], ret
))
254 KCharMacroExpander::expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
)
256 if (str
[pos
+ 1] == escapeChar()) {
257 ret
+= QString( escapeChar() );
260 if (expandMacro( str
[pos
+1], ret
))
266 KWordMacroExpander::expandPlainMacro( const QString
&str
, int pos
, QStringList
&ret
)
268 if (isIdentifier( str
[pos
- 1] ))
271 for (sl
= 0; isIdentifier( str
[pos
+ sl
] ); sl
++)
275 if (expandMacro( str
.mid( pos
, sl
), ret
))
281 KWordMacroExpander::expandEscapedMacro( const QString
&str
, int pos
, QStringList
&ret
)
283 if (str
[pos
+ 1] == escapeChar()) {
284 ret
+= QString( escapeChar() );
288 if (str
[pos
+ 1] == QLatin1Char('{')) {
290 for (sl
= 0; str
[rpos
+ sl
] != QLatin1Char('}'); sl
++)
291 if (rpos
+ sl
>= str
.length())
296 for (sl
= 0; isIdentifier( str
[rpos
+ sl
] ); sl
++)
302 if (expandMacro( str
.mid( rpos
, sl
), ret
))
309 template <typename KT
, typename VT
>
311 TexpandMacros( const QString
&ostr
, const QHash
<KT
,VT
> &map
, QChar c
)
314 KMacroMapExpander
<KT
,VT
> kmx( map
, c
);
315 kmx
.expandMacros( str
);
319 template <typename KT
, typename VT
>
321 TexpandMacrosShellQuote( const QString
&ostr
, const QHash
<KT
,VT
> &map
, QChar c
)
324 KMacroMapExpander
<KT
,VT
> kmx( map
, c
);
325 if (!kmx
.expandMacrosShellQuote( str
))
331 namespace KMacroExpander
{
333 QString
expandMacros( const QString
&ostr
, const QHash
<QChar
,QString
> &map
, QChar c
)
334 { return TexpandMacros( ostr
, map
, c
); }
335 QString
expandMacrosShellQuote( const QString
&ostr
, const QHash
<QChar
,QString
> &map
, QChar c
)
336 { return TexpandMacrosShellQuote( ostr
, map
, c
); }
337 QString
expandMacros( const QString
&ostr
, const QHash
<QString
,QString
> &map
, QChar c
)
338 { return TexpandMacros( ostr
, map
, c
); }
339 QString
expandMacrosShellQuote( const QString
&ostr
, const QHash
<QString
,QString
> &map
, QChar c
)
340 { return TexpandMacrosShellQuote( ostr
, map
, c
); }
341 QString
expandMacros( const QString
&ostr
, const QHash
<QChar
,QStringList
> &map
, QChar c
)
342 { return TexpandMacros( ostr
, map
, c
); }
343 QString
expandMacrosShellQuote( const QString
&ostr
, const QHash
<QChar
,QStringList
> &map
, QChar c
)
344 { return TexpandMacrosShellQuote( ostr
, map
, c
); }
345 QString
expandMacros( const QString
&ostr
, const QHash
<QString
,QStringList
> &map
, QChar c
)
346 { return TexpandMacros( ostr
, map
, c
); }
347 QString
expandMacrosShellQuote( const QString
&ostr
, const QHash
<QString
,QStringList
> &map
, QChar c
)
348 { return TexpandMacrosShellQuote( ostr
, map
, c
); }