31#include <wx/cmdline.h>
34#include <fmt/format.h>
63 virtual std::unique_ptr<BOARD_ITEM>
Parse() = 0;
79 std::unique_ptr<BOARD_ITEM>
Parse()
override
82 return std::unique_ptr<BOARD_ITEM>( board );
115 std::unique_ptr<BOARD_ITEM>
Parse()
override
118 return std::unique_ptr<BOARD_ITEM>{ parser.
Parse() };
133 m_buffer.assign( std::istreambuf_iterator<char>( aStream ), std::istreambuf_iterator<char>() );
136 if( aStream.fail() && !aStream.eof() )
142 std::unique_ptr<BOARD_ITEM>
Parse()
override
145 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
174 std::unique_ptr<STREAM_PARSER> parser;
181 std::cerr << fmt::format(
"Unsupported plugin type for streaming input: {}",
187 wxCHECK( parser,
false );
191 parser->PrepareStream( aStream );
195 std::cerr << fmt::format(
"Error preparing stream: {}", e.
What().ToStdString() ) << std::endl;
202 bool Parse(
const wxString& aFilename )
211 std::unique_ptr<BOARD_ITEM> board;
217 board = aParser.
Parse();
222 std::cerr <<
"Parsing failed: " << e.
What() << std::endl;
227 std::cout << fmt::format(
"Took: {}us", duration.count() ) << std::endl;
230 std::cout << fmt::format(
" {} nets", board->GetBoard()->GetNetCount() ) << std::endl;
233 return board !=
nullptr;
246 _(
"displays help on the command line parameters" ).mb_str(),
248 wxCMD_LINE_OPTION_HELP,
254 _(
"print parsing information" ).mb_str(),
260 _(
"parser plugin to use (kicad, allegro, etc.)" ).mb_str(),
261 wxCMD_LINE_VAL_STRING,
267 _(
"list available plugins and exit" ).mb_str(),
273 _(
"number of times to loop when parsing from stdin (for AFL)" ).mb_str(),
274 wxCMD_LINE_VAL_NUMBER,
280 _(
"input file" ).mb_str(),
281 wxCMD_LINE_VAL_STRING,
282 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE,
320 if( aExplicitPlugin ==
"auto" )
326 auto pluginIt =
pluginTypeMap.find( aExplicitPlugin.ToStdString() );
331 return pluginIt->second;
341 wxMessageOutput::Set(
new wxMessageOutputStderr );
342 wxCmdLineParser cl_parser( argc, argv );
344 cl_parser.AddUsageText(
_(
"This program parses PCB files, either from the stdin stream or "
345 "from the given filenames. This can be used either for standalone "
346 "testing of the parser or for fuzz testing." ) );
348 int cmd_parsed_ok = cl_parser.Parse();
349 if( cmd_parsed_ok != 0 )
355 const bool verbose = cl_parser.Found(
"verbose" );
357 if( cl_parser.Found(
"list-plugins" ) )
361 std::cout <<
name << std::endl;
363 std::cout <<
"auto" << std::endl;
369 const size_t file_count = cl_parser.GetParamCount();
371 wxString plugin(
"auto" );
372 cl_parser.Found(
"plugin", &plugin );
374 long aflLoopCount = 1;
375 cl_parser.Found(
"loop", &aflLoopCount );
377 if( file_count == 0 && plugin ==
"auto" )
379 std::cerr <<
"When parsing from stdin, you must specify the plugin type with -p" << std::endl;
388 std::cerr << fmt::format(
"Failed to determine plugin type for input using plugin {}", plugin.ToStdString() )
400 std::vector<std::string> failedFiles;
402 if( file_count == 0 )
407 while( __AFL_LOOP( aflLoopCount ) )
410 ok = runner.
Parse( std::cin );
418 for(
size_t i = 0; i < file_count; i++ )
420 const wxString filename = cl_parser.GetParam( i );
423 std::cout << fmt::format(
"Parsing: {}", filename.ToStdString() ) << std::endl;
425 if( !runner.
Parse( filename ) )
428 failedFiles.push_back( filename.ToStdString() );
433 for(
const auto& failedFile : failedFiles )
435 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.