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 <>
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 =
172 wxString::Format( _( "An unexpected error occurred while reading library table %s "),
173 aPath.string().c_str() );
174 return tl::unexpected( LIBRARY_PARSE_ERROR( { .description = msg } ) );
175 }
176 }
177 catch( const parse_error& e )
178 {
179 const auto& p = e.positions().front();
180 std::string msg = fmt::format( "Error at line {}, column {}:\n{}\n{:>{}}\n{}",
181 p.line, p.column, in.line_at( p ), "^", p.column,
182 e.message() );
183
184 wxLogTrace( traceLibraries, "%s", msg.c_str() );
185
186 wxString description = wxString::Format( _( "Syntax error at line %zu, column %zu" ),
187 p.line, p.column );
188
189 return tl::unexpected( LIBRARY_PARSE_ERROR( {
190 .description = description,
191 .line = p.line,
192 .column = p.column
193 } ) );
194 }
195
196 return state.model;
197 }
198 catch( std::filesystem::filesystem_error& e )
199 {
200 wxLogTrace( traceLibraries, "LIBRARY_TABLE_PARSER::Parse loading '%s' error: %s",
201 aPath.string(), e.what() );
202 return tl::unexpected( LIBRARY_PARSE_ERROR( {
203 .description = e.what()
204 } ) );
205 }
206}
207
208
209tl::expected<LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR> LIBRARY_TABLE_PARSER::ParseBuffer(
210 const std::string& aBuffer )
211{
212 memory_input in( aBuffer, "" );
214 wxLogTrace( traceLibraries, "LIBRARY_TABLE_PARSER::Parse from string buffer" );
215
216 try
217 {
219 {
220 wxLogTrace( traceLibraries, "Parsing failed without throwing" );
221 wxString msg =
222 wxString::Format( _( "An unexpected error occurred while reading library table") );
223 return tl::unexpected( LIBRARY_PARSE_ERROR( { .description = msg } ) );
224 }
225 }
226 catch( const parse_error& e )
227 {
228 const auto& p = e.positions().front();
229 std::string msg = fmt::format( "Error at line {}, column {}:\n{}\n{:>{}}\n{}",
230 p.line, p.column, in.line_at( p ), "^", p.column,
231 e.message() );
232
233 wxLogTrace( traceLibraries, "%s", msg.c_str() );
234
235 wxString description = wxString::Format( _( "Syntax error at line %zu, column %zu" ),
236 p.line, p.column );
237
238 return tl::unexpected( LIBRARY_PARSE_ERROR( {
239 .description = description,
240 .line = p.line,
241 .column = p.column
242 } ) );
243 }
244
245 return state.model;
246}
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.