KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_report.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include "drc_report.h"
21#include "eda_item.h"
22
23#include <fstream>
24
25#include <wx/string.h>
26
27#include <board.h>
29#include <build_version.h>
30#include <drc/drc_item.h>
31#include <locale_io.h>
33#include <macros.h>
34#include <json_common.h>
35#include <rc_json_schema.h>
36#include <string_utils.h>
38
39
40DRC_REPORT::DRC_REPORT( BOARD* aBoard, EDA_UNITS aReportUnits,
41 std::shared_ptr<RC_ITEMS_PROVIDER> aMarkersProvider,
42 std::shared_ptr<RC_ITEMS_PROVIDER> aRatsnestProvider,
43 std::shared_ptr<RC_ITEMS_PROVIDER> aFpWarningsProvider) :
44 m_board( aBoard ),
45 m_reportUnits( aReportUnits ),
46 m_markersProvider( std::move( aMarkersProvider ) ),
47 m_ratsnestProvider( std::move( aRatsnestProvider ) ),
48 m_fpWarningsProvider( std::move( aFpWarningsProvider ) ),
50{
52 m_reportedSeverities = m_markersProvider->GetSeverities();
53}
54
55
56bool DRC_REPORT::WriteTextReport( const wxString& aFullFileName )
57{
58 // We need the global LOCALE_IO here in order to
59 // write the report in the c-locale.
60 LOCALE_IO locale;
61 FILE* fp = wxFopen( aFullFileName, wxT( "w" ) );
62
63 if( fp == nullptr )
64 return false;
65
66 UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits );
67 BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
68 BOARD_RC_ITEM_RESOLVER itemResolver( *m_board );
69 int count = 0;
70
71 wxFileName fn( m_board->GetFileName() );
72 fprintf( fp, "** Drc report for %s **\n", TO_UTF8( fn.GetFullName() ) );
73
74 fprintf( fp, "** Created on %s **\n", TO_UTF8( GetISO8601CurrentDateTime() ) );
75
76 fprintf( fp, "** Report includes: %s **\n", TO_UTF8( formatSeverities( m_reportedSeverities ) ) );
77
78 count = m_markersProvider->GetCount();
79
80 fprintf( fp, "\n** Found %d DRC violations **\n", count );
81
82 for( int i = 0; i < count; ++i )
83 {
84 const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
85 SEVERITY severity = item->GetParent()->GetSeverity();
86
87 if( severity == RPT_SEVERITY_EXCLUSION )
88 severity = bds.GetSeverity( item->GetErrorCode() );
89
90 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemResolver ) ) );
91 }
92
93 count = m_ratsnestProvider->GetCount();
94
95 fprintf( fp, "\n** Found %d unconnected pads **\n", count );
96
97 for( int i = 0; i < count; ++i )
98 {
99 const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
100 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
101
102 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemResolver ) ) );
103 }
104
105 count = m_fpWarningsProvider->GetCount();
106
107 fprintf( fp, "\n** Found %d Footprint errors **\n", count );
108
109 for( int i = 0; i < count; ++i )
110 {
111 const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i );
112 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
113
114 fprintf( fp, "%s", TO_UTF8( item->ShowReport( &unitsProvider, severity, itemResolver ) ) );
115 }
116
117 fprintf( fp, "\n** Ignored checks **\n" );
118
119 bool hasIgnored = false;
120
121 for( const std::reference_wrapper<RC_ITEM>& item : DRC_ITEM::GetItemsWithSeverities() )
122 {
123 int code = item.get().GetErrorCode();
124
125 if( code > 0 && bds.Ignore( code ) )
126 {
127 fprintf( fp, " - %s\n", TO_UTF8( HYPERLINK_DV_RENDERER::StripMarkup( item.get().GetErrorMessage( false ) ) ) );
128 hasIgnored = true;
129 }
130 }
131
132 if( !hasIgnored )
133 fprintf( fp, " - %s\n", TO_UTF8( _( "None" ) ) );
134
135 fprintf( fp, "\n** End of Report **\n" );
136
137 fclose( fp );
138
139 return true;
140}
141
142
143bool DRC_REPORT::WriteJsonReport( const wxString& aFullFileName )
144{
145 std::ofstream jsonFileStream( aFullFileName.fn_str() );
146
147 UNITS_PROVIDER unitsProvider( pcbIUScale, m_reportUnits );
148 BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
149 BOARD_RC_ITEM_RESOLVER itemResolver( *m_board );
150
151 RC_JSON::DRC_REPORT reportHead;
152
153 wxFileName fn( m_board->GetFileName() );
154 reportHead.$schema = "https://schemas.kicad.org/drc.v1.json";
155 reportHead.source = fn.GetFullName();
156 reportHead.date = GetISO8601CurrentDateTime();
159
160 // Document which severities are included in this report
162 reportHead.included_severities.push_back( wxS( "error" ) );
163
165 reportHead.included_severities.push_back( wxS( "warning" ) );
166
168 reportHead.included_severities.push_back( wxS( "exclusion" ) );
169
170 for( int i = 0; i < m_markersProvider->GetCount(); ++i )
171 {
172 const std::shared_ptr<RC_ITEM>& item = m_markersProvider->GetItem( i );
173 SEVERITY severity = item->GetParent()->GetSeverity();
174
175 if( severity == RPT_SEVERITY_EXCLUSION )
176 severity = bds.GetSeverity( item->GetErrorCode() );
177
178 RC_JSON::VIOLATION violation;
179 item->GetJsonViolation( violation, &unitsProvider, severity, itemResolver );
180
181 reportHead.violations.push_back( violation );
182 }
183
184 for( int i = 0; i < m_ratsnestProvider->GetCount(); ++i )
185 {
186 const std::shared_ptr<RC_ITEM>& item = m_ratsnestProvider->GetItem( i );
187 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
188
189 RC_JSON::VIOLATION violation;
190 item->GetJsonViolation( violation, &unitsProvider, severity, itemResolver );
191
192 reportHead.unconnected_items.push_back( violation );
193 }
194
195
196 for( int i = 0; i < m_fpWarningsProvider->GetCount(); ++i )
197 {
198 const std::shared_ptr<RC_ITEM>& item = m_fpWarningsProvider->GetItem( i );
199 SEVERITY severity = bds.GetSeverity( item->GetErrorCode() );
200
201 RC_JSON::VIOLATION violation;
202 item->GetJsonViolation( violation, &unitsProvider, severity, itemResolver );
203
204 reportHead.schematic_parity.push_back( violation );
205 }
206
207 for( const std::reference_wrapper<RC_ITEM>& item : DRC_ITEM::GetItemsWithSeverities() )
208 {
209 int code = item.get().GetErrorCode();
210
211 if( code > 0 && bds.Ignore( code ) )
212 {
213 RC_JSON::IGNORED_CHECK ignoredCheck;
214 ignoredCheck.key = item.get().GetSettingsKey();
215 ignoredCheck.description = HYPERLINK_DV_RENDERER::StripMarkup( item.get().GetErrorMessage( false ) );
216 reportHead.ignored_checks.push_back( ignoredCheck );
217 }
218 }
219
220 nlohmann::json saveJson = nlohmann::json( reportHead );
221 jsonFileStream << std::setw( 4 ) << saveJson << std::endl;
222 jsonFileStream.flush();
223 jsonFileStream.close();
224
225 return true;
226}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:128
wxString GetMajorMinorPatchVersion()
Get the major, minor and patch version in a string major.minor.patch This is extracted by CMake from ...
Container for design settings for a BOARD object.
bool Ignore(int aDRCErrorCode) const
Return true if the DRC error code's severity is RPT_SEVERITY_ERROR.
SEVERITY GetSeverity(int aDRCErrorCode) const
Return the severity of a given DRC error code.
Implements the RC_ITEM_RESOLVER interface to resolve PCB items by their KIID.
Definition drc_item.h:349
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:411
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
Definition drc_item.h:172
std::shared_ptr< RC_ITEMS_PROVIDER > m_ratsnestProvider
Definition drc_report.h:46
bool WriteJsonReport(const wxString &aFullFileName)
BOARD * m_board
Definition drc_report.h:43
int m_reportedSeverities
Definition drc_report.h:48
std::shared_ptr< RC_ITEMS_PROVIDER > m_markersProvider
Definition drc_report.h:45
bool WriteTextReport(const wxString &aFullFileName)
EDA_UNITS m_reportUnits
Definition drc_report.h:44
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)
std::shared_ptr< RC_ITEMS_PROVIDER > m_fpWarningsProvider
Definition drc_report.h:47
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
#define _(s)
EDA_UNITS
Definition eda_units.h:44
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition idf_helpers.h:37
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
STL namespace.
wxString formatSeverities(int aSeverities)
Convert a severity mask to a human-readable comma-separated string.
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_EXCLUSION
wxString GetISO8601CurrentDateTime()
std::vector< wxString > included_severities
std::vector< VIOLATION > unconnected_items
std::vector< IGNORED_CHECK > ignored_checks
std::vector< VIOLATION > violations
std::vector< VIOLATION > schematic_parity