Exemple #1
0
void KMacroExpanderBase::expandMacros(QString &str)
{
    int pos;
    int len;
    ushort ec = d->escapechar.unicode();
    QStringList rst;
    QString rsts;

    for (pos = 0; pos < str.length();) {
        if (ec != 0) {
            if (str.unicode()[pos].unicode() != ec) {
                goto nohit;
            }
            if (!(len = expandEscapedMacro(str, pos, rst))) {
                goto nohit;
            }
        } else {
            if (!(len = expandPlainMacro(str, pos, rst))) {
                goto nohit;
            }
        }
        if (len < 0) {
            pos -= len;
            continue;
        }
        rsts = rst.join(QLatin1Char(' '));
        rst.clear();
        str.replace(pos, len, rsts);
        pos += rsts.length();
        continue;
    nohit:
        pos++;
    }
}
bool KMacroExpanderBase::expandMacrosShellQuote( QString &str, int &pos )
{
    int len;
    int pos2;
    ushort uc;
    ushort ec = d->escapechar.unicode();
    bool shellQuote = false; // shell is in quoted state
    bool crtQuote = false; // c runtime is in quoted state
    bool escaped = false; // previous char was a circumflex
    int bslashes = 0; // previous chars were backslashes
    int parens = 0; // parentheses nesting level
    QStringList rst;
    QString rsts;

    while (pos < str.length()) {
        ushort cc = str.unicode()[pos].unicode();
        if (escaped) // prevent anomalies due to expansion
            goto notcf;
        if (ec != 0) {
            if (cc != ec)
                goto nohit;
            if (!(len = expandEscapedMacro( str, pos, rst )))
                goto nohit;
        } else {
            if (!(len = expandPlainMacro( str, pos, rst )))
                goto nohit;
        }
            if (len < 0) {
                pos -= len;
                continue;
            }
            if (shellQuote != crtQuote) // Silly, isn't it? Ahoy to Redmond.
                return false;
            if (shellQuote) {
                rsts = KShell::quoteArgInternal( rst.join( QLatin1String(" ") ), true );
            } else {
                if (rst.isEmpty()) {
                    str.remove( pos, len );
                    continue;
                }
                rsts = KShell::joinArgs( rst );
            }
            pos2 = 0;
            while (pos2 < rsts.length() &&
                   ((uc = rsts.unicode()[pos2].unicode()) == '\\' || uc == '^'))
                pos2++;
            if (pos2 < rsts.length() && rsts.unicode()[pos2].unicode() == '"') {
                QString bsl;
                bsl.reserve( bslashes );
                for (; bslashes; bslashes--)
                    bsl.append( QLatin1String("\\") );
                rsts.prepend( bsl );
            }
            bslashes = 0;
            rst.clear();
            str.replace( pos, len, rsts );
            pos += rsts.length();
            continue;
      nohit:
        if (!escaped && !shellQuote && cc == '^') {
            escaped = true;
        } else {
          notcf:
            if (cc == '\\') {
                bslashes++;
            } else {
                if (cc == '"') {
                    if (!escaped)
                        shellQuote = !shellQuote;
                    if (!(bslashes & 1))
                        crtQuote = !crtQuote;
                } else if (!shellQuote) {
                    if (cc == '(')
                        parens++;
                    else if (cc == ')')
                        if (--parens < 0)
                            break;
                }
                bslashes = 0;
            }
            escaped = false;
        }
        pos++;
    }
    return true;
}