• Skip to content
  • Skip to link menu
KDE 4.3 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     ushort ec = d->escapechar.unicode();
00055     QStringList rst;
00056     QString rsts;
00057 
00058     for (pos = 0; pos < str.length(); ) {
00059         if (ec != 0) {
00060             if (str.unicode()[pos].unicode() != 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( ushort c )
00118 {
00119     return c == '_' ||
00120           (c >= 'A' && c <= 'Z') ||
00121           (c >= 'a' && c <= 'z') ||
00122           (c >= '0' && c <= '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.unicode()[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.length() <= pos + 1)
00159       return 0;
00160 
00161     if (str.unicode()[pos + 1] == escapeChar()) {
00162         ret += QString( escapeChar() );
00163         return 2;
00164     }
00165     typename QHash<QChar,VT>::const_iterator it = macromap.constFind(str.unicode()[pos + 1]);
00166     if (it != macromap.constEnd()) {
00167        ret += it.value();
00168        return 2;
00169     }
00170 
00171     return 0;
00172 }
00173 
00174 template <typename VT>
00175 class KMacroMapExpander<QString,VT> : public KMacroExpanderBase {
00176 
00177 public:
00178     KMacroMapExpander( const QHash<QString,VT> &map, QChar c = QLatin1Char('%') ) :
00179         KMacroExpanderBase( c ), macromap( map ) {}
00180 
00181 protected:
00182     virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
00183     virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
00184 
00185 private:
00186     QHash<QString,VT> macromap;
00187 };
00188 
00189 template <typename VT>
00190 int
00191 KMacroMapExpander<QString,VT>::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00192 {
00193     if (pos && isIdentifier( str.unicode()[pos - 1].unicode() ))
00194         return 0;
00195     int sl;
00196     for (sl = 0; isIdentifier( str.unicode()[pos + sl].unicode() ); sl++)
00197         ;
00198     if (!sl)
00199         return 0;
00200     typename QHash<QString,VT>::const_iterator it = 
00201         macromap.constFind( str.mid( pos, sl ) );
00202     if (it != macromap.constEnd()) {
00203         ret += it.value();
00204         return sl;
00205     }
00206     return 0;
00207 }
00208 
00209 template <typename VT>
00210 int
00211 KMacroMapExpander<QString,VT>::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00212 {
00213     if (str.length() <= pos + 1)
00214       return 0;
00215 
00216     if (str.unicode()[pos + 1] == escapeChar()) {
00217         ret += QString( escapeChar() );
00218         return 2;
00219     }
00220     int sl, rsl, rpos;
00221     if (str.unicode()[pos + 1].unicode() == '{') {
00222         rpos = pos + 2;
00223         if ((sl = str.indexOf(QLatin1Char('}'), rpos)) < 0)
00224             return 0;
00225         sl -= rpos;
00226         rsl = sl + 3;
00227     } else {
00228         rpos = pos + 1;
00229         for (sl = 0; isIdentifier( str.unicode()[rpos + sl].unicode() ); sl++)
00230             ;
00231         rsl = sl + 1;
00232     }
00233     if (!sl)
00234         return 0;
00235     typename QHash<QString,VT>::const_iterator it =
00236         macromap.constFind( str.mid( rpos, sl ) );
00237     if (it != macromap.constEnd()) {
00238         ret += it.value();
00239         return rsl;
00240     }
00241     return 0;
00242 }
00243 
00245 
00246 int
00247 KCharMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00248 {
00249     if (expandMacro( str.unicode()[pos], ret ))
00250         return 1;
00251     return 0;
00252 }
00253 
00254 int
00255 KCharMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00256 {
00257     if (str.length() <= pos + 1)
00258       return 0;
00259 
00260     if (str.unicode()[pos + 1] == escapeChar()) {
00261         ret += QString( escapeChar() );
00262         return 2;
00263     }
00264     if (expandMacro( str.unicode()[pos + 1], ret ))
00265         return 2;
00266     return 0;
00267 }
00268 
00269 int
00270 KWordMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00271 {
00272     if (pos && isIdentifier( str.unicode()[pos - 1].unicode() ))
00273         return 0;
00274     int sl;
00275     for (sl = 0; isIdentifier( str.unicode()[pos + sl].unicode() ); sl++)
00276         ;
00277     if (!sl)
00278         return 0;
00279     if (expandMacro( str.mid( pos, sl ), ret ))
00280         return sl;
00281     return 0;
00282 }
00283 
00284 int
00285 KWordMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00286 {
00287     if (str.length() <= pos + 1)
00288       return 0;
00289 
00290     if (str.unicode()[pos + 1] == escapeChar()) {
00291         ret += QString( escapeChar() );
00292         return 2;
00293     }
00294     int sl, rsl, rpos;
00295     if (str.unicode()[pos + 1].unicode() == '{') {
00296         rpos = pos + 2;
00297         if ((sl = str.indexOf(QLatin1Char('}'), rpos)) < 0)
00298             return 0;
00299         sl -= rpos;
00300         rsl = sl + 3;
00301     } else {
00302         rpos = pos + 1;
00303         for (sl = 0; isIdentifier( str.unicode()[rpos + sl].unicode() ); sl++)
00304             ;
00305         rsl = sl + 1;
00306     }
00307     if (!sl)
00308         return 0;
00309     if (expandMacro( str.mid( rpos, sl ), ret ))
00310         return rsl;
00311     return 0;
00312 }
00313 
00315 
00316 template <typename KT, typename VT>
00317 inline QString
00318 TexpandMacros( const QString &ostr, const QHash<KT,VT> &map, QChar c )
00319 {
00320     QString str( ostr );
00321     KMacroMapExpander<KT,VT> kmx( map, c );
00322     kmx.expandMacros( str );
00323     return str;
00324 }
00325 
00326 template <typename KT, typename VT>
00327 inline QString
00328 TexpandMacrosShellQuote( const QString &ostr, const QHash<KT,VT> &map, QChar c )
00329 {
00330     QString str( ostr );
00331     KMacroMapExpander<KT,VT> kmx( map, c );
00332     if (!kmx.expandMacrosShellQuote( str ))
00333         return QString();
00334     return str;
00335 }
00336 
00337 // public API
00338 namespace KMacroExpander {
00339 
00340   QString expandMacros( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
00341     { return TexpandMacros( ostr, map, c ); }
00342   QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
00343     { return TexpandMacrosShellQuote( ostr, map, c ); }
00344   QString expandMacros( const QString &ostr, const QHash<QString,QString> &map, QChar c )
00345     { return TexpandMacros( ostr, map, c ); }
00346   QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QString> &map, QChar c )
00347     { return TexpandMacrosShellQuote( ostr, map, c ); }
00348   QString expandMacros( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
00349     { return TexpandMacros( ostr, map, c ); }
00350   QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
00351     { return TexpandMacrosShellQuote( ostr, map, c ); }
00352   QString expandMacros( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
00353     { return TexpandMacros( ostr, map, c ); }
00354   QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
00355     { return TexpandMacrosShellQuote( ostr, map, c ); }
00356 
00357 } // 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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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