Fork of Smoothie to port to mbed non-LPC targets.
Fork of Smoothie by
libs/ConfigSources/FileConfigSource.cpp@0:31e91bb0ef3c, 2012-07-31 (annotated)
- 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?
User | Revision | Line number | New 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 |