clean up config parsing, make more robust
authorJim Morris <morris@wolfman.com>
Thu, 10 Apr 2014 07:33:14 +0000 (00:33 -0700)
committerJim Morris <morris@wolfman.com>
Thu, 10 Apr 2014 07:33:14 +0000 (00:33 -0700)
clean up config code in general
in kernel setup serial before config so we can print errors to serial console

13 files changed:
src/libs/Config.cpp
src/libs/Config.h
src/libs/ConfigSource.cpp
src/libs/ConfigSource.h
src/libs/ConfigSources/FileConfigSource.cpp
src/libs/ConfigSources/FileConfigSource.h
src/libs/ConfigSources/FirmConfigSource.cpp
src/libs/ConfigSources/FirmConfigSource.h
src/libs/Kernel.cpp
src/libs/utils.cpp
src/main.cpp
src/modules/utils/configurator/Configurator.cpp
src/modules/utils/configurator/Configurator.h

index 6184d8a..afbf0c9 100644 (file)
@@ -22,41 +22,39 @@ using namespace std;
 
 // Add various config sources. Config can be fetched from several places.
 // All values are read into a cache, that is then used by modules to read their configuration
-Config::Config(){
+Config::Config()
+{
     this->config_cache_loaded = false;
 
     // Config source for firm config found in src/config.default
-    this->config_sources.push_back( new FirmConfigSource() );
+    this->config_sources.push_back( new FirmConfigSource("firm") );
 
     // Config source for */config files
-    FileConfigSourcefcs = NULL;
+    FileConfigSource *fcs = NULL;
     if( file_exists("/local/config") )
-        fcs = new FileConfigSource("/local/config", LOCAL_CONFIGSOURCE_CHECKSUM);
+        fcs = new FileConfigSource("/local/config", "local");
     else if( file_exists("/local/config.txt") )
-        fcs = new FileConfigSource("/local/config.txt", LOCAL_CONFIGSOURCE_CHECKSUM);
-    if( fcs != NULL ){
+        fcs = new FileConfigSource("/local/config.txt", "local");
+    if( fcs != NULL ) {
         this->config_sources.push_back( fcs );
         fcs = NULL;
     }
     if( file_exists("/sd/config") )
-       fcs = new FileConfigSource("/sd/config",    SD_CONFIGSOURCE_CHECKSUM   );
+        fcs = new FileConfigSource("/sd/config", "sd");
     else if( file_exists("/sd/config.txt") )
-       fcs = new FileConfigSource("/sd/config.txt",    SD_CONFIGSOURCE_CHECKSUM   );
+        fcs = new FileConfigSource("/sd/config.txt", "sd");
     if( fcs != NULL )
         this->config_sources.push_back( fcs );
-
-    // Pre-load the config cache
-    this->config_cache_load();
-
 }
 
-void Config::on_module_loaded(){}
+void Config::on_module_loaded() {}
 
-void Config::on_console_line_received( void* argument ){}
+void Config::on_console_line_received( void *argument ) {}
 
 // Set a value in the config cache, but not in any config source
-void Config::set_string( string setting, string value ){
-    ConfigValue* cv = new ConfigValue;
+void Config::set_string( string setting, string value )
+{
+    ConfigValue *cv = new ConfigValue;
     cv->found = true;
     get_checksums(cv->check_sums, setting);
     cv->value = value;
@@ -67,11 +65,12 @@ void Config::set_string( string setting, string value ){
 }
 
 // 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
-void Config::get_module_list(vector<uint16_t>* list, uint16_t family){
-    for( unsigned int i=1; i<this->config_cache.size(); i++){
-        ConfigValue* value = this->config_cache.at(i);
+void Config::get_module_list(vector<uint16_t> *list, uint16_t family)
+{
+    for( unsigned int i = 1; i < this->config_cache.size(); i++) {
+        ConfigValue *value = this->config_cache.at(i);
         //if( value->check_sums.size() == 3 && value->check_sums.at(2) == CHECKSUM("enable") && value->check_sums.at(0) == family ){
-        if( value->check_sums[2] == CHECKSUM("enable") && value->check_sums[0] == family ){
+        if( value->check_sums[2] == CHECKSUM("enable") && value->check_sums[0] == family ) {
             // We found a module enable for this family, add it's number
             list->push_back(value->check_sums[1]);
         }
@@ -80,18 +79,18 @@ void Config::get_module_list(vector<uint16_t>* list, uint16_t family){
 
 
 // Command to load config cache into buffer for multiple reads during init
-void Config::config_cache_load(){
+void Config::config_cache_load()
+{
 
     // First clear the cache
     this->config_cache_clear();
 
     // First element is a special empty ConfigValue for values not found
-    ConfigValueresult = new ConfigValue;
+    ConfigValue *result = new ConfigValue;
     this->config_cache.push_back(result);
 
     // For each ConfigSource in our stack
-    for( unsigned int i = 0; i < this->config_sources.size(); i++ ){
-        ConfigSource* source = this->config_sources[i];
+    for( ConfigSource *source : this->config_sources ) {
         source->transfer_values_to_cache(&this->config_cache);
     }
 
@@ -99,16 +98,20 @@ void Config::config_cache_load(){
 }
 
 // Command to clear the config cache after init
-void Config::config_cache_clear(){
-    while( ! this->config_cache.empty() ){
-        delete this->config_cache.back();
-        this->config_cache.pop_back();
+void Config::config_cache_clear()
+{
+    for (ConfigValue *i : this->config_cache)  {
+        delete i;
     }
+
+    //this->config_cache.clear(); // does not release vector memory
+    ConfigCache().swap(this->config_cache);   //  makes sure the vector releases its memory
     this->config_cache_loaded = false;
 }
 
 // Three ways to read a value from the config, depending on adress length
-ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c ){
+ConfigValue *Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c )
+{
     uint16_t check_sums[3];
     check_sums[0] = check_sum_a;
     check_sums[1] = check_sum_b;
@@ -116,7 +119,8 @@ ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t
     return this->value(check_sums);
 }
 
-ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b){
+ConfigValue *Config::value(uint16_t check_sum_a, uint16_t check_sum_b)
+{
     uint16_t check_sums[3];
     check_sums[0] = check_sum_a;
     check_sums[1] = check_sum_b;
@@ -124,7 +128,8 @@ ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b){
     return this->value(check_sums);
 }
 
-ConfigValue* Config::value(uint16_t check_sum){
+ConfigValue *Config::value(uint16_t check_sum)
+{
     uint16_t check_sums[3];
     check_sums[0] = check_sum;
     check_sums[1] = 0x0000;
@@ -135,30 +140,33 @@ ConfigValue* Config::value(uint16_t check_sum){
 // Get a value from the configuration as a string
 // 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
 // See get_checksum
-ConfigValue* Config::value(uint16_t check_sums[]){
-    ConfigValue* result = this->config_cache[0];
+ConfigValue *Config::value(uint16_t check_sums[])
+{
     bool cache_preloaded = this->config_cache_loaded;
-    if( !cache_preloaded ){ this->config_cache_load(); }
+    if( !cache_preloaded ) {
+        this->config_cache_load();
+    }
+    ConfigValue *result = this->config_cache[0];
 
-    for( unsigned int i=1; i<this->config_cache.size(); i++){
+    for( unsigned int i = 1; i < this->config_cache.size(); i++) {
         // If this line matches the checksum
         bool match = true;
         unsigned int counter = 0;
-        while(check_sums[counter] != 0x0000 && counter <= 2 ){
-             if(this->config_cache[i]->check_sums[counter] != check_sums[counter] ){
+        while(check_sums[counter] != 0x0000 && counter <= 2 ) {
+            if(this->config_cache[i]->check_sums[counter] != check_sums[counter] ) {
                 match = false;
                 break;
             }
             counter++;
         }
-        if( match == false ){
+        if( match == false ) {
             continue;
         }
         result = this->config_cache[i];
         break;
     }
 
-    if( !cache_preloaded ){
+    if( !cache_preloaded ) {
         this->config_cache_clear();
     }
     return result;
index 3300834..3e9cca0 100644 (file)
@@ -14,9 +14,6 @@ using namespace std;
 #include <vector>
 #include <string>
 
-#define LOCAL_CONFIGSOURCE_CHECKSUM     13581
-#define SD_CONFIGSOURCE_CHECKSUM        19415
-
 class ConfigValue;
 class ConfigSource;
 
dissimilarity index 87%
index a029b57..71f0eb3 100644 (file)
@@ -1,78 +1,73 @@
-#include "utils.h"
-#include "ConfigSource.h"
-#include "ConfigValue.h"
-#include "ConfigCache.h"
-
-#include "stdio.h"
-
-string ConfigSource::process_char_from_ascii_config(int c, ConfigCache *cache)
-{
-    static string buffer;
-    if (c == '\n' || c == EOF) {
-        // We have a new line
-        if( buffer[0] == '#' ) {
-            buffer.clear();    // Ignore comments
-            return "";
-        }
-        if( buffer.length() < 3 ) {
-            buffer.clear();    //Ignore empty lines
-            return "";
-        }
-        size_t begin_key = buffer.find_first_not_of(" \t");
-        size_t begin_value = buffer.find_first_not_of(" \t", buffer.find_first_of(" \t", begin_key));
-
-        uint16_t check_sums[3];
-        get_checksums(check_sums, buffer.substr(begin_key,  buffer.find_first_of(" \t", begin_key) - begin_key).append(" "));
-
-        ConfigValue *result = new ConfigValue;
-
-        result->found = true;
-        result->check_sums[0] = check_sums[0];
-        result->check_sums[1] = check_sums[1];
-        result->check_sums[2] = check_sums[2];
-
-        result->value = buffer.substr(begin_value, buffer.find_first_of("\r\n# \t", begin_value + 1) - begin_value);
-        // Append the newly found value to the cache we were passed
-        cache->replace_or_push_back(result);
-
-        buffer.clear();
-
-
-        return result->value;
-    } else
-        buffer += c;
-
-    return "";
-}
-
-string ConfigSource::process_char_from_ascii_config(int c, uint16_t line_checksums[3])
-{
-    static string buffer;
-    string value;
-    if (c == '\n' || c == EOF) {
-        // We have a new line
-        if( buffer[0] == '#' ) {
-            buffer.clear();    // Ignore comments
-            return "";
-        }
-        if( buffer.length() < 3 ) {
-            buffer.clear();    //Ignore empty lines
-            return "";
-        }
-        size_t begin_key = buffer.find_first_not_of(" \t");
-        size_t begin_value = buffer.find_first_not_of(" \t", buffer.find_first_of(" \t", begin_key));
-
-        uint16_t check_sums[3];
-        get_checksums(check_sums, buffer.substr(begin_key,  buffer.find_first_of(" \t", begin_key) - begin_key).append(" "));
-
-        if(check_sums[0] == line_checksums[0] && check_sums[1] == line_checksums[1] && check_sums[2] == line_checksums[2] ) {
-            value = buffer.substr(begin_value, buffer.find_first_of("\r\n# \t", begin_value + 1) - begin_value);
-            buffer.clear();
-            return value;
-        }
-
-        buffer.clear();
-    } else
-        buffer += c;
-    return value;
-}
+#include "utils.h"
+#include "ConfigSource.h"
+#include "ConfigValue.h"
+#include "ConfigCache.h"
+
+#include "stdio.h"
+
+ConfigValue* ConfigSource::process_line(const string &buffer)
+{
+    if( buffer[0] == '#' ) {
+        return NULL;
+    }
+    if( buffer.length() < 3 ) {
+        return NULL;
+    }
+
+    size_t begin_key = buffer.find_first_not_of(" \t");
+    if(begin_key == string::npos || buffer[begin_key] == '#') return NULL; // comment line or blank line
+
+    size_t end_key = buffer.find_first_of(" \t", begin_key);
+    if(end_key == string::npos) {
+        printf("ERROR: config file line %s is invalid, no key value pair found\r\n", buffer.c_str());
+        return NULL;
+    }
+
+    size_t begin_value = buffer.find_first_not_of(" \t", end_key);
+    if(begin_value == string::npos || buffer[begin_value] == '#') {
+        printf("ERROR: config file line %s has no value\r\n", buffer.c_str());
+        return NULL;
+    }
+
+    string key= buffer.substr(begin_key,  end_key - begin_key).append(" ");
+    uint16_t check_sums[3];
+    get_checksums(check_sums, key);
+
+    ConfigValue *result = new ConfigValue;
+
+    result->found = true;
+    result->check_sums[0] = check_sums[0];
+    result->check_sums[1] = check_sums[1];
+    result->check_sums[2] = check_sums[2];
+
+    size_t end_value = buffer.find_first_of("\r\n# \t", begin_value + 1);
+    size_t vsize = end_value == string::npos ? end_value : end_value - begin_value;
+    result->value = buffer.substr(begin_value, vsize);
+
+    //printf("key: %s, value: %s\n\n", key.c_str(), result->value.c_str());
+    return result;
+}
+
+string ConfigSource::process_line_from_ascii_config(const string &buffer, ConfigCache *cache)
+{
+    ConfigValue *result = process_line(buffer);
+    if(result != NULL) {
+        // Append the newly found value to the cache we were passed
+        cache->replace_or_push_back(result);
+        return result->value;
+    }
+    return "";
+}
+
+string ConfigSource::process_line_from_ascii_config(const string &buffer, uint16_t line_checksums[3])
+{
+    string value= "";
+    ConfigValue *result = process_line(buffer);
+    if(result != NULL) {
+        if(result->check_sums[0] == line_checksums[0] && result->check_sums[1] == line_checksums[1] && result->check_sums[2] == line_checksums[2]) {
+            value= result->value;
+        }
+        delete result;
+    }
+    return value;
+}
index 767e231..b5f9a9c 100644 (file)
@@ -28,8 +28,11 @@ class ConfigSource {
         uint16_t name_checksum;
 
     protected:
-        virtual string process_char_from_ascii_config(int c, ConfigCache* cache);
-        virtual string process_char_from_ascii_config(int c, uint16_t line_checksums[3]);
+        virtual string process_line_from_ascii_config(const string& line, ConfigCache* cache);
+        virtual string process_line_from_ascii_config(const string& line, uint16_t line_checksums[3]);
+
+    private:
+        ConfigValue* process_line(const string &buffer);
 };
 
 
index 2718813..997d55a 100644 (file)
 #include "utils.h"
 #include <malloc.h>
 
-
 using namespace std;
 #include <string>
-
+#include <fstream>
 #include <stdio.h>
 
-FileConfigSource::FileConfigSource(string config_file, uint16_t name_checksum){
-    this->name_checksum = name_checksum;
+FileConfigSource::FileConfigSource(string config_file, const char *name)
+{
+    this->name_checksum = get_checksum(name);
     this->config_file = config_file;
     this->config_file_found = false;
 }
 
 // Transfer all values found in the file to the passed cache
-void FileConfigSource::transfer_values_to_cache( ConfigCache* cache ){
+void FileConfigSource::transfer_values_to_cache( ConfigCache *cache )
+{
 
-    if( this->has_config_file() == false ){return;}
+    if( !this->has_config_file() ) {
+        return;
+    }
     // Open the config file ( find it if we haven't already found it )
-    FILE *lp = fopen(this->get_config_file().c_str(), "r");
-    int c;
+    std::ifstream ifs(this->get_config_file().c_str(), std::ifstream::in);
     // For each line
-    do {
-        process_char_from_ascii_config(c = fgetc(lp), cache);
-    } while (c != EOF);
-    fclose(lp);
+    string line;
+    while(ifs.good()) {
+        std::getline(ifs, line);
+        process_line_from_ascii_config(line, cache);
+    }
+    ifs.close();
 }
 
 // Return true if the check_sums match
-bool FileConfigSource::is_named( uint16_t check_sum ){
+bool FileConfigSource::is_named( uint16_t check_sum )
+{
     return check_sum == this->name_checksum;
 }
 
 // Write a config setting to the file
-void FileConfigSource::write( string setting, string value ){
+void FileConfigSource::write( string setting, string value )
+{
     // Open the config file ( find it if we haven't already found it )
     FILE *lp = fopen(this->get_config_file().c_str(), "r+");
     string buffer;
@@ -52,23 +58,34 @@ void FileConfigSource::write( string setting, string value ){
     // For each line
     do {
         c = fgetc (lp);
-        if (c == '\n' || c == EOF){
+        if (c == '\n' || c == EOF) {
             // We have a new line
-            if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
-            if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
+            if( buffer[0] == '#' ) {
+                buffer.clear();    // Ignore comments
+                continue;
+            }
+            if( buffer.length() < 3 ) {
+                buffer.clear();    //Ignore empty lines
+                continue;
+            }
             size_t begin_key = buffer.find_first_not_of(" \t");
             size_t begin_value = buffer.find_first_not_of(" \t", buffer.find_first_of(" \t", begin_key));
             // If this line matches the checksum
             string candidate = buffer.substr(begin_key,  buffer.find_first_of(" \t", begin_key) - begin_key);
-            if( candidate.compare(setting) != 0 ){ buffer.clear(); continue; }
-            int free_space = int(int(buffer.find_first_of("\r\n#", begin_value+1))-begin_value);
-            if( int(value.length()) >= free_space ){
+            if( candidate.compare(setting) != 0 ) {
+                buffer.clear();
+                continue;
+            }
+            int free_space = int(int(buffer.find_first_of("\r\n#", begin_value + 1)) - begin_value);
+            if( int(value.length()) >= free_space ) {
                 //THEKERNEL->streams->printf("ERROR: Not enough room for value\r\n");
                 fclose(lp);
                 return;
             }
             // Update value
-            for( int i = value.length(); i < free_space; i++){ value += " "; }
+            for( int i = value.length(); i < free_space; i++) {
+                value += " ";
+            }
             fpos_t pos;
             fgetpos( lp, &pos );
             int start = pos - buffer.length() + begin_value - 1;
@@ -76,7 +93,7 @@ void FileConfigSource::write( string setting, string value ){
             fputs(value.c_str(), lp);
             fclose(lp);
             return;
-        }else{
+        } else {
             buffer += c;
         }
     } while (c != EOF);
@@ -85,49 +102,62 @@ void FileConfigSource::write( string setting, string value ){
 }
 
 // Return the value for a specific checksum
-string FileConfigSource::read( uint16_t check_sums[3] ){
-
+string FileConfigSource::read( uint16_t check_sums[3] )
+{
     string value = "";
 
-    if( this->has_config_file() == false ){return value;}
+    if( this->has_config_file() == false ) {
+        return value;
+    }
+
     // Open the config file ( find it if we haven't already found it )
-    FILE *lp = fopen(this->get_config_file().c_str(), "r");
-    int c;
+    std::ifstream ifs(this->get_config_file().c_str(), std::ifstream::in);
     // For each line
-    do {
-        c = fgetc (lp);
-        process_char_from_ascii_config(c, check_sums);
-    } while (c != EOF);
-    fclose(lp);
+    string line;
+    while(ifs.good()) {
+        std::getline(ifs, line);
+        value = process_line_from_ascii_config(line, check_sums);
+        if(!value.empty()) break; // found it
+    }
+    ifs.close();
 
     return value;
 }
 
 // Return wether or not we have a readable config file
-bool FileConfigSource::has_config_file(){
-    if( this->config_file_found ){ return true; }
+bool FileConfigSource::has_config_file()
+{
+    if( this->config_file_found ) {
+        return true;
+    }
     this->try_config_file(this->config_file);
-    if( this->config_file_found ){
+    if( this->config_file_found ) {
         return true;
-    }else{
+    } else {
         return false;
     }
 
 }
 
 // Tool function for get_config_file
-inline void FileConfigSource::try_config_file(string candidate){
-    if(file_exists(candidate)){ this->config_file_found = true; }
+inline void FileConfigSource::try_config_file(string candidate)
+{
+    if(file_exists(candidate)) {
+        this->config_file_found = true;
+    }
 }
 
 // Get the filename for the config file
-string FileConfigSource::get_config_file(){
-    if( this->config_file_found ){ return this->config_file; }
-    if( this->has_config_file() ){
+string FileConfigSource::get_config_file()
+{
+    if( this->config_file_found ) {
+        return this->config_file;
+    }
+    if( this->has_config_file() ) {
         return this->config_file;
-    }else{
+    } else {
         printf("ERROR: no config file found\r\n");
-               return "";
+        return "";
     }
 }
 
index 4985e2c..a535e96 100644 (file)
@@ -15,23 +15,21 @@ class ConfigCache;
 using namespace std;
 #include <string>
 
-#define FILE_CONFIGSOURCE_CHECKSUM    5281      // "file"
-
-class FileConfigSource : public ConfigSource {
-    public:
-        FileConfigSource(string config_file = "/sd/config", uint16_t name_checksum = FILE_CONFIGSOURCE_CHECKSUM);
-        void transfer_values_to_cache( ConfigCache* cache );
-        bool is_named( uint16_t check_sum );
-        void write( string setting, string value );
-        string read( uint16_t check_sums[3] );
-        bool has_config_file();
-        void try_config_file(string candidate);
-        string get_config_file();
-
-        string config_file;         // Path to the config file
-        bool   config_file_found;   // Wether or not the config file's location is known
-
-
+class FileConfigSource : public ConfigSource
+{
+public:
+    FileConfigSource(string config_file, const char *name);
+    void transfer_values_to_cache( ConfigCache *cache );
+    bool is_named( uint16_t check_sum );
+    void write( string setting, string value );
+    string read( uint16_t check_sums[3] );
+    bool has_config_file();
+    void try_config_file(string candidate);
+    string get_config_file();
+
+private:
+    string config_file;         // Path to the config file
+    bool   config_file_found;   // Wether or not the config file's location is known
 };
 
 
index 0c2b363..d0b25ee 100644 (file)
@@ -10,7 +10,7 @@
 #include "FirmConfigSource.h"
 #include "ConfigCache.h"
 #include <malloc.h>
-
+#include "utils.h"
 
 using namespace std;
 #include <string>
@@ -21,8 +21,8 @@ extern char _binary_config_default_start;
 extern char _binary_config_default_end;
 
 
-FirmConfigSource::FirmConfigSource(uint16_t name_checksum){
-    this->name_checksum = name_checksum;
+FirmConfigSource::FirmConfigSource(const char* name){
+    this->name_checksum = get_checksum(name);
 }
 
 // Transfer all values found in the file to the passed cache
@@ -30,8 +30,16 @@ void FirmConfigSource::transfer_values_to_cache( ConfigCache* cache ){
 
     char* p = &_binary_config_default_start;
     // For each line
-    while( p != &_binary_config_default_end ){
-        process_char_from_ascii_config(*p++, cache);
+    while( p < &_binary_config_default_end ){
+        // find eol
+        char *eol= p;
+        while(eol < &_binary_config_default_end) {
+            if(*eol++ == '\n') break;
+        }
+        string line(p, eol-p);
+        //printf("firm: processing %s\n", line.c_str());
+        p= eol;
+        process_line_from_ascii_config(line, cache);
     }
 }
 
@@ -52,10 +60,16 @@ string FirmConfigSource::read( uint16_t check_sums[3] ){
 
     char* p = &_binary_config_default_start;
     // For each line
-    while( p != &_binary_config_default_end ){
-        value = process_char_from_ascii_config(*p++, check_sums);
-        if (value.length())
-            return value;
+    while( p < &_binary_config_default_end ){
+        // find eol
+        char *eol= p;
+        while(eol < &_binary_config_default_end) {
+            if(*eol++ == '\n') break;
+        }
+        string line(p, eol-p);
+        p= eol;
+        value = process_line_from_ascii_config(line, check_sums);
+        if(!value.empty()) return value;
     }
 
     return value;
index 5a425e1..15ba95a 100644 (file)
@@ -16,11 +16,9 @@ class ConfigCache;
 using namespace std;
 #include <string>
 
-#define FIRM_CONFIGSOURCE_CHECKSUM    CHECKSUM("firm")
-
 class FirmConfigSource : public ConfigSource {
     public:
-        FirmConfigSource(uint16_t name_checksum = FIRM_CONFIGSOURCE_CHECKSUM);
+        FirmConfigSource(const char* name);
         void transfer_values_to_cache( ConfigCache* cache );
         bool is_named( uint16_t check_sum );
         void write( string setting, string value );
index b5dacc8..2fa961e 100644 (file)
@@ -42,16 +42,24 @@ Kernel* Kernel::instance;
 Kernel::Kernel(){
     instance= this; // setup the Singleton instance of the kernel
 
-    // Config first, because we need the baud_rate setting before we start serial
+    // serial first at fixed baud rate (MRI_BAUD) so config can report errors to serial
+    this->serial = new SerialConsole(USBTX, USBRX, 115200); // TODO set to whatver MRI is
+
+    // Config next, but does not load cache yet
     this->config         = new Config();
+    // Pre-load the config cache, do after ssetting up serial so we can report errors to serial
+    this->config->config_cache_load();
+
+    // now config is loaded we can do normal setup for serial and the rest
+    delete this->serial;
 
-    // Serial second, because the other modules might want to say something
     this->streams        = new StreamOutputPool();
 
     this->current_path   = "/";
 
     // Configure UART depending on MRI config
     // Match up the SerialConsole to MRI UART. This makes it easy to use only one UART for both debug and actual commands.
+    // FIXME this requires MRI which is not present in a Release build
     NVIC_SetPriorityGrouping(0);
     switch( __mriPlatform_CommUartIndex() ) {
         case 0:
index 899933a..78325b6 100644 (file)
@@ -42,7 +42,7 @@ void get_checksums(uint16_t check_sums[], const string key){
     check_sums[2] = 0x0000;
     size_t begin_key = 0;
     unsigned int counter = 0;
-    while( begin_key < key.size()-1 ){
+    while( begin_key < key.size()-1 && counter < 3 ){
         const size_t end_key =  k.find_first_of(" .", begin_key);
         const string key_node = k.substr(begin_key, end_key - begin_key);
         check_sums[counter] = get_checksum(key_node);
index 6be92d7..dad0577 100644 (file)
@@ -81,7 +81,7 @@ int main() {
 
     Kernel* kernel = new Kernel();
 
-    kernel->streams->printf("Smoothie ( grbl port ) version 0.7.2 with new accel @%ldMHz\r\n", SystemCoreClock / 1000000);
+    kernel->streams->printf("Smoothie Running @%ldMHz\r\n", SystemCoreClock / 1000000);
     Version version;
     kernel->streams->printf("  Build version %s, Build date %s\r\n", version.get_build(), version.get_build_date());
 
index 7ec2689..4109a6d 100644 (file)
 #include "FileConfigSource.h"
 #include "ConfigValue.h"
 
+#define CONF_NONE       0
+#define CONF_ROM        1
+#define CONF_SD         2
+#define CONF_EEPROM     3
+
+#define config_get_command_checksum        CHECKSUM("config-get")
+#define config_set_command_checksum        CHECKSUM("config-set")
+#define config_load_command_checksum       CHECKSUM("config-load")
+
 void Configurator::on_module_loaded(){
     this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
 //    this->register_for_event(ON_GCODE_RECEIVED);
@@ -74,8 +83,13 @@ void Configurator::config_get_command( string parameters, StreamOutput* stream )
         get_checksums(setting_checksums, setting );
         ConfigValue* cv = THEKERNEL->config->value(setting_checksums);
         string value = "";
-        if(cv->found){ value = cv->as_string(); }
-        stream->printf( "live: %s is set to %s\r\n", setting.c_str(), value.c_str() );
+        if(cv->found){
+            value = cv->as_string();
+            stream->printf( "live: %s is set to %s\r\n", setting.c_str(), value.c_str() );
+        }else{
+            stream->printf( "live: %s is not in config\r\n", setting.c_str());
+        }
+
     } else { // output setting from specified source
         uint16_t source_checksum = get_checksum( source );
         uint16_t setting_checksums[3];
@@ -83,7 +97,11 @@ void Configurator::config_get_command( string parameters, StreamOutput* stream )
         for(unsigned int i=0; i < THEKERNEL->config->config_sources.size(); i++){
             if( THEKERNEL->config->config_sources[i]->is_named(source_checksum) ){
                 string value = THEKERNEL->config->config_sources[i]->read(setting_checksums);
-                stream->printf( "%s: %s is set to %s\r\n", source.c_str(), setting.c_str(), value.c_str() );
+                if(value.empty()){
+                    stream->printf( "%s: %s is not in config\r\n", source.c_str(), setting.c_str() );
+                }else{
+                    stream->printf( "%s: %s is set to %s\r\n", source.c_str(), setting.c_str(), value.c_str() );
+                }
                 break;
             }
         }
@@ -121,7 +139,7 @@ void Configurator::config_load_command( string parameters, StreamOutput* stream
         THEKERNEL->call_event(ON_CONFIG_RELOAD);
         stream->printf( "Reloaded settings\r\n" );
     } else if(file_exists(source)){
-        FileConfigSource fcs(source);
+        FileConfigSource fcs(source, "userfile");
         fcs.transfer_values_to_cache(&THEKERNEL->config->config_cache);
         THEKERNEL->call_event(ON_CONFIG_RELOAD);
         stream->printf( "Loaded settings from %s\r\n", source.c_str() );
index e945126..2664813 100644 (file)
@@ -9,20 +9,12 @@
 #ifndef configurator_h
 #define configurator_h
 
-#include "libs/Kernel.h"
-#include "libs/nuts_bolts.h"
-#include "libs/utils.h"
-#include "libs/StreamOutput.h"
+#include "Module.h"
 
+#include <string>
+using std::string;
 
-#define CONF_NONE       0
-#define CONF_ROM        1
-#define CONF_SD         2
-#define CONF_EEPROM     3
-
-#define config_get_command_checksum        CHECKSUM("config-get")
-#define config_set_command_checksum        CHECKSUM("config-set")
-#define config_load_command_checksum       CHECKSUM("config-load")
+class StreamOutput;
 
 class Configurator : public Module {
     public: