Run-time config for advanced options
This can be used for "advanced" options which are for developers to use for feature-flags and other configuration. Run time config has some advantages over preprocessor defines: * Can be changed without recompilation * Sensitive to XDG_CONFIG_DIR, so flipping configs is easy * Better compiler coverage (less conditionally compiled code means less chance to break a different configuration). Also better analysis coverage. * Type safe config params * Centralised documentation: it's in doxygen, in one place No advanced config should be required by a general users. If a general user does use one of these configs, it's probably because: * There is a bug and one of these configs is a workaround * A config in here is generally useful and should be moved into the relevant application config and given UI. For now, the config is read-only, and is read from the "kicad_advanced" config file in the normal config dir.
This commit is contained in:
parent
9f21d32563
commit
a33a8292a4
|
@ -259,9 +259,20 @@ Some available masks:
|
|||
* `KICAD_GEDA_PLUGIN`
|
||||
* `KICAD_PCB_PLUGIN`
|
||||
|
||||
# Advanced configuration
|
||||
|
||||
There are some advance configuration options, which are mostly used for
|
||||
development or testing purposes.
|
||||
|
||||
To set these options, you can create the file `kicad_advanced` and set the keys
|
||||
as desired (the [advanced config documentation][] for a current list. You should
|
||||
never need to set these keys for normal usage - if you do, that's a bug.
|
||||
|
||||
|
||||
[CTest]: https://cmake.org/cmake/help/latest/module/CTest.html
|
||||
[Boost Unit Test framework]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/index.html
|
||||
[boost-test-functions]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html
|
||||
[AFL fuzzing tool]: http://lcamtuf.coredump.cx/afl/
|
||||
[trace mask documentation]: http://docs.kicad-pcb.org/doxygen/group__trace__env__vars.html
|
||||
[trace mask documentation]: http://docs.kicad-pcb.org/doxygen/group__trace__env__vars.html
|
||||
[trace mask documentation]: http://docs.kicad-pcb.org/doxygen/group__trace__env__vars.html
|
||||
[advanced config documentation]: http://docs.kicad-pcb.org/doxygen/namespaceAC__KEYS.html
|
|
@ -269,6 +269,7 @@ set( COMMON_SRCS
|
|||
${COMMON_PAGE_LAYOUT_SRCS}
|
||||
${COMMON_PREVIEW_ITEMS_SRCS}
|
||||
${PLOTTERS_CONTROL_SRCS}
|
||||
advanced_config.cpp
|
||||
base_struct.cpp
|
||||
bezier_curves.cpp
|
||||
bin_mod.cpp
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <advanced_config.h>
|
||||
|
||||
#include <common.h>
|
||||
#include <config_params.h>
|
||||
|
||||
#include <wx/config.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
/*
|
||||
* Flag to enable advanced config debugging
|
||||
*
|
||||
* Use "KICAD_ADVANCED_CONFIG" to enable.
|
||||
*
|
||||
* @ingroup trace_env_vars
|
||||
*/
|
||||
static const wxChar AdvancedConfigMask[] = wxT( "KICAD_ADVANCED_CONFIG" );
|
||||
|
||||
/**
|
||||
* List of known keys for advanced configuration options.
|
||||
*
|
||||
* Set these options in the file `kicad_advanced` in the
|
||||
* KiCad config directory.
|
||||
*/
|
||||
namespace AC_KEYS
|
||||
{
|
||||
} // namespace KEYS
|
||||
|
||||
|
||||
/*
|
||||
* Get a simple string for common parameters.
|
||||
*
|
||||
* This isn't exhaustive, but it covers most common types that might be
|
||||
* used in the advance config
|
||||
*/
|
||||
wxString dumpParamCfg( const PARAM_CFG_BASE& aParam )
|
||||
{
|
||||
wxString s = aParam.m_Ident + ": ";
|
||||
|
||||
/*
|
||||
* This implementation is rather simplistic, but it is
|
||||
* effective enough for simple uses. A better implementation would be
|
||||
* some kind of visitor, but that's somewhat more work.
|
||||
*/
|
||||
switch( aParam.m_Type )
|
||||
{
|
||||
case paramcfg_id::PARAM_INT:
|
||||
case paramcfg_id::PARAM_INT_WITH_SCALE:
|
||||
s << *static_cast<const PARAM_CFG_INT&>( aParam ).m_Pt_param;
|
||||
break;
|
||||
case paramcfg_id::PARAM_DOUBLE:
|
||||
s << *static_cast<const PARAM_CFG_DOUBLE&>( aParam ).m_Pt_param;
|
||||
break;
|
||||
case paramcfg_id::PARAM_WXSTRING:
|
||||
s << *static_cast<const PARAM_CFG_WXSTRING&>( aParam ).m_Pt_param;
|
||||
break;
|
||||
case paramcfg_id::PARAM_FILENAME:
|
||||
s << *static_cast<const PARAM_CFG_FILENAME&>( aParam ).m_Pt_param;
|
||||
break;
|
||||
case paramcfg_id::PARAM_BOOL:
|
||||
s << ( *static_cast<const PARAM_CFG_BOOL&>( aParam ).m_Pt_param ? "true" : "false" );
|
||||
break;
|
||||
default: s << "Unsupported PARAM_CFG variant: " << aParam.m_Type;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump the configs in the given array to trace.
|
||||
*/
|
||||
static void dumpCfg( const PARAM_CFG_ARRAY& aArray )
|
||||
{
|
||||
// only dump if we need to
|
||||
if( !wxLog::IsAllowedTraceMask( AdvancedConfigMask ) )
|
||||
return;
|
||||
|
||||
for( const auto& param : aArray )
|
||||
{
|
||||
wxLogTrace( AdvancedConfigMask, dumpParamCfg( param ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the filename for the advanced config file
|
||||
*
|
||||
* The user must check the file exists if they care.
|
||||
*/
|
||||
static wxFileName getAdvancedCfgFilename()
|
||||
{
|
||||
const static wxString cfg_filename{ "kicad_advanced" };
|
||||
return wxFileName( GetKicadConfigPath(), cfg_filename );
|
||||
}
|
||||
|
||||
|
||||
ADVANCED_CFG::ADVANCED_CFG()
|
||||
{
|
||||
wxLogTrace( AdvancedConfigMask, "Init advanced config" );
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
|
||||
const ADVANCED_CFG& ADVANCED_CFG::GetCfg()
|
||||
{
|
||||
static ADVANCED_CFG instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
void ADVANCED_CFG::loadFromConfigFile()
|
||||
{
|
||||
const auto k_advanced = getAdvancedCfgFilename();
|
||||
|
||||
if( !k_advanced.FileExists() )
|
||||
{
|
||||
wxLogTrace( AdvancedConfigMask, "File does not exist %s", k_advanced.GetFullPath() );
|
||||
return;
|
||||
}
|
||||
|
||||
wxLogTrace( AdvancedConfigMask, "Loading advanced config from: %s", k_advanced.GetFullPath() );
|
||||
|
||||
wxFileConfig file_cfg( "", "", k_advanced.GetFullPath() );
|
||||
loadSettings( file_cfg );
|
||||
}
|
||||
|
||||
|
||||
void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
{
|
||||
PARAM_CFG_ARRAY configParams;
|
||||
|
||||
// Add configs here
|
||||
|
||||
wxConfigLoadSetups( &aCfg, configParams );
|
||||
|
||||
dumpCfg( configParams );
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef ADVANCED_CFG__H
|
||||
#define ADVANCED_CFG__H
|
||||
|
||||
class wxConfigBase;
|
||||
|
||||
/**
|
||||
* Class containing "advanced" configuration options.
|
||||
*
|
||||
* Options set here are for developer or advanced users only. If a general user
|
||||
* needs to set one of these for normal KiCad use, either:
|
||||
* * They are working around some bug that should be fixed, or
|
||||
* * The parameter they are setting is of general interest and should be in the
|
||||
* main application config, with UI provided.
|
||||
*
|
||||
* Options in this class are, in general, preferable to #defines, as they
|
||||
* allow more flexible configuration by developers, and don't hide code from
|
||||
* the compiler on other configurations, which can result in broken builds.
|
||||
*
|
||||
* Never use advanced configs in an untestable way. If a function depends on
|
||||
* advanced config such that you cannot test it without changing the config,
|
||||
* "lift" the config to a higher level and make pass it as parameter of the code
|
||||
* under test. The tests can pass their own values as needed.
|
||||
*
|
||||
* This also applies to code that does not depend on "common" - it cannot
|
||||
* use this class, so you must pass configuration in as proper parameters.
|
||||
*
|
||||
* Sometimes you can just use values directly, and sometimes helper functions
|
||||
* might be provided to allow extra logic (for example when a advanced config
|
||||
* applies only on certain platforms).
|
||||
*
|
||||
* For more information on what config keys set these parameters in the
|
||||
* config files, and why you might want to set them, see #AC_KEYS
|
||||
*
|
||||
*/
|
||||
class ADVANCED_CFG
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Get the singleton instance's config, which is shared by all
|
||||
* consumers of advanced config.
|
||||
*
|
||||
* This configuration is read-only - to set options, users should
|
||||
* add the parameters to their config files at ~/.config/kicad/advanced, or the
|
||||
* platform equivalent.
|
||||
*/
|
||||
static const ADVANCED_CFG& GetCfg();
|
||||
|
||||
private:
|
||||
ADVANCED_CFG();
|
||||
|
||||
/**
|
||||
* Load the config from the normal config file
|
||||
*/
|
||||
void loadFromConfigFile();
|
||||
|
||||
/*
|
||||
* Load config from the given config base
|
||||
*/
|
||||
void loadSettings( wxConfigBase& aCfg );
|
||||
};
|
||||
|
||||
#endif // ADVANCED_CFG__H
|
Loading…
Reference in New Issue