Commit 0390fbf9 authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

speedups

parent f280c737
Loading
Loading
Loading
Loading
+40 −56
Original line number Diff line number Diff line
@@ -374,11 +374,11 @@ int DSNLEXER::NeedNUMBER( const char* aExpectation ) throw( IO_ERROR )
 * i.e. no bytes with MSB on can be considered whitespace, since they are likely part
 * of a multibyte UTF8 character.
 */
static bool isSpace( int cc )
static bool isSpace( char cc )
{
    // cc was signed extended from signed char, so it is often negative.
    // cc is signed, so it is often negative.
    // Treat negative as large positive to exclude rapidly.
    if( unsigned( cc ) <= ' ' )
    if( (unsigned char) cc <= ' ' )
    {
        switch( cc )
        {
@@ -394,47 +394,41 @@ static bool isSpace( int cc )
}


/**
 * Function isNumber
 * return true if the next sequence of s-expression text is a number:
 * either an integer, fixed point, or float with exponent.
 *
 * @param cp is the start of the current token.
 * @param limit is the end of the current line of text.
 * @param next is where to put a pointer to the start of the token after this one, but is only
 *    updated if the return value is true.
 * @return bool - true if this is a number, else false.
 */
static bool isNumber( const char* cp, const char* limit, const char** next )
inline bool isDigit( char cc )
{
#if 0   // no exponents supported
    return '0' <= cc && cc <= '9';
}

    if( strchr( "+-.0123456789", *cp ) )
    {
        ++cp;
        while( cp<limit && strchr( ".0123456789", *cp )  )
            ++cp;

        if( cp==limit || isSpace( *cp ) || *cp==')' || *cp=='(' )
/// return true if @a cc is an s-expression separator character
inline bool isSep( char cc )
{
            *next = cp;
            return true;
        }
    return isSpace( cc ) || cc=='(' || cc==')';
}

    return false;

#else   // support numbers with exponents.

    // regex for a float: "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?" i.e. any number
    // is traversed, coded manually here:
/**
 * Function isNumber
 * returns true if the next sequence of text is a number:
 * either an integer, fixed point, or float with exponent.  Stops scanning
 * at the first non-number character, even if it is not whitespace.
 *
 * @param cp is the start of the current token.
 * @param limit is the end of the current line of text.
 * @return const char* - pointer to the start of the token after this one, but if
 *    this token is a number, else NULL
 */
static const char* isNumber( const char* cp, const char* limit )
{
    // regex for a float: "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?" i.e. any number,
    // code traversal manually here:

    bool sawNumber = false;

    if( cp < limit && strchr( "-+", *cp ) )
    if( cp < limit && ( *cp=='-' || *cp=='+' ) )
        ++cp;

    while( cp < limit && strchr( "0123456789", *cp ) )
    while( cp < limit && isDigit( *cp ) )
    {
        ++cp;
        sawNumber = true;
@@ -444,7 +438,7 @@ static bool isNumber( const char* cp, const char* limit, const char** next )
    {
        ++cp;

        while( cp < limit && strchr( "0123456789", *cp ) )
        while( cp < limit && isDigit( *cp ) )
        {
            ++cp;
            sawNumber = true;
@@ -453,16 +447,16 @@ static bool isNumber( const char* cp, const char* limit, const char** next )

    if( sawNumber )
    {
        if( cp < limit && strchr( "Ee", *cp ) )
        if( cp < limit && ( *cp=='E' || *cp=='e' ) )
        {
            ++cp;

            sawNumber = false;  // exponent mandates at least one digit thereafter.

            if( cp < limit && strchr( "-+", *cp ) )
            if( cp < limit && ( *cp=='-' || *cp=='+' )  )
                ++cp;

            while( cp < limit && strchr( "0123456789", *cp ) )
            while( cp < limit && isDigit( *cp ) )
            {
                ++cp;
                sawNumber = true;
@@ -470,18 +464,7 @@ static bool isNumber( const char* cp, const char* limit, const char** next )
        }
    }

    if( sawNumber )
    {
        // token can only be a number if not adjoined with other non-number token text
        if( cp==limit || isSpace( *cp ) || *cp==')' || *cp=='(' )
        {
            *next = cp;
            return true;
        }
    }

    return false;
#endif
    return sawNumber ? cp : NULL;
}


@@ -577,7 +560,7 @@ L_read:

            head = cur+1;

            if( head<limit && *head!=')' && *head!='(' && !isSpace(*head) )
            if( head<limit && !isSep( *head ) )
            {
                THROW_PARSE_ERROR( errtxt, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
            }
@@ -598,9 +581,10 @@ L_read:
            goto exit;
        }

        if( isNumber( cur, limit, &head ) )
        if( ( head = isNumber( cur, limit ) ) != NULL &&
            // token can only be a number if trailing text is a separator or line end
            ( head==limit || isSep( *head ) ) )
        {
            // handle DSN_NUMBER
            curText.clear();
            curText.append( cur, head );
            curTok = DSN_NUMBER;
@@ -726,7 +710,7 @@ L_read:
        // If not, then call it a DSN_SYMBOL.
        {
            head = cur+1;
            while( head<limit && !isSpace( *head ) && *head!=')' && *head!='(' )
            while( head<limit && !isSep( *head ) )
                ++head;

            curText.clear();