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