aboutsummaryrefslogtreecommitdiff
path: root/doc/api/cplusplus/examples/example_mask.cc
blob: fe98d6fa9b17f62774329446af0a7ceca02ee9b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* vim: set sw=4 sts=4 et foldmethod=syntax : */

/** \file
 *
 * Example \ref example_mask.cc "example_mask.cc" .
 *
 * \ingroup g_mask
 */

/** \example example_mask.cc
 *
 * This example demonstrates how to use Mask. It displays all the
 * mask keys for a particular PackageID.
 */

#include <paludis/paludis.hh>
#include "example_command_line.hh"
#include <iostream>
#include <iomanip>
#include <set>
#include <time.h>

using namespace paludis;
using namespace examples;

using std::cout;
using std::endl;
using std::left;
using std::setw;

namespace
{
    /* We use this visitor to display extra information about a Mask,
     * depending upon its type. */
    class MaskInformationVisitor
    {
        public:
            void visit(const UserMask &)
            {
                cout << left << setw(30) << "    Class:" << " " << "UserMask" << endl;
            }

            void visit(const UnacceptedMask & mask)
            {
                cout << left << setw(30) << "    Class:" << " " << "UnacceptedMask" << endl;
                cout << left << setw(30) << "    Unaccepted key:" << " " << mask.unaccepted_key_name() << endl;
            }

            void visit(const RepositoryMask & mask)
            {
                cout << left << setw(30) << "    Class:" << " " << "RepositoryMask" << endl;
                cout << left << setw(30) << "    Mask key:" << " " << mask.mask_key_name() << endl;
            }

            void visit(const UnsupportedMask & mask)
            {
                cout << left << setw(30) << "    Class:" << " " << "UnsupportedMask" << endl;
                cout << left << setw(30) << "    Explanation:" << " " << mask.explanation() << endl;
            }

            void visit(const AssociationMask & mask)
            {
                cout << left << setw(30) << "    Class:" << " " << "AssociationMask" << endl;
                cout << left << setw(30) << "    Associated package:" << " " << mask.associated_package_spec() << endl;
            }
    };
}

int main(int argc, char * argv[])
{
    int exit_status(0);

    try
    {
        CommandLine::get_instance()->run(argc, argv,
                "example_mask", "EXAMPLE_MASK_OPTIONS", "EXAMPLE_MASK_CMDLINE");

        /* We start with an Environment, respecting the user's '--environment' choice. */
        std::shared_ptr<Environment> env(EnvironmentFactory::get_instance()->create(
                    CommandLine::get_instance()->a_environment.argument()));

        /* Fetch package IDs for 'sys-apps/paludis'. */
        std::shared_ptr<const PackageIDSequence> ids((*env)[selection::AllVersionsSorted(
                    generator::Package(QualifiedPackageName("sys-apps/paludis")))]);

        /* For each ID: */
        for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
                i != i_end ; ++i)
        {
            cout << **i << ":" << endl;

            /* For each mask key: */
            for (PackageID::MasksConstIterator m((*i)->begin_masks()), m_end((*i)->end_masks()) ;
                    m != m_end ; ++m)
            {
                /* All Mask instances have two basic bits of information: a one
                 * character short key, and a longer description. */
                cout << left << setw(30) << "    Key:" << " " << std::string(1, (*m)->key()) << endl;
                cout << left << setw(30) << "    Description:" << " " << (*m)->description() << endl;

                /* To display more information about a Mask we create a visitor
                 * that visits the appropriate subtype. */
                MaskInformationVisitor v;
                (*m)->accept(v);

                cout << endl;
            }

            cout << endl;
        }
    }
    catch (const Exception & e)
    {
        /* Paludis exceptions can provide a handy human-readable backtrace and
         * an explanation message. Where possible, these should be displayed. */
        cout << endl;
        cout << "Unhandled exception:" << endl
            << "  * " << e.backtrace("\n  * ")
            << e.message() << " (" << e.what() << ")" << endl;
        return EXIT_FAILURE;
    }
    catch (const std::exception & e)
    {
        cout << endl;
        cout << "Unhandled exception:" << endl
            << "  * " << e.what() << endl;
        return EXIT_FAILURE;
    }
    catch (...)
    {
        cout << endl;
        cout << "Unhandled exception:" << endl
            << "  * Unknown exception type. Ouch..." << endl;
        return EXIT_FAILURE;
    }

    return exit_status;
}