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 )
181static int parseLibTable(
const wxString& aTablePath,
bool aVerbose, std::set<wxString>& aVisited )
184 wxFileName tableFn( aTablePath );
185 tableFn.MakeAbsolute();
187 wxString canonicalPath = tableFn.GetFullPath();
190 if( aVisited.count( canonicalPath ) )
193 aVisited.insert( canonicalPath );
199 std::cerr << fmt::format(
"Failed to load library table '{}': {}", canonicalPath.ToStdString(),
200 table.ErrorDescription().ToStdString() )
206 bool hadRows =
false;
208 for(
const auto& row :
table.Rows() )
210 if( row.Disabled() || row.Hidden() )
215 wxString uri = row.URI();
222 wxFileName uriFn( uri );
223 uriFn.MakeAbsolute( tableFn.GetPath() );
224 uri = uriFn.GetFullPath();
229 std::cout << fmt::format(
"Parsing library '{}': {}", row.Nickname().ToStdString(), uri.ToStdString() )
238 if( nestedCount >= 0 )
239 okCount += nestedCount;
241 else if( row.Type() == wxS(
"KiCad" ) )
253 std::cerr << fmt::format(
"Skipping unsupported library type '{}' for '{}'", row.Type().ToStdString(),
254 row.Nickname().ToStdString() )
272 _(
"displays help on the command line parameters" ).mb_str(),
274 wxCMD_LINE_OPTION_HELP,
280 _(
"print parsing information" ).mb_str(),
286 _(
"path to a symbol library table file" ).mb_str(),
287 wxCMD_LINE_VAL_STRING,
293 _(
"number of times to loop when parsing from stdin (for AFL)" ).mb_str(),
294 wxCMD_LINE_VAL_NUMBER,
300 _(
"library file" ).mb_str(),
301 wxCMD_LINE_VAL_STRING,
302 wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE,
322 wxMessageOutput::Set(
new wxMessageOutputStderr );
323 wxCmdLineParser cl_parser( argc, argv );
325 cl_parser.AddUsageText(
"This program parses schematic symbol library files, either from the stdin "
326 "stream, from individual library files, or from libraries listed in a symbol "
327 "library table. This can be used for profiling, fuzz testing, etc.\n" );
329 cl_parser.AddUsageText(
"If no library files or library table are specified, the program will read from stdin. "
330 "This is useful for fuzz testing, for example.\n" );
332 cl_parser.AddUsageText(
"Fuzzing with AFL:\n" );
334 cl_parser.AddUsageText(
" afl-fuzz -i <input_dir> -o <output_dir> -- qa_eeschema_tools lib_parser --loop 1000\n" );
336 cl_parser.AddUsageText(
"Some fuzzing seeds for the -i option can be found in the KiCad source tree under"
337 " qa/data/fuzzing/kicad_sym\n" );
339 cl_parser.AddUsageText(
"See the fuzzing documentation in dev-docs for more information." );
341 int cmd_parsed_ok = cl_parser.Parse();
343 if( cmd_parsed_ok != 0 )
353 const bool verbose = cl_parser.Found(
"verbose" );
357 std::vector<wxString> libPaths;
359 for(
size_t i = 0; i < cl_parser.GetParamCount(); i++ )
360 libPaths.push_back( cl_parser.GetParam( i ) );
365 if( cl_parser.Found(
"lib-table", &tablePath ) )
368 wxFileName tableFn( tablePath );
369 tableFn.MakeAbsolute();
372 std::set<wxString> visited;
378 if( count == 0 && !verbose )
382 std::cerr << fmt::format(
"No libraries successfully parsed from table '{}'", tablePath.ToStdString() )
387 long aflLoopCount = 1;
388 cl_parser.Found(
"loop", &aflLoopCount );
390 if( libPaths.empty() )
394 if( cl_parser.Found(
"lib-table" ) )
398 while( __AFL_LOOP( aflLoopCount ) )
407 for(
const auto&
path : libPaths )
425 "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
Symbol library map sorted by the symbol name.