diff --git a/kicad/kicad_cli.cpp b/kicad/kicad_cli.cpp index b045438116..68d42d5ac4 100644 --- a/kicad/kicad_cli.cpp +++ b/kicad/kicad_cli.cpp @@ -36,6 +36,8 @@ #include #include +#include +#include #include #include "pgm_kicad.h" @@ -297,6 +299,74 @@ static void printHelp( argparse::ArgumentParser& argParser ) } +/** + * Check if a string looks like a numeric vector value that happens to start with a minus sign. + * + * This handles values like "-45,0,45" or "-3.5,0,1.2" which are valid vector arguments + * but get misinterpreted by argparse as unknown options because they start with '-'. + */ +static bool looksLikeNegativeVectorValue( const std::string& aValue ) +{ + if( aValue.empty() || aValue[0] != '-' ) + return false; + + if( aValue.find( ',' ) == std::string::npos ) + return false; + + for( size_t i = 1; i < aValue.size(); ++i ) + { + char c = aValue[i]; + + if( !std::isdigit( c ) && c != '.' && c != ',' && c != '-' && c != '+' ) + return false; + } + + return true; +} + + +/** + * Pre-process command line arguments to handle negative numeric values. + * + * The argparse library interprets values starting with '-' as option flags. + * For arguments that accept vector values (like --rotate, --pan, --pivot), + * we wrap negative values in single quotes to prevent argparse from treating + * them as options. The parsing code in command_pcb_render.cpp already strips + * these quotes via getToVector3(). + * + * Example: "--rotate -45,0,45" becomes "--rotate='-45,0,45'" + */ +static std::vector preprocessArgs( int argc, char** argv ) +{ + std::vector result; + + static const std::set vectorArgs = { + "--rotate", "--pan", "--pivot" + }; + + for( int i = 0; i < argc; ++i ) + { + std::string current( argv[i] ); + + if( vectorArgs.count( current ) && i + 1 < argc ) + { + std::string next( argv[i + 1] ); + + if( looksLikeNegativeVectorValue( next ) ) + { + result.push_back( current + "='" + next + "'" ); + ++i; + continue; + } + } + + result.push_back( current ); + } + + return result; +} + + bool PGM_KICAD::OnPgmInit() { PGM_BASE::BuildArgvUtf8(); @@ -349,7 +419,11 @@ int PGM_KICAD::OnPgmRun() // Use the C locale to parse arguments // Otherwise the decimal separator for the locale will be applied LOCALE_IO dummy; - argParser.parse_args( m_argcUtf8, m_argvUtf8 ); + + // Pre-process arguments to handle negative vector values (e.g., --rotate -45,0,45) + // which argparse would otherwise interpret as unknown options + std::vector args = preprocessArgs( m_argcUtf8, m_argvUtf8 ); + argParser.parse_args( args ); } // std::runtime_error doesn't seem to be enough for the scan<>() catch( const std::exception& err )