ADDED: DRC JSON report
This commit is contained in:
parent
64a7bad56e
commit
14a0fa435c
|
@ -266,7 +266,7 @@ void NOTIFICATIONS_MANAGER::Load()
|
|||
{
|
||||
nlohmann::json saved_json;
|
||||
|
||||
std::ifstream saved_json_stream( m_destFileName.GetFullPath().ToUTF8() );
|
||||
std::ifstream saved_json_stream( m_destFileName.GetFullPath().fn_str() );
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -289,7 +289,7 @@ void NOTIFICATIONS_MANAGER::Load()
|
|||
|
||||
void NOTIFICATIONS_MANAGER::Save()
|
||||
{
|
||||
std::ofstream jsonFileStream( m_destFileName.GetFullPath().ToUTF8() );
|
||||
std::ofstream jsonFileStream( m_destFileName.GetFullPath().fn_str() );
|
||||
|
||||
nlohmann::json saveJson = nlohmann::json( m_notifications );
|
||||
jsonFileStream << std::setw( 4 ) << saveJson << std::endl;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <marker_base.h>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <rc_item.h>
|
||||
#include <rc_json_schema.h>
|
||||
#include <eda_item.h>
|
||||
#include <base_units.h>
|
||||
|
||||
|
@ -76,22 +77,30 @@ void RC_ITEM::SetItems( const EDA_ITEM* aItem, const EDA_ITEM* bItem,
|
|||
}
|
||||
|
||||
|
||||
wxString RC_ITEM::ShowReport( UNITS_PROVIDER* aUnitsProvider, SEVERITY aSeverity,
|
||||
const std::map<KIID, EDA_ITEM*>& aItemMap ) const
|
||||
wxString getSeverityString( SEVERITY aSeverity )
|
||||
{
|
||||
wxString severity;
|
||||
|
||||
switch( aSeverity )
|
||||
{
|
||||
case RPT_SEVERITY_ERROR: severity = wxT( "Severity: error" ); break;
|
||||
case RPT_SEVERITY_WARNING: severity = wxT( "Severity: warning" ); break;
|
||||
case RPT_SEVERITY_ACTION: severity = wxT( "Severity: action" ); break;
|
||||
case RPT_SEVERITY_INFO: severity = wxT( "Severity: info" ); break;
|
||||
case RPT_SEVERITY_EXCLUSION: severity = wxT( "Severity: exclusion" ); break;
|
||||
case RPT_SEVERITY_DEBUG: severity = wxT( "Severity: debug" ); break;
|
||||
case RPT_SEVERITY_ERROR: severity = wxS( "error" ); break;
|
||||
case RPT_SEVERITY_WARNING: severity = wxS( "warning" ); break;
|
||||
case RPT_SEVERITY_ACTION: severity = wxS( "action" ); break;
|
||||
case RPT_SEVERITY_INFO: severity = wxS( "info" ); break;
|
||||
case RPT_SEVERITY_EXCLUSION: severity = wxS( "exclusion" ); break;
|
||||
case RPT_SEVERITY_DEBUG: severity = wxS( "debug" ); break;
|
||||
default:;
|
||||
};
|
||||
|
||||
return severity;
|
||||
}
|
||||
|
||||
|
||||
wxString RC_ITEM::ShowReport( UNITS_PROVIDER* aUnitsProvider, SEVERITY aSeverity,
|
||||
const std::map<KIID, EDA_ITEM*>& aItemMap ) const
|
||||
{
|
||||
wxString severity = getSeverityString( aSeverity );
|
||||
|
||||
if( m_parent && m_parent->IsExcluded() )
|
||||
severity += wxT( " (excluded)" );
|
||||
|
||||
|
@ -146,6 +155,59 @@ wxString RC_ITEM::ShowReport( UNITS_PROVIDER* aUnitsProvider, SEVERITY aSeverity
|
|||
}
|
||||
|
||||
|
||||
void RC_ITEM::GetJsonViolation( RC_JSON::VIOLATION& aViolation, UNITS_PROVIDER* aUnitsProvider,
|
||||
SEVERITY aSeverity,
|
||||
const std::map<KIID, EDA_ITEM*>& aItemMap ) const
|
||||
{
|
||||
wxString severity = getSeverityString( aSeverity );
|
||||
|
||||
aViolation.severity = severity;
|
||||
aViolation.description = GetViolatingRuleDesc();
|
||||
aViolation.type = GetSettingsKey();
|
||||
|
||||
EDA_ITEM* mainItem = nullptr;
|
||||
EDA_ITEM* auxItem = nullptr;
|
||||
|
||||
auto ii = aItemMap.find( GetMainItemID() );
|
||||
|
||||
if( ii != aItemMap.end() )
|
||||
mainItem = ii->second;
|
||||
|
||||
ii = aItemMap.find( GetAuxItemID() );
|
||||
|
||||
if( ii != aItemMap.end() )
|
||||
auxItem = ii->second;
|
||||
|
||||
if( mainItem )
|
||||
{
|
||||
RC_JSON::AFFECTED_ITEM item;
|
||||
item.description = mainItem->GetItemDescription( aUnitsProvider );
|
||||
item.uuid = mainItem->m_Uuid.AsString();
|
||||
item.pos.x = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
|
||||
aUnitsProvider->GetUserUnits(),
|
||||
mainItem->GetPosition().x );
|
||||
item.pos.y = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
|
||||
aUnitsProvider->GetUserUnits(),
|
||||
mainItem->GetPosition().y );
|
||||
aViolation.items.emplace_back( item );
|
||||
}
|
||||
|
||||
if( auxItem )
|
||||
{
|
||||
RC_JSON::AFFECTED_ITEM item;
|
||||
item.description = auxItem->GetItemDescription( aUnitsProvider );
|
||||
item.uuid = auxItem->m_Uuid.AsString();
|
||||
item.pos.x = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
|
||||
aUnitsProvider->GetUserUnits(),
|
||||
auxItem->GetPosition().x );
|
||||
item.pos.y = EDA_UNIT_UTILS::UI::ToUserUnit( aUnitsProvider->GetIuScale(),
|
||||
aUnitsProvider->GetUserUnits(),
|
||||
auxItem->GetPosition().y );
|
||||
aViolation.items.emplace_back( item );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KIID RC_TREE_MODEL::ToUUID( wxDataViewItem aItem )
|
||||
{
|
||||
const RC_TREE_NODE* node = RC_TREE_MODEL::ToNode( aItem );
|
||||
|
|
|
@ -190,6 +190,7 @@ const std::string TextFileExtension( "txt" );
|
|||
const std::string MarkdownFileExtension( "md" );
|
||||
const std::string CsvFileExtension( "csv" );
|
||||
const std::string XmlFileExtension( "xml" );
|
||||
const std::string JsonFileExtension( "json" );
|
||||
|
||||
const wxString GerberFileExtensionsRegex( "(gbr|gko|pho|(g[tb][alops])|(gm?\\d\\d*)|(gp[tb]))" );
|
||||
|
||||
|
|
|
@ -36,6 +36,10 @@ class RC_ITEM;
|
|||
class EDA_ITEM;
|
||||
class EDA_DRAW_FRAME;
|
||||
|
||||
namespace RC_JSON
|
||||
{
|
||||
struct VIOLATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an abstract interface of a RC_ITEM* list manager.
|
||||
|
@ -133,6 +137,19 @@ public:
|
|||
virtual wxString ShowReport( UNITS_PROVIDER* aUnitsProvider, SEVERITY aSeverity,
|
||||
const std::map<KIID, EDA_ITEM*>& aItemMap ) const;
|
||||
|
||||
/**
|
||||
* Translate this object into an RC_JSON::VIOLATION object
|
||||
*
|
||||
* @param aViolation is the violation to be populated by info from this item
|
||||
* @param aUnitsProvider is the units provider that will be used to output coordinates
|
||||
* @param aSeverity is the severity of this item
|
||||
* @param aItemMap is a map allowing the lookup of items from KIIDs
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
virtual void GetJsonViolation( RC_JSON::VIOLATION& aViolation, UNITS_PROVIDER* aUnitsProvider,
|
||||
SEVERITY aSeverity, const std::map<KIID, EDA_ITEM*>& aItemMap ) const;
|
||||
|
||||
int GetErrorCode() const { return m_errorCode; }
|
||||
void SetErrorCode( int aCode ) { m_errorCode = aCode; }
|
||||
|
||||
|
@ -274,6 +291,7 @@ public:
|
|||
protected:
|
||||
void rebuildModel( std::shared_ptr<RC_ITEMS_PROVIDER> aProvider, int aSeverities );
|
||||
void onSizeView( wxSizeEvent& aEvent );
|
||||
wxString getSeverityString( SEVERITY aSeverity );
|
||||
|
||||
EDA_DRAW_FRAME* m_editFrame;
|
||||
wxDataViewCtrl* m_view;
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RC_JSON_SCHEMA_H
|
||||
#define RC_JSON_SCHEMA_H
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <wx/string.h>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Contains the json serialization structs for DRC and ERC reports
|
||||
* If you are trying to change the output schema
|
||||
* Please update the schemas located in /resources/schemas/ as both documentation
|
||||
* and use by end user implementations
|
||||
*/
|
||||
namespace RC_JSON
|
||||
{
|
||||
struct COORDINATE
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( COORDINATE, x, y )
|
||||
|
||||
struct AFFECTED_ITEM
|
||||
{
|
||||
wxString uuid;
|
||||
wxString description;
|
||||
COORDINATE pos;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( AFFECTED_ITEM, uuid, description, pos )
|
||||
|
||||
struct VIOLATION
|
||||
{
|
||||
wxString type;
|
||||
wxString description;
|
||||
wxString severity;
|
||||
std::vector<AFFECTED_ITEM> items;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( VIOLATION, type, description, severity, items )
|
||||
|
||||
struct REPORT_BASE
|
||||
{
|
||||
wxString source;
|
||||
wxString date;
|
||||
wxString kicad_version;
|
||||
wxString type;
|
||||
wxString coordinate_units;
|
||||
};
|
||||
|
||||
struct DRC_REPORT : REPORT_BASE
|
||||
{
|
||||
DRC_REPORT() { type = wxS( "drc" ); }
|
||||
|
||||
std::vector<VIOLATION> violations;
|
||||
std::vector<VIOLATION> unconnected_items;
|
||||
std::vector<VIOLATION> schematic_parity;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( DRC_REPORT, source, date, kicad_version, violations,
|
||||
unconnected_items, schematic_parity, coordinate_units )
|
||||
|
||||
struct ERC_SHEET
|
||||
{
|
||||
wxString uuid;
|
||||
wxString path;
|
||||
std::vector<VIOLATION> violations;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( ERC_SHEET, uuid, path, violations )
|
||||
|
||||
struct ERC_REPORT : REPORT_BASE
|
||||
{
|
||||
ERC_REPORT() { type = wxS( "erc" ); }
|
||||
|
||||
std::vector<ERC_SHEET> sheets;
|
||||
};
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE( ERC_REPORT, source, date, kicad_version, sheets,
|
||||
coordinate_units )
|
||||
|
||||
} // namespace RC_JSON
|
||||
|
||||
#endif
|
|
@ -176,6 +176,7 @@ extern const std::string TextFileExtension;
|
|||
extern const std::string MarkdownFileExtension;
|
||||
extern const std::string CsvFileExtension;
|
||||
extern const std::string XmlFileExtension;
|
||||
extern const std::string JsonFileExtension;
|
||||
|
||||
extern const wxString GerberFileExtensionsRegex;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ CLI::PCB_DRC_COMMAND::PCB_DRC_COMMAND() : EXPORT_PCB_BASE_COMMAND( "drc" )
|
|||
{
|
||||
m_argParser.add_argument( ARG_FORMAT )
|
||||
.default_value( std::string( "report" ) )
|
||||
.help( UTF8STDSTR( _( "Output file format, options: report" ) ) );
|
||||
.help( UTF8STDSTR( _( "Output file format, options: json, report" ) ) );
|
||||
|
||||
m_argParser.add_argument( ARG_ALL_TRACK_ERRORS )
|
||||
.help( UTF8STDSTR( _( "Report all errors for each track" ) ) )
|
||||
|
@ -140,6 +140,10 @@ int CLI::PCB_DRC_COMMAND::doPerform( KIWAY& aKiway )
|
|||
{
|
||||
drcJob->m_format = JOB_PCB_DRC::OUTPUT_FORMAT::REPORT;
|
||||
}
|
||||
else if( format == "json" )
|
||||
{
|
||||
drcJob->m_format = JOB_PCB_DRC::OUTPUT_FORMAT::JSON;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFprintf( stderr, _( "Invalid report format\n" ) );
|
||||
|
|
|
@ -233,6 +233,7 @@ set( PCBNEW_MICROWAVE_SRCS
|
|||
|
||||
set( PCBNEW_DRC_SRCS
|
||||
drc/drc_interactive_courtyard_clearance.cpp
|
||||
drc/drc_report.cpp
|
||||
drc/drc_test_provider.cpp
|
||||
drc/drc_test_provider_annular_width.cpp
|
||||
drc/drc_test_provider_disallow.cpp
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <macros.h>
|
||||
#include <pad.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_report.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
#include <connectivity/connectivity_algo.h>
|
||||
#include <drawing_sheet/ds_proxy_view_item.h>
|
||||
|
@ -869,7 +870,10 @@ void DIALOG_DRC::OnSaveReport( wxCommandEvent& aEvent )
|
|||
fn.MakeAbsolute( prj_path );
|
||||
}
|
||||
|
||||
if( DRC_TOOL::WriteReport( fn.GetFullPath(), m_frame->GetBoard(), GetUserUnits(), m_markersProvider, m_ratsnestProvider, m_fpWarningsProvider ) )
|
||||
DRC_REPORT reportWriter( m_frame->GetBoard(), GetUserUnits(), m_markersProvider,
|
||||
m_ratsnestProvider, m_fpWarningsProvider );
|
||||
|
||||
if( reportWriter.WriteJsonReport( fn.GetFullPath() ) )
|
||||
{
|
||||
m_messages->Report( wxString::Format( _( "Report file '%s' created<br>" ),
|
||||
fn.GetFullPath() ) );
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <build_version.h>
|
||||
#include "drc_report.h"
|
||||
#include <drc/drc_item.h>
|
||||
#include <fstream>
|
||||
#include <macros.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <rc_json_schema.h>
|
||||
|
||||
|
||||
DRC_REPORT::DRC_REPORT(BOARD* aBoard, EDA_UNITS aReportUnits,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider) :
|
||||
m_board( aBoard ),
|
||||
m_reportUnits( aReportUnits ),
|
||||
m_markersProvider( aMarkersProvider ),
|
||||
m_ratsnestProvider( aRatsnestProvider ),
|
||||
m_fpWarningsProvider( aFpWarningsProvider )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool DRC_REPORT::WriteTextReport( const wxString& aFullFileName )
|
||||
{
|
||||
FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
|
||||
|
||||
if( fp == nullptr )
|
||||
return false;
|
||||
|
||||
std::map<KIID, EDA_ITEM*> itemMap;
|
||||
m_board->FillItemMap( itemMap );
|
||||
|
||||
UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits );
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
int count;
|
||||
|
||||
fprintf( fp, "** Drc report for %s **\n", TO_UTF8( m_board->GetFileName() ) );
|
||||
|
||||
fprintf( fp, "** Created on %s **\n", TO_UTF8( GetISO8601CurrentDateTime() ) );
|
||||
|
||||
count = m_markersProvider->GetCount();
|
||||
|
||||
fprintf( fp, "\n** Found %d DRC violations **\n", count );
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
|
||||
SEVERITY severity = item->GetParent()->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
|
||||
}
|
||||
|
||||
count = m_ratsnestProvider->GetCount();
|
||||
|
||||
fprintf( fp, "\n** Found %d unconnected pads **\n", count );
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
|
||||
}
|
||||
|
||||
count = m_fpWarningsProvider->GetCount();
|
||||
|
||||
fprintf( fp, "\n** Found %d Footprint errors **\n", count );
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
|
||||
}
|
||||
|
||||
|
||||
fprintf( fp, "\n** End of Report **\n" );
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DRC_REPORT::WriteJsonReport( const wxString& aFullFileName )
|
||||
{
|
||||
std::ofstream jsonFileStream( aFullFileName.fn_str() );
|
||||
|
||||
UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits );
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
std::map<KIID, EDA_ITEM*> itemMap;
|
||||
m_board->FillItemMap( itemMap );
|
||||
|
||||
RC_JSON::DRC_REPORT reportHead;
|
||||
reportHead.source = m_board->GetFileName();
|
||||
reportHead.date = GetISO8601CurrentDateTime();
|
||||
reportHead.kicad_version = GetMajorMinorPatchVersion();
|
||||
reportHead.coordinate_units = EDA_UNIT_UTILS::GetLabel( m_reportUnits );
|
||||
|
||||
for( int i = 0; i < m_markersProvider->GetCount(); ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
|
||||
SEVERITY severity = item->GetParent()->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
RC_JSON::VIOLATION violation;
|
||||
item->GetJsonViolation( violation, &unitsProvider, severity, itemMap );
|
||||
|
||||
reportHead.violations.push_back( violation );
|
||||
}
|
||||
|
||||
for( int i = 0; i < m_ratsnestProvider->GetCount(); ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
RC_JSON::VIOLATION violation;
|
||||
item->GetJsonViolation( violation, &unitsProvider, severity, itemMap );
|
||||
|
||||
reportHead.unconnected_items.push_back( violation );
|
||||
}
|
||||
|
||||
|
||||
for( int i = 0; i < m_fpWarningsProvider->GetCount(); ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
RC_JSON::VIOLATION violation;
|
||||
item->GetJsonViolation( violation, &unitsProvider, severity, itemMap );
|
||||
|
||||
reportHead.schematic_parity.push_back( violation );
|
||||
}
|
||||
|
||||
|
||||
nlohmann::json saveJson = nlohmann::json( reportHead );
|
||||
jsonFileStream << std::setw( 4 ) << saveJson << std::endl;
|
||||
jsonFileStream.flush();
|
||||
jsonFileStream.close();
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DRC_REPORT_H
|
||||
#define DRC_REPORT_H
|
||||
|
||||
#include <memory>
|
||||
#include <eda_units.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
class BOARD;
|
||||
class RC_ITEMS_PROVIDER;
|
||||
|
||||
class DRC_REPORT
|
||||
{
|
||||
public:
|
||||
DRC_REPORT( BOARD* aBoard,
|
||||
EDA_UNITS aReportUnits,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider );
|
||||
|
||||
bool WriteTextReport( const wxString& aFullFileName );
|
||||
bool WriteJsonReport( const wxString& aFullFileName );
|
||||
|
||||
private:
|
||||
BOARD* m_board;
|
||||
EDA_UNITS m_reportUnits;
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> m_markersProvider;
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> m_ratsnestProvider;
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> m_fpWarningsProvider;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -23,6 +23,7 @@
|
|||
#include <board_commit.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <drc/drc_report.h>
|
||||
#include <drawing_sheet/ds_proxy_view_item.h>
|
||||
#include <jobs/job_fp_export_svg.h>
|
||||
#include <jobs/job_fp_upgrade.h>
|
||||
|
@ -866,6 +867,10 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob )
|
|||
{
|
||||
wxFileName fn = brd->GetFileName();
|
||||
fn.SetName( fn.GetName() );
|
||||
|
||||
if( drcJob->m_format == JOB_PCB_DRC::OUTPUT_FORMAT::JSON )
|
||||
fn.SetExt( JsonFileExtension );
|
||||
else
|
||||
fn.SetExt( ReportFileExtension );
|
||||
|
||||
drcJob->m_outputFile = fn.GetFullName();
|
||||
|
@ -922,8 +927,23 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob )
|
|||
ratsnestProvider->SetSeverities( drcJob->m_severity );
|
||||
fpWarningsProvider->SetSeverities( drcJob->m_severity );
|
||||
|
||||
bool wroteReport = DRC_TOOL::WriteReport( drcJob->m_outputFile, brd, units, markersProvider,
|
||||
ratsnestProvider, fpWarningsProvider );
|
||||
m_reporter->Report(
|
||||
wxString::Format( _( "Found %d violations\n" ), markersProvider->GetCount() ),
|
||||
RPT_SEVERITY_INFO );
|
||||
m_reporter->Report(
|
||||
wxString::Format( _( "Found %d unconnected items\n" ), ratsnestProvider->GetCount() ),
|
||||
RPT_SEVERITY_INFO );
|
||||
m_reporter->Report( wxString::Format( _( "Found %d schematic parity issues\n" ),
|
||||
fpWarningsProvider->GetCount() ),
|
||||
RPT_SEVERITY_INFO );
|
||||
|
||||
DRC_REPORT reportWriter( brd, units, markersProvider, ratsnestProvider, fpWarningsProvider );
|
||||
|
||||
bool wroteReport = false;
|
||||
if( drcJob->m_format == JOB_PCB_DRC::OUTPUT_FORMAT::JSON )
|
||||
wroteReport = reportWriter.WriteJsonReport( drcJob->m_outputFile );
|
||||
else
|
||||
wroteReport = reportWriter.WriteTextReport( drcJob->m_outputFile );
|
||||
|
||||
if( !wroteReport )
|
||||
{
|
||||
|
|
|
@ -295,76 +295,3 @@ void DRC_TOOL::setTransitions()
|
|||
Go( &DRC_TOOL::CrossProbe, EVENTS::PointSelectedEvent );
|
||||
Go( &DRC_TOOL::CrossProbe, EVENTS::SelectedEvent );
|
||||
}
|
||||
|
||||
|
||||
bool DRC_TOOL::WriteReport( const wxString& aFullFileName,
|
||||
BOARD* aBoard,
|
||||
EDA_UNITS aReportUnits,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider )
|
||||
{
|
||||
FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
|
||||
|
||||
if( fp == nullptr )
|
||||
return false;
|
||||
|
||||
std::map<KIID, EDA_ITEM*> itemMap;
|
||||
aBoard->FillItemMap( itemMap );
|
||||
|
||||
BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
|
||||
UNITS_PROVIDER unitsProvider( pcbIUScale, aReportUnits );
|
||||
int count;
|
||||
|
||||
fprintf( fp, "** Drc report for %s **\n", TO_UTF8( aBoard->GetFileName() ) );
|
||||
|
||||
wxDateTime now = wxDateTime::Now();
|
||||
|
||||
fprintf( fp, "** Created on %s **\n", TO_UTF8( now.Format( wxT( "%F %T" ) ) ) );
|
||||
|
||||
count = aMarkersProvider->GetCount();
|
||||
|
||||
fprintf( fp, "\n** Found %d DRC violations **\n", count );
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = aMarkersProvider->GetItem( i );
|
||||
SEVERITY severity = item->GetParent()->GetSeverity();
|
||||
|
||||
if( severity == RPT_SEVERITY_EXCLUSION )
|
||||
severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
|
||||
}
|
||||
|
||||
count = aRatsnestProvider->GetCount();
|
||||
|
||||
fprintf( fp, "\n** Found %d unconnected pads **\n", count );
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = aRatsnestProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
|
||||
}
|
||||
|
||||
count = aFpWarningsProvider->GetCount();
|
||||
|
||||
fprintf( fp, "\n** Found %d Footprint errors **\n", count );
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
const std::shared_ptr<RC_ITEM>& item = aFpWarningsProvider->GetItem( i );
|
||||
SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
|
||||
|
||||
fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemMap ) ) );
|
||||
}
|
||||
|
||||
|
||||
fprintf( fp, "\n** End of Report **\n" );
|
||||
|
||||
fclose( fp );
|
||||
|
||||
return true;
|
||||
}
|
|
@ -95,17 +95,6 @@ public:
|
|||
|
||||
int ExcludeMarker( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Function writeReport
|
||||
* outputs the MARKER items with commentary to an open text file.
|
||||
* @param aFullFileName The text filename to write the report to.
|
||||
* @return true if OK, false on error
|
||||
*/
|
||||
static bool WriteReport( const wxString& aFullFileName, BOARD* aBoard, EDA_UNITS aReportUnits,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider,
|
||||
std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider );
|
||||
|
||||
private:
|
||||
///< Set up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://schemas.kicad.org/drc.v1.json",
|
||||
"title": "KiCad DRC Report Schema",
|
||||
"description": "KiCad Plugin and Content Manager repository and package metadata schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"source": {
|
||||
"type": "string",
|
||||
"description": "Source file path"
|
||||
},
|
||||
"date": {
|
||||
"type": "string",
|
||||
"description": "Time at generation of report",
|
||||
"format": "date-time"
|
||||
},
|
||||
"kicad_version": {
|
||||
"type": "string",
|
||||
"description": "KiCad version used to generate the report",
|
||||
"pattern": "^\\d{1,2}(\\.\\d{1,2}(\\.\\d{1,2})?)?$"
|
||||
},
|
||||
"violations": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Violation"
|
||||
}
|
||||
},
|
||||
"unconnected_items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Violation"
|
||||
}
|
||||
},
|
||||
"schematic_parity": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/Violation"
|
||||
}
|
||||
},
|
||||
"coordinate_units": {
|
||||
"type": "string",
|
||||
"description": "Units that all coordinates in this report are encoded in",
|
||||
"enum": [
|
||||
"mm",
|
||||
"mils",
|
||||
"in"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"source",
|
||||
"date",
|
||||
"kicad_version",
|
||||
"violations",
|
||||
"unconnected_items",
|
||||
"schematic_parity",
|
||||
"coordinate_units",
|
||||
],
|
||||
"definitions": {
|
||||
"Violation": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "KiCad type name for the violation"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Description of the violation"
|
||||
},
|
||||
"severity": {
|
||||
"$ref": "#/definitions/Severity"
|
||||
},
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/AffectedItem"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"description",
|
||||
"severity",
|
||||
"items"
|
||||
]
|
||||
},
|
||||
"AffectedItem": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"uuid": {
|
||||
"$ref": "#/definitions/Uuid"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Description of the item"
|
||||
},
|
||||
"pos": {
|
||||
"$ref": "#/definitions/Coordinate"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"uuid",
|
||||
"description",
|
||||
"pos"
|
||||
]
|
||||
},
|
||||
"Uuid": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the item",
|
||||
"pattern": "^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$"
|
||||
},
|
||||
"Severity": {
|
||||
"type": "string",
|
||||
"description": "Severity of the violation",
|
||||
"enum": [
|
||||
"error",
|
||||
"warning",
|
||||
"ignore"
|
||||
]
|
||||
},
|
||||
"Coordinate": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "number",
|
||||
"description": "x coordinate"
|
||||
},
|
||||
"y": {
|
||||
"type": "number",
|
||||
"description": "y coordinate"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"x",
|
||||
"y"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue