Use static kernel singleton pointer instead of per-class instance pointer
[clinton/Smoothieware.git] / src / libs / ConfigSources / FileConfigSource.cpp
CommitLineData
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
15using namespace std;
16#include <string>
17
18
32891c60
L
19FileConfigSource::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
26void 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
40bool 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
45void 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 86string 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
105bool 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
117inline 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
122string 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