1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 Red Hat, Inc.
5 //
6 // Author: Dodji Seketeli
7 
8 /// @file
9 ///
10 /// This file contains the declarations for the ini file reader used in
11 /// the libabigail library.
12 
13 #ifndef __ABG_INI_H__
14 #define __ABG_INI_H__
15 
16 #include <istream>
17 #include <memory>
18 #include <ostream>
19 #include <string>
20 #include <vector>
21 
22 namespace abigail
23 {
24 /// Namespace for handling ini-style files
25 namespace ini
26 {
27 // Inject some standard types in this namespace.
28 using std::shared_ptr;
29 using std::dynamic_pointer_cast;
30 using std::string;
31 using std::vector;
32 using std:: pair;
33 
34 class property;
35 /// Convenience typefef for shared_ptr to @ref property.
36 typedef shared_ptr<property> property_sptr;
37 
38 /// The base class of the different kinds of properties of an INI
39 /// file.
40 class property
41 {
42   struct priv;
43   typedef shared_ptr<priv> priv_sptr;
44   priv_sptr priv_;
45 
46 public:
47 
48   property();
49 
50   property(const string& name);
51 
52   const string&
53   get_name() const;
54 
55   void
56   set_name(const string& name);
57 
58   virtual ~property();
59 }; // end class property
60 
61 class property_value;
62 
63 /// Convenience typedef for a shared_ptr to @ref property_value.
64 typedef shared_ptr<property_value> property_value_sptr;
65 
66 /// Base class of propertie values.
67 class property_value
68 {
69 public:
70   enum value_kind
71   {
72     ABSTRACT_PROPERTY_VALUE = 0,
73     STRING_PROPERTY_VALUE = 1,
74     LIST_PROPERTY_VALUE = 2,
75     TUPLE_PROPERTY_VALUE = 3,
76   };
77 
78 private:
79   struct priv;
80   typedef shared_ptr<priv> priv_sptr;
81   priv_sptr priv_;
82 
83 public:
84 
85   property_value();
86   property_value(value_kind);
87 
88   value_kind
89   get_kind() const;
90 
91   virtual const string&
92   as_string() const = 0;
93 
94   operator const string& () const;
95 
96   virtual ~property_value();
97 }; // end class property_value.
98 
99 class string_property_value;
100 
101 /// A convenience typedef for a shared_ptr to @ref string_property_value.
102 typedef shared_ptr<string_property_value> string_property_value_sptr;
103 
104 /// A property value which is a string.
105 class string_property_value : public property_value
106 {
107   struct priv;
108   typedef shared_ptr<priv> priv_sptr;
109   priv_sptr priv_;
110 
111 public:
112   string_property_value();
113   string_property_value(const string& value);
114 
115   void
116   set_content(const string&);
117 
118   virtual const string&
119   as_string() const;
120 
121   operator string() const;
122 
123   virtual ~string_property_value();
124 }; // end class string_property_value
125 
126 string_property_value*
127 is_string_property_value(const property_value*);
128 
129 string_property_value_sptr
130 is_string_property_value(const property_value_sptr);
131 
132 class list_property_value;
133 
134 /// A convenience typedef for a shared_ptr to @ref
135 /// list_property_value.
136 typedef shared_ptr<list_property_value> list_property_value_sptr;
137 
138 /// Abstracts the value of a property representing a list of strings.
139 ///
140 /// It's the right hand side of the construct which syntax looks like:
141 ///
142 ///   name = val1, val2, val3
143 ///
144 /// where val1, val2 and val3 are strings.
145 ///
146 /// So this class abstracts the set [val1, val2, val3].
147 class list_property_value : public property_value
148 {
149   struct priv;
150   typedef shared_ptr<priv> priv_sptr;
151 
152   priv_sptr priv_;
153 
154 public:
155   list_property_value();
156   list_property_value(const vector<string>& values);
157 
158   const vector<string>&
159   get_content() const;
160 
161   void
162   set_content(const vector<string>&);
163 
164   virtual const string&
165   as_string() const;
166 }; // end class list_property_value
167 
168 list_property_value*
169 is_list_property_value(const property_value*);
170 
171 list_property_value_sptr
172 is_list_property_value(const property_value_sptr&);
173 
174 class tuple_property_value;
175 
176 /// Convenience typedef for a shared_ptr to a @ref
177 /// tuple_property_value.
178 typedef shared_ptr<tuple_property_value> tuple_property_value_sptr;
179 
180 /// A property value that is a tuple.
181 ///
182 /// Each element of the tuple is itself a property value that can
183 /// either be a string, or another tuple, for instance.
184 class tuple_property_value : public property_value
185 {
186   struct priv;
187   typedef shared_ptr<priv> priv_sptr;
188   priv_sptr priv_;
189 
190 public:
191   tuple_property_value(const vector<property_value_sptr>&);
192 
193   const vector<property_value_sptr>&
194   get_value_items() const;
195 
196   vector<property_value_sptr>&
197   get_value_items();
198 
199   virtual const string&
200   as_string() const;
201 
202   operator string() const;
203 
204   virtual ~tuple_property_value();
205 }; // end class tuple_property_value
206 
207 tuple_property_value*
208 is_tuple_property_value(const property_value*);
209 
210 tuple_property_value_sptr
211 is_tuple_property_value(const property_value_sptr);
212 
213 class simple_property;
214 /// Convenience typedef for a shared_ptr to an @ref simple_property.
215 typedef shared_ptr<simple_property> simple_property_sptr;
216 
217 /// A simple property.  That is, one which value is a
218 /// @ref string_property_value.
219 class simple_property : public property
220 {
221   struct priv;
222   typedef shared_ptr<priv> priv_sptr;
223 
224   priv_sptr priv_;
225 
226 public:
227   simple_property();
228 
229   simple_property(const string& name,
230 		  const string_property_value_sptr& value);
231 
232   simple_property(const string& name);
233 
234   const string_property_value_sptr&
235   get_value() const;
236 
237   void
238   set_value(const string_property_value_sptr& value);
239 
240   bool
241   has_empty_value() const;
242 
243   virtual ~simple_property();
244 }; // end class simple_property
245 
246 simple_property*
247 is_simple_property(const property* p);
248 
249 simple_property_sptr
250 is_simple_property(const property_sptr p);
251 
252 class list_property;
253 
254 /// A convenience typedef for a shared_ptr to a @ref list_property.
255 typedef shared_ptr<list_property> list_property_sptr;
256 
257 /// A class representing a list property.
258 ///
259 /// It abstracts a construct which syntax looks like:
260 ///
261 ///    name = val1, val2, val3
262 ///
263 /// The value of a list property is a @ref list_property_value, i.e, a
264 /// list of strings.
265 class list_property : public property
266 {
267   struct priv;
268   typedef shared_ptr<priv> priv_sptr;
269 
270   priv_sptr priv_;
271 
272 public:
273   list_property();
274 
275   list_property(const string& name,
276 		const list_property_value_sptr& value);
277 
278   const list_property_value_sptr&
279   get_value() const;
280 
281   void
282   set_value(const list_property_value_sptr& value);
283 
284   virtual ~list_property();
285 }; // end class list_property
286 
287 list_property*
288 is_list_property(const property* p);
289 
290 list_property_sptr
291 is_list_property(const property_sptr p);
292 
293 class tuple_property;
294 /// Convenience typedef for a shared_ptr of @ref tuple_property.
295 typedef shared_ptr<tuple_property> tuple_property_sptr;
296 
297 /// Abstraction of a tuple property.  A tuple property is a property
298 /// which value is a @ref tuple_property_value.
299 class tuple_property : public property
300 {
301   struct priv;
302   typedef shared_ptr<priv> priv_sptr;
303 
304   priv_sptr priv_;
305 
306 public:
307   tuple_property();
308 
309   tuple_property(const string& name,
310 		 const tuple_property_value_sptr v);
311 
312   void
313   set_value(const tuple_property_value_sptr value);
314 
315   const tuple_property_value_sptr&
316   get_value() const;
317 
318   virtual
319   ~tuple_property();
320 }; // end class tuple_property
321 
322 tuple_property*
323 is_tuple_property(const property* p);
324 
325 tuple_property_sptr
326 is_tuple_property(const property_sptr p);
327 
328 class config;
329 
330 /// A convenience typedef for a shared pointer to @ref config
331 typedef shared_ptr<config> config_sptr;
332 
333 /// The abstraction of the structured content of an .ini file.  This
334 /// roughly follows what is explained at
335 /// http://en.wikipedia.org/wiki/INI_file.
336 class config
337 {
338   class priv;
339   typedef shared_ptr<priv> priv_sptr;
340 
341 public:
342   class section;
343   /// A convenience typedef for a shared pointer to a config::section.
344   typedef shared_ptr<section> section_sptr;
345 
346   /// A convenience typedef for a vector of config::section_sptr.
347   typedef vector<section_sptr> sections_type;
348 
349   /// A convenience typedef for a vector of @ref property_sptr
350   typedef vector<property_sptr> properties_type;
351 
352 private:
353   priv_sptr priv_;
354 
355 public:
356 
357   config();
358 
359   config(const string& path,
360 	 sections_type& sections);
361 
362   virtual ~config();
363 
364   const string&
365   get_path() const;
366 
367   void
368   set_path(const string& path);
369 
370   const sections_type&
371   get_sections() const;
372 
373   void
374   set_sections(const sections_type& sections);
375 }; // end class config
376 
377 /// The abstraction of one section of the .ini config.
378 class config::section
379 {
380   class priv;
381   typedef shared_ptr<priv> priv_sptr;
382 
383   priv_sptr priv_;
384 
385   // Forbid this
386   section();
387 
388 public:
389   section(const string& name);
390 
391   section(const string& name, const properties_type& properties);
392 
393   const string&
394   get_name() const;
395 
396   const properties_type&
397   get_properties() const;
398 
399   void
400   set_properties(const properties_type& properties);
401 
402   void
403   add_property(const property_sptr prop);
404 
405   property_sptr
406   find_property(const string& prop_name) const;
407 
408   virtual ~section();
409 }; //end class config::section
410 
411 bool
412 read_sections(std::istream& input,
413 	      config::sections_type& sections);
414 
415 bool
416 read_sections(const string& path,
417 	      config::sections_type& sections);
418 
419 bool
420 read_config(std::istream& input,
421 	    config& conf);
422 
423 config_sptr
424 read_config(std::istream& input);
425 
426 bool
427 read_config(const string& path,
428 	    config& conf);
429 
430 config_sptr
431 read_config(const string& path);
432 
433 bool
434 write_sections(const config::sections_type& sections,
435 	       std::ostream& output);
436 
437 bool
438 write_sections(const config::sections_type& sections,
439 	       const string& path);
440 
441 bool
442 write_config(const config& conf,
443 	     std::ostream& output);
444 
445 bool
446 write_config(const config& conf,
447 	     const string& path);
448 
449 class function_call_expr;
450 
451 /// Convenience typedef for a shared pointer to function_call_expr
452 typedef shared_ptr<function_call_expr> function_call_expr_sptr;
453 
454 /// The abstraction of a function call expression.
455 class function_call_expr
456 {
457   struct priv;
458   typedef shared_ptr<priv> priv_sptr;
459   priv_sptr priv_;
460 
461   function_call_expr();
462 
463 public:
464   function_call_expr(const string& name,
465 		     const vector<string>& args);
466 
467   const string&
468   get_name() const;
469 
470   const vector<string>&
471   get_arguments() const;
472 
473   vector<string>&
474   get_arguments();
475 }; //end function_call_expr
476 
477 bool
478 read_function_call_expr(std::istream& input,
479 			function_call_expr_sptr& expr);
480 
481 bool
482 read_function_call_expr(const string& input,
483 			function_call_expr_sptr& expr);
484 
485 function_call_expr_sptr
486 read_function_call_expr(const string& input);
487 }// end namespace ini
488 }// end namespace abigail
489 #endif // __ABG_INI_H__
490