Browse Source

Shove kicad2step into pcbnew itself with a new cli

7.0
Mark Roszko 3 years ago
parent
commit
fb8a4c10f7
  1. 4
      CMakeLists.txt
  2. 1
      bitmap2component/CMakeLists.txt
  3. 8
      common/CMakeLists.txt
  4. 48
      common/cli/command.h
  5. 31
      common/cli/command_export_kicad_pcbnew.cpp
  6. 36
      common/cli/command_export_kicad_pcbnew.h
  7. 126
      common/cli/command_export_pcb_svg.cpp
  8. 36
      common/cli/command_export_pcb_svg.h
  9. 30
      common/cli/command_export_pcbnew.cpp
  10. 36
      common/cli/command_export_pcbnew.h
  11. 174
      common/cli/command_export_step.cpp
  12. 36
      common/cli/command_export_step.h
  13. 38
      common/cli/exit_codes.h
  14. 42
      common/jobs/job.h
  15. 38
      common/jobs/job_dispatcher.cpp
  16. 39
      common/jobs/job_dispatcher.h
  17. 49
      common/jobs/job_export_pcb_svg.h
  18. 34
      common/jobs/job_export_step.cpp
  19. 45
      common/jobs/job_export_step.h
  20. 8
      common/kiway.cpp
  21. 24
      common/pgm_base.cpp
  22. 148
      common/single_top.cpp
  23. 3
      eeschema/CMakeLists.txt
  24. 7
      eeschema/eeschema.cpp
  25. 1
      gerbview/CMakeLists.txt
  26. 8
      include/kiway.h
  27. 14
      include/kiway_player.h
  28. 10
      include/pgm_base.h
  29. 7
      kicad/CMakeLists.txt
  30. 87
      kicad/kicad.cpp
  31. 25
      libs/kiplatform/msw/app.cpp
  32. 1
      pagelayout_editor/CMakeLists.txt
  33. 1
      pcb_calculator/CMakeLists.txt
  34. 14
      pcbnew/CMakeLists.txt
  35. 68
      pcbnew/dialogs/dialog_export_step.cpp
  36. 81
      pcbnew/dialogs/dialog_export_svg.cpp
  37. 36
      pcbnew/exporters/step/CMakeLists.txt
  38. 146
      pcbnew/exporters/step/kicad2step.cpp
  39. 11
      pcbnew/exporters/step/kicad2step.h
  40. 0
      pcbnew/exporters/step/kicad2step_app.cpp
  41. 4
      pcbnew/exporters/step/kicad2step_frame_base.cpp
  42. 6
      pcbnew/exporters/step/kicad2step_frame_base.fbp
  43. 3
      pcbnew/exporters/step/kicad2step_frame_base.h
  44. 4
      pcbnew/exporters/step/panel_kicad2step.h
  45. 2
      pcbnew/exporters/step/pcb/3d_resolver.cpp
  46. 0
      pcbnew/exporters/step/pcb/3d_resolver.h
  47. 0
      pcbnew/exporters/step/pcb/base.cpp
  48. 0
      pcbnew/exporters/step/pcb/base.h
  49. 0
      pcbnew/exporters/step/pcb/kicadcurve.cpp
  50. 0
      pcbnew/exporters/step/pcb/kicadcurve.h
  51. 0
      pcbnew/exporters/step/pcb/kicadfootprint.cpp
  52. 0
      pcbnew/exporters/step/pcb/kicadfootprint.h
  53. 0
      pcbnew/exporters/step/pcb/kicadmodel.cpp
  54. 0
      pcbnew/exporters/step/pcb/kicadmodel.h
  55. 0
      pcbnew/exporters/step/pcb/kicadpad.cpp
  56. 0
      pcbnew/exporters/step/pcb/kicadpad.h
  57. 0
      pcbnew/exporters/step/pcb/kicadpcb.cpp
  58. 0
      pcbnew/exporters/step/pcb/kicadpcb.h
  59. 0
      pcbnew/exporters/step/pcb/oce_utils.cpp
  60. 0
      pcbnew/exporters/step/pcb/oce_utils.h
  61. 106
      pcbnew/pcb_plot_svg.cpp
  62. 43
      pcbnew/pcb_plot_svg.h
  63. 13
      pcbnew/pcbnew.cpp
  64. 102
      pcbnew/pcbnew_jobs_handler.cpp
  65. 34
      pcbnew/pcbnew_jobs_handler.h
  66. 5
      qa/tools/pcbnew_tools/CMakeLists.txt
  67. 1
      resources/msw/cmd-wrappers/kicad.cmd
  68. 1
      resources/msw/cmd-wrappers/pcbnew.cmd
  69. 1
      thirdparty/CMakeLists.txt
  70. 117
      thirdparty/argparse/.clang-format
  71. 21
      thirdparty/argparse/.clang-tidy
  72. 87
      thirdparty/argparse/.github/workflows/ci.yml
  73. 273
      thirdparty/argparse/.gitignore
  74. 39
      thirdparty/argparse/.travis.yml
  75. 98
      thirdparty/argparse/CMakeLists.txt
  76. 17
      thirdparty/argparse/CONTRIBUTING.md
  77. 7
      thirdparty/argparse/LICENSE
  78. 1143
      thirdparty/argparse/README.md
  79. 1
      thirdparty/argparse/clang_format.bash
  80. 10
      thirdparty/argparse/conanfile.py
  81. 1652
      thirdparty/argparse/include/argparse/argparse.hpp
  82. 7
      thirdparty/argparse/packaging/pkgconfig.pc.in
  83. 46
      thirdparty/argparse/samples/CMakeLists.txt
  84. 36
      thirdparty/argparse/samples/compound_arguments.cpp
  85. 27
      thirdparty/argparse/samples/custom_assignment_characters.cpp
  86. 31
      thirdparty/argparse/samples/custom_prefix_characters.cpp
  87. 17
      thirdparty/argparse/samples/description_epilog_metavar.cpp
  88. 24
      thirdparty/argparse/samples/gathering_remaining_arguments.cpp
  89. 26
      thirdparty/argparse/samples/is_used.cpp
  90. 28
      thirdparty/argparse/samples/joining_repeated_optional_arguments.cpp
  91. 30
      thirdparty/argparse/samples/list_of_arguments.cpp
  92. 32
      thirdparty/argparse/samples/negative_numbers.cpp
  93. 22
      thirdparty/argparse/samples/optional_flag_argument.cpp
  94. 26
      thirdparty/argparse/samples/parse_known_args.cpp
  95. 28
      thirdparty/argparse/samples/positional_argument.cpp
  96. 17
      thirdparty/argparse/samples/repeating_argument_to_increase_value.cpp
  97. 19
      thirdparty/argparse/samples/required_optional_argument.cpp
  98. 65
      thirdparty/argparse/samples/subcommands.cpp
  99. 2
      thirdparty/argparse/test/.gitignore
  100. 63
      thirdparty/argparse/test/CMakeLists.txt

4
CMakeLists.txt

@ -155,10 +155,6 @@ cmake_dependent_option( KICAD_WIN32_INSTALL_PDBS
OFF "WIN32"
OFF )
option( KICAD_STEP_EXPORT_LIB
"Build and use kicad2step as a library, meant for debugging"
OFF )
option( KICAD_USE_3DCONNEXION
"Build KiCad with support for 3Dconnexion devices (Currently only for Mac/MSW)"
OFF )

1
bitmap2component/CMakeLists.txt

@ -53,6 +53,7 @@ add_executable( bitmap2component WIN32 MACOSX_BUNDLE
target_link_libraries( bitmap2component
common
argparse::argparse
${wxWidgets_LIBRARIES}
potrace
)

8
common/CMakeLists.txt

@ -287,6 +287,12 @@ set( COMMON_SRCS
${PLUGINS_CADSTAR_SRCS}
${PLUGINS_EAGLE_SRCS}
${FONT_SRCS}
cli/command_export_kicad_pcbnew.cpp
cli/command_export_pcb_svg.cpp
cli/command_export_pcbnew.cpp
cli/command_export_step.cpp
jobs/job_export_step.cpp
jobs/job_dispatcher.cpp
advanced_config.cpp
array_axis.cpp
array_options.cpp
@ -481,6 +487,7 @@ target_link_libraries( common
compoundfilereader
pcm_settings
nanodbc # for now; maybe hoist out of common
argparse::argparse
${Boost_LIBRARIES}
${CURL_LIBRARIES}
${wxWidgets_LIBRARIES}
@ -574,6 +581,7 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/pcb_painter.cpp
${CMAKE_SOURCE_DIR}/pcbnew/plugins/kicad/pcb_parser.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_plot_params.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_plot_svg.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_screen.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcb_view.cpp
${CMAKE_SOURCE_DIR}/pcbnew/pcbnew_settings.cpp

48
common/cli/command.h

@ -0,0 +1,48 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLI_COMMAND_H
#define CLI_COMMAND_H
#include <argparse/argparse.hpp>
#include <kiway.h>
namespace CLI
{
struct COMMAND
{
COMMAND( std::string aName ) : m_name( aName ), m_argParser( aName ){};
virtual int Perform( KIWAY& aKiway ) const = 0;
virtual ~COMMAND() = default;
argparse::ArgumentParser& GetArgParser() { return m_argParser; }
const std::string& GetName() const { return m_name; }
protected:
std::string m_name;
argparse::ArgumentParser m_argParser;
};
}
#endif

31
common/cli/command_export_kicad_pcbnew.cpp

@ -0,0 +1,31 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_kicad_pcbnew.h"
CLI::EXPORT_KICAD_PCBNEW_COMMAND::EXPORT_KICAD_PCBNEW_COMMAND() : COMMAND( "export-pcb" )
{
}
int CLI::EXPORT_KICAD_PCBNEW_COMMAND::Perform( KIWAY& aKiway ) const
{
return 0;
}

36
common/cli/command_export_kicad_pcbnew.h

@ -0,0 +1,36 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_KICAD_PCBNEW_H
#define COMMAND_EXPORT_KICAD_PCBNEW_H
#include "command.h"
namespace CLI
{
struct EXPORT_KICAD_PCBNEW_COMMAND : public COMMAND
{
EXPORT_KICAD_PCBNEW_COMMAND();
int Perform( KIWAY& aKiway ) const override;
};
}
#endif

126
common/cli/command_export_pcb_svg.cpp

@ -0,0 +1,126 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_pcb_svg.h"
#include "exit_codes.h"
#include "jobs/job_export_pcb_svg.h"
#include <kiface_base.h>
#include <layer_ids.h>
#include <regex>
#include <macros.h>
#include <wx/tokenzr.h>
#define ARG_PAGE_SIZE "--page-size-mode"
#define ARG_MIRROR "--mirror"
#define ARG_BLACKANDWHITE "--black-and-white"
#define ARG_OUTPUT "--output"
#define ARG_THEME "--theme"
#define ARG_LAYERS "--layers"
#define ARG_INPUT "input"
CLI::EXPORT_PCB_SVG_COMMAND::EXPORT_PCB_SVG_COMMAND() : COMMAND( "svg" )
{
m_argParser.add_argument( "-o", ARG_OUTPUT )
.default_value( std::string() )
.help( "output file name" );
m_argParser.add_argument( "-l", ARG_LAYERS )
.default_value( std::string() )
.help( "comma separated list of untranslated layer names to include such as F.Cu,B.Cu" );
m_argParser.add_argument( "-m", ARG_MIRROR )
.help( "Mirror the board (useful for trying to show bottom layers)" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "-t", ARG_THEME )
.default_value( std::string() )
.help( "Color theme to use (will default to pcbnew settings)" );
m_argParser.add_argument( ARG_BLACKANDWHITE )
.help( "Black and white only" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_PAGE_SIZE )
.help( "Set page sizing mode (0 = page with frame and title block, 1 = current page size, 2 = board area only)" )
.default_value( 0 );
m_argParser.add_argument( ARG_INPUT ).help( "input file" );
}
int CLI::EXPORT_PCB_SVG_COMMAND::Perform( KIWAY& aKiway ) const
{
std::map<std::string, LSET> layerMasks;
for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
{
std::string untranslated = TO_UTF8( wxString( LSET::Name( PCB_LAYER_ID( layer ) ) ) );
//m_layerIndices[untranslated] = PCB_LAYER_ID( layer );
layerMasks[untranslated] = LSET( PCB_LAYER_ID( layer ) );
}
layerMasks["*.Cu"] = LSET::AllCuMask();
layerMasks["*In.Cu"] = LSET::InternalCuMask();
layerMasks["F&B.Cu"] = LSET( 2, F_Cu, B_Cu );
layerMasks["*.Adhes"] = LSET( 2, B_Adhes, F_Adhes );
layerMasks["*.Paste"] = LSET( 2, B_Paste, F_Paste );
layerMasks["*.Mask"] = LSET( 2, B_Mask, F_Mask );
layerMasks["*.SilkS"] = LSET( 2, B_SilkS, F_SilkS );
layerMasks["*.Fab"] = LSET( 2, B_Fab, F_Fab );
layerMasks["*.CrtYd"] = LSET( 2, B_CrtYd, F_CrtYd );
JOB_EXPORT_PCB_SVG* svgJob = new JOB_EXPORT_PCB_SVG( true );
svgJob->m_mirror = m_argParser.get<bool>( ARG_MIRROR );
svgJob->m_blackAndWhite = m_argParser.get<bool>( ARG_BLACKANDWHITE );
svgJob->m_pageSizeMode = m_argParser.get<int>( ARG_PAGE_SIZE );
svgJob->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
svgJob->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
svgJob->m_colorTheme = FROM_UTF8( m_argParser.get<std::string>( ARG_THEME ).c_str() );
wxString layers = FROM_UTF8( m_argParser.get<std::string>( ARG_LAYERS ).c_str() );
LSET layerMask = LSET::AllCuMask();
if( !layers.IsEmpty() )
{
layerMask.reset();
wxStringTokenizer layerTokens( layers, "," );
while( layerTokens.HasMoreTokens() )
{
std::string token = TO_UTF8(layerTokens.GetNextToken());
if( layerMasks.count( token ) )
{
layerMask |= layerMasks[token];
}
}
}
svgJob->m_printMaskLayer = layerMask;
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, svgJob );
return exitCode;
}

36
common/cli/command_export_pcb_svg.h

@ -0,0 +1,36 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_PCB_SVG_H
#define COMMAND_EXPORT_PCB_SVG_H
#include "command.h"
namespace CLI
{
struct EXPORT_PCB_SVG_COMMAND : public COMMAND
{
EXPORT_PCB_SVG_COMMAND();
int Perform( KIWAY& aKiway ) const override;
};
} // namespace CLI
#endif

30
common/cli/command_export_pcbnew.cpp

@ -0,0 +1,30 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_pcbnew.h"
CLI::EXPORT_PCBNEW_COMMAND::EXPORT_PCBNEW_COMMAND() : COMMAND( "export" )
{
}
int CLI::EXPORT_PCBNEW_COMMAND::Perform( KIWAY& aKiway ) const
{
return 0;
}

36
common/cli/command_export_pcbnew.h

@ -0,0 +1,36 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_PCBNEW_H
#define COMMAND_EXPORT_PCBNEW_H
#include "command.h"
namespace CLI
{
struct EXPORT_PCBNEW_COMMAND : public COMMAND
{
EXPORT_PCBNEW_COMMAND();
int Perform( KIWAY& aKiway ) const override;
};
}
#endif

174
common/cli/command_export_step.cpp

@ -0,0 +1,174 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "command_export_step.h"
#include "exit_codes.h"
#include "jobs/job_export_step.h"
#include <kiface_base.h>
#include <regex>
#include <macros.h>
#define ARG_DRILL_ORIGIN "--drill-origin"
#define ARG_GRID_ORIGIN "--grid-origin"
#define ARG_NO_VIRTUAL "--no-virtual"
#define ARG_SUBST_MODELS "--subst-models"
#define ARG_FORCE "--force"
#define ARG_OUTPUT "--output"
#define ARG_INPUT "input"
#define ARG_MIN_DISTANCE "--min-distance"
#define ARG_USER_ORIGIN "--user-origin"
#define ARG_GUI "--gui"
#define REGEX_QUANTITY "([\\s]*[+-]?[\\d]*[.]?[\\d]*)"
#define REGEX_DELIMITER "(?:[\\s]*x)"
#define REGEX_UNIT "([m]{2}|(?:in))"
CLI::EXPORT_STEP_COMMAND::EXPORT_STEP_COMMAND() : COMMAND( "step" )
{
m_argParser.add_argument( ARG_DRILL_ORIGIN )
.help( "Use Drill Origin for output origin" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_GRID_ORIGIN )
.help( "Use Grid Origin for output origin" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_NO_VIRTUAL )
.help( "Exclude 3D models for components with 'virtual' attribute" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( "--subst-models" )
.help( "Substitute STEP or IGS models with the same name in place of VRML models" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_FORCE, "-f" )
.help( "overwrite output file" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_GUI )
.help( "Show GUI (log window)" )
.implicit_value( true )
.default_value( false );
m_argParser.add_argument( ARG_MIN_DISTANCE )
.default_value( std::string() )
.help( "Minimum distance between points to treat them as separate ones (default 0.01mm)" );
m_argParser.add_argument( ARG_USER_ORIGIN )
.default_value( std::string() )
.help( "User-specified output origin ex. 1x1in, 1x1inch, 25.4x25.4mm (default mm)" );
m_argParser.add_argument( "-o", ARG_OUTPUT )
.default_value( std::string() )
.help( "output file name" );
m_argParser.add_argument( ARG_INPUT ).help( "input file" );
}
int CLI::EXPORT_STEP_COMMAND::Perform( KIWAY& aKiway ) const
{
JOB_EXPORT_STEP* step = new JOB_EXPORT_STEP( true );
step->m_useDrillOrigin = m_argParser.get<bool>( ARG_DRILL_ORIGIN );
step->m_useGridOrigin = m_argParser.get<bool>( ARG_GRID_ORIGIN );
step->m_includeVirtual = !m_argParser.get<bool>( ARG_NO_VIRTUAL );
step->m_substModels = m_argParser.get<bool>( ARG_SUBST_MODELS );
step->m_overwrite = m_argParser.get<bool>( ARG_FORCE );
step->m_filename = FROM_UTF8( m_argParser.get<std::string>( ARG_INPUT ).c_str() );
step->m_outputFile = FROM_UTF8( m_argParser.get<std::string>( ARG_OUTPUT ).c_str() );
step->m_gui = m_argParser.get<bool>( ARG_GUI );
wxString userOrigin = FROM_UTF8( m_argParser.get<std::string>( ARG_USER_ORIGIN ).c_str() );
if( !userOrigin.IsEmpty() )
{
std::regex re_pattern( REGEX_QUANTITY REGEX_DELIMITER REGEX_QUANTITY REGEX_UNIT,
std::regex_constants::icase );
std::smatch sm;
std::string str( userOrigin.ToUTF8() );
std::regex_search( str, sm, re_pattern );
step->m_xOrigin = atof( sm.str( 1 ).c_str() );
step->m_yOrigin = atof( sm.str( 2 ).c_str() );
std::string tunit( sm[3] );
if( tunit.size() > 0 ) // No unit accepted ( default = mm )
{
if( ( !sm.str( 1 ).compare( " " ) || !sm.str( 2 ).compare( " " ) )
|| ( sm.size() != 4 ) )
{
std::cout << m_argParser;
return CLI::EXIT_CODES::ERR_ARGS;
}
// only in, inch and mm are valid:
if( !tunit.compare( "in" ) || !tunit.compare( "inch" ) )
{
step->m_xOrigin *= 25.4;
step->m_yOrigin *= 25.4;
}
else if( tunit.compare( "mm" ) )
{
std::cout << m_argParser;
return CLI::EXIT_CODES::ERR_ARGS;
}
}
}
wxString minDistance = FROM_UTF8( m_argParser.get<std::string>( ARG_MIN_DISTANCE ).c_str() );
if( !minDistance.IsEmpty() )
{
std::istringstream istr;
istr.str( std::string( minDistance.ToUTF8() ) );
istr >> step->m_minDistance;
if( istr.fail() )
{
std::cout << m_argParser;
return CLI::EXIT_CODES::ERR_ARGS;
}
if( !istr.eof() )
{
std::string tunit;
istr >> tunit;
if( !tunit.compare( "in" ) || !tunit.compare( "inch" ) )
{
step->m_minDistance *= 25.4;
}
else if( tunit.compare( "mm" ) )
{
std::cout << m_argParser;
return CLI::EXIT_CODES::ERR_ARGS;
}
}
}
int exitCode = aKiway.ProcessJob( KIWAY::FACE_PCB, step );
return exitCode;
}

36
common/cli/command_export_step.h

@ -0,0 +1,36 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMAND_EXPORT_STEP_H
#define COMMAND_EXPORT_STEP_H
#include "command.h"
namespace CLI
{
struct EXPORT_STEP_COMMAND : public COMMAND
{
EXPORT_STEP_COMMAND();
int Perform( KIWAY& aKiway ) const override;
};
}
#endif

38
common/cli/exit_codes.h

@ -0,0 +1,38 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLI_EXIT_CODES_H
#define CLI_EXIT_CODES_H
namespace CLI
{
namespace EXIT_CODES
{
static const int AVOID_CLOSING = -1;
static const int SUCCESS = 0;
static const int OK = 0;
static const int ERR_ARGS = 1;
static const int ERR_UNKNOWN = 2;
static const int ERR_INVALID_INPUT_FILE = 3;
static const int ERR_INVALID_OUTPUT_CONFLICT = 4;
};
}
#endif

42
common/jobs/job.h

@ -0,0 +1,42 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_H
#define JOB_H
/**
* An simple container class that lets us dispatch output jobs to kifaces
*/
class JOB
{
public:
JOB( const std::string& aType, bool aIsCli ) : m_type( aType ), m_isCli( aIsCli ) {}
virtual ~JOB() {}
const std::string& GetType() const { return m_type; };
bool IsCli() const { return m_isCli; };
private:
std::string m_type;
bool m_isCli;
};
#endif

38
common/jobs/job_dispatcher.cpp

@ -0,0 +1,38 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cli/exit_codes.h>
#include <jobs/job_dispatcher.h>
void JOB_DISPATCHER::Register( const std::string& aJobTypeName,
std::function<int( JOB* job )> aHandler )
{
m_jobHandlers.emplace( aJobTypeName, aHandler );
}
int JOB_DISPATCHER::RunJob( JOB* job )
{
if( m_jobHandlers.count( job->GetType() ) )
{
return m_jobHandlers[job->GetType()]( job );
}
return CLI::EXIT_CODES::ERR_UNKNOWN;
}

39
common/jobs/job_dispatcher.h

@ -0,0 +1,39 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_DISPATCHER_H
#define JOB_DISPATCHER_H
#include <functional>
#include <string>
#include <map>
#include <jobs/job.h>
class JOB_DISPATCHER
{
public:
void Register( const std::string& aJobTypeName, std::function<int( JOB* job )> aHandler );
int RunJob( JOB* job );
private:
std::map<std::string, std::function<int( JOB* job )>> m_jobHandlers;
};
#endif

49
common/jobs/job_export_pcb_svg.h

@ -0,0 +1,49 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_EXPORT_PCB_SVG_H
#define JOB_EXPORT_PCB_SVG_H
#include <layer_ids.h>
#include <wx/string.h>
#include "job.h"
class JOB_EXPORT_PCB_SVG : public JOB
{
public:
JOB_EXPORT_PCB_SVG( bool aIsCli ) :
JOB( "svg", aIsCli ), m_filename(), m_outputFile(), m_colorTheme(), m_mirror( false ),
m_blackAndWhite( false ), m_pageSizeMode( 0 ), m_printMaskLayer()
{
}
wxString m_filename;
wxString m_outputFile;
wxString m_colorTheme;
bool m_mirror;
bool m_blackAndWhite;
int m_pageSizeMode;
LSET m_printMaskLayer;
};
#endif

34
common/jobs/job_export_step.cpp

@ -0,0 +1,34 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "jobs/job_export_step.h"
JOB_EXPORT_STEP::JOB_EXPORT_STEP( bool aIsCli ) : JOB( "step", aIsCli )
{
m_overwrite = false;
m_useGridOrigin = false;
m_useDrillOrigin = false;
m_includeVirtual = true;
m_substModels = false;
m_xOrigin = 0.0;
m_yOrigin = 0.0;
m_minDistance = 0.0;
m_gui = false;
}

45
common/jobs/job_export_step.h

@ -0,0 +1,45 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef JOB_EXPORT_STEP_H
#define JOB_EXPORT_STEP_H
#include <wx/string.h>
#include "job.h"
class JOB_EXPORT_STEP : public JOB
{
public:
JOB_EXPORT_STEP( bool aIsCli );
bool m_overwrite;
bool m_useGridOrigin;
bool m_useDrillOrigin;
bool m_includeVirtual;
bool m_substModels;
wxString m_filename;
wxString m_outputFile;
double m_xOrigin;
double m_yOrigin;
double m_minDistance;
bool m_gui;
};
#endif

8
common/kiway.cpp

@ -654,6 +654,14 @@ bool KIWAY::ProcessEvent( wxEvent& aEvent )
}
int KIWAY::ProcessJob( KIWAY::FACE_T aFace, JOB* job )
{
KIFACE* kiface = KiFACE( aFace );
return kiface->HandleJob( job );
}
void KIWAY::OnKiCadExit()
{
if( m_ctl & KFCTL_CPP_PROJECT_SUITE )

24
common/pgm_base.cpp

@ -124,6 +124,8 @@ PGM_BASE::PGM_BASE()
m_Printing = false;
m_Quitting = false;
m_ModalDialogCount = 0;
m_argcUtf8 = 0;
m_argvUtf8 = nullptr;
setLanguageId( wxLANGUAGE_DEFAULT );
@ -134,6 +136,13 @@ PGM_BASE::PGM_BASE()
PGM_BASE::~PGM_BASE()
{
Destroy();
for( size_t n = 0; n < m_argcUtf8; n++ )
{
delete m_argvUtf8[n];
}
delete m_argvUtf8;
}
@ -370,6 +379,21 @@ void PGM_BASE::sentryPrompt()
#endif
void PGM_BASE::BuildArgvUtf8()
{
const wxArrayString& argArray = App().argv.GetArguments();
m_argcUtf8 = argArray.size();
m_argvUtf8 = new char*[m_argcUtf8 + 1];
for( size_t n = 0; n < m_argcUtf8; n++ )
{
m_argvUtf8[n] = wxStrdup( argArray[n].ToUTF8() );
}
m_argvUtf8[m_argcUtf8] = NULL; // null terminator at end of argv
}
bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit )
{
// Just make sure we init precreate any folders early for later code

148
common/single_top.cpp

@ -40,6 +40,7 @@
#include <wx/stdpaths.h>
#include <wx/snglinst.h>
#include <wx/html/htmlwin.h>
#include <argparse/argparse.hpp>
#include <kiway.h>
#include <pgm_base.h>
@ -48,9 +49,14 @@
#include <confirm.h>
#include <settings/settings_manager.h>
#include <kicad_build_version.h>
#include <kiplatform/app.h>
#include <kiplatform/environment.h>
#include "cli/command_export_pcbnew.h"
#include "cli/command_export_pcb_svg.h"
#include "cli/command_export_step.h"
#include "cli/exit_codes.h"
// Only a single KIWAY is supported in this single_top top level component,
// which is dedicated to loading only a single DSO.
@ -274,8 +280,36 @@ struct APP_SINGLE_TOP : public wxApp
IMPLEMENT_APP( APP_SINGLE_TOP )
struct COMMAND_ENTRY
{
CLI::COMMAND* handler;
std::vector<COMMAND_ENTRY> subCommands;
COMMAND_ENTRY( CLI::COMMAND* aHandler ) : handler( aHandler ){};
COMMAND_ENTRY( CLI::COMMAND* aHandler, std::vector<COMMAND_ENTRY> aSub ) :
handler( aHandler ), subCommands( aSub ) {};
};
#ifdef PCBNEW
static CLI::EXPORT_STEP_COMMAND stepCmd{};
static CLI::EXPORT_PCB_SVG_COMMAND svgCmd{};
static CLI::EXPORT_PCBNEW_COMMAND exportCmd{};
static std::vector<COMMAND_ENTRY> commandStack = {
{ &exportCmd, { &stepCmd, &svgCmd } }
};
#else
static std::vector<COMMAND_ENTRY> commandStack = {
};
#endif
bool PGM_SINGLE_TOP::OnPgmInit()
{
PGM_BASE::BuildArgvUtf8();
#if defined(DEBUG)
wxString absoluteArgv0 = wxStandardPaths::Get().GetExecutablePath();
@ -285,10 +319,62 @@ bool PGM_SINGLE_TOP::OnPgmInit()
return false;
}
#endif
wxString pgm_name;
if( App().argc == 0 )
pgm_name = wxT( "kicad" );
else
pgm_name = wxFileName( App().argv[0] ).GetName().Lower();
argparse::ArgumentParser argParser( std::string( pgm_name.utf8_str() ), KICAD_MAJOR_MINOR_VERSION );
for(COMMAND_ENTRY& entry : commandStack)
{
argParser.add_subparser( entry.handler->GetArgParser() );
for( COMMAND_ENTRY& subentry : entry.subCommands )
{
entry.handler->GetArgParser().add_subparser( subentry.handler->GetArgParser() );
}
}
try
{
argParser.parse_args( m_argcUtf8, m_argvUtf8 );
}
catch( const std::runtime_error& err )
{
// this provides the nice pretty print
std::cerr << err.what() << std::endl;
std::cerr << argParser;
std::exit( CLI::EXIT_CODES::ERR_ARGS );
}
bool cliCmdRequested = false;
CLI::COMMAND* cliCmd = nullptr;
for( COMMAND_ENTRY& entry : commandStack )
{
if( argParser.is_subcommand_used( entry.handler->GetName() ) )
{
for( COMMAND_ENTRY& subentry : entry.subCommands )
{
if( entry.handler->GetArgParser().is_subcommand_used( subentry.handler->GetName() ) )
{
cliCmd = subentry.handler;
cliCmdRequested = true;
}
}
if( !cliCmdRequested )
{
cliCmd = entry.handler;
}
}
}
// Not all kicad applications use the python stuff. skip python init
// for these apps.
bool skip_python_initialization = false;
bool skip_python_initialization = cliCmdRequested;
#if defined( BITMAP_2_CMP ) || defined( PL_EDITOR ) || defined( GERBVIEW ) ||\
defined( PCB_CALCULATOR_BUILD )
skip_python_initialization = true;
@ -320,53 +406,29 @@ bool PGM_SINGLE_TOP::OnPgmInit()
Kiway.set_kiface( KIWAY::KifaceType( TOP_FRAME ), kiface );
#endif
static const wxCmdLineEntryDesc desc[] = {
{ wxCMD_LINE_OPTION, "f", "frame", "Frame to load", wxCMD_LINE_VAL_STRING, 0 },
{ wxCMD_LINE_PARAM, nullptr, nullptr, "File to load", wxCMD_LINE_VAL_STRING,
wxCMD_LINE_PARAM_MULTIPLE | wxCMD_LINE_PARAM_OPTIONAL },
{ wxCMD_LINE_NONE, nullptr, nullptr, nullptr, wxCMD_LINE_VAL_NONE, 0 }
};
wxCmdLineParser parser( App().argc, App().argv );
parser.SetDesc( desc );
parser.Parse( false );
FRAME_T appType = TOP_FRAME;
const struct
{
wxString name;
FRAME_T type;
} frameTypes[] = {
{ wxT( "pcb" ), FRAME_PCB_EDITOR },
{ wxT( "fpedit" ), FRAME_FOOTPRINT_EDITOR },
{ wxT( "" ), FRAME_T_COUNT }
};
wxString frameName;
// Tell the settings manager about the current Kiway
GetSettingsManager().SetKiway( &Kiway );
if( parser.Found( "frame", &frameName ) )
if( cliCmdRequested )
{
appType = FRAME_T_COUNT;
for( const auto& it : frameTypes )
int exitCode = CLI::EXIT_CODES::ERR_UNKNOWN;
if( cliCmd )
{
if( it.name == frameName )
appType = it.type;
exitCode = cliCmd->Perform( Kiway );
}
if( appType == FRAME_T_COUNT )
if( exitCode != CLI::EXIT_CODES::AVOID_CLOSING )
{
wxLogError( wxT( "Unknown frame: %s" ), frameName );
// Clean up
OnPgmExit();
return false;
std::exit( exitCode );
}
else
{
return true;
}
}
// Tell the settings manager about the current Kiway
GetSettingsManager().SetKiway( &Kiway );
// Use KIWAY to create a top window, which registers its existence also.
// "TOP_FRAME" is a macro that is passed on compiler command line from CMake,
// and is one of the types in FRAME_T.
@ -390,14 +452,10 @@ bool PGM_SINGLE_TOP::OnPgmInit()
frame->Show();
wxSafeYield();
// Individual frames may provide additional option/switch processing, but for compatibility,
// any positional arguments are treated as a list of files to pass to OpenProjectFiles
frame->ParseArgs( parser );
// Now after the frame processing, the rest of the positional args are files
std::vector<wxString> fileArgs;
if( parser.GetParamCount() )
if( App().argc > 1 )
{
/*
gerbview handles multiple project data files, i.e. gerber files on
@ -408,15 +466,15 @@ bool PGM_SINGLE_TOP::OnPgmInit()
launcher.
*/
for( size_t i = 0; i < parser.GetParamCount(); i++ )
fileArgs.push_back( parser.GetParam( i ) );
for( size_t i = 1; i < App().argc; i++ )
fileArgs.push_back( App().argv[i] );
// special attention to a single argument: argv[1] (==argSet[0])
if( fileArgs.size() == 1 )
{
wxFileName argv1( fileArgs[0] );
#if defined(PGM_DATA_FILE_EXT)
#if defined( PGM_DATA_FILE_EXT )
// PGM_DATA_FILE_EXT, if present, may be different for each compile,
// it may come from CMake on the compiler command line, but often does not.
// This facility is mostly useful for those program footprints

3
eeschema/CMakeLists.txt

@ -278,7 +278,7 @@ set( EESCHEMA_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/ibis/ibis_parser.cpp
${CMAKE_SOURCE_DIR}/pcbnew/ibis/kibis.cpp
# Some simulation features must be built even if libngspice is not linked.
sim/sim_library.cpp
sim/sim_library_spice.cpp
@ -427,6 +427,7 @@ target_link_libraries( eeschema
# There's way too much crap coming in from common yet.
gal
common
argparse::argparse
${wxWidgets_LIBRARIES}
)

7
eeschema/eeschema.cpp

@ -298,6 +298,9 @@ static struct IFACE : public KIFACE_BASE
const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
const wxString& aSrcFilePath, wxString& aErrors ) override;
int HandleJob( JOB* aJob ) override;
} kiface( "eeschema", KIWAY::FACE_SCH );
} // namespace
@ -560,3 +563,7 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje
}
}
int IFACE::HandleJob( JOB* aJob )
{
return 0;
}

1
gerbview/CMakeLists.txt

@ -112,6 +112,7 @@ target_link_libraries( gerbview
gal
common
nlohmann_json
argparse::argparse
${wxWidgets_LIBRARIES}
)

8
include/kiway.h

@ -104,6 +104,7 @@
#include <frame_type.h>
#include <mail_type.h>
#include <ki_exception.h>
#include <jobs/job.h>
#define KIFACE_VERSION 1
@ -233,6 +234,11 @@ struct KIFACE
* Append this Kiface's registered actions to the given list.
*/
virtual void GetActions( std::vector<TOOL_ACTION*>& aActions ) const = 0;
virtual int HandleJob( JOB* aJob )
{
return 0;
}
};
@ -403,6 +409,8 @@ public:
bool ProcessEvent( wxEvent& aEvent ) override;
int ProcessJob( KIWAY::FACE_T aFace, JOB* job );
/**
* Gets the window pointer to the blocking dialog (to send it signals)
* @return Pointer to blocking dialog window or null if none

14
include/kiway_player.h

@ -127,20 +127,6 @@ public:
return false;
}
/**
* Handle command-line arguments in a frame-specific way.
*
* The given argument parser has already been initialized with the command line and any
* options/switches that are handled by the top-level launcher before passing control to
* the child frame.
*
* @param aParser is the argument parser created by the top-level launcher.
*/
virtual void ParseArgs( wxCmdLineParser& aParser )
{
WXUNUSED( aParser );
}
/**
* Show this wxFrame as if it were a modal dialog, with all other instantiated wxFrames

10
include/pgm_base.h

@ -118,6 +118,11 @@ public:
virtual void OnPgmExit() = 0; // call this from wxApp::OnExit()
#endif
/**
* Builds the UTF8 based argv variable
*/
void BuildArgvUtf8();
/**
* Specific to MacOSX (not used under Linux or Windows).
*
@ -342,6 +347,11 @@ protected:
wxFileName m_sentry_uid_fn;
wxString m_sentryUid;
#endif
char** m_argvUtf8; /// argv parameters converted to utf8 form, because wxwidgets has opinions
/// and will return argv as either force converted to ascii in char* or wchar_t only
int m_argcUtf8;
};

7
kicad/CMakeLists.txt

@ -107,11 +107,12 @@ if( KICAD_WIN32_INSTALL_PDBS )
install(FILES $<TARGET_PDB_FILE:kicad> DESTINATION ${KICAD_BIN})
endif()
if( MSVC )
# Allow for MSVC to run from the build directory
if( WIN32 )
add_custom_command( TARGET kicad POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/pcm/schemas" "${CMAKE_BINARY_DIR}/schemas"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/kicad.cmd" "$<TARGET_FILE_DIR:kicad>"
)
install(FILES "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/kicad.cmd" DESTINATION ${KICAD_BIN})
endif()
if( APPLE )

87
kicad/kicad.cpp

@ -51,9 +51,13 @@
#include "pgm_kicad.h"
#include "kicad_manager_frame.h"
#include <kicad_build_version.h>
#include <kiplatform/app.h>
#include <kiplatform/environment.h>
#include "cli/command_export_kicad_pcbnew.h"
#include "cli/command_export_step.h"
#include "cli/exit_codes.h"
// a dummy to quiet linking with EDA_BASE_FRAME::config();
#include <kiface_base.h>
@ -89,9 +93,25 @@ PGM_KICAD& PgmTop()
return program;
}
struct COMMAND_ENTRY
{
CLI::COMMAND* handler;
std::vector<COMMAND_ENTRY> subCommands;
COMMAND_ENTRY( CLI::COMMAND* aHandler ) : handler( aHandler ){};
COMMAND_ENTRY( CLI::COMMAND* aHandler, std::vector<COMMAND_ENTRY> aSub ) :
handler( aHandler ), subCommands( aSub ){};
};
static CLI::EXPORT_STEP_COMMAND stepCmd{};
static CLI::EXPORT_KICAD_PCBNEW_COMMAND exportPcbCmd{};
static std::vector<COMMAND_ENTRY> commandStack = { { &exportPcbCmd, { &stepCmd } } };
bool PGM_KICAD::OnPgmInit()
{
PGM_BASE::BuildArgvUtf8();
App().SetAppDisplayName( wxT( "KiCad" ) );
#if defined(DEBUG)
@ -104,6 +124,55 @@ bool PGM_KICAD::OnPgmInit()
}
#endif
argparse::ArgumentParser argParser( std::string( "kicad" ),
KICAD_MAJOR_MINOR_VERSION );
for( COMMAND_ENTRY& entry : commandStack )
{
argParser.add_subparser( entry.handler->GetArgParser() );
for( COMMAND_ENTRY& subentry : entry.subCommands )
{
entry.handler->GetArgParser().add_subparser( subentry.handler->GetArgParser() );
}
}
try
{
argParser.parse_args( m_argcUtf8, m_argvUtf8 );
}
catch( const std::runtime_error& err )
{
// this provides the nice pretty print
std::cerr << err.what() << std::endl;
std::cerr << argParser;
std::exit( CLI::EXIT_CODES::ERR_ARGS );
}
bool cliCmdRequested = false;
CLI::COMMAND* cliCmd = nullptr;
for( COMMAND_ENTRY& entry : commandStack )
{
if( argParser.is_subcommand_used( entry.handler->GetName() ) )
{
for( COMMAND_ENTRY& subentry : entry.subCommands )
{
if( entry.handler->GetArgParser().is_subcommand_used(
subentry.handler->GetName() ) )
{
cliCmd = subentry.handler;
cliCmdRequested = true;
}
}
if( !cliCmdRequested )
{
cliCmd = entry.handler;
}
}
}
if( !InitPgm() )
return false;
@ -148,6 +217,24 @@ bool PGM_KICAD::OnPgmInit()
m_bm.m_search.Insert( it->second.GetValue(), 0 );
}
if( cliCmdRequested )
{
int exitCode = CLI::EXIT_CODES::ERR_UNKNOWN;
if( cliCmd )
{
exitCode = cliCmd->Perform( Kiway );
}
if( exitCode != CLI::EXIT_CODES::AVOID_CLOSING )
{
std::exit( exitCode );
}
else
{
return true;
}
}
KICAD_MANAGER_FRAME* frame = new KICAD_MANAGER_FRAME( nullptr, wxT( "KiCad" ),
wxDefaultPosition, wxSize( 775, -1 ) );
App().SetTopWindow( frame );

25
libs/kiplatform/msw/app.cpp

@ -28,6 +28,8 @@
#include <strsafe.h>
#include <config.h>
#include <VersionHelpers.h>
#include <iostream>
#include <cstdio>
#if defined( _MSC_VER )
#include <werapi.h> // issues on msys2
@ -63,22 +65,35 @@ bool KIPLATFORM::APP::Init()
// In order to support GUI and CLI
// Let's attach to console when it's possible
HANDLE handleStdOut, handleStdErr;
HANDLE handle;
if( AttachConsole( ATTACH_PARENT_PROCESS ) )
{
handleStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
if( handleStdOut != INVALID_HANDLE_VALUE )
if( GetStdHandle( STD_INPUT_HANDLE ) != INVALID_HANDLE_VALUE )
{
freopen( "CONIN$", "r", stdin );
setvbuf( stdin, NULL, _IONBF, 0 );
}
if( GetStdHandle( STD_OUTPUT_HANDLE ) != INVALID_HANDLE_VALUE )
{
freopen( "CONOUT$", "w", stdout );
setvbuf( stdout, NULL, _IONBF, 0 );
}
handleStdErr = GetStdHandle( STD_ERROR_HANDLE );
if( handleStdErr != INVALID_HANDLE_VALUE )
if( GetStdHandle( STD_ERROR_HANDLE ) != INVALID_HANDLE_VALUE )
{
freopen( "CONOUT$", "w", stderr );
setvbuf( stderr, NULL, _IONBF, 0 );
}
std::ios::sync_with_stdio( true );
std::wcout.clear();
std::cout.clear();
std::wcerr.clear();
std::cerr.clear();
std::wcin.clear();
std::cin.clear();
}
return true;

1
pagelayout_editor/CMakeLists.txt

@ -85,6 +85,7 @@ target_link_libraries( pl_editor
# There's way too much crap coming in from common yet.
gal
common
argparse::argparse
${wxWidgets_LIBRARIES}
)

1
pcb_calculator/CMakeLists.txt

@ -90,6 +90,7 @@ target_link_libraries( pcb_calculator
#singletop # replaces common, giving us restrictive control and link warnings.
# There's way too much crap coming in from common yet.
common
argparse::argparse
${wxWidgets_LIBRARIES}
)

14
pcbnew/CMakeLists.txt

@ -13,6 +13,7 @@ add_definitions( -DPCBNEW )
add_subdirectory(connectivity)
add_subdirectory(router)
add_subdirectory(exporters/step)
# psnrouter depends on make_lexer outputs in common (bug #1285878 )
add_dependencies( pnsrouter pcbcommon )
@ -313,6 +314,7 @@ set( PCBNEW_CLASS_SRCS
pcb_layer_box_selector.cpp
pcb_edit_frame.cpp
pcbnew_config.cpp
pcbnew_jobs_handler.cpp
pcbnew_printout.cpp
pcbnew_settings.cpp
pcbplot.cpp
@ -639,6 +641,7 @@ target_link_libraries( pcbnew
scripting
nlohmann_json
rectpack2d
argparse::argparse
${wxWidgets_LIBRARIES}
)
@ -674,16 +677,13 @@ target_link_libraries( pcbnew_kiface_objects
tinyspline_lib
nlohmann_json
rectpack2d
kicad2step_lib
)
target_include_directories( pcbnew_kiface_objects PRIVATE
$<TARGET_PROPERTY:thread-pool,INTERFACE_INCLUDE_DIRECTORIES>
)
if( KICAD_STEP_EXPORT_LIB )
add_definitions( -DKICAD_STEP_EXPORT_LIB )
endif()
add_library( pcbnew_kiface MODULE )
set_target_properties( pcbnew_kiface PROPERTIES
@ -756,6 +756,12 @@ if( WIN32 )
add_custom_command( TARGET pcbnew POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:kicad_3dsg>" "$<TARGET_FILE_DIR:pcbnew>"
)
add_custom_command( TARGET pcbnew POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/pcbnew.cmd" "$<TARGET_FILE_DIR:pcbnew>"
)
install(FILES "${CMAKE_SOURCE_DIR}/resources/msw/cmd-wrappers/pcbnew.cmd" DESTINATION ${KICAD_BIN})
endif()
# these 2 binaries are a matched set, keep them together:

68
pcbnew/dialogs/dialog_export_step.cpp

@ -46,9 +46,7 @@
#include <filename_resolver.h>
#ifdef KICAD_STEP_EXPORT_LIB
#include <kicad2step.h>
#endif
class DIALOG_EXPORT_STEP : public DIALOG_EXPORT_STEP_BASE
@ -371,7 +369,6 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
double xOrg = 0.0;
double yOrg = 0.0;
#ifndef KICAD_STEP_EXPORT_LIB
wxFileName appK2S( wxStandardPaths::Get().GetExecutablePath() );
#ifdef __WXMAC__
// On macOS, we have standalone applications inside the main bundle, so we handle that here:
@ -385,12 +382,16 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
}
#endif
appK2S.SetName( wxT( "kicad2step" ) );
appK2S.SetName( wxT( "pcbnew" ) );
wxString cmdK2S = wxT( "\"" );
cmdK2S.Append( appK2S.GetFullPath() );
cmdK2S.Append( wxT( "\"" ) );
cmdK2S.Append( wxT( " export" ) );
cmdK2S.Append( wxT( " step" ) );
cmdK2S.Append( wxT( " --gui" ) );
if( GetNoVirtOption() )
cmdK2S.Append( wxT( " --no-virtual" ) );
@ -458,65 +459,8 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
// Output file path.
cmdK2S.Append( wxString::Format( wxT( " %c%s%c" ), quote, m_boardPath, quote ) );
wxLogTrace( traceKiCad2Step, wxT( "KiCad2Step command: %s" ), cmdK2S );
wxLogTrace( traceKiCad2Step, wxT( "export step command: %s" ), cmdK2S );
wxExecute( cmdK2S, wxEXEC_ASYNC | wxEXEC_SHOW_CONSOLE );
#else
KICAD2MCAD_PRMS params;
params.m_filename = m_boardPath;
params.m_outputFile = m_filePickerSTEP->GetPath();
params.m_includeVirtual = !GetNoVirtOption();
params.m_substModels = GetSubstOption();
params.m_minDistance = tolerance;
params.m_overwrite = true;
switch( orgOpt )
{
case DIALOG_EXPORT_STEP::STEP_ORG_0:
break;
case DIALOG_EXPORT_STEP::STEP_ORG_PLOT_AXIS:
params.m_useDrillOrigin = true;
break;
case DIALOG_EXPORT_STEP::STEP_ORG_GRID_AXIS:
params.m_useGridOrigin = true;
break;
case DIALOG_EXPORT_STEP::STEP_ORG_USER:
{
xOrg = GetXOrg();
yOrg = GetYOrg();
if( GetOrgUnitsChoice() == 1 )
{
// selected reference unit is in inches, and STEP units are mm
xOrg *= 25.4;
yOrg *= 25.4;
}
params.m_xOrigin = xOrg;
params.m_yOrigin = yOrg;
break;
}
case DIALOG_EXPORT_STEP::STEP_ORG_BOARD_CENTER:
{
BOX2I bbox = m_parent->GetBoard()->ComputeBoundingBox( true );
xOrg = pcbIUScale.IUTomm( bbox.GetCenter().x );
yOrg = pcbIUScale.IUTomm( bbox.GetCenter().y );
params.m_xOrigin = xOrg;
params.m_yOrigin = yOrg;
break;
}
}
KICAD2STEP converter( params );
converter.Run();
#endif
aEvent.Skip(); // Close the dialog
}

81
pcbnew/dialogs/dialog_export_svg.cpp

@ -41,6 +41,7 @@
#include <plotters/plotters_pslike.h>
#include <wx/dirdlg.h>
#include <pgm_base.h>
#include <pcb_plot_svg.h>
class DIALOG_EXPORT_SVG : public DIALOG_EXPORT_SVG_BASE
{
@ -68,8 +69,6 @@ private:
void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) override;
void ExportSVGFile( bool aOnlyOneFile );
bool CreateSVGFile( const wxString& FullFileName );
LSET getCheckBoxSelectedLayers() const;
};
@ -281,6 +280,13 @@ void DIALOG_EXPORT_SVG::ExportSVGFile( bool aOnlyOneFile )
LSET all_selected = getCheckBoxSelectedLayers();
PCB_PLOT_SVG_OPTIONS svgPlotOptions;
svgPlotOptions.m_blackAndWhite = m_printBW;
svgPlotOptions.m_printMaskLayer = m_printMaskLayer;
svgPlotOptions.m_pageSizeMode = m_rbSvgPageSizeOpt->GetSelection();
svgPlotOptions.m_colorTheme = ""; // will use default
svgPlotOptions.m_mirror = m_printMirror;
for( LSEQ seq = all_selected.Seq(); seq; ++seq )
{
PCB_LAYER_ID layer = *seq;
@ -295,7 +301,10 @@ void DIALOG_EXPORT_SVG::ExportSVGFile( bool aOnlyOneFile )
if( m_checkboxEdgesOnAllPages->GetValue() )
m_printMaskLayer.set( Edge_Cuts );
if( CreateSVGFile( svgPath ) )
svgPlotOptions.m_outputFile = svgPath;
svgPlotOptions.m_printMaskLayer = m_printMaskLayer;
if( PCB_PLOT_SVG::Plot(m_board, svgPlotOptions ) )
{
reporter.Report( wxString::Format( _( "Exported '%s'." ), svgPath ),
RPT_SEVERITY_ACTION );
@ -312,72 +321,6 @@ void DIALOG_EXPORT_SVG::ExportSVGFile( bool aOnlyOneFile )
}
// Actual SVG file export function.
bool DIALOG_EXPORT_SVG::CreateSVGFile( const wxString& aFullFileName )
{
PCB_PLOT_PARAMS plot_opts;
plot_opts.SetPlotFrameRef( m_rbSvgPageSizeOpt->GetSelection() == 0 );
// Adding drill marks, for copper layers
if( ( m_printMaskLayer & LSET::AllCuMask() ).any() )
plot_opts.SetDrillMarksType( PCB_PLOT_PARAMS::FULL_DRILL_SHAPE );
else
plot_opts.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
plot_opts.SetSkipPlotNPTH_Pads( false );
plot_opts.SetMirror( m_printMirror );
plot_opts.SetFormat( PLOT_FORMAT::SVG );
// coord format: 4 digits in mantissa (units always in mm). This is a good choice.
plot_opts.SetSvgPrecision( 4 );
PAGE_INFO savedPageInfo = m_board->GetPageSettings();
VECTOR2I savedAuxOrigin = m_board->GetDesignSettings().GetAuxOrigin();
if( m_rbSvgPageSizeOpt->GetSelection() == 2 ) // Page is board boundary size
{
BOX2I bbox = m_board->ComputeBoundingBox();
PAGE_INFO currpageInfo = m_board->GetPageSettings();
currpageInfo.SetWidthMils( bbox.GetWidth() / pcbIUScale.IU_PER_MILS );
currpageInfo.SetHeightMils( bbox.GetHeight() / pcbIUScale.IU_PER_MILS );
m_board->SetPageSettings( currpageInfo );
plot_opts.SetUseAuxOrigin( true );
VECTOR2I origin = bbox.GetOrigin();
m_board->GetDesignSettings().SetAuxOrigin( origin );
}
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>();
plot_opts.SetColorSettings( mgr.GetColorSettings( cfg->m_ColorTheme ) );
LOCALE_IO toggle;
//@todo allow controlling the sheet name and path that will be displayed in the title block
// Leave blank for now
SVG_PLOTTER* plotter = (SVG_PLOTTER*) StartPlotBoard( m_board, &plot_opts, UNDEFINED_LAYER,
aFullFileName, wxEmptyString,
wxEmptyString );
if( plotter )
{
plotter->SetColorMode( !m_printBW );
PlotBoardLayers( m_board, plotter, m_printMaskLayer.SeqStackupBottom2Top(), plot_opts );
plotter->EndPlot();
}
delete plotter;
// reset to the values saved earlier
m_board->GetDesignSettings().SetAuxOrigin( savedAuxOrigin );
m_board->SetPageSettings( savedPageInfo );
return true;
}
void DIALOG_EXPORT_SVG::OnButtonPlot( wxCommandEvent& event )
{
m_oneFileOnly = !m_checkboxPagePerLayer->GetValue();

36
utils/kicad2step/CMakeLists.txt → pcbnew/exporters/step/CMakeLists.txt

@ -16,7 +16,6 @@ set( KS2_LIB_FILES
pcb/oce_utils.cpp
)
# Break the library out for re-use by both kicad2step and any qa that needs it
# In future, this could move for re-use by other programs needing s-expr support (?)
add_library( kicad2step_lib STATIC
@ -33,45 +32,14 @@ target_include_directories( kicad2step_lib PUBLIC
target_link_libraries( kicad2step_lib
sexpr
common
${wxWidgets_LIBRARIES}
${OCC_LIBRARIES}
${ZLIB_LIBRARIES}
kimath
)
set( K2S_FILES
kicad2step_app.cpp
)
if( MINGW )
list( APPEND K2S_FILES ${CMAKE_SOURCE_DIR}/common/streamwrapper.cpp )
endif( MINGW )
add_executable( kicad2step_bin WIN32 ${K2S_FILES} )
target_link_libraries( kicad2step_bin
kicad2step_lib )
target_include_directories( kicad2step_lib PRIVATE
$<TARGET_PROPERTY:gzip-hpp,INTERFACE_INCLUDE_DIRECTORIES>
)
set_target_properties( kicad2step_bin
PROPERTIES OUTPUT_NAME kicad2step)
if( APPLE )
# puts binaries into the *.app bundle while linking
set_target_properties( kicad2step_bin PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_BIN_DIR}
)
else()
install( TARGETS kicad2step_bin
RUNTIME DESTINATION ${KICAD_BIN}
ARCHIVE DESTINATION ${KICAD_LIB}
COMPONENT binary )
endif()
if( KICAD_WIN32_INSTALL_PDBS )
# Get the PDBs to copy over for MSVC
install(FILES $<TARGET_PDB_FILE:kicad2step_bin> DESTINATION ${KICAD_BIN})
endif()
)

146
utils/kicad2step/kicad2step.cpp → pcbnew/exporters/step/kicad2step.cpp

@ -28,11 +28,14 @@
#include <wx/msgdlg.h>
#include <wx/string.h>
#include <wx/filename.h>
#include <wx/crt.h>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <sstream>
#include <cli/exit_codes.h>
#include <pgm_base.h>
#include "kicad2step.h"
#include "pcb/kicadpcb.h"
#include "kicad2step_frame_base.h"
@ -52,26 +55,33 @@
class KICAD2STEP_FRAME : public KICAD2STEP_FRAME_BASE
{
public:
KICAD2STEP_FRAME( const wxString& title );
KICAD2STEP_FRAME( KICAD2STEP* aConverter, const wxString& title );
protected:
virtual void OnOKButtonClick( wxCommandEvent& aEvent ) override;
virtual void OnIdle( wxIdleEvent& aEvent ) override;
KICAD2STEP* m_converter;
bool m_running;
};
// Horrible hack until we decouple things more
static PANEL_KICAD2STEP* openPanel = nullptr;
static KICAD2STEP* k2sInstance = nullptr;
void ReportMessage( const wxString& aMessage )
{
if( openPanel != nullptr )
openPanel->AppendMessage( aMessage );
if( k2sInstance != nullptr )
k2sInstance->ReportMessage( aMessage );
}
class KiCadPrinter : public Message_Printer
{
public:
KiCadPrinter( KICAD2STEP* aConverter ) : m_converter( aConverter ) {}
protected:
#if OCC_VERSION_HEX < OCC_VERSION_MIN
virtual void Send( const TCollection_ExtendedString& theString,
@ -91,24 +101,28 @@ protected:
{
if( theGravity >= Message_Info )
{
ReportMessage( theString.ToCString() );
m_converter->ReportMessage( theString.ToCString() );
#if OCC_VERSION_HEX < OCC_VERSION_MIN
if( theToPutEol )
ReportMessage( wxT( "\n" ) );
#else
ReportMessage( wxT( "\n" ) );
m_converter->ReportMessage( wxT( "\n" ) );
#endif
}
if( theGravity >= Message_Alarm )
openPanel->m_error = true;
m_converter->SetError();
if( theGravity == Message_Fail )
openPanel->m_fail = true;
m_converter->SetFail();
}
private:
KICAD2STEP* m_converter;
};
KICAD2MCAD_PRMS::KICAD2MCAD_PRMS()
{
#ifdef SUPPORTS_IGES
@ -126,8 +140,8 @@ KICAD2MCAD_PRMS::KICAD2MCAD_PRMS()
}
KICAD2STEP_FRAME::KICAD2STEP_FRAME( const wxString& title ) :
KICAD2STEP_FRAME_BASE( nullptr, wxID_ANY, title )
KICAD2STEP_FRAME::KICAD2STEP_FRAME( KICAD2STEP* aConverter, const wxString& title ) :
KICAD2STEP_FRAME_BASE( nullptr, wxID_ANY, title ), m_converter( aConverter ), m_running( false )
{
}
@ -138,9 +152,21 @@ void KICAD2STEP_FRAME::OnOKButtonClick( wxCommandEvent& aEvent )
}
PANEL_KICAD2STEP::PANEL_KICAD2STEP( wxWindow* parent, wxWindowID id, const wxPoint& pos,
void KICAD2STEP_FRAME::OnIdle( wxIdleEvent& aEvent )
{
if( !m_running )
{
m_running = true;
m_converter->DoRun();
}
}
PANEL_KICAD2STEP::PANEL_KICAD2STEP( wxWindow* parent, wxWindowID id,
const wxPoint& pos,
const wxSize& size, long style ) :
wxPanel( parent, id, pos, size, style ), m_error( false ), m_fail( false )
wxPanel( parent, id, pos, size, style ),
m_error( false ), m_fail( false )
{
wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
@ -161,14 +187,33 @@ void PANEL_KICAD2STEP::AppendMessage( const wxString& aMessage )
}
int PANEL_KICAD2STEP::RunConverter()
wxString KICAD2MCAD_PRMS::getOutputExt() const
{
#ifdef SUPPORTS_IGES
if( m_fmtIGES )
return wxT( "igs" );
else
#endif
return wxT( "step" );
}
KICAD2STEP::KICAD2STEP( KICAD2MCAD_PRMS aParams ) :
m_params( aParams ), m_panel( nullptr ), m_error( false ), m_fail( false )
{
}
int KICAD2STEP::DoRun()
{
wxFileName fname( m_params.m_filename );
if( !fname.FileExists() )
{
wxMessageBox( wxString::Format( _( "No such file: %s" ), m_params.m_filename ) );
return -1;
ReportMessage( wxString::Format( _( "No such file: %s" ), m_params.m_filename ) );
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
wxFileName out_fname;
@ -192,7 +237,7 @@ int PANEL_KICAD2STEP::RunConverter()
ReportMessage( _( "** Output already exists. Export aborted. **\n"
"Enable the force overwrite flag to overwrite it." ) );
return -1;
return CLI::EXIT_CODES::ERR_INVALID_OUTPUT_CONFLICT;
}
wxString outfile = out_fname.GetFullPath();
@ -203,7 +248,7 @@ int PANEL_KICAD2STEP::RunConverter()
ReportMessage( wxString::Format( _( "Read file: '%s'\n" ), m_params.m_filename ) );
Message::DefaultMessenger()->RemovePrinters( STANDARD_TYPE( Message_PrinterOStream ) );
Message::DefaultMessenger()->AddPrinter( new KiCadPrinter );
Message::DefaultMessenger()->AddPrinter( new KiCadPrinter( this ) );
if( pcb.ReadFile( m_params.m_filename ) )
{
@ -224,7 +269,8 @@ int PANEL_KICAD2STEP::RunConverter()
if( !res )
{
ReportMessage( _( "\n** Error building STEP board model. Export aborted. **\n" ) );
return -1;
return CLI::EXIT_CODES::ERR_UNKNOWN;
}
ReportMessage( _( "Write STEP file\n" ) );
@ -239,7 +285,7 @@ int PANEL_KICAD2STEP::RunConverter()
if( !res )
{
ReportMessage( _( "\n** Error writing STEP file. **\n" ) );
return -1;
return CLI::EXIT_CODES::ERR_UNKNOWN;
}
else
{
@ -250,18 +296,18 @@ int PANEL_KICAD2STEP::RunConverter()
{
ReportMessage( e.GetMessageString() );
ReportMessage( _( "\n** Error exporting STEP file. Export aborted. **\n" ) );
return -1;
return CLI::EXIT_CODES::ERR_UNKNOWN;
}
catch( ... )
{
ReportMessage( _( "\n** Error exporting STEP file. Export aborted. **\n" ) );
return -1;
return CLI::EXIT_CODES::ERR_INVALID_INPUT_FILE;
}
}
else
{
ReportMessage( _( "\n** Error reading kicad_pcb file. **\n" ) );
return -1;
return CLI::EXIT_CODES::ERR_UNKNOWN;
}
wxString msg;
@ -278,49 +324,45 @@ int PANEL_KICAD2STEP::RunConverter()
ReportMessage( msg );
return 0;
}
wxString KICAD2MCAD_PRMS::getOutputExt() const
{
#ifdef SUPPORTS_IGES
if( m_fmtIGES )
return wxT( "igs" );
else
#endif
return wxT( "step" );
}
KICAD2STEP::KICAD2STEP( KICAD2MCAD_PRMS aParams ) : m_params( aParams ), m_panel( nullptr )
{
return CLI::EXIT_CODES::SUCCESS;
}
int KICAD2STEP::Run()
{
// create the main application window
KICAD2STEP_FRAME* frame = new KICAD2STEP_FRAME( wxT( "Kicad2step" ) );
k2sInstance = this;
m_panel = frame->m_panelKicad2Step;
m_panel->m_params = m_params;
// and show it (a wxFrame is not shown when created initially)
frame->Show( true );
frame->Iconize( false );
if( m_params.m_gui )
{
// create the main application window
KICAD2STEP_FRAME* frame = new KICAD2STEP_FRAME( this, wxT( "PCB Step Export" ) );
openPanel = m_panel;
m_panel = frame->m_panelKicad2Step;
m_panel->m_params = m_params;
int diag = m_panel->RunConverter();
Pgm().App().SetTopWindow( frame );
openPanel = nullptr;
frame->Iconize( false );
frame->Show( true );
return diag;
return CLI::EXIT_CODES::AVOID_CLOSING;
}
else
{
int diag = DoRun();
return diag;
}
}
void KICAD2STEP::ReportMessage( const wxString& aMessage )
{
m_panel->AppendMessage( aMessage );
if( m_params.m_gui )
{
m_panel->AppendMessage( aMessage );
}
else
{
wxPrintf( aMessage );
}
}

11
utils/kicad2step/kicad2step.h → pcbnew/exporters/step/kicad2step.h

@ -51,6 +51,7 @@ public:
double m_xOrigin;
double m_yOrigin;
double m_minDistance;
bool m_gui;
};
class APIEXPORT KICAD2STEP
@ -61,9 +62,19 @@ public:
int Run();
void ReportMessage( const wxString& aMessage );
void SetError() { m_error = true; }
void SetFail() { m_error = true; }
private:
int DoRun();
KICAD2MCAD_PRMS m_params;
PANEL_KICAD2STEP* m_panel;
bool m_error;
bool m_fail;
friend class KICAD2STEP_FRAME;
};
#endif

0
utils/kicad2step/kicad2step_app.cpp → pcbnew/exporters/step/kicad2step_app.cpp

4
utils/kicad2step/kicad2step_frame_base.cpp → pcbnew/exporters/step/kicad2step_frame_base.cpp

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -34,12 +34,14 @@ KICAD2STEP_FRAME_BASE::KICAD2STEP_FRAME_BASE( wxWindow* parent, wxWindowID id, c
this->Centre( wxBOTH );
// Connect Events
this->Connect( wxEVT_IDLE, wxIdleEventHandler( KICAD2STEP_FRAME_BASE::OnIdle ) );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KICAD2STEP_FRAME_BASE::OnOKButtonClick ), NULL, this );
}
KICAD2STEP_FRAME_BASE::~KICAD2STEP_FRAME_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_IDLE, wxIdleEventHandler( KICAD2STEP_FRAME_BASE::OnIdle ) );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( KICAD2STEP_FRAME_BASE::OnOKButtonClick ), NULL, this );
}

6
utils/kicad2step/kicad2step_frame_base.fbp → pcbnew/exporters/step/kicad2step_frame_base.fbp

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<FileVersion major="1" minor="16" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -14,6 +14,7 @@
<property name="file">kicad2step_frame_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">kicad2step_frame</property>
@ -25,6 +26,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Frame" expanded="1">
@ -50,10 +52,12 @@
<property name="subclass">; forward_declare; forward_declare</property>
<property name="title">Kicad2step Converter</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<property name="xrc_skip_sizer">1</property>
<event name="OnIdle">OnIdle</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>

3
utils/kicad2step/kicad2step_frame_base.h → pcbnew/exporters/step/kicad2step_frame_base.h

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -36,6 +36,7 @@ class KICAD2STEP_FRAME_BASE : public wxFrame
wxButton* m_sdbSizer1OK;
// Virtual event handlers, override them in your derived class
virtual void OnIdle( wxIdleEvent& event ) { event.Skip(); }
virtual void OnOKButtonClick( wxCommandEvent& event ) { event.Skip(); }

4
utils/kicad2step/panel_kicad2step.h → pcbnew/exporters/step/panel_kicad2step.h

@ -44,10 +44,6 @@ public:
const wxSize& size = wxSize( 500,300 ),
long style = wxTAB_TRAVERSAL );
/**
* Run the KiCad to STEP converter.
*/
int RunConverter();
/**
* Add a message to m_tcMessages.

2
utils/kicad2step/pcb/3d_resolver.cpp → pcbnew/exporters/step/pcb/3d_resolver.cpp

@ -374,7 +374,7 @@ bool S3D_RESOLVER::readPathList( void )
if( !wxFileName::Exists( cfgname ) )
{
wxLogTrace( trace3dResolver, wxT( "%s:%s:d\n * no 3D configuration file '%s'" ),
wxLogTrace( trace3dResolver, wxT( "%s:%s:%d\n * no 3D configuration file '%s'" ),
__FILE__, __FUNCTION__, __LINE__, cfgname );
return false;

0
utils/kicad2step/pcb/3d_resolver.h → pcbnew/exporters/step/pcb/3d_resolver.h

0
utils/kicad2step/pcb/base.cpp → pcbnew/exporters/step/pcb/base.cpp

0
utils/kicad2step/pcb/base.h → pcbnew/exporters/step/pcb/base.h

0
utils/kicad2step/pcb/kicadcurve.cpp → pcbnew/exporters/step/pcb/kicadcurve.cpp

0
utils/kicad2step/pcb/kicadcurve.h → pcbnew/exporters/step/pcb/kicadcurve.h

0
utils/kicad2step/pcb/kicadfootprint.cpp → pcbnew/exporters/step/pcb/kicadfootprint.cpp

0
utils/kicad2step/pcb/kicadfootprint.h → pcbnew/exporters/step/pcb/kicadfootprint.h

0
utils/kicad2step/pcb/kicadmodel.cpp → pcbnew/exporters/step/pcb/kicadmodel.cpp

0
utils/kicad2step/pcb/kicadmodel.h → pcbnew/exporters/step/pcb/kicadmodel.h

0
utils/kicad2step/pcb/kicadpad.cpp → pcbnew/exporters/step/pcb/kicadpad.cpp

0
utils/kicad2step/pcb/kicadpad.h → pcbnew/exporters/step/pcb/kicadpad.h

0
utils/kicad2step/pcb/kicadpcb.cpp → pcbnew/exporters/step/pcb/kicadpcb.cpp

0
utils/kicad2step/pcb/kicadpcb.h → pcbnew/exporters/step/pcb/kicadpcb.h

0
utils/kicad2step/pcb/oce_utils.cpp → pcbnew/exporters/step/pcb/oce_utils.cpp

0
utils/kicad2step/pcb/oce_utils.h → pcbnew/exporters/step/pcb/oce_utils.h

106
pcbnew/pcb_plot_svg.cpp

@ -0,0 +1,106 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <board.h>
#include <board_design_settings.h>
#include <locale_io.h>
#include <pcbnew_settings.h>
#include <pcb_plot_params.h>
#include <pcb_plot_svg.h>
#include <pcbplot.h>
#include <pgm_base.h>
#include <plotters/plotters_pslike.h>
bool PCB_PLOT_SVG::Plot( BOARD* aBoard, const PCB_PLOT_SVG_OPTIONS& aSvgPlotOptions )
{
PCB_PLOT_PARAMS plot_opts;
plot_opts.SetPlotFrameRef( aSvgPlotOptions.m_pageSizeMode );
// Adding drill marks, for copper layers
if( ( aSvgPlotOptions.m_printMaskLayer & LSET::AllCuMask() ).any() )
plot_opts.SetDrillMarksType( PCB_PLOT_PARAMS::FULL_DRILL_SHAPE );
else
plot_opts.SetDrillMarksType( PCB_PLOT_PARAMS::NO_DRILL_SHAPE );
plot_opts.SetSkipPlotNPTH_Pads( false );
plot_opts.SetMirror( aSvgPlotOptions.m_mirror );
plot_opts.SetFormat( PLOT_FORMAT::SVG );
// coord format: 4 digits in mantissa (units always in mm). This is a good choice.
plot_opts.SetSvgPrecision( 4 );
PAGE_INFO savedPageInfo = aBoard->GetPageSettings();
VECTOR2I savedAuxOrigin = aBoard->GetDesignSettings().GetAuxOrigin();
if( aSvgPlotOptions.m_pageSizeMode == 2 ) // Page is board boundary size
{
BOX2I bbox = aBoard->ComputeBoundingBox();
PAGE_INFO currpageInfo = aBoard->GetPageSettings();
currpageInfo.SetWidthMils( bbox.GetWidth() / pcbIUScale.IU_PER_MILS );
currpageInfo.SetHeightMils( bbox.GetHeight() / pcbIUScale.IU_PER_MILS );
aBoard->SetPageSettings( currpageInfo );
plot_opts.SetUseAuxOrigin( true );
VECTOR2I origin = bbox.GetOrigin();
aBoard->GetDesignSettings().SetAuxOrigin( origin );
}
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
PCBNEW_SETTINGS* cfg = mgr.GetAppSettings<PCBNEW_SETTINGS>();
plot_opts.SetColorSettings( mgr.GetColorSettings( cfg->m_ColorTheme ) );
COLOR_SETTINGS* theme = nullptr;
if( !aSvgPlotOptions.m_colorTheme.IsEmpty() )
{
theme = mgr.GetColorSettings( aSvgPlotOptions.m_colorTheme );
}
if( !theme )
{
theme = mgr.GetColorSettings( cfg->m_ColorTheme );
}
LOCALE_IO toggle;
//@todo allow controlling the sheet name and path that will be displayed in the title block
// Leave blank for now
SVG_PLOTTER* plotter = (SVG_PLOTTER*) StartPlotBoard( aBoard, &plot_opts, UNDEFINED_LAYER,
aSvgPlotOptions.m_outputFile,
wxEmptyString, wxEmptyString );
if( plotter )
{
plotter->SetColorMode( !aSvgPlotOptions.m_blackAndWhite );
PlotBoardLayers( aBoard, plotter, aSvgPlotOptions.m_printMaskLayer.SeqStackupBottom2Top(),
plot_opts );
plotter->EndPlot();
}
delete plotter;
// reset to the values saved earlier
aBoard->GetDesignSettings().SetAuxOrigin( savedAuxOrigin );
aBoard->SetPageSettings( savedPageInfo );
return true;
}

43
pcbnew/pcb_plot_svg.h

@ -0,0 +1,43 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PCB_PLOT_SVG_H
#define PCB_PLOT_SVG_H
struct PCB_PLOT_SVG_OPTIONS
{
wxString m_outputFile;
wxString m_colorTheme;
bool m_mirror;
bool m_blackAndWhite;
int m_pageSizeMode;
LSET m_printMaskLayer;
};
class PCB_PLOT_SVG
{
public:
static bool Plot( BOARD* aBoard, const PCB_PLOT_SVG_OPTIONS& aSvgPlotOptions );
};
#endif

13
pcbnew/pcbnew.cpp

@ -60,6 +60,7 @@
#include "invoke_pcb_dialog.h"
#include <wildcards_and_files_ext.h>
#include "pcbnew_jobs_handler.h"
/* init functions defined by swig */
@ -290,6 +291,11 @@ static struct IFACE : public KIFACE_BASE
const wxString& aNewProjectBasePath, const wxString& aNewProjectName,
const wxString& aSrcFilePath, wxString& aErrors ) override;
int HandleJob( JOB* aJob ) override;
private:
std::unique_ptr<PCBNEW_JOBS_HANDLER> m_jobHandler;
} kiface( "pcbnew", KIWAY::FACE_PCB );
} // namespace
@ -381,6 +387,8 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
}
}
m_jobHandler = std::make_unique<PCBNEW_JOBS_HANDLER>();
return true;
}
@ -478,3 +486,8 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aSrcPr
}
}
int IFACE::HandleJob( JOB* aJob )
{
return m_jobHandler->RunJob( aJob );
}

102
pcbnew/pcbnew_jobs_handler.cpp

@ -0,0 +1,102 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pcbnew_jobs_handler.h"
#include <kicad2step.h>
#include <jobs/job_export_pcb_svg.h>
#include <jobs/job_export_step.h>
#include <cli/exit_codes.h>
#include <plotters/plotters_pslike.h>
#include <pgm_base.h>
#include <pcbplot.h>
#include <board_design_settings.h>
#include <pcbnew_settings.h>
#include <wx/crt.h>
#include <pcb_plot_svg.h>
#include "pcbnew_scripting_helpers.h"
PCBNEW_JOBS_HANDLER::PCBNEW_JOBS_HANDLER()
{
Register( "step",
std::bind( &PCBNEW_JOBS_HANDLER::JobExportStep, this, std::placeholders::_1 ) );
Register( "svg",
std::bind( &PCBNEW_JOBS_HANDLER::JobExportSvg, this, std::placeholders::_1 ) );
}
int PCBNEW_JOBS_HANDLER::JobExportStep( JOB* aJob )
{
JOB_EXPORT_STEP* aStepJob = dynamic_cast<JOB_EXPORT_STEP*>( aJob );
if( aStepJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN;
KICAD2MCAD_PRMS params;
params.m_useDrillOrigin = aStepJob->m_useDrillOrigin;
params.m_useGridOrigin = aStepJob->m_useGridOrigin;
params.m_overwrite = aStepJob->m_overwrite;
params.m_includeVirtual = aStepJob->m_includeVirtual;
params.m_filename = aStepJob->m_filename;
params.m_outputFile = aStepJob->m_outputFile;
params.m_xOrigin = aStepJob->m_xOrigin;
params.m_yOrigin = aStepJob->m_yOrigin;
params.m_minDistance = aStepJob->m_minDistance;
params.m_substModels = aStepJob->m_substModels;
params.m_gui = aStepJob->m_gui;
// we might need the lifetime of the converter to continue until frame destruction
// due to the gui parameter
KICAD2STEP* converter = new KICAD2STEP( params );
return converter->Run();
}
int PCBNEW_JOBS_HANDLER::JobExportSvg( JOB* aJob )
{
JOB_EXPORT_PCB_SVG* aSvgJob = dynamic_cast<JOB_EXPORT_PCB_SVG*>( aJob );
if( aSvgJob == nullptr )
return CLI::EXIT_CODES::ERR_UNKNOWN;
PCB_PLOT_SVG_OPTIONS svgPlotOptions;
svgPlotOptions.m_blackAndWhite = aSvgJob->m_blackAndWhite;
svgPlotOptions.m_colorTheme = aSvgJob->m_colorTheme;
svgPlotOptions.m_outputFile = aSvgJob->m_outputFile;
svgPlotOptions.m_mirror = aSvgJob->m_mirror;
svgPlotOptions.m_pageSizeMode = aSvgJob->m_pageSizeMode;
svgPlotOptions.m_printMaskLayer = aSvgJob->m_printMaskLayer;
if( aJob->IsCli() )
wxPrintf( _( "Loading board\n" ) );
BOARD* brd = LoadBoard( aSvgJob->m_filename );
if( aJob->IsCli() )
{
if( PCB_PLOT_SVG::Plot( brd, svgPlotOptions ) )
wxPrintf( _( "Successfully created svg file" ) );
else
wxPrintf( _( "Error creating svg file" ) );
}
return CLI::EXIT_CODES::OK;
}

34
pcbnew/pcbnew_jobs_handler.h

@ -0,0 +1,34 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PCBNEW_JOBS_HANDLER_H
#define PCBNEW_JOBS_HANDLER_H
#include <jobs/job_dispatcher.h>
class PCBNEW_JOBS_HANDLER : public JOB_DISPATCHER
{
public:
PCBNEW_JOBS_HANDLER();
int JobExportStep( JOB* aJob );
int JobExportSvg( JOB* aJob );
};
#endif

5
qa/tools/pcbnew_tools/CMakeLists.txt

@ -29,10 +29,6 @@ add_executable( qa_pcbnew_tools
tools/polygon_generator/polygon_generator.cpp
tools/polygon_triangulation/polygon_triangulation.cpp
# Older CMakes cannot link OBJECT libraries
# https://cmake.org/pipermail/cmake/2013-November/056263.html
$<TARGET_OBJECTS:pcbnew_kiface_objects>
)
# Anytime we link to the kiface_objects, we have to add a dependency on the last object
@ -41,6 +37,7 @@ add_executable( qa_pcbnew_tools
add_dependencies( qa_pcbnew_tools pcbnew )
target_link_libraries( qa_pcbnew_tools
pcbnew_kiface_objects
qa_pcbnew_utils
3d-viewer
connectivity

1
resources/msw/cmd-wrappers/kicad.cmd

@ -0,0 +1 @@
@"%~dp0kicad.exe" %*

1
resources/msw/cmd-wrappers/pcbnew.cmd

@ -0,0 +1 @@
@"%~dp0pcbnew.exe" %*

1
thirdparty/CMakeLists.txt

@ -23,6 +23,7 @@
# Note: The glew folder isn't added here because it is added inside the main CMakeLists.txt
add_subdirectory( argparse )
add_subdirectory( clipper )
add_subdirectory( compoundfilereader )
add_subdirectory( delaunator )

117
thirdparty/argparse/.clang-format

@ -0,0 +1,117 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
RawStringFormats:
- Language: TextProto
Delimiters:
- 'pb'
- 'proto'
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: c++17
TabWidth: 8
UseTab: Never
...

21
thirdparty/argparse/.clang-tidy

@ -0,0 +1,21 @@
Checks:
-*,
clang-analyzer-*,
cppcoreguidelines-avoid-c-arrays,
cppcoreguidelines-special-member-functions,
readability-*,
CheckOptions:
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
- { key: readability-identifier-naming.ConstexprVariableCase, value: lower_case }
- { key: readability-identifier-naming.ConstexprVariableIgnoredRegexp, value: "^Is.+" }
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
- { key: readability-identifier-naming.PrivateMemberPrefix, value: m_ }
- { key: readability-identifier-naming.StructCase, value: CamelCase }
- { key: readability-identifier-naming.StructIgnoredRegexp, value: "parse_number" }
- { key: readability-identifier-naming.VariableCase, value: lower_case }
HeaderFilterRegex: '.*'

87
thirdparty/argparse/.github/workflows/ci.yml

@ -0,0 +1,87 @@
name: CI
on: pull_request
jobs:
test:
name: ${{ matrix.toolchain }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
toolchain:
- macos-latest-clang
- macos-12-clang
- ubuntu-latest-clang
- ubuntu-latest-gcc
- windows-2019-msvc
- windows-latest-msvc
- windows-latest-clang
include:
- toolchain: macos-latest-clang
os: macos-latest
c_compiler: clang
cxx_compiler: clang++
- toolchain: macos-12-clang
os: macos-latest
c_compiler: clang
cxx_compiler: clang++
- toolchain: ubuntu-latest-clang
os: ubuntu-latest
c_compiler: clang
cxx_compiler: clang++
- toolchain: ubuntu-latest-gcc
os: ubuntu-latest
c_compiler: cc
cxx_compiler: g++
- toolchain: windows-2019-msvc
os: windows-2019
c_compiler: msvc
cxx_compiler: msvc
- toolchain: windows-latest-msvc
os: windows-latest
c_compiler: msvc
cxx_compiler: msvc
- toolchain: windows-latest-clang
os: windows-latest
c_compiler: clang-cl
cxx_compiler: clang-cl
cmake_opts: -T ClangCL
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Configure
working-directory: test
run: cmake -S . -B build ${{ matrix.cmake_opts }}
env:
CC: ${{ matrix.c_compiler }}
CXX: ${{ matrix.cxx_compiler }}
- name: Build for ${{ matrix.os }} with ${{ matrix.compiler }}
working-directory: test
run: cmake --build build
- name: Test
if: ${{ ! startsWith(matrix.os, 'windows') }}
working-directory: test/build
run: ./tests
- name: Test (Windows)
if: ${{ startsWith(matrix.os, 'windows') }}
working-directory: test/build
run: ./Debug/tests.exe

273
thirdparty/argparse/.gitignore

@ -0,0 +1,273 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
.vscode/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# CMake build directory
build
# Cppcheck build directory
analysis-cppcheck-build-dir
# Ideas directory
ideas
desktop.iniimages/

39
thirdparty/argparse/.travis.yml

@ -0,0 +1,39 @@
matrix:
include:
- os: linux
dist: bionic
language: cpp
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
env: CXX=g++-8 CC=gcc-8
- os: osx
osx_image: xcode10.2
language: cpp
compiler: clang
- os: windows
language: bash
env: CXX=cl.exe
install:
- |
if [[ $TRAVIS_OS_NAME == 'windows' ]]; then
choco install ninja cmake
elif [[ $TRAVIS_OS_NAME == 'osx' ]]; then
export PATH=~/Library/Python/3.7/bin:$PATH
pip3 install --user ninja cmake
else
pipenv global 3.6
pip install --user ninja cmake
fi
script:
- |
if [[ $TRAVIS_OS_NAME == 'windows' ]]; then
tools/build.bat
else
sh tools/build.sh
fi
- ./build/test/tests

98
thirdparty/argparse/CMakeLists.txt

@ -0,0 +1,98 @@
cmake_minimum_required(VERSION 3.12.4)
project(argparse
VERSION 2.9.0
DESCRIPTION "A single header argument parser for C++17"
HOMEPAGE_URL "https://github.com/p-ranav/argparse"
LANGUAGES CXX
)
option(ARGPARSE_BUILD_TESTS OFF)
option(ARGPARSE_LONG_VERSION_ARG_ONLY OFF)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
string(REPLACE "/${CMAKE_LIBRARY_ARCHITECTURE}" "" CMAKE_INSTALL_LIBDIR_ARCHIND "${CMAKE_INSTALL_LIBDIR}")
add_library(argparse INTERFACE)
add_library(argparse::argparse ALIAS argparse)
if (ARGPARSE_LONG_VERSION_ARG_ONLY)
target_compile_definitions(argparse INTERFACE ARGPARSE_LONG_VERSION_ARG_ONLY=true)
endif ()
target_compile_features(argparse INTERFACE cxx_std_17)
target_include_directories(argparse INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
if(ARGPARSE_BUILD_SAMPLES)
add_subdirectory(samples)
endif()
if(ARGPARSE_BUILD_TESTS)
add_subdirectory(test)
endif()
install(TARGETS argparse EXPORT argparseConfig)
install(EXPORT argparseConfig
NAMESPACE argparse::
DESTINATION ${CMAKE_INSTALL_LIBDIR_ARCHIND}/cmake/${PROJECT_NAME})
install(FILES ${CMAKE_CURRENT_LIST_DIR}/include/argparse/argparse.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/argparse)
set(CONFIG_FILE_NAME_WITHOUT_EXT "${PROJECT_NAME}Config")
set(CMAKE_CONFIG_FILE_BASENAME "${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_FILE_NAME_WITHOUT_EXT}")
set(CMAKE_CONFIG_VERSION_FILE_NAME "${CMAKE_CONFIG_FILE_BASENAME}-version.cmake")
set(CMAKE_CONFIG_FILE_NAME "${CMAKE_CONFIG_FILE_BASENAME}.cmake")
if(${CMAKE_VERSION} VERSION_GREATER "3.14")
set(OPTIONAL_ARCH_INDEPENDENT "ARCH_INDEPENDENT")
endif()
write_basic_package_version_file("${CMAKE_CONFIG_VERSION_FILE_NAME}"
COMPATIBILITY ExactVersion
${OPTIONAL_ARCH_INDEPENDENT}
)
export(EXPORT argparseConfig
NAMESPACE argparse::)
install(FILES "${CMAKE_CONFIG_VERSION_FILE_NAME}"
DESTINATION "${CMAKE_INSTALL_LIBDIR_ARCHIND}/cmake/${PROJECT_NAME}")
set(PackagingTemplatesDir "${CMAKE_CURRENT_SOURCE_DIR}/packaging")
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_VENDOR "argparse (C++) developers")
set(CPACK_PACKAGE_DESCRIPTION "${PROJECT_DESCRIPTION}")
set(CPACK_DEBIAN_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_RPM_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
set(CPACK_PACKAGE_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}")
set(CPACK_PACKAGE_MAINTAINER "Pranav Srinivas Kumar")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_PACKAGE_MAINTAINER}")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_DEBIAN_PACKAGE_NAME "lib${PROJECT_NAME}-dev")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6-dev")
set(CPACK_DEBIAN_PACKAGE_SUGGESTS "cmake, pkg-config, pkg-conf")
set(CPACK_RPM_PACKAGE_NAME "lib${PROJECT_NAME}-devel")
set(CPACK_RPM_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}")
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_RPM_COMPONENT_INSTALL ON)
set(CPACK_NSIS_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_COMPRESSION_TYPE "xz")
set(PKG_CONFIG_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc")
configure_file("${PackagingTemplatesDir}/pkgconfig.pc.in" "${PKG_CONFIG_FILE_NAME}" @ONLY)
install(FILES "${PKG_CONFIG_FILE_NAME}"
DESTINATION "${CMAKE_INSTALL_LIBDIR_ARCHIND}/pkgconfig"
)
include(CPack)

17
thirdparty/argparse/CONTRIBUTING.md

@ -0,0 +1,17 @@
# Contributing
Contributions are welcomed. Open a pull-request or an issue.
## Code of conduct
This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code.
[code-of-conduct]: https://github.com/spotify/code-of-conduct/blob/master/code-of-conduct.md
## Code Style
This project prefers, but does not strictly enforce, a specific source code style. The style is described in `.clang-format` and `.clang-tidy`.
To generate a clang-tidy report:
```bash
clang-tidy --extra-arg=-std=c++17 --config-file=.clang-tidy include/argparse/argparse.hpp
```

7
thirdparty/argparse/LICENSE

@ -0,0 +1,7 @@
Copyright (c) 2018 Pranav Srinivas Kumar <pranav.srinivas.kumar@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

1143
thirdparty/argparse/README.md
File diff suppressed because it is too large
View File

1
thirdparty/argparse/clang_format.bash

@ -0,0 +1 @@
clang-format -i include/argparse/*.hpp test/*.cpp samples/*.cpp

10
thirdparty/argparse/conanfile.py

@ -0,0 +1,10 @@
from conans import ConanFile
class ArgparseConan(ConanFile):
name = "argparse"
version = "2.9"
exports_sources = "include/argparse.hpp"
no_copy_source = True
def package(self):
self.copy("argparse.hpp")

1652
thirdparty/argparse/include/argparse/argparse.hpp
File diff suppressed because it is too large
View File

7
thirdparty/argparse/packaging/pkgconfig.pc.in

@ -0,0 +1,7 @@
prefix=@CMAKE_INSTALL_PREFIX@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @PROJECT_VERSION@
Cflags: -I${includedir}

46
thirdparty/argparse/samples/CMakeLists.txt

@ -0,0 +1,46 @@
cmake_minimum_required(VERSION 3.6)
project(argparse_samples)
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -Wsign-conversion -Wshadow -Wconversion")
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# Disable deprecation for windows
if (WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
function(add_sample NAME)
ADD_EXECUTABLE(ARGPARSE_SAMPLE_${NAME} ${NAME}.cpp)
INCLUDE_DIRECTORIES("../include" ".")
TARGET_LINK_LIBRARIES(ARGPARSE_SAMPLE_${NAME} PRIVATE argparse::argparse)
set_target_properties(ARGPARSE_SAMPLE_${NAME} PROPERTIES OUTPUT_NAME ${NAME})
endfunction()
add_sample(positional_argument)
add_sample(optional_flag_argument)
add_sample(required_optional_argument)
add_sample(is_used)
add_sample(joining_repeated_optional_arguments)
add_sample(repeating_argument_to_increase_value)
add_sample(negative_numbers)
add_sample(description_epilog_metavar)
add_sample(list_of_arguments)
add_sample(compound_arguments)
add_sample(gathering_remaining_arguments)
add_sample(subcommands)
add_sample(parse_known_args)
add_sample(custom_prefix_characters)
add_sample(custom_assignment_characters)

36
thirdparty/argparse/samples/compound_arguments.cpp

@ -0,0 +1,36 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("-a").default_value(false).implicit_value(true);
program.add_argument("-b").default_value(false).implicit_value(true);
program.add_argument("-c")
.nargs(2)
.default_value(std::vector<float>{0.0f, 0.0f})
.scan<'g', float>();
try {
program.parse_args(argc, argv); // Example: ./main -abc 1.95 2.47
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
auto a = program.get<bool>("-a"); // true
auto b = program.get<bool>("-b"); // true
auto c = program.get<std::vector<float>>("-c"); // {1.95, 2.47}
std::cout << "a: " << std::boolalpha << a << "\n";
std::cout << "b: " << b << "\n";
if (!c.empty()) {
std::cout << "c: ";
for (auto &v : c) {
std::cout << v << " ";
}
std::cout << std::endl;
}
}

27
thirdparty/argparse/samples/custom_assignment_characters.cpp

@ -0,0 +1,27 @@
#include <argparse/argparse.hpp>
#include <cassert>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.set_prefix_chars("-+/");
program.set_assign_chars("=:");
program.add_argument("--foo");
program.add_argument("/B");
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if (program.is_used("--foo")) {
std::cout << "--foo : " << program.get("--foo") << "\n";
}
if (program.is_used("/B")) {
std::cout << "/B : " << program.get("/B") << "\n";
}
}

31
thirdparty/argparse/samples/custom_prefix_characters.cpp

@ -0,0 +1,31 @@
#include <argparse/argparse.hpp>
#include <cassert>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.set_prefix_chars("-+/");
program.add_argument("+f");
program.add_argument("--bar");
program.add_argument("/foo");
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if (program.is_used("+f")) {
std::cout << "+f : " << program.get("+f") << "\n";
}
if (program.is_used("--bar")) {
std::cout << "--bar : " << program.get("--bar") << "\n";
}
if (program.is_used("/foo")) {
std::cout << "/foo : " << program.get("/foo") << "\n";
}
}

17
thirdparty/argparse/samples/description_epilog_metavar.cpp

@ -0,0 +1,17 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("main");
program.add_argument("thing").help("Thing to use.").metavar("THING");
program.add_argument("--member")
.help("The alias for the member to pass to.")
.metavar("ALIAS");
program.add_argument("--verbose").default_value(false).implicit_value(true);
program.add_description("Forward a thing to the next member.");
program.add_epilog("Possible things include betingalw, chiz, and res.");
program.parse_args(argc, argv);
std::cout << program << std::endl;
}

24
thirdparty/argparse/samples/gathering_remaining_arguments.cpp

@ -0,0 +1,24 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("compiler");
program.add_argument("files").remaining();
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
try {
auto files = program.get<std::vector<std::string>>("files");
std::cout << files.size() << " files provided" << std::endl;
for (auto &file : files)
std::cout << file << std::endl;
} catch (std::logic_error &e) {
std::cout << "No files provided" << std::endl;
}
}

26
thirdparty/argparse/samples/is_used.cpp

@ -0,0 +1,26 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("--color")
.default_value(std::string{
"orange"}) // might otherwise be type const char* leading to an error
// when trying program.get<std::string>
.help("specify the cat's fur color");
try {
program.parse_args(argc, argv); // Example: ./main --color orange
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
auto color = program.get<std::string>("--color"); // "orange"
auto explicit_color =
program.is_used("--color"); // true, user provided orange
std::cout << "Color: " << color << "\n";
std::cout << "Argument was explicitly provided by user? " << std::boolalpha
<< explicit_color << "\n";
}

28
thirdparty/argparse/samples/joining_repeated_optional_arguments.cpp

@ -0,0 +1,28 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("--color")
.default_value<std::vector<std::string>>({"orange"})
.append()
.help("specify the cat's fur color");
try {
program.parse_args(
argc, argv); // Example: ./main --color red --color green --color blue
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
auto colors = program.get<std::vector<std::string>>(
"--color"); // {"red", "green", "blue"}
std::cout << "Colors: ";
for (const auto &c : colors) {
std::cout << c << " ";
}
std::cout << "\n";
}

30
thirdparty/argparse/samples/list_of_arguments.cpp

@ -0,0 +1,30 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("main");
program.add_argument("--input_files")
.help("The list of input files")
.nargs(2);
try {
program.parse_args(
argc, argv); // Example: ./main --input_files config.yml System.xml
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
auto files = program.get<std::vector<std::string>>(
"--input_files"); // {"config.yml", "System.xml"}
if (!files.empty()) {
std::cout << "Files: ";
for (auto &file : files) {
std::cout << file << " ";
}
std::cout << std::endl;
}
}

32
thirdparty/argparse/samples/negative_numbers.cpp

@ -0,0 +1,32 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("integer").help("Input number").scan<'i', int>();
program.add_argument("floats")
.help("Vector of floats")
.nargs(4)
.scan<'g', float>();
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if (program.is_used("integer")) {
std::cout << "Integer : " << program.get<int>("integer") << "\n";
}
if (program.is_used("floats")) {
std::cout << "Floats : ";
for (const auto &f : program.get<std::vector<float>>("floats")) {
std::cout << f << " ";
}
std::cout << std::endl;
}
}

22
thirdparty/argparse/samples/optional_flag_argument.cpp

@ -0,0 +1,22 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("--verbose")
.help("increase output verbosity")
.default_value(false)
.implicit_value(true);
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
if (program["--verbose"] == true) {
std::cout << "Verbosity enabled" << std::endl;
}
}

26
thirdparty/argparse/samples/parse_known_args.cpp

@ -0,0 +1,26 @@
#include <argparse/argparse.hpp>
#include <cassert>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("--foo").implicit_value(true).default_value(false);
program.add_argument("bar");
auto unknown_args = program.parse_known_args(argc, argv);
if (program.is_used("--foo")) {
std::cout << "--foo : " << program.get<bool>("--foo") << "\n";
}
if (program.is_used("bar")) {
std::cout << "bar : " << program.get<std::string>("bar") << "\n";
}
if (!unknown_args.empty()) {
std::cout << "Unknown args : ";
for (const auto &u : unknown_args) {
std::cout << u << " ";
}
std::cout << std::endl;
}
}

28
thirdparty/argparse/samples/positional_argument.cpp

@ -0,0 +1,28 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("main");
program.add_argument("square")
.help("display the square of a given number")
.scan<'i', int>();
program.add_argument("--verbose").default_value(false).implicit_value(true);
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
int input = program.get<int>("square");
if (program["--verbose"] == true) {
std::cout << "The square of " << input << " is " << (input * input)
<< std::endl;
} else {
std::cout << (input * input) << std::endl;
}
}

17
thirdparty/argparse/samples/repeating_argument_to_increase_value.cpp

@ -0,0 +1,17 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
int verbosity = 0;
program.add_argument("-V", "--verbose")
.action([&](const auto &) { ++verbosity; })
.append()
.default_value(false)
.implicit_value(true)
.nargs(0);
program.parse_args(argc, argv); // Example: ./main -VVVV
std::cout << "verbose level: " << verbosity << std::endl; // verbose level: 4
}

19
thirdparty/argparse/samples/required_optional_argument.cpp

@ -0,0 +1,19 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("test");
program.add_argument("-o", "--output")
.required()
.help("specify the output file.");
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
std::cout << "Output written to " << program.get("-o") << "\n";
}

65
thirdparty/argparse/samples/subcommands.cpp

@ -0,0 +1,65 @@
#include <argparse/argparse.hpp>
int main(int argc, char *argv[]) {
argparse::ArgumentParser program("git");
// git add subparser
argparse::ArgumentParser add_command("add");
add_command.add_description("Add file contents to the index");
add_command.add_argument("files")
.help("Files to add content from. Fileglobs (e.g. *.c) can be given to "
"add all matching files.")
.remaining();
// git commit subparser
argparse::ArgumentParser commit_command("commit");
commit_command.add_description("Record changes to the repository");
commit_command.add_argument("-a", "--all")
.help("Tell the command to automatically stage files that have been "
"modified and deleted.")
.default_value(false)
.implicit_value(true);
commit_command.add_argument("-m", "--message")
.help("Use the given <msg> as the commit message.");
// git cat-file subparser
argparse::ArgumentParser catfile_command("cat-file");
catfile_command.add_description(
"Provide content or type and size information for repository objects");
catfile_command.add_argument("-t").help(
"Instead of the content, show the object type identified by <object>.");
catfile_command.add_argument("-p").help(
"Pretty-print the contents of <object> based on its type.");
// git submodule subparser
argparse::ArgumentParser submodule_command("submodule");
submodule_command.add_description("Initialize, update or inspect submodules");
argparse::ArgumentParser submodule_update_command("update");
submodule_update_command.add_description(
"Update the registered submodules to match what the superproject "
"expects");
submodule_update_command.add_argument("--init")
.default_value(false)
.implicit_value(true);
submodule_update_command.add_argument("--recursive")
.default_value(false)
.implicit_value(true);
submodule_command.add_subparser(submodule_update_command);
program.add_subparser(add_command);
program.add_subparser(commit_command);
program.add_subparser(catfile_command);
program.add_subparser(submodule_command);
try {
program.parse_args(argc, argv);
} catch (const std::runtime_error &err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
// Use arguments
}

2
thirdparty/argparse/test/.gitignore

@ -0,0 +1,2 @@
build/
build_linux/

63
thirdparty/argparse/test/CMakeLists.txt

@ -0,0 +1,63 @@
cmake_minimum_required(VERSION 3.6)
project(argparse_tests)
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -Wsign-conversion -Wshadow -Wconversion")
endif()
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# Disable deprecation for windows
if (WIN32)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()
# ARGPARSE executable
file(GLOB ARGPARSE_TEST_SOURCES
main.cpp
test_actions.cpp
test_append.cpp
test_compound_arguments.cpp
test_container_arguments.cpp
test_const_correct.cpp
test_default_args.cpp
test_get.cpp
test_help.cpp
test_invalid_arguments.cpp
test_is_used.cpp
test_issue_37.cpp
test_negative_numbers.cpp
test_optional_arguments.cpp
test_parent_parsers.cpp
test_parse_args.cpp
test_positional_arguments.cpp
test_repr.cpp
test_required_arguments.cpp
test_scan.cpp
test_value_semantics.cpp
test_version.cpp
test_subparsers.cpp
test_parse_known_args.cpp
test_equals_form.cpp
test_prefix_chars.cpp
)
set_source_files_properties(main.cpp
PROPERTIES
COMPILE_DEFINITIONS DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN)
ADD_EXECUTABLE(ARGPARSE_TESTS ${ARGPARSE_TEST_SOURCES})
INCLUDE_DIRECTORIES("../include" ".")
set_target_properties(ARGPARSE_TESTS PROPERTIES OUTPUT_NAME tests)
set_property(TARGET ARGPARSE_TESTS PROPERTY CXX_STANDARD 17)
# Set ${PROJECT_NAME} as the startup project
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ARGPARSE_TESTS)

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save