sbuild  1.5.3
sbuild-basic-keyfile.h
00001 /* Copyright © 2005-2009  Roger Leigh <rleigh@debian.org>
00002  *
00003  * schroot is free software: you can redistribute it and/or modify it
00004  * under the terms of the GNU General Public License as published by
00005  * the Free Software Foundation, either version 3 of the License, or
00006  * (at your option) any later version.
00007  *
00008  * schroot is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011  * General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see
00015  * <http://www.gnu.org/licenses/>.
00016  *
00017  *********************************************************************/
00018 
00019 #ifndef SBUILD_BASIC_KEYFILE_H
00020 #define SBUILD_BASIC_KEYFILE_H
00021 
00022 #include <sbuild/sbuild-i18n.h>
00023 #include <sbuild/sbuild-log.h>
00024 #include <sbuild/sbuild-keyfile-base.h>
00025 #include <sbuild/sbuild-parse-error.h>
00026 #include <sbuild/sbuild-parse-value.h>
00027 #include <sbuild/sbuild-types.h>
00028 #include <sbuild/sbuild-tr1types.h>
00029 #include <sbuild/sbuild-util.h>
00030 
00031 #include <cassert>
00032 #include <map>
00033 #include <string>
00034 #include <sstream>
00035 
00036 #include <boost/format.hpp>
00037 
00038 namespace sbuild
00039 {
00043   template <typename K>
00044   class basic_keyfile_parser
00045   {
00046   public:
00048     typedef keyfile_base::error error;
00049 
00051     basic_keyfile_parser ():
00052       group(),
00053       group_set(false),
00054       key(),
00055       key_set(false),
00056       value(),
00057       value_set(false),
00058       comment(),
00059       comment_set(false),
00060       line_number(0)
00061     {
00062     }
00063 
00065     virtual ~basic_keyfile_parser ()
00066     {
00067     }
00068 
00070     typename K::group_name_type group;
00071 
00073     bool                        group_set;
00074 
00076     typename K::key_type        key;
00077 
00079     bool                        key_set;
00080 
00082     typename K::value_type      value;
00083 
00085     bool                        value_set;
00086 
00088     typename K::comment_type    comment;
00089 
00091     bool                        comment_set;
00092 
00094     typename K::size_type       line_number;
00095 
00100     virtual void
00101     begin ()
00102     {
00103       line_number = 0;
00104     }
00105 
00116     virtual void
00117     parse_line (std::string const& line)
00118     {
00119       ++line_number;
00120     }
00121 
00126     virtual void
00127     end()
00128     {
00129     }
00130   };
00131 
00137   template <typename K, typename P = basic_keyfile_parser<K> >
00138   class basic_keyfile : public keyfile_base
00139   {
00140   public:
00142     typedef typename K::group_name_type group_name_type;
00143 
00145     typedef typename K::key_type key_type;
00146 
00148     typedef typename K::value_type value_type;
00149 
00151     typedef typename K::comment_type comment_type;
00152 
00154     typedef typename K::size_type size_type;
00155 
00157     typedef std::vector<group_name_type> group_list;
00158 
00160     typedef std::vector<value_type> value_list;
00161 
00162   private:
00164     typedef P parse_type;
00165 
00167     typedef std::tuple<key_type,value_type,comment_type,size_type>
00168     item_type;
00169 
00171     typedef std::map<key_type,item_type> item_map_type;
00172 
00174     typedef std::tuple<group_name_type,item_map_type,comment_type,size_type> group_type;
00175 
00177     typedef std::map<group_name_type,group_type> group_map_type;
00178 
00180     typedef std::vector<key_type> key_list;
00181 
00182   public:
00184     basic_keyfile ();
00185 
00191     basic_keyfile (std::string const& file);
00192 
00198     basic_keyfile (std::istream& stream);
00199 
00201     virtual ~basic_keyfile ();
00202 
00209     group_list
00210     get_groups () const;
00211 
00219     key_list
00220     get_keys (group_name_type const& group) const;
00221 
00230     void
00231     check_keys (group_name_type const& group,
00232                 key_list const&        keys) const;
00233 
00240     bool
00241     has_group (group_name_type const& group) const;
00242 
00250     bool
00251     has_key (group_name_type const& group,
00252              key_type const&        key) const;
00253 
00261     void
00262     set_group (group_name_type const& group,
00263                comment_type const&    comment);
00264 
00273     void
00274     set_group (group_name_type const& group,
00275                comment_type const&    comment,
00276                size_type              line);
00277 
00284     comment_type
00285     get_comment (group_name_type const& group) const;
00286 
00294     comment_type
00295     get_comment (group_name_type const& group,
00296                  key_type const&        key) const;
00297 
00304     size_type
00305     get_line (group_name_type const& group) const;
00306 
00314     size_type
00315     get_line (group_name_type const& group,
00316               key_type const&        key) const;
00317 
00328     template <typename T>
00329     bool
00330     get_value (group_name_type const& group,
00331                key_type const&        key,
00332                T&                     value) const
00333     {
00334       log_debug(DEBUG_INFO) << "Getting keyfile group=" << group
00335                             << ", key=" << key << std::endl;
00336       const item_type *found_item = find_item(group, key);
00337       if (found_item)
00338         {
00339           value_type const& strval(std::get<1>(*found_item));
00340           try
00341             {
00342               parse_value(strval, value);
00343               return true;
00344             }
00345           catch (parse_value_error const& e)
00346             {
00347               size_type line = get_line(group, key);
00348               if (line)
00349                 {
00350                   error ep(line, group, key, PASSTHROUGH_LGK, e);
00351                   log_exception_warning(ep);
00352                 }
00353               else
00354                 {
00355                   error ep(group, key, PASSTHROUGH_GK, e);
00356                   log_exception_warning(ep);
00357                 }
00358               return false;
00359             }
00360         }
00361       log_debug(DEBUG_NOTICE) << "key not found" << std::endl;
00362       return false;
00363     }
00364 
00377     template <typename T>
00378     bool
00379     get_value (group_name_type const& group,
00380                key_type const&        key,
00381                priority               priority,
00382                T&                     value) const
00383     {
00384       bool status = get_value(group, key, value);
00385       check_priority(group, key, priority, status);
00386       return status;
00387     }
00388 
00398     bool
00399     get_locale_string (group_name_type const& group,
00400                        key_type const&        key,
00401                        value_type&            value) const;
00402 
00414     bool
00415     get_locale_string (group_name_type const& group,
00416                        key_type const&        key,
00417                        priority               priority,
00418                        value_type&            value) const;
00419 
00430     bool
00431     get_locale_string (group_name_type const& group,
00432                        key_type const&        key,
00433                        std::string const&     locale,
00434                        value_type&            value) const;
00435 
00449     bool
00450     get_locale_string (group_name_type const& group,
00451                        key_type const&        key,
00452                        std::string const&     locale,
00453                        priority               priority,
00454                        value_type&            value) const;
00455 
00468     template <typename C>
00469     bool
00470     get_list_value (group_name_type const& group,
00471                     key_type const&        key,
00472                     C&                     container) const
00473     {
00474       value_type item_value;
00475       if (get_value(group, key, item_value))
00476         {
00477           value_list items = split_string(item_value,
00478                                           this->separator);
00479           for (typename value_list::const_iterator pos = items.begin();
00480                pos != items.end();
00481                ++pos
00482                )
00483             {
00484               typename C::value_type tmp;
00485 
00486               try
00487                 {
00488                   parse_value(*pos, tmp);
00489                 }
00490               catch (parse_value_error const& e)
00491                 {
00492                   size_type line = get_line(group, key);
00493                   if (line)
00494                     {
00495                       error ep(line, group, key, PASSTHROUGH_LGK, e);
00496                       log_exception_warning(ep);
00497                     }
00498                   else
00499                     {
00500                       error ep(group, key, PASSTHROUGH_GK, e);
00501                       log_exception_warning(ep);
00502                     }
00503                   return false;
00504                 }
00505 
00506               container.push_back(tmp);
00507             }
00508           return true;
00509         }
00510       return false;
00511     }
00512 
00527     template <typename C>
00528     bool
00529     get_list_value (group_name_type const& group,
00530                     key_type const&        key,
00531                     priority               priority,
00532                     C&                     container) const
00533     {
00534       bool status = get_list_value(group, key, container);
00535       check_priority(group, key, priority, status);
00536       return status;
00537     }
00538 
00551     template <typename C>
00552     bool
00553     get_set_value (group_name_type const& group,
00554                    key_type const&        key,
00555                    C&                     container) const
00556     {
00557       value_type item_value;
00558       if (get_value(group, key, item_value))
00559         {
00560           value_list items = split_string(item_value,
00561                                           this->separator);
00562           for (typename value_list::const_iterator pos = items.begin();
00563                pos != items.end();
00564                ++pos
00565                )
00566             {
00567               typename C::value_type tmp;
00568 
00569               try
00570                 {
00571                   parse_value(*pos, tmp);
00572                 }
00573               catch (parse_value_error const& e)
00574                 {
00575                   size_type line = get_line(group, key);
00576                   if (line)
00577                     {
00578                       error ep(line, group, key, PASSTHROUGH_LGK, e);
00579                       log_exception_warning(ep);
00580                     }
00581                   else
00582                     {
00583                       error ep(group, key, PASSTHROUGH_GK, e);
00584                       log_exception_warning(ep);
00585                     }
00586                   return false;
00587                 }
00588 
00589               container.insert(tmp);
00590             }
00591           return true;
00592         }
00593       return false;
00594     }
00595 
00610     template <typename C>
00611     bool
00612     get_set_value (group_name_type const& group,
00613                    key_type const&        key,
00614                    priority               priority,
00615                    C&                     container) const
00616     {
00617       bool status = get_set_value(group, key, container);
00618       check_priority(group, key, priority, status);
00619       return status;
00620     }
00621 
00630     template <typename T>
00631     void
00632     set_value (group_name_type const& group,
00633                key_type const&        key,
00634                T const&               value)
00635     {
00636       set_value(group, key, value, comment_type());
00637     }
00638 
00648     template <typename T>
00649     void
00650     set_value (group_name_type const& group,
00651                key_type const&        key,
00652                T const&               value,
00653                comment_type const&    comment)
00654     {
00655       set_value(group, key, value, comment, 0);
00656     }
00657 
00668     template <typename T>
00669     void
00670     set_value (group_name_type const& group,
00671                key_type const&        key,
00672                T const&               value,
00673                comment_type const&    comment,
00674                size_type              line)
00675     {
00676       std::ostringstream os;
00677       os.imbue(std::locale::classic());
00678       os << std::boolalpha << value;
00679 
00680       set_group(group, "");
00681       group_type *found_group = find_group(group);
00682       assert (found_group != 0); // should not fail
00683 
00684       item_map_type& items = std::get<1>(*found_group);
00685 
00686       typename item_map_type::iterator pos = items.find(key);
00687       if (pos != items.end())
00688         items.erase(pos);
00689       items.insert
00690         (typename item_map_type::value_type(key,
00691                                             item_type(key, os.str(),
00692                                                       comment, line)));
00693     }
00694 
00704     template <typename I>
00705     void
00706     set_list_value (group_name_type const& group,
00707                     key_type const&        key,
00708                     I                      begin,
00709                     I                      end)
00710     {
00711       set_list_value(group, key, begin, end, comment_type());
00712     }
00713 
00724     template <typename I>
00725     void
00726     set_list_value (group_name_type const& group,
00727                     key_type const&        key,
00728                     I                      begin,
00729                     I                      end,
00730                     comment_type const&    comment)
00731     {
00732       set_list_value (group, key, begin, end, comment, 0);
00733     }
00734 
00746     template <typename I>
00747     void
00748     set_list_value (group_name_type const& group,
00749                     key_type const&        key,
00750                     I                      begin,
00751                     I                      end,
00752                     comment_type const&    comment,
00753                     size_type              line)
00754     {
00755       value_type strval;
00756 
00757       for (I pos = begin; pos != end;)
00758         {
00759           std::ostringstream os;
00760           os.imbue(std::locale::classic());
00761           os << std::boolalpha << *pos;
00762           if (os)
00763             {
00764               strval += os.str();
00765               if (++pos != end)
00766                 strval += this->separator;
00767             }
00768         }
00769 
00770       set_value (group, key, strval, comment, line);
00771     }
00772 
00782     template <typename I>
00783     void
00784     set_set_value (group_name_type const& group,
00785                    key_type const&        key,
00786                    I                      begin,
00787                    I                      end)
00788     {
00789       std::vector<typename std::iterator_traits<I>::value_type> l(begin, end);
00790       std::sort(l.begin(), l.end());
00791       set_list_value(group, key, l.begin(), l.end());
00792     }
00793 
00804     template <typename I>
00805     void
00806     set_set_value (group_name_type const& group,
00807                    key_type const&        key,
00808                    I                      begin,
00809                    I                      end,
00810                    comment_type const&    comment)
00811     {
00812       std::vector<typename std::iterator_traits<I>::value_type> l(begin, end);
00813       std::sort(l.begin(), l.end());
00814       set_list_value(group, key, l.begin(), l.end(), comment);
00815     }
00816 
00828     template <typename I>
00829     void
00830     set_set_value (group_name_type const& group,
00831                    key_type const&        key,
00832                    I                      begin,
00833                    I                      end,
00834                    comment_type const&    comment,
00835                    size_type              line)
00836     {
00837       std::vector<typename std::iterator_traits<I>::value_type> l(begin, end);
00838       std::sort(l.begin(), l.end());
00839       set_list_value(group, key, l.begin(), l.end(), comment, line);
00840     }
00841 
00847     void
00848     remove_group (group_name_type const& group);
00849 
00856     void
00857     remove_key (group_name_type const& group,
00858                 key_type const&        key);
00859 
00866     basic_keyfile&
00867     operator += (basic_keyfile const& rhs);
00868 
00876     template <typename _K, typename _P>
00877     friend basic_keyfile<_K, _P>
00878     operator + (basic_keyfile<_K, _P> const& lhs,
00879                 basic_keyfile<_K, _P> const& rhs);
00880 
00888     template <class charT, class traits>
00889     friend
00890     std::basic_istream<charT,traits>&
00891     operator >> (std::basic_istream<charT,traits>& stream,
00892                  basic_keyfile&                    kf)
00893     {
00894       basic_keyfile tmp;
00895       parse_type state;
00896       std::string line;
00897 
00898       state.begin();
00899 
00900       while (std::getline(stream, line))
00901       {
00902         state.parse_line(line);
00903 
00904         // Insert group
00905         if (state.group_set)
00906           {
00907             if (tmp.has_group(state.group))
00908               throw error(state.line_number, DUPLICATE_GROUP, state.group);
00909             else
00910               tmp.set_group(state.group, state.comment, state.line_number);
00911           }
00912 
00913         // Insert item
00914         if (state.key_set && state.value_set)
00915           {
00916             if (tmp.has_key(state.group, state.key))
00917               throw error(state.line_number, state.group, DUPLICATE_KEY, state.key);
00918             else
00919               tmp.set_value(state.group, state.key, state.value, state.comment, state.line_number);
00920           }
00921       }
00922 
00923       state.end();
00924       // TODO: do inserts here as well.
00925 
00926       kf += tmp;
00927 
00928       return stream;
00929     }
00930 
00938     template <class charT, class traits>
00939     friend
00940     std::basic_ostream<charT,traits>&
00941     operator << (std::basic_ostream<charT,traits>& stream,
00942                  basic_keyfile const&              kf)
00943     {
00944       size_type group_count = 0;
00945 
00946       for (typename group_map_type::const_iterator gp = kf.groups.begin();
00947            gp != kf.groups.end();
00948            ++gp, ++group_count)
00949         {
00950           if (group_count > 0)
00951             stream << '\n';
00952 
00953           group_type const& group = gp->second;
00954           group_name_type const& groupname = std::get<0>(group);
00955           comment_type const& comment = std::get<2>(group);
00956 
00957           if (comment.length() > 0)
00958             print_comment(comment, stream);
00959 
00960           stream << '[' << groupname << ']' << '\n';
00961 
00962           item_map_type const& items(std::get<1>(group));
00963           for (typename item_map_type::const_iterator it = items.begin();
00964                it != items.end();
00965                ++it)
00966             {
00967               item_type const& item = it->second;
00968               key_type const& key(std::get<0>(item));
00969               value_type const& value(std::get<1>(item));
00970               comment_type const& comment(std::get<2>(item));
00971 
00972               if (comment.length() > 0)
00973                 print_comment(comment, stream);
00974 
00975               stream << key << '=' << value << '\n';
00976             }
00977         }
00978 
00979       return stream;
00980     }
00981 
00982   private:
00989     const group_type *
00990     find_group (group_name_type const& group) const;
00991 
00998     group_type *
00999     find_group (group_name_type const& group);
01000 
01008     const item_type *
01009     find_item (group_name_type const& group,
01010                key_type const&        key) const;
01011 
01019     item_type *
01020     find_item (group_name_type const& group,
01021                key_type const&        key);
01022 
01031     void
01032     check_priority (group_name_type const& group,
01033                     key_type const&        key,
01034                     priority               priority,
01035                     bool                   valid) const;
01036 
01048     static void
01049     print_comment (comment_type const& comment,
01050                    std::ostream&       stream);
01051 
01053     group_map_type groups;
01055     value_type     separator;
01056 
01057   public:
01070     template<class C, typename T>
01071     static void
01072     set_object_value (C const&               object,
01073                       T                (C::* method)() const,
01074                       basic_keyfile&         basic_keyfile,
01075                       group_name_type const& group,
01076                       key_type const&        key)
01077     {
01078       try
01079         {
01080           if (method)
01081             basic_keyfile.set_value(group, key, (object.*method)());
01082         }
01083       catch (std::runtime_error const& e)
01084         {
01085           throw error(group, key, PASSTHROUGH_GK, e);
01086         }
01087     }
01088 
01101     template<class C, typename T>
01102     static void
01103     set_object_value (C const&               object,
01104                       T const&         (C::* method)() const,
01105                       basic_keyfile&         basic_keyfile,
01106                       group_name_type const& group,
01107                       key_type const&        key)
01108     {
01109       try
01110         {
01111           if (method)
01112             basic_keyfile.set_value(group, key, (object.*method)());
01113         }
01114       catch (std::runtime_error const& e)
01115         {
01116           throw error(group, key, PASSTHROUGH_GK, e);
01117         }
01118     }
01119 
01133     template<class C, typename T>
01134     static void
01135     set_object_list_value (C const&               object,
01136                            T                (C::* method)() const,
01137                            basic_keyfile&         basic_keyfile,
01138                            group_name_type const& group,
01139                            key_type const&        key)
01140     {
01141       try
01142         {
01143           if (method)
01144             basic_keyfile.set_list_value(group, key,
01145                                          (object.*method)().begin(),
01146                                          (object.*method)().end());
01147         }
01148       catch (std::runtime_error const& e)
01149         {
01150           throw error(group, key, PASSTHROUGH_GK, e);
01151         }
01152     }
01153 
01168     template<class C, typename T>
01169     static void
01170     set_object_list_value (C const&               object,
01171                            T const&         (C::* method)() const,
01172                            basic_keyfile&         basic_keyfile,
01173                            group_name_type const& group,
01174                            key_type const&        key)
01175     {
01176       try
01177         {
01178           if (method)
01179             basic_keyfile.set_list_value(group, key,
01180                                          (object.*method)().begin(),
01181                                          (object.*method)().end());
01182         }
01183       catch (std::runtime_error const& e)
01184         {
01185           throw error(group, key, PASSTHROUGH_GK, e);
01186         }
01187     }
01188 
01202     template<class C, typename T>
01203     static void
01204     set_object_set_value (C const&               object,
01205                           T                (C::* method)() const,
01206                           basic_keyfile&         basic_keyfile,
01207                           group_name_type const& group,
01208                           key_type const&        key)
01209     {
01210       try
01211         {
01212           if (method)
01213             basic_keyfile.set_set_value(group, key,
01214                                         (object.*method)().begin(),
01215                                         (object.*method)().end());
01216         }
01217       catch (std::runtime_error const& e)
01218         {
01219           throw error(group, key, PASSTHROUGH_GK, e);
01220         }
01221     }
01222 
01237     template<class C, typename T>
01238     static void
01239     set_object_set_value (C const&               object,
01240                           T const&         (C::* method)() const,
01241                           basic_keyfile&         basic_keyfile,
01242                           group_name_type const& group,
01243                           key_type const&        key)
01244     {
01245       try
01246         {
01247           if (method)
01248             basic_keyfile.set_set_value(group, key,
01249                                         (object.*method)().begin(),
01250                                         (object.*method)().end());
01251         }
01252       catch (std::runtime_error const& e)
01253         {
01254           throw error(group, key, PASSTHROUGH_GK, e);
01255         }
01256     }
01257 
01272     template<class C, typename T>
01273     static void
01274     get_object_value (C&                      object,
01275                       void              (C::* method)(T param),
01276                       basic_keyfile const&    basic_keyfile,
01277                       group_name_type const&  group,
01278                       key_type const&         key,
01279                       basic_keyfile::priority priority)
01280     {
01281       try
01282         {
01283           T value;
01284           if (basic_keyfile.get_value(group, key, priority, value)
01285               && method)
01286             (object.*method)(value);
01287         }
01288       catch (std::runtime_error const& e)
01289         {
01290           size_type line = basic_keyfile.get_line(group, key);
01291           if (line)
01292             throw error(line, group, key, PASSTHROUGH_LGK, e);
01293           else
01294             throw error(group, key, PASSTHROUGH_GK, e);
01295         }
01296     }
01297 
01312     template<class C, typename T>
01313     static void
01314     get_object_value (C&                      object,
01315                       void              (C::* method)(T const& param),
01316                       basic_keyfile const&    basic_keyfile,
01317                       group_name_type const&  group,
01318                       key_type const&         key,
01319                       basic_keyfile::priority priority)
01320     {
01321       try
01322         {
01323           T value;
01324           if (basic_keyfile.get_value(group, key, priority, value)
01325               && method)
01326             (object.*method)(value);
01327         }
01328       catch (std::runtime_error const& e)
01329         {
01330           size_type line = basic_keyfile.get_line(group, key);
01331           if (line)
01332             throw error(line, group, key, PASSTHROUGH_LGK, e);
01333           else
01334             throw error(group, key, PASSTHROUGH_GK, e);
01335         }
01336     }
01337 
01352     template<class C, typename T>
01353     static void
01354     get_object_list_value (C&                      object,
01355                            void              (C::* method)(T param),
01356                            basic_keyfile const&    basic_keyfile,
01357                            group_name_type const&  group,
01358                            key_type const&         key,
01359                            basic_keyfile::priority priority)
01360     {
01361       try
01362         {
01363           T value;
01364           if (basic_keyfile.get_list_value(group, key, priority, value)
01365               && method)
01366             (object.*method)(value);
01367         }
01368       catch (std::runtime_error const& e)
01369         {
01370           size_type line = basic_keyfile.get_line(group, key);
01371           if (line)
01372             throw error(line, group, key, PASSTHROUGH_LGK, e);
01373           else
01374             throw error(group, key, PASSTHROUGH_GK, e);
01375           throw error(basic_keyfile.get_line(group, key),
01376                       group, key, e);
01377         }
01378     }
01379 
01395     template<class C, typename T>
01396     static void
01397     get_object_list_value (C&                      object,
01398                            void              (C::* method)(T const& param),
01399                            basic_keyfile const&    basic_keyfile,
01400                            group_name_type const&  group,
01401                            key_type const&         key,
01402                            basic_keyfile::priority priority)
01403     {
01404       try
01405         {
01406           T value;
01407           if (basic_keyfile.get_list_value(group, key, priority, value)
01408               && method)
01409             (object.*method)(value);
01410         }
01411       catch (std::runtime_error const& e)
01412         {
01413           size_type line = basic_keyfile.get_line(group, key);
01414           if (line)
01415             throw error(line, group, key, PASSTHROUGH_LGK, e);
01416           else
01417             throw error(group, key, PASSTHROUGH_GK, e);
01418           throw error(basic_keyfile.get_line(group, key),
01419                       group, key, e);
01420         }
01421     }
01422 
01437     template<class C, typename T>
01438     static void
01439     get_object_set_value (C&                      object,
01440                           void              (C::* method)(T param),
01441                           basic_keyfile const&    basic_keyfile,
01442                           group_name_type const&  group,
01443                           key_type const&         key,
01444                           basic_keyfile::priority priority)
01445     {
01446       try
01447         {
01448           T value;
01449           if (basic_keyfile.get_set_value(group, key, priority, value)
01450               && method)
01451             (object.*method)(value);
01452         }
01453       catch (std::runtime_error const& e)
01454         {
01455           size_type line = basic_keyfile.get_line(group, key);
01456           if (line)
01457             throw error(line, group, key, PASSTHROUGH_LGK, e);
01458           else
01459             throw error(group, key, PASSTHROUGH_GK, e);
01460           throw error(basic_keyfile.get_line(group, key),
01461                       group, key, e);
01462         }
01463     }
01464 
01480     template<class C, typename T>
01481     static void
01482     get_object_set_value (C&                      object,
01483                           void              (C::* method)(T const& param),
01484                           basic_keyfile const&    basic_keyfile,
01485                           group_name_type const&  group,
01486                           key_type const&         key,
01487                           basic_keyfile::priority priority)
01488     {
01489       try
01490         {
01491           T value;
01492           if (basic_keyfile.get_set_value(group, key, priority, value)
01493               && method)
01494             (object.*method)(value);
01495         }
01496       catch (std::runtime_error const& e)
01497         {
01498           size_type line = basic_keyfile.get_line(group, key);
01499           if (line)
01500             throw error(line, group, key, PASSTHROUGH_LGK, e);
01501           else
01502             throw error(group, key, PASSTHROUGH_GK, e);
01503           throw error(basic_keyfile.get_line(group, key),
01504                       group, key, e);
01505         }
01506     }
01507   };
01508 
01509 }
01510 
01511 #include <sbuild/sbuild-basic-keyfile.tcc>
01512 
01513 #endif /* SBUILD_BASIC_KEYFILE_H */
01514 
01515 /*
01516  * Local Variables:
01517  * mode:C++
01518  * End:
01519  */