LCOV - code coverage report
Current view: top level - lang/cpp/src - configuration.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 197 375 52.5 %
Date: 2018-11-15 08:49:49 Functions: 40 71 56.3 %

          Line data    Source code
       1             : /*
       2             :   configuration.cpp - wraps gpgme configuration components
       3             :   Copyright (C) 2010 Klarälvdalens Datakonsult AB
       4             :   2016 Bundesamt für Sicherheit in der Informationstechnik
       5             :   Software engineering by Intevation GmbH
       6             : 
       7             :   This file is part of GPGME++.
       8             : 
       9             :   GPGME++ is free software; you can redistribute it and/or
      10             :   modify it under the terms of the GNU Library General Public
      11             :   License as published by the Free Software Foundation; either
      12             :   version 2 of the License, or (at your option) any later version.
      13             : 
      14             :   GPGME++ is distributed in the hope that it will be useful,
      15             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :   GNU Library General Public License for more details.
      18             : 
      19             :   You should have received a copy of the GNU Library General Public License
      20             :   along with GPGME++; see the file COPYING.LIB.  If not, write to the
      21             :   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      22             :   Boston, MA 02110-1301, USA.
      23             : */
      24             : 
      25             : #ifdef HAVE_CONFIG_H
      26             :  #include "config.h"
      27             : #endif
      28             : 
      29             : #include "configuration.h"
      30             : #include "error.h"
      31             : #include "util.h"
      32             : 
      33             : #include <gpgme.h>
      34             : 
      35             : #include <iterator>
      36             : #include <algorithm>
      37             : #include <ostream>
      38             : #include <cstring>
      39             : #include <assert.h>
      40             : 
      41             : using namespace GpgME;
      42             : using namespace GpgME::Configuration;
      43             : 
      44             : typedef std::shared_ptr< std::remove_pointer<gpgme_conf_opt_t>::type > shared_gpgme_conf_opt_t;
      45             : typedef std::weak_ptr< std::remove_pointer<gpgme_conf_opt_t>::type > weak_gpgme_conf_opt_t;
      46             : 
      47             : typedef std::shared_ptr< std::remove_pointer<gpgme_conf_arg_t>::type > shared_gpgme_conf_arg_t;
      48             : typedef std::weak_ptr< std::remove_pointer<gpgme_conf_arg_t>::type > weak_gpgme_conf_arg_t;
      49             : 
      50             : typedef std::shared_ptr< std::remove_pointer<gpgme_ctx_t>::type > shared_gpgme_ctx_t;
      51             : typedef std::weak_ptr< std::remove_pointer<gpgme_ctx_t>::type > weak_gpgme_ctx_t;
      52             : 
      53             : namespace
      54             : {
      55             : struct nodelete {
      56             :     template <typename T> void operator()(T *) {}
      57             : };
      58             : }
      59             : 
      60             : // static
      61          23 : std::vector<Component> Component::load(Error &returnedError)
      62             : {
      63             : 
      64             :     //
      65             :     // 1. get a context:
      66             :     //
      67          23 :     gpgme_ctx_t ctx_native = 0;
      68          23 :     if (const gpgme_error_t err = gpgme_new(&ctx_native)) {
      69           0 :         returnedError = Error(err);
      70           0 :         return std::vector<Component>();
      71             :     }
      72          46 :     const shared_gpgme_ctx_t ctx(ctx_native, &gpgme_release);
      73             : 
      74             :     //
      75             :     // 2. load the config:
      76             :     //
      77          23 :     gpgme_conf_comp_t conf_list_native = 0;
      78          23 :     if (const gpgme_error_t err = gpgme_op_conf_load(ctx_native, &conf_list_native)) {
      79           0 :         returnedError = Error(err);
      80           0 :         return std::vector<Component>();
      81             :     }
      82          46 :     shared_gpgme_conf_comp_t head(conf_list_native, &gpgme_conf_release);
      83             : 
      84             :     //
      85             :     // 3. convert to vector<Component>:
      86             :     //
      87          46 :     std::vector<Component> result;
      88             : 
      89         299 :     while (head) {
      90             :         // secure 'head->next' (if any) against memleaks:
      91         276 :         shared_gpgme_conf_comp_t next;
      92         138 :         if (head->next) {
      93         115 :             next.reset(head->next, &gpgme_conf_release);
      94             :         }
      95             : 
      96             :         // now prevent double-free of next.get() and following:
      97         138 :         head->next = 0;
      98             : 
      99             :         // now add a new Component to 'result' (may throw):
     100         138 :         result.resize(result.size() + 1);
     101         138 :         result.back().comp.swap(head);   // .comp = std::move( head );
     102         138 :         head.swap(next);                 //  head = std::move( next );
     103             :     }
     104             : 
     105          23 :     return result;
     106             : }
     107             : 
     108         132 : Error Component::save() const
     109             : {
     110             : 
     111         132 :     if (isNull()) {
     112           0 :         return Error(make_error(GPG_ERR_INV_ARG));
     113             :     }
     114             : 
     115             :     //
     116             :     // 1. get a context:
     117             :     //
     118         132 :     gpgme_ctx_t ctx_native = 0;
     119         132 :     if (const gpgme_error_t err = gpgme_new(&ctx_native)) {
     120           0 :         return Error(err);
     121             :     }
     122         264 :     const shared_gpgme_ctx_t ctx(ctx_native, &gpgme_release);
     123             : 
     124             :     //
     125             :     // 2. save the config:
     126             :     //
     127         132 :     return Error(gpgme_op_conf_save(ctx.get(), comp.get()));
     128             : }
     129             : 
     130         276 : const char *Component::name() const
     131             : {
     132         276 :     return comp ? comp->name : 0 ;
     133             : }
     134             : 
     135         138 : const char *Component::description() const
     136             : {
     137         138 :     return comp ? comp->description : 0 ;
     138             : }
     139             : 
     140         138 : const char *Component::programName() const
     141             : {
     142         138 :     return comp ? comp->program_name : 0 ;
     143             : }
     144             : 
     145           0 : Option Component::option(unsigned int idx) const
     146             : {
     147           0 :     gpgme_conf_opt_t opt = 0;
     148           0 :     if (comp) {
     149           0 :         opt = comp->options;
     150             :     }
     151           0 :     while (opt && idx) {
     152           0 :         opt = opt->next;
     153           0 :         --idx;
     154             :     }
     155           0 :     if (opt) {
     156           0 :         return Option(comp, opt);
     157             :     }
     158           0 :     return Option();
     159             : }
     160             : 
     161           0 : Option Component::option(const char *name) const
     162             : {
     163           0 :     gpgme_conf_opt_t opt = 0;
     164           0 :     if (comp) {
     165           0 :         opt = comp->options;
     166             :     }
     167             :     using namespace std; // for strcmp
     168           0 :     while (opt && strcmp(name, opt->name) != 0) {
     169           0 :         opt = opt->next;
     170             :     }
     171           0 :     if (opt) {
     172           0 :         return Option(comp, opt);
     173             :     }
     174           0 :     return Option();
     175             : }
     176             : 
     177           0 : unsigned int Component::numOptions() const
     178             : {
     179           0 :     unsigned int result = 0;
     180           0 :     for (gpgme_conf_opt_t opt = comp ? comp->options : 0 ; opt ; opt = opt->next) {
     181           0 :         ++result;
     182             :     }
     183           0 :     return result;
     184             : }
     185             : 
     186         276 : std::vector<Option> Component::options() const
     187             : {
     188         276 :     std::vector<Option> result;
     189        6164 :     for (gpgme_conf_opt_t opt = comp ? comp->options : 0 ; opt ; opt = opt->next) {
     190        5888 :         result.push_back(Option(comp, opt));
     191             :     }
     192         276 :     return result;
     193             : }
     194             : 
     195       14753 : static gpgme_conf_arg_t mygpgme_conf_arg_copy(gpgme_conf_arg_t other, gpgme_conf_type_t type)
     196             : {
     197       14753 :     gpgme_conf_arg_t result = 0, last = 0;
     198       15993 :     for (gpgme_conf_arg_t a = other ; a ; a = a->next) {
     199        1240 :         gpgme_conf_arg_t arg = 0;
     200             :         const gpgme_error_t err
     201        2480 :             = gpgme_conf_arg_new(&arg, type,
     202        2480 :                                  a->no_arg                 ? 0 :
     203             :                                  type == GPGME_CONF_STRING ? a->value.string :
     204        1240 :                                  /* else */                  static_cast<void *>(&a->value));
     205        1240 :         if (err) {
     206           0 :             gpgme_conf_arg_release(result, type);
     207           0 :             return 0;
     208             :         }
     209        1240 :         assert(arg);
     210        1240 :         if (result) {
     211           0 :             last->next = arg;
     212             :         } else {
     213        1240 :             result = arg;
     214             :         }
     215        1240 :         last = arg;
     216             :     }
     217       14753 :     return result;
     218             : }
     219             : 
     220           0 : Component Option::parent() const
     221             : {
     222           0 :     return Component(comp.lock());
     223             : }
     224             : 
     225       20661 : unsigned int Option::flags() const
     226             : {
     227       20661 :     return isNull() ? 0 : opt->flags;
     228             : }
     229             : 
     230        2944 : Level Option::level() const
     231             : {
     232        2944 :     return isNull() ? Internal : static_cast<Level>(opt->level) ;
     233             : }
     234             : 
     235        5888 : const char *Option::name() const
     236             : {
     237        5888 :     return isNull() ? 0 : opt->name ;
     238             : }
     239             : 
     240        2944 : const char *Option::description() const
     241             : {
     242        2944 :     return isNull() ? 0 : opt->description ;
     243             : }
     244             : 
     245        2944 : const char *Option::argumentName() const
     246             : {
     247        2944 :     return isNull() ? 0 : opt->argname ;
     248             : }
     249             : 
     250        2965 : Type Option::type() const
     251             : {
     252        2965 :     return isNull() ? NoType : static_cast<Type>(opt->type) ;
     253             : }
     254             : 
     255        4215 : Type Option::alternateType() const
     256             : {
     257        4215 :     return isNull() ? NoType : static_cast<Type>(opt->alt_type) ;
     258             : }
     259             : 
     260             : #if 0
     261             : static Option::Variant argument_to_variant(gpgme_conf_type_t type, bool list, gpgme_conf_arg_t arg)
     262             : {
     263             :     assert(arg);
     264             :     switch (type) {
     265             :     case GPGME_CONF_NONE:
     266             :         if (list) {
     267             :             // return the count (number of times set):
     268             :             return arg->value.count;
     269             :         } else {
     270             :             return none;
     271             :         }
     272             :     case GPGME_CONF_INT32:
     273             :         if (list) {
     274             :             std::vector<int> result;
     275             :             for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     276             :                 result.push_back(a->value.int32);
     277             :             }
     278             :             return result;
     279             :         } else {
     280             :             return arg->value.int32;
     281             :         }
     282             :     case GPGME_CONF_UINT32:
     283             :         if (list) {
     284             :             std::vector<unsigned int> result;
     285             :             for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     286             :                 result.push_back(a->value.uint32);
     287             :             }
     288             :             return result;
     289             :         } else {
     290             :             return arg->value.uint32;
     291             :         }
     292             :     case GPGME_CONF_FILENAME:
     293             :     case GPGME_CONF_LDAP_SERVER:
     294             :     case GPGME_CONF_KEY_FPR:
     295             :     case GPGME_CONF_PUB_KEY:
     296             :     case GPGME_CONF_SEC_KEY:
     297             :     case GPGME_CONF_ALIAS_LIST:
     298             :     // these should not happen in alt_type, but fall through
     299             :     case GPGME_CONF_STRING:
     300             :         if (list) {
     301             :             std::vector<const char *> result;
     302             :             for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     303             :                 result.push_back(a->value.string);
     304             :             }
     305             :             return result;
     306             :         } else {
     307             :             return arg->value.string;
     308             :         }
     309             :     }
     310             :     assert(!"Option: unknown alt_type!");
     311             :     return Option::Variant();
     312             : }
     313             : 
     314             : namespace
     315             : {
     316             : inline const void *to_void_star(const char *s)
     317             : {
     318             :     return s;
     319             : }
     320             : inline const void *to_void_star(const std::string &s)
     321             : {
     322             :     return s.c_str();
     323             : }
     324             : inline const void *to_void_star(const int &i)
     325             : {
     326             :     return &i;    // const-&: sic!
     327             : }
     328             : inline const void *to_void_star(const unsigned int &i)
     329             : {
     330             :     return &i;    // const-&: sic!
     331             : }
     332             : 
     333             : struct VariantToArgumentVisitor : boost::static_visitor<gpgme_conf_arg_t> {
     334             :     static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value)
     335             :     {
     336             :         gpgme_conf_arg_t arg = 0;
     337             : #ifdef HAVE_GPGME_CONF_ARG_NEW_WITH_CONST_VALUE
     338             :         if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) {
     339             :             return 0;
     340             :         }
     341             : #else
     342             :         if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, const_cast<void *>(value))) {
     343             :             return 0;
     344             :         }
     345             : #endif
     346             :         else {
     347             :             return arg;
     348             :         }
     349             :     }
     350             : 
     351             :     gpgme_conf_arg_t operator()(bool v) const
     352             :     {
     353             :         return v ? make_argument(0) : 0 ;
     354             :     }
     355             : 
     356             :     gpgme_conf_arg_t operator()(const char *s) const
     357             :     {
     358             :         return make_argument(s ? s : "");
     359             :     }
     360             : 
     361             :     gpgme_conf_arg_t operator()(const std::string &s) const
     362             :     {
     363             :         return operator()(s.c_str());
     364             :     }
     365             : 
     366             :     gpgme_conf_arg_t operator()(int i) const
     367             :     {
     368             :         return make_argument(&i);
     369             :     }
     370             : 
     371             :     gpgme_conf_arg_t operator()(unsigned int i) const
     372             :     {
     373             :         return make_argument(&i);
     374             :     }
     375             : 
     376             :     template <typename T>
     377             :     gpgme_conf_arg_t operator()(const std::vector<T> &value) const
     378             :     {
     379             :         gpgme_conf_arg_t result = 0;
     380             :         gpgme_conf_arg_t last = 0;
     381             :         for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) {
     382             :             if (gpgme_conf_arg_t arg = make_argument(to_void_star(*it))) {
     383             :                 if (last) {
     384             :                     last = last->next = arg;
     385             :                 } else {
     386             :                     result = last = arg;
     387             :                 }
     388             :             }
     389             :         }
     390             :         return result;
     391             :     }
     392             : 
     393             : };
     394             : }
     395             : 
     396             : static gpgme_conf_arg_t variant_to_argument(const Option::Variant &value)
     397             : {
     398             :     VariantToArgumentVisitor v;
     399             :     return apply_visitor(v, value);
     400             : }
     401             : 
     402             : optional<Option::Variant> Option::defaultValue() const
     403             : {
     404             :     if (isNull()) {
     405             :         return optional<Variant>();
     406             :     } else {
     407             :         return argument_to_variant(opt->alt_type, opt->flags & GPGME_CONF_LIST, opt->default_value);
     408             :     }
     409             : }
     410             : #endif
     411             : 
     412        2944 : Argument Option::defaultValue() const
     413             : {
     414        2944 :     if (isNull()) {
     415           0 :         return Argument();
     416             :     } else {
     417        2944 :         return Argument(comp.lock(), opt, opt->default_value, false);
     418             :     }
     419             : }
     420             : 
     421        2944 : const char *Option::defaultDescription() const
     422             : {
     423        2944 :     return isNull() ? 0 : opt->default_description ;
     424             : }
     425             : 
     426        2944 : Argument Option::noArgumentValue() const
     427             : {
     428        2944 :     if (isNull()) {
     429           0 :         return Argument();
     430             :     } else {
     431        2944 :         return Argument(comp.lock(), opt, opt->no_arg_value, false);
     432             :     }
     433             : }
     434             : 
     435        2944 : const char *Option::noArgumentDescription() const
     436             : {
     437        2944 :     return isNull() ? 0 : opt->no_arg_description ;
     438             : }
     439             : 
     440        2944 : Argument Option::activeValue() const
     441             : {
     442        2944 :     if (isNull()) {
     443           0 :         return Argument();
     444             :     } else {
     445        2944 :         return Argument(comp.lock(), opt, opt->value, false);
     446             :     }
     447             : }
     448             : 
     449        2966 : Argument Option::currentValue() const
     450             : {
     451        2966 :     if (isNull()) {
     452           0 :         return Argument();
     453             :     }
     454             :     const gpgme_conf_arg_t arg =
     455        5932 :         opt->change_value ? opt->new_value ? opt->new_value : opt->default_value :
     456        5910 :         opt->value        ? opt->value :
     457        5910 :         /* else */          opt->default_value ;
     458        2966 :     return Argument(comp.lock(), opt, arg, false);
     459             : }
     460             : 
     461        2944 : Argument Option::newValue() const
     462             : {
     463        2944 :     if (isNull()) {
     464           0 :         return Argument();
     465             :     } else {
     466        2944 :         return Argument(comp.lock(), opt, opt->new_value, false);
     467             :     }
     468             : }
     469             : 
     470        2944 : bool Option::set() const
     471             : {
     472        2944 :     if (isNull()) {
     473           0 :         return false;
     474        2944 :     } else if (opt->change_value) {
     475           0 :         return opt->new_value;
     476             :     } else {
     477        2944 :         return opt->value;
     478             :     }
     479             : }
     480             : 
     481        2944 : bool Option::dirty() const
     482             : {
     483        2944 :     return !isNull() && opt->change_value ;
     484             : }
     485             : 
     486          11 : Error Option::setNewValue(const Argument &argument)
     487             : {
     488          11 :     if (isNull()) {
     489           0 :         return Error(make_error(GPG_ERR_INV_ARG));
     490          11 :     } else if (argument.isNull()) {
     491           0 :         return resetToDefaultValue();
     492          11 :     } else if (const gpgme_conf_arg_t arg = mygpgme_conf_arg_copy(argument.arg, opt->alt_type)) {
     493          11 :         return Error(gpgme_conf_opt_change(opt, 0, arg));
     494             :     } else {
     495           0 :         return Error(make_error(GPG_ERR_ENOMEM));
     496             :     }
     497             : }
     498             : 
     499           0 : Error Option::resetToActiveValue()
     500             : {
     501           0 :     if (isNull()) {
     502           0 :         return Error(make_error(GPG_ERR_INV_ARG));
     503             :     } else {
     504           0 :         return Error(gpgme_conf_opt_change(opt, 1, 0));
     505             :     }
     506             : }
     507             : 
     508          11 : Error Option::resetToDefaultValue()
     509             : {
     510          11 :     if (isNull()) {
     511           0 :         return Error(make_error(GPG_ERR_INV_ARG));
     512             :     } else {
     513          11 :         return Error(gpgme_conf_opt_change(opt, 0, 0));
     514             :     }
     515             : }
     516             : 
     517          11 : static gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const void *value)
     518             : {
     519          11 :     gpgme_conf_arg_t arg = 0;
     520          11 :     if (const gpgme_error_t err = gpgme_conf_arg_new(&arg, type, value)) {
     521           0 :         return 0;
     522             :     } else {
     523          11 :         return arg;
     524             :     }
     525             : }
     526             : 
     527           0 : Argument Option::createNoneArgument(bool set) const
     528             : {
     529           0 :     if (isNull() || alternateType() != NoType) {
     530           0 :         return Argument();
     531             :     } else {
     532           0 :         if (set) {
     533           0 :             return createNoneListArgument(1);
     534             :         }
     535             :     }
     536           0 :     return Argument();
     537             : }
     538             : 
     539          11 : Argument Option::createStringArgument(const char *value) const
     540             : {
     541          11 :     if (isNull() || alternateType() != StringType) {
     542           0 :         return Argument();
     543             :     } else {
     544          11 :         return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value), true);
     545             :     }
     546             : }
     547             : 
     548           0 : Argument Option::createStringArgument(const std::string &value) const
     549             : {
     550           0 :     if (isNull() || alternateType() != StringType) {
     551           0 :         return Argument();
     552             :     } else {
     553           0 :         return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value.c_str()), true);
     554             :     }
     555             : }
     556             : 
     557           0 : Argument Option::createIntArgument(int value) const
     558             : {
     559           0 :     if (isNull() || alternateType() != IntegerType) {
     560           0 :         return Argument();
     561             :     } else {
     562           0 :         return Argument(comp.lock(), opt, make_argument(GPGME_CONF_INT32, &value), true);
     563             :     }
     564             : }
     565             : 
     566           0 : Argument Option::createUIntArgument(unsigned int value) const
     567             : {
     568           0 :     if (isNull() || alternateType() != UnsignedIntegerType) {
     569           0 :         return Argument();
     570             :     } else {
     571           0 :         return Argument(comp.lock(), opt, make_argument(GPGME_CONF_UINT32, &value), true);
     572             :     }
     573             : }
     574             : 
     575             : namespace
     576             : {
     577           0 : const void *to_void_star(const char *s)
     578             : {
     579           0 :     return s;
     580             : }
     581           0 : const void *to_void_star(const std::string &s)
     582             : {
     583           0 :     return s.c_str();
     584             : }
     585           0 : const void *to_void_star(const int &i)
     586             : {
     587           0 :     return &i;    // const-&: sic!
     588             : }
     589           0 : const void *to_void_star(const unsigned int &i)
     590             : {
     591           0 :     return &i;    // const-&: sic!
     592             : }
     593             : 
     594             : template <typename T>
     595           0 : gpgme_conf_arg_t make_argument(gpgme_conf_type_t type, const std::vector<T> &value)
     596             : {
     597           0 :     gpgme_conf_arg_t result = 0;
     598           0 :     gpgme_conf_arg_t last = 0;
     599           0 :     for (typename std::vector<T>::const_iterator it = value.begin(), end = value.end() ; it != end ; ++it) {
     600           0 :         if (gpgme_conf_arg_t arg = make_argument(type, to_void_star(*it))) {
     601           0 :             if (last) {
     602           0 :                 last = last->next = arg;
     603             :             } else {
     604           0 :                 result = last = arg;
     605             :             }
     606             :         }
     607             :     }
     608           0 :     return result;
     609             : }
     610             : }
     611             : 
     612           0 : Argument Option::createNoneListArgument(unsigned int value) const
     613             : {
     614           0 :     if (value) {
     615           0 :         return Argument(comp.lock(), opt, make_argument(GPGME_CONF_NONE, &value), true);
     616             :     }
     617           0 :     return Argument();
     618             : }
     619             : 
     620           0 : Argument Option::createStringListArgument(const std::vector<const char *> &value) const
     621             : {
     622           0 :     return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value), true);
     623             : }
     624             : 
     625           0 : Argument Option::createStringListArgument(const std::vector<std::string> &value) const
     626             : {
     627           0 :     return Argument(comp.lock(), opt, make_argument(GPGME_CONF_STRING, value), true);
     628             : }
     629             : 
     630           0 : Argument Option::createIntListArgument(const std::vector<int> &value) const
     631             : {
     632           0 :     return Argument(comp.lock(), opt, make_argument(GPGME_CONF_INT32, value), true);
     633             : }
     634             : 
     635           0 : Argument Option::createUIntListArgument(const std::vector<unsigned int> &value) const
     636             : {
     637           0 :     return Argument(comp.lock(), opt, make_argument(GPGME_CONF_UINT32, value), true);
     638             : }
     639             : 
     640       14753 : Argument::Argument(const shared_gpgme_conf_comp_t &comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg, bool owns)
     641             :     : comp(comp),
     642             :       opt(opt),
     643       14753 :       arg(owns ? arg : mygpgme_conf_arg_copy(arg, opt ? opt->alt_type : GPGME_CONF_NONE))
     644             : {
     645             : 
     646       14753 : }
     647             : 
     648             : #if 0
     649             : Argument::Argument(const shared_gpgme_conf_comp_t &comp, gpgme_conf_opt_t opt, gpgme_conf_arg_t arg)
     650             :     : comp(comp),
     651             :       opt(opt),
     652             :       arg(mygpgme_conf_arg_copy(arg, opt ? opt->alt_type : GPGME_CONF_NONE))
     653             : {
     654             : 
     655             : }
     656             : #endif
     657             : 
     658           0 : Argument::Argument(const Argument &other)
     659             :     : comp(other.comp),
     660           0 :       opt(other.opt),
     661           0 :       arg(mygpgme_conf_arg_copy(other.arg, opt ? opt->alt_type : GPGME_CONF_NONE))
     662             : {
     663             : 
     664           0 : }
     665             : 
     666       29506 : Argument::~Argument()
     667             : {
     668       14753 :     gpgme_conf_arg_release(arg, opt ? opt->alt_type : GPGME_CONF_NONE);
     669       14753 : }
     670             : 
     671       14720 : Option Argument::parent() const
     672             : {
     673       14720 :     return Option(comp.lock(), opt);
     674             : }
     675             : 
     676           0 : bool Argument::boolValue() const
     677             : {
     678           0 :     return numberOfTimesSet();
     679             : }
     680             : 
     681           0 : unsigned int Argument::numElements() const
     682             : {
     683           0 :     if (isNull()) {
     684           0 :         return 0;
     685             :     }
     686           0 :     unsigned int result = 0;
     687           0 :     for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     688           0 :         ++result;
     689             :     }
     690           0 :     return result;
     691             : }
     692             : 
     693         641 : const char *Argument::stringValue(unsigned int idx) const
     694             : {
     695         641 :     if (isNull() || opt->alt_type != GPGME_CONF_STRING) {
     696          10 :         return 0;
     697             :     }
     698         631 :     gpgme_conf_arg_t a = arg;
     699         631 :     while (a && idx) {
     700           0 :         a = a->next;
     701           0 :         --idx;
     702             :     }
     703         631 :     return a ? a->value.string : 0 ;
     704             : }
     705             : 
     706         598 : int Argument::intValue(unsigned int idx) const
     707             : {
     708         598 :     if (isNull() || opt->alt_type != GPGME_CONF_INT32) {
     709         506 :         return 0;
     710             :     }
     711          92 :     gpgme_conf_arg_t a = arg;
     712          92 :     while (a && idx) {
     713           0 :         a = a->next;
     714           0 :         --idx;
     715             :     }
     716          92 :     return a ? a->value.int32 : 0 ;
     717             : }
     718             : 
     719           0 : unsigned int Argument::uintValue(unsigned int idx) const
     720             : {
     721           0 :     if (isNull() || opt->alt_type != GPGME_CONF_UINT32) {
     722           0 :         return 0;
     723             :     }
     724           0 :     gpgme_conf_arg_t a = arg;
     725           0 :     while (a && idx) {
     726           0 :         a = a->next;
     727           0 :         --idx;
     728             :     }
     729           0 :     return a ? a->value.uint32 : 0 ;
     730             : }
     731             : 
     732           0 : unsigned int Argument::numberOfTimesSet() const
     733             : {
     734           0 :     if (isNull() || opt->alt_type != GPGME_CONF_NONE) {
     735           0 :         return 0;
     736             :     }
     737           0 :     return arg->value.count;
     738             : }
     739             : 
     740           0 : std::vector<const char *> Argument::stringValues() const
     741             : {
     742           0 :     if (isNull() || opt->alt_type != GPGME_CONF_STRING) {
     743           0 :         return std::vector<const char *>();
     744             :     }
     745           0 :     std::vector<const char *> result;
     746           0 :     for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     747           0 :         result.push_back(a->value.string);
     748             :     }
     749           0 :     return result;
     750             : }
     751             : 
     752           0 : std::vector<int> Argument::intValues() const
     753             : {
     754           0 :     if (isNull() || opt->alt_type != GPGME_CONF_INT32) {
     755           0 :         return std::vector<int>();
     756             :     }
     757           0 :     std::vector<int> result;
     758           0 :     for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     759           0 :         result.push_back(a->value.int32);
     760             :     }
     761           0 :     return result;
     762             : }
     763             : 
     764           0 : std::vector<unsigned int> Argument::uintValues() const
     765             : {
     766           0 :     if (isNull() || opt->alt_type != GPGME_CONF_UINT32) {
     767           0 :         return std::vector<unsigned int>();
     768             :     }
     769           0 :     std::vector<unsigned int> result;
     770           0 :     for (gpgme_conf_arg_t a = arg ; a ; a = a->next) {
     771           0 :         result.push_back(a->value.uint32);
     772             :     }
     773           0 :     return result;
     774             : }
     775             : 
     776        2944 : std::ostream &Configuration::operator<<(std::ostream &os, Level level)
     777             : {
     778        2944 :     switch (level) {
     779        1242 :     case Basic:     return os << "Basic";
     780         943 :     case Advanced:  return os << "Advanced";
     781         460 :     case Expert:    return os << "Expert";
     782         299 :     case Invisible: return os << "Invisible";
     783           0 :     case Internal:  return os << "Internal";
     784             :     case NumLevels: ;
     785             :     }
     786           0 :     return os << "<unknown>";
     787             : }
     788             : 
     789        5888 : std::ostream &Configuration::operator<<(std::ostream &os, Type type)
     790             : {
     791        5888 :     switch (type) {
     792        3358 :     case NoType:              return os << "None";
     793        1541 :     case StringType:          return os << "String";
     794          92 :     case IntegerType:         return os << "Integer";
     795         690 :     case UnsignedIntegerType: return os << "UnsignedInteger";
     796         138 :     case FilenameType:        return os << "Filename";
     797          46 :     case LdapServerType:      return os << "LdapServer";
     798           0 :     case KeyFingerprintType:  return os << "KeyFingerprint";
     799           0 :     case PublicKeyType:       return os << "PublicKey";
     800           0 :     case SecretKeyType:       return os << "SecretKey";
     801          23 :     case AliasListType:       return os << "AliasList";
     802             :     case MaxType: ;
     803             :     }
     804           0 :     return os << "<unknown>";
     805             : }
     806             : 
     807        2944 : std::ostream &Configuration::operator<<(std::ostream &os, Flag f)
     808             : {
     809        2944 :     unsigned int flags = f;
     810        5888 :     std::vector<const char *> s;
     811        2944 :     if (flags & Group) {
     812         621 :         s.push_back("Group");
     813             :     }
     814        2944 :     if (flags & Optional) {
     815         184 :         s.push_back("Optional");
     816             :     }
     817        2944 :     if (flags & List) {
     818         184 :         s.push_back("List");
     819             :     }
     820        2944 :     if (flags & Runtime) {
     821         805 :         s.push_back("Runtime");
     822             :     }
     823        2944 :     if (flags & Default) {
     824         690 :         s.push_back("Default");
     825             :     }
     826        2944 :     if (flags & DefaultDescription) {
     827           0 :         s.push_back("DefaultDescription");
     828             :     }
     829        2944 :     if (flags & NoArgumentDescription) {
     830           0 :         s.push_back("NoArgumentDescription");
     831             :     }
     832        2944 :     if (flags & NoChange) {
     833          46 :         s.push_back("NoChange");
     834             :     }
     835        2944 :     flags &= ~(Group | Optional | List | Runtime | Default | DefaultDescription | NoArgumentDescription | NoChange);
     836        2944 :     if (flags) {
     837           0 :         s.push_back("other flags(");
     838             :     }
     839             :     std::copy(s.begin(), s.end(),
     840        2944 :               std::ostream_iterator<const char *>(os, "|"));
     841        2944 :     if (flags) {
     842           0 :         os << flags << ')';
     843             :     }
     844        5888 :     return os;
     845             : }
     846             : 
     847         138 : std::ostream &Configuration::operator<<(std::ostream &os, const Component &c)
     848             : {
     849             :     os << "Component["
     850             :        << "\n  name       : " << protect(c.name())
     851             :        << "\n  description: " << protect(c.description())
     852             :        << "\n  programName: " << protect(c.programName())
     853         138 :        << "\n  options    : \n";
     854         276 :     const std::vector<Option> options = c.options();
     855             :     std::copy(options.begin(), options.end(),
     856         138 :               std::ostream_iterator<Option>(os, "\n"));
     857         138 :     os << "\n]";
     858         276 :     return os;
     859             : }
     860             : 
     861        2944 : std::ostream &Configuration::operator<<(std::ostream &os, const Option &o)
     862             : {
     863             :     return os << "Option["
     864             :            << "\n  name:       : " << protect(o.name())
     865             :            << "\n  description : " << protect(o.description())
     866             :            << "\n  argName     : " << protect(o.argumentName())
     867        2944 :            << "\n  flags       : " << static_cast<Flag>(o.flags())
     868        5888 :            << "\n  level       : " << o.level()
     869        5888 :            << "\n  type        : " << o.type()
     870        5888 :            << "\n  alt_type    : " << o.alternateType()
     871        8832 :            << "\n  default_val : " << o.defaultValue()
     872             :            << "\n  default_desc: " << protect(o.defaultDescription())
     873        8832 :            << "\n  no_arg_value: " << o.noArgumentValue()
     874             :            << "\n  no_arg_desc : " << protect(o.noArgumentDescription())
     875        8832 :            << "\n  active_value: " << o.activeValue()
     876        8832 :            << "\n  new_value   : " << o.newValue()
     877        8832 :            << "\n  --> cur_val : " << o.currentValue()
     878        5888 :            << "\n  set         : " << o.set()
     879        5888 :            << "\n  dirty       : " << o.dirty()
     880        5888 :            << "\n]"
     881             :            ;
     882             : }
     883             : 
     884       14720 : std::ostream &Configuration::operator<<(std::ostream &os, const Argument &a)
     885             : {
     886       29440 :     const Option o = a.parent();
     887       14720 :     const bool list = o.flags() & List;
     888       14720 :     os << "Argument[";
     889       14720 :     if (a) {
     890        1217 :         switch (o.alternateType()) {
     891             :         case NoType:
     892           0 :             if (list) {
     893           0 :                 os << a.numberOfTimesSet() << 'x';
     894             :             } else {
     895           0 :                 os << a.boolValue();
     896             :             }
     897           0 :             break;
     898             :         default:
     899             :         case StringType:
     900         619 :             if (list) {
     901           0 :                 const std::vector<const char *> v = a.stringValues();
     902           0 :                 os << v.size() << ':';
     903             :                 // can't use std::copy + ostream_iterator here, since we need the protect() call
     904           0 :                 bool first = true;
     905           0 :                 std::for_each(v.begin(), v.end(), [&first, &os](const char *s) {
     906           0 :                     if (first) {
     907           0 :                         first = false;
     908             :                     } else {
     909           0 :                         os << ',';
     910             :                     }
     911           0 :                     os << protect(s);
     912           0 :                 });
     913             :             } else {
     914         619 :                 os << protect(a.stringValue());
     915             :             }
     916         619 :             break;
     917             :         case IntegerType:
     918          92 :             if (list) {
     919           0 :                 const std::vector<int> v = a.intValues();
     920           0 :                 os << v.size() << ':';
     921             :                 std::copy(v.begin(), v.end(),
     922           0 :                           std::ostream_iterator<int>(os, ","));
     923             :             } else {
     924          92 :                 os << a.intValue();
     925             :             }
     926          92 :             break;
     927             :         case UnsignedIntegerType:
     928         506 :             if (list) {
     929           0 :                 const std::vector<unsigned int> v = a.uintValues();
     930           0 :                 os << v.size() << ':';
     931             :                 std::copy(v.begin(), v.end(),
     932           0 :                           std::ostream_iterator<unsigned int>(os, ","));
     933             :             } else {
     934         506 :                 os << a.intValue();
     935             :             }
     936         506 :             break;
     937             :         }
     938             :     }
     939       29440 :     return os << ']';
     940          24 : }

Generated by: LCOV version 1.13