Example #1
0
void HeaderFile::parse()
{
    Parser p( contents() );
    p.scan( "\nclass " );
    while ( !p.atEnd() ) {
        EString className = p.identifier();
        EString superclass = 0;
        p.whitespace();
        if ( p.lookingAt( ":" ) ) {
            p.step();
            EString inheritance = p.word();
            if ( inheritance != "public" ) {
                (void)new Error( this, p.line(),
                                 "Non-public inheritance for class " +
                                 className );
                return;
            }
            EString parent = p.identifier();
            if ( parent.isEmpty() ) {
                (void)new Error( this, p.line(),
                                 "Cannot parse superclass name for class " +
                                 className );
                return;
            }
            superclass = parent;
        }
        p.whitespace();
        if ( p.lookingAt( "{" ) ) {
            Class * c = Class::find( className );
            if ( !c )
                c = new Class( className, 0, 0 );
            c->setParent( superclass );
            if ( c && c->file() ) {
                (void) new Error( this, p.line(),
                                  "Class " + className +
                                  " conflicts with " + className + " at " +
                                  c->file()->name() + ":" +
                                  fn( c->line() ) );
                (void) new Error( c->file(), c->line(),
                                  "Class " + className +
                                  " conflicts with " + className + " at " +
                                  name() + ":" +
                                  fn( p.line() ) );
            }
            else {
                c->setSource( this, p.line() );
            }
            p.step();
            bool ok = false;
            do {
                ok = false;
                p.whitespace();
                while ( p.lookingAt( "public:" ) ||
                        p.lookingAt( "private:" ) ||
                        p.lookingAt( "protected:" ) ) {
                    p.scan( ":" );
                    p.step();
                    p.whitespace();
                }
                if ( p.lookingAt( "virtual " ) )
                    p.scan( " " );
                p.whitespace();
                EString t;
                EString n;
                uint l = p.line();
                if ( p.lookingAt( "operator " ) ) {
                    n = p.identifier();
                }
                else if ( p.lookingAt( "enum " ) ) {
                    p.scan( " " );
                    Enum * e = new Enum( c, p.word(), this, l );
                    p.whitespace();
                    if ( p.lookingAt( "{" ) ) {
                        bool again = true;
                        while ( again ) {
                            p.step();
                            p.whitespace();
                            EString v = p.word();
                            if ( v.isEmpty() )
                                (void)new Error( this, p.line(),
                                                 "Could not parse "
                                                 "enum value" );
                            else
                                e->addValue( v );
                            p.whitespace();
                            if ( p.lookingAt( "=" ) ) {
                                p.step();
                                p.whitespace();
                                (void)p.value();
                                p.whitespace();
                            }
                            again = p.lookingAt( "," );
                        }
                        if ( p.lookingAt( "}" ) ) {
                            p.step();
                            ok = true;
                        }
                        else {
                            (void)new Error( this, p.line(),
                                             "Enum definition for " +
                                             className + "::" + n +
                                             " does not end with '}'" );
                        }
                    }
                    else if ( p.lookingAt( ";" ) ) {
                        // senseless crap
                        ok = true;
                    }
                    else {
                        (void)new Error( this, l,
                                         "Cannot parse enum " +
                                         className + "::" + n );
                    }
                }
                else if ( p.lookingAt( "typedef " ) ) {
                    ok = true;
                }
                else {
                    t = p.type();
                    n = p.identifier();
                    if ( n.isEmpty() ) {
                        // constructor/destructor?
                        if ( t == className || t == "~" + className ) {
                            n = t;
                            t = "";
                        }
                        else if ( t.isEmpty() && p.lookingAt( "~" ) ) {
                            p.step();
                            n = "~" + p.identifier();
                        }
                    }
                }
                if ( !n.isEmpty() ) {
                    p.whitespace();
                    if ( p.lookingAt( ";" ) )
                        ok = true;
                    EString a = p.argumentList();
                    p.whitespace();
                    bool fc = false;
                    if ( p.lookingAt( "const" ) ) {
                        fc = true;
                        p.word();
                    }
                    if ( !n.isEmpty() && n.find( ':' ) < 0 &&
                         !a.isEmpty() ) {
                        n = className + "::" + n;
                        Function * f = Function::find( n, a, fc );
                        if ( !f )
                            f = new Function( t, n, a, fc, this, l );
                        ok = true;
                    }
                }
                if ( ok ) {
                    p.whitespace();
                    if ( p.lookingAt( "{" ) ) {
                        uint level = 0;
                        while ( level > 0 || p.lookingAt( "{" ) ) {
                            if ( p.lookingAt( "{" ) ) {
                                level++;
                            }
                            else if ( p.lookingAt( "}" ) ) {
                                level--;
                            }
                            p.step();
                            p.whitespace();
                        }
                    }
                    else {
                        p.scan( ";" );
                    }
                }
            } while ( ok );
        }
        p.scan( "\nclass " );
    }
}