• Skip to content
  • Skip to link menu
KDE 4.1 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     const KMacroMapExpander<QChar,VT> *const_this = this;
00147     typename QHash<QChar,VT>::const_iterator it = const_this->macromap.find(str[pos]);
00148     if (it != const_this->macromap.end()) {
00149        ret += it.value();
00150        return 1;
00151     }
00152     return 0;
00153 }
00154 
00155 template <typename VT>
00156 int
00157 KMacroMapExpander<QChar,VT>::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00158 {
00159     if (str[pos + 1] == escapeChar()) {
00160         ret += QString( escapeChar() );
00161         return 2;
00162     }
00163     const KMacroMapExpander<QChar,VT> *const_this = this;
00164     typename QHash<QChar,VT>::const_iterator it = const_this->macromap.find(str[pos+1]);
00165     if (it != const_this->macromap.end()) {
00166        ret += it.value();
00167        return 2;
00168     }
00169 
00170     return 0;
00171 }
00172 
00173 template <typename VT>
00174 class KMacroMapExpander<QString,VT> : public KMacroExpanderBase {
00175 
00176 public:
00177     KMacroMapExpander( const QHash<QString,VT> &map, QChar c = QLatin1Char('%') ) :
00178         KMacroExpanderBase( c ), macromap( map ) {}
00179 
00180 protected:
00181     virtual int expandPlainMacro( const QString &str, int pos, QStringList &ret );
00182     virtual int expandEscapedMacro( const QString &str, int pos, QStringList &ret );
00183 
00184 private:
00185     QHash<QString,VT> macromap;
00186 };
00187 
00188 template <typename VT>
00189 int
00190 KMacroMapExpander<QString,VT>::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00191 {
00192     if (isIdentifier( str[pos - 1] ))
00193         return 0;
00194     int sl;
00195     for (sl = 0; isIdentifier( str[pos + sl] ); sl++)
00196         ;
00197     if (!sl)
00198         return 0;
00199     const KMacroMapExpander<QString,VT> *const_this = this;
00200     typename QHash<QString,VT>::const_iterator it = 
00201         const_this->macromap.find( str.mid( pos, sl ) );
00202     if (it != const_this->macromap.end()) {
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[pos + 1] == escapeChar()) {
00217         ret += QString( escapeChar() );
00218         return 2;
00219     }
00220     int sl, rsl, rpos;
00221     if (str[pos + 1] == QLatin1Char('{')) {
00222         rpos = pos + 2;
00223         sl = str.indexOf(QLatin1Char('}'), rpos);
00224         if (sl == -1)
00225             return 0;
00226         else
00227           sl -= rpos;
00228         rsl = sl + 3;
00229     } else {
00230         rpos = pos + 1;
00231         for (sl = 0; (rpos + sl < str.length()) && isIdentifier( str[rpos + sl] ); sl++)
00232             ;
00233         rsl = sl + 1;
00234     }
00235     if (!sl)
00236         return 0;
00237     const KMacroMapExpander<QString,VT> *const_this = this;
00238     typename QHash<QString,VT>::const_iterator it =
00239         const_this->macromap.find( str.mid( rpos, sl ) );
00240     if (it != const_this->macromap.end()) {
00241         ret += it.value();
00242         return rsl;
00243     }
00244     return 0;
00245 }
00246 
00248 
00249 int
00250 KCharMacroExpander::expandPlainMacro( const QString &str, int pos, QStringList &ret )
00251 {
00252     if (expandMacro( str[pos], ret ))
00253         return 1;
00254     return 0;
00255 }
00256 
00257 int
00258 KCharMacroExpander::expandEscapedMacro( const QString &str, int pos, QStringList &ret )
00259 {
00260     if (str[pos + 1] == escapeChar()) {
00261         ret += QString( escapeChar() );
00262         return 2;
00263     }
00264     if (expandMacro( str[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 (isIdentifier( str[pos - 1] ))
00273         return 0;
00274     int sl;
00275     for (sl = 0; isIdentifier( str[pos + sl] ); 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[pos + 1] == escapeChar()) {
00288         ret += QString( escapeChar() );
00289         return 2;
00290     }
00291     int sl, rsl, rpos;
00292     if (str[pos + 1] == QLatin1Char('{')) {
00293         rpos = pos + 2;
00294         for (sl = 0; str[rpos + sl] != QLatin1Char('}'); sl++)
00295             if (rpos + sl >= str.length())
00296                 return 0;
00297         rsl = sl + 3;
00298     } else {
00299         rpos = pos + 1;
00300         for (sl = 0; isIdentifier( str[rpos + sl] ); sl++)
00301             ;
00302         rsl = sl + 1;
00303     }
00304     if (!sl)
00305         return 0;
00306     if (expandMacro( str.mid( rpos, sl ), ret ))
00307         return rsl;
00308     return 0;
00309 }
00310 
00312 
00313 template <typename KT, typename VT>
00314 inline QString
00315 TexpandMacros( const QString &ostr, const QHash<KT,VT> &map, QChar c )
00316 {
00317     QString str( ostr );
00318     KMacroMapExpander<KT,VT> kmx( map, c );
00319     kmx.expandMacros( str );
00320     return str;
00321 }
00322 
00323 template <typename KT, typename VT>
00324 inline QString
00325 TexpandMacrosShellQuote( const QString &ostr, const QHash<KT,VT> &map, QChar c )
00326 {
00327     QString str( ostr );
00328     KMacroMapExpander<KT,VT> kmx( map, c );
00329     if (!kmx.expandMacrosShellQuote( str ))
00330         return QString();
00331     return str;
00332 }
00333 
00334 // public API
00335 namespace KMacroExpander {
00336 
00337   QString expandMacros( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
00338     { return TexpandMacros( ostr, map, c ); }
00339   QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QString> &map, QChar c )
00340     { return TexpandMacrosShellQuote( ostr, map, c ); }
00341   QString expandMacros( const QString &ostr, const QHash<QString,QString> &map, QChar c )
00342     { return TexpandMacros( ostr, map, c ); }
00343   QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QString> &map, QChar c )
00344     { return TexpandMacrosShellQuote( ostr, map, c ); }
00345   QString expandMacros( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
00346     { return TexpandMacros( ostr, map, c ); }
00347   QString expandMacrosShellQuote( const QString &ostr, const QHash<QChar,QStringList> &map, QChar c )
00348     { return TexpandMacrosShellQuote( ostr, map, c ); }
00349   QString expandMacros( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
00350     { return TexpandMacros( ostr, map, c ); }
00351   QString expandMacrosShellQuote( const QString &ostr, const QHash<QString,QStringList> &map, QChar c )
00352     { return TexpandMacrosShellQuote( ostr, map, c ); }
00353 
00354 } // 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
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
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