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