KiCad PCB EDA Suite
Loading...
Searching...
No Matches
merge_validators.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
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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, you may find one here:
18 * http://www.gnu.org/licenses/gpl-3.0.html
19 * or you may search the http://www.gnu.org website for the version 3 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <algorithm>
27#include <map>
28
29
30namespace KICAD_DIFF
31{
32
34{
35 return std::any_of( failures.begin(), failures.end(),
36 []( const VALIDATION_FAILURE& aF )
37 {
38 return aF.severity == RPT_SEVERITY_ERROR;
39 } );
40}
41
42
44{
45 failures.reserve( failures.size() + aOther.failures.size() );
46
47 for( VALIDATION_FAILURE& f : aOther.failures )
48 failures.push_back( std::move( f ) );
49
50 aOther.failures.clear();
51}
52
53
54VALIDATION_REPORT CheckRefdesUniqueness( const std::vector<REFDES_ENTRY>& aEntries )
55{
56 VALIDATION_REPORT report;
57
58 // Group entries by refdes. Empty refdeses are unassigned components and
59 // don't collide.
60 std::map<wxString, std::vector<KIID_PATH>> byRefdes;
61
62 for( const REFDES_ENTRY& e : aEntries )
63 {
64 if( e.refdes.IsEmpty() )
65 continue;
66
67 // Skip refdeses with a trailing '?' — those are also unassigned
68 // (placeholder before annotation).
69 if( e.refdes.EndsWith( wxS( "?" ) ) )
70 continue;
71
72 byRefdes[e.refdes].push_back( e.id );
73 }
74
75 for( const auto& [refdes, ids] : byRefdes )
76 {
77 if( ids.size() < 2 )
78 continue;
79
82 f.validator = wxS( "RefdesUniqueness" );
83 f.message = wxString::Format( wxS( "Reference designator '%s' is used %zu times" ),
84 refdes, ids.size() );
85 f.relatedItems = ids;
86 report.failures.push_back( std::move( f ) );
87 }
88
89 return report;
90}
91
92
94 bool aApplierReportedRebuild )
95{
96 VALIDATION_REPORT report;
97
98 if( aPlanRequiredRebuild && !aApplierReportedRebuild )
99 {
102 f.validator = wxS( "ConnectivityRebuild" );
103 f.message = wxS( "Plan required a connectivity rebuild but the applier did not "
104 "report performing one — connectivity data may be stale." );
105 report.failures.push_back( std::move( f ) );
106 }
107
108 return report;
109}
110
111
112VALIDATION_REPORT CheckSchemaVersions( int aAncestorVersion, int aOursVersion,
113 int aTheirsVersion )
114{
115 VALIDATION_REPORT report;
116
117 // Versions are encoded as YYYYMMDD ints in KiCad serialization. Any two
118 // sides differing in their major epoch (>5y span) is rejected; closer
119 // spans surface as WARNING so the user can intervene.
120 constexpr int MAJOR_EPOCH_DELTA = 50000; // ~5 years in YYYYMMDD encoding
121
122 int maxV = std::max( { aAncestorVersion, aOursVersion, aTheirsVersion } );
123 int minV = std::min( { aAncestorVersion, aOursVersion, aTheirsVersion } );
124
125 if( maxV - minV >= MAJOR_EPOCH_DELTA )
126 {
129 f.validator = wxS( "SchemaVersion" );
130 f.message = wxString::Format(
131 wxS( "Schema version spread between merge inputs is too large "
132 "(min=%d, max=%d). Refusing to merge." ),
133 minV, maxV );
134 report.failures.push_back( std::move( f ) );
135 }
136 else if( maxV != minV )
137 {
140 f.validator = wxS( "SchemaVersion" );
141 f.message = wxString::Format(
142 wxS( "Merge inputs use different schema versions "
143 "(ancestor=%d, ours=%d, theirs=%d)." ),
144 aAncestorVersion, aOursVersion, aTheirsVersion );
145 report.failures.push_back( std::move( f ) );
146 }
147
148 return report;
149}
150
151} // namespace KICAD_DIFF
VALIDATION_REPORT CheckConnectivityRebuildFlag(bool aPlanRequiredRebuild, bool aApplierReportedRebuild)
Information needed for the connectivity-rebuild side-effect check.
VALIDATION_REPORT CheckSchemaVersions(int aAncestorVersion, int aOursVersion, int aTheirsVersion)
Schema-version compatibility check: every input to the merge must use a compatible serialization vers...
VALIDATION_REPORT CheckRefdesUniqueness(const std::vector< REFDES_ENTRY > &aEntries)
Run refdes-uniqueness checks.
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
Reference-designator uniqueness over a flat list of (refdes, id) pairs.
Outcome of a single validator run.
std::vector< KIID_PATH > relatedItems
void Merge(VALIDATION_REPORT &&aOther)
std::vector< VALIDATION_FAILURE > failures