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

better error reporting and parsing of bad legacy footprint libs

parent 64f8e0b8
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
/**
/**
 * @file annotate_dialog.cpp
 * @file dialog_annotate.cpp
 * @brief Annotation dialog functions.
 * @brief Annotation dialog functions.
 */
 */


+2 −2
Original line number Original line Diff line number Diff line
@@ -44,8 +44,8 @@ class wxTextCtrl;
 * The purpose of the REPORTER object is to offer a way for a procedural function
 * The purpose of the REPORTER object is to offer a way for a procedural function
 * to report multiple errors without having to:
 * to report multiple errors without having to:
 * <ul>
 * <ul>
 * <li> a) know too much about the caller's UI, i.e. wx. </li>
 * <li> know too much about the caller's UI, i.e. wx. </li>
 * <li> b) stop after the first error </li>
 * <li> stop after the first error </li>
 * </ul>
 * </ul>
 */
 */
class REPORTER
class REPORTER
+10 −6
Original line number Original line Diff line number Diff line
@@ -25,17 +25,18 @@
#ifndef PROJECT_TEMPLATE_SELECTOR_H
#ifndef PROJECT_TEMPLATE_SELECTOR_H
#define PROJECT_TEMPLATE_SELECTOR_H
#define PROJECT_TEMPLATE_SELECTOR_H


#include "dialogs/dialog_template_selector_base.h"
#include <dialogs/dialog_template_selector_base.h>
#include "project_template.h"
#include "project_template.h"



class TEMPLATE_WIDGET : public TEMPLATE_WIDGET_BASE
class TEMPLATE_WIDGET : public TEMPLATE_WIDGET_BASE
{
{
protected:
protected:
    wxDialog*   dialog;
    wxDialog*   dialog;
    wxWindow*   parent;
    wxWindow*   parent;
    wxPanel*    panel;
    wxPanel*    panel;

    bool        selected;
    bool        selected;

    PROJECT_TEMPLATE* templ;
    PROJECT_TEMPLATE* templ;


    void OnKillFocus( wxFocusEvent& event );
    void OnKillFocus( wxFocusEvent& event );
@@ -56,6 +57,7 @@ public:
    bool IsSelected();
    bool IsSelected();
};
};



class TEMPLATE_SELECTION_PANEL : public TEMPLATE_SELECTION_PANEL_BASE
class TEMPLATE_SELECTION_PANEL : public TEMPLATE_SELECTION_PANEL_BASE
{
{
protected:
protected:
@@ -65,6 +67,7 @@ protected:
public:
public:
    /**
    /**
     * @param aParent The window creating the dialog
     * @param aParent The window creating the dialog
     * @param aPath the path
     */
     */
    TEMPLATE_SELECTION_PANEL( wxWindow* aParent, const wxString& aPath );
    TEMPLATE_SELECTION_PANEL( wxWindow* aParent, const wxString& aPath );
    ~TEMPLATE_SELECTION_PANEL();
    ~TEMPLATE_SELECTION_PANEL();
@@ -72,6 +75,7 @@ public:
    const wxString& GetPath() { return m_templatesPath; }
    const wxString& GetPath() { return m_templatesPath; }
};
};



class DIALOG_TEMPLATE_SELECTOR : public DIALOG_TEMPLATE_SELECTOR_BASE
class DIALOG_TEMPLATE_SELECTOR : public DIALOG_TEMPLATE_SELECTOR_BASE
{
{
protected:
protected:
+1 −1
Original line number Original line Diff line number Diff line
@@ -59,7 +59,7 @@
        ~~~~~~~~~~~~~~
        ~~~~~~~~~~~~~~


        /info.html  - Contains html formatted information about the template which is used by the
        /info.html  - Contains html formatted information about the template which is used by the
                      user to determine if the template is what they are after. The <title> tag
                      user to determine if the template is what they are after. The &lt;title&gt; tag
                      determines the actual name of the template that is exposed to the user for
                      determines the actual name of the template that is exposed to the user for
                      template selection. Using html to format this document means that images can
                      template selection. Using html to format this document means that images can
                      be in-lined without having to invent a new scheme. Only HTML supported by
                      be in-lined without having to invent a new scheme. Only HTML supported by
+74 −43
Original line number Original line Diff line number Diff line
@@ -276,8 +276,9 @@ void LEGACY_PLUGIN::loadAllSections( bool doAppend )


        if( TESTLINE( "$MODULE" ) )
        if( TESTLINE( "$MODULE" ) )
        {
        {
            MODULE* m = LoadMODULE();
            auto_ptr<MODULE>    module( new MODULE( m_board ) );
            m_board->Add( m, ADD_APPEND );
            LoadMODULE( module.get() );
            m_board->Add( module.release(), ADD_APPEND );
        }
        }


        else if( TESTLINE( "$DRAWSEGMENT" ) )
        else if( TESTLINE( "$DRAWSEGMENT" ) )
@@ -918,9 +919,8 @@ void LEGACY_PLUGIN::loadSETUP()
}
}




MODULE* LEGACY_PLUGIN::LoadMODULE()
void LEGACY_PLUGIN::LoadMODULE( MODULE* aModule )
{
{
    auto_ptr<MODULE>    module( new MODULE( m_board ) );
    char*               line;
    char*               line;


    while( ( line = READLINE( m_reader ) ) != NULL )
    while( ( line = READLINE( m_reader ) ) != NULL )
@@ -929,14 +929,14 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()


        // most frequently encountered ones at the top
        // most frequently encountered ones at the top


        if( TESTSUBSTR( "D" ) )          // read a drawing item, e.g. "DS"
        if( TESTSUBSTR( "D" ) && strchr( "SCAP", line[1] ) )  // read a drawing item, e.g. "DS"
        {
        {
            loadMODULE_EDGE( module.get() );
            loadMODULE_EDGE( aModule );
        }
        }


        else if( TESTLINE( "$PAD" ) )
        else if( TESTLINE( "$PAD" ) )
        {
        {
            loadPAD( module.get() );
            loadPAD( aModule );
        }
        }


        // Read a footprint text description (ref, value, or drawing)
        // Read a footprint text description (ref, value, or drawing)
@@ -951,17 +951,17 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
            switch( tnum )
            switch( tnum )
            {
            {
            case TEXTE_MODULE::TEXT_is_REFERENCE:
            case TEXTE_MODULE::TEXT_is_REFERENCE:
                textm = &module->Reference();
                textm = &aModule->Reference();
                break;
                break;


            case TEXTE_MODULE::TEXT_is_VALUE:
            case TEXTE_MODULE::TEXT_is_VALUE:
                textm = &module->Value();
                textm = &aModule->Value();
                break;
                break;


            default:
            default:
                // text is a drawing
                // text is a drawing
                textm = new TEXTE_MODULE( module.get() );
                textm = new TEXTE_MODULE( aModule );
                module->GraphicalItems().PushBack( textm );
                aModule->GraphicalItems().PushBack( textm );
            }
            }


            loadMODULE_TEXT( textm );
            loadMODULE_TEXT( textm );
@@ -986,29 +986,29 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
            // data is now a two character long string
            // data is now a two character long string
            // Note: some old files do not have this field
            // Note: some old files do not have this field
            if( data && data[0] == 'F' )
            if( data && data[0] == 'F' )
                module->SetLocked( true );
                aModule->SetLocked( true );


            if( data && data[1] == 'P' )
            if( data && data[1] == 'P' )
                module->SetIsPlaced( true );
                aModule->SetIsPlaced( true );


            module->SetPosition( wxPoint( pos_x, pos_y ) );
            aModule->SetPosition( wxPoint( pos_x, pos_y ) );
            module->SetLayer( layer );
            aModule->SetLayer( layer );
            module->SetOrientation( orient );
            aModule->SetOrientation( orient );
            module->SetTimeStamp( timestamp );
            aModule->SetTimeStamp( timestamp );
            module->SetLastEditTime( edittime );
            aModule->SetLastEditTime( edittime );
        }
        }


        else if( TESTLINE( "Li" ) )         // Library name of footprint
        else if( TESTLINE( "Li" ) )         // Library name of footprint
        {
        {
            // There can be whitespace in the footprint name on some old libraries.
            // There can be whitespace in the footprint name on some old libraries.
            // Grab everything after "Li" up to end of line:
            // Grab everything after "Li" up to end of line:
            module->SetLibRef( FROM_UTF8( StrPurge( line + SZ( "Li" ) ) ) );
            // aModule->SetLibRef( FROM_UTF8( StrPurge( line + SZ( "Li" ) ) ) );
        }
        }


        else if( TESTLINE( "Sc" ) )         // timestamp
        else if( TESTLINE( "Sc" ) )         // timestamp
        {
        {
            time_t timestamp = hexParse( line + SZ( "Sc" ) );
            time_t timestamp = hexParse( line + SZ( "Sc" ) );
            module->SetTimeStamp( timestamp );
            aModule->SetTimeStamp( timestamp );
        }
        }


        else if( TESTLINE( "Op" ) )         // (Op)tions for auto placement
        else if( TESTLINE( "Op" ) )         // (Op)tions for auto placement
@@ -1020,7 +1020,7 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
            if( cntRot180 > 10 )
            if( cntRot180 > 10 )
                cntRot180 = 10;
                cntRot180 = 10;


            module->SetPlacementCost180( cntRot180 );
            aModule->SetPlacementCost180( cntRot180 );


            int cntRot90  = itmp1 & 0x0F;
            int cntRot90  = itmp1 & 0x0F;
            if( cntRot90 > 10 )
            if( cntRot90 > 10 )
@@ -1030,7 +1030,7 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
            if( itmp1 > 10 )
            if( itmp1 > 10 )
                itmp1 = 0;
                itmp1 = 0;


            module->SetPlacementCost90( (itmp1 << 4) | cntRot90 );
            aModule->SetPlacementCost90( (itmp1 << 4) | cntRot90 );
        }
        }


        else if( TESTLINE( "At" ) )         // (At)tributes of module
        else if( TESTLINE( "At" ) )         // (At)tributes of module
@@ -1045,30 +1045,31 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
            if( strstr( data, "VIRTUAL" ) )
            if( strstr( data, "VIRTUAL" ) )
                attrs |= MOD_VIRTUAL;
                attrs |= MOD_VIRTUAL;


            module->SetAttributes( attrs );
            aModule->SetAttributes( attrs );
        }
        }


        else if( TESTLINE( "AR" ) )         // Alternate Reference
        else if( TESTLINE( "AR" ) )         // Alternate Reference
        {
        {
            // e.g. "AR /47BA2624/45525076"
            // e.g. "AR /47BA2624/45525076"
            data = strtok( line + SZ( "AR" ), delims );
            data = strtok( line + SZ( "AR" ), delims );
            module->SetPath( FROM_UTF8( data ) );
            if( data )
                aModule->SetPath( FROM_UTF8( data ) );
        }
        }


        else if( TESTLINE( "$SHAPE3D" ) )
        else if( TESTLINE( "$SHAPE3D" ) )
        {
        {
            load3D( module.get() );
            load3D( aModule );
        }
        }


        else if( TESTLINE( "Cd" ) )
        else if( TESTLINE( "Cd" ) )
        {
        {
            // e.g. "Cd Double rangee de contacts 2 x 4 pins\r\n"
            // e.g. "Cd Double rangee de contacts 2 x 4 pins\r\n"
            module->SetDescription( FROM_UTF8( StrPurge( line + SZ( "Cd" ) ) ) );
            aModule->SetDescription( FROM_UTF8( StrPurge( line + SZ( "Cd" ) ) ) );
        }
        }


        else if( TESTLINE( "Kw" ) )         // Key words
        else if( TESTLINE( "Kw" ) )         // Key words
        {
        {
            module->SetKeywords( FROM_UTF8( StrPurge( line + SZ( "Kw" ) ) ) );
            aModule->SetKeywords( FROM_UTF8( StrPurge( line + SZ( "Kw" ) ) ) );
        }
        }


        else if( TESTLINE( ".SolderPasteRatio" ) )
        else if( TESTLINE( ".SolderPasteRatio" ) )
@@ -1082,54 +1083,58 @@ MODULE* LEGACY_PLUGIN::LoadMODULE()
                tmp = -0.50;
                tmp = -0.50;
            if( tmp > 0.0 )
            if( tmp > 0.0 )
                tmp = 0.0;
                tmp = 0.0;
            module->SetLocalSolderPasteMarginRatio( tmp );
            aModule->SetLocalSolderPasteMarginRatio( tmp );
        }
        }


        else if( TESTLINE( ".SolderPaste" ) )
        else if( TESTLINE( ".SolderPaste" ) )
        {
        {
            BIU tmp = biuParse( line + SZ( ".SolderPaste" ) );
            BIU tmp = biuParse( line + SZ( ".SolderPaste" ) );
            module->SetLocalSolderPasteMargin( tmp );
            aModule->SetLocalSolderPasteMargin( tmp );
        }
        }


        else if( TESTLINE( ".SolderMask" ) )
        else if( TESTLINE( ".SolderMask" ) )
        {
        {
            BIU tmp = biuParse( line + SZ( ".SolderMask" ) );
            BIU tmp = biuParse( line + SZ( ".SolderMask" ) );
            module->SetLocalSolderMaskMargin( tmp );
            aModule->SetLocalSolderMaskMargin( tmp );
        }
        }


        else if( TESTLINE( ".LocalClearance" ) )
        else if( TESTLINE( ".LocalClearance" ) )
        {
        {
            BIU tmp = biuParse( line + SZ( ".LocalClearance" ) );
            BIU tmp = biuParse( line + SZ( ".LocalClearance" ) );
            module->SetLocalClearance( tmp );
            aModule->SetLocalClearance( tmp );
        }
        }


        else if( TESTLINE( ".ZoneConnection" ) )
        else if( TESTLINE( ".ZoneConnection" ) )
        {
        {
            int tmp = intParse( line + SZ( ".ZoneConnection" ) );
            int tmp = intParse( line + SZ( ".ZoneConnection" ) );
            module->SetZoneConnection( (ZoneConnection)tmp );
            aModule->SetZoneConnection( (ZoneConnection)tmp );
        }
        }


        else if( TESTLINE( ".ThermalWidth" ) )
        else if( TESTLINE( ".ThermalWidth" ) )
        {
        {
            BIU tmp = biuParse( line + SZ( ".ThermalWidth" ) );
            BIU tmp = biuParse( line + SZ( ".ThermalWidth" ) );
            module->SetThermalWidth( tmp );
            aModule->SetThermalWidth( tmp );
        }
        }


        else if( TESTLINE( ".ThermalGap" ) )
        else if( TESTLINE( ".ThermalGap" ) )
        {
        {
            BIU tmp = biuParse( line + SZ( ".ThermalGap" ) );
            BIU tmp = biuParse( line + SZ( ".ThermalGap" ) );
            module->SetThermalGap( tmp );
            aModule->SetThermalGap( tmp );
        }
        }


        else if( TESTLINE( "$EndMODULE" ) )
        else if( TESTLINE( "$EndMODULE" ) )
        {
        {
            module->CalculateBoundingBox();
            aModule->CalculateBoundingBox();


            return module.release();     // preferred exit
            return;     // preferred exit
        }
        }
    }
    }


    THROW_IO_ERROR( "Missing '$EndMODULE'" );
    wxString msg = wxString::Format(
                        wxT( "Missing '$EndMODULE' for MODULE '%s'" ),
                        GetChars( aModule->GetLibRef() ) );

    THROW_IO_ERROR( msg );
}
}




@@ -1175,8 +1180,12 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
            case 'O':   padshape = PAD_OVAL;        break;
            case 'O':   padshape = PAD_OVAL;        break;
            case 'T':   padshape = PAD_TRAPEZOID;   break;
            case 'T':   padshape = PAD_TRAPEZOID;   break;
            default:
            default:
                m_error.Printf( _( "Unknown padshape '%s' on line:%d" ),
                m_error.Printf( _( "Unknown padshape '%c=0x%02x' on line:%d of module:'%s'" ),
                    FROM_UTF8( line ).GetData(), m_reader->LineNumber() );
                    (unsigned char) padshape,
                    (unsigned char) padshape,
                    m_reader->LineNumber(),
                    GetChars( aModule->GetLibRef() )
                    );
                THROW_IO_ERROR( m_error );
                THROW_IO_ERROR( m_error );
            }
            }


@@ -1372,8 +1381,12 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
    case 'A':   shape = S_ARC;       break;
    case 'A':   shape = S_ARC;       break;
    case 'P':   shape = S_POLYGON;   break;
    case 'P':   shape = S_POLYGON;   break;
    default:
    default:
        m_error.Printf( wxT( "Unknown EDGE_MODULE type '%s' line %d" ),
        m_error.Printf( wxT( "Unknown EDGE_MODULE type:'%c=0x%02x' on line:%d of module:'%s'" ),
                        FROM_UTF8( line ).GetData(), m_reader->LineNumber() );
                        (unsigned char) line[1],
                        (unsigned char) line[1],
                        m_reader->LineNumber(),
                        GetChars( aModule->GetLibRef() )
                        );
        THROW_IO_ERROR( m_error );
        THROW_IO_ERROR( m_error );
    }
    }


@@ -4036,9 +4049,27 @@ void FPL_CACHE::LoadModules( LINE_READER* aReader )
        // test first for the $MODULE, even before reading because of INDEX bug.
        // test first for the $MODULE, even before reading because of INDEX bug.
        if( TESTLINE( "$MODULE" ) )
        if( TESTLINE( "$MODULE" ) )
        {
        {
            MODULE* m = m_owner->LoadMODULE();
            auto_ptr<MODULE>    module( new MODULE( m_owner->m_board ) );

            std::string         footprintName = StrPurge( line + SZ( "$MODULE" ) );

            // set the footprint name first thing, so exceptions can use name.
            module->SetLibRef( FROM_UTF8( footprintName.c_str() ) );

#if 0 && defined( DEBUG )
            printf( "%s\n", footprintName.c_str() );
            if( footprintName == "QFN40" )
            {
                int breakhere = 1;
                (void) breakhere;
            }
#endif

            m_owner->LoadMODULE( module.get() );

            MODULE* m = module.release();   // exceptions after this are not expected.


            std::string footprintName = TO_UTF8( m->GetLibRef() );
            wxASSERT( footprintName == TO_UTF8( m->GetLibRef() ) );


            /*
            /*


Loading