ADDED: DRC JSON report

This commit is contained in:
Marek Roszko 2023-08-13 14:44:31 -04:00
parent 64a7bad56e
commit 14a0fa435c
15 changed files with 599 additions and 102 deletions

View File

@ -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;

View File

@ -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;
default: ;
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 );

View File

@ -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]))" );

View File

@ -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; }
@ -272,8 +289,9 @@ public:
void DeleteItems( bool aCurrentOnly, bool aIncludeExclusions, bool aDeep );
protected:
void rebuildModel( std::shared_ptr<RC_ITEMS_PROVIDER> aProvider, int aSeverities );
void onSizeView( wxSizeEvent& aEvent );
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;

103
include/rc_json_schema.h Normal file
View File

@ -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

View File

@ -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;

View File

@ -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" ) );

View File

@ -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

View File

@ -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() ) );

172
pcbnew/drc/drc_report.cpp Normal file
View File

@ -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;
}

51
pcbnew/drc/drc_report.h Normal file
View File

@ -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

View File

@ -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,7 +867,11 @@ int PCBNEW_JOBS_HANDLER::JobExportDrc( JOB* aJob )
{
wxFileName fn = brd->GetFileName();
fn.SetName( fn.GetName() );
fn.SetExt( ReportFileExtension );
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 )
{

View File

@ -294,77 +294,4 @@ void DRC_TOOL::setTransitions()
Go( &DRC_TOOL::ExcludeMarker, ACTIONS::excludeMarker.MakeEvent() );
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;
}

View File

@ -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;

View File

@ -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"
]
}
}
}