smoothie port to mbed online compiler (smoothieware.org)

Dependencies:   mbed

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 using namespace std;
00013 #include <string>
00014 
00015 FileConfigSource::FileConfigSource(string config_file, uint16_t name_checksum){
00016     this->name_checksum = name_checksum;
00017     this->config_file = config_file;
00018     this->config_file_found = false;
00019 }
00020 
00021 // Transfer all values found in the file to the passed cache
00022 void FileConfigSource::transfer_values_to_cache( ConfigCache* cache ){
00023     // Default empty value
00024     ConfigValue* result = new ConfigValue;
00025     if( this->has_config_file() == false ){
00026         return;
00027     }
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     string buffer;
00031     int c; 
00032     // For each line 
00033     do {
00034         c = fgetc (lp);
00035         if (c == '\n' || c == EOF){
00036             // We have a new line
00037             if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
00038             if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
00039             size_t begin_key = buffer.find_first_not_of(" ");
00040             size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
00041             string key = buffer.substr(begin_key,  buffer.find_first_of(" ", begin_key) - begin_key).append(" ");
00042             vector<uint16_t> check_sums = get_checksums(key);
00043 
00044             result = new ConfigValue;
00045             result->found = true;
00046             result->check_sums = check_sums;
00047             result->value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
00048             
00049             // Append the newly found value to the cache we were passed 
00050             cache->replace_or_push_back(result);
00051             
00052             buffer.clear();
00053         }else{
00054             buffer += c;
00055         }
00056     } while (c != EOF);  
00057     fclose(lp);
00058 
00059 }
00060 
00061 // Return true if the check_sums match
00062 bool FileConfigSource::is_named( uint16_t check_sum ){
00063     return check_sum == this->name_checksum;
00064 }
00065 
00066 // Write a config setting to the file
00067 void FileConfigSource::write( string setting, string value ){
00068 /*
00069     // Open the config file ( find it if we haven't already found it )
00070     FILE *lp = fopen(this->get_config_file().c_str(), "r+");
00071     string buffer;
00072     int c;
00073     // For each line
00074     do {
00075         c = fgetc (lp);
00076         if (c == '\n' || c == EOF){
00077             // We have a new line
00078             if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
00079             if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
00080             size_t begin_key = buffer.find_first_not_of(" ");
00081             size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
00082             // If this line matches the checksum
00083             string candidate = buffer.substr(begin_key,  buffer.find_first_of(" ", begin_key) - begin_key);
00084             if( candidate.compare(setting) != 0 ){ buffer.clear(); continue; }
00085             int free_space = int(int(buffer.find_first_of("\r\n#", begin_value+1))-begin_value);
00086             if( int(value.length()) >= free_space ){
00087                 //this->kernel->serial->printf("ERROR: Not enough room for value\r\n");
00088                 fclose(lp);
00089                 return;
00090             }
00091             // Update value
00092             for( int i = value.length(); i < free_space; i++){ value += " "; }
00093             fpos_t pos;
00094             fgetpos( lp, &pos );
00095             int start = pos - buffer.length() + begin_value - 1;
00096             fseek(lp, start, SEEK_SET);
00097             fputs(value.c_str(), lp);
00098             fclose(lp);
00099             return;
00100         }else{
00101             buffer += c;
00102         }
00103     } while (c != EOF);
00104     fclose(lp);
00105     //this->kernel->serial->printf("ERROR: configuration key not found\r\n");
00106     */
00107 }
00108 
00109 // Return the value for a specific checksum
00110 string FileConfigSource::read( vector<uint16_t> check_sums ){
00111 
00112     string value = "";
00113 
00114     if( this->has_config_file() == false ){return value;}
00115     // Open the config file ( find it if we haven't already found it ) 
00116     FILE *lp = fopen(this->get_config_file().c_str(), "r");
00117     string buffer;
00118     int c; 
00119     // For each line 
00120     do {
00121         c = fgetc (lp);
00122         if (c == '\n' || c == EOF){
00123             // We have a new line
00124             if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
00125             if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
00126             size_t begin_key = buffer.find_first_not_of(" ");
00127             size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
00128             string key = buffer.substr(begin_key,  buffer.find_first_of(" ", begin_key) - begin_key).append(" ");
00129             vector<uint16_t> line_checksums = get_checksums(key);
00130 
00131             if(check_sums == line_checksums){
00132                 value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
00133                 break;
00134             }
00135             
00136             buffer.clear();
00137         }else{
00138             buffer += c;
00139         }
00140     } while (c != EOF);  
00141     fclose(lp);
00142 
00143     return value;
00144 }
00145 
00146 // Return wether or not we have a readable config file
00147 bool FileConfigSource::has_config_file(){
00148     if( this->config_file_found ){ return true; }
00149     this->try_config_file(this->config_file);
00150     if( this->config_file_found ){
00151         return true;
00152     }else{
00153         return false;
00154     }
00155 
00156 }
00157 
00158 // Tool function for get_config_file
00159 inline void FileConfigSource::try_config_file(string candidate){
00160     if(file_exists(candidate)){ 
00161         this->config_file_found = true; 
00162     }
00163 }
00164 
00165 // Get the filename for the config file
00166 string FileConfigSource::get_config_file(){
00167     if( this->config_file_found ){ return this->config_file; }
00168     if( this->has_config_file() ){
00169         return this->config_file;
00170     }else{
00171         printf("ERROR: no config file found\r\n");
00172     }
00173 }
00174 
00175 
00176 
00177