Line data Source code
1 : /*
2 : * License:
3 : * Copyright (c) 2006-2019 Made to Order Software Corp. All Rights Reserved
4 : *
5 : * https://snapwebsites.org/
6 : * contact@m2osw.com
7 : *
8 : * This program is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU General Public License as published by
10 : * the Free Software Foundation; either version 2 of the License, or
11 : * (at your option) any later version.
12 : *
13 : * This program is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU General Public License along
19 : * with this program; if not, write to the Free Software Foundation, Inc.,
20 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 : *
22 : * Authors:
23 : * Alexis Wilke alexis@m2osw.com
24 : * Doug Barbieri doug@m2osw.com
25 : */
26 : #pragma once
27 :
28 : /** \file
29 : * \brief Declaration of the conf_file class used to read a configuration file.
30 : *
31 : * The library offers a way to read a configuration file parameters without
32 : * doing anything more than that. The getopt class uses it to read and verify
33 : * the parameters. It also uses it to read files of configuration options.
34 : */
35 :
36 : // C++ lib
37 : //
38 : #include <fstream>
39 : #include <functional>
40 : #include <map>
41 : #include <memory>
42 : #include <set>
43 :
44 :
45 :
46 : namespace advgetopt
47 : {
48 :
49 :
50 :
51 : enum class callback_action_t
52 : {
53 : created,
54 : updated,
55 : erased
56 : };
57 :
58 :
59 : enum class line_continuation_t
60 : {
61 : line_continuation_single_line, // no continuation support
62 : line_continuation_rfc_822, // like email/HTTP, whitespace at start of next line
63 : line_continuation_msdos, // '&' at end of line
64 : line_continuation_unix, // '\' at end of line
65 : line_continuation_fortran, // '&' at start of next line
66 : line_continuation_semicolon // ';' ends the _line_
67 : };
68 :
69 :
70 : typedef std::uint_fast16_t assignment_operator_t;
71 :
72 : constexpr assignment_operator_t ASSIGNMENT_OPERATOR_EQUAL = 0x0001; // a = b
73 : constexpr assignment_operator_t ASSIGNMENT_OPERATOR_COLON = 0x0002; // a: b
74 : constexpr assignment_operator_t ASSIGNMENT_OPERATOR_SPACE = 0x0004; // a b
75 :
76 : constexpr assignment_operator_t ASSIGNMENT_OPERATOR_MASK = 0x0007;
77 :
78 :
79 : typedef std::uint_fast16_t comment_t;
80 :
81 : constexpr comment_t COMMENT_NONE = 0x0000; // no support for comments
82 : constexpr comment_t COMMENT_INI = 0x0001; // ; comment
83 : constexpr comment_t COMMENT_SHELL = 0x0002; // # comment
84 : constexpr comment_t COMMENT_CPP = 0x0004; // // comment
85 :
86 : constexpr comment_t COMMENT_MASK = 0x0007;
87 :
88 :
89 : typedef std::uint_fast16_t section_operator_t;
90 :
91 : constexpr section_operator_t SECTION_OPERATOR_NONE = 0x0000; // no support
92 : constexpr section_operator_t SECTION_OPERATOR_C = 0x0001; // a.b
93 : constexpr section_operator_t SECTION_OPERATOR_CPP = 0x0002; // a::b
94 : constexpr section_operator_t SECTION_OPERATOR_BLOCK = 0x0004; // a { ... }
95 : constexpr section_operator_t SECTION_OPERATOR_INI_FILE = 0x0008; // [a]
96 :
97 : constexpr section_operator_t SECTION_OPERATOR_ONE_SECTION = 0x8000; // accept at most 1 section
98 :
99 : constexpr section_operator_t SECTION_OPERATOR_MASK = 0x000F;
100 :
101 :
102 28659 : class conf_file_setup
103 : {
104 : public:
105 : conf_file_setup(
106 : std::string const & filename
107 : , line_continuation_t line_continuation = line_continuation_t::line_continuation_unix
108 : , assignment_operator_t assignment_operator = ASSIGNMENT_OPERATOR_EQUAL
109 : , comment_t comment = COMMENT_INI | COMMENT_SHELL
110 : , section_operator_t section_operator = SECTION_OPERATOR_INI_FILE);
111 :
112 : bool is_valid() const;
113 : std::string const & get_filename() const;
114 : line_continuation_t get_line_continuation() const;
115 : assignment_operator_t get_assignment_operator() const;
116 : comment_t get_comment() const;
117 : section_operator_t get_section_operator() const;
118 : std::string get_config_url() const;
119 :
120 : private:
121 : std::string f_filename = std::string();
122 : line_continuation_t f_line_continuation = line_continuation_t::line_continuation_unix;
123 : assignment_operator_t f_assignment_operator = ASSIGNMENT_OPERATOR_EQUAL;
124 : comment_t f_comment = COMMENT_INI | COMMENT_SHELL;
125 : section_operator_t f_section_operator = SECTION_OPERATOR_INI_FILE;
126 : mutable std::string f_url = std::string();
127 : };
128 :
129 :
130 177 : class conf_file
131 : : public std::enable_shared_from_this<conf_file>
132 : {
133 : public:
134 : typedef std::shared_ptr<conf_file> pointer_t;
135 : typedef std::set<std::string> sections_t;
136 : typedef std::map<std::string, std::string> parameters_t;
137 : typedef std::function<void(pointer_t conf_file, callback_action_t action, std::string const & variable_name, std::string const & value)>
138 : callback_t;
139 :
140 : static conf_file::pointer_t get_conf_file(conf_file_setup const & setup);
141 :
142 : bool save_configuration(bool create_backup = true);
143 :
144 : conf_file_setup const & get_setup() const;
145 : void set_callback(callback_t callback);
146 :
147 : int get_errno() const;
148 :
149 : sections_t get_sections() const;
150 : parameters_t get_parameters() const;
151 : bool has_parameter(std::string name) const;
152 : std::string get_parameter(std::string name) const;
153 : bool set_parameter(std::string section, std::string name, std::string const & value);
154 : bool erase_parameter(std::string name);
155 : bool was_modified() const;
156 :
157 : bool is_assignment_operator(int c) const;
158 : bool is_comment(char const * s) const;
159 :
160 : private:
161 : conf_file(conf_file_setup const & setup);
162 :
163 : int getc(std::ifstream & stream);
164 : void ungetc(int c);
165 : bool get_line(std::ifstream & stream, std::string & line);
166 : void read_configuration();
167 :
168 : conf_file_setup const f_setup;
169 :
170 : int f_unget_char = '\0';
171 : int f_line = 0;
172 : int f_errno = 0;
173 : bool f_reading = false;
174 :
175 : bool f_modified = false;
176 : sections_t f_sections = sections_t();
177 : parameters_t f_parameters = parameters_t();
178 : callback_t f_callback = callback_t();
179 : };
180 :
181 :
182 : bool iswspace(int c);
183 :
184 :
185 : } // namespace advgetopt
186 : // vim: ts=4 sw=4 et
|