27#include <wx/cmdline.h>
30#include <fmt/format.h>
59 virtual std::unique_ptr<BOARD_ITEM>
Parse() = 0;
75 std::unique_ptr<BOARD_ITEM>
Parse()
override
110 std::unique_ptr<BOARD_ITEM>
Parse()
override
113 return std::unique_ptr<BOARD_ITEM>{ parser.
Parse() };
128 m_buffer.assign( std::istreambuf_iterator<char>( aStream ), std::istreambuf_iterator<char>() );
131 if( aStream.fail() && !aStream.eof() )
137 std::unique_ptr<BOARD_ITEM>
Parse()
override
140 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
169 std::unique_ptr<STREAM_PARSER> parser;
176 std::cerr << fmt::format(
"Unsupported plugin type for streaming input: {}",
182 wxCHECK( parser,
false );
186 parser->PrepareStream( aStream );
190 std::cerr << fmt::format(
"Error preparing stream: {}", e.
What().ToStdString() ) << std::endl;
197 bool Parse(
const wxString& aFilename )
206 std::unique_ptr<BOARD_ITEM> board;
212 board = aParser.
Parse();
217 std::cerr <<
"Parsing failed: " << e.
What() << std::endl;
222 std::cout << fmt::format(
"Took: {}us", duration.count() ) << std::endl;
225 std::cout << fmt::format(
" {} nets", board->GetBoard()->GetNetCount() ) << std::endl;
228 return board !=
nullptr;
241 _(
"displays help on the command line parameters" ).mb_str(),
243 wxCMD_LINE_OPTION_HELP,
249 _(
"print parsing information" ).mb_str(),
255 _(
"parser plugin to use (kicad, allegro, etc.)" ).mb_str(),
256 wxCMD_LINE_VAL_STRING,
262 _(
"list available plugins and exit" ).mb_str(),
268 _(
"number of times to loop when parsing from stdin (for AFL)" ).mb_str(),
269 wxCMD_LINE_VAL_NUMBER,
275 _(
"input file" ).mb_str(),
276 wxCMD_LINE_VAL_STRING,
277 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE,
315 if( aExplicitPlugin ==
"auto" )
321 auto pluginIt =
pluginTypeMap.find( aExplicitPlugin.ToStdString() );
326 return pluginIt->second;
336 wxMessageOutput::Set(
new wxMessageOutputStderr );
337 wxCmdLineParser cl_parser( argc, argv );
339 cl_parser.AddUsageText(
_(
"This program parses PCB files, either from the stdin stream or "
340 "from the given filenames. This can be used either for standalone "
341 "testing of the parser or for fuzz testing." ) );
343 int cmd_parsed_ok = cl_parser.Parse();
344 if( cmd_parsed_ok != 0 )
350 const bool verbose = cl_parser.Found(
"verbose" );
352 if( cl_parser.Found(
"list-plugins" ) )
356 std::cout <<
name << std::endl;
358 std::cout <<
"auto" << std::endl;
364 const size_t file_count = cl_parser.GetParamCount();
366 wxString plugin(
"auto" );
367 cl_parser.Found(
"plugin", &plugin );
369 long aflLoopCount = 1;
370 cl_parser.Found(
"loop", &aflLoopCount );
372 if( file_count == 0 && plugin ==
"auto" )
374 std::cerr <<
"When parsing from stdin, you must specify the plugin type with -p" << std::endl;
383 std::cerr << fmt::format(
"Failed to determine plugin type for input using plugin {}", plugin.ToStdString() )
395 std::vector<std::string> failedFiles;
397 if( file_count == 0 )
402 while( __AFL_LOOP( aflLoopCount ) )
405 ok = runner.
Parse( std::cin );
413 for(
size_t i = 0; i < file_count; i++ )
415 const wxString filename = cl_parser.GetParam( i );
418 std::cout << fmt::format(
"Parsing: {}", filename.ToStdString() ) << std::endl;
420 if( !runner.
Parse( filename ) )
423 failedFiles.push_back( filename.ToStdString() );
428 for(
const auto& failedFile : failedFiles )
430 std::cerr << fmt::format(
"Failed to parse: {}", failedFile ) << std::endl;
std::vector< uint8_t > m_buffer
std::unique_ptr< BOARD_ITEM > Parse() override
Actually perform the parsing and return a BOARD_ITEM if successful, or nullptr if not.
void PrepareStream(std::istream &aStream) override
Take some input stream and prepare it for parsing.
Generic board parser - this makes no assumption about what the source data might be.
virtual std::unique_ptr< BOARD_ITEM > Parse()=0
Actually perform the parsing and return a BOARD_ITEM if successful, or nullptr if not.
virtual ~BOARD_PARSER()=default
Provide the BOARD_PARSER interface wrapping a normal PCB_IO file-based plugin lookup.
FILE_PARSER(PCB_IO_MGR::PCB_FILE_T aFileType, const wxString &aFileName)
PCB_IO_MGR::PCB_FILE_T m_fileType
std::unique_ptr< BOARD_ITEM > Parse() override
Actually perform the parsing and return a BOARD_ITEM if successful, or nullptr if not.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
bool LoadBoardFromData(const uint8_t *aData, size_t aSize, BOARD &aBoard)
Read a Pcbnew s-expression formatted LINE_READER object and returns the appropriate BOARD_ITEM object...
PCB_FILE_T
The set of file types that the PCB_IO_MGR knows about, and for which there has been a plugin written,...
@ KICAD_SEXP
S-expression Pcbnew file format.
@ GEDA_PCB
Geda PCB file formats.
@ LEGACY
Legacy Pcbnew file formats prior to s-expression.
static PCB_FILE_T FindPluginTypeFromBoardPath(const wxString &aFileName, int aCtl=0)
Return a plugin type given a path for a board file.
static std::unique_ptr< BOARD > Load(PCB_FILE_T aFileType, const wxString &aFileName, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Find the requested #PLUGIN and if found, calls the #PLUGIN::LoadBoard() function on it using the argu...
static const wxString ShowType(PCB_FILE_T aFileType)
Return a brief name for a plugin given aFileType enum.
Runs a BOARD_PARSER against a filename or stream and reports results.
bool doParse(BOARD_PARSER &aParser)
bool Parse(const wxString &aFilename)
PCB_IO_MGR::PCB_FILE_T m_pluginType
PCB_PARSE_RUNNER(PCB_IO_MGR::PCB_FILE_T aPluginType, bool aVerbose)
bool Parse(std::istream &aStream)
A small class to help profiling.
DURATION SinceStart(bool aSinceLast=false)
STDISTREAM_LINE_READER m_reader
void PrepareStream(std::istream &aStream) override
Take some input stream and prepare it for parsing.
std::unique_ptr< BOARD_ITEM > Parse() override
Actually perform the parsing and return a BOARD_ITEM if successful, or nullptr if not.
LINE_READER that wraps a given std::istream instance.
In order to support fuzz testing, we need to be able to parse from stdin.
virtual void PrepareStream(std::istream &aStream)=0
Take some input stream and prepare it for parsing.
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
static const wxCmdLineEntryDesc g_cmdLineDesc[]
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
std::chrono::microseconds PARSE_DURATION
@ TOOL_SPECIFIC
Tools can define their own statuses from here onwards.
@ BAD_CMDLINE
The command line was not correct for the tool.
Pcbnew s-expression file format parser definition.