Commit | Line | Data |
---|---|---|
7b49793d | 1 | /* |
c295905f AW |
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. | |
7b49793d | 5 | You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>. |
c295905f AW |
6 | */ |
7 | ||
8 | #include "libs/Kernel.h" | |
9 | #include "ConfigValue.h" | |
10 | #include "FileConfigSource.h" | |
11 | #include "ConfigCache.h" | |
a39e1557 AW |
12 | #include <malloc.h> |
13 | ||
c295905f AW |
14 | |
15 | using namespace std; | |
16 | #include <string> | |
17 | ||
18 | ||
32891c60 L |
19 | FileConfigSource::FileConfigSource(string config_file, uint16_t name_checksum){ |
20 | this->name_checksum = name_checksum; | |
8d857d2e | 21 | this->config_file = config_file; |
c295905f AW |
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 ){ | |
7b49793d | 27 | |
c295905f | 28 | if( this->has_config_file() == false ){return;} |
7b49793d | 29 | // Open the config file ( find it if we haven't already found it ) |
c295905f | 30 | FILE *lp = fopen(this->get_config_file().c_str(), "r"); |
7b49793d MM |
31 | int c; |
32 | // For each line | |
c295905f | 33 | do { |
2b56b363 | 34 | process_char_from_ascii_config(c = fgetc(lp), cache); |
7b49793d | 35 | } while (c != EOF); |
c295905f | 36 | fclose(lp); |
c295905f AW |
37 | } |
38 | ||
5913c006 | 39 | // Return true if the check_sums match |
5efaa1b1 L |
40 | bool FileConfigSource::is_named( uint16_t check_sum ){ |
41 | return check_sum == this->name_checksum; | |
42 | } | |
43 | ||
5913c006 L |
44 | // Write a config setting to the file |
45 | void FileConfigSource::write( string setting, string value ){ | |
46 | // Open the config file ( find it if we haven't already found it ) | |
47 | FILE *lp = fopen(this->get_config_file().c_str(), "r+"); | |
48 | string buffer; | |
49 | int c; | |
50 | // For each line | |
51 | do { | |
52 | c = fgetc (lp); | |
53 | if (c == '\n' || c == EOF){ | |
54 | // We have a new line | |
55 | if( buffer[0] == '#' ){ buffer.clear(); continue; } // Ignore comments | |
56 | if( buffer.length() < 3 ){ buffer.clear(); continue; } //Ignore empty lines | |
240bd6f2 L |
57 | size_t begin_key = buffer.find_first_not_of(" \t"); |
58 | size_t begin_value = buffer.find_first_not_of(" \t", buffer.find_first_of(" \t", begin_key)); | |
5913c006 | 59 | // If this line matches the checksum |
240bd6f2 | 60 | string candidate = buffer.substr(begin_key, buffer.find_first_of(" \t", begin_key) - begin_key); |
5913c006 L |
61 | if( candidate.compare(setting) != 0 ){ buffer.clear(); continue; } |
62 | int free_space = int(int(buffer.find_first_of("\r\n#", begin_value+1))-begin_value); | |
63 | if( int(value.length()) >= free_space ){ | |
314ab8f7 | 64 | //THEKERNEL->streams->printf("ERROR: Not enough room for value\r\n"); |
5913c006 L |
65 | fclose(lp); |
66 | return; | |
67 | } | |
68 | // Update value | |
69 | for( int i = value.length(); i < free_space; i++){ value += " "; } | |
70 | fpos_t pos; | |
71 | fgetpos( lp, &pos ); | |
72 | int start = pos - buffer.length() + begin_value - 1; | |
73 | fseek(lp, start, SEEK_SET); | |
74 | fputs(value.c_str(), lp); | |
75 | fclose(lp); | |
76 | return; | |
77 | }else{ | |
78 | buffer += c; | |
79 | } | |
80 | } while (c != EOF); | |
81 | fclose(lp); | |
314ab8f7 | 82 | //THEKERNEL->streams->printf("ERROR: configuration key not found\r\n"); |
5913c006 | 83 | } |
5efaa1b1 | 84 | |
5761c645 | 85 | // Return the value for a specific checksum |
4464301d | 86 | string FileConfigSource::read( uint16_t check_sums[3] ){ |
5761c645 L |
87 | |
88 | string value = ""; | |
89 | ||
90 | if( this->has_config_file() == false ){return value;} | |
7b49793d | 91 | // Open the config file ( find it if we haven't already found it ) |
5761c645 | 92 | FILE *lp = fopen(this->get_config_file().c_str(), "r"); |
7b49793d MM |
93 | int c; |
94 | // For each line | |
5761c645 L |
95 | do { |
96 | c = fgetc (lp); | |
2b56b363 | 97 | process_char_from_ascii_config(c, check_sums); |
7b49793d | 98 | } while (c != EOF); |
5761c645 L |
99 | fclose(lp); |
100 | ||
101 | return value; | |
102 | } | |
5efaa1b1 | 103 | |
c295905f AW |
104 | // Return wether or not we have a readable config file |
105 | bool FileConfigSource::has_config_file(){ | |
106 | if( this->config_file_found ){ return true; } | |
8d857d2e | 107 | this->try_config_file(this->config_file); |
c295905f AW |
108 | if( this->config_file_found ){ |
109 | return true; | |
110 | }else{ | |
111 | return false; | |
112 | } | |
113 | ||
114 | } | |
115 | ||
116 | // Tool function for get_config_file | |
117 | inline void FileConfigSource::try_config_file(string candidate){ | |
8d857d2e | 118 | if(file_exists(candidate)){ this->config_file_found = true; } |
c295905f AW |
119 | } |
120 | ||
121 | // Get the filename for the config file | |
122 | string FileConfigSource::get_config_file(){ | |
123 | if( this->config_file_found ){ return this->config_file; } | |
124 | if( this->has_config_file() ){ | |
125 | return this->config_file; | |
126 | }else{ | |
127 | printf("ERROR: no config file found\r\n"); | |
69735c09 | 128 | return ""; |
c295905f AW |
129 | } |
130 | } | |
131 | ||
132 | ||
133 | ||
134 | ||
135 | ||
136 |