Пример #1
0
bool KICADPCB::parseGeneral( SEXPR::SEXPR* data )
{
    size_t nc = data->GetNumberOfChildren();
    SEXPR::SEXPR* child = NULL;

    for( size_t i = 1; i < nc; ++i )
    {
        child = data->GetChild( i );

        if( !child->IsList() )
        {
            std::ostringstream ostr;
            ostr << "* corrupt PCB file: '" << m_filename << "'\n";
            wxLogMessage( "%s\n", ostr.str().c_str() );
            return false;
        }

        // at the moment only the thickness is of interest in
        // the general section
        if( child->GetChild( 0 )->GetSymbol() != "thickness" )
            continue;

        m_thickness = child->GetChild( 1 )->GetDouble();
        return true;
    }

    std::ostringstream ostr;
    ostr << "* corrupt PCB file: '" << m_filename << "'\n";
    ostr << "* no PCB thickness specified in general section\n";
    wxLogMessage( "%s\n", ostr.str().c_str() );

    return false;
}
Пример #2
0
bool KICADPCB::parsePCB( SEXPR::SEXPR* data )
{
    if( NULL == data )
        return false;

    if( data->IsList() )
    {
        size_t nc = data->GetNumberOfChildren();
        SEXPR::SEXPR* child = data->GetChild( 0 );
        std::string name = child->GetSymbol();

        if( name != "kicad_pcb" )
        {
            std::ostringstream ostr;
            ostr << "* data is not a valid PCB file: '" << m_filename << "'\n";
            wxLogMessage( "%s\n", ostr.str().c_str() );
            return false;
        }

        bool result = true;

        for( size_t i = 1; i < nc && result; ++i )
        {
            child = data->GetChild( i );

            if( !child->IsList() )
            {
                std::ostringstream ostr;
                ostr << "* corrupt PCB file: '" << m_filename << "'\n";
                wxLogMessage( "%s\n", ostr.str().c_str() );
                return false;
            }

            std::string symname( child->GetChild( 0 )->GetSymbol() );

            if( symname == "general" )
                result = result && parseGeneral( child );
            else if( symname == "module" )
                result = result && parseModule( child );
            else if( symname == "gr_arc" )
                result = result && parseCurve( child, CURVE_ARC );
            else if( symname == "gr_line" )
                result = result && parseCurve( child, CURVE_LINE );
            else if( symname == "gr_circle" )
                result = result && parseCurve( child, CURVE_CIRCLE );
        }

        return result;
    }

    std::ostringstream ostr;
    ostr << "* data is not a valid PCB file: '" << m_filename << "'\n";
    wxLogMessage( "%s\n", ostr.str().c_str() );

    return false;
}
Пример #3
0
bool KICADMODULE::parseText( SEXPR::SEXPR* data )
{
    // we're only interested in the Reference Designator
    if( data->GetNumberOfChildren() < 3 )
        return true;

    SEXPR::SEXPR* child = data->GetChild( 1 );
    std::string text;

    if( child->IsSymbol() )
        text = child->GetSymbol();
    else if( child->IsString() )
        text = child->GetString();

    if( text != "reference" )
        return true;

    child = data->GetChild( 2 );

    if( child->IsSymbol() )
        text = child->GetSymbol();
    else if( child->IsString() )
        text = child->GetString();

    m_refdes = text;
    return true;
}
bool KICADMODEL::Read( SEXPR::SEXPR* aEntry )
{
    // form: ( pad N thru_hole shape (at x y {r}) (size x y) (drill {oval} x {y}) (layers X X X) )
    int nchild = aEntry->GetNumberOfChildren();

    if( nchild < 2 )
    {
        std::ostringstream ostr;
        ostr << "* invalid model entry";
        wxLogMessage( "%s\n", ostr.str().c_str() );
        return false;
    }

    SEXPR::SEXPR* child = aEntry->GetChild( 1 );

    if( child->IsSymbol() )
        m_modelname = child->GetSymbol();
    else if( child->IsString() )
        m_modelname = child->GetString();
    else
    {
        std::ostringstream ostr;
        ostr << "* invalid model entry; invalid path";
        wxLogMessage( "%s\n", ostr.str().c_str() );
        return false;
    }

    for( int i = 2; i < nchild; ++i )
    {
        child = aEntry->GetChild( i );

        if( !child->IsList() )
            continue;

        std::string name = child->GetChild( 0 )->GetSymbol();
        bool ret = true;

        if( name == "at" )
            ret = Get3DCoordinate( child->GetChild( 1 ), m_offset );
        else if( name == "scale" )
            ret = Get3DCoordinate( child->GetChild( 1 ), m_scale );
        else if( name == "rotate" )
            ret = GetXYZRotation( child->GetChild( 1 ), m_rotation );

        if( !ret )
            return false;
    }

    return true;
}
Пример #5
0
bool KICADMODULE::parseLayer( SEXPR::SEXPR* data )
{
    SEXPR::SEXPR* val = data->GetChild( 1 );
    std::string layer;

    if( val->IsSymbol() )
        layer = val->GetSymbol();
    else if( val->IsString() )
        layer = val->GetString();
    else
    {
        std::ostringstream ostr;
        ostr << "* corrupt module in PCB file; layer cannot be parsed\n";
        wxLogMessage( "%s\n", ostr.str().c_str() );
        return false;
    }

    if( layer == "F.Cu" )
        m_side = LAYER_TOP;
    else if( layer == "B.Cu" )
        m_side = LAYER_BOTTOM;

    return true;
}
Пример #6
0
bool KICADPAD::Read( SEXPR::SEXPR* aEntry )
{
    // form: ( pad N thru_hole shape (at x y {r}) (size x y) (drill {oval} x {y}) (layers X X X) )
    int nchild = aEntry->GetNumberOfChildren();

    if( nchild < 2 )
    {
        std::ostringstream ostr;
        ostr << bad_pad;
        wxLogMessage( "%s\n", ostr.str().c_str() );
        return false;
    }

    SEXPR::SEXPR* child;

    for( int i = 1; i < nchild; ++i )
    {
        child = aEntry->GetChild( i );

        if( child->IsSymbol() &&
            ( child->GetSymbol() == "thru_hole" || child->GetSymbol() == "np_thru_hole" ) )
        {
            m_thruhole = true;
            continue;
        }

        if( child->IsList() )
        {
            std::string name = child->GetChild( 0 )->GetSymbol();
            bool ret = true;

            if( name == "drill" )
            {
                // ignore any drill info for SMD pads
                if( m_thruhole )
                    ret = parseDrill( child );
            }
            else if( name == "at" )
            {
                ret = Get2DPositionAndRotation( child, m_position, m_rotation );
            }

            if( !ret )
                return false;
        }
    }

    return true;
}
Пример #7
0
bool KICADPAD::parseDrill( SEXPR::SEXPR* aDrill )
{
    // form: (drill {oval} X {Y})
    const char bad_drill[] = "* corrupt module in PCB file; bad drill";
    int nchild = aDrill->GetNumberOfChildren();

    if( nchild < 2 )
    {
        std::ostringstream ostr;
        ostr << bad_drill;
        wxLogMessage( "%s\n", ostr.str().c_str() );
        return false;
    }

    SEXPR::SEXPR* child = aDrill->GetChild( 1 );
    int idx = 1;
    m_drill.oval = false;

    if( child->IsSymbol() )
    {
        if( child->GetSymbol() == "oval" && nchild >= 4 )
        {
            m_drill.oval = true;
            child = aDrill->GetChild( ++idx );
        }
        else
        {
            std::ostringstream ostr;
            ostr << bad_drill << " (unexpected symbol: ";
            ostr << child->GetSymbol() << "), nchild = " << nchild;
            wxLogMessage( "%s\n", ostr.str().c_str() );
            return false;
        }
    }

    double x;

    if( child->IsDouble() )
        x = child->GetDouble();
    else if( child->IsInteger() )
        x = (double) child->GetInteger();
    else
    {
        std::ostringstream ostr;
        ostr << bad_drill << " (did not find X size)";
        wxLogMessage( "%s\n", ostr.str().c_str() );
        return false;
    }

    m_drill.size.x = x;
    m_drill.size.y = x;

    if( ++idx == nchild || !m_drill.oval )
        return true;

    for( int i = idx; i < nchild; ++i )
    {
        child = aDrill->GetChild( i );

        // NOTE: the Offset of the copper pad is stored
        // in the drill string but since the copper is not
        // needed in the MCAD model the Offset is simply ignored.
        if( !child->IsList() )
        {
            double y;

            if( child->IsDouble() )
                y = child->GetDouble();
            else if( child->IsInteger() )
                y = (double) child->GetInteger();
            else
            {
                std::ostringstream ostr;
                ostr << bad_drill << " (did not find Y size)";
                wxLogMessage( "%s\n", ostr.str().c_str() );
                return false;
            }

            m_drill.size.y = y;
        }
    }

    return true;
}
Пример #8
0
bool KICADMODULE::Read( SEXPR::SEXPR* aEntry )
{
    if( NULL == aEntry )
        return false;

    if( aEntry->IsList() )
    {
        size_t nc = aEntry->GetNumberOfChildren();
        SEXPR::SEXPR* child = aEntry->GetChild( 0 );
        std::string name = child->GetSymbol();

        if( name != "module" )
        {
            std::ostringstream ostr;
            ostr << "* BUG: module parser invoked for type '" << name << "'\n";
            wxLogMessage( "%s\n", ostr.str().c_str() );
            return false;
        }

        bool result = true;

        for( size_t i = 1; i < nc && result; ++i )
        {
            child = aEntry->GetChild( i );

            // skip the module name and the optional 'locked' attribute;
            // due to the vagaries of the kicad version of sexpr, the
            // name may be a Symbol or a String
            if( i <= 2 && ( child->IsSymbol() || child->IsString() ) )
                continue;

            if( !child->IsList() )
            {
                std::ostringstream ostr;
                ostr << "* corrupt module in PCB file\n";
                wxLogMessage( "%s\n", ostr.str().c_str() );
                return false;
            }

            std::string symname( child->GetChild( 0 )->GetSymbol() );

            if( symname == "layer" )
                result = result && parseLayer( child );
            else if( symname == "at" )
                result = result && parsePosition( child );
            else if( symname == "fp_text" )
                result = result && parseText( child );
            else if( symname == "fp_arc" )
                result = result && parseCurve( child, CURVE_ARC );
            else if( symname == "fp_line" )
                result = result && parseCurve( child, CURVE_LINE );
            else if( symname == "fp_circle" )
                result = result && parseCurve( child, CURVE_CIRCLE );
            else if( symname == "pad" )
                result = result && parsePad( child );
            else if( symname == "model" )
                result = result && parseModel( child );
        }

        return result;
    }

    std::ostringstream ostr;
    ostr << "* data is not a valid PCB module\n";
    wxLogMessage( "%s\n", ostr.str().c_str() );

    return false;
}