Michael Spencer / Smoothie

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FileConfigSource.cpp Source File

FileConfigSource.cpp

00001 /*
00002       This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
00003       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.
00004       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.
00005       You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
00006 */
00007 
00008 #include "libs/Kernel.h"
00009 #include "ConfigValue.h"
00010 #include "FileConfigSource.h"
00011 #include "ConfigCache.h"
00012 
00013 
00014 using namespace std;
00015 #include <string>
00016 
00017 
00018 FileConfigSource::FileConfigSource(string config_file, uint16_t name_checksum){
00019     this->name_checksum = name_checksum;
00020     this->config_file = config_file;
00021     this->config_file_found = false;
00022 }
00023 
00024 // Transfer all values found in the file to the passed cache
00025 void FileConfigSource::transfer_values_to_cache( ConfigCache* cache ){
00026 
00027     if( this->has_config_file() == false ){return;}
00028     // Open the config file ( find it if we haven't already found it )
00029     FILE *lp = fopen(this->get_config_file().c_str(), "r");
00030     int c;
00031     // For each line
00032     do {
00033         process_char_from_ascii_config(c = fgetc(lp), cache);
00034     } while (c != EOF);
00035     fclose(lp);
00036 }
00037 
00038 // Return true if the check_sums match
00039 bool FileConfigSource::is_named( uint16_t check_sum ){
00040     return check_sum == this->name_checksum;
00041 }
00042 
00043 // Write a config setting to the file
00044 void FileConfigSource::write( string setting, string value ){
00045     // Open the config file ( find it if we haven't already found it )
00046     FILE *lp = fopen(this->get_config_file().c_str(), "r+");
00047     string buffer;
00048     int c;
00049     // For each line
00050     do {
00051         c = fgetc (lp);
00052         if (c == '\n' || c == EOF){
00053             // We have a new line
00054             if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
00055             if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
00056             size_t begin_key = buffer.find_first_not_of(" \t");
00057             size_t begin_value = buffer.find_first_not_of(" \t", buffer.find_first_of(" \t", begin_key));
00058             // If this line matches the checksum
00059             string candidate = buffer.substr(begin_key,  buffer.find_first_of(" \t", begin_key) - begin_key);
00060             if( candidate.compare(setting) != 0 ){ buffer.clear(); continue; }
00061             int free_space = int(int(buffer.find_first_of("\r\n#", begin_value+1))-begin_value);
00062             if( int(value.length()) >= free_space ){
00063                 //THEKERNEL->streams->printf("ERROR: Not enough room for value\r\n");
00064                 fclose(lp);
00065                 return;
00066             }
00067             // Update value
00068             for( int i = value.length(); i < free_space; i++){ value += " "; }
00069             fpos_t pos;
00070             int position = fgetpos( lp, &pos );
00071             int start = position - buffer.length() + begin_value - 1;
00072             fseek(lp, start, SEEK_SET);
00073             fputs(value.c_str(), lp);
00074             fclose(lp);
00075             return;
00076         }else{
00077             buffer += c;
00078         }
00079     } while (c != EOF);
00080     fclose(lp);
00081     //THEKERNEL->streams->printf("ERROR: configuration key not found\r\n");
00082 }
00083 
00084 // Return the value for a specific checksum
00085 string FileConfigSource::read( uint16_t check_sums[3] ){
00086 
00087     string value = "";
00088 
00089     if( this->has_config_file() == false ){return value;}
00090     // Open the config file ( find it if we haven't already found it )
00091     FILE *lp = fopen(this->get_config_file().c_str(), "r");
00092     int c;
00093     // For each line
00094     do {
00095         c = fgetc (lp);
00096         process_char_from_ascii_config(c, check_sums);
00097     } while (c != EOF);
00098     fclose(lp);
00099 
00100     return value;
00101 }
00102 
00103 // Return wether or not we have a readable config file
00104 bool FileConfigSource::has_config_file(){
00105     if( this->config_file_found ){ return true; }
00106     this->try_config_file(this->config_file);
00107     if( this->config_file_found ){
00108         return true;
00109     }else{
00110         return false;
00111     }
00112 
00113 }
00114 
00115 // Tool function for get_config_file
00116 inline void FileConfigSource::try_config_file(string candidate){
00117     if(file_exists(candidate)){ this->config_file_found = true; }
00118 }
00119 
00120 // Get the filename for the config file
00121 string FileConfigSource::get_config_file(){
00122     if( this->config_file_found ){ return this->config_file; }
00123     if( this->has_config_file() ){
00124         return this->config_file;
00125     }else{
00126         printf("ERROR: no config file found\r\n");
00127         return "";
00128     }
00129 }
00130 
00131 
00132 
00133 
00134 
00135