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
78 return std::unique_ptr<BOARD_ITEM>( board );
111 std::unique_ptr<BOARD_ITEM>
Parse()
override
114 return std::unique_ptr<BOARD_ITEM>{ parser.
Parse() };
129 m_buffer.assign( std::istreambuf_iterator<char>( aStream ), std::istreambuf_iterator<char>() );
132 if( aStream.fail() && !aStream.eof() )
138 std::unique_ptr<BOARD_ITEM>
Parse()
override
141 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
170 std::unique_ptr<STREAM_PARSER> parser;
177 std::cerr << fmt::format(
"Unsupported plugin type for streaming input: {}",
183 wxCHECK( parser,
false );
187 parser->PrepareStream( aStream );
191 std::cerr << fmt::format(
"Error preparing stream: {}", e.
What().ToStdString() ) << std::endl;
198 bool Parse(
const wxString& aFilename )
207 std::unique_ptr<BOARD_ITEM> board;
213 board = aParser.
Parse();
218 std::cerr <<
"Parsing failed: " << e.
What() << std::endl;
223 std::cout << fmt::format(
"Took: {}us", duration.count() ) << std::endl;
226 std::cout << fmt::format(
" {} nets", board->GetBoard()->GetNetCount() ) << std::endl;
229 return board !=
nullptr;
242 _(
"displays help on the command line parameters" ).mb_str(),
244 wxCMD_LINE_OPTION_HELP,
250 _(
"print parsing information" ).mb_str(),
256 _(
"parser plugin to use (kicad, allegro, etc.)" ).mb_str(),
257 wxCMD_LINE_VAL_STRING,
263 _(
"list available plugins and exit" ).mb_str(),
269 _(
"number of times to loop when parsing from stdin (for AFL)" ).mb_str(),
270 wxCMD_LINE_VAL_NUMBER,
276 _(
"input file" ).mb_str(),
277 wxCMD_LINE_VAL_STRING,
278 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE,
316 if( aExplicitPlugin ==
"auto" )
322 auto pluginIt =
pluginTypeMap.find( aExplicitPlugin.ToStdString() );
327 return pluginIt->second;
337 wxMessageOutput::Set(
new wxMessageOutputStderr );
338 wxCmdLineParser cl_parser( argc, argv );
340 cl_parser.AddUsageText(
_(
"This program parses PCB files, either from the stdin stream or "
341 "from the given filenames. This can be used either for standalone "
342 "testing of the parser or for fuzz testing." ) );
344 int cmd_parsed_ok = cl_parser.Parse();
345 if( cmd_parsed_ok != 0 )
351 const bool verbose = cl_parser.Found(
"verbose" );
353 if( cl_parser.Found(
"list-plugins" ) )
357 std::cout <<
name << std::endl;
359 std::cout <<
"auto" << std::endl;
365 const size_t file_count = cl_parser.GetParamCount();
367 wxString plugin(
"auto" );
368 cl_parser.Found(
"plugin", &plugin );
370 long aflLoopCount = 1;
371 cl_parser.Found(
"loop", &aflLoopCount );
373 if( file_count == 0 && plugin ==
"auto" )
375 std::cerr <<
"When parsing from stdin, you must specify the plugin type with -p" << std::endl;
384 std::cerr << fmt::format(
"Failed to determine plugin type for input using plugin {}", plugin.ToStdString() )
396 std::vector<std::string> failedFiles;
398 if( file_count == 0 )
403 while( __AFL_LOOP( aflLoopCount ) )
406 ok = runner.
Parse( std::cin );
414 for(
size_t i = 0; i < file_count; i++ )
416 const wxString filename = cl_parser.GetParam( i );
419 std::cout << fmt::format(
"Parsing: {}", filename.ToStdString() ) << std::endl;
421 if( !runner.
Parse( filename ) )
424 failedFiles.push_back( filename.ToStdString() );
429 for(
const auto& failedFile : failedFiles )
431 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
Information pertinent to a Pcbnew printed circuit board.
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...
static BOARD * Load(PCB_FILE_T aFileType, const wxString &aFileName, BOARD *aAppendToMe=nullptr, 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...
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 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
@ 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.