• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • kdecore
  • util
kmacroexpander.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE libraries
3 
4  Copyright (c) 2002-2003 Oswald Buddenhagen <ossi@kde.org>
5  Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
6 
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.
11 
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.
16 
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.
21 */
22 
23 #include "kmacroexpander_p.h"
24 #include "kdebug.h"
25 
26 #include <QtCore/QHash>
27 #include <QtCore/QStringList>
28 
29 KMacroExpanderBase::KMacroExpanderBase( QChar c ) : d(new KMacroExpanderBasePrivate(c))
30 {
31 }
32 
33 KMacroExpanderBase::~KMacroExpanderBase()
34 {
35  delete d;
36 }
37 
38 void
39 KMacroExpanderBase::setEscapeChar( QChar c )
40 {
41  d->escapechar = c;
42 }
43 
44 QChar
45 KMacroExpanderBase::escapeChar() const
46 {
47  return d->escapechar;
48 }
49 
50 void KMacroExpanderBase::expandMacros( QString &str )
51 {
52  int pos;
53  int len;
54  ushort ec = d->escapechar.unicode();
55  QStringList rst;
56  QString rsts;
57 
58  for (pos = 0; pos < str.length(); ) {
59  if (ec != 0) {
60  if (str.unicode()[pos].unicode() != ec)
61  goto nohit;
62  if (!(len = expandEscapedMacro( str, pos, rst )))
63  goto nohit;
64  } else {
65  if (!(len = expandPlainMacro( str, pos, rst )))
66  goto nohit;
67  }
68  if (len < 0) {
69  pos -= len;
70  continue;
71  }
72  rsts = rst.join( QLatin1String(" ") );
73  rst.clear();
74  str.replace( pos, len, rsts );
75  pos += rsts.length();
76  continue;
77  nohit:
78  pos++;
79  }
80 }
81 
82 bool KMacroExpanderBase::expandMacrosShellQuote( QString &str )
83 {
84  int pos = 0;
85  return expandMacrosShellQuote( str, pos ) && pos == str.length();
86 }
87 
88 int KMacroExpanderBase::expandPlainMacro( const QString &, int, QStringList & )
89 { qFatal( "KMacroExpanderBase::expandPlainMacro called!" ); return 0; }
90 
91 int KMacroExpanderBase::expandEscapedMacro( const QString &, int, QStringList & )
92 { qFatal( "KMacroExpanderBase::expandEscapedMacro called!" ); return 0; }
93 
94 
96 
97 template <typename KT, typename VT>
98 class KMacroMapExpander : public KMacroExpanderBase {
99 
100 public:
101  KMacroMapExpander( const QHash<KT,VT> &map, QChar c = QLatin1Char('%') ) :
102  KMacroExpanderBase( c ), macromap( map ) {}
103 
104 protected:
105  virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
106  virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
107 
108 private:
109  QHash<KT,VT> macromap;
110 };
111 
112 static QStringList &operator+=( QStringList &s, const QString &n) { s << n; return s; }
113 
115 
116 static bool
117 isIdentifier( ushort c )
118 {
119  return c == '_' ||
120  (c >= 'A' && c <= 'Z') ||
121  (c >= 'a' && c <= 'z') ||
122  (c >= '0' && c <= '9');
123 }
124 
126 
127 template <typename VT>
128 class KMacroMapExpander<QChar,VT> : public KMacroExpanderBase {
129 
130 public:
131  KMacroMapExpander( const QHash<QChar,VT> &map, QChar c = QLatin1Char('%') ) :
132  KMacroExpanderBase( c ), macromap( map ) {}
133 
134 protected:
135  virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
136  virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
137 
138 private:
139  QHash<QChar,VT> macromap;
140 };
141 
142 template <typename VT>
143 int
144 KMacroMapExpander<QChar,VT>::expandPlainMacro( const QString &str, int pos, QStringList &ret )
145 {
146  typename QHash<QChar,VT>::const_iterator it = macromap.constFind(str.unicode()[pos]);
147  if (it != macromap.constEnd()) {
148  ret += it.value();
149  return 1;
150  }
151  return 0;
152 }
153 
154 template <typename VT>
155 int
156 KMacroMapExpander<QChar,VT>::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
157 {
158  if (str.length() <= pos + 1)
159  return 0;
160 
161  if (str.unicode()[pos + 1] == escapeChar()) {
162  ret += QString( escapeChar() );
163  return 2;
164  }
165  typename QHash<QChar,VT>::const_iterator it = macromap.constFind(str.unicode()[pos + 1]);
166  if (it != macromap.constEnd()) {
167  ret += it.value();
168  return 2;
169  }
170 
171  return 0;
172 }
173 
174 template <typename VT>
175 class KMacroMapExpander<QString,VT> : public KMacroExpanderBase {
176 
177 public:
178  KMacroMapExpander( const QHash<QString,VT> &map, QChar c = QLatin1Char('%') ) :
179  KMacroExpanderBase( c ), macromap( map ) {}
180 
181 protected:
182  virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
183  virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
184 
185 private:
186  QHash<QString,VT> macromap;
187 };
188 
189 template <typename VT>
190 int
191 KMacroMapExpander<QString,VT>::expandPlainMacro( const QString &str, int pos, QStringList &ret )
192 {
193  if (pos && isIdentifier( str.unicode()[pos - 1].unicode() ))
194  return 0;
195  int sl;
196  for (sl = 0; isIdentifier( str.unicode()[pos + sl].unicode() ); sl++)
197  ;
198  if (!sl)
199  return 0;
200  typename QHash<QString,VT>::const_iterator it =
201  macromap.constFind( str.mid( pos, sl ) );
202  if (it != macromap.constEnd()) {
203  ret += it.value();
204  return sl;
205  }
206  return 0;
207 }
208 
209 template <typename VT>
210 int
211 KMacroMapExpander<QString,VT>::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
212 {
213  if (str.length() <= pos + 1)
214  return 0;
215 
216  if (str.unicode()[pos + 1] == escapeChar()) {
217  ret += QString( escapeChar() );
218  return 2;
219  }
220  int sl, rsl, rpos;
221  if (str.unicode()[pos + 1].unicode() == '{') {
222  rpos = pos + 2;
223  if ((sl = str.indexOf(QLatin1Char('}'), rpos)) < 0)
224  return 0;
225  sl -= rpos;
226  rsl = sl + 3;
227  } else {
228  rpos = pos + 1;
229  for (sl = 0; isIdentifier( str.unicode()[rpos + sl].unicode() ); ++sl)
230  ;
231  rsl = sl + 1;
232  }
233  if (!sl)
234  return 0;
235  typename QHash<QString,VT>::const_iterator it =
236  macromap.constFind( str.mid( rpos, sl ) );
237  if (it != macromap.constEnd()) {
238  ret += it.value();
239  return rsl;
240  }
241  return 0;
242 }
243 
245 
246 int
247 KCharMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
248 {
249  if (expandMacro( str.unicode()[pos], ret ))
250  return 1;
251  return 0;
252 }
253 
254 int
255 KCharMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
256 {
257  if (str.length() <= pos + 1)
258  return 0;
259 
260  if (str.unicode()[pos + 1] == escapeChar()) {
261  ret += QString( escapeChar() );
262  return 2;
263  }
264  if (expandMacro( str.unicode()[pos + 1], ret ))
265  return 2;
266  return 0;
267 }
268 
269 int
270 KWordMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
271 {
272  if (pos && isIdentifier( str.unicode()[pos - 1].unicode() ))
273  return 0;
274  int sl;
275  for (sl = 0; isIdentifier( str.unicode()[pos + sl].unicode() ); sl++)
276  ;
277  if (!sl)
278  return 0;
279  if (expandMacro( str.mid( pos, sl ), ret ))
280  return sl;
281  return 0;
282 }
283 
284 int
285 KWordMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
286 {
287  if (str.length() <= pos + 1)
288  return 0;
289 
290  if (str.unicode()[pos + 1] == escapeChar()) {
291  ret += QString( escapeChar() );
292  return 2;
293  }
294  int sl, rsl, rpos;
295  if (str.unicode()[pos + 1].unicode() == '{') {
296  rpos = pos + 2;
297  if ((sl = str.indexOf(QLatin1Char('}'), rpos)) < 0)
298  return 0;
299  sl -= rpos;
300  rsl = sl + 3;
301  } else {
302  rpos = pos + 1;
303  for (sl = 0; isIdentifier( str.unicode()[rpos + sl].unicode() ); ++sl)
304  ;
305  rsl = sl + 1;
306  }
307  if (!sl)
308  return 0;
309  if (expandMacro( str.mid( rpos, sl ), ret ))
310  return rsl;
311  return 0;
312 }
313 
315 
316 template <typename KT, typename VT>
317 inline QString
318 TexpandMacros( const QString &ostr, const QHash<KT,VT> &map, QChar c )
319 {
320  QString str( ostr );
321  KMacroMapExpander<KT,VT> kmx( map, c );
322  kmx.expandMacros( str );
323  return str;
324 }
325 
326 template <typename KT, typename VT>
327 inline QString
328 TexpandMacrosShellQuote( const QString &ostr, const QHash<KT,VT> &map, QChar c )
329 {
330  QString str( ostr );
331  KMacroMapExpander<KT,VT> kmx( map, c );
332  if (!kmx.expandMacrosShellQuote( str ))
333  return QString();
334  return str;
335 }
336 
337 // public API
338 namespace KMacroExpander {
339 
340  QString expandMacros( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
341  { return TexpandMacros( ostr, map, c ); }
342  QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
343  { return TexpandMacrosShellQuote( ostr, map, c ); }
344  QString expandMacros( const QString &ostr, const QHash<QString,QString> &map, QChar c )
345  { return TexpandMacros( ostr, map, c ); }
346  QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QString> &map, QChar c )
347  { return TexpandMacrosShellQuote( ostr, map, c ); }
348  QString expandMacros( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
349  { return TexpandMacros( ostr, map, c ); }
350  QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
351  { return TexpandMacrosShellQuote( ostr, map, c ); }
352  QString expandMacros( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
353  { return TexpandMacros( ostr, map, c ); }
354  QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
355  { return TexpandMacrosShellQuote( ostr, map, c ); }
356 
357 } // namespace
QList::clear
void clear()
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
KMacroExpanderBase::expandMacros
void expandMacros(QString &str)
Perform safe macro expansion (substitution) on a string.
Definition: kmacroexpander.cpp:50
KMacroExpanderBase
Abstract base class for the worker classes behind the KMacroExpander namespace and the KCharMacroExpa...
Definition: kmacroexpander.h:41
KCharMacroExpander::expandMacro
virtual bool expandMacro(QChar chr, QStringList &ret)=0
Return substitution list ret for single-character macro chr.
operator+=
static QStringList & operator+=(QStringList &s, const QString &n)
Definition: kmacroexpander.cpp:112
kdebug.h
isIdentifier
static bool isIdentifier(ushort c)
Definition: kmacroexpander.cpp:117
KMacroExpanderBase::KMacroExpanderBase
KMacroExpanderBase(QChar c=QLatin1Char('%'))
Constructor.
Definition: kmacroexpander.cpp:29
KMacroExpanderBase::expandMacrosShellQuote
bool expandMacrosShellQuote(QString &str, int &pos)
Perform safe macro expansion (substitution) on a string for use in shell commands.
Definition: kmacroexpander_unix.cpp:48
QChar
KCharMacroExpander::expandEscapedMacro
virtual int expandEscapedMacro(const QString &str, int pos, QStringList &ret)
Definition: kmacroexpander.cpp:255
KMacroExpanderBase::~KMacroExpanderBase
virtual ~KMacroExpanderBase()
Destructor.
Definition: kmacroexpander.cpp:33
QHash::constFind
const_iterator constFind(const Key &key) const
QStringList::join
QString join(const QString &separator) const
KMacroExpanderBase::setEscapeChar
void setEscapeChar(QChar c)
Set the macro escape character.
Definition: kmacroexpander.cpp:39
KMacroExpanderBase::expandEscapedMacro
virtual int expandEscapedMacro(const QString &str, int pos, QStringList &ret)
This function is called every time the escape char is found if it is not QChar::null.
Definition: kmacroexpander.cpp:91
KMacroExpanderBasePrivate
Definition: kmacroexpander_p.h:27
QHash
Definition: ksycocafactory.h:28
KWordMacroExpander::expandEscapedMacro
virtual int expandEscapedMacro(const QString &str, int pos, QStringList &ret)
Definition: kmacroexpander.cpp:285
KMacroExpanderBase::expandPlainMacro
virtual int expandPlainMacro(const QString &str, int pos, QStringList &ret)
This function is called for every single char within the string if the escape char is QChar::null...
Definition: kmacroexpander.cpp:88
KMacroExpanderBasePrivate::escapechar
QChar escapechar
Definition: kmacroexpander_p.h:31
KCharMacroExpander::expandPlainMacro
virtual int expandPlainMacro(const QString &str, int pos, QStringList &ret)
Definition: kmacroexpander.cpp:247
KWordMacroExpander::expandMacro
virtual bool expandMacro(const QString &str, QStringList &ret)=0
Return substitution list ret for string macro str.
QString
QChar::unicode
ushort unicode() const
TexpandMacros
QString TexpandMacros(const QString &ostr, const QHash< KT, VT > &map, QChar c)
Definition: kmacroexpander.cpp:318
QStringList
KMacroExpander::expandMacros
QString expandMacros(const QString &ostr, const QHash< QChar, QString > &map, QChar c)
Perform safe macro expansion (substitution) on a string.
Definition: kmacroexpander.cpp:340
KWordMacroExpander::expandPlainMacro
virtual int expandPlainMacro(const QString &str, int pos, QStringList &ret)
Definition: kmacroexpander.cpp:270
QLatin1Char
QString::replace
QString & replace(int position, int n, QChar after)
QString::unicode
const QChar * unicode() const
KMacroExpander::expandMacrosShellQuote
QString expandMacrosShellQuote(const QString &ostr, const QHash< QChar, QString > &map, QChar c)
Perform safe macro expansion (substitution) on a string for use in shell commands.
Definition: kmacroexpander.cpp:342
QString::mid
QString mid(int position, int n) const
QLatin1String
KMacroExpanderBase::escapeChar
QChar escapeChar() const
Obtain the macro escape character.
Definition: kmacroexpander.cpp:45
kmacroexpander_p.h
TexpandMacrosShellQuote
QString TexpandMacrosShellQuote(const QString &ostr, const QHash< KT, VT > &map, QChar c)
Definition: kmacroexpander.cpp:328
QString::length
int length() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:11 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

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

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal