Blame qtools/qregexp.cpp

Packit Service 50c9f2
/****************************************************************************
Packit Service 50c9f2
** 
Packit Service 50c9f2
**
Packit Service 50c9f2
** Implementation of QRegExp class
Packit Service 50c9f2
**
Packit Service 50c9f2
** Created : 950126
Packit Service 50c9f2
**
Packit Service 50c9f2
** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is part of the tools module of the Qt GUI Toolkit.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed under the terms of the Q Public License
Packit Service 50c9f2
** as defined by Trolltech AS of Norway and appearing in the file
Packit Service 50c9f2
** LICENSE.QPL included in the packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file may be distributed and/or modified under the terms of the
Packit Service 50c9f2
** GNU General Public License version 2 as published by the Free Software
Packit Service 50c9f2
** Foundation and appearing in the file LICENSE.GPL included in the
Packit Service 50c9f2
** packaging of this file.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
Packit Service 50c9f2
** licenses may use this file in accordance with the Qt Commercial License
Packit Service 50c9f2
** Agreement provided with the Software.
Packit Service 50c9f2
**
Packit Service 50c9f2
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
Packit Service 50c9f2
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Packit Service 50c9f2
**
Packit Service 50c9f2
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
Packit Service 50c9f2
**   information about Qt Commercial License Agreements.
Packit Service 50c9f2
** See http://www.trolltech.com/qpl/ for QPL licensing information.
Packit Service 50c9f2
** See http://www.trolltech.com/gpl/ for GPL licensing information.
Packit Service 50c9f2
**
Packit Service 50c9f2
** Contact info@trolltech.com if any conditions of this licensing are
Packit Service 50c9f2
** not clear to you.
Packit Service 50c9f2
**
Packit Service 50c9f2
**********************************************************************/
Packit Service 50c9f2
Packit Service 50c9f2
#include "qregexp.h"
Packit Service 50c9f2
#include <ctype.h>
Packit Service 50c9f2
#include <stdlib.h>
Packit Service 50c9f2
Packit Service 50c9f2
// NOT REVISED
Packit Service 50c9f2
/*!
Packit Service 50c9f2
  \class QRegExp qregexp.h
Packit Service 50c9f2
  \ingroup tools
Packit Service 50c9f2
  \ingroup misc
Packit Service 50c9f2
  \brief The QRegExp class provides pattern matching using regular
Packit Service 50c9f2
  expressions or wildcards.
Packit Service 50c9f2
Packit Service 50c9f2
  QRegExp knows these regexp primitives:
Packit Service 50c9f2
  
    Packit Service 50c9f2
      
  • <dfn>c</dfn> matches the character 'c'
  • Packit Service 50c9f2
      
  • <dfn>.</dfn> matches any character
  • Packit Service 50c9f2
      
  • <dfn>^</dfn> matches start of input
  • Packit Service 50c9f2
      
  • <dfn>$</dfn> matches end of input
  • Packit Service 50c9f2
      
  • <dfn>[]</dfn> matches a defined set of characters - see below.
  • Packit Service 50c9f2
      
  • <dfn>a*</dfn> matches a sequence of zero or more a's
  • Packit Service 50c9f2
      
  • <dfn>a+</dfn> matches a sequence of one or more a's
  • Packit Service 50c9f2
      
  • <dfn>a?</dfn> matches an optional a
  • Packit Service 50c9f2
      
  • <dfn>\c</dfn> escape code for matching special characters such
  • Packit Service 50c9f2
      as \, [, *, +, . etc.
    Packit Service 50c9f2
      
  • <dfn>\t</dfn> matches the TAB character (9)
  • Packit Service 50c9f2
      
  • <dfn>\n</dfn> matches newline (10)
  • Packit Service 50c9f2
      
  • <dfn>\r</dfn> matches return (13)
  • Packit Service 50c9f2
      
  • <dfn>\s</dfn> matches a white space (defined as any character
  • Packit Service 50c9f2
      for which QChar::isSpace() returns TRUE. This includes at least
    Packit Service 50c9f2
      ASCII characters 9 (TAB), 10 (LF), 11 (VT), 12(FF), 13 (CR) and 32
    Packit Service 50c9f2
      (Space)).
    Packit Service 50c9f2
      
  • <dfn>\d</dfn> matches a digit (defined as any character for
  • Packit Service 50c9f2
      which QChar::isDigit() returns TRUE. This includes at least ASCII
    Packit Service 50c9f2
      characters '0'-'9').
    Packit Service 50c9f2
      
  • <dfn>\x1f6b</dfn> matches the character with unicode point U1f6b
  • Packit Service 50c9f2
      (hexadecimal 1f6b). \x0012 will match the ASCII/Latin1 character
    Packit Service 50c9f2
      0x12 (18 decimal, 12 hexadecimal).
    Packit Service 50c9f2
      
  • <dfn>\022</dfn> matches the ASCII/Latin1 character 022 (18
  • Packit Service 50c9f2
      decimal, 22 octal).
    Packit Service 50c9f2
      
    Packit Service 50c9f2
    Packit Service 50c9f2
      In wildcard mode, it only knows four primitives:
    Packit Service 50c9f2
      
      Packit Service 50c9f2
        
    • <dfn>c</dfn> matches the character 'c'
    • Packit Service 50c9f2
        
    • <dfn>?</dfn> matches any character
    • Packit Service 50c9f2
        
    • <dfn>*</dfn> matches any sequence of characters
    • Packit Service 50c9f2
        
    • <dfn>[]</dfn> matches a defined set of characters - see below.
    • Packit Service 50c9f2
        
      Packit Service 50c9f2
      Packit Service 50c9f2
        QRegExp supports Unicode both in the pattern strings and in the
      Packit Service 50c9f2
        strings to be matched.
      Packit Service 50c9f2
      Packit Service 50c9f2
        When writing regular expressions in C++ code, remember that C++
      Packit Service 50c9f2
        processes \ characters.  So in order to match e.g. a "." character,
      Packit Service 50c9f2
        you must write "\\." in C++ source, not "\.".
      Packit Service 50c9f2
      Packit Service 50c9f2
        A character set matches a defined set of characters. For example,
      Packit Service 50c9f2
        [BSD] matches any of 'B', 'D' and 'S'. Within a character set, the
      Packit Service 50c9f2
        special characters '.', '*', '?', '^', '$', '+' and '[' lose their
      Packit Service 50c9f2
        special meanings. The following special characters apply:
      Packit Service 50c9f2
        
        Packit Service 50c9f2
          
      • <dfn>^</dfn> When placed first in the list, changes the
      • Packit Service 50c9f2
          character set to match any character \e not in the list. To include
        Packit Service 50c9f2
          the character '^' itself in the set, escape it or place it anywhere
        Packit Service 50c9f2
          but first.
        Packit Service 50c9f2
          
      • <dfn>-</dfn> Defines a range of characters. To include the
      • Packit Service 50c9f2
          character '-' itself in the set, escape it or place it last.
        Packit Service 50c9f2
          
      • <dfn>]</dfn> Ends the character set definition. To include the
      • Packit Service 50c9f2
          character ']' itself in the set, escape it or place it first (but
        Packit Service 50c9f2
          after the negation operator '^', if present)
        Packit Service 50c9f2
          
        Packit Service 50c9f2
          Thus, [a-zA-Z0-9.] matches upper and lower case ASCII letters,
        Packit Service 50c9f2
          digits and dot; and [^\s] matches everything except white space.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \bug Case insensitive matching is not supported for non-ASCII/Latin1
        Packit Service 50c9f2
          (non-8bit) characters. Any character with a non-zero QChar.row() is
        Packit Service 50c9f2
          matched case sensitively even if the QRegExp is in case insensitive
        Packit Service 50c9f2
          mode.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \note In Qt 3.0, the language of regular expressions will contain
        Packit Service 50c9f2
          five more special characters, namely '(', ')', '{', '|' and '}'. To
        Packit Service 50c9f2
          ease porting, it's a good idea to escape these characters with a
        Packit Service 50c9f2
          backslash in all the regular expressions you'll write from now on.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        // The regexp pattern is internally represented as an array of uints,
        Packit Service 50c9f2
        // each element containing an 16-bit character or a 32-bit code
        Packit Service 50c9f2
        // (listed below).  User-defined character classes (e.g. [a-zA-Z])
        Packit Service 50c9f2
        // are encoded as this:
        Packit Service 50c9f2
        // uint no:	1		2		3		...
        Packit Service 50c9f2
        // value:	CCL | n		from | to	from | to
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        // where n is the (16-bit) number of following range definitions and
        Packit Service 50c9f2
        // from and to define the ranges inclusive. from <= to is always true,
        Packit Service 50c9f2
        // otherwise it is a built-in charclass (Pxx, eg \s - PWS). Single
        Packit Service 50c9f2
        // characters in the class are coded as from==to.  Negated classes
        Packit Service 50c9f2
        // (e.g. [^a-z]) use CCN instead of CCL.
        Packit Service 50c9f2
        Packit Service 50c9f2
        const uint END	= 0x00000000;
        Packit Service 50c9f2
        const uint PWS	= 0x10010000;		// predef charclass: whitespace (\s)
        Packit Service 50c9f2
        const uint PDG	= 0x10020000;		// predef charclass: digit (\d)
        Packit Service 50c9f2
        const uint CCL	= 0x20010000;		// character class	[]
        Packit Service 50c9f2
        const uint CCN	= 0x20020000;		// neg character class	[^]
        Packit Service 50c9f2
        const uint CHR	= 0x40000000;		// character
        Packit Service 50c9f2
        const uint BOL	= 0x80010000;		// beginning of line	^
        Packit Service 50c9f2
        const uint EOL	= 0x80020000;		// end of line		$
        Packit Service 50c9f2
        const uint BOW	= 0x80030000;		// beginning of word	\<
        Packit Service 50c9f2
        const uint EOW	= 0x80040000;		// end of word		\>
        Packit Service 50c9f2
        const uint ANY	= 0x80050000;		// any character	.
        Packit Service 50c9f2
        const uint CLO	= 0x80070000;		// Kleene closure	*
        Packit Service 50c9f2
        const uint OPT	= 0x80080000;		// Optional closure	?
        Packit Service 50c9f2
        Packit Service 50c9f2
        const uint MCC  = 0x20000000;		// character class bitmask
        Packit Service 50c9f2
        const uint MCD  = 0xffff0000;		// code mask
        Packit Service 50c9f2
        const uint MVL  = 0x0000ffff;		// value mask
        Packit Service 50c9f2
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        // QRegExp::error codes (internal)
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        Packit Service 50c9f2
        const int PatOk		= 0;			// pattern ok
        Packit Service 50c9f2
        const int PatNull	= 1;			// no pattern defined
        Packit Service 50c9f2
        const int PatSyntax	= 2;			// pattern syntax error
        Packit Service 50c9f2
        const int PatOverflow	= 4;			// pattern too long
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*****************************************************************************
        Packit Service 50c9f2
          QRegExp member functions
        Packit Service 50c9f2
         *****************************************************************************/
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Constructs an empty regular expression.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        QRegExp::QRegExp()
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            rxdata = 0;
        Packit Service 50c9f2
            cs = TRUE;
        Packit Service 50c9f2
            wc = FALSE;
        Packit Service 50c9f2
            error = PatOk;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Constructs a regular expression.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \arg \e pattern is the regular expression pattern string.
        Packit Service 50c9f2
          \arg \e caseSensitive specifies whether or not to use case sensitive
        Packit Service 50c9f2
          matching.
        Packit Service 50c9f2
          \arg \e wildcard specifies whether the pattern string should be used for
        Packit Service 50c9f2
          wildcard matching (also called globbing expression), normally used for
        Packit Service 50c9f2
          matching file names.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \sa setWildcard()
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        QRegExp::QRegExp( const QCString &pattern, bool caseSensitive, bool wildcard )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            rxstring = pattern;
        Packit Service 50c9f2
            rxdata = 0;
        Packit Service 50c9f2
            cs = caseSensitive;
        Packit Service 50c9f2
            wc = wildcard;
        Packit Service 50c9f2
            compile();
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Constructs a regular expression which is a copy of \e r.
        Packit Service 50c9f2
          \sa operator=(const QRegExp&)
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        QRegExp::QRegExp( const QRegExp &r )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            rxstring = r.pattern();
        Packit Service 50c9f2
            rxdata = 0;
        Packit Service 50c9f2
            cs = r.caseSensitive();
        Packit Service 50c9f2
            wc = r.wildcard();
        Packit Service 50c9f2
            compile();
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Destructs the regular expression and cleans up its internal data.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        QRegExp::~QRegExp()
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            if ( rxdata )                      // Avoid purify complaints
        Packit Service 50c9f2
        	delete [] rxdata;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Copies the regexp \e r and returns a reference to this regexp.
        Packit Service 50c9f2
          The case sensitivity and wildcard options are copied, as well.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        QRegExp &QRegExp::operator=( const QRegExp &r )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            rxstring = r.rxstring;
        Packit Service 50c9f2
            cs = r.cs;
        Packit Service 50c9f2
            wc = r.wc;
        Packit Service 50c9f2
            compile();
        Packit Service 50c9f2
            return *this;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \obsolete
        Packit Service 50c9f2
          Consider using setPattern() instead of this method.
        Packit Service 50c9f2
        Packit Service 50c9f2
          Sets the pattern string to \e pattern and returns a reference to this regexp.
        Packit Service 50c9f2
          The case sensitivity or wildcard options do not change.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        QRegExp &QRegExp::operator=( const QCString &pattern )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            rxstring = pattern;
        Packit Service 50c9f2
            compile();
        Packit Service 50c9f2
            return *this;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Returns TRUE if this regexp is equal to \e r.
        Packit Service 50c9f2
        Packit Service 50c9f2
          Two regexp objects are equal if they have equal pattern strings,
        Packit Service 50c9f2
          case sensitivity options and wildcard options.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        bool QRegExp::operator==( const QRegExp &r ) const
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            return rxstring == r.rxstring && cs == r.cs && wc == r.wc;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn bool QRegExp::operator!=( const QRegExp &r ) const
        Packit Service 50c9f2
        Packit Service 50c9f2
          Returns TRUE if this regexp is \e not equal to \e r.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \sa operator==()
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn bool QRegExp::isEmpty() const
        Packit Service 50c9f2
          Returns TRUE if the regexp is empty.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn bool QRegExp::isValid() const
        Packit Service 50c9f2
          Returns TRUE if the regexp is valid, or FALSE if it is invalid.
        Packit Service 50c9f2
        Packit Service 50c9f2
          The pattern "[a-z" is an example of an invalid pattern, since it lacks a
        Packit Service 50c9f2
          closing bracket.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn bool QRegExp::wildcard() const
        Packit Service 50c9f2
          Returns TRUE if wildcard mode is on, otherwise FALSE. \sa setWildcard().
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Sets the wildcard option for the regular expression.	The default
        Packit Service 50c9f2
          is FALSE.
        Packit Service 50c9f2
        Packit Service 50c9f2
          Setting \e wildcard to TRUE makes it convenient to match filenames
        Packit Service 50c9f2
          instead of plain text.
        Packit Service 50c9f2
        Packit Service 50c9f2
          For example, "qr*.cpp" matches the string "qregexp.cpp" in wildcard mode,
        Packit Service 50c9f2
          but not "qicpp" (which would be matched in normal mode).
        Packit Service 50c9f2
        Packit Service 50c9f2
          \sa wildcard()
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        void QRegExp::setWildcard( bool wildcard )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            if ( wildcard != wc ) {
        Packit Service 50c9f2
        	wc = wildcard;
        Packit Service 50c9f2
        	compile();
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn bool QRegExp::caseSensitive() const
        Packit Service 50c9f2
        Packit Service 50c9f2
          Returns TRUE if case sensitivity is enabled, otherwise FALSE.	 The
        Packit Service 50c9f2
          default is TRUE.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \sa setCaseSensitive()
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Enables or disables case sensitive matching.
        Packit Service 50c9f2
        Packit Service 50c9f2
          In case sensitive mode, "a.e" matches "axe" but not "Axe".
        Packit Service 50c9f2
        Packit Service 50c9f2
          See also: caseSensitive()
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        void QRegExp::setCaseSensitive( bool enable )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            if ( cs != enable ) {
        Packit Service 50c9f2
        	cs = enable;
        Packit Service 50c9f2
        	compile();
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn QCString QRegExp::pattern() const
        Packit Service 50c9f2
          Returns the pattern string of the regexp.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \fn void QRegExp::setPattern(const QCString & pattern)
        Packit Service 50c9f2
          Sets the pattern string to \a pattern and returns a reference to this regexp.
        Packit Service 50c9f2
          The case sensitivity or wildcard options do not change.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        static inline bool iswordchar( int x )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            return isalnum(x) || x == '_';	//# Only 8-bit support
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \internal
        Packit Service 50c9f2
          Match character class
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        static bool matchcharclass( uint *rxd, char c )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            uint *d = rxd;
        Packit Service 50c9f2
            uint clcode = *d & MCD;
        Packit Service 50c9f2
            bool neg = clcode == CCN;
        Packit Service 50c9f2
            if ( clcode != CCL && clcode != CCN)
        Packit Service 50c9f2
        	qWarning("QRegExp: Internal error, please report to qt-bugs@trolltech.com");
        Packit Service 50c9f2
            uint numFields = *d & MVL;
        Packit Service 50c9f2
            uint cval = (unsigned char)c; //(((uint)(c.row())) << 8) | ((uint)c.cell());
        Packit Service 50c9f2
            bool found = FALSE;
        Packit Service 50c9f2
            for ( int i = 0; i < (int)numFields; i++ ) {
        Packit Service 50c9f2
        	d++;
        Packit Service 50c9f2
        	if ( *d == PWS && isspace(c) ) {
        Packit Service 50c9f2
        	    found = TRUE;
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	if ( *d == PDG && isdigit(c) ) {
        Packit Service 50c9f2
        	    found = TRUE;
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	else {
        Packit Service 50c9f2
        	    uint from = ( *d & MCD ) >> 16;
        Packit Service 50c9f2
        	    uint to = *d & MVL;
        Packit Service 50c9f2
        	    if ( (cval >= from) && (cval <= to) ) {
        Packit Service 50c9f2
        		found = TRUE;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            return neg ? !found : found;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*
        Packit Service 50c9f2
          Internal: Recursively match string.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        static int matchstring( uint *rxd, const char *str, uint strlength,
        Packit Service 50c9f2
        			const char *bol, bool cs )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            const char *p = str;
        Packit Service 50c9f2
            const char *start = p;
        Packit Service 50c9f2
            uint pl = strlength;
        Packit Service 50c9f2
            uint *d = rxd;
        Packit Service 50c9f2
        Packit Service 50c9f2
            //### in all cases here: handle pl == 0! (don't read past strlen)
        Packit Service 50c9f2
            while ( *d ) {
        Packit Service 50c9f2
        	if ( *d & CHR ) {			// match char
        Packit Service 50c9f2
        	    if ( !pl )
        Packit Service 50c9f2
        		return -1;
        Packit Service 50c9f2
        	    char c =  *d;
        Packit Service 50c9f2
        	    if ( !cs /*&& !c.row()*/ ) {		// case insensitive, #Only 8bit
        Packit Service 50c9f2
        		if ( tolower(*p) != c )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        	    } else {				// case insensitive
        Packit Service 50c9f2
        		if ( *p != c )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	    d++;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	else if ( *d & MCC ) {			// match char class
        Packit Service 50c9f2
        	    if ( !pl )
        Packit Service 50c9f2
        		return -1;
        Packit Service 50c9f2
        	    if ( !matchcharclass( d, *p ) )
        Packit Service 50c9f2
        		return -1;
        Packit Service 50c9f2
        	    p++;
        Packit Service 50c9f2
        	    pl--;
        Packit Service 50c9f2
        	    d += (*d & MVL) + 1;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	else switch ( *d++ ) {
        Packit Service 50c9f2
        	    case PWS:				// match whitespace
        Packit Service 50c9f2
        		if ( !pl || !isspace(*p) )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case PDG:				// match digits
        Packit Service 50c9f2
        		if ( !pl || !isdigit(*p) )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case ANY:				// match anything
        Packit Service 50c9f2
        		if ( !pl )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case BOL:				// match beginning of line
        Packit Service 50c9f2
        		if ( p != bol )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case EOL:				// match end of line
        Packit Service 50c9f2
        		if ( pl )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case BOW:				// match beginning of word
        Packit Service 50c9f2
        		if ( !iswordchar(*p) || (p > bol && iswordchar(*(p-1)) ) )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case EOW:				// match end of word
        Packit Service 50c9f2
        		if ( iswordchar(*p) || p == bol || !iswordchar(*(p-1)) )
        Packit Service 50c9f2
        		    return -1;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case CLO:				// Kleene closure
        Packit Service 50c9f2
        		{
        Packit Service 50c9f2
        		const char *first_p = p;
        Packit Service 50c9f2
        		if ( *d & CHR ) {		// match char
        Packit Service 50c9f2
        		    char c =  *d;
        Packit Service 50c9f2
        		    if ( !cs /*&& !c.row()*/ ) {	// case insensitive, #only 8bit
        Packit Service 50c9f2
        			while ( pl /*&& !p->row()*/ && tolower(*p)==c ) {
        Packit Service 50c9f2
        			    p++;
        Packit Service 50c9f2
        			    pl--;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    else {			// case sensitive
        Packit Service 50c9f2
        			while ( pl && *p == c ) {
        Packit Service 50c9f2
        			    p++;
        Packit Service 50c9f2
        			    pl--;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d & MCC ) {			// match char class
        Packit Service 50c9f2
        		    while( pl && matchcharclass( d, *p ) ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d += (*d & MVL) + 1;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d == PWS ) {
        Packit Service 50c9f2
        		    while ( pl && isspace(*p) ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d == PDG ) {
        Packit Service 50c9f2
        		    while ( pl && isdigit(*p) ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d == ANY ) {
        Packit Service 50c9f2
        		    p += pl;
        Packit Service 50c9f2
        		    pl = 0;
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else {
        Packit Service 50c9f2
        		    return -1;			// error
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		d++;				// skip CLO's END
        Packit Service 50c9f2
        		while ( p >= first_p ) {	// go backwards
        Packit Service 50c9f2
        		    int end = matchstring( d, p, pl, bol, cs );
        Packit Service 50c9f2
        		    if ( end >= 0 )
        Packit Service 50c9f2
        			return ( (int)(p - start) ) + end;
        Packit Service 50c9f2
        		    if ( !p )
        Packit Service 50c9f2
        			return -1;
        Packit Service 50c9f2
        		    --p;
        Packit Service 50c9f2
        		    ++pl;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		return -1;
        Packit Service 50c9f2
        	    case OPT:				// optional closure
        Packit Service 50c9f2
        		{
        Packit Service 50c9f2
        		const char *first_p = p;
        Packit Service 50c9f2
        		if ( *d & CHR ) {		// match char
        Packit Service 50c9f2
        		    char c =  *d;
        Packit Service 50c9f2
        		    if ( !cs /*&& !c.row()*/ ) {	// case insensitive, #only 8bit
        Packit Service 50c9f2
        			if ( pl && /*!p->row() &&*/ tolower(*p) == c ) {
        Packit Service 50c9f2
        			    p++;
        Packit Service 50c9f2
        			    pl--;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    else {			// case sensitive
        Packit Service 50c9f2
        			if ( pl && *p == c ) {
        Packit Service 50c9f2
        			    p++;
        Packit Service 50c9f2
        			    pl--;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d & MCC ) {			// match char class
        Packit Service 50c9f2
        		    if ( pl && matchcharclass( d, *p ) ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d += (*d & MVL) + 1;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d == PWS ) {
        Packit Service 50c9f2
        		    if ( pl && isspace(*p) ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d == PDG ) {
        Packit Service 50c9f2
        		    if ( pl && isdigit(*p) ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else if ( *d == ANY ) {
        Packit Service 50c9f2
        		    if ( pl ) {
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    d++;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else {
        Packit Service 50c9f2
        		    return -1;			// error
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		d++;				// skip OPT's END
        Packit Service 50c9f2
        		while ( p >= first_p ) {	// go backwards
        Packit Service 50c9f2
        		    int end = matchstring( d, p, pl, bol, cs );
        Packit Service 50c9f2
        		    if ( end >= 0 )
        Packit Service 50c9f2
        			return ( (int)(p - start) ) + end;
        Packit Service 50c9f2
        		    if ( !p )
        Packit Service 50c9f2
        			return -1;
        Packit Service 50c9f2
        		    --p;
        Packit Service 50c9f2
        		    ++pl;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		return -1;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    default:				// error
        Packit Service 50c9f2
        		return -1;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            return (int)(p - start);
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \internal
        Packit Service 50c9f2
          Recursively match string.
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        // This is obsolete now, but since it is protected (not private), it
        Packit Service 50c9f2
        // is still implemented on the off-chance that somebody has made a
        Packit Service 50c9f2
        // class derived from QRegExp and calls this directly.
        Packit Service 50c9f2
        // Qt 3.0: Remove this?
        Packit Service 50c9f2
        Packit Service 50c9f2
        #if 0
        Packit Service 50c9f2
        const char *QRegExp::matchstr( uint *rxd, const QChar *str, uint strlength,
        Packit Service 50c9f2
        				const QChar *bol ) const
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            int len = matchstring( rxd, str, strlength, bol, cs );
        Packit Service 50c9f2
            if ( len < 0 )
        Packit Service 50c9f2
        	return 0;
        Packit Service 50c9f2
            return str + len;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        #endif
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          Attempts to match in \e str, starting from position \e index.
        Packit Service 50c9f2
          Returns the position of the match, or -1 if there was no match.
        Packit Service 50c9f2
        Packit Service 50c9f2
          If \e len is not a null pointer, the length of the match is stored in
        Packit Service 50c9f2
          \e *len.
        Packit Service 50c9f2
        Packit Service 50c9f2
          If \e indexIsStart is TRUE (the default), the position \e index in
        Packit Service 50c9f2
          the string will match the start-of-input primitive (^) in the
        Packit Service 50c9f2
          regexp, if present. Otherwise, position 0 in \e str will match.
        Packit Service 50c9f2
        Packit Service 50c9f2
          Example:
        Packit Service 50c9f2
          \code
        Packit Service 50c9f2
            QRegExp r("[0-9]*\\.[0-9]+");		// matches floating point
        Packit Service 50c9f2
            int len;
        Packit Service 50c9f2
            r.match("pi = 3.1416", 0, &len;;		// returns 5, len == 6
        Packit Service 50c9f2
          \endcode
        Packit Service 50c9f2
        Packit Service 50c9f2
          \note In Qt 3.0, this function will be replaced by find().
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        int QRegExp::match( const QCString &str, int index, int *len,
        Packit Service 50c9f2
        		    bool indexIsStart ) const
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            if ( !isValid() || isEmpty() )
        Packit Service 50c9f2
        	return -1;
        Packit Service 50c9f2
            if ( str.length() < (uint)index )
        Packit Service 50c9f2
        	return -1;
        Packit Service 50c9f2
            const char *start = str.data();
        Packit Service 50c9f2
            const char *p = start + index;
        Packit Service 50c9f2
            uint pl = str.length() - index;
        Packit Service 50c9f2
            uint *d  = rxdata;
        Packit Service 50c9f2
            int ep = -1;
        Packit Service 50c9f2
        Packit Service 50c9f2
            if ( *d == BOL ) {				// match from beginning of line
        Packit Service 50c9f2
        	ep = matchstring( d, p, pl, indexIsStart ? p : start, cs );
        Packit Service 50c9f2
            } else {
        Packit Service 50c9f2
        	if ( *d & CHR ) {
        Packit Service 50c9f2
        	    char c = *d;
        Packit Service 50c9f2
        	    if ( !cs /*&& !c.row()*/ ) {		// case sensitive, # only 8bit
        Packit Service 50c9f2
        		while ( pl && ( /*p->row() ||*/ tolower(*p) != c ) ) {
        Packit Service 50c9f2
        		    p++;
        Packit Service 50c9f2
        		    pl--;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        	    } else {				// case insensitive
        Packit Service 50c9f2
        		while ( pl && *p != c ) {
        Packit Service 50c9f2
        		    p++;
        Packit Service 50c9f2
        		    pl--;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	while( 1 ) {				// regular match
        Packit Service 50c9f2
        	    ep = matchstring( d, p, pl, indexIsStart ? start+index : start, cs );
        Packit Service 50c9f2
        	    if ( ep >= 0 )
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    if ( !pl )
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    p++;
        Packit Service 50c9f2
        	    pl--;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            if ( len )
        Packit Service 50c9f2
        	*len = ep >= 0 ? ep : 0;      // No match -> 0, for historical reasons
        Packit Service 50c9f2
            return ep >= 0 ? (int)(p - start) : -1;		// return index;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*! \fn int QRegExp::find( const QCString& str, int index )
        Packit Service 50c9f2
        Packit Service 50c9f2
          Attempts to match in \e str, starting from position \e index.
        Packit Service 50c9f2
          Returns the position of the match, or -1 if there was no match.
        Packit Service 50c9f2
        Packit Service 50c9f2
          \sa match()
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        // Translate wildcard pattern to standard regexp pattern.
        Packit Service 50c9f2
        // Ex:	 *.cpp	==> ^.*\.cpp$
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        Packit Service 50c9f2
        static QCString wc2rx( const QCString &pattern )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            int patlen = (int)pattern.length();
        Packit Service 50c9f2
            QCString wcpattern("^");
        Packit Service 50c9f2
        Packit Service 50c9f2
            char c;
        Packit Service 50c9f2
            for( int i = 0; i < patlen; i++ ) {
        Packit Service 50c9f2
        	c = pattern[i];
        Packit Service 50c9f2
        	switch ( (char)c ) {
        Packit Service 50c9f2
        	case '*':				// '*' ==> '.*'
        Packit Service 50c9f2
        	    wcpattern += '.';
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        	case '?':				// '?' ==> '.'
        Packit Service 50c9f2
        	    c = '.';
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        	case '.':				// quote special regexp chars
        Packit Service 50c9f2
        	case '+':
        Packit Service 50c9f2
        	case '\\':
        Packit Service 50c9f2
        	case '$':
        Packit Service 50c9f2
        	case '^':
        Packit Service 50c9f2
        	    wcpattern += '\\';
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        	case '[':
        Packit Service 50c9f2
        	    if ( (char)pattern[i+1] == '^' ) { // don't quote '^' after '['
        Packit Service 50c9f2
        		wcpattern += '[';
        Packit Service 50c9f2
        		c = pattern[i+1];
        Packit Service 50c9f2
        		i++;
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	wcpattern += c;
        Packit Service 50c9f2
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            wcpattern += '$';
        Packit Service 50c9f2
            return wcpattern;				// return new regexp pattern
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        // Internal: Get char value and increment pointer.
        Packit Service 50c9f2
        //
        Packit Service 50c9f2
        Packit Service 50c9f2
        static uint char_val( const char **str, uint *strlength )   // get char value
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            const char *p = *str;
        Packit Service 50c9f2
            uint pl = *strlength;
        Packit Service 50c9f2
            uint len = 1;
        Packit Service 50c9f2
            uint v = 0;
        Packit Service 50c9f2
            if ( (char)*p == '\\' ) {			// escaped code
        Packit Service 50c9f2
        	p++;
        Packit Service 50c9f2
        	pl--;
        Packit Service 50c9f2
        	if ( !pl ) {				// it is just a '\'
        Packit Service 50c9f2
        	    (*str)++;
        Packit Service 50c9f2
        	    (*strlength)--;
        Packit Service 50c9f2
        	    return '\\';
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	len++;					// length at least 2
        Packit Service 50c9f2
        	int i;
        Packit Service 50c9f2
        	char c;
        Packit Service 50c9f2
        	char ch = tolower((char)*p);
        Packit Service 50c9f2
        	switch ( ch ) {
        Packit Service 50c9f2
        	    case 'b':  v = '\b';  break;	// bell
        Packit Service 50c9f2
        	    case 'f':  v = '\f';  break;	// form feed
        Packit Service 50c9f2
        	    case 'n':  v = '\n';  break;	// newline
        Packit Service 50c9f2
        	    case 'r':  v = '\r';  break;	// return
        Packit Service 50c9f2
        	    case 't':  v = '\t';  break;	// tab
        Packit Service 50c9f2
        	    case 's':  v = PWS; break;		// whitespace charclass
        Packit Service 50c9f2
        	    case 'd':  v = PDG; break;		// digit charclass
        Packit Service 50c9f2
        	    case '<':  v = BOW; break;		// word beginning matcher
        Packit Service 50c9f2
        	    case '>':  v = EOW; break;		// word ending matcher
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    case 'x': {				// hex code
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		for ( i = 0; (i < 4) && pl; i++ ) {	//up to 4 hex digits
        Packit Service 50c9f2
        		    c = tolower((char)*p);
        Packit Service 50c9f2
        		    bool a = ( c >= 'a' && c <= 'f' );
        Packit Service 50c9f2
        		    if ( (c >= '0' && c <= '9') || a ) {
        Packit Service 50c9f2
        			v <<= 4;
        Packit Service 50c9f2
        			v += a ? 10 + c - 'a' : c - '0';
        Packit Service 50c9f2
        			len++;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    else {
        Packit Service 50c9f2
        			break;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    p++;
        Packit Service 50c9f2
        		    pl--;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	    break;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    default: {
        Packit Service 50c9f2
        		if ( ch >= '0' && ch <= '7' ) {	//octal code
        Packit Service 50c9f2
        		    len--;
        Packit Service 50c9f2
        		    for ( i = 0; (i < 3) && pl; i++ ) {	// up to 3 oct digits
        Packit Service 50c9f2
        			c = (char)*p;
        Packit Service 50c9f2
        			if ( c >= '0' && c <= '7' ) {
        Packit Service 50c9f2
        			    v <<= 3;
        Packit Service 50c9f2
        			    v += c - '0';
        Packit Service 50c9f2
        			    len++;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        			else {
        Packit Service 50c9f2
        			    break;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        			p++;
        Packit Service 50c9f2
        			pl--;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else {				// not an octal number
        Packit Service 50c9f2
        		    v = (uint)*p; //(((uint)(p->row())) << 8) | ((uint)p->cell());
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
            } else {
        Packit Service 50c9f2
        	v = (uint)*p; //(((uint)(p->row())) << 8) | ((uint)p->cell());
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            *str += len;
        Packit Service 50c9f2
            *strlength -= len;
        Packit Service 50c9f2
            return v;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        #if 0 //defined(DEBUG)
        Packit Service 50c9f2
        static uint *dump( uint *p )
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            while ( *p != END ) {
        Packit Service 50c9f2
        	if ( *p & CHR ) {
        Packit Service 50c9f2
        	    uchar uc = (uchar)*p;
        Packit Service 50c9f2
        	    char c = (char)uc;
        Packit Service 50c9f2
        	    uint u = (uint)uc; //(((uint)(uc.row())) << 8) | ((uint)uc.cell());
        Packit Service 50c9f2
        	    qDebug( "\tCHR\tU%04x (%c)", u, (c ? c : ' '));
        Packit Service 50c9f2
        	    p++;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	else if ( *p & MCC ) {
        Packit Service 50c9f2
        	    uint clcode = *p & MCD;
        Packit Service 50c9f2
        	    uint numFields = *p & MVL;
        Packit Service 50c9f2
        	    if ( clcode == CCL )
        Packit Service 50c9f2
        		qDebug( "\tCCL\t%i", numFields );
        Packit Service 50c9f2
        	    else if ( clcode == CCN )
        Packit Service 50c9f2
        		qDebug( "\tCCN\t%i", numFields );
        Packit Service 50c9f2
        	    else
        Packit Service 50c9f2
        		qDebug("coding error!");
        Packit Service 50c9f2
        	    for ( int i = 0; i < (int)numFields; i++ ) {
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		if ( *p == PWS )
        Packit Service 50c9f2
        		    qDebug( "\t\tPWS" );
        Packit Service 50c9f2
        		else if ( *p == PDG )
        Packit Service 50c9f2
        		    qDebug( "\t\tPDG" );
        Packit Service 50c9f2
        		else {
        Packit Service 50c9f2
        		    uint from = ( *p & MCD ) >> 16;
        Packit Service 50c9f2
        		    uint to = *p & MVL;
        Packit Service 50c9f2
        		    char fc = (char)from;
        Packit Service 50c9f2
        		    char tc = (char)to;
        Packit Service 50c9f2
        		    qDebug( "\t\tU%04x (%c) - U%04x (%c)", from,
        Packit Service 50c9f2
        			   (fc ? fc : ' '), to, (tc ? tc : ' ') );
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        	    }
        Packit Service 50c9f2
        	    p++;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	else switch ( *p++ ) {
        Packit Service 50c9f2
        	    case PWS:
        Packit Service 50c9f2
        		qDebug( "\tPWS" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case PDG:
        Packit Service 50c9f2
        		qDebug( "\tPDG" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case BOL:
        Packit Service 50c9f2
        		qDebug( "\tBOL" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case EOL:
        Packit Service 50c9f2
        		qDebug( "\tEOL" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case BOW:
        Packit Service 50c9f2
        		qDebug( "\tBOW" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case EOW:
        Packit Service 50c9f2
        		qDebug( "\tEOW" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case ANY:
        Packit Service 50c9f2
        		qDebug( "\tANY" );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case CLO:
        Packit Service 50c9f2
        		qDebug( "\tCLO" );
        Packit Service 50c9f2
        		p = dump( p );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	    case OPT:
        Packit Service 50c9f2
        		qDebug( "\tOPT" );
        Packit Service 50c9f2
        		p = dump( p );
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            qDebug( "\tEND" );
        Packit Service 50c9f2
            return p+1;
        Packit Service 50c9f2
        }
        Packit Service 50c9f2
        #endif // DEBUG
        Packit Service 50c9f2
        Packit Service 50c9f2
        Packit Service 50c9f2
        static const int maxlen = 1024;			// max length of regexp array
        Packit Service 50c9f2
        static uint rxarray[ maxlen ];			// tmp regexp array
        Packit Service 50c9f2
        Packit Service 50c9f2
        /*!
        Packit Service 50c9f2
          \internal
        Packit Service 50c9f2
          Compiles the regular expression and stores the result in rxdata.
        Packit Service 50c9f2
          The 'error' flag is set to non-zero if an error is detected.
        Packit Service 50c9f2
          NOTE! This function is not reentrant!
        Packit Service 50c9f2
        */
        Packit Service 50c9f2
        Packit Service 50c9f2
        void QRegExp::compile()
        Packit Service 50c9f2
        {
        Packit Service 50c9f2
            if ( rxdata ) {				// delete old data
        Packit Service 50c9f2
        	delete [] rxdata;
        Packit Service 50c9f2
        	rxdata = 0;
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            if ( rxstring.isEmpty() ) {			// no regexp pattern set
        Packit Service 50c9f2
        	error = PatNull;
        Packit Service 50c9f2
        	return;
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
        Packit Service 50c9f2
            error = PatOk;				// assume pattern is ok
        Packit Service 50c9f2
        Packit Service 50c9f2
            QCString pattern;
        Packit Service 50c9f2
            if ( wc )
        Packit Service 50c9f2
        	pattern = wc2rx(rxstring);
        Packit Service 50c9f2
            else
        Packit Service 50c9f2
        	pattern = rxstring;
        Packit Service 50c9f2
            const char *start = pattern.data();	        // pattern pointer
        Packit Service 50c9f2
            const char *p = start;			// pattern pointer
        Packit Service 50c9f2
            uint pl = pattern.length();
        Packit Service 50c9f2
            uint *d = rxarray;				// data pointer
        Packit Service 50c9f2
            uint *prev_d = 0;
        Packit Service 50c9f2
        Packit Service 50c9f2
        #define GEN(x)	*d++ = (x)
        Packit Service 50c9f2
        Packit Service 50c9f2
            while ( pl ) {
        Packit Service 50c9f2
        	char ch = (char)*p;
        Packit Service 50c9f2
        	switch ( ch ) {
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    case '^':				// beginning of line
        Packit Service 50c9f2
        		prev_d = d;
        Packit Service 50c9f2
        		GEN( p == start ? BOL : (CHR | ch) );
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    case '$':				// end of line
        Packit Service 50c9f2
        		prev_d = d;
        Packit Service 50c9f2
        		GEN( pl == 1 ? EOL : (CHR | ch) );
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    case '.':				// any char
        Packit Service 50c9f2
        		prev_d = d;
        Packit Service 50c9f2
        		GEN( ANY );
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    case '[':				// character class
        Packit Service 50c9f2
        		{
        Packit Service 50c9f2
        		prev_d = d;
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		if ( !pl ) {
        Packit Service 50c9f2
        		    error = PatSyntax;
        Packit Service 50c9f2
        		    return;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		bool firstIsEscaped = ( (char)*p == '\\' );
        Packit Service 50c9f2
        		uint cch = char_val( &p, &pl );
        Packit Service 50c9f2
        		if ( cch == '^' && !firstIsEscaped ) {	// negate!
        Packit Service 50c9f2
        		    GEN( CCN );
        Packit Service 50c9f2
        		    if ( !pl ) {
        Packit Service 50c9f2
        			error = PatSyntax;
        Packit Service 50c9f2
        			return;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    cch = char_val( &p, &pl );
        Packit Service 50c9f2
        		} else {
        Packit Service 50c9f2
        		    GEN( CCL );
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		uint numFields = 0;
        Packit Service 50c9f2
        		while ( pl ) {
        Packit Service 50c9f2
        		    if ((pl>2) && ((char)*p == '-') && ((char)*(p+1) != ']')) {
        Packit Service 50c9f2
        			// Found a range
        Packit Service 50c9f2
        		       	char_val( &p, &pl ); // Read the '-'
        Packit Service 50c9f2
        			uint cch2 = char_val( &p, &pl ); // Read the range end
        Packit Service 50c9f2
        			if ( cch > cch2 ) { 		// swap start and stop
        Packit Service 50c9f2
        			    int tmp = cch;
        Packit Service 50c9f2
        			    cch = cch2;
        Packit Service 50c9f2
        			    cch2 = tmp;
        Packit Service 50c9f2
        			}
        Packit Service 50c9f2
        			GEN( (cch << 16) | cch2 );	// from < to
        Packit Service 50c9f2
        			numFields++;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    else {
        Packit Service 50c9f2
        			// Found a single character
        Packit Service 50c9f2
        			if ( cch & MCD ) // It's a code; will not be mistaken
        Packit Service 50c9f2
        			    GEN( cch );	 // for a range, since from > to
        Packit Service 50c9f2
        			else
        Packit Service 50c9f2
        			    GEN( (cch << 16) | cch ); // from == to range
        Packit Service 50c9f2
        			numFields++;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    if ( d >= rxarray + maxlen ) {	// pattern too long
        Packit Service 50c9f2
        			error = PatOverflow;		
        Packit Service 50c9f2
        			return;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    if ( !pl ) {		// At least ']' should be left
        Packit Service 50c9f2
        			error = PatSyntax;
        Packit Service 50c9f2
        			return;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    bool nextIsEscaped = ( (char)*p == '\\' );
        Packit Service 50c9f2
        		    cch = char_val( &p, &pl );
        Packit Service 50c9f2
        		    if ( cch == (uint)']' && !nextIsEscaped )
        Packit Service 50c9f2
        			break;
        Packit Service 50c9f2
        		    if ( !pl ) {		// End, should have seen ']'
        Packit Service 50c9f2
        			error = PatSyntax;
        Packit Service 50c9f2
        			return;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		*prev_d |= numFields;		// Store number of fields
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    case '*':				// Kleene closure, or
        Packit Service 50c9f2
        	    case '+':				// positive closure, or
        Packit Service 50c9f2
        	    case '?':				// optional closure
        Packit Service 50c9f2
        		{
        Packit Service 50c9f2
        		if ( prev_d == 0 ) {		// no previous expression
        Packit Service 50c9f2
        		    error = PatSyntax;		// empty closure
        Packit Service 50c9f2
        		    return;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		switch ( *prev_d ) {		// test if invalid closure
        Packit Service 50c9f2
        		    case BOL:
        Packit Service 50c9f2
        		    case BOW:
        Packit Service 50c9f2
        		    case EOW:
        Packit Service 50c9f2
        		    case CLO:
        Packit Service 50c9f2
        		    case OPT:
        Packit Service 50c9f2
        			error = PatSyntax;
        Packit Service 50c9f2
        			return;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		int ddiff = (int)(d - prev_d);
        Packit Service 50c9f2
        		if ( *p == '+' ) {		// convert to Kleene closure
        Packit Service 50c9f2
        		    if ( d + ddiff >= rxarray + maxlen ) {
        Packit Service 50c9f2
        			error = PatOverflow;	// pattern too long
        Packit Service 50c9f2
        			return;
        Packit Service 50c9f2
        		    }
        Packit Service 50c9f2
        		    memcpy( d, prev_d, ddiff*sizeof(uint) );
        Packit Service 50c9f2
        		    d += ddiff;
        Packit Service 50c9f2
        		    prev_d += ddiff;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		memmove( prev_d+1, prev_d, ddiff*sizeof(uint) );
        Packit Service 50c9f2
        		*prev_d = ch == '?' ? OPT : CLO;
        Packit Service 50c9f2
        		d++;
        Packit Service 50c9f2
        		GEN( END );
        Packit Service 50c9f2
        		p++;
        Packit Service 50c9f2
        		pl--;
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		break;
        Packit Service 50c9f2
        Packit Service 50c9f2
        	    default:
        Packit Service 50c9f2
        		{
        Packit Service 50c9f2
        		prev_d = d;
        Packit Service 50c9f2
        		uint cv = char_val( &p, &pl );
        Packit Service 50c9f2
        		if ( cv & MCD ) {			// It's a code
        Packit Service 50c9f2
        		    GEN( cv );
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		else {
        Packit Service 50c9f2
        		    if ( !cs && cv <= 0xff )		// #only 8bit support
        Packit Service 50c9f2
        			cv = tolower( cv );
        Packit Service 50c9f2
        		    GEN( CHR | cv );
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        		}
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
        	if ( d >= rxarray + maxlen ) {		// oops!
        Packit Service 50c9f2
        	    error = PatOverflow;		// pattern too long
        Packit Service 50c9f2
        	    return;
        Packit Service 50c9f2
        	}
        Packit Service 50c9f2
            }
        Packit Service 50c9f2
            GEN( END );
        Packit Service 50c9f2
            int len = (int)(d - rxarray);
        Packit Service 50c9f2
            rxdata = new uint[ len ];			// copy from rxarray to rxdata
        Packit Service 50c9f2
            CHECK_PTR( rxdata );
        Packit Service 50c9f2
            memcpy( rxdata, rxarray, len*sizeof(uint) );
        Packit Service 50c9f2
        #if defined(DEBUG)
        Packit Service 50c9f2
            //dump( rxdata );	// uncomment this line for debugging
        Packit Service 50c9f2
        #endif
        Packit Service 50c9f2
        }