예제 #1
0
void NETLIST_READER_KICAD_PARSER::Parse( BOARD * aBrd )
    throw( IO_ERROR, PARSE_ERROR )
{
    wxString text;
    while( ( token = NextTok() ) != T_EOF )
    {
        if( token == T_LEFT )
            token = NextTok();
        if( token == T_components )
        {
            // The section comp starts here.
            while( ( token = NextTok() ) != T_RIGHT )
            {
                if( token == T_LEFT )
                    token = NextTok();
                if( token == T_comp )
                {
                    // A comp section if found. Read it
                    COMPONENT_INFO* cmp_info = ParseComp();
                    netlist_reader->AddModuleInfo( cmp_info );
                }
            }
            if( netlist_reader->BuildModuleListOnlyOpt() )
                return; // at this point, the module list is read and built.
            // Load new footprints
            netlist_reader->InitializeModules();
            netlist_reader->TestFootprintsMatchingAndExchange();
        }

        if( token == T_nets )
        {
            // The section nets starts here.
            while( ( token = NextTok() ) != T_RIGHT )
            {
                if( token == T_LEFT )
                    token = NextTok();
                if( token == T_net )
                {
                    // A net section if found. Read it
                    ParseNet( aBrd );
                }
            }
        }

        if( token == T_libparts && netlist_reader->ReadLibpartSectionOpt() )
        {
            // The section libparts starts here.
            while( ( token = NextTok() ) != T_RIGHT )
            {
                if( token == T_LEFT )
                    token = NextTok();
                if( token == T_libpart )
                {
                    // A libpart section if found. Read it
                    ParseKicadLibpartList();
                }
            }
        }
    }
}
예제 #2
0
void PCB_EDIT_FRAME::ReadPcbNetlist( const wxString& aNetlistFileName,
                                     const wxString& aCmpFileName,
                                     REPORTER*       aReporter,
                                     bool            aChangeFootprints,
                                     bool            aDeleteUnconnectedTracks,
                                     bool            aDeleteExtraFootprints,
                                     bool            aSelectByTimeStamp,
                                     bool            aDeleteSinglePadNets,
                                     bool            aIsDryRun )
{
    wxString        msg;
    NETLIST         netlist;
    NETLIST_READER* netlistReader;

    netlist.SetIsDryRun( aIsDryRun );
    netlist.SetFindByTimeStamp( aSelectByTimeStamp );
    netlist.SetDeleteExtraFootprints( aDeleteExtraFootprints );
    netlist.SetReplaceFootprints( aChangeFootprints );

    try
    {
        netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFileName,
                                                          aCmpFileName );

        if( netlistReader == NULL )
        {
            msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFileName ) );
            wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR, this );
            return;
        }

        std::auto_ptr< NETLIST_READER > nlr( netlistReader );
        SetLastNetListRead( aNetlistFileName );
        netlistReader->LoadNetlist();
        loadFootprints( netlist, aReporter );
    }
    catch( const IO_ERROR& ioe )
    {
        msg.Printf( _( "Error loading netlist.\n%s" ), ioe.errorText.GetData() );
        wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
        return;
    }

    // Clear undo and redo lists to avoid inconsistencies between lists
    if( !netlist.IsDryRun() )
        GetScreen()->ClearUndoRedoList();

    netlist.SortByReference();
    GetBoard()->ReplaceNetlist( netlist, aDeleteSinglePadNets, aReporter );

    // If it was a dry run, nothing has changed so we're done.
    if( netlist.IsDryRun() )
        return;

    OnModify();

    SetCurItem( NULL );

    if( aDeleteUnconnectedTracks && GetBoard()->m_Track )
    {
        // Remove erroneous tracks.  This should probably pushed down to the #BOARD object.
        RemoveMisConnectedTracks();
    }

    // Rebuild the board connectivity:
    Compile_Ratsnest( NULL, true );
    SetMsgPanel( GetBoard() );
    m_canvas->Refresh();
}
예제 #3
0
/* Read the section "libparts" like:
 * (libparts
 *   (libpart (lib device) (part C)
 *     (description "Condensateur non polarise")
 *     (footprints
 *       (fp SM*)
 *       (fp C?)
 *       (fp C1-1))
 *     (fields
 *       (field (name Reference) C)
 *       (field (name Value) C))
 *     (pins
 *       (pin (num 1) (name ~) (type passive))
 *       (pin (num 2) (name ~) (type passive))))
 *
 *  And add the strings giving the footprint filter (subsection footprints)
 *  of the corresponding module info
 */
void NETLIST_READER_KICAD_PARSER::ParseKicadLibpartList() throw( IO_ERROR, PARSE_ERROR )
{
   /* Parses a section like
     *   (libpart (lib device) (part C)
     *     (description "Condensateur non polarise")
     *     (footprints
     *       (fp SM*)
     *       (fp C?)
     *       (fp C1-1))
     *     (fields
     *       (field (name Reference) C)
     *       (field (name Value) C))
     *     (pins
     *       (pin (num 1) (name ~) (type passive))
     *       (pin (num 2) (name ~) (type passive))))
     *
     * Currently footprints section/fp are read and data stored
     * other fields (unused) are skipped
     */
    wxString device;
    wxString filter;
    LIPBART_INFO* libpart_info = NULL;

    // The last token read was libpart, so read the next token
    while( (token = NextTok()) != T_RIGHT )
    {
        if( token == T_LEFT )
            token = NextTok();
        switch( token )
        {
        case T_part:
            NeedSYMBOLorNUMBER();
            device = FROM_UTF8( CurText() );
            NeedRIGHT();
            libpart_info = new LIPBART_INFO( device );
            netlist_reader->AddLibpartInfo( libpart_info );
            break;

        case T_footprints:
            // Ensure "(part C)" was already read
            if( libpart_info == NULL )
                Expecting( T_part );
            // Read all fp elements (footprint filter item)
            while( (token = NextTok()) != T_RIGHT )
            {
                if( token == T_LEFT )
                    token = NextTok();
                if( token != T_fp )
                    Expecting( T_fp );
                NeedSYMBOLorNUMBER();
                filter = FROM_UTF8( CurText() );
                NeedRIGHT();
                libpart_info->m_FootprintFilter.Add( filter );
            }
            break;

        default:
            // Skip not used data (i.e all other tokens)
            SkipCurrent();
            break;
        }
    }
}
예제 #4
0
void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )
    throw( IO_ERROR, PARSE_ERROR )
{
    /* Parses a section like
     * (net (code 20) (name /PC-A0)
     *  (node (ref BUS1) (pin 62))
     *  (node (ref U3) (pin 3))
     *  (node (ref U9) (pin M6)))
     */

    wxString code;
    wxString name;
    wxString cmpref;
    wxString pin;
    int nodecount = 0;
    std::vector<D_PAD*> padList;

    // The token net was read, so the next data is (code <number>)
    while( (token = NextTok()) != T_RIGHT )
    {
        if( token == T_LEFT )
            token = NextTok();
        switch( token )
        {
        case T_code:
            NeedSYMBOLorNUMBER();
            code = FROM_UTF8( CurText() );
            NeedRIGHT();
        break;

        case T_name:
            NeedSYMBOLorNUMBER();
            name = FROM_UTF8( CurText() );
            NeedRIGHT();
            if( name.IsEmpty() )      // Give a dummy net name like N-000109
                name = wxT("N-00000") + code;
            break;

        case T_node:
            while( (token = NextTok()) != T_RIGHT )
            {
                if( token == T_LEFT )
                    token = NextTok();
                switch( token )
                {
                case T_ref:
                    NeedSYMBOLorNUMBER();
                    cmpref = FROM_UTF8( CurText() );
                    NeedRIGHT();
                    break;

                case T_pin:
                    NeedSYMBOLorNUMBER();
                    pin = FROM_UTF8( CurText() );
                    NeedRIGHT();
                    break;

                default:
                    SkipCurrent();
                    break;
                }
            }
            netlist_reader->SetPadsNetName( cmpref, pin, name, padList );
            nodecount++;
            break;

        default:
            SkipCurrent();
            break;
        }
    }

    // When there is only one item in net, clear pad netname
    // Remember one can have more than one pad in list, because a footprint
    // can have many pads with the same pad name
    if( nodecount < 2 )
        for( unsigned ii = 0; ii < padList.size(); ii++ )
            padList[ii]->SetNetname( wxEmptyString );
}
bool DIALOG_NETLIST::verifyFootprints( const wxString&         aNetlistFilename,
                                       const wxString &        aCmpFilename,
                                       std::vector< MODULE* >& aDuplicates,
                                       wxArrayString&          aMissing,
                                       std::vector< MODULE* >& aNotInNetlist )
{
    wxString        msg;
    MODULE*         module;
    MODULE*         nextModule;
    NETLIST         netlist;
    wxBusyCursor    dummy;           // Shows an hourglass while calculating.
    NETLIST_READER* netlistReader;
    COMPONENT*      component;

    try
    {
        netlistReader = NETLIST_READER::GetNetlistReader( &netlist, aNetlistFilename,
                        aCmpFilename );

        if( netlistReader == NULL )
        {
            msg.Printf( _( "Cannot open netlist file \"%s\"." ), GetChars( aNetlistFilename ) );
            wxMessageBox( msg, _( "Netlist Load Error." ), wxOK | wxICON_ERROR );
            return false;
        }

        std::auto_ptr< NETLIST_READER > nlr( netlistReader );
        netlistReader->LoadNetlist();
    }
    catch( const IO_ERROR& ioe )
    {
        msg.Printf( _( "Error loading netlist file:\n%s" ), ioe.errorText.GetData() );
        wxMessageBox( msg, _( "Netlist Load Error" ), wxOK | wxICON_ERROR );
        return false;
    }

    BOARD* pcb = m_parent->GetBoard();

    // Search for duplicate footprints.
    module = pcb->m_Modules;

    for( ; module != NULL; module = module->Next() )
    {
        nextModule = module->Next();

        for( ; nextModule != NULL; nextModule = nextModule->Next() )
        {
            if( module->GetReference().CmpNoCase( nextModule->GetReference() ) == 0 )
            {
                aDuplicates.push_back( module );
                break;
            }
        }
    }

    // Search for component footprints in the netlist but not on the board.
    for( unsigned ii = 0; ii < netlist.GetCount(); ii++ )
    {
        component = netlist.GetComponent( ii );

        module = pcb->FindModuleByReference( component->GetReference() );

        if( module == NULL )
        {
            aMissing.Add( component->GetReference() );
            aMissing.Add( component->GetValue() );
        }
    }

    // Search for component footprints found on board but not in netlist.
    module = pcb->m_Modules;

    for( ; module != NULL; module = module->Next() )
    {

        component = netlist.GetComponentByReference( module->GetReference() );

        if( component == NULL )
            aNotInNetlist.push_back( module );
    }

    return true;
}