Merge remote-tracking branch 'upstream/edge' into upstream-master
[clinton/Smoothieware.git] / src / libs / Config.cpp
CommitLineData
df27a6a3 1/*
4cff3ded
AW
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie 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.
4 Smoothie 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.
df27a6a3 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
4cff3ded
AW
6*/
7
3c132bd0
AW
8using namespace std;
9#include <vector>
4cff3ded 10#include <string>
3c132bd0 11
4cff3ded
AW
12#include "libs/Kernel.h"
13#include "Config.h"
c295905f
AW
14#include "ConfigValue.h"
15#include "ConfigSource.h"
16#include "ConfigCache.h"
4eb9c745
AW
17#include "libs/nuts_bolts.h"
18#include "libs/utils.h"
6268c527 19#include "libs/SerialMessage.h"
c295905f 20#include "libs/ConfigSources/FileConfigSource.h"
33110301 21#include "libs/ConfigSources/FirmConfigSource.h"
a2f7633f 22#include "StreamOutputPool.h"
4cff3ded 23
93694d6b
AW
24// Add various config sources. Config can be fetched from several places.
25// All values are read into a cache, that is then used by modules to read their configuration
577414f6
JM
26Config::Config()
27{
a2f7633f 28 this->config_cache = NULL;
fc82a1ee 29
33110301 30 // Config source for firm config found in src/config.default
577414f6 31 this->config_sources.push_back( new FirmConfigSource("firm") );
33110301 32
c295905f 33 // Config source for */config files
577414f6 34 FileConfigSource *fcs = NULL;
40a7c6c0 35 if( file_exists("/local/config") )
577414f6 36 fcs = new FileConfigSource("/local/config", "local");
40a7c6c0 37 else if( file_exists("/local/config.txt") )
577414f6
JM
38 fcs = new FileConfigSource("/local/config.txt", "local");
39 if( fcs != NULL ) {
40a7c6c0 40 this->config_sources.push_back( fcs );
247f7afd
L
41 fcs = NULL;
42 }
40a7c6c0 43 if( file_exists("/sd/config") )
577414f6 44 fcs = new FileConfigSource("/sd/config", "sd");
40a7c6c0 45 else if( file_exists("/sd/config.txt") )
577414f6 46 fcs = new FileConfigSource("/sd/config.txt", "sd");
40a7c6c0
L
47 if( fcs != NULL )
48 this->config_sources.push_back( fcs );
cebe90b6
AW
49}
50
93ea6adb
JM
51Config::Config(ConfigSource *cs)
52{
53 this->config_cache = NULL;
54 this->config_sources.push_back( cs );
55}
56
57Config::~Config()
58{
59 config_cache_clear();
60 for(auto i : this->config_sources) {
61 delete i;
62 }
63}
64
577414f6 65void Config::on_module_loaded() {}
26806df9 66
577414f6 67void Config::on_console_line_received( void *argument ) {}
ced5fce8 68
93694d6b 69// Get a list of modules, used by module "pools" that look for the "enable" keyboard to find things like "moduletype.modulename.enable" as the marker of a new instance of a module
577414f6
JM
70void Config::get_module_list(vector<uint16_t> *list, uint16_t family)
71{
a2f7633f 72 this->config_cache->collect(family, CHECKSUM("enable"), list);
26c569a2 73}
26806df9 74
d272dd3c 75// Command to load config cache into buffer for multiple reads during init
a2f7633f 76void Config::config_cache_load(bool parse)
577414f6 77{
93694d6b 78 // First clear the cache
d272dd3c 79 this->config_cache_clear();
c295905f 80
a2f7633f
JM
81 this->config_cache= new ConfigCache;
82 if(parse) {
83 // For each ConfigSource in our stack
84 for( ConfigSource *source : this->config_sources ) {
85 source->transfer_values_to_cache(this->config_cache);
86 }
c295905f 87 }
d272dd3c
L
88}
89
90// Command to clear the config cache after init
577414f6
JM
91void Config::config_cache_clear()
92{
a2f7633f
JM
93 delete this->config_cache;
94 this->config_cache= NULL;
da24d6ae
AW
95}
96
93694d6b 97// Three ways to read a value from the config, depending on adress length
577414f6
JM
98ConfigValue *Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c )
99{
df27a6a3
MM
100 uint16_t check_sums[3];
101 check_sums[0] = check_sum_a;
4464301d
AW
102 check_sums[1] = check_sum_b;
103 check_sums[2] = check_sum_c;
3c132bd0 104 return this->value(check_sums);
df27a6a3 105}
3c132bd0 106
d41a043b
JM
107static ConfigValue dummyValue;
108
4cff3ded
AW
109// Get a value from the configuration as a string
110// Because we don't like to waste space in Flash with lengthy config parameter names, we take a checksum instead so that the name does not have to be stored
111// See get_checksum
577414f6
JM
112ConfigValue *Config::value(uint16_t check_sums[])
113{
a2f7633f
JM
114 if( !is_config_cache_loaded() ) {
115 THEKERNEL->streams->printf("ERROR: calling value after config cache has been cleared\n");
116 // note this will cause whatever called it to blow up!
117 return NULL;
d272dd3c 118 }
2b56b363 119
a2f7633f
JM
120 ConfigValue *result = this->config_cache->lookup(check_sums);
121
122 if(result == NULL) {
123 // create a dummy value for this to play with, each call requires it's own value not a shared one
d41a043b
JM
124 // result= new ConfigValue(check_sums);
125 // config_cache->add(result);
126 dummyValue.clear();
127 result = &dummyValue;
d272dd3c 128 }
a2f7633f 129
b66fb830 130 return result;
4cff3ded
AW
131}
132
3c132bd0 133
4cff3ded 134