libabigail
abg-ini.cc
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2// -*- Mode: C++ -*-
3//
4// Copyright (C) 2013-2025 Red Hat, Inc.
5//
6// Author: Dodji Seketeli
7
8/// @file
9///
10/// This file contains the definitions for the ini file reader used in
11/// the libabigail library.
12
13#include <cassert>
14#include <cstdlib>
15#include <utility>
16#include <memory>
17#include <fstream>
18#include <sstream>
19
20#include "abg-fwd.h"
21#include "abg-internal.h"
22// <headers defining libabigail's API go under here>
23ABG_BEGIN_EXPORT_DECLARATIONS
24
25#include "abg-ini.h"
26
27ABG_END_EXPORT_DECLARATIONS
28// </headers defining libabigail's API>
29
30namespace abigail
31{
32namespace ini
33{
34
35using std::istream;
36using std::pair;
37
38static bool
39char_is_white_space(int b);
40
41static bool
42char_is_comment_start(int b);
43
44/// Test if a given character is a delimiter.
45///
46///
47///@param b the value of the character to test for.
48///
49///@param include_white_space if true, consider white spaces as a
50///delimiter.
51///
52///@param include_square_bracket if true, consider square brackets as
53/// delimiters
54///
55/// @param include_equal if true, consider the equal character ('=')
56/// as a delimiter.
57///
58/// @return true iff @p b is a delimiter.
59static bool
60char_is_delimiter(int b, bool include_white_space = true,
61 bool include_square_bracket = true,
62 bool include_equal = true)
63{
64 return ((include_square_bracket && (b == '['))
65 || (include_square_bracket && (b == ']'))
66 || b == '{'
67 || b == '}'
68 || (include_equal && (b == '='))
69 || b == ','
70 || (include_white_space && char_is_white_space(b))
71 || char_is_comment_start(b));
72}
73
74/// Return true iff a given character can be part of a property
75/// value.
76///
77/// Note that white spaces, square brackets and the equal character can be
78/// part of a property value. The reason why we accept the equal
79/// character is because it can appear in an URL.
80///
81/// @param b the character to test against.
82///
83/// @return true iff @p b is a character that can be part of a
84/// property value.
85static bool
86char_is_property_value_char(int b)
87{
88 if (char_is_delimiter(b, /*include_white_space=*/false,
89 /*include_square_bracket=*/false,
90 /*include_equal=*/false)
91 || b == '\n')
92 return false;
93 return true;
94}
95
96/// Test if a given character is meant to be part of a section name.
97///
98/// @param b the character to test against.
99///
100/// @return true iff @p b is a character that is meant to be part of
101/// a section name.
102static bool
103char_is_section_name_char(int b)
104{
105 if (b == '[' || b == ']' || b == '\n' || char_is_comment_start(b))
106 return false;
107 return true;
108}
109
110/// Test if a given character is meant to be part of a property name.
111///
112/// @param b the character to test against.
113///
114/// @return true iff @p b is a character that is meant to be part of
115/// a section name.
116static bool
117char_is_property_name_char(int b)
118{
119 if (char_is_delimiter(b))
120 return false;
121 return true;
122}
123
124/// Test if a given character is meant to be part of a function name.
125///
126/// @param b the character to test against.
127///
128/// @return true iff @p b is a character that is meant to be part of a
129/// function name.
130static bool
131char_is_function_name_char(int b)
132{
133 if (char_is_delimiter(b) || b == '(' || b == ')')
134 return false;
135 return true;
136}
137
138/// Test if a given character is meant to be part of a function
139/// argument.
140///
141/// @param b the character to test against.
142///
143/// @return true iff @p b is a character that is meant to be part of a
144/// function argument.
145static bool
146char_is_function_argument_char(int b)
147{
148 if (b == '(' || b == ')')
149 return false;
150 return true;
151}
152
153/// Test if a given character is meant to be the start of a comment.
154///
155/// @param b the character to test against.
156///
157/// @return true iff @p b is the start of a comment.
158static bool
159char_is_comment_start(int b)
160{return b == ';' || b == '#';}
161
162/// Test if a character is meant to be a white space.
163///
164/// @param b the character to test against.
165///
166/// @return true iff @p b is a white space.
167static bool
168char_is_white_space(int b)
169{return b == ' ' || b == '\t' || b == '\n';}
170
171/// Remove the spaces at the begining and at the end of a given string.
172///
173/// @param str the string to remove leading and trailing white spaces from.
174///
175/// @return the string resulting from the removal of white space from @p str.
176static string
177trim_white_space(const string& str)
178{
179 if (str.empty())
180 return str;
181
182 unsigned s = 0, e = str.size() -1;
183
184 for (; s <= e; ++s)
185 if (!char_is_white_space(str[s]))
186 break;
187
188 for (; e > s; --e)
189 if (!char_is_white_space(str[e]))
190 break;
191
192 return str.substr(s, e - s + 1);
193}
194
195// <property stuff>
196
197/// Private data of @ref property type.
198struct property::priv
199{
200 string name_;
201
202 priv()
203 {}
204
205 priv(const string& name)
206 : name_(name)
207 {}
208}; // end struct property::priv
209
210/// Constructor of @ref property.
212 : priv_(new priv)
213{}
214
215/// Constructor of @ref property
216///
217/// @param name the name of the property.
218property::property(const string& name)
219 : priv_(new priv(name))
220{}
221
222/// Getter of the name of the property.
223///
224/// @return the name of the property.
225const string&
227{return priv_->name_;}
228
229/// Setter of the name of the property.
230///
231/// @param name the new name of the property.
232void
233property::set_name(const string& name)
234{priv_->name_ = name;}
235
236/// Destructor of the property.
238{}
239// </property stuff>
240
241// <property_value stuff>
242
243/// Private data for the @ref property_value type.
244struct property_value::priv
245{
246 enum property_value::value_kind kind_;
247
248 priv(property_value::value_kind kind = ABSTRACT_PROPERTY_VALUE)
249 : kind_(kind)
250 {}
251}; // property_value::priv
252
253/// Default constructor for the @ref property_value type.
254///
255/// @param kind the of @ref property_value that is being constructed.
257 : priv_(new priv(ABSTRACT_PROPERTY_VALUE))
258{}
259
260/// Constructor for the @ref property_value type.
261///
262/// @param kind the of @ref property_value that is being constructed.
264 : priv_(new priv(kind))
265{}
266
267/// Getter for the kind of the @ref property_value type.
268///
269/// @return the kind of @ref property_value we are looking at.
270property_value::value_kind
272{return priv_->kind_;}
273
274/// Converts the current property value to a string.
275///
276/// @return the string representation of the property value.
277property_value::operator const string& () const
278{return as_string();}
279
280/// Destructor for the @ref proprerty_value type.
282{}
283// </property_value stuff>
284
285// <string_property stuff>
286
287/// The private data for the @ref string_property_value type.
288struct string_property_value::priv
289{
290 string content_;
291
292 priv()
293 {}
294
295 priv(const string& c)
296 : content_(c)
297 {}
298}; // end struct string_property::priv
299
300/// Constructor of the @ref string_property_value type.
302 : property_value(STRING_PROPERTY_VALUE),
303 priv_(new priv())
304{}
305
306/// Constructor of the @ref string_property_value.
307///
308/// @param content the string content of the property value.
310 : property_value(STRING_PROPERTY_VALUE),
311 priv_(new priv(content))
312{}
313
314/// Setter of the content of the string property value.
315///
316/// @param c the new content.
317void
319{priv_->content_ = c;}
320
321/// Convert the string property value into a string.
322///
323/// @return the string contained in the string property value.
324const string&
326{return priv_->content_;}
327
328/// Conversion operator to a string, for the @ref
329/// string_property_value type.
330///
331/// @return the string representing this string_property_value.
332string_property_value::operator string() const
333{return as_string();}
334
335/// Test if a given property value is a string property value.
336///
337/// @return a pointer to the @ref string_property_value sub-object of
338/// the @ref property_value instance, if it's an instance of @ref
339/// string_property_value too.
342{return dynamic_cast<string_property_value*>(const_cast<property_value*>(v));}
343
344/// Test if a given property value is a string property value.
345///
346/// @return a pointer to the @ref string_property_value sub-object of
347/// the @ref property_value instance, if it's an instance of @ref
348/// string_property_value too.
351{return dynamic_pointer_cast<string_property_value>(v);}
352
353/// Destructor for the @ref string_property_value
355{}
356
357// </string_property_value stuff>
358
359// <list_property_value stuff>
360struct list_property_value::priv
361{
362 vector<string> values_;
363 string representation_;
364
365 priv()
366 {}
367
368 priv(const vector<string>& vals)
369 : values_(vals)
370 {}
371}; // end struct list_property_value::priv
372
373/// Default constructor of the @ref list_property_value type.
375 : property_value(property_value::LIST_PROPERTY_VALUE),
376 priv_(new priv)
377{}
378
379/// Copy constructor of the @ref list_property_value type.
380///
381/// @param values the instance of @ref list_property_value to copy from.
382list_property_value::list_property_value(const vector<string>& values)
383 : property_value(property_value::LIST_PROPERTY_VALUE),
384 priv_(new priv(values))
385{
386}
387
388/// Getter of the content of the @ref list_property_value.
389///
390/// The content of the @ref list_property_value is a vector of
391/// strings.
392///
393/// @return the vector of strings contained in the @ref
394/// list_property_value.
395const vector<string>&
397{return priv_->values_;}
398
399/// Setter of the content of the @ref list_property_value.
400///
401/// @param values the new content, which is a vector of strings.
402void
403list_property_value::set_content(const vector<string>& values)
404{
405 priv_->values_ = values;
406 priv_->representation_.clear();
407}
408
409/// Return a string representation of the @list_property_value.
410///
411/// @return the string representation.
412const string&
414{
415 if (priv_->representation_.empty())
416 {
417 for (vector<string>::const_iterator i = priv_->values_.begin();
418 i != priv_->values_.end();
419 ++i)
420 {
421 if (i != priv_->values_.begin())
422 priv_->representation_ += ",";
423 priv_->representation_ += *i;
424 }
425 }
426 return priv_->representation_;
427}
428
429/// Test if an instance of @property_value is a @ref list_property_value.
430///
431/// @param v the property_value to consider.
432///
433/// @return the @ref property_value converted into a @ref
434/// list_property_value if the @p v is a @ref list_property_value, nil
435/// otherwise.
438{return dynamic_cast<list_property_value*>(const_cast<property_value*>(v));}
439
440/// Test if an instance of @property_value is a @ref list_property_value.
441///
442/// @param v the property_value to consider.
443///
444/// @return the @ref property_value converted into a @ref
445/// list_property_value if the @p v is a @ref list_property_value, nil
446/// otherwise.
449{return dynamic_pointer_cast<list_property_value>(v);}
450
451// </list_property_value stuff>
452
453// <tuple_property_value>
454
455/// The private data of the @ref tuple_property_value type.
456struct tuple_property_value::priv
457{
458 vector<property_value_sptr> value_items_;
459 string string_rep_;
460
461 priv()
462 {}
463
464 priv(const vector<property_value_sptr>& value_items)
465 : value_items_(value_items)
466 {}
467}; // end struct tuple_property_value::priv
468
469/// Constructor for the @ref tuple_property_value type.
470///
471/// @param v the tuple content of the value.
472tuple_property_value::tuple_property_value(const vector<property_value_sptr>& v)
473 : property_value(TUPLE_PROPERTY_VALUE),
474 priv_(new priv(v))
475{}
476
477/// Getter for the content of the @ref tuple_property_value instance.
478///
479/// @return the content of the @ref tuple_property_value instance.
480const vector<property_value_sptr>&
482{return priv_->value_items_;}
483
484/// Getter for the content of the @ref tuple_property_value instance.
485///
486/// @return the content of the @ref tuple_property_value instance.
487vector<property_value_sptr>&
489{return priv_->value_items_;}
490
491/// Destructor of the @ref tuple_property_value type.
493{}
494
495/// Convert to the instance of @ref tuple_property_value to a string.
496///
497/// @return the string representation of the @ref tuple_property_value.
498const string&
500{
501 if (priv_->string_rep_.empty())
502 {
503 priv_->string_rep_ += '{';
504 for (vector<property_value_sptr>::const_iterator i =
505 get_value_items().begin();
506 i != get_value_items().end();
507 ++i)
508 {
509 if (i != get_value_items().begin())
510 priv_->string_rep_ += ",";
511 priv_->string_rep_ += (*i)->as_string();
512 }
513 priv_->string_rep_ += '}';
514 }
515 return priv_->string_rep_;
516}
517
518/// Test if a given instance of @ref property_value is an instance of
519/// @ref tuple_property_value too.
520///
521/// @return the @ref tuple_property_value sub-object of the @ref
522/// property_value instance, if it's an instance of @ref
523/// tuple_property_value too.
526{return dynamic_cast<tuple_property_value*>(const_cast<property_value*>(v));}
527
528/// Test if a given instance of @ref property_value is an instance of
529/// @ref tuple_property_value too.
530///
531/// @return the @ref tuple_property_value sub-object of the @ref
532/// property_value instance, if it's an instance of @ref
533/// tuple_property_value too.
536{return dynamic_pointer_cast<tuple_property_value>(v);}
537
538// </tuple_property_value>
539
540// <simple_property stuff>
541
542/// Private data of the @ref simple_property type.
543struct simple_property::priv
544{
546
547 priv()
548 {}
549
550 priv(const string_property_value_sptr value)
551 : value_(value)
552 {}
553}; // end struct simple_property::priv
554
555/// Default constructor of the @ref simple_property type.
557 : property(),
558 priv_(new priv)
559{}
560
561/// Constructor for the @ref simple_property type.
562///
563/// @param name the name of the property.
564///
565/// @param value the value of the property.
567 const string_property_value_sptr& value)
568 : property(name),
569 priv_(new priv(value))
570{}
571
572/// Constructor for the @ref simple_property type.
573///
574/// This one constructs a property with an empty value.
575///
576/// @param name the name of the property.
578 : property(name),
579 priv_(new priv)
580{}
581
582/// Getter for the string value of the property.
583///
584/// @return the string value of the property.
587{return priv_->value_;}
588
589/// Setter for the string value of the property.
590///
591/// @param value the new string value of the property.
592void
594{priv_->value_ = value;}
595
596/// Test if the property has an empty value.
597///
598/// An empty value is either no value at all or an empty string value.
599///
600/// @return true iff the property has an empty value.
601bool
603{
604 if (!priv_->value_)
605 return true;
606 return priv_->value_->as_string().empty();
607}
608
609/// Destructor of the @ref simple_property type.
611{}
612
613/// Tests if a @ref property is a simple property.
614///
615/// @return a pointer to the @ref simple_property sub-object of the
616/// @ref property instance, iff it's an @ref simple_property
617/// instance.
620{return dynamic_cast<simple_property*>(const_cast<property*>(p));}
621
622/// Tests if a @ref property is a simple property.
623///
624/// @return a smart pointer to the @ref simple_property sub-object of
625/// the @ref property instance, iff it's an @ref simple_property
626/// instance.
629{return dynamic_pointer_cast<simple_property>(p);}
630
631// </simple_property stuff>
632
633// <list_property stuff>
634struct list_property::priv
635{
637
638 priv()
639 {}
640
641 priv(const list_property_value_sptr value)
642 : value_(value)
643 {}
644}; //end struct list_property
645
646/// Default constructor for @ref list_property.
648 : priv_(new priv)
649{}
650
651/// Constructor for @ref list_property.
652///
653/// @param name the name of the property.
654///
655/// @param value the value of the property.
657 const list_property_value_sptr& value)
658 : property(name),
659 priv_(new priv(value))
660{}
661
662/// Getter for the value of the @ref list_property_value
665{return priv_->value_;}
666
667/// Setter for the value of the @ref list_property.
668///
669/// @param value the new value.
670void
672{priv_->value_ = value;}
673
674/// Destructor of the @ref list_property type.
676{}
677
678/// Test if an instance of a @ref property is actually an instance of
679/// @ref list_property.
680///
681/// @param p the @ref property to test.
682///
683/// @return the @p p converted into a @ref list_property if it's of
684/// type @ref list_property, or nil otherwise.
687{return dynamic_cast<list_property*>(const_cast<property*>(p));}
688
689/// Test if an instance of a @ref property is actually an instance of
690/// @ref list_property.
691///
692/// @param p the @ref property to test.
693///
694/// @return the @p p converted into a @ref list_property if it's of
695/// type @ref list_property, or nil otherwise.
698{return dynamic_pointer_cast<list_property>(p);}
699// </list_property stuff>
700
701// <tuple_property stuff>
702struct tuple_property::priv
703{
705
706 priv()
707 {}
708
709 priv(const tuple_property_value_sptr value)
710 : value_(value)
711 {}
712}; // end struct tuple_property::priv
713
714/// Default constructor of the @ref tuple_property type.
716 : property(),
717 priv_(new priv)
718{}
719
720/// Constructor of the @ref tuple_property type.
721///
722/// @param name the name of the property.
723///
724/// @param values the tuple value of the property.
726 const tuple_property_value_sptr value)
727 : property(name),
728 priv_(new priv(value))
729{}
730
731/// Setter for the tuple value of the property.
732///
733/// @param values the new tuple value of the property.
734void
736{priv_->value_ = value;}
737
738/// Getter for the tuple value of the property.
739///
740/// @return the tuple value of the property.
743{return priv_->value_;}
744
745/// Destructor for the @ref tuple_property type.
747{}
748
749/// Test if an instance of @ref property is an instance of @ref
750/// tuple_property.
751///
752/// @param p the instance of @ref property to test for.
753///
754/// @return return a pointer to the sub-object of @ref tuple_property
755/// iff @p p is an instance of @ref tuple_property.
758{return dynamic_cast<tuple_property*>(const_cast<property*>(p));}
759
760/// Test if an instance of @ref property is an instance of @ref
761/// tuple_property.
762///
763/// @param p the instance of @ref property to test for.
764///
765/// @return return a smart pointer to the sub-object of @ref
766/// tuple_property iff @p p is an instance of @ref tuple_property.
769{return dynamic_pointer_cast<tuple_property>(p);}
770
771// </tuple_property stuff>
772
773class config::section::priv
774{
775 string name_;
776 properties_type properties_;
777
778 // Forbid this;
779 priv();
780
781public:
782 priv(const string& name)
783 : name_(name)
784 {}
785
786 friend class config::section;
787};//end struct config::section::priv
788
789// <config::section stuff>
790
791/// Constructor for config::section.
792///
793/// @param name the name of the ini section.
794config::section::section(const string& name)
795 : priv_(new priv(name))
796{}
797
798/// Constructor for the config::section.
799///
800/// @param name the name of the ini section.
801///
802/// @param properties the properties of the section.
803config::section::section(const string& name,
804 const properties_type& properties)
805 : priv_(new priv(name))
806{set_properties(properties);}
807
808/// Get the name of the section.
809///
810/// @return the name of the section.
811const string&
813{return priv_->name_;}
814
815/// Get the properties of the section.
816///
817/// @return a vector of the properties of the section.
820{return priv_->properties_;}
821
822/// Set the properties of the section.
823///
824/// @param properties the new properties to set.
825void
827{priv_->properties_ = properties;}
828
829/// Add one property to this section.
830///
831/// @param prop the property to add to the section.
832void
834{priv_->properties_.push_back(prop);}
835
836/// Find a property that has a given name.
837///
838/// Note that this only returns the first property with that name.
839///
840/// @param prop_name the name of the property to find.
841///
842/// @return the found property, or nil if no property with the name @p
843/// prop_name was found.
845config::section::find_property(const string& prop_name) const
846{
847 for (properties_type::const_iterator i = get_properties().begin();
848 i != get_properties().end();
849 ++i)
850 if ((*i)->get_name() == prop_name)
851 return *i;
852 return property_sptr();
853}
854
855/// Destructor of config::section.
857{}
858// /<config::section stuff>
859
860// <read_context stuff>
861
862/// The context of the ini file parsing.
863///
864/// This is a private type that is used only in the internals of the
865/// ini file parsing.
866class read_context
867{
868 /// The input stream we are parsing from.
869 istream& in_;
870 /// The current line being parsed.
871 unsigned cur_line_;
872 /// The current column on the current line.
873 unsigned cur_column_;
874 vector<char> buf_;
875
876 // Forbid this;
877 read_context();
878
879public:
880
881 /// The constructor of @ref read_context.
882 ///
883 /// @param in the input stream to parse from.
884 read_context(istream& in)
885 : in_(in),
886 cur_line_(0),
887 cur_column_(0)
888 {}
889
890 /// @return the character that is going to be read by the next
891 /// invocation of read_next_char().
892 ///
893 /// Note that this function doesn't alter the input stream.
894 ///
895 /// Also note that this function handles escaping using the '\'
896 /// (backslash) character.
897 ///
898 /// @param escaped This is an output parameter. It's set to true by
899 /// this function if it escaped the peeked character. Otherwise,
900 /// it's set to false.
901 ///
902 /// @return peeked character.
903 char
904 peek(bool& escaped)
905 {
906 if (!buf_.empty())
907 return buf_.back();
908
909 escaped = false;
910 char c = in_.peek();
911 if (handle_escape(c, /*peek=*/true))
912 {
913 put_back(c);
914 escaped = true;
915 }
916 return c;
917 }
918
919 /// @return the character that is going to be read by the next
920 /// invocation of read_next_char().
921 ///
922 /// Note that this function doesn't alter the input stream.
923 ///
924 /// Also note that this function handles escaping using the '\'
925 /// (backslash) character.
926 ///
927 /// @return peeked character.
928 char
929 peek()
930 {
931 bool escaped = false;
932 return peek(escaped);
933 }
934
935 /// Get the next character of the input stream.
936 ///
937 /// This function knows how to handles escaped characters from the
938 /// input stream.
939 ///
940 /// @param do_handle_escape if yes, this function handles escaped
941 /// characters from the input stream.
942 ///
943 /// @return the next character of the input stream.
944 char
945 get(bool do_handle_escape = true)
946 {
947 char result = 0;
948 if (!buf_.empty())
949 {
950 result = buf_.back();
951 buf_.pop_back();
952 }
953 else
954 {
955 result = in_.get();
956 if (do_handle_escape)
957 handle_escape(result);
958 }
959 return result;
960 }
961
962 /// Put a character that was read from the input stream, back into
963 /// that input stream, so that a subsequent call to
964 /// read_context::get() returns that same character.
965 ///
966 /// @param c the character to put back into the stream.
967 void
968 put_back(char c)
969 {buf_.push_back(c);}
970
971 /// Test if the status of the input stream is good.
972 ///
973 /// @return true iff the status of the input stream is good.
974 bool
975 good() const
976 {
977 if (!buf_.empty())
978 return true;
979 return in_.good();
980 }
981
982 /// Tests if the input stream has reached end of file.
983 ///
984 /// @return true iff the input stream has reached end of file.
985 bool
986 eof() const
987 {
988 if (!buf_.empty())
989 return false;
990 return in_.eof();
991 }
992
993 /// Handles the escaping of a character.
994 ///
995 /// This function must be called whenever the low level character
996 /// reading function encountered a backslash character ('\'). In
997 /// that case, this function reads the subsequent characters from
998 /// the input stream, sees if it needs to escape them and then
999 /// handles the escaping if need be. Otherwise, it does nothing.
1000 ///
1001 /// This is a subroutine of the read_context::get() and
1002 /// read_context::peek() functions.
1003 ///
1004 /// @param peek if true, it means this function was called after the
1005 /// caller issued a read_context::peek() call, rather than a
1006 /// read_context::get() call.
1007 ///
1008 /// @return true if an escaping took place.
1009 bool
1010 handle_escape(char& c, bool peek = false)
1011 {
1012 bool escaped = false;
1013 char b = c;
1014
1015 if (b == '\\')
1016 {
1017 escaped = true;
1018 b = get(/*escape=*/false);
1019 if (!good())
1020 return escaped;
1021 if (peek)
1022 {
1023 ABG_ASSERT(b == c);
1024 b = get(/*escape=*/false);
1025 if (!good())
1026 return escaped;
1027 }
1028
1029 switch (b)
1030 {
1031 case '0':
1032 case 'a':
1033 case 'b':
1034 case 'r':
1035 // let's replace this by a space
1036 c = ' ';
1037 break;
1038 case 't':
1039 c = '\t';
1040 break;
1041 case '\n':
1042 // continuation line. So we should drop both the backslash
1043 // character and this end-of-line character on the floor
1044 // just like if they never existed.
1045 ++cur_column_;
1046 b = get(/*escape=*/false);
1047 if (!good())
1048 return escaped;
1049 c = b;
1050 break;
1051 case '\\':
1052 case ';':
1053 case '#':
1054 case '[':
1055 case ']':
1056 default:
1057 c = b;
1058 break;
1059 }
1060 }
1061 else
1062 c = b;
1063
1064 return escaped;
1065 }
1066
1067 /// Read the next character from the input stream.
1068 ///
1069 /// This method updates the current line/column number after looking
1070 /// at the actual char that got read. Note that escaped characters
1071 /// are handled transparently at this point.
1072 ///
1073 /// @param c output parameter. This is set by this function to the
1074 /// character that was read. It's set iff the function returned
1075 /// true.
1076 ///
1077 /// @return true if the reading went well and if the input stream is
1078 /// in a non-erratic state.
1079 bool
1080 read_next_char(char& c)
1081 {
1082 char b = get();
1083 if (!good())
1084 return false;
1085
1086 c = b;
1087
1088 if (cur_line_ == 0)
1089 cur_line_ = 1;
1090
1091 if (b == '\n')
1092 {
1093 ++cur_line_;
1094 cur_column_ = 0;
1095 }
1096 else
1097 ++cur_column_;
1098
1099 return true;
1100 }
1101
1102 /// Skip (that is, read characters and drop them on the floor) all
1103 /// the characters up to the next line.
1104 ///
1105 /// Note that the new line character (\n' on unices) is skipped as
1106 /// well.
1107 ///
1108 /// @return true iff the skipping proceeded successfully and that
1109 /// the input stream is left in a non-erratic state.
1110 bool
1111 skip_line()
1112 {
1113 char c = 0;
1114 for (bool is_ok = read_next_char(c);
1115 is_ok;
1116 is_ok = read_next_char(c))
1117 if (c == '\n')
1118 break;
1119
1120 return (c == '\n' || eof());
1121 }
1122
1123 /// If the current character is a white space, skip it and all the
1124 /// contiguous ones that follow.
1125 ///
1126 /// @return true iff the input stream is left in a non-erratic state.
1127 bool
1128 skip_white_spaces()
1129 {
1130 for (char c = peek(); good(); c = peek())
1131 if (char_is_white_space(c))
1132 ABG_ASSERT(read_next_char(c));
1133 else
1134 break;
1135 return good() || eof();
1136 }
1137
1138 /// If the current character is the beginning of a comment, skip
1139 /// (read and drop on the floor) the entire remaining line,
1140 /// including the current character.
1141 ///
1142 /// @return true if the input stream is left in a non-erratic state.
1143 bool
1144 skip_comments()
1145 {
1146 for (char c = peek(); good(); c = peek())
1147 if (char_is_comment_start(c))
1148 skip_line();
1149 else
1150 break;
1151 return good() || eof();
1152 }
1153
1154 /// If the current character is either the beginning of a comment or
1155 /// a white space, skip the entire commented line or the subsequent
1156 /// contiguous white spaces.
1157 ///
1158 /// @return true iff the stream is left in a non-erratic state.
1159 bool
1160 skip_white_spaces_or_comments()
1161 {
1162 int b = 0;
1163 while (good())
1164 {
1165 b = peek();
1166 if (char_is_white_space(b))
1167 skip_white_spaces();
1168 else if (char_is_comment_start(b))
1169 skip_comments();
1170 else
1171 break;
1172 }
1173 return good() || eof();
1174 }
1175
1176 /// Read a property name.
1177 ///
1178 /// @param name out parameter. Is set to the parsed property name,
1179 /// if any. Note that this is set only if the function returned
1180 /// true.
1181 ///
1182 /// @return true iff the input stream is left in a non-erratic
1183 /// state.
1184 bool
1185 read_property_name(string& name)
1186 {
1187 char c = peek();
1188 if (!good() || !char_is_property_name_char(c))
1189 return false;
1190
1191 ABG_ASSERT(read_next_char(c));
1192 name += c;
1193
1194 for (c = peek(); good(); c = peek())
1195 {
1196 if (!char_is_property_name_char(c))
1197 break;
1198 ABG_ASSERT(read_next_char(c));
1199 name += c;
1200 }
1201
1202 return true;
1203 }
1204
1205 /// Read a function name.
1206 ///
1207 /// @param name the name of the function. This is an output
1208 /// parameter when this puts the function name that was read, iff
1209 /// this function returns true.
1210 ///
1211 /// @return true iff the function name was successfully read into @p
1212 /// name.
1213 bool
1214 read_function_name(string& name)
1215 {
1216 char c = peek();
1217 if (!good() || !char_is_function_name_char(c))
1218 return false;
1219
1220 ABG_ASSERT(read_next_char(c));
1221 name += c;
1222
1223 for (c = peek(); good(); c = peek())
1224 {
1225 if (!char_is_function_name_char(c))
1226 break;
1227 ABG_ASSERT(read_next_char(c));
1228 name += c;
1229 }
1230
1231 return true;
1232 }
1233
1234 /// Read a function argument.
1235 ///
1236 /// @param argument the argument of the function that was just
1237 /// read. This is an ouput parameter that is set iff the function
1238 /// returns true.
1239 ///
1240 /// @return true iff parameter @p argument was successful set.
1241 bool
1242 read_function_argument(string& argument)
1243 {
1244 char c = peek();
1245 if (!good() || !char_is_function_argument_char(c))
1246 return false;
1247
1248 ABG_ASSERT(read_next_char(c));
1249 argument += c;
1250
1251 for (c = peek(); good(); c = peek())
1252 {
1253 if (!char_is_function_argument_char(c))
1254 break;
1255 ABG_ASSERT(read_next_char(c));
1256 argument += c;
1257 }
1258
1259 return true;
1260 }
1261
1262 /// Read a function call expression.
1263 ///
1264 /// The expression this function can read has the form:
1265 /// 'foo(bar,baz, blah)'
1266 ///
1267 /// @param expr this is an output parameter that is set with the
1268 /// resulting function call expression that was read, iff this
1269 /// function returns true.
1270 ///
1271 /// @param return true iff @p expr was successful set with the
1272 /// function call expression that was read.
1273 bool
1275 {
1276 if (!good())
1277 return false;
1278
1279 skip_white_spaces_or_comments();
1280 if (!good())
1281 return false;
1282
1283 string name;
1284 if (!read_function_name(name) || name.empty())
1285 return false;
1286
1287 skip_white_spaces_or_comments();
1288
1289 int b = peek();
1290 if (!good() || b != '(')
1291 return false;
1292
1293 char c = 0;
1294 if (!read_next_char(c))
1295 return false;
1296 ABG_ASSERT(c == '(');
1297
1298 skip_white_spaces_or_comments();
1299 if (!good())
1300 return false;
1301
1302 // Read function call arguments.
1303 vector<string> arguments;
1304 for (;;)
1305 {
1306 if (peek() == ')')
1307 break;
1308
1309 string arg;
1310 if (!read_function_argument(arg))
1311 return true;
1312
1313 skip_white_spaces_or_comments();
1314 if (!good())
1315 return false;
1316
1317 if (peek() == ',')
1318 {
1319 c = 0;
1320 ABG_ASSERT(read_next_char(c) && c == ',');
1321 skip_white_spaces_or_comments();
1322 if (!good())
1323 return false;
1324 }
1325
1326 arguments.push_back(arg);
1327 }
1328
1329 c = 0;
1330 ABG_ASSERT(read_next_char(c) && c == ')');
1331
1332 expr.reset(new function_call_expr(name, arguments));
1333 return true;
1334 }
1335
1336 /// Read a property value.
1337 ///
1338 /// @return the property value read.
1340 read_property_value()
1341 {
1342 property_value_sptr nil, result;
1343
1344 int b = peek();
1345 if (!good())
1346 return nil;
1347
1348 if (b == '{')
1349 {
1350 if (tuple_property_value_sptr t = read_tuple_property_value())
1351 return t;
1352 return nil;
1353 }
1354
1355 list_property_value_sptr list = read_list_property_value();
1356 if (list && list->get_content().size() == 1)
1357 result.reset(new string_property_value(list->get_content()[0]));
1358 else
1359 result = list;
1360
1361 return result;
1362 }
1363
1364 /// Reads a string from the input stream.
1365 ///
1366 /// A string is just a contiguous set of characters that test
1367 /// positive when passed to
1368 /// read_context::char_is_property_value_char().
1369 ///
1370 /// Note that all escaped characters are suitable to be in a string.
1371 ///
1372 /// @return the string read.
1373 string
1374 read_string()
1375 {
1376 bool escaped = false;
1377 int b = peek(escaped);
1378 if (!good())
1379 return "";
1380
1381 if (!escaped && char_is_delimiter(b, /*include_white_space=*/false))
1382 // Empty property value. This is accepted.
1383 return "";
1384
1385 string v;
1386 for (b = peek(escaped); good(); b = peek(escaped))
1387 {
1388 // If the current character is not suitable to be a in string,
1389 // then we reached the end of the string. Note that espaced
1390 // characters are always suitable to be a string.
1391 if (!escaped && !char_is_property_value_char(b))
1392 break;
1393 char c = 0;
1394 ABG_ASSERT(read_next_char(c));
1395 v += c;
1396 }
1397 return trim_white_space(v);
1398 }
1399
1400 /// Read a string property value.
1401 ///
1402 /// @return the property value that has been parsed.
1404 read_string_property_value()
1405 {
1406 string_property_value_sptr nil, result;
1407 if (!good())
1408 return nil;
1409
1410 string value = read_string();
1411 result.reset(new string_property_value(value));
1412 return result;
1413 }
1414
1415 /// Read a @ref list_property_value.
1416 ///
1417 /// @return the instance of @ref list_property_value read, or nil if
1418 /// none was read.
1420 read_list_property_value()
1421 {
1422 list_property_value_sptr nil, result;
1423 string str;
1424 vector<string> content;
1425
1426 for (;;)
1427 {
1428 str = read_string();
1429 if (str.empty())
1430 break;
1431 content.push_back(str);
1432
1433 skip_white_spaces();
1434
1435 int b = peek();
1436 if (!good() || b != ',')
1437 break;
1438 skip_white_spaces();
1439
1440 char c = 0;
1441 read_next_char(c);
1442 ABG_ASSERT(c == ',');
1443 skip_white_spaces();
1444 }
1445
1446 if (!content.empty())
1447 result.reset(new list_property_value(content));
1448
1449 return result;
1450 }
1451
1452 /// A property value that is a tuple.
1453 ///
1454 /// @param tuple the read property tuple value.
1455 ///
1456 /// @return true iff the tuple property value could be read
1457 /// correctly.
1459 read_tuple_property_value()
1460 {
1461 tuple_property_value_sptr nil, result;
1462 int b = peek();
1463 if (!good())
1464 return nil;
1465
1466 if (b != '{')
1467 return nil;
1468
1469 char c = 0;
1470 ABG_ASSERT(read_next_char(c));
1471
1472 property_value_sptr value;
1473 vector<property_value_sptr> values;
1474 while (good() && peek() != '}')
1475 {
1476 skip_white_spaces();
1477 if ((value = read_property_value()))
1478 values.push_back(value);
1479 skip_white_spaces();
1480 if (good() && peek() == ',')
1481 {
1482 c = 0;
1483 read_next_char(c);
1484 }
1485 }
1486
1487 b = peek();
1488 if (b != '}')
1489 return nil;
1490
1491 c = 0;
1492 read_next_char(c);
1493
1494 result.reset(new tuple_property_value(values));
1495 return result;
1496 }
1497
1498 /// Read the name of a section.
1499 ///
1500 /// @param name out parameter. Is set to the name of the section
1501 /// that was parsed. Note that this is set only if the function
1502 /// returned true.
1503 ///
1504 /// @return true if the input stream was left in a non-erratic
1505 /// state.
1506 bool
1507 read_section_name(string& name)
1508 {
1509 int b = peek();
1510 if (!good() || !char_is_section_name_char(b))
1511 return false;
1512
1513 char c = 0;
1514 ABG_ASSERT(read_next_char(c) || char_is_section_name_char(b));
1515 name += c;
1516
1517 for (b = peek(); good(); b = peek())
1518 {
1519 if (!char_is_section_name_char(b))
1520 break;
1521 ABG_ASSERT(read_next_char(c));
1522 name += c;
1523 }
1524
1525 return true;
1526 }
1527
1528 /// Read a property (<name> = <value>).
1529 ///
1530 /// @return the resulting pointer to property iff one could be
1531 /// parsed.
1533 read_property()
1534 {
1535 property_sptr nil;
1536
1537 string name;
1538 if (!read_property_name(name))
1539 return nil;
1540
1541 skip_white_spaces();
1542
1543 property_sptr result;
1544
1545 char c = peek();
1546 if (c == '=')
1547 {
1548 ABG_ASSERT(read_next_char(c));
1549 ABG_ASSERT(c == '=');
1550 skip_white_spaces();
1551 }
1552 else
1553 {
1554 property_sptr empty_value_property(new simple_property(name));
1555 return empty_value_property;
1556 }
1557
1558 if (!good())
1559 return nil;
1560
1561 property_value_sptr value = read_property_value();
1562 if (!value)
1563 return nil;
1564
1566 result.reset(new tuple_property(name, tv));
1568 result.reset(new list_property(name, lv));
1570 result.reset(new simple_property(name, sv));
1571 else
1572 // This new kind of property is not yet supported!
1573 std::abort();
1574
1575 return result;
1576 }
1577
1578 /// Read an ini section.
1579 ///
1580 /// @return a pointer to a section iff it could be successfully
1581 /// parsed.
1583 read_section()
1584 {
1586
1587 int b = peek();
1588 if (!good())
1589 return nil;
1590
1591 char c = 0;
1592 if (b == '[')
1593 ABG_ASSERT(read_next_char(c) && c == '[');
1594
1595 string name;
1596 if (!read_section_name(name))
1597 return nil;
1598
1599 if (!skip_white_spaces())
1600 return nil;
1601
1602 if (! read_next_char(c) || c != ']')
1603 return nil;
1604
1605 if (!skip_white_spaces_or_comments())
1606 return nil;
1607
1608 config::properties_type properties;
1609 while (property_sptr prop = read_property())
1610 {
1611 properties.push_back(prop);
1612 skip_white_spaces_or_comments();
1613 }
1614
1615 if (!properties.empty())
1616 {
1617 config::section_sptr section(new config::section(name, properties));
1618 return section;
1619 }
1620
1621 return nil;
1622 }
1623};//end struct read_context
1624
1625// </read_context stuff>
1626
1627// <config stuff>
1628
1629class config::priv
1630{
1631 string path_;
1632 sections_type sections_;
1633
1634public:
1635 friend class config;
1636
1637 priv()
1638 {}
1639
1640 priv(const string& path,
1641 sections_type& sections)
1642 : path_(path),
1643 sections_(sections)
1644 {}
1645
1646};
1647
1648/// @param path the path to the config file.
1649///
1650/// @param sections the sections of the config file.
1651config::config(const string& path,
1652 sections_type& sections)
1653 : priv_(new priv(path, sections))
1654{}
1655
1656config::config()
1657 : priv_(new priv)
1658{}
1659
1660config::~config()
1661{}
1662
1663/// @return the path to the config file.
1664const string&
1666{return priv_->path_;}
1667
1668/// Set the path to the config file.
1669///
1670/// @param the new path to the config file.
1671void
1672config::set_path(const string& path)
1673{priv_->path_ = path;}
1674
1675/// @return the sections of the config file.
1678{return priv_->sections_;}
1679
1680/// Set new sections to the ini config
1681///
1682/// @param sections the new sections to set.
1683void
1685{priv_->sections_ = sections;}
1686
1687// </config stuff>
1688
1689// <config reader stuff>
1690
1691/// Parse the sections of an *.ini file.
1692///
1693/// @param input the input stream to parse the ini file from.
1694///
1695/// @param section out parameter. This is set to the vector of
1696/// sections that have been parsed from the input stream.
1697///
1698/// @return true upon successful completion and if if the stream is
1699/// left in a non-erratic state.
1700bool
1701read_sections(std::istream& input,
1702 config::sections_type& sections)
1703{
1704 read_context ctxt(input);
1705
1706 while (input.good())
1707 {
1708 ctxt.skip_white_spaces_or_comments();
1709 if (config::section_sptr section = ctxt.read_section())
1710 sections.push_back(section);
1711 else
1712 break;
1713 }
1714
1715 return input.good() || input.eof();
1716}
1717
1718/// Parse the sections of an *.ini file.
1719///
1720/// @param path the path of the ini file to parse.
1721///
1722/// @param section out parameter. This is set to the vector of
1723/// sections that have been parsed from the input stream.
1724///
1725/// @return true upon successful completion and if if the stream is
1726/// left in a non-erratic state.
1727bool
1728read_sections(const string& path,
1729 config::sections_type& sections)
1730{
1731 std::ifstream in(path.c_str(), std::ifstream::binary);
1732 if (!in.good())
1733 return false;
1734
1735 bool is_ok = read_sections(in, sections);
1736 in.close();
1737
1738 return is_ok;
1739}
1740
1741/// Parse an ini config file from an input stream.
1742///
1743/// @param input the input stream to parse the ini config file from.
1744///
1745/// @return true upon successful parsing.
1746bool
1747read_config(istream& input,
1748 config& conf)
1749{
1750 config::sections_type sections;
1751 if (!read_sections(input, sections))
1752 return false;
1753 conf.set_sections(sections);
1754 return true;
1755}
1756
1757/// Parse an ini config file from a file on disk.
1758///
1759/// @param path the path to the ini file to parse.
1760///
1761/// @param conf the resulting config file to populate as a result of
1762/// the parsing. This is populated iff the function returns true.
1763///
1764/// @return true upon succcessful completion.
1765bool
1766read_config(const string& path,
1767 config& conf)
1768{
1769 config::sections_type sections;
1770 if (!read_sections(path, sections))
1771 return false;
1772 conf.set_path(path);
1773 conf.set_sections(sections);
1774 return true;
1775}
1776
1777/// Parse an ini config file from an input stream.
1778///
1779/// @return a shared pointer to the resulting config, or nil if it
1780/// couldn't be parsed.
1782read_config(std::istream& input)
1783{
1784 config_sptr c(new config);
1785 if (!read_config(input, *c))
1786 return config_sptr();
1787 return c;
1788}
1789
1790
1791/// Parse an ini config file from an on-disk file.
1792///
1793/// @return a shared pointer to the resulting config, or nil if it
1794/// couldn't be parsed.
1796read_config(const string& path)
1797{
1798 config_sptr c(new config);
1799 if (!read_config(path, *c))
1800 return config_sptr();
1801 return c;
1802}
1803// <config reader stuff>
1804
1805// <config writer stuff>
1806
1807/// Serialize the value of a property to a string.
1808///
1809/// @param prop the property which value to serialize.
1810///
1811/// @return the string that represents the value of @p prop.
1812static string
1813write_property_value(const property_sptr& prop)
1814{
1815 string result;
1816 if (simple_property_sptr simple_prop = is_simple_property(prop))
1817 {
1818 if (!simple_prop->has_empty_value())
1819 result = simple_prop->get_value()->as_string();
1820 }
1821 else if (list_property_sptr list_prop = is_list_property(prop))
1822 result = list_prop->get_value()->as_string();
1823 else if (tuple_property_sptr tuple_prop = is_tuple_property(prop))
1824 result = tuple_prop->get_value()->as_string();
1825 else
1826 // This new kind of property is not yet supported!
1827 abort();
1828 return result;
1829}
1830
1831/// Serialize an ini property to an output stream.
1832///
1833/// @param prop the property to serialize to the output stream.
1834///
1835/// @param out the output stream to serialize to.
1836///
1837/// @return true if the ouput stream is left in a non-erratic state.
1838static bool
1839write_property(const property_sptr& prop,
1840 std::ostream& out)
1841{
1842 out << prop->get_name();
1843 string value = write_property_value(prop);
1844 if (!value.empty())
1845 out << " = " << write_property_value(prop);
1846 return out.good();
1847}
1848
1849/// Serialize an ini section to an output stream.
1850///
1851/// @param section the ini section to serialize.
1852///
1853/// @param out the output stream to serialize the section to.
1854static bool
1855write_section(const config::section& section,
1856 std::ostream& out)
1857{
1858 out << "[" << section.get_name() << "]\n";
1859 for (config::properties_type::const_iterator i =
1860 section.get_properties().begin();
1861 i != section.get_properties().end();
1862 ++i)
1863 {
1864 out << " ";
1865 write_property(*i, out);
1866 out << "\n";
1867 }
1868 return out.good();
1869}
1870
1871/// Serialize a vector of sections that make up an ini config file to
1872/// an output stream.
1873///
1874/// Note that an ini config is just a collection of sections.
1875///
1876/// @param sections the vector of sections to serialize.
1877///
1878/// @param out the output stream.
1879///
1880/// @return true if the output stream is left in a non-erratic state.
1881bool
1883 std::ostream& out)
1884{
1885 for (config::sections_type::const_iterator i = sections.begin();
1886 i != sections.end();
1887 ++i)
1888 {
1889 write_section(**i, out);
1890 out << "\n";
1891 }
1892 return out.good();
1893}
1894
1895/// Serialize a vector of sections that make up an ini config to a
1896/// file.
1897///
1898/// @param sections the vector of sections to serialize.
1899///
1900/// @param out the output stream.
1901///
1902/// @return true if the output stream is left in a non-erratic state.
1903bool
1905 const string& path)
1906{
1907 std::ofstream f(path.c_str(), std::ofstream::binary);
1908
1909 if (!f.good())
1910 return false;
1911
1912 bool is_ok = write_sections(sections, f);
1913
1914 f.close();
1915
1916 return is_ok;
1917}
1918
1919/// Serialize an instance of @ref config to an output stream.
1920///
1921/// @param conf the instance of @ref config to serialize.
1922///
1923/// @param output the output stream to serialize @p conf to.
1924///
1925/// @return true upon successful completion.
1926bool
1928 std::ostream& output)
1929{
1930 if (!write_sections(conf.get_sections(), output))
1931 return false;
1932 return true;
1933}
1934
1935/// Serialize an instance of @ref conf to an on-disk file.
1936///
1937/// @param conf the instance of @ref config to serialize.
1938///
1939/// @param path the path to the on-disk file to serialize to.
1940///
1941/// @return true upon successful completion.
1942bool
1944 const string& path)
1945{
1946 if (!write_sections(conf.get_sections(), path))
1947 return false;
1948 return true;
1949}
1950// </config writer stuff>
1951
1952// <function_call_expr stuff>
1953
1954/// The private data type of @ref function_call_expr.
1955struct function_call_expr::priv
1956{
1957 string name_;
1958 vector<string> arguments_;
1959
1960 priv()
1961 {}
1962
1963 priv(const string& name,
1964 const vector<string>& arguments)
1965 : name_(name),
1966 arguments_(arguments)
1967 {}
1968}; // end struct function_call_expr::priv
1969
1970/// Constructor for the @ref function_call_expr type.
1971///
1972/// @param name the name of the function being called.
1973///
1974/// @param args a vector of the arguements of the function being
1975/// called.
1976function_call_expr::function_call_expr(const string& name,
1977 const vector<string>& args)
1978 : priv_(new priv(name, args))
1979{}
1980
1981/// Getter of the name of the function being called.
1982///
1983/// @return the name of the function being called.
1984const string&
1986{return priv_->name_;}
1987
1988/// Getter for the arguments of the function call expression.
1989///
1990/// That is, a getter for the arguments of the function call.
1991///
1992/// @return the operands of the function call expression.
1993const vector<string>&
1995{return priv_->arguments_;}
1996
1997/// Getter for the arguments of the function call expression.
1998///
1999/// That is, a getter for the arguments of the function call.
2000///
2001/// @return the operands of the function call expression.
2002vector<string>&
2004{return priv_->arguments_;}
2005
2006/// Read a function call expression and build its representation.
2007///
2008/// @param input the input stream where to read the function call
2009/// expression from.
2010///
2011/// @param expr the expression resulting from the parsing. This is an
2012/// output parameter that is set iff this function returns true.
2013///
2014/// @return true iff the parameter @p expr is successfully set with
2015/// the resulting of parsing the @p input.
2016bool
2017read_function_call_expr(std::istream& input,
2019{
2020 read_context ctxt(input);
2021 return ctxt.read_function_call_expr(expr);
2022}
2023
2024/// Read a function call expression and build its representation.
2025///
2026/// @param input a string where to read the function call expression
2027/// from.
2028///
2029/// @param expr the expression resulting from the parsing. This is an
2030/// output parameter that is set iff this function returns true.
2031///
2032/// @return true iff the parameter @p expr is successfully set with
2033/// the resulting of parsing the @p input.
2034bool
2035read_function_call_expr(const string& input,
2037{
2038 std::istringstream in(input);
2039 return read_function_call_expr(in, expr);
2040}
2041
2042/// Read a function call expression and build its representation.
2043///
2044/// @param input a string where to read the function call expression
2045/// from.
2046///
2047/// @return the representation of the expression resulting from the
2048/// parsing.
2050read_function_call_expr(const string& input)
2051{
2053 read_function_call_expr(input, expr);
2054 return expr;
2055}
2056// </function_call_expr stuff>
2057}// end namespace ini
2058}// end namespace abigail
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Definition: abg-fwd.h:1737
This file contains the declarations for the ini file reader used in the libabigail library.
const string & get_name() const
Get the name of the section.
Definition: abg-ini.cc:812
void set_properties(const properties_type &properties)
Set the properties of the section.
Definition: abg-ini.cc:826
property_sptr find_property(const string &prop_name) const
Find a property that has a given name.
Definition: abg-ini.cc:845
const properties_type & get_properties() const
Get the properties of the section.
Definition: abg-ini.cc:819
virtual ~section()
Destructor of config::section.
Definition: abg-ini.cc:856
void add_property(const property_sptr prop)
Add one property to this section.
Definition: abg-ini.cc:833
The abstraction of the structured content of an .ini file. This roughly follows what is explained at ...
Definition: abg-ini.h:322
vector< property_sptr > properties_type
A convenience typedef for a vector of property_sptr.
Definition: abg-ini.h:335
shared_ptr< section > section_sptr
A convenience typedef for a shared pointer to a config::section.
Definition: abg-ini.h:329
void set_path(const string &path)
Set the path to the config file.
Definition: abg-ini.cc:1672
void set_sections(const sections_type &sections)
Set new sections to the ini config.
Definition: abg-ini.cc:1684
vector< section_sptr > sections_type
A convenience typedef for a vector of config::section_sptr.
Definition: abg-ini.h:332
const sections_type & get_sections() const
Definition: abg-ini.cc:1677
const string & get_path() const
Definition: abg-ini.cc:1665
const vector< string > & get_arguments() const
Getter for the arguments of the function call expression.
Definition: abg-ini.cc:1994
const string & get_name() const
Getter of the name of the function being called.
Definition: abg-ini.cc:1985
Abstracts the value of a property representing a list of strings.
Definition: abg-ini.h:142
list_property_value()
Default constructor of the list_property_value type.
Definition: abg-ini.cc:374
void set_content(const vector< string > &)
Setter of the content of the list_property_value.
Definition: abg-ini.cc:403
virtual const string & as_string() const
Return a string representation of the @list_property_value.
Definition: abg-ini.cc:413
const vector< string > & get_content() const
Getter of the content of the list_property_value.
Definition: abg-ini.cc:396
A class representing a list property.
Definition: abg-ini.h:255
list_property()
Default constructor for list_property.
Definition: abg-ini.cc:647
virtual ~list_property()
Destructor of the list_property type.
Definition: abg-ini.cc:675
const list_property_value_sptr & get_value() const
Getter for the value of the list_property_value.
Definition: abg-ini.cc:664
void set_value(const list_property_value_sptr &value)
Setter for the value of the list_property.
Definition: abg-ini.cc:671
Base class of propertie values.
Definition: abg-ini.h:67
property_value()
Default constructor for the property_value type.
Definition: abg-ini.cc:256
value_kind get_kind() const
Getter for the kind of the property_value type.
Definition: abg-ini.cc:271
virtual ~property_value()
Destructor for the proprerty_value type.
Definition: abg-ini.cc:281
The base class of the different kinds of properties of an INI file.
Definition: abg-ini.h:41
property()
Constructor of property.
Definition: abg-ini.cc:211
virtual ~property()
Destructor of the property.
Definition: abg-ini.cc:237
const string & get_name() const
Getter of the name of the property.
Definition: abg-ini.cc:226
void set_name(const string &name)
Setter of the name of the property.
Definition: abg-ini.cc:233
A simple property. That is, one which value is a string_property_value.
Definition: abg-ini.h:211
void set_value(const string_property_value_sptr &value)
Setter for the string value of the property.
Definition: abg-ini.cc:593
bool has_empty_value() const
Test if the property has an empty value.
Definition: abg-ini.cc:602
const string_property_value_sptr & get_value() const
Getter for the string value of the property.
Definition: abg-ini.cc:586
virtual ~simple_property()
Destructor of the simple_property type.
Definition: abg-ini.cc:610
simple_property()
Default constructor of the simple_property type.
Definition: abg-ini.cc:556
A property value which is a string.
Definition: abg-ini.h:101
virtual ~string_property_value()
Destructor for the string_property_value.
Definition: abg-ini.cc:354
void set_content(const string &)
Setter of the content of the string property value.
Definition: abg-ini.cc:318
virtual const string & as_string() const
Convert the string property value into a string.
Definition: abg-ini.cc:325
string_property_value()
Constructor of the string_property_value type.
Definition: abg-ini.cc:301
A property value that is a tuple.
Definition: abg-ini.h:177
virtual ~tuple_property_value()
Destructor of the tuple_property_value type.
Definition: abg-ini.cc:492
tuple_property_value(const vector< property_value_sptr > &)
Constructor for the tuple_property_value type.
Definition: abg-ini.cc:472
const vector< property_value_sptr > & get_value_items() const
Getter for the content of the tuple_property_value instance.
Definition: abg-ini.cc:481
virtual const string & as_string() const
Convert to the instance of tuple_property_value to a string.
Definition: abg-ini.cc:499
Abstraction of a tuple property. A tuple property is a property which value is a tuple_property_value...
Definition: abg-ini.h:287
tuple_property()
Default constructor of the tuple_property type.
Definition: abg-ini.cc:715
void set_value(const tuple_property_value_sptr value)
Setter for the tuple value of the property.
Definition: abg-ini.cc:735
virtual ~tuple_property()
Destructor for the tuple_property type.
Definition: abg-ini.cc:746
const tuple_property_value_sptr & get_value() const
Getter for the tuple value of the property.
Definition: abg-ini.cc:742
shared_ptr< property_value > property_value_sptr
Convenience typedef for a shared_ptr to property_value.
Definition: abg-ini.h:63
shared_ptr< list_property_value > list_property_value_sptr
A convenience typedef for a shared_ptr to list_property_value.
Definition: abg-ini.h:130
bool read_function_call_expr(std::istream &input, function_call_expr_sptr &expr)
Read a function call expression and build its representation.
Definition: abg-ini.cc:2017
list_property * is_list_property(const property *p)
Test if an instance of a property is actually an instance of list_property.
Definition: abg-ini.cc:686
bool write_config(const config &conf, std::ostream &output)
Serialize an instance of config to an output stream.
Definition: abg-ini.cc:1927
shared_ptr< property > property_sptr
Convenience typefef for shared_ptr to property.
Definition: abg-ini.h:36
shared_ptr< list_property > list_property_sptr
A convenience typedef for a shared_ptr to a list_property.
Definition: abg-ini.h:244
shared_ptr< config > config_sptr
A convenience typedef for a shared pointer to config.
Definition: abg-ini.h:316
list_property_value * is_list_property_value(const property_value *v)
Test if an instance of @property_value is a list_property_value.
Definition: abg-ini.cc:437
bool read_config(istream &input, config &conf)
Parse an ini config file from an input stream.
Definition: abg-ini.cc:1747
bool read_sections(std::istream &input, config::sections_type &sections)
Parse the sections of an *.ini file.
Definition: abg-ini.cc:1701
shared_ptr< tuple_property > tuple_property_sptr
Convenience typedef for a shared_ptr of tuple_property.
Definition: abg-ini.h:282
shared_ptr< simple_property > simple_property_sptr
Convenience typedef for a shared_ptr to an simple_property.
Definition: abg-ini.h:206
shared_ptr< function_call_expr > function_call_expr_sptr
Convenience typedef for a shared pointer to function_call_expr.
Definition: abg-ini.h:430
shared_ptr< string_property_value > string_property_value_sptr
A convenience typedef for a shared_ptr to string_property_value.
Definition: abg-ini.h:97
string_property_value * is_string_property_value(const property_value *v)
Test if a given property value is a string property value.
Definition: abg-ini.cc:341
tuple_property * is_tuple_property(const property *p)
Test if an instance of property is an instance of tuple_property.
Definition: abg-ini.cc:757
shared_ptr< tuple_property_value > tuple_property_value_sptr
Convenience typedef for a shared_ptr to a tuple_property_value.
Definition: abg-ini.h:170
simple_property * is_simple_property(const property *p)
Tests if a property is a simple property.
Definition: abg-ini.cc:619
tuple_property_value * is_tuple_property_value(const property_value *v)
Test if a given instance of property_value is an instance of tuple_property_value too.
Definition: abg-ini.cc:525
bool write_sections(const config::sections_type &sections, std::ostream &out)
Serialize a vector of sections that make up an ini config file to an output stream.
Definition: abg-ini.cc:1882
Toplevel namespace for libabigail.