Commit 06390721 authored by Dick Hollenbeck's avatar Dick Hollenbeck
Browse files

more fp_lib_table work, enhance parser

parent 6ad94a49
Loading
Loading
Loading
Loading
+4 −6
Original line number Original line Diff line number Diff line
@@ -304,9 +304,8 @@ void DSNLEXER::Unexpected( int aTok ) throw( IO_ERROR )


void DSNLEXER::Duplicate( int aTok ) throw( IO_ERROR )
void DSNLEXER::Duplicate( int aTok ) throw( IO_ERROR )
{
{
    wxString    errText;
    wxString errText = wxString::Format(

        _("%s is a duplicate"), GetTokenString( aTok ).GetData() );
    errText.Printf( _("%s is a duplicate"), GetTokenString( aTok ).GetData() );
    THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
    THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
}
}


@@ -358,9 +357,8 @@ int DSNLEXER::NeedNUMBER( const char* aExpectation ) throw( IO_ERROR )
    int tok = NextTok();
    int tok = NextTok();
    if( tok != DSN_NUMBER )
    if( tok != DSN_NUMBER )
    {
    {
        wxString    errText;
        wxString errText = wxString::Format(

            _("need a NUMBER for '%s'"), wxString::FromUTF8( aExpectation ).GetData() );
        errText.Printf( _("need a NUMBER for '%s'"), wxString::FromUTF8( aExpectation ).GetData() );
        THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
        THROW_PARSE_ERROR( errText, CurSource(), CurLine(), CurLineNumber(), CurOffset() );
    }
    }
    return tok;
    return tok;
+100 −42
Original line number Original line Diff line number Diff line
@@ -24,6 +24,8 @@
 */
 */




#include <wx/config.h>      // wxExpandEnvVars()

#include <set>
#include <set>


#include <io_mgr.h>
#include <io_mgr.h>
@@ -45,11 +47,29 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :


void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR )
void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR )
{
{
    /*
        (fp_lib_table
            (lib (name NICKNAME)(descr DESCRIPTION)(type TYPE)(full_uri FULL_URI)(options OPTIONS))
            :
        )

        Elements after (name) are order independent.
    */

    T       tok;
    T       tok;


    // This table may be nested within a larger s-expression, or not.
    // Allow for parser of that optional outter s-epression to have looked ahead.
    if( in->CurTok() != T_fp_lib_table )
    {
        in->NeedLEFT();
        if( ( tok = in->NextTok() ) != T_fp_lib_table )
            in->Expecting( T_fp_lib_table );
    }

    while( ( tok = in->NextTok() ) != T_RIGHT )
    while( ( tok = in->NextTok() ) != T_RIGHT )
    {
    {
        // (lib (name "LOGICAL")(type "TYPE")(full_uri "FULL_URI")(options "OPTIONS"))
        ROW     row;        // reconstructed for each row in input stream.


        if( tok == T_EOF )
        if( tok == T_EOF )
            in->Expecting( T_RIGHT );
            in->Expecting( T_RIGHT );
@@ -57,10 +77,14 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
        if( tok != T_LEFT )
        if( tok != T_LEFT )
            in->Expecting( T_LEFT );
            in->Expecting( T_LEFT );


        if( ( tok = in->NextTok() ) != T_fp_lib )
        // in case there is a "row integrity" error, tell where later.
            in->Expecting( T_fp_lib );
        int lineNum = in->CurLineNumber();
        int offset  = in->CurOffset();


        // (name "LOGICAL_NAME")
        if( ( tok = in->NextTok() ) != T_lib )
            in->Expecting( T_lib );

        // (name LOGICAL_NAME)
        in->NeedLEFT();
        in->NeedLEFT();


        if( ( tok = in->NextTok() ) != T_name )
        if( ( tok = in->NextTok() ) != T_name )
@@ -68,48 +92,74 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR


        in->NeedSYMBOLorNUMBER();
        in->NeedSYMBOLorNUMBER();


        ROW     row;

        row.SetNickName( in->FromUTF8() );
        row.SetNickName( in->FromUTF8() );


        in->NeedRIGHT();
        in->NeedRIGHT();


        // (uri "FULL_URI")
        // After (name), remaining (lib) elements are order independent, and in
        in->NeedLEFT();
        // the future, perhaps optional.  Flexibility for future changes.


        if( ( tok = in->NextTok() ) != T_full_uri )
        bool    sawType = false;
            in->Expecting( T_full_uri );
        bool    sawOpts = false;
        bool    sawDesc = false;
        bool    sawUri  = false;


        in->NeedSYMBOLorNUMBER();
        while( ( tok = in->NextTok() ) != T_RIGHT )

        {
        row.SetFullURI( in->FromUTF8() );
            if( tok == T_EOF )
                in->Unexpected( T_EOF );


        in->NeedRIGHT();
            if( tok != T_LEFT )
                in->Expecting( T_LEFT );


        // (type "TYPE")
            tok = in->NeedSYMBOLorNUMBER();
        in->NeedLEFT();

        if( ( tok = in->NextTok() ) != T_type )
            in->Expecting( T_type );


            switch( tok )
            {
            case T_uri:
                if( sawUri )
                    in->Duplicate( tok );
                sawUri = true;
                in->NeedSYMBOLorNUMBER();
                in->NeedSYMBOLorNUMBER();
                row.SetFullURI( in->FromUTF8() );
                break;


            case T_type:
                if( sawType )
                    in->Duplicate( tok );
                sawType = true;
                in->NeedSYMBOLorNUMBER();
                row.SetType( in->FromUTF8() );
                row.SetType( in->FromUTF8() );
                break;


        in->NeedRIGHT();
            case T_options:

                if( sawOpts )
        // (options "OPTIONS")
                    in->Duplicate( tok );
        in->NeedLEFT();
                sawOpts = true;

                in->NeedSYMBOLorNUMBER();
        if( ( tok = in->NextTok() ) != T_options )
                row.SetOptions( in->FromUTF8() );
            in->Expecting( T_options );
                break;


            case T_descr:
                if( sawDesc )
                    in->Duplicate( tok );
                sawDesc = true;
                in->NeedSYMBOLorNUMBER();
                in->NeedSYMBOLorNUMBER();
                row.SetDescr( in->FromUTF8() );
                break;


        row.SetOptions( in->FromUTF8() );
            default:
                in->Unexpected( tok );
            }


            in->NeedRIGHT();
            in->NeedRIGHT();
        in->NeedRIGHT();            // terminate the (lib..)
        }

        if( !sawType )
            in->Expecting( T_type );

        if( !sawUri )
            in->Expecting( T_uri );


        // all nickNames within this table fragment must be unique, so we do not
        // all nickNames within this table fragment must be unique, so we do not
        // use doReplace in InsertRow().  (However a fallBack table can have a
        // use doReplace in InsertRow().  (However a fallBack table can have a
@@ -119,9 +169,8 @@ void FP_LIB_TABLE::Parse( FP_LIB_TABLE_LEXER* in ) throw( IO_ERROR, PARSE_ERROR
        {
        {
            wxString msg = wxString::Format(
            wxString msg = wxString::Format(
                                _( "'%s' is a duplicate footprint library nickName" ),
                                _( "'%s' is a duplicate footprint library nickName" ),
                                GetChars( row.nickName )
                                GetChars( row.nickName ) );
                                );
            THROW_PARSE_ERROR( msg, in->CurSource(), in->CurLine(), lineNum, offset );
            THROW_IO_ERROR( msg );
        }
        }
    }
    }
}
}
@@ -142,8 +191,9 @@ void FP_LIB_TABLE::Format( OUTPUTFORMATTER* out, int nestLevel ) const
void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
void FP_LIB_TABLE::ROW::Format( OUTPUTFORMATTER* out, int nestLevel ) const
    throw( IO_ERROR )
    throw( IO_ERROR )
{
{
    out->Print( nestLevel, "(lib (name %s)(full_uri %s)(type %s)(options %s))\n",
    out->Print( nestLevel, "(lib (name %s)(descr %s)(uri %s)(type %s)(options %s))\n",
                out->Quotew( GetNickName() ).c_str(),
                out->Quotew( GetNickName() ).c_str(),
                out->Quotew( GetDescr() ).c_str(),
                out->Quotew( GetFullURI() ).c_str(),
                out->Quotew( GetFullURI() ).c_str(),
                out->Quotew( GetType() ).c_str(),
                out->Quotew( GetType() ).c_str(),
                out->Quotew( GetOptions() ).c_str()
                out->Quotew( GetOptions() ).c_str()
@@ -252,6 +302,14 @@ PLUGIN* FP_LIB_TABLE::PluginFind( const wxString& aLibraryNickName )
}
}




const wxString FP_LIB_TABLE::ExpandSubtitutions( const wxString aString )
{
    // We reserve the right to do this another way, but providing our own member
    // function.
    return wxExpandEnvVars( aString );
}


#if 0  // don't know that this is needed yet
#if 0  // don't know that this is needed yet
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
MODULE* FP_LIB_TABLE::LookupFootprint( const FP_LIB_ID& aFootprintId )
    throw( IO_ERROR )
    throw( IO_ERROR )
+3 −5
Original line number Original line Diff line number Diff line
fp_lib_table
fp_lib_table
lib
name
name
type
type
kicad
uri
legacy
eagle
full_uri
options
options
fp_lib
descr
+41 −10
Original line number Original line Diff line number Diff line
@@ -39,15 +39,44 @@
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.





void IO_ERROR::init( const char* aThrowersFile, const char* aThrowersLoc, const wxString& aMsg )
{
    errorText.Printf( IO_FORMAT, aMsg.GetData(),
        wxString::FromUTF8( aThrowersFile ).GetData(),
        wxString::FromUTF8( aThrowersLoc ).GetData() );
}


void PARSE_ERROR::init( const char* aThrowersFile, const char* aThrowersLoc,
           const wxString& aMsg, const wxString& aSource,
           const char* aInputLine,
           int aLineNumber, int aByteIndex )
{
    // save inpuLine, lineNumber, and offset for UI (.e.g. Sweet text editor)
    inputLine  = aInputLine;
    lineNumber = aLineNumber;
    byteIndex  = aByteIndex;

    errorText.Printf( PARSE_FORMAT, aMsg.GetData(), aSource.GetData(),
        aLineNumber, aByteIndex,
        wxString::FromUTF8( aThrowersFile ).GetData(),
        wxString::FromUTF8( aThrowersLoc ).GetData() );
}


//-----<LINE_READER>------------------------------------------------------
//-----<LINE_READER>------------------------------------------------------


LINE_READER::LINE_READER( unsigned aMaxLineLength )
LINE_READER::LINE_READER( unsigned aMaxLineLength )
{
{
    lineNum = 0;
    lineNum = 0;


    if( aMaxLineLength == 0 )       // caller is goofed up.
    if( aMaxLineLength == 0 )
        aMaxLineLength = LINE_READER_LINE_DEFAULT_MAX;
    {

        line = 0;
    }
    else
    {
        maxLineLength = aMaxLineLength;
        maxLineLength = aMaxLineLength;


        // start at the INITIAL size, expand as needed up to the MAX size in maxLineLength
        // start at the INITIAL size, expand as needed up to the MAX size in maxLineLength
@@ -60,6 +89,8 @@ LINE_READER::LINE_READER( unsigned aMaxLineLength )
        line = new char[capacity];
        line = new char[capacity];


        line[0] = '\0';
        line[0] = '\0';
    }

    length  = 0;
    length  = 0;
}
}


+61 −59
Original line number Original line Diff line number Diff line
@@ -41,7 +41,7 @@ class FP_LIB_TABLE_LEXER;


/**
/**
 * Class FP_LIB_TABLE
 * Class FP_LIB_TABLE
 * holds FP_LIB_TABLE::ROW records, and can be searched based on logical library name.
 * holds FP_LIB_TABLE::ROW records (rows), and can be searched based on library nickName.
 * <p>
 * <p>
 * This class owns the <b>footprint library table</b>, which is like fstab in concept and maps
 * This class owns the <b>footprint library table</b>, which is like fstab in concept and maps
 * logical library name to the library URI, type, and options. It is heavily based on the SWEET
 * logical library name to the library URI, type, and options. It is heavily based on the SWEET
@@ -104,10 +104,12 @@ public:
        {
        {
        }
        }


        ROW( const wxString& aNick, const wxString& aURI, const wxString& aType, const wxString& aOptions ) :
        ROW( const wxString& aNick, const wxString& aURI, const wxString& aType,
                const wxString& aOptions, const wxString& aDescr = wxEmptyString ) :
            nickName( aNick ),
            nickName( aNick ),
            uri( aURI ),
            uri( aURI ),
            options( aOptions )
            options( aOptions ),
            description( aDescr )
        {
        {
            SetType( aType );
            SetType( aType );
        }
        }
@@ -119,90 +121,80 @@ public:


        bool operator!=( const ROW& r ) const   { return !( *this == r ); }
        bool operator!=( const ROW& r ) const   { return !( *this == r ); }


        //-----<accessors>------------------------------------------------------

        /**
        /**
         * Function GetNickName
         * Function GetNickName
         * returns the short name of this library table row.
         * returns the short name of this library table row.
         */
         */
        const wxString& GetNickName() const
        const wxString& GetNickName() const         { return nickName; }
        {

            return nickName;
        /**
        }
         * Function SetNickName
         * changes the logical name of this library, useful for an editor.
         */
        void SetNickName( const wxString& aNickName ) { nickName = aNickName; }


        /**
        /**
         * Function GetType
         * Function GetType
         * returns the type of LIB represented by this record.
         * returns the type of LIB represented by this row.
         */
         */
        const wxString GetType() const
        const wxString GetType() const              { return IO_MGR::ShowType( type ); }
        {

            return IO_MGR::ShowType( type );
        /**
        }
         * Function SetType
         * changes the type represented by this row.
         */
        void SetType( const wxString& aType )       { type = IO_MGR::EnumFromStr( aType ); }


        /**
        /**
         * Function GetFullURI
         * Function GetFullURI
         * returns the full location specifying URI for the LIB.
         * returns the full location specifying URI for the LIB.
         */
         */
        const wxString& GetFullURI() const
        const wxString& GetFullURI() const          { return uri; }
        {

            return uri;
        /**
        }
         * Function SetFullURI
         * changes the full URI for the library.
         */
        void SetFullURI( const wxString& aFullURI ) { uri = aFullURI; }


        /**
        /**
         * Function GetOptions
         * Function GetOptions
         * returns the options string, which may hold a password or anything else needed to
         * returns the options string, which may hold a password or anything else needed to
         * instantiate the underlying LIB_SOURCE.
         * instantiate the underlying LIB_SOURCE.
         */
         */
        const wxString& GetOptions() const
        const wxString& GetOptions() const          { return options; }
        {
            return options;
        }


        /**
        /**
         * Function Format
         * Function SetOptions
         * serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
         * make it look good using multiple lines and indentation.
         * @param out is an #OUTPUTFORMATTER
         * @param nestLevel is the indentation level to base all lines of the output.
         *   Actual indentation will be 2 spaces for each nestLevel.
         */
         */
        void Format( OUTPUTFORMATTER* out, int nestLevel ) const
        void SetOptions( const wxString& aOptions ) { options = aOptions; }
            throw( IO_ERROR );


        /**
        /**
         * Function SetNickName
         * Function GetDescr
         * changes the logical name of this library, useful for an editor.
         * returns the description of the library referenced by this row.
         */
         */
        void SetNickName( const wxString& aNickName )
        const wxString& GetDescr() const            { return description; }
        {
            nickName = aNickName;
        }


        /**
        /**
         * Function SetType
         * Function SetDescr
         * changes the type represented by this record.
         * changes the description of the library referenced by this row.
         */
         */
        void SetType( const wxString& aType )
        void SetDescr( const wxString& aDescr )     { description = aDescr; }
        {
            type = IO_MGR::EnumFromStr( aType );
        }


        /**
        //-----</accessors>-----------------------------------------------------
         * Function SetFullURI
         * changes the full URI for the library, useful from a library table editor.
         */
        void SetFullURI( const wxString& aFullURI )
        {
            uri = aFullURI;
        }


        /**
        /**
         * Function SetOptions
         * Function Format
         * changes the options string for this record, and is useful from
         * serializes this object as utf8 text to an OUTPUTFORMATTER, and tries to
         * the library table editor.
         * make it look good using multiple lines and indentation.
         * @param out is an #OUTPUTFORMATTER
         * @param nestLevel is the indentation level to base all lines of the output.
         *   Actual indentation will be 2 spaces for each nestLevel.
         */
         */
        void SetOptions( const wxString& aOptions )
        void Format( OUTPUTFORMATTER* out, int nestLevel ) const
        {
            throw( IO_ERROR );
            options = aOptions;
        }


    private:
    private:


@@ -210,6 +202,7 @@ public:
        wxString        uri;
        wxString        uri;
        LIB_T           type;
        LIB_T           type;
        wxString        options;
        wxString        options;
        wxString        description;
    };
    };




@@ -219,7 +212,7 @@ public:
     * @a aFallBackTable.  Loading of this table fragment is done by using Parse().
     * @a aFallBackTable.  Loading of this table fragment is done by using Parse().
     *
     *
     * @param aFallBackTable is another FP_LIB_TABLE which is searched only when
     * @param aFallBackTable is another FP_LIB_TABLE which is searched only when
     *                       a record is not found in this table.  No ownership is
     *                       a row is not found in this table.  No ownership is
     *                       taken of aFallBackTable.
     *                       taken of aFallBackTable.
     */
     */
    FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
    FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable = NULL );
@@ -249,9 +242,9 @@ public:
     *
     *
     * <pre>
     * <pre>
     * (fp_lib_table
     * (fp_lib_table
     *   (lib (name LOGICAL)(type TYPE)(uri FULL_URI)(options OPTIONS))
     *   (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
     *   (lib (name LOGICAL)(type TYPE)(uri FULL_URI)(options OPTIONS))
     *   (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
     *   (lib (name LOGICAL)(type TYPE)(uri FULL_URI)(options OPTIONS))
     *   (lib (name LOGICAL)(descr DESCRIPTION)(uri FULL_URI)(type TYPE)(options OPTIONS))
     *  )
     *  )
     * </pre>
     * </pre>
     *
     *
@@ -363,6 +356,15 @@ public:
    const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );
    const ROW* FindRow( const wxString& aNickName ) throw( IO_ERROR );




    /**
     * Function ExpandEnvSubsitutions
     * replaces any environment variable references with their values and is
     * here to fully embellish the ROW::uri in a platform independent way.
     * This enables (fp_lib_table)s to have platform dependent environment
     * variables in them, allowing for a uniform table across platforms.
     */
    static const wxString ExpandSubtitutions( const wxString aString );

protected:
protected:


    /**
    /**
Loading