tools/linguist/shared/proparserutils.h
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Linguist of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef PROPARSERUTILS_H
       
    43 #define PROPARSERUTILS_H
       
    44 
       
    45 #include <QtCore/QDir>
       
    46 #include <QtCore/QLibraryInfo>
       
    47 
       
    48 QT_BEGIN_NAMESPACE
       
    49 
       
    50 // Pre- and postcondition macros
       
    51 #define PRE(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0)
       
    52 #define POST(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0)
       
    53 
       
    54 // This struct is from qmake, but we are not using everything.
       
    55 struct Option
       
    56 {
       
    57     //simply global convenience
       
    58     //static QString libtool_ext;
       
    59     //static QString pkgcfg_ext;
       
    60     //static QString prf_ext;
       
    61     //static QString prl_ext;
       
    62     //static QString ui_ext;
       
    63     //static QStringList h_ext;
       
    64     //static QStringList cpp_ext;
       
    65     //static QString h_moc_ext;
       
    66     //static QString cpp_moc_ext;
       
    67     //static QString obj_ext;
       
    68     //static QString lex_ext;
       
    69     //static QString yacc_ext;
       
    70     //static QString h_moc_mod;
       
    71     //static QString cpp_moc_mod;
       
    72     //static QString lex_mod;
       
    73     //static QString yacc_mod;
       
    74     static QString dir_sep;
       
    75     static QString dirlist_sep;
       
    76     static QString qmakespec;
       
    77     static QChar field_sep;
       
    78 
       
    79     enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE, TARG_QNX6_MODE };
       
    80     static TARG_MODE target_mode;
       
    81     //static QString pro_ext;
       
    82     //static QString res_ext;
       
    83 
       
    84     static void init()
       
    85     {
       
    86 #ifdef Q_OS_WIN
       
    87         Option::dirlist_sep = QLatin1Char(';');
       
    88         Option::dir_sep = QLatin1Char('\\');
       
    89 #else
       
    90         Option::dirlist_sep = QLatin1Char(':');
       
    91         Option::dir_sep = QLatin1Char(QLatin1Char('/'));
       
    92 #endif
       
    93         Option::qmakespec = QString::fromLatin1(qgetenv("QMAKESPEC").data());
       
    94         Option::field_sep = QLatin1Char(' ');
       
    95     }
       
    96 
       
    97     enum StringFixFlags {
       
    98         FixNone                 = 0x00,
       
    99         FixEnvVars              = 0x01,
       
   100         FixPathCanonicalize     = 0x02,
       
   101         FixPathToLocalSeparators  = 0x04,
       
   102         FixPathToTargetSeparators = 0x08
       
   103     };
       
   104     static QString fixString(QString string, uchar flags);
       
   105 
       
   106     inline static QString fixPathToLocalOS(const QString &in, bool fix_env = true, bool canonical = true)
       
   107     {
       
   108         uchar flags = FixPathToLocalSeparators;
       
   109         if (fix_env)
       
   110             flags |= FixEnvVars;
       
   111         if (canonical)
       
   112             flags |= FixPathCanonicalize;
       
   113         return fixString(in, flags);
       
   114     }
       
   115 };
       
   116 #if defined(Q_OS_WIN32)
       
   117 Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE;
       
   118 #elif defined(Q_OS_MAC)
       
   119 Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE;
       
   120 #elif defined(Q_OS_QNX6)
       
   121 Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE;
       
   122 #else
       
   123 Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE;
       
   124 #endif
       
   125 
       
   126 QString Option::qmakespec;
       
   127 QString Option::dirlist_sep;
       
   128 QString Option::dir_sep;
       
   129 QChar Option::field_sep;
       
   130 
       
   131 static void insertUnique(QHash<QString, QStringList> *map,
       
   132     const QString &key, const QStringList &value)
       
   133 {
       
   134     QStringList &sl = (*map)[key];
       
   135     foreach (const QString &str, value)
       
   136         if (!sl.contains(str))
       
   137             sl.append(str);
       
   138 }
       
   139 
       
   140 static void removeEach(QHash<QString, QStringList> *map,
       
   141     const QString &key, const QStringList &value)
       
   142 {
       
   143     QStringList &sl = (*map)[key];
       
   144     foreach (const QString &str, value)
       
   145         sl.removeAll(str);
       
   146 }
       
   147 
       
   148 /*
       
   149   See ProFileEvaluator::Private::visitProValue(...)
       
   150 
       
   151 static QStringList replaceInList(const QStringList &varList, const QRegExp &regexp,
       
   152                            const QString &replace, bool global)
       
   153 {
       
   154     QStringList resultList = varList;
       
   155 
       
   156     for (QStringList::Iterator varit = resultList.begin(); varit != resultList.end();) {
       
   157         if (varit->contains(regexp)) {
       
   158             *varit = varit->replace(regexp, replace);
       
   159             if (varit->isEmpty())
       
   160                 varit = resultList.erase(varit);
       
   161             else
       
   162                 ++varit;
       
   163             if (!global)
       
   164                 break;
       
   165         } else {
       
   166             ++varit;
       
   167         }
       
   168     }
       
   169     return resultList;
       
   170 }
       
   171 */
       
   172 
       
   173 inline QString fixEnvVariables(const QString &x)
       
   174 {
       
   175     return Option::fixString(x, Option::FixEnvVars);
       
   176 }
       
   177 
       
   178 inline QStringList splitPathList(const QString &paths)
       
   179 {
       
   180     return paths.split(Option::dirlist_sep);
       
   181 }
       
   182 
       
   183 static QStringList split_arg_list(QString params)
       
   184 {
       
   185     int quote = 0;
       
   186     QStringList args;
       
   187 
       
   188     const ushort LPAREN = '(';
       
   189     const ushort RPAREN = ')';
       
   190     const ushort SINGLEQUOTE = '\'';
       
   191     const ushort DOUBLEQUOTE = '"';
       
   192     const ushort COMMA = ',';
       
   193     const ushort SPACE = ' ';
       
   194     //const ushort TAB = '\t';
       
   195 
       
   196     ushort unicode;
       
   197     const QChar *params_data = params.data();
       
   198     const int params_len = params.length();
       
   199     int last = 0;
       
   200     while (last < params_len && ((params_data+last)->unicode() == SPACE
       
   201                                 /*|| (params_data+last)->unicode() == TAB*/))
       
   202         ++last;
       
   203     for (int x = last, parens = 0; x <= params_len; x++) {
       
   204         unicode = (params_data+x)->unicode();
       
   205         if (x == params_len) {
       
   206             while (x && (params_data+(x-1))->unicode() == SPACE)
       
   207                 --x;
       
   208             QString mid(params_data+last, x-last);
       
   209             if (quote) {
       
   210                 if (mid[0] == quote && mid[(int)mid.length()-1] == quote)
       
   211                     mid = mid.mid(1, mid.length()-2);
       
   212                 quote = 0;
       
   213             }
       
   214             args << mid;
       
   215             break;
       
   216         }
       
   217         if (unicode == LPAREN) {
       
   218             --parens;
       
   219         } else if (unicode == RPAREN) {
       
   220             ++parens;
       
   221         } else if (quote && unicode == quote) {
       
   222             quote = 0;
       
   223         } else if (!quote && (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE)) {
       
   224             quote = unicode;
       
   225         }
       
   226         if (!parens && !quote && unicode == COMMA) {
       
   227             QString mid = params.mid(last, x - last).trimmed();
       
   228             args << mid;
       
   229             last = x+1;
       
   230             while (last < params_len && ((params_data+last)->unicode() == SPACE
       
   231                                         /*|| (params_data+last)->unicode() == TAB*/))
       
   232                 ++last;
       
   233         }
       
   234     }
       
   235     return args;
       
   236 }
       
   237 
       
   238 static QStringList split_value_list(const QString &vals, bool do_semicolon=false)
       
   239 {
       
   240     QString build;
       
   241     QStringList ret;
       
   242     QStack<char> quote;
       
   243 
       
   244     const ushort LPAREN = '(';
       
   245     const ushort RPAREN = ')';
       
   246     const ushort SINGLEQUOTE = '\'';
       
   247     const ushort DOUBLEQUOTE = '"';
       
   248     const ushort BACKSLASH = '\\';
       
   249     const ushort SEMICOLON = ';';
       
   250 
       
   251     ushort unicode;
       
   252     const QChar *vals_data = vals.data();
       
   253     const int vals_len = vals.length();
       
   254     for (int x = 0, parens = 0; x < vals_len; x++) {
       
   255         unicode = vals_data[x].unicode();
       
   256         if (x != (int)vals_len-1 && unicode == BACKSLASH &&
       
   257             (vals_data[x+1].unicode() == SINGLEQUOTE || vals_data[x+1].unicode() == DOUBLEQUOTE)) {
       
   258             build += vals_data[x++]; //get that 'escape'
       
   259         } else if (!quote.isEmpty() && unicode == quote.top()) {
       
   260             quote.pop();
       
   261         } else if (unicode == SINGLEQUOTE || unicode == DOUBLEQUOTE) {
       
   262             quote.push(unicode);
       
   263         } else if (unicode == RPAREN) {
       
   264             --parens;
       
   265         } else if (unicode == LPAREN) {
       
   266             ++parens;
       
   267         }
       
   268 
       
   269         if (!parens && quote.isEmpty() && ((do_semicolon && unicode == SEMICOLON) ||
       
   270                                            vals_data[x] == Option::field_sep)) {
       
   271             ret << build;
       
   272             build.clear();
       
   273         } else {
       
   274             build += vals_data[x];
       
   275         }
       
   276     }
       
   277     if (!build.isEmpty())
       
   278         ret << build;
       
   279     return ret;
       
   280 }
       
   281 
       
   282 static QStringList qmake_mkspec_paths()
       
   283 {
       
   284     QStringList ret;
       
   285     const QString concat = QDir::separator() + QLatin1String("mkspecs");
       
   286     QByteArray qmakepath = qgetenv("QMAKEPATH");
       
   287     if (!qmakepath.isEmpty()) {
       
   288         const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
       
   289         for (QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it)
       
   290             ret << ((*it) + concat);
       
   291     }
       
   292     ret << QLibraryInfo::location(QLibraryInfo::DataPath) + concat;
       
   293 
       
   294     return ret;
       
   295 }
       
   296 
       
   297 QT_END_NAMESPACE
       
   298 
       
   299 #endif // PROPARSERUTILS_H