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