28#include <fmt/format.h>
29#include <wx/cmdline.h>
70 if( item.GetDefinedExternally() )
75 if( !wxGetEnv(
name, &existing ) )
76 wxSetEnv(
name, item.GetValue() );
89 wxFileName fn( aPath );
91 wxString absPath = fn.GetFullPath();
95 std::cout << fmt::format(
"Parsing library: {}", absPath.ToStdString() ) << std::endl;
100 std::vector<LIB_SYMBOL*> symbols;
111 std::cerr << fmt::format(
"Failed to parse library '{}' after {} us: {}", absPath.ToStdString(),
112 duration.count(), e.
What().ToStdString() )
117 std::cerr << fmt::format(
"Failed to parse library '{}': {}", absPath.ToStdString(),
118 e.
What().ToStdString() )
127 std::cout << fmt::format(
" {} symbols", symbols.size() ) << std::endl;
128 std::cout << fmt::format(
" Took: {} us", duration.count() ) << std::endl;
131 return static_cast<int>( symbols.size() );
143 std::string content( ( std::istreambuf_iterator<char>( std::cin ) ), std::istreambuf_iterator<char>() );
145 if( content.empty() )
165 for(
auto& entry : symbolMap )
179static int parseLibTable(
const wxString& aTablePath,
bool aVerbose, std::set<wxString>& aVisited )
182 wxFileName tableFn( aTablePath );
183 tableFn.MakeAbsolute();
185 wxString canonicalPath = tableFn.GetFullPath();
188 if( aVisited.count( canonicalPath ) )
191 aVisited.insert( canonicalPath );
197 std::cerr << fmt::format(
"Failed to load library table '{}': {}", canonicalPath.ToStdString(),
198 table.ErrorDescription().ToStdString() )
204 bool hadRows =
false;
206 for(
const auto& row :
table.Rows() )
208 if( row.Disabled() || row.Hidden() )
213 wxString uri = row.URI();
220 wxFileName uriFn( uri );
221 uriFn.MakeAbsolute( tableFn.GetPath() );
222 uri = uriFn.GetFullPath();
227 std::cout << fmt::format(
"Parsing library '{}': {}", row.Nickname().ToStdString(), uri.ToStdString() )
236 if( nestedCount >= 0 )
237 okCount += nestedCount;
239 else if( row.Type() == wxS(
"KiCad" ) )
251 std::cerr << fmt::format(
"Skipping unsupported library type '{}' for '{}'", row.Type().ToStdString(),
252 row.Nickname().ToStdString() )
270 _(
"displays help on the command line parameters" ).mb_str(),
272 wxCMD_LINE_OPTION_HELP,
278 _(
"print parsing information" ).mb_str(),
284 _(
"path to a symbol library table file" ).mb_str(),
285 wxCMD_LINE_VAL_STRING,
291 _(
"number of times to loop when parsing from stdin (for AFL)" ).mb_str(),
292 wxCMD_LINE_VAL_NUMBER,
298 _(
"library file" ).mb_str(),
299 wxCMD_LINE_VAL_STRING,
300 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE,
320 wxMessageOutput::Set(
new wxMessageOutputStderr );
321 wxCmdLineParser cl_parser( argc, argv );
323 cl_parser.AddUsageText(
"This program parses schematic symbol library files, either from the stdin "
324 "stream, from individual library files, or from libraries listed in a symbol "
325 "library table. This can be used for profiling, fuzz testing, etc.\n" );
327 cl_parser.AddUsageText(
"If no library files or library table are specified, the program will read from stdin. "
328 "This is useful for fuzz testing, for example.\n" );
330 cl_parser.AddUsageText(
"Fuzzing with AFL:\n" );
332 cl_parser.AddUsageText(
" afl-fuzz -i <input_dir> -o <output_dir> -- qa_eeschema_tools lib_parser --loop 1000\n" );
334 cl_parser.AddUsageText(
"Some fuzzing seeds for the -i option can be found in the KiCad source tree under"
335 " qa/data/fuzzing/kicad_sym\n" );
337 cl_parser.AddUsageText(
"See the fuzzing documentation in dev-docs for more information." );
339 int cmd_parsed_ok = cl_parser.Parse();
341 if( cmd_parsed_ok != 0 )
351 const bool verbose = cl_parser.Found(
"verbose" );
355 std::vector<wxString> libPaths;
357 for(
size_t i = 0; i < cl_parser.GetParamCount(); i++ )
358 libPaths.push_back( cl_parser.GetParam( i ) );
363 if( cl_parser.Found(
"lib-table", &tablePath ) )
366 wxFileName tableFn( tablePath );
367 tableFn.MakeAbsolute();
370 std::set<wxString> visited;
376 if( count == 0 && !verbose )
380 std::cerr << fmt::format(
"No libraries successfully parsed from table '{}'", tablePath.ToStdString() )
385 long aflLoopCount = 1;
386 cl_parser.Found(
"loop", &aflLoopCount );
388 if( libPaths.empty() )
392 if( cl_parser.Found(
"lib-table" ) )
396 while( __AFL_LOOP( aflLoopCount ) )
405 for(
const auto&
path : libPaths )
423 "Parse schematic symbol library files",
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()
static const wxString TABLE_TYPE_NAME
A small class to help profiling.
DURATION SinceStart(bool aSinceLast=false)
Object to parser s-expression symbol library and schematic file formats.
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
A SCH_IO derivation for loading schematic files using the new s-expression file format.
void EnumerateSymbolLib(wxArrayString &aSymbolNameList, const wxString &aLibraryPath, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Populate a list of LIB_SYMBOL alias names contained within the library aLibraryPath.
COMMON_SETTINGS * GetCommonSettings() const
Retrieve the common settings shared by all applications.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
static void ResolvePossibleSymlinks(wxFileName &aFilename)
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
static const wxCmdLineEntryDesc g_cmdLineDesc[]
static int parseLibraryFile(const wxString &aPath, bool aVerbose)
Parse a single library file path and return the number of symbols loaded.
static bool parseStdin()
Parse symbol library content from stdin (for fuzzing).
std::chrono::microseconds PARSE_DURATION
static int parseLibTable(const wxString &aTablePath, bool aVerbose, std::set< wxString > &aVisited)
Load libraries from a symbol library table file.
static void loadKiCadEnvVars()
Load the KiCad common settings and set any configured environment variables (e.g.
int lib_parser_main_func(int argc, char **argv)
@ TOOL_SPECIFIC
Tools can define their own statuses from here onwards.
@ BAD_CMDLINE
The command line was not correct for the tool.
#define PROJECT_VAR_NAME
A variable name whose value holds the current project directory.
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP