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

KDECore

kmacroexpander.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of the KDE libraries
00003 
00004     Copyright (c) 2002-2003 Oswald Buddenhagen <ossi@kde.org>
00005     Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kmacroexpander_p.h"
00024 #include "kdebug.h"
00025 
00026 #include <QtCore/QHash>
00027 #include <QtCore/QStringList>
00028 
00029 KMacroExpanderBase::KMacroExpanderBase( QChar c ) : d(new KMacroExpanderBasePrivate(c))
00030 {
00031 }
00032 
00033 KMacroExpanderBase::~KMacroExpanderBase()
00034 {
00035     delete d;
00036 }
00037 
00038 void
00039 KMacroExpanderBase::setEscapeChar( QChar c )
00040 {
00041     d->escapechar = c;
00042 }
00043 
00044 QChar
00045 KMacroExpanderBase::escapeChar() const
00046 {
00047     return d->escapechar;
00048 }
00049 
00050 void KMacroExpanderBase::expandMacros( QString &str )
00051 {
00052     int pos;
00053     int len;
00054     QChar ec( d->escapechar );
00055     QStringList rst;
00056     QString rsts;
00057 
00058     for (pos = 0; pos < str.length(); ) {
00059         if (ec != QLatin1Char(0) ) {
00060             if (str.unicode()[pos] != ec)
00061                 goto nohit;
00062             if (!(len = expandEscapedMacro( str, pos, rst )))
00063                 goto nohit;
00064         } else {
00065             if (!(len = expandPlainMacro( str, pos, rst )))
00066                 goto nohit;
00067         }
00068             if (len < 0) {
00069                 pos -= len;
00070                 continue;
00071             }
00072             rsts = rst.join( QLatin1String(" ") );
00073             rst.clear();
00074             str.replace( pos, len, rsts );
00075             pos += rsts.length();
00076             continue;
00077       nohit:
00078         pos++;
00079     }
00080 }
00081 
00082 bool KMacroExpanderBase::expandMacrosShellQuote( QString &str )
00083 {
00084   int pos = 0;
00085   return expandMacrosShellQuote( str, pos ) && pos == str.length();
00086 }
00087 
00088 int KMacroExpanderBase::expandPlainMacro( const QString &, int, QStringList & )
00089 { qFatal( "KMacroExpanderBase::expandPlainMacro called!" ); return 0; }
00090 
00091 int KMacroExpanderBase::expandEscapedMacro( const QString &, int, QStringList & )
00092 { qFatal( "KMacroExpanderBase::expandEscapedMacro called!" ); return 0; }
00093 
00094 
00096 
00097 template <typename KT, typename VT>
00098 class KMacroMapExpander : public KMacroExpanderBase {
00099 
00100 public:
00101     KMacroMapExpander( const QHash<KT,VT> &map, QChar c = QLatin1Char('%') ) :
00102         KMacroExpanderBase( c ), macromap( map ) {}
00103 
00104 protected:
00105     virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
00106     virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
00107 
00108 private:
00109     QHash<KT,VT> macromap;
00110 };
00111 
00112 static QStringList &operator+=( QStringList &s, const QString &n) { s << n; return s; }
00113 
00115 
00116 static bool
00117 isIdentifier( QChar c )
00118 {
00119     return c == QLatin1Char('_') || 
00120           (c >= QLatin1Char('A') && c <= QLatin1Char('Z')) || 
00121           (c >= QLatin1Char('a') && c <= QLatin1Char('z')) || 
00122           (c >= QLatin1Char('0') && c <= QLatin1Char('9'));
00123 }
00124 
00126 
00127 template <typename VT>
00128 class KMacroMapExpander<QChar,VT> : public KMacroExpanderBase {
00129 
00130 public:
00131     KMacroMapExpander( const QHash<QChar,VT> &map, QChar c = QLatin1Char('%') ) :
00132         KMacroExpanderBase( c ), macromap( map ) {}
00133 
00134 protected:
00135     virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
00136     virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
00137 
00138 private:
00139     QHash<QChar,VT> macromap;
00140 };
00141 
00142 template <typename VT>
00143 int
00144 KMacroMapExpander<QChar,VT>::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00145 {
00146     typename QHash<QChar,VT>::const_iterator it = macromap.constFind(str[pos]);
00147     if (it != macromap.constEnd()) {
00148        ret += it.value();
00149        return 1;
00150     }
00151     return 0;
00152 }
00153 
00154 template <typename VT>
00155 int
00156 KMacroMapExpander<QChar,VT>::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00157 {
00158     if (str[pos + 1] == escapeChar()) {
00159         ret += QString( escapeChar() );
00160         return 2;
00161     }
00162     typename QHash<QChar,VT>::const_iterator it = macromap.constFind(str[pos+1]);
00163     if (it != macromap.constEnd()) {
00164        ret += it.value();
00165        return 2;
00166     }
00167 
00168     return 0;
00169 }
00170 
00171 template <typename VT>
00172 class KMacroMapExpander<QString,VT> : public KMacroExpanderBase {
00173 
00174 public:
00175     KMacroMapExpander( const QHash<QString,VT> &map, QChar c = QLatin1Char('%') ) :
00176         KMacroExpanderBase( c ), macromap( map ) {}
00177 
00178 protected:
00179     virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
00180     virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
00181 
00182 private:
00183     QHash<QString,VT> macromap;
00184 };
00185 
00186 template <typename VT>
00187 int
00188 KMacroMapExpander<QString,VT>::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00189 {
00190     if (isIdentifier( str[pos - 1] ))
00191         return 0;
00192     int sl;
00193     for (sl = 0; isIdentifier( str[pos + sl] ); sl++)
00194         ;
00195     if (!sl)
00196         return 0;
00197     typename QHash<QString,VT>::const_iterator it = 
00198         macromap.constFind( str.mid( pos, sl ) );
00199     if (it != macromap.constEnd()) {
00200         ret += it.value();
00201         return sl;
00202     }
00203     return 0;
00204 }
00205 
00206 template <typename VT>
00207 int
00208 KMacroMapExpander<QString,VT>::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00209 {
00210     if (str.length() <= pos + 1)
00211       return 0;
00212 
00213     if (str[pos + 1] == escapeChar()) {
00214         ret += QString( escapeChar() );
00215         return 2;
00216     }
00217     int sl, rsl, rpos;
00218     if (str[pos + 1] == QLatin1Char('{')) {
00219         rpos = pos + 2;
00220         sl = str.indexOf(QLatin1Char('}'), rpos);
00221         if (sl == -1)
00222             return 0;
00223         else
00224           sl -= rpos;
00225         rsl = sl + 3;
00226     } else {
00227         rpos = pos + 1;
00228         for (sl = 0; (rpos + sl < str.length()) && isIdentifier( str[rpos + sl] ); sl++)
00229             ;
00230         rsl = sl + 1;
00231     }
00232     if (!sl)
00233         return 0;
00234     typename QHash<QString,VT>::const_iterator it =
00235         macromap.constFind( str.mid( rpos, sl ) );
00236     if (it != macromap.constEnd()) {
00237         ret += it.value();
00238         return rsl;
00239     }
00240     return 0;
00241 }
00242 
00244 
00245 int
00246 KCharMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00247 {
00248     if (expandMacro( str[pos], ret ))
00249         return 1;
00250     return 0;
00251 }
00252 
00253 int
00254 KCharMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00255 {
00256     if (str[pos + 1] == escapeChar()) {
00257         ret += QString( escapeChar() );
00258         return 2;
00259     }
00260     if (expandMacro( str[pos+1], ret ))
00261         return 2;
00262     return 0;
00263 }
00264 
00265 int
00266 KWordMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00267 {
00268     if (isIdentifier( str[pos - 1] ))
00269         return 0;
00270     int sl;
00271     for (sl = 0; isIdentifier( str[pos + sl] ); sl++)
00272         ;
00273     if (!sl)
00274         return 0;
00275     if (expandMacro( str.mid( pos, sl ), ret ))
00276         return sl;
00277     return 0;
00278 }
00279 
00280 int
00281 KWordMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00282 {
00283     if (str[pos + 1] == escapeChar()) {
00284         ret += QString( escapeChar() );
00285         return 2;
00286     }
00287     int sl, rsl, rpos;
00288     if (str[pos + 1] == QLatin1Char('{')) {
00289         rpos = pos + 2;
00290         for (sl = 0; str[rpos + sl] != QLatin1Char('}'); sl++)
00291             if (rpos + sl >= str.length())
00292                 return 0;
00293         rsl = sl + 3;
00294     } else {
00295         rpos = pos + 1;
00296         for (sl = 0; isIdentifier( str[rpos + sl] ); sl++)
00297             ;
00298         rsl = sl + 1;
00299     }
00300     if (!sl)
00301         return 0;
00302     if (expandMacro( str.mid( rpos, sl ), ret ))
00303         return rsl;
00304     return 0;
00305 }
00306 
00308 
00309 template <typename KT, typename VT>
00310 inline QString
00311 TexpandMacros( const QString &ostr, const QHash<KT,VT> &map, QChar c )
00312 {
00313     QString str( ostr );
00314     KMacroMapExpander<KT,VT> kmx( map, c );
00315     kmx.expandMacros( str );
00316     return str;
00317 }
00318 
00319 template <typename KT, typename VT>
00320 inline QString
00321 TexpandMacrosShellQuote( const QString &ostr, const QHash<KT,VT> &map, QChar c )
00322 {
00323     QString str( ostr );
00324     KMacroMapExpander<KT,VT> kmx( map, c );
00325     if (!kmx.expandMacrosShellQuote( str ))
00326         return QString();
00327     return str;
00328 }
00329 
00330 // public API
00331 namespace KMacroExpander {
00332 
00333   QString expandMacros( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
00334     { return TexpandMacros( ostr, map, c ); }
00335   QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
00336     { return TexpandMacrosShellQuote( ostr, map, c ); }
00337   QString expandMacros( const QString &ostr, const QHash<QString,QString> &map, QChar c )
00338     { return TexpandMacros( ostr, map, c ); }
00339   QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QString> &map, QChar c )
00340     { return TexpandMacrosShellQuote( ostr, map, c ); }
00341   QString expandMacros( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
00342     { return TexpandMacros( ostr, map, c ); }
00343   QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
00344     { return TexpandMacrosShellQuote( ostr, map, c ); }
00345   QString expandMacros( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
00346     { return TexpandMacros( ostr, map, c ); }
00347   QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
00348     { return TexpandMacrosShellQuote( ostr, map, c ); }
00349 
00350 } // namespace

KDECore

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal