Stéphane Cachat
/
Smoothie
smoothie port to mbed online compiler (smoothieware.org)
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 14:14:40 by 1.7.2