Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Committer:
scachat
Date:
Tue Jul 31 21:11:18 2012 +0000
Revision:
0:31e91bb0ef3c
Child:
2:1df0b61d3b5a
smoothie port to mbed online compiler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
scachat 0:31e91bb0ef3c 1 /*
scachat 0:31e91bb0ef3c 2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
scachat 0:31e91bb0ef3c 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.
scachat 0:31e91bb0ef3c 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.
scachat 0:31e91bb0ef3c 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
scachat 0:31e91bb0ef3c 6 */
scachat 0:31e91bb0ef3c 7
scachat 0:31e91bb0ef3c 8 #include "libs/Kernel.h"
scachat 0:31e91bb0ef3c 9 #include "ConfigValue.h"
scachat 0:31e91bb0ef3c 10 #include "FileConfigSource.h"
scachat 0:31e91bb0ef3c 11 #include "ConfigCache.h"
scachat 0:31e91bb0ef3c 12 using namespace std;
scachat 0:31e91bb0ef3c 13 #include <string>
scachat 0:31e91bb0ef3c 14
scachat 0:31e91bb0ef3c 15 FileConfigSource::FileConfigSource(string config_file, uint16_t name_checksum){
scachat 0:31e91bb0ef3c 16 this->name_checksum = name_checksum;
scachat 0:31e91bb0ef3c 17 this->config_file = config_file;
scachat 0:31e91bb0ef3c 18 this->config_file_found = false;
scachat 0:31e91bb0ef3c 19 }
scachat 0:31e91bb0ef3c 20
scachat 0:31e91bb0ef3c 21 // Transfer all values found in the file to the passed cache
scachat 0:31e91bb0ef3c 22 void FileConfigSource::transfer_values_to_cache( ConfigCache* cache ){
scachat 0:31e91bb0ef3c 23 // Default empty value
scachat 0:31e91bb0ef3c 24 ConfigValue* result = new ConfigValue;
scachat 0:31e91bb0ef3c 25 if( this->has_config_file() == false ){
scachat 0:31e91bb0ef3c 26 return;
scachat 0:31e91bb0ef3c 27 }
scachat 0:31e91bb0ef3c 28 // Open the config file ( find it if we haven't already found it )
scachat 0:31e91bb0ef3c 29 FILE *lp = fopen(this->get_config_file().c_str(), "r");
scachat 0:31e91bb0ef3c 30 string buffer;
scachat 0:31e91bb0ef3c 31 int c;
scachat 0:31e91bb0ef3c 32 // For each line
scachat 0:31e91bb0ef3c 33 do {
scachat 0:31e91bb0ef3c 34 c = fgetc (lp);
scachat 0:31e91bb0ef3c 35 if (c == '\n' || c == EOF){
scachat 0:31e91bb0ef3c 36 // We have a new line
scachat 0:31e91bb0ef3c 37 if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
scachat 0:31e91bb0ef3c 38 if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
scachat 0:31e91bb0ef3c 39 size_t begin_key = buffer.find_first_not_of(" ");
scachat 0:31e91bb0ef3c 40 size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
scachat 0:31e91bb0ef3c 41 string key = buffer.substr(begin_key, buffer.find_first_of(" ", begin_key) - begin_key).append(" ");
scachat 0:31e91bb0ef3c 42 vector<uint16_t> check_sums = get_checksums(key);
scachat 0:31e91bb0ef3c 43
scachat 0:31e91bb0ef3c 44 result = new ConfigValue;
scachat 0:31e91bb0ef3c 45 result->found = true;
scachat 0:31e91bb0ef3c 46 result->check_sums = check_sums;
scachat 0:31e91bb0ef3c 47 result->value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
scachat 0:31e91bb0ef3c 48
scachat 0:31e91bb0ef3c 49 // Append the newly found value to the cache we were passed
scachat 0:31e91bb0ef3c 50 cache->replace_or_push_back(result);
scachat 0:31e91bb0ef3c 51
scachat 0:31e91bb0ef3c 52 buffer.clear();
scachat 0:31e91bb0ef3c 53 }else{
scachat 0:31e91bb0ef3c 54 buffer += c;
scachat 0:31e91bb0ef3c 55 }
scachat 0:31e91bb0ef3c 56 } while (c != EOF);
scachat 0:31e91bb0ef3c 57 fclose(lp);
scachat 0:31e91bb0ef3c 58
scachat 0:31e91bb0ef3c 59 }
scachat 0:31e91bb0ef3c 60
scachat 0:31e91bb0ef3c 61 // Return true if the check_sums match
scachat 0:31e91bb0ef3c 62 bool FileConfigSource::is_named( uint16_t check_sum ){
scachat 0:31e91bb0ef3c 63 return check_sum == this->name_checksum;
scachat 0:31e91bb0ef3c 64 }
scachat 0:31e91bb0ef3c 65
scachat 0:31e91bb0ef3c 66 // Write a config setting to the file
scachat 0:31e91bb0ef3c 67 void FileConfigSource::write( string setting, string value ){
scachat 0:31e91bb0ef3c 68 /*
scachat 0:31e91bb0ef3c 69 // Open the config file ( find it if we haven't already found it )
scachat 0:31e91bb0ef3c 70 FILE *lp = fopen(this->get_config_file().c_str(), "r+");
scachat 0:31e91bb0ef3c 71 string buffer;
scachat 0:31e91bb0ef3c 72 int c;
scachat 0:31e91bb0ef3c 73 // For each line
scachat 0:31e91bb0ef3c 74 do {
scachat 0:31e91bb0ef3c 75 c = fgetc (lp);
scachat 0:31e91bb0ef3c 76 if (c == '\n' || c == EOF){
scachat 0:31e91bb0ef3c 77 // We have a new line
scachat 0:31e91bb0ef3c 78 if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
scachat 0:31e91bb0ef3c 79 if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
scachat 0:31e91bb0ef3c 80 size_t begin_key = buffer.find_first_not_of(" ");
scachat 0:31e91bb0ef3c 81 size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
scachat 0:31e91bb0ef3c 82 // If this line matches the checksum
scachat 0:31e91bb0ef3c 83 string candidate = buffer.substr(begin_key, buffer.find_first_of(" ", begin_key) - begin_key);
scachat 0:31e91bb0ef3c 84 if( candidate.compare(setting) != 0 ){ buffer.clear(); continue; }
scachat 0:31e91bb0ef3c 85 int free_space = int(int(buffer.find_first_of("\r\n#", begin_value+1))-begin_value);
scachat 0:31e91bb0ef3c 86 if( int(value.length()) >= free_space ){
scachat 0:31e91bb0ef3c 87 //this->kernel->serial->printf("ERROR: Not enough room for value\r\n");
scachat 0:31e91bb0ef3c 88 fclose(lp);
scachat 0:31e91bb0ef3c 89 return;
scachat 0:31e91bb0ef3c 90 }
scachat 0:31e91bb0ef3c 91 // Update value
scachat 0:31e91bb0ef3c 92 for( int i = value.length(); i < free_space; i++){ value += " "; }
scachat 0:31e91bb0ef3c 93 fpos_t pos;
scachat 0:31e91bb0ef3c 94 fgetpos( lp, &pos );
scachat 0:31e91bb0ef3c 95 int start = pos - buffer.length() + begin_value - 1;
scachat 0:31e91bb0ef3c 96 fseek(lp, start, SEEK_SET);
scachat 0:31e91bb0ef3c 97 fputs(value.c_str(), lp);
scachat 0:31e91bb0ef3c 98 fclose(lp);
scachat 0:31e91bb0ef3c 99 return;
scachat 0:31e91bb0ef3c 100 }else{
scachat 0:31e91bb0ef3c 101 buffer += c;
scachat 0:31e91bb0ef3c 102 }
scachat 0:31e91bb0ef3c 103 } while (c != EOF);
scachat 0:31e91bb0ef3c 104 fclose(lp);
scachat 0:31e91bb0ef3c 105 //this->kernel->serial->printf("ERROR: configuration key not found\r\n");
scachat 0:31e91bb0ef3c 106 */
scachat 0:31e91bb0ef3c 107 }
scachat 0:31e91bb0ef3c 108
scachat 0:31e91bb0ef3c 109 // Return the value for a specific checksum
scachat 0:31e91bb0ef3c 110 string FileConfigSource::read( vector<uint16_t> check_sums ){
scachat 0:31e91bb0ef3c 111
scachat 0:31e91bb0ef3c 112 string value = "";
scachat 0:31e91bb0ef3c 113
scachat 0:31e91bb0ef3c 114 if( this->has_config_file() == false ){return value;}
scachat 0:31e91bb0ef3c 115 // Open the config file ( find it if we haven't already found it )
scachat 0:31e91bb0ef3c 116 FILE *lp = fopen(this->get_config_file().c_str(), "r");
scachat 0:31e91bb0ef3c 117 string buffer;
scachat 0:31e91bb0ef3c 118 int c;
scachat 0:31e91bb0ef3c 119 // For each line
scachat 0:31e91bb0ef3c 120 do {
scachat 0:31e91bb0ef3c 121 c = fgetc (lp);
scachat 0:31e91bb0ef3c 122 if (c == '\n' || c == EOF){
scachat 0:31e91bb0ef3c 123 // We have a new line
scachat 0:31e91bb0ef3c 124 if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments
scachat 0:31e91bb0ef3c 125 if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines
scachat 0:31e91bb0ef3c 126 size_t begin_key = buffer.find_first_not_of(" ");
scachat 0:31e91bb0ef3c 127 size_t begin_value = buffer.find_first_not_of(" ", buffer.find_first_of(" ", begin_key));
scachat 0:31e91bb0ef3c 128 string key = buffer.substr(begin_key, buffer.find_first_of(" ", begin_key) - begin_key).append(" ");
scachat 0:31e91bb0ef3c 129 vector<uint16_t> line_checksums = get_checksums(key);
scachat 0:31e91bb0ef3c 130
scachat 0:31e91bb0ef3c 131 if(check_sums == line_checksums){
scachat 0:31e91bb0ef3c 132 value = buffer.substr(begin_value, buffer.find_first_of("\r\n# ", begin_value+1)-begin_value);
scachat 0:31e91bb0ef3c 133 break;
scachat 0:31e91bb0ef3c 134 }
scachat 0:31e91bb0ef3c 135
scachat 0:31e91bb0ef3c 136 buffer.clear();
scachat 0:31e91bb0ef3c 137 }else{
scachat 0:31e91bb0ef3c 138 buffer += c;
scachat 0:31e91bb0ef3c 139 }
scachat 0:31e91bb0ef3c 140 } while (c != EOF);
scachat 0:31e91bb0ef3c 141 fclose(lp);
scachat 0:31e91bb0ef3c 142
scachat 0:31e91bb0ef3c 143 return value;
scachat 0:31e91bb0ef3c 144 }
scachat 0:31e91bb0ef3c 145
scachat 0:31e91bb0ef3c 146 // Return wether or not we have a readable config file
scachat 0:31e91bb0ef3c 147 bool FileConfigSource::has_config_file(){
scachat 0:31e91bb0ef3c 148 if( this->config_file_found ){ return true; }
scachat 0:31e91bb0ef3c 149 this->try_config_file(this->config_file);
scachat 0:31e91bb0ef3c 150 if( this->config_file_found ){
scachat 0:31e91bb0ef3c 151 return true;
scachat 0:31e91bb0ef3c 152 }else{
scachat 0:31e91bb0ef3c 153 return false;
scachat 0:31e91bb0ef3c 154 }
scachat 0:31e91bb0ef3c 155
scachat 0:31e91bb0ef3c 156 }
scachat 0:31e91bb0ef3c 157
scachat 0:31e91bb0ef3c 158 // Tool function for get_config_file
scachat 0:31e91bb0ef3c 159 inline void FileConfigSource::try_config_file(string candidate){
scachat 0:31e91bb0ef3c 160 if(file_exists(candidate)){
scachat 0:31e91bb0ef3c 161 this->config_file_found = true;
scachat 0:31e91bb0ef3c 162 }
scachat 0:31e91bb0ef3c 163 }
scachat 0:31e91bb0ef3c 164
scachat 0:31e91bb0ef3c 165 // Get the filename for the config file
scachat 0:31e91bb0ef3c 166 string FileConfigSource::get_config_file(){
scachat 0:31e91bb0ef3c 167 if( this->config_file_found ){ return this->config_file; }
scachat 0:31e91bb0ef3c 168 if( this->has_config_file() ){
scachat 0:31e91bb0ef3c 169 return this->config_file;
scachat 0:31e91bb0ef3c 170 }else{
scachat 0:31e91bb0ef3c 171 printf("ERROR: no config file found\r\n");
scachat 0:31e91bb0ef3c 172 }
scachat 0:31e91bb0ef3c 173 }
scachat 0:31e91bb0ef3c 174
scachat 0:31e91bb0ef3c 175
scachat 0:31e91bb0ef3c 176
scachat 0:31e91bb0ef3c 177