KiCad PCB EDA Suite
Loading...
Searching...
No Matches
job_import_utils.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 along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21#include <reporter.h>
22#include <string_utils.h>
23#include <wx/file.h>
24#include <wx/ffile.h>
25#include <wx/filename.h>
26#include <wx/intl.h>
27
28
29bool ParseImportReportFormat( const wxString& aText, IMPORT_REPORT_FORMAT& aFormat )
30{
31 if( aText == wxS( "none" ) )
33 else if( aText == wxS( "json" ) )
35 else if( aText == wxS( "text" ) )
37 else
38 return false;
39
40 return true;
41}
42
43
44wxString DefaultImportOutputPath( const wxString& aInputFile, const wxString& aKiCadExt )
45{
46 wxFileName fn( aInputFile );
47 fn.SetExt( aKiCadExt );
48
49 return fn.GetFullPath();
50}
51
52
53bool LoadLayerMapFile( const wxString& aFile, std::map<wxString, wxString>& aMap, wxString& aError )
54{
55 wxFFile file( aFile, wxS( "rb" ) );
56
57 if( !file.IsOpened() )
58 {
59 aError = wxString::Format( _( "Could not open layer map file '%s'" ), aFile );
60 return false;
61 }
62
63 wxString content;
64
65 if( !file.ReadAll( &content ) )
66 {
67 aError = wxString::Format( _( "Could not read layer map file '%s'" ), aFile );
68 return false;
69 }
70
71 nlohmann::json json;
72
73 try
74 {
75 json = nlohmann::json::parse( content.ToStdString() );
76 }
77 catch( const nlohmann::json::exception& e )
78 {
79 aError = wxString::Format( _( "Layer map file '%s' is not valid JSON: %s" ), aFile,
80 From_UTF8( e.what() ) );
81 return false;
82 }
83
84 if( !json.is_object() )
85 {
86 aError = wxString::Format( _( "Layer map file '%s' must be a JSON object mapping source "
87 "layer names to KiCad layer names" ), aFile );
88 return false;
89 }
90
91 std::map<wxString, wxString> parsed;
92
93 for( auto it = json.begin(); it != json.end(); ++it )
94 {
95 if( !it.value().is_string() )
96 {
97 aError = wxString::Format( _( "Layer map entry for '%s' must be a KiCad layer name "
98 "string" ), From_UTF8( it.key().c_str() ) );
99 return false;
100 }
101
102 parsed[From_UTF8( it.key().c_str() )] = From_UTF8( it.value().get<std::string>().c_str() );
103 }
104
105 aMap = std::move( parsed );
106 return true;
107}
108
109
111 const wxString& aReportFile, const IMPORT_REPORT_DATA& aData )
112{
113 if( aFormat == IMPORT_REPORT_FORMAT::NONE )
114 return;
115
116 wxString output;
117
118 if( aFormat == IMPORT_REPORT_FORMAT::JSON )
119 {
120 nlohmann::json report;
121
122 report["source_file"] = aData.m_sourceFile.ToStdString();
123 report["source_format"] = aData.m_sourceFormat.ToStdString();
124 report["output_file"] = aData.m_outputFile.ToStdString();
125
126 nlohmann::json statistics = nlohmann::json::object();
127
128 for( const auto& [key, value] : aData.m_statistics )
129 statistics[key.ToStdString()] = value;
130
131 report["statistics"] = statistics;
132
133 for( auto it = aData.m_extraJson.begin(); it != aData.m_extraJson.end(); ++it )
134 report[it.key()] = it.value();
135
136 nlohmann::json warningsJson = nlohmann::json::array();
137
138 for( const wxString& warning : aData.m_warnings )
139 warningsJson.push_back( warning.ToStdString() );
140
141 report["warnings"] = warningsJson;
142
143 nlohmann::json errorsJson = nlohmann::json::array();
144
145 for( const wxString& error : aData.m_errors )
146 errorsJson.push_back( error.ToStdString() );
147
148 report["errors"] = errorsJson;
149
150 output = wxString::FromUTF8( report.dump( 2 ) );
151 }
152 else
153 {
154 output += wxS( "Import Report\n" );
155 output += wxS( "=============\n\n" );
156 output += wxString::Format( wxS( "Source file: %s\n" ), aData.m_sourceFile );
157 output += wxString::Format( wxS( "Source format: %s\n" ), aData.m_sourceFormat );
158 output += wxString::Format( wxS( "Output file: %s\n\n" ), aData.m_outputFile );
159 output += wxS( "Statistics:\n" );
160
161 for( const auto& [key, value] : aData.m_statistics )
162 {
163 wxString label = key.Left( 1 ).Upper() + key.Mid( 1 );
164 output += wxString::Format( wxS( " %s: %zu\n" ), label, value );
165 }
166
167 if( !aData.m_warnings.empty() )
168 {
169 output += wxS( "\nWarnings:\n" );
170
171 for( const wxString& warning : aData.m_warnings )
172 output += wxString::Format( wxS( " - %s\n" ), warning );
173 }
174 }
175
176 if( !aReportFile.IsEmpty() )
177 {
178 wxFile file( aReportFile, wxFile::write );
179
180 if( file.IsOpened() )
181 {
182 file.Write( output );
183 file.Close();
184 }
185 else if( aReporter )
186 {
187 aReporter->Report( wxString::Format( _( "Failed to write import report to '%s'\n" ),
188 aReportFile ),
190 }
191 }
192 else if( aReporter )
193 {
194 aReporter->Report( output + wxS( "\n" ), RPT_SEVERITY_INFO );
195 }
196}
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:100
#define _(s)
nlohmann::json json
Definition gerbview.cpp:49
void WriteImportReport(REPORTER *aReporter, IMPORT_REPORT_FORMAT aFormat, const wxString &aReportFile, const IMPORT_REPORT_DATA &aData)
Emit an import report in the requested format to aReportFile, or to aReporter (at INFO severity) when...
wxString DefaultImportOutputPath(const wxString &aInputFile, const wxString &aKiCadExt)
Build the default output path for an import by swapping the input file's extension for the given KiCa...
bool ParseImportReportFormat(const wxString &aText, IMPORT_REPORT_FORMAT &aFormat)
Parse the user-facing report format name ("none", "json" or "text") into its enum.
bool LoadLayerMapFile(const wxString &aFile, std::map< wxString, wxString > &aMap, wxString &aError)
Load an explicit layer-mapping file into aMap.
IMPORT_REPORT_FORMAT
Output format for the report shared by the board and schematic import jobs.
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_INFO
wxString From_UTF8(const char *cstring)
nlohmann::json output