KiCad PCB EDA Suite
Loading...
Searching...
No Matches
library_table_parser.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 * @author Jon Evans <[email protected]>
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <fmt/format.h>
22#include <pegtl/contrib/parse_tree.hpp>
23#include <wx/log.h>
24
27#include <trace_helpers.h>
28#include <boost/locale/boundary/types.hpp>
29
30
31using namespace LIBRARY_TABLE_GRAMMAR;
32
33
46
47
48template <typename Rule>
49struct LIBRARY_TABLE_PARSER_ACTION : tao::pegtl::nothing<Rule>
50{
51};
52
53
54template <>
56{
61};
62
63
64template <>
66{
71};
72
73
74template <>
75struct LIBRARY_TABLE_PARSER_ACTION<KEYWORDS::DESIGN_BLOCK_LIB_TABLE>
76{
81};
82
83template <>
85{
86 template <typename ActionInput>
87 static void apply( const ActionInput& in, LIBRARY_TABLE_PARSER_STATE& s )
88 {
89 wxCHECK2( s.target_string, return );
90 *s.target_string = in.string();
91 }
92};
93
94
95template <>
97{
98 template <typename ActionInput>
99 static void apply( const ActionInput& in, LIBRARY_TABLE_PARSER_STATE& s )
100 {
101 wxCHECK2( s.target_string, return );
102 wxCHECK2( in.string().size() >= 2, return );
103 *s.target_string = in.string().substr( 1, in.string().size() - 2 );
104 }
105};
106
107
108#define DEFINE_STRING_ACTION( Rule, StateVariable ) \
109template <> \
110struct LIBRARY_TABLE_PARSER_ACTION<Rule> \
111{ \
112 static void apply0( LIBRARY_TABLE_PARSER_STATE& s ) \
113 { \
114 s.target_string = &s.StateVariable; \
115 } \
116} \
117
119DEFINE_STRING_ACTION( KEYWORDS::NAME, current_row_model.nickname );
120DEFINE_STRING_ACTION( KEYWORDS::TYPE, current_row_model.type );
121DEFINE_STRING_ACTION( KEYWORDS::URI, current_row_model.uri );
122DEFINE_STRING_ACTION( KEYWORDS::OPTIONS, current_row_model.options );
123DEFINE_STRING_ACTION( KEYWORDS::DESCR, current_row_model.description );
124
125// Handle (hidden), (disabled)
126#define DEFINE_FLAG_ACTION( Rule, StateVariable ) \
127template <> \
128struct LIBRARY_TABLE_PARSER_ACTION<Rule> \
129{ \
130 static void apply0( LIBRARY_TABLE_PARSER_STATE& s ) \
131 { \
132 s.StateVariable = true; \
133 } \
134} \
135
136DEFINE_FLAG_ACTION( HIDDEN_MARKER, current_row_model.hidden );
137DEFINE_FLAG_ACTION( DISABLED_MARKER, current_row_model.disabled );
138
139
140template <>
142{
144 {
145 s.model.rows.emplace_back( s.current_row_model );
147 }
148};
149
150
154
155
156tl::expected<LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR> LIBRARY_TABLE_PARSER::Parse(
157 const std::filesystem::path& aPath )
158{
159 try
160 {
161 file_input in( aPath );
162
164 wxLogTrace( traceLibraries, "LIBRARY_TABLE_PARSER::Parse %s", aPath.string().c_str() );
165
166 try
167 {
169 {
170 wxLogTrace( traceLibraries, "Parsing failed without throwing" );
171 wxString msg = wxString::Format( _( "An unexpected error occurred while reading library table %s "),
172 aPath.string().c_str() );
173 return tl::unexpected( LIBRARY_PARSE_ERROR( { .description = msg } ) );
174 }
175 }
176 catch( const parse_error& e )
177 {
178 const auto& p = e.positions().front();
179 std::string msg = fmt::format( "Error at line {}, column {}:\n{}\n{:>{}}\n{}",
180 p.line, p.column, in.line_at( p ), "^", p.column,
181 e.message() );
182
183 wxLogTrace( traceLibraries, "%s", msg.c_str() );
184
185 return tl::unexpected( LIBRARY_PARSE_ERROR( {
186 .description = wxString::Format( _( "Syntax error at line %zu, column %zu" ),
187 p.line, p.column ),
188 .line = p.line,
189 .column = p.column
190 } ) );
191 }
192
193 return state.model;
194 }
195 catch( std::filesystem::filesystem_error& e )
196 {
197 wxLogTrace( traceLibraries, "LIBRARY_TABLE_PARSER::Parse loading '%s' error: %s", aPath.string(), e.what() );
198
199 return tl::unexpected( LIBRARY_PARSE_ERROR( {
200 .description = e.what()
201 } ) );
202 }
203}
204
205
206tl::expected<LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR> LIBRARY_TABLE_PARSER::ParseBuffer( const std::string& aBuffer )
207{
208 memory_input in( aBuffer, "" );
210 wxLogTrace( traceLibraries, "LIBRARY_TABLE_PARSER::Parse from string buffer" );
211
212 try
213 {
215 {
216 wxLogTrace( traceLibraries, "Parsing failed without throwing" );
217
218 return tl::unexpected( LIBRARY_PARSE_ERROR( {
219 .description = _( "An unexpected error occurred while reading library table" )
220 } ) );
221 }
222 }
223 catch( const parse_error& e )
224 {
225 const auto& p = e.positions().front();
226 std::string msg = fmt::format( "Error at line {}, column {}:\n{}\n{:>{}}\n{}",
227 p.line, p.column, in.line_at( p ), "^", p.column,
228 e.message() );
229
230 wxLogTrace( traceLibraries, "%s", msg.c_str() );
231
232 return tl::unexpected( LIBRARY_PARSE_ERROR( {
233 .description = wxString::Format( _( "Syntax error at line %zu, column %zu" ),
234 p.line, p.column ),
235 .line = p.line,
236 .column = p.column
237 } ) );
238 }
239
240 return state.model;
241}
tl::expected< LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR > ParseBuffer(const std::string &aBuffer)
tl::expected< LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR > Parse(const std::filesystem::path &aPath)
#define _(s)
const wxChar *const traceLibraries
Flag to enable library table and library manager tracing.
#define DEFINE_FLAG_ACTION(Rule, StateVariable)
#define DEFINE_STRING_ACTION(Rule, StateVariable)
bool parse(std::istream &aStream, bool aVerbose)
Parse a PCB or footprint file from the given input stream.
The intermediate representation that a library table is parsed into.
std::vector< LIBRARY_TABLE_ROW_IR > rows
LIBRARY_TABLE_TYPE type
static void apply0(LIBRARY_TABLE_PARSER_STATE &s)
static void apply0(LIBRARY_TABLE_PARSER_STATE &s)
static void apply0(LIBRARY_TABLE_PARSER_STATE &s)
static void apply(const ActionInput &in, LIBRARY_TABLE_PARSER_STATE &s)
static void apply(const ActionInput &in, LIBRARY_TABLE_PARSER_STATE &s)
LIBRARY_TABLE_ROW_IR current_row_model
wxLogTrace helper definitions.