aboutsummaryrefslogtreecommitdiff
path: root/doc/api/cplusplus
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-15 11:10:38 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-15 11:10:38 +0000
commit503481c165de28bc0a5db25b7848708df7cb2668 (patch)
tree41eac48b7d7915ca0e7e88bb5dc9ea65225d3b99 /doc/api/cplusplus
parent8f51d97de6b38b8bc8a9b129baecf4bebd183c7b (diff)
downloadpaludis-503481c165de28bc0a5db25b7848708df7cb2668.tar.gz
paludis-503481c165de28bc0a5db25b7848708df7cb2668.tar.xz
Start reworking docs
Diffstat (limited to 'doc/api/cplusplus')
-rw-r--r--doc/api/cplusplus/Makefile.am51
-rw-r--r--doc/api/cplusplus/doxygen.conf.in1295
-rw-r--r--doc/api/cplusplus/examples/Makefile.am184
-rw-r--r--doc/api/cplusplus/examples/example_about.cc34
-rw-r--r--doc/api/cplusplus/examples/example_action.cc143
-rw-r--r--doc/api/cplusplus/examples/example_command_line.cc96
-rw-r--r--doc/api/cplusplus/examples/example_command_line.hh88
-rw-r--r--doc/api/cplusplus/examples/example_contents.cc141
-rw-r--r--doc/api/cplusplus/examples/example_dep_label.cc225
-rw-r--r--doc/api/cplusplus/examples/example_dep_spec.cc177
-rw-r--r--doc/api/cplusplus/examples/example_dep_spec_flattener.cc135
-rw-r--r--doc/api/cplusplus/examples/example_dep_tag.cc198
-rw-r--r--doc/api/cplusplus/examples/example_dep_tree.cc274
-rw-r--r--doc/api/cplusplus/examples/example_environment.cc108
-rw-r--r--doc/api/cplusplus/examples/example_formatter.cc247
-rw-r--r--doc/api/cplusplus/examples/example_mask.cc144
-rw-r--r--doc/api/cplusplus/examples/example_match_package.cc98
-rw-r--r--doc/api/cplusplus/examples/example_metadata_key.cc261
-rw-r--r--doc/api/cplusplus/examples/example_name.cc107
-rw-r--r--doc/api/cplusplus/examples/example_package_database.cc105
-rw-r--r--doc/api/cplusplus/examples/example_package_id.cc160
-rw-r--r--doc/api/cplusplus/examples/example_query.cc108
-rw-r--r--doc/api/cplusplus/examples/example_query_delegate.cc165
-rw-r--r--doc/api/cplusplus/examples/example_repository.cc119
-rw-r--r--doc/api/cplusplus/examples/example_stringify_formatter.cc108
-rw-r--r--doc/api/cplusplus/examples/example_version_operator.cc116
-rw-r--r--doc/api/cplusplus/examples/example_version_spec.cc99
-rw-r--r--doc/api/cplusplus/groups.doxygen370
-rw-r--r--doc/api/cplusplus/main_page.doxygen20
-rw-r--r--doc/api/cplusplus/namespaces.doxygen14
-rw-r--r--doc/api/cplusplus/references.doxygen47
31 files changed, 5437 insertions, 0 deletions
diff --git a/doc/api/cplusplus/Makefile.am b/doc/api/cplusplus/Makefile.am
new file mode 100644
index 000000000..f3f44a7b0
--- /dev/null
+++ b/doc/api/cplusplus/Makefile.am
@@ -0,0 +1,51 @@
+SUBDIRS = examples .
+
+if HAVE_DOXYGEN_TAGS
+
+tagfiles = \
+ libstdc++.tag \
+ libwrapiter.tag
+
+libstdc++.tag :
+ wget -O $@ http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/libstdc++.tag
+
+libwrapiter.tag :
+ wget -O $@ http://libwrapiter.pioto.org/libwrapiter.tag
+
+endif
+
+doxygen_files = \
+ groups.doxygen \
+ main_page.doxygen \
+ namespaces.doxygen \
+ references.doxygen
+
+EXTRA_DIST = doxygen.conf.in $(doxygen_files)
+CLEANFILES = *~ doxygen/ paludis.tag
+
+MAINTAINERCLEANFILES = Makefile.in doxygen.conf $(tagfiles)
+
+if HAVE_DOXYGEN
+
+doxygen : doxygen.conf $(doxygen_files) $(tagfiles)
+ doxygen doxygen.conf
+
+else
+
+doxygen :
+ @echo "You don't have doxygen installed!"
+ exit 1
+
+endif
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
+distcheck-deps : $(DISTCHECK_DEPS) distcheck-deps-subdirs
+
+distcheck-deps-subdirs :
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s distcheck-deps || exit 1 ; done
+
+clean-local :
+ rm -fr doxygen/
+
diff --git a/doc/api/cplusplus/doxygen.conf.in b/doc/api/cplusplus/doxygen.conf.in
new file mode 100644
index 000000000..d5cfe2b96
--- /dev/null
+++ b/doc/api/cplusplus/doxygen.conf.in
@@ -0,0 +1,1295 @@
+# Doxyfile 1.5.3
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that
+# follow. The default is UTF-8 which is also the encoding used for all text before
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+# possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = @PACKAGE@
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = "Version @VERSION@"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be extracted
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+# where file will be replaced with the base name of the file that contains the anonymous
+# namespace. By default anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = ../../../paludis ../../../paludis/args ../../../paludis/environments ../../../paludis/environments/no_config ../../../paludis/environments/adapted ../../../paludis/environments/test ../../../paludis/fetchers ../../../paludis/repositories/fake ../../../paludis/selinux ../../../paludis/syncers ../../../paludis/util ./ ./examples/
+
+# This tag can be used to specify the character encoding of the source files that
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS = *.hh *.doxygen example_*.cc
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = YES
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = *-sr.* *-se.*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the output.
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS = *_GUARD_*
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = ./examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
+# then you must also enable this option. If you don't then doxygen will produce
+# a warning and turn it on anyway
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = doxygen
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH = ../../../
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = DOXYGEN=1 PALUDIS_VISIBLE=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES = @DOXYGEN_TAG_FILES@
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = paludis.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
+# be found in the default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a caller dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the number
+# of direct children of the root node in a graph is already larger than
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
+
diff --git a/doc/api/cplusplus/examples/Makefile.am b/doc/api/cplusplus/examples/Makefile.am
new file mode 100644
index 000000000..6773fdca9
--- /dev/null
+++ b/doc/api/cplusplus/examples/Makefile.am
@@ -0,0 +1,184 @@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src @PALUDIS_CXXFLAGS@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+SUBDIRS = .
+
+noinst_PROGRAMS = \
+ example_about \
+ example_action \
+ example_contents \
+ example_dep_label \
+ example_dep_spec \
+ example_dep_tag \
+ example_dep_tree \
+ example_dep_spec_flattener \
+ example_environment \
+ example_formatter \
+ example_stringify_formatter \
+ example_package_id \
+ example_metadata_key \
+ example_mask \
+ example_repository \
+ example_match_package \
+ example_query \
+ example_query_delegate \
+ example_package_database \
+ example_version_operator \
+ example_version_spec \
+ example_name
+
+EXTRA_DIST = $(noinst_SCRIPTS)
+
+noinst_LIBRARIES = libpaludisexamples.a
+
+libpaludisexamples_a_SOURCES = \
+ example_command_line.hh \
+ example_command_line.cc
+
+libpaludisexamples_a_LIBADD = \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_about_SOURCES = example_about.cc
+example_about_LDFLAGS = \
+ $(top_builddir)/paludis/libpaludis.la
+
+example_action_SOURCES = example_action.cc
+example_action_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_contents_SOURCES = example_contents.cc
+example_contents_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_dep_label_SOURCES = example_dep_label.cc
+example_dep_label_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_dep_spec_SOURCES = example_dep_spec.cc
+example_dep_spec_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_dep_tree_SOURCES = example_dep_tree.cc
+example_dep_tree_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_dep_tag_SOURCES = example_dep_tag.cc
+example_dep_tag_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_dep_spec_flattener_SOURCES = example_dep_spec_flattener.cc
+example_dep_spec_flattener_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_environment_SOURCES = example_environment.cc
+example_environment_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_formatter_SOURCES = example_formatter.cc
+example_formatter_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_stringify_formatter_SOURCES = example_stringify_formatter.cc
+example_stringify_formatter_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_package_id_SOURCES = example_package_id.cc
+example_package_id_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_mask_SOURCES = example_mask.cc
+example_mask_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_metadata_key_SOURCES = example_metadata_key.cc
+example_metadata_key_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_repository_SOURCES = example_repository.cc
+example_repository_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_match_package_SOURCES = example_match_package.cc
+example_match_package_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_query_delegate_SOURCES = example_query_delegate.cc
+example_query_delegate_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_query_SOURCES = example_query.cc
+example_query_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_package_database_SOURCES = example_package_database.cc
+example_package_database_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_version_operator_SOURCES = example_version_operator.cc
+example_version_operator_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_version_spec_SOURCES = example_version_spec.cc
+example_version_spec_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+example_name_SOURCES = example_name.cc
+example_name_LDFLAGS = \
+ libpaludisexamples.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/args/libpaludisargs.la
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
+distcheck-deps : $(DISTCHECK_DEPS) distcheck-deps-subdirs
+
+distcheck-deps-subdirs :
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s distcheck-deps || exit 1 ; done
+
diff --git a/doc/api/cplusplus/examples/example_about.cc b/doc/api/cplusplus/examples/example_about.cc
new file mode 100644
index 000000000..2ef9156f0
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_about.cc
@@ -0,0 +1,34 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_about.cc "example_about.cc" .
+ *
+ * \ingroup g_about
+ */
+
+/** \example example_about.cc
+ *
+ * A simple example showing how to use Paludis version macros.
+ */
+
+#include <paludis/paludis.hh>
+#include <iostream>
+#include <cstdlib>
+
+using std::cout;
+using std::endl;
+
+int main(int, char *[])
+{
+ cout << "Built using Paludis " << PALUDIS_VERSION_MAJOR << "." << PALUDIS_VERSION_MINOR
+ << "." << PALUDIS_VERSION_MICRO << PALUDIS_VERSION_SUFFIX;
+
+ if (! std::string(PALUDIS_SUBVERSION_REVISION).empty())
+ cout << " " << PALUDIS_SUBVERSION_REVISION;
+
+ cout << endl;
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/doc/api/cplusplus/examples/example_action.cc b/doc/api/cplusplus/examples/example_action.cc
new file mode 100644
index 000000000..e00f42f61
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_action.cc
@@ -0,0 +1,143 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_action.cc "example_action.cc" .
+ *
+ * \ingroup g_actions
+ */
+
+/** \example example_action.cc
+ *
+ * This example demonstrates how to use actions. It uses FetchAction to fetch
+ * source files for all versions of sys-apps/paludis that support fetching.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ /* Do we support a FetchAction? We find out by creating a
+ * SupportsActionTest<FetchAction> object, and querying via the
+ * PackageID::supports_action method. */
+ SupportsActionTest<FetchAction> supports_fetch_action;
+ if (! (*i)->supports_action(supports_fetch_action))
+ {
+ cout << "ID '" << **i << "' does not support the fetch action." << endl;
+ }
+ else
+ {
+ cout << "ID '" << **i << "' supports the fetch action, trying to fetch:" << endl;
+
+ /* Carry out a FetchAction. We need to specify various options when
+ * creating a FetchAction, controlling whether safe resume is used
+ * and whether unneeded (e.g. due to disabled USE flags) source
+ * files should still be fetched. */
+ FetchAction fetch_action(FetchActionOptions::create()
+ .fetch_unneeded(false)
+ .safe_resume(true)
+ );
+ try
+ {
+ (*i)->perform_action(fetch_action);
+ }
+ catch (const FetchActionError & e)
+ {
+ exit_status |= 1;
+
+ cout << "Caught FetchActionError, with the following details:" << endl;
+
+ /* We might get detailed information about individual fetch
+ * failures. */
+ for (Sequence<FetchActionFailure>::ConstIterator f(e.failures()->begin()), f_end(e.failures()->end()) ;
+ f != f_end ; ++f)
+ {
+ cout << " * File '" << f->target_file << "': ";
+
+ bool need_comma(false);
+ if (f->requires_manual_fetching)
+ {
+ cout << "requires manual fetching";
+ need_comma = true;
+ }
+
+ if (f->failed_automatic_fetching)
+ {
+ if (need_comma)
+ cout << ", ";
+ cout << "failed automatic fetching";
+ need_comma = true;
+ }
+
+ if (! f->failed_integrity_checks.empty())
+ {
+ if (need_comma)
+ cout << ", ";
+ cout << "failed integrity checks: " << f->failed_integrity_checks;
+ need_comma = true;
+ }
+ }
+
+ 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;
+}
+
diff --git a/doc/api/cplusplus/examples/example_command_line.cc b/doc/api/cplusplus/examples/example_command_line.cc
new file mode 100644
index 000000000..08ef3d568
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_command_line.cc
@@ -0,0 +1,96 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Basic command line handling for most examples.
+ */
+
+#include "example_command_line.hh"
+#include <paludis/paludis.hh>
+#include <cstdlib>
+#include <iostream>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+
+template class InstantiationPolicy<CommandLine, instantiation_method::SingletonTag>;
+
+CommandLine::CommandLine() :
+ ArgsHandler(),
+
+ action_args(this, "Actions",
+ "Selects which basic action to perform. At most one action should "
+ "be specified."),
+ a_version(&action_args, "version", 'V', "Display program version"),
+ a_help(&action_args, "help", 'h', "Display program help"),
+
+ general_args(this, "General options",
+ "Options which are relevant for most or all actions."),
+ a_log_level(&general_args, "log-level", '\0'),
+ a_environment(&general_args, "environment", 'E', "Environment specification (class:suffix, both parts optional)")
+{
+}
+
+std::string
+CommandLine::app_name() const
+{
+ return "example";
+}
+
+std::string
+CommandLine::app_synopsis() const
+{
+ return "An example app";
+}
+
+std::string
+CommandLine::app_description() const
+{
+ return "This is an example program.";
+}
+
+CommandLine::~CommandLine()
+{
+}
+
+void
+examples::show_help_and_exit(const char * const argv[])
+{
+ cout << "Usage: " << argv[0] << " [options]" << endl;
+ cout << endl;
+ cout << *CommandLine::get_instance();
+
+ exit(EXIT_SUCCESS);
+}
+
+void
+examples::show_version_and_exit()
+{
+ cout << PALUDIS_PACKAGE << " " << PALUDIS_VERSION_MAJOR << "."
+ << PALUDIS_VERSION_MINOR << "." << PALUDIS_VERSION_MICRO << PALUDIS_VERSION_SUFFIX;
+ if (! std::string(PALUDIS_SUBVERSION_REVISION).empty())
+ cout << " svn " << PALUDIS_SUBVERSION_REVISION;
+ cout << endl;
+
+ exit(EXIT_SUCCESS);
+}
+
+void
+CommandLine::run(const int argc, const char * const * const argv, const std::string & client,
+ const std::string & env_var, const std::string & env_prefix)
+{
+ args::ArgsHandler::run(argc, argv, client, env_var, env_prefix);
+
+ if (CommandLine::get_instance()->a_log_level.specified())
+ Log::get_instance()->set_log_level(CommandLine::get_instance()->a_log_level.option());
+
+ if (CommandLine::get_instance()->a_help.specified())
+ show_help_and_exit(argv);
+
+ if (CommandLine::get_instance()->a_version.specified())
+ show_version_and_exit();
+}
+
diff --git a/doc/api/cplusplus/examples/example_command_line.hh b/doc/api/cplusplus/examples/example_command_line.hh
new file mode 100644
index 000000000..62a4d73d1
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_command_line.hh
@@ -0,0 +1,88 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+#ifndef PALUDIS_GUARD_DOC_EXAMPLES_EXAMPLE_COMMAND_LINE_HH
+#define PALUDIS_GUARD_DOC_EXAMPLES_EXAMPLE_COMMAND_LINE_HH 1
+
+#include <paludis/args/args.hh>
+#include <paludis/args/log_level_arg.hh>
+#include <paludis/paludis.hh>
+
+/** \file
+ *
+ * Basic command line handling for most examples.
+ */
+
+namespace examples
+{
+ /**
+ * This class provides basic command line handling for most examples.
+ *
+ * Most Paludis clients should support at least '--help', '--version'
+ * and '--log-level'. If paludis::EnvironmentMaker is used to create
+ * the environment (as opposed to, say, paludis::NoConfigEnvironment),
+ * then '--environment' must also be an option.
+ *
+ * Clients are free to use whichever command line handling library they
+ * prefer, but for convenience all Paludis core clients use a common utility
+ * library with a much simpler interface than that provided by overly C-ish
+ * getopt derivatives.
+ *
+ * The command line is a singleton -- that is, only one instance of
+ * it exists globally. This avoids the need to pass around lots of
+ * parameters.
+ */
+ class CommandLine :
+ public paludis::args::ArgsHandler,
+ public paludis::InstantiationPolicy<CommandLine, paludis::instantiation_method::SingletonTag>
+ {
+ friend class paludis::InstantiationPolicy<CommandLine, paludis::instantiation_method::SingletonTag>;
+
+ private:
+ CommandLine();
+ ~CommandLine();
+
+ public:
+ virtual void run(const int, const char * const * const,
+ const std::string & client, const std::string & env_var,
+ const std::string & env_prefix);
+
+ ///\name Program information
+ ///\{
+
+ virtual std::string app_name() const;
+ virtual std::string app_synopsis() const;
+ virtual std::string app_description() const;
+
+ ///\}
+
+ ///\name Action arguments
+ ///\{
+
+ paludis::args::ArgsGroup action_args;
+ paludis::args::SwitchArg a_version;
+ paludis::args::SwitchArg a_help;
+
+ ///\}
+
+ ///\name General arguments
+ ///{
+
+ paludis::args::ArgsGroup general_args;
+ paludis::args::LogLevelArg a_log_level;
+ paludis::args::StringArg a_environment;
+
+ ///}
+ };
+
+ /**
+ * Show a '--help' message, and exit.
+ */
+ void show_help_and_exit(const char * const argv[]) PALUDIS_ATTRIBUTE((noreturn));
+
+ /**
+ * Show a '--version' message, and exit.
+ */
+ void show_version_and_exit() PALUDIS_ATTRIBUTE((noreturn));
+}
+
+#endif
diff --git a/doc/api/cplusplus/examples/example_contents.cc b/doc/api/cplusplus/examples/example_contents.cc
new file mode 100644
index 000000000..f728c24a9
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_contents.cc
@@ -0,0 +1,141 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_contents.cc "example_contents.cc" .
+ *
+ * \ingroup g_contents
+ */
+
+/** \example example_contents.cc
+ *
+ * This example demonstrates how to use contents. It displays details about
+ * the files installed by 'sys-apps/paludis'.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::left;
+using std::setw;
+
+namespace
+{
+ /* This visitor displays information about ContentsEntry subclasses. */
+ class ContentsPrinter :
+ public ConstVisitor<ContentsVisitorTypes>
+ {
+ public:
+ void visit(const ContentsDevEntry & d)
+ {
+ cout << left << setw(10) << "device" << d.name() << endl;
+ }
+
+ void visit(const ContentsMiscEntry & d)
+ {
+ cout << left << setw(10) << "misc" << d.name() << endl;
+ }
+
+ void visit(const ContentsFileEntry & d)
+ {
+ cout << left << setw(10) << "file" << d.name() << endl;
+ }
+
+ void visit(const ContentsDirEntry & d)
+ {
+ cout << left << setw(10) << "dir" << d.name() << endl;
+ }
+
+ void visit(const ContentsFifoEntry & d)
+ {
+ cout << left << setw(10) << "fifo" << d.name() << endl;
+ }
+
+ void visit(const ContentsSymEntry & d)
+ {
+ cout << left << setw(10) << "sym" << d.name() << " -> " << d.target() << endl;
+ }
+ };
+}
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_contents", "EXAMPLE_CONTENTS_OPTIONS", "EXAMPLE_CONTENTS_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for installed 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)) &
+ query::SupportsAction<InstalledAction>(),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ /* Do we have a contents key? PackageID _key() methods can return
+ * a zero pointer. */
+ if (! (*i)->contents_key())
+ {
+ cout << "ID '" << **i << "' does not provide a contents key." << endl;
+ }
+ else
+ {
+ cout << "ID '" << **i << "' provides contents key:" << endl;
+
+ /* Visit the contents key's value's entries with our visitor. We use
+ * indirect_iterator because value()->begin() and ->end() return
+ * iterators to tr1::shared_ptr<>s rather than raw objects. */
+ ContentsPrinter p;
+ std::for_each(
+ indirect_iterator((*i)->contents_key()->value()->begin()),
+ indirect_iterator((*i)->contents_key()->value()->end()),
+ accept_visitor(p));
+ }
+
+ 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;
+}
+
diff --git a/doc/api/cplusplus/examples/example_dep_label.cc b/doc/api/cplusplus/examples/example_dep_label.cc
new file mode 100644
index 000000000..7429e7747
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_dep_label.cc
@@ -0,0 +1,225 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_dep_label.cc "example_dep_label.cc" .
+ *
+ * \ingroup g_dep_spec
+ */
+
+/** \example example_dep_label.cc
+ *
+ * This example demonstrates how to handle dependency labels. It produces a
+ * summary of distfiles for all installed packages, together with a notice of
+ * whether that distfile is fetch-restricted.
+ *
+ * See \ref example_dep_tree.cc "example_dep_tree.cc" for trees.
+ * See \ref example_dep_spec.cc "example_dep_spec.cc" for specs.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <cstdlib>
+#include <list>
+#include <map>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+/* We store our results in a map from distfile name to whether it is fetch
+ * restricted. */
+typedef std::map<std::string, bool> ResultsMap;
+
+namespace
+{
+ /* This visitor class is used to determine whether a label represents a
+ * fetch restriction. */
+ class IsLabelRestrictedVisitor :
+ public ConstVisitor<URILabelVisitorTypes>
+ {
+ public:
+ bool result;
+
+ IsLabelRestrictedVisitor(const bool initial) :
+ result(initial)
+ {
+ }
+
+ void visit(const URIListedThenMirrorsLabel &)
+ {
+ result = false;
+ }
+
+ void visit(const URIListedOnlyLabel &)
+ {
+ result = false;
+ }
+
+ void visit(const URIMirrorsOnlyLabel &)
+ {
+ result = false;
+ }
+
+ void visit(const URIMirrorsThenListedLabel &)
+ {
+ result = false;
+ }
+
+ void visit(const URILocalMirrorsOnlyLabel &)
+ {
+ result = true;
+ }
+
+ void visit(const URIManualOnlyLabel &)
+ {
+ result = true;
+ }
+ };
+
+ /* This visitor class collects src_uri entries and stores the result in
+ * a provided map. Label statuses are handled by a stack. When we enter
+ * a block (an AllDepSpec or a UseDepSpec), we duplicate the top item
+ * of the stack, since labels recurse into subblocks. When we encounter
+ * a label, we replace the top item of the stack. */
+ class DistfilesCollector :
+ public ConstVisitor<FetchableURISpecTree>
+ {
+ private:
+ ResultsMap & _results;
+ std::list<bool> _restricted;
+
+ public:
+ DistfilesCollector(ResultsMap & r, const bool initial) :
+ _results(r)
+ {
+ _restricted.push_back(initial);
+ }
+
+ void visit_sequence(const AllDepSpec &,
+ FetchableURISpecTree::ConstSequenceIterator cur,
+ FetchableURISpecTree::ConstSequenceIterator end)
+ {
+ /* When we encounter an AllDepSpec, duplicate the top item of
+ * our restricted stack, and then recurse over all of its
+ * children, and then restore the stack. */
+ _restricted.push_back(_restricted.back());
+ std::for_each(cur, end, accept_visitor(*this));
+ _restricted.pop_back();
+ }
+
+ void visit_sequence(const UseDepSpec &,
+ FetchableURISpecTree::ConstSequenceIterator cur,
+ FetchableURISpecTree::ConstSequenceIterator end)
+ {
+ /* Always recurse over a UseDepSpec's children. In real world
+ * code, we would more likely check whether the use flag is
+ * accepted. */
+ _restricted.push_back(_restricted.back());
+ std::for_each(cur, end, accept_visitor(*this));
+ _restricted.pop_back();
+ }
+
+ void visit_leaf(const FetchableURIDepSpec & s)
+ {
+ /* When we encounter a FetchableURIDepSpec, store its distfile name.
+ * We handle 'a -> b' style specs by taking 'b' as the
+ * distfile name. */
+ _results.insert(std::make_pair(s.filename(), _restricted.back()));
+ }
+
+ void visit_leaf(const URILabelsDepSpec & l)
+ {
+ /* Find out whether the label represents a fetch restriction.
+ * Change the top item of the stack as appropriate. Although
+ * a URILabelsDepSpec can contain multiple labels, only the last
+ * one is relevant. */
+ IsLabelRestrictedVisitor v(_restricted.back());
+ std::for_each(indirect_iterator(l.begin()), indirect_iterator(l.end()), accept_visitor(v));
+ _restricted.back() = v.result;
+ }
+ };
+}
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_label", "EXAMPLE_DEP_LABEL_OPTIONS", "EXAMPLE_DEP_LABEL_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for all installed packages. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::SupportsAction<InstalledAction>(),
+ qo_whatever));
+
+ /* Store a map from distfile name to whether it is fetch restricted. */
+ ResultsMap results;
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ /* If we don't have a fetches key, skip this package. All PackageID
+ * _key() functions can potentially return zero pointers, so checking is
+ * essential. */
+ if (! (*i)->fetches_key())
+ continue;
+
+ /* We need to know whether the default label for this package's src_uri
+ * is restricted. */
+ IsLabelRestrictedVisitor is_initial_label_restricted(false);
+ (*i)->fetches_key()->initial_label()->accept(is_initial_label_restricted);
+
+ /* Create a visitor that will collect distfiles, and do the collecting. */
+ DistfilesCollector collector(results, is_initial_label_restricted.result);
+ (*i)->fetches_key()->value()->accept(collector);
+ }
+
+ /* Display summary of results */
+ cout << left << setw(59) << "Distfile Name" << "| " << "Fetch Restricted?" << endl;
+ cout << std::string(59, '-') << "+" << std::string(18, '-') << endl;
+ for (ResultsMap::const_iterator r(results.begin()), r_end(results.end()) ;
+ r != r_end ; ++r)
+ cout << left << setw(59) << r->first << "| " << (r->second ? "yes" : "no") << 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_SUCCESS;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_dep_spec.cc b/doc/api/cplusplus/examples/example_dep_spec.cc
new file mode 100644
index 000000000..129c2b3df
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_dep_spec.cc
@@ -0,0 +1,177 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_dep_spec.cc "example_dep_spec.cc" .
+ *
+ * \ingroup g_dep_spec
+ */
+
+/** \example example_dep_spec.cc
+ *
+ * This example demonstrates how to handle dependency specs.
+ *
+ * See \ref example_dep_label.cc "example_dep_label.cc" for labels.
+ * See \ref example_dep_tree.cc "example_dep_tree.cc" for trees.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <cstdlib>
+#include <list>
+#include <map>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_spec", "EXAMPLE_DEP_SPEC_OPTIONS", "EXAMPLE_DEP_SPEC_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* For each command line parameter... */
+ for (CommandLine::ParametersConstIterator q(CommandLine::get_instance()->begin_parameters()),
+ q_end(CommandLine::get_instance()->end_parameters()) ; q != q_end ; ++q)
+ {
+ /* Create a PackageDepSpec from the parameter. For user-inputted
+ * data, pds_pm_permissive or pds_pm_unspecific should be used (only
+ * the latter allows wildcards). */
+ PackageDepSpec spec(*q, pds_pm_unspecific);
+
+ /* Display information about the PackageDepSpec. */
+ cout << "Information about '" << spec << "':" << endl;
+
+ if (spec.package_ptr())
+ cout << " " << left << setw(24) << "Package:" << " " << *spec.package_ptr() << endl;
+
+ if (spec.category_name_part_ptr())
+ cout << " " << left << setw(24) << "Category part:" << " " << *spec.category_name_part_ptr() << endl;
+
+ if (spec.package_name_part_ptr())
+ cout << " " << left << setw(24) << "Package part:" << " " << *spec.package_name_part_ptr() << endl;
+
+ if (spec.version_requirements_ptr() && ! spec.version_requirements_ptr()->empty())
+ {
+ cout << " " << left << setw(24) << "Version requirements:" << " ";
+ bool need_join(false);
+ for (VersionRequirements::ConstIterator r(spec.version_requirements_ptr()->begin()),
+ r_end(spec.version_requirements_ptr()->end()) ; r != r_end ; ++r)
+ {
+ if (need_join)
+ {
+ switch (spec.version_requirements_mode())
+ {
+ case vr_and:
+ cout << " and ";
+ break;
+
+ case vr_or:
+ cout << " or ";
+ break;
+
+ case last_vr:
+ throw InternalError(PALUDIS_HERE, "Bad version_requirements_mode");
+ }
+ }
+
+ cout << r->version_operator << r->version_spec;
+ need_join = true;
+ }
+ cout << endl;
+ }
+
+ if (spec.slot_ptr())
+ cout << " " << left << setw(24) << "Slot:" << " " << *spec.slot_ptr() << endl;
+
+ if (spec.repository_ptr())
+ cout << " " << left << setw(24) << "Repository:" << " " << *spec.repository_ptr() << endl;
+
+ if (spec.use_requirements_ptr() && ! spec.use_requirements_ptr()->empty())
+ {
+ cout << " " << left << setw(24) << "Use requirements:" << " ";
+ bool need_join(false);
+ for (UseRequirements::ConstIterator u(spec.use_requirements_ptr()->begin()),
+ u_end(spec.use_requirements_ptr()->end()) ; u != u_end ; ++u)
+ {
+ if (need_join)
+ cout << " and ";
+
+ switch (u->second)
+ {
+ case use_enabled:
+ case use_unspecified:
+ break;
+
+ case use_disabled:
+ cout << "-";
+ break;
+
+ case last_use:
+ throw InternalError(PALUDIS_HERE, "Bad use requirements");
+ }
+ cout << u->first;
+
+ need_join = true;
+ }
+ cout << endl;
+ }
+
+ /* And display packages matching that spec */
+ cout << " " << left << setw(24) << "Matches:" << " ";
+ tr1::shared_ptr<const PackageIDSequence> ids(
+ env->package_database()->query(query::Matches(spec), qo_order_by_version));
+ bool need_indent(false);
+ for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ if (need_indent)
+ cout << " " << left << setw(24) << "" << " ";
+ cout << **i << endl;
+ need_indent = true;
+ }
+
+ 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_SUCCESS;
+}
+
diff --git a/doc/api/cplusplus/examples/example_dep_spec_flattener.cc b/doc/api/cplusplus/examples/example_dep_spec_flattener.cc
new file mode 100644
index 000000000..1974bce6d
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_dep_spec_flattener.cc
@@ -0,0 +1,135 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_dep_spec_flattener.cc "example_dep_spec_flattener.cc" .
+ *
+ * \ingroup g_dep_spec
+ */
+
+/** \example example_dep_spec_flattener.cc
+ *
+ * This example demonstrates how to use DepSpecFlattener. It extracts various
+ * metadata items from a package.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <cstdlib>
+#include <set>
+#include <map>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_spec_flattener", "EXAMPLE_DEP_SPEC_FLATTENER_OPTIONS", "EXAMPLE_DEP_SPEC_FLATTENER_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for all installed packages. */
+ tr1::shared_ptr<const PackageIDSequence> ids(
+ env->package_database()->query(
+ query::SupportsAction<InstalledAction>(),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSequence::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ cout << "Information about '" << **i << "':" << endl;
+
+ /* Do we have a provides key? All PackageID key methods may return a
+ * zero pointer. */
+ if ((*i)->provide_key())
+ {
+ /* Create our flattener... */
+ DepSpecFlattener<ProvideSpecTree, PackageDepSpec> provides(env.get(), **i);
+
+ /* Populate it by making it visit the key's value */
+ (*i)->provide_key()->value()->accept(provides);
+
+ /* The results are available through DepSpecFlattener::begin()
+ * and ::end(). These return an iterator to a tr1::shared_ptr<>,
+ * so we use indirect_iterator to add a level of dereferencing.*/
+ cout << " " << left << setw(24) << "Provides:" << " "
+ << join(indirect_iterator(provides.begin()), indirect_iterator(provides.end()), " ")
+ << endl;
+ }
+
+ /* Again for homepage */
+ if ((*i)->homepage_key())
+ {
+ DepSpecFlattener<SimpleURISpecTree, SimpleURIDepSpec> homepages(env.get(), **i);
+ (*i)->homepage_key()->value()->accept(homepages);
+
+ cout << " " << left << setw(24) << "Homepages:" << " "
+ << join(indirect_iterator(homepages.begin()), indirect_iterator(homepages.end()), " ")
+ << endl;
+ }
+
+ /* And again for restricts. There's no global restrict key, since
+ * it has no meaning outside of the repositories that support it.
+ * Instead, we use PackageID::find_metadata to see if the key we
+ * want exists, and then visitor_cast<> to see whether it's of a
+ * suitable type (the key could be something other than a
+ * MetadataSpecTreeKey<RestrictSpecTree>). */
+ if ((*i)->end_metadata() != (*i)->find_metadata("RESTRICT") &&
+ visitor_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(**(*i)->find_metadata("RESTRICT")))
+ {
+ DepSpecFlattener<RestrictSpecTree, PlainTextDepSpec> restricts(env.get(), **i);
+
+ visitor_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(
+ **(*i)->find_metadata("RESTRICT"))->value()->accept(restricts);
+
+ cout << " " << left << setw(24) << "Restricts:" << " "
+ << join(indirect_iterator(restricts.begin()), indirect_iterator(restricts.end()), " ")
+ << 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_SUCCESS;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_dep_tag.cc b/doc/api/cplusplus/examples/example_dep_tag.cc
new file mode 100644
index 000000000..17e1a3df4
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_dep_tag.cc
@@ -0,0 +1,198 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_dep_tag.cc "example_dep_tag.cc" .
+ *
+ * \ingroup g_dep_spec
+ */
+
+/** \example example_dep_tag.cc
+ *
+ * This example demonstrates how to handle dependency tags. It displays
+ * information about the 'security' and 'world' sets.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <set>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+using std::boolalpha;
+
+/* We store a set of dep tag categories that we've seen. */
+typedef std::set<std::string> SeenCategories;
+
+namespace
+{
+ /* This visitor is used to display information about a tag. */
+ class TagDisplayer :
+ public ConstVisitor<DepTagVisitorTypes>
+ {
+ public:
+ void visit(const DependencyDepTag & tag)
+ {
+ /* A DependencyDepTag is used during dependency resolution. It
+ * shows why a package is included on a DepList. It has three
+ * additional fields: an optional package ID that pulled in the
+ * entry, an optional dep spec that pulled in the dependency and
+ * an optional set of conditions upon which that dependency is
+ * active. The third field is not used here, since it is too
+ * complicated for this example. */
+ if (tag.package_id())
+ cout << left << setw(20) << " Package ID:" << " " << *tag.package_id() << endl;
+ if (tag.dependency())
+ cout << left << setw(20) << " Dependency:" << " " << *tag.dependency() << endl;
+ }
+
+ void visit(const GLSADepTag & tag)
+ {
+ /* A GLSADepTag is for security advisories. It carries one
+ * additional field, the GLSA's title. */
+ cout << left << setw(20) << " GLSA title:" << " " << tag.glsa_title() << endl;
+ }
+
+ void visit(const GeneralSetDepTag & tag)
+ {
+ /* A GeneralSetDepTag is for general package sets. It carries
+ * one additional field, the source (e.g. a repository or
+ * environment name). */
+ cout << left << setw(20) << " Source:" << " " << tag.source() << endl;
+ }
+
+ void visit(const TargetDepTag &)
+ {
+ /* A TargetDepTag is used to indicate explicit targets when
+ * resolving dependencies. It carries no extra information. */
+ }
+ };
+
+ /* Display information about a named set. */
+ void display_set(
+ const tr1::shared_ptr<const Environment> & env,
+ const SetName & name,
+ SeenCategories & seen_categories)
+ {
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(env->set(name));
+
+ /* Environment::set can return a zero pointer, if a set is not known. */
+ if (! set)
+ return;
+
+ /* The set isn't necessarily flat. We use DepSpecFlattener to make it
+ * so, rather than writing a full visitor ourselves. We don't need to
+ * supply a package, since a SetSpecTree cannot contain a UseDepSpec. */
+ DepSpecFlattener<SetSpecTree, PackageDepSpec> set_flat(env.get());
+ set->accept(set_flat);
+
+ cout << "Set '" << name << "':" << endl;
+
+ /* For each item... */
+ for (DepSpecFlattener<SetSpecTree, PackageDepSpec>::ConstIterator s(set_flat.begin()),
+ s_end(set_flat.end()) ; s != s_end ; ++s)
+ {
+ /* Ignore it, if it has no tag. */
+ if (! (*s)->tag())
+ continue;
+
+ cout << " " << **s << ": " << endl;
+
+ /* All dep tags have short text and a category. As well as
+ * displaying the category, we remember it for the categories
+ * summary later on. */
+ cout << left << setw(20) << " Short text:" << " " << (*s)->tag()->short_text() << endl;
+ cout << left << setw(20) << " Category:" << " " << (*s)->tag()->category() << endl;
+ seen_categories.insert((*s)->tag()->category());
+
+ /* We use a visitor to do extra displaying, so that we can display
+ * more detailed information for whatever our tag type is. */
+ TagDisplayer displayer;
+ (*s)->tag()->accept(displayer);
+
+ cout << endl;
+ }
+
+ cout << endl;
+ }
+}
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_tag", "EXAMPLE_DEP_TAG_OPTIONS", "EXAMPLE_DEP_TAG_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ SeenCategories seen_categories;
+
+ /* First, tell us about the 'security' set: */
+ display_set(env, SetName("security"), seen_categories);
+
+ /* Then the 'world' set: */
+ display_set(env, SetName("world"), seen_categories);
+
+ /* Now display a summary of seen categories. */
+ cout << "Seen categories:" << endl;
+ for (SeenCategories::const_iterator s(seen_categories.begin()), s_end(seen_categories.end()) ;
+ s != s_end ; ++s)
+ {
+ cout << " " << *s << ":" << endl;
+
+ /* Fetch the category. DepTagCategoryMaker::find_maker returns a
+ * function that creates the category, rather than directly
+ * returning the category. */
+ tr1::shared_ptr<const DepTagCategory> category(
+ DepTagCategoryMaker::get_instance()->find_maker(*s)());
+
+ cout << left << setw(20) << " Visible:" << " " << boolalpha << category->visible() << endl;
+ cout << left << setw(20) << " ID:" << " " << category->id() << endl;
+ cout << left << setw(20) << " Title:" << " " << category->title() << endl;
+ cout << left << setw(20) << " Pre text:" << " " << category->pre_text() << endl;
+ cout << left << setw(20) << " Post text:" << " " << category->post_text() << 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_SUCCESS;
+}
+
+
+
diff --git a/doc/api/cplusplus/examples/example_dep_tree.cc b/doc/api/cplusplus/examples/example_dep_tree.cc
new file mode 100644
index 000000000..defa451dd
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_dep_tree.cc
@@ -0,0 +1,274 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_dep_tree.cc "example_dep_tree.cc" .
+ *
+ * \ingroup g_dep_spec
+ */
+
+/** \example example_dep_tree.cc
+ *
+ * This example demonstrates how to handle dependency specs. It looks through
+ * all installed packages, and picks out any package whose dependencies include
+ * 'app-arch/unzip', or whose fetchable files includes any with a '.zip'
+ * extension.
+ *
+ * See \ref example_dep_label.cc "example_dep_label.cc" for labels.
+ * See \ref example_dep_spec.cc "example_dep_spec.cc" for specs.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <cstdlib>
+#include <list>
+#include <map>
+#include <set>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+/* We use this map to store accumulated results. The first item in the pair
+ * is whether we see a dependency, the second whether we see an extension. */
+typedef std::map<std::string, std::pair<bool, bool> > ResultsMap;
+
+namespace
+{
+ /* This visitor handles collection of packages with interesting
+ * dependencies. We use the ConstVisitor<>::VisitConstSequence helper mixin
+ * for AllDepSpec and AnyDepSpec, rather than explicitly visiting all the
+ * children manually. */
+ class DependenciesCollector :
+ public ConstVisitor<DependencySpecTree>,
+ public ConstVisitor<DependencySpecTree>::VisitConstSequence<DependenciesCollector, AllDepSpec>,
+ public ConstVisitor<DependencySpecTree>::VisitConstSequence<DependenciesCollector, AnyDepSpec>
+ {
+ private:
+ const tr1::shared_ptr<const Environment> _env;
+ const tr1::shared_ptr<const PackageID> _id;
+ ResultsMap & _results;
+ std::set<SetName> _recursing_sets;
+
+ public:
+ DependenciesCollector(
+ const tr1::shared_ptr<const Environment> & e,
+ const tr1::shared_ptr<const PackageID> & i,
+ ResultsMap & r) :
+ _env(e),
+ _id(i),
+ _results(r)
+ {
+ }
+
+ using ConstVisitor<DependencySpecTree>::VisitConstSequence<DependenciesCollector, AllDepSpec>::visit_sequence;
+ using ConstVisitor<DependencySpecTree>::VisitConstSequence<DependenciesCollector, AnyDepSpec>::visit_sequence;
+
+ void visit_sequence(const UseDepSpec & u,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+ {
+ /* Was this use flag enabled (or, if we're inverse, disabled)
+ * when we built this package? */
+ if (_env->query_use(u.flag(), *_id) ^ u.inverse())
+ std::for_each(cur, end, accept_visitor(*this));
+ }
+
+ void visit_leaf(const PackageDepSpec & spec)
+ {
+ /* spec.package_ptr() may return a zero pointer if it's a
+ * wildcarded dep. */
+ if (spec.package_ptr() && *spec.package_ptr() == QualifiedPackageName("app-arch/unzip"))
+ _results[stringify(*_id)].first = true;
+ }
+
+ void visit_leaf(const NamedSetDepSpec & spec)
+ {
+ /* For named set specs, we visit the set. */
+ tr1::shared_ptr<const SetSpecTree::ConstItem> set(_env->set(spec.name()));
+
+ /* First complication: we might have a name referring to a set
+ * that doesn't exist. */
+ if (! set)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Unknown set '" << spec << "'";
+ return;
+ }
+
+ /* Second complication: we need to handle sets that contain
+ * themselves. Although this shouldn't happen, user-defined
+ * sets can be made to include themselves, possibly with
+ * other sets inbetween (a includes b includes a). */
+ if (! _recursing_sets.insert(spec.name()).second)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Recursively defined set '" << spec << "'";
+ return;
+ }
+
+ /* Now that we have the set, we can handle it simply by
+ * visiting it. */
+ set->accept(*this);
+
+ _recursing_sets.erase(spec.name());
+ }
+
+ void visit_leaf(const BlockDepSpec &)
+ {
+ /* Not interested */
+ }
+
+ void visit_leaf(const DependencyLabelsDepSpec &)
+ {
+ /* Not interested */
+ }
+ };
+
+ /* This visitor handles collection of packages with interesting
+ * filenames. Again, we use the ConstVisitor<>::VisitConstSequence helper mixin
+ * for AllDepSpec (AnyDepSpec is not allowed in a FetchableURISpecTree). */
+ class FileExtensionsCollector :
+ public ConstVisitor<FetchableURISpecTree>,
+ public ConstVisitor<FetchableURISpecTree>::VisitConstSequence<FileExtensionsCollector, AllDepSpec>
+ {
+ private:
+ const tr1::shared_ptr<const Environment> _env;
+ const tr1::shared_ptr<const PackageID> _id;
+ ResultsMap & _results;
+
+ public:
+ FileExtensionsCollector(
+ const tr1::shared_ptr<const Environment> & e,
+ const tr1::shared_ptr<const PackageID> & i,
+ ResultsMap & r) :
+ _env(e),
+ _id(i),
+ _results(r)
+ {
+ }
+
+ using ConstVisitor<FetchableURISpecTree>::VisitConstSequence<FileExtensionsCollector, AllDepSpec>::visit_sequence;
+
+ void visit_sequence(const UseDepSpec & u,
+ FetchableURISpecTree::ConstSequenceIterator cur,
+ FetchableURISpecTree::ConstSequenceIterator end)
+ {
+ /* Was this use flag enabled (or, if we're inverse, disabled)
+ * when we built this package? */
+ if (_env->query_use(u.flag(), *_id) ^ u.inverse())
+ std::for_each(cur, end, accept_visitor(*this));
+ }
+
+ void visit_leaf(const FetchableURIDepSpec & spec)
+ {
+ /* We need to be careful not to assume that the filename has
+ * an extension. */
+ std::string::size_type p(spec.filename().rfind('.'));
+ if ((std::string::npos != p) && (".zip" == spec.filename().substr(p)))
+ _results[stringify(*_id)].second = true;
+ }
+
+ void visit_leaf(const URILabelsDepSpec &)
+ {
+ /* Not interested */
+ }
+ };
+}
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_tree", "EXAMPLE_DEP_TREE_OPTIONS", "EXAMPLE_DEP_TREE_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for all installed packages. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::SupportsAction<InstalledAction>(),
+ qo_order_by_version));
+
+ ResultsMap results;
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ /* Ignore old-style virtuals. */
+ if ((*i)->virtual_for_key())
+ continue;
+
+ /* Insert a default result for this ID */
+ results[stringify(**i)] = std::make_pair(false, false);
+
+ /* Create a visitor that collects 'app-arch/unzip' dependencies. */
+ DependenciesCollector dependencies_collector(env, *i, results);
+
+ /* IDs can potentially have four dependency-related keys. Each of
+ * these keys may return a zero pointer. If it doesn't, visit its
+ * value with our collector. */
+ if ((*i)->build_dependencies_key())
+ (*i)->build_dependencies_key()->value()->accept(dependencies_collector);
+ if ((*i)->run_dependencies_key())
+ (*i)->run_dependencies_key()->value()->accept(dependencies_collector);
+ if ((*i)->post_dependencies_key())
+ (*i)->post_dependencies_key()->value()->accept(dependencies_collector);
+ if ((*i)->suggested_dependencies_key())
+ (*i)->suggested_dependencies_key()->value()->accept(dependencies_collector);
+
+ /* Create a visitor that collects '.zip' file extenstions. */
+ FileExtensionsCollector extensions_collector(env, *i, results);
+
+ /* Again, we check for a zero pointer and visit otherwise: */
+ if ((*i)->fetches_key())
+ (*i)->fetches_key()->value()->accept(extensions_collector);
+ }
+
+ /* Display our results */
+ cout << left << setw(60) << "Package" << "| " << left << setw(4) << "Dep" << "| " << "Ext" << endl;
+ cout << std::string(60, '-') << "+" << std::string(4, '-') << "+" << std::string(4, '-') << endl;
+ for (ResultsMap::const_iterator r(results.begin()), r_end(results.end()) ;
+ r != r_end ; ++r)
+ cout << left << setw(60) << r->first << "| "
+ << left << setw(4) << (r->second.first ? "yes" : "no") << "| "
+ << left << setw(4) << (r->second.second ? "yes" : "no") << 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_SUCCESS;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_environment.cc b/doc/api/cplusplus/examples/example_environment.cc
new file mode 100644
index 000000000..5b092358a
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_environment.cc
@@ -0,0 +1,108 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_environment.cc "example_environment.cc" .
+ *
+ * \ingroup g_environment
+ */
+
+/** \example example_environment.cc
+ *
+ * This example demonstrates how to use EnvironmentMaker and the resultant
+ * Environment.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::left;
+using std::setw;
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_environment", "EXAMPLE_ENVIRONMENT_OPTIONS", "EXAMPLE_ENVIRONMENT_CMDLINE");
+
+ /* We use EnvironmentMaker to construct an environment from the user's
+ * --environment commandline choice. With an empty string, this uses the
+ * distribution-defined default environment. With a non-empty string, it
+ * is split into two parts upon the first colon (if there is no colon,
+ * the second part is considered empty). The first part is the name of
+ * the environment class to use (e.g. 'paludis', 'portage') and the
+ * second part is passed as parameters to be handled by that
+ * environment's constructor. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* A lot of the Environment members aren't very useful to clients. The
+ * mask related methods are used by PackageID, and shouldn't usually be
+ * called directly from clients. The system information and mirror
+ * functions are mostly for use by Repository subclasses. That leaves
+ * the package database, sets and (currently, although this may well
+ * change in the future) use flag queries. The package database has its
+ * own examples, so we'll start with sets: */
+
+ tr1::shared_ptr<SetSpecTree::ConstItem> world(env->set(SetName("world")));
+ if (world)
+ {
+ /* See \ref example_dep_tree.cc "example_dep_tree.cc" for how to
+ * make use of this set. */
+ cout << "World set exists" << endl;
+ }
+ else
+ cout << "No world set defined" << endl;
+
+ /* And use flags, for which we need a package IDs: */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)) &
+ query::SupportsAction<InstalledAction>(),
+ qo_order_by_version));
+
+ if (! ids->empty())
+ {
+ UseFlagName u("ruby");
+ cout << "Use flag '" << u << "' for ID '" << **ids->rbegin() << "' is "
+ << (env->query_use(u, **ids->rbegin()) ? "enabled" : "disabled") << 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;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_formatter.cc b/doc/api/cplusplus/examples/example_formatter.cc
new file mode 100644
index 000000000..51582a806
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_formatter.cc
@@ -0,0 +1,247 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_formatter.cc "example_formatter.cc" .
+ *
+ * \ingroup g_formatters
+ */
+
+/** \example example_formatter.cc
+ *
+ * This example demonstrates how to create a formatter. It outputs information
+ * about a package's dependencies in HTML.
+ *
+ * See \ref example_stringify_formatter.cc "example_stringify_formatter.cc" for
+ * StringifyFormatter, a premade formatter that uses stringify.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+
+namespace
+{
+ /* Utility function that replaces dodgy characters with HTML escapes. */
+ std::string escape_html(const std::string & s)
+ {
+ std::string result;
+ for (std::string::const_iterator i(s.begin()), i_end(s.end()) ;
+ i != i_end ; ++i)
+ switch (*i)
+ {
+ case '<':
+ result.append("&lt;");
+ break;
+
+ case '>':
+ result.append("&gt;");
+ break;
+
+ case '&':
+ result.append("&amp;");
+ break;
+
+ default:
+ result.append(std::string(1, *i));
+ }
+
+ return result;
+ }
+
+ /* Utility function that creates an HTML <span> with a colour. */
+ std::string span_colour(const std::string & s, const std::string & c)
+ {
+ return "<span style=\"color: " + c + "\">" + s + "</span>";
+ }
+
+ /* This formatter outputs information about dependencies in HTML. We need
+ * to implement CanFormat<> for all of the things that can be found in
+ * DependencySpecTree::ItemFormatter, as well as CanSpace. */
+ class HTMLFormatter :
+ public CanSpace,
+ public CanFormat<PackageDepSpec>,
+ public CanFormat<DependencyLabelsDepSpec>,
+ public CanFormat<UseDepSpec>,
+ public CanFormat<NamedSetDepSpec>,
+ public CanFormat<BlockDepSpec>
+ {
+ public:
+ /* The second parameter to the format functions has no meaning
+ * beyond being used to overload to the appropriate function. */
+ std::string format(const PackageDepSpec & s, const format::Plain &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#666666");
+ }
+
+ std::string format(const PackageDepSpec & s, const format::Installed &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#6666ff");
+ }
+
+ std::string format(const PackageDepSpec & s, const format::Installable &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#66ff66");
+ }
+
+ std::string format(const DependencyLabelsDepSpec & s, const format::Plain &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#666666");
+ }
+
+ std::string format(const UseDepSpec & s, const format::Plain &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#666666");
+ }
+
+ std::string format(const UseDepSpec & s, const format::Enabled &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#66ff66");
+ }
+
+ std::string format(const UseDepSpec & s, const format::Disabled &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#ff6666");
+ }
+
+ std::string format(const UseDepSpec & s, const format::Forced &) const
+ {
+ return span_colour(escape_html("(" + stringify(s) + ")"), "#66ff66");
+ }
+
+ std::string format(const UseDepSpec & s, const format::Masked &) const
+ {
+ return span_colour(escape_html("(" + stringify(s) + ")"), "#ff6666");
+ }
+
+ std::string format(const NamedSetDepSpec & s, const format::Plain &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#666666");
+ }
+
+ std::string format(const BlockDepSpec & s, const format::Plain &) const
+ {
+ return span_colour(escape_html(stringify(s)), "#666666");
+ }
+
+ std::string newline() const
+ {
+ return "<br />\n";
+ }
+
+ std::string indent(const int i) const
+ {
+ std::string result;
+ for (int x(0) ; x < i ; ++x)
+ result.append("&nbsp; &nbsp; ");
+ return result;
+ }
+ };
+}
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_formatter", "EXAMPLE_FORMATTER_OPTIONS", "EXAMPLE_FORMATTER_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for installable 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)) &
+ query::SupportsAction<InstallAction>(),
+ qo_order_by_version));
+
+ /* Write nice valid XHTML, because we're good like that. */
+ cout << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"" << endl;
+ cout << " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" << endl;
+ cout << "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">" << endl;
+ cout << "<head><title>Dependencies for sys-apps/paludis</title></head>" << endl;
+ cout << "<body>" << endl;
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ cout << "<h1>" << escape_html(stringify(**i)) << "</h1>" << endl;
+
+ /* Our formatter. It has no saved state, so we can use a single
+ * formatter for all of the keys. */
+ HTMLFormatter formatter;
+
+ /* We need to check that _key() methods don't return zero. */
+ if ((*i)->build_dependencies_key())
+ {
+ cout << "<h2>" << escape_html((*i)->build_dependencies_key()->human_name()) << "</h2>" << endl;
+ cout << "<div style=\"border: 1px solid #999999; background-color: #eeeeee; "
+ "margin-left: 1em; padding: 0.2em 0.5em; \">" << endl;
+ cout << (*i)->build_dependencies_key()->pretty_print(formatter);
+ cout << endl << "</div>" << endl;
+ }
+
+ if ((*i)->run_dependencies_key())
+ {
+ cout << "<h2>" << escape_html((*i)->run_dependencies_key()->human_name()) << "</h2>" << endl;
+ cout << "<div style=\"border: 1px solid #999999; background-color: #eeeeee; "
+ "margin-left: 1em; padding: 0.2em 0.5em; \">" << endl;
+ cout << (*i)->run_dependencies_key()->pretty_print(formatter);
+ cout << endl << "</div>" << endl;
+ }
+
+ if ((*i)->post_dependencies_key())
+ {
+ cout << "<h2>" << escape_html((*i)->post_dependencies_key()->human_name()) << "</h2>" << endl;
+ cout << "<div style=\"border: 1px solid #999999; background-color: #eeeeee; "
+ "margin-left: 1em; padding: 0.2em 0.5em; \">" << endl;
+ cout << (*i)->post_dependencies_key()->pretty_print(formatter);
+ cout << endl << "</div>" << endl;
+ }
+
+ cout << endl;
+ }
+
+ cout << "</body>" << endl;
+ cout << "</html>" << 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_SUCCESS;
+}
+
+
+
diff --git a/doc/api/cplusplus/examples/example_mask.cc b/doc/api/cplusplus/examples/example_mask.cc
new file mode 100644
index 000000000..1b60e77a5
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_mask.cc
@@ -0,0 +1,144 @@
+/* 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 ConstVisitor<MaskVisitorTypes>
+ {
+ public:
+ void visit(const UserMask &)
+ {
+ cout << left << setw(30) << " Class:" << " " << "UserMask" << endl;
+ }
+
+ void visit(const UnacceptedMask & mask)
+ {
+ cout << left << setw(30) << " Class:" << " " << "UnacceptedMask" << endl;
+ if (mask.unaccepted_key())
+ cout << left << setw(30) << " Unaccepted key:" << " " << mask.unaccepted_key()->raw_name() << endl;
+ }
+
+ void visit(const RepositoryMask & mask)
+ {
+ cout << left << setw(30) << " Class:" << " " << "RepositoryMask" << endl;
+ if (mask.mask_key())
+ cout << left << setw(30) << " Mask key:" << " " << mask.mask_key()->raw_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;
+ if (mask.associated_package())
+ cout << left << setw(30) << " Associated package:" << " " << *mask.associated_package() << 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. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSet::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;
+}
+
diff --git a/doc/api/cplusplus/examples/example_match_package.cc b/doc/api/cplusplus/examples/example_match_package.cc
new file mode 100644
index 000000000..dbe540466
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_match_package.cc
@@ -0,0 +1,98 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_match_package.cc "example_match_package.cc" .
+ *
+ * \ingroup g_query
+ */
+
+/** \example example_match_package.cc
+ *
+ * This example demonstrates how to use paludis::match_package and
+ * paludis::match_package_in_set.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::left;
+using std::setw;
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_match_package", "EXAMPLE_MATCH_PACKAGE_OPTIONS", "EXAMPLE_MATCH_PACKAGE_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch all installed packages. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::SupportsAction<InstalledAction>(),
+ qo_order_by_version));
+
+ /* Fetch the 'system' and 'world' sets. Ordinarily we should check for
+ * zero pointers here, but these two sets will always exist. */
+ tr1::shared_ptr<const SetSpecTree::ConstItem> system(env->set(SetName("system"))),
+ world(env->set(SetName("world")));
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ /* Is it paludis? */
+ if (match_package(*env, PackageDepSpec("sys-apps/paludis", pds_pm_permissive), **i))
+ cout << left << setw(50) << (stringify(**i) + ":") << " " << "paludis" << endl;
+
+ /* No. Is it in system or world? */
+ else if (match_package_in_set(*env, *system, **i))
+ cout << left << setw(50) << (stringify(**i) + ":") << " " << "system" << endl;
+ else if (match_package_in_set(*env, *world, **i))
+ cout << left << setw(50) << (stringify(**i) + ":") << " " << "world" << endl;
+ else
+ cout << left << setw(50) << (stringify(**i) + ":") << " " << "nothing" << 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;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_metadata_key.cc b/doc/api/cplusplus/examples/example_metadata_key.cc
new file mode 100644
index 000000000..ea3a3555a
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_metadata_key.cc
@@ -0,0 +1,261 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_metadata_key.cc "example_metadata_key.cc" .
+ *
+ * \ingroup g_metadata_key
+ */
+
+/** \example example_metadata_key.cc
+ *
+ * This example demonstrates how to use MetadataKey. It displays all the
+ * metadata 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 MetadataKey,
+ * depending upon its type. */
+ class MetadataKeyInformationVisitor :
+ public ConstVisitor<MetadataKeyVisitorTypes>
+ {
+ private:
+ /* Various methods need a formatter. See \ref example_stringify_formatter.cc
+ * "example_stringify_formatter.cc" for more details. */
+ StringifyFormatter formatter;
+
+ public:
+ void visit(const MetadataStringKey & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataStringKey" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.value() << endl;
+ }
+
+ void visit(const MetadataFSEntryKey & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataFSEntryKey" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.value() << endl;
+ }
+
+ void visit(const MetadataPackageIDKey & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataPackageIDKey" << endl;
+ cout << left << setw(30) << " Value:" << " " << *key.value() << endl;
+ }
+
+ void visit(const MetadataTimeKey & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataTimeKey" << endl;
+
+ /* Yay horrible C formatting routines! */
+ time_t t(key.value());
+ char buf[255];
+ if (! strftime(buf, 254, "%c", gmtime(&t)))
+ buf[0] = '\0';
+ cout << left << setw(30) << " Value:" << " " << buf << endl;
+ }
+
+ void visit(const MetadataContentsKey &)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataContentsKey" << endl;
+ /* We won't display the contents of the contents key here, since
+ * it involves creating another visitor. See \ref
+ * example_contents.cc "example_contents.cc" for that. */
+ }
+
+ void visit(const MetadataRepositoryMaskInfoKey & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataRepositoryMaskInfoKey" << endl;
+
+ /* MetadataRepositoryMaskInfoKey::value() can return a zero
+ * pointer. Other keys can't. */
+ if (key.value())
+ {
+ cout << left << setw(30) << " Mask file:" << " " << key.value()->mask_file << endl;
+ /* Comment looks best if it's outputted over multiple lines,
+ * as that's how it tends to be stored in package.mask. */
+ cout << left << setw(30) << " Comment:" << " ";
+ bool first(true);
+ for (Sequence<std::string>::ConstIterator i(key.value()->comment->begin()),
+ i_end(key.value()->comment->end()) ;
+ i != i_end ; ++i)
+ {
+ if (! first)
+ cout << left << setw(30) << " ..." << " ";
+ cout << *i << endl;
+ first = false;
+ }
+ }
+ }
+
+ void visit(const MetadataSpecTreeKey<RestrictSpecTree> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<RestrictSpecTree>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSpecTreeKey<ProvideSpecTree> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<ProvideSpecTree>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSpecTreeKey<LicenseSpecTree> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<LicenseSpecTree>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSpecTreeKey<SimpleURISpecTree> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<SimpleURISpecTree>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSpecTreeKey<DependencySpecTree> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<DependencySpecTree>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSpecTreeKey<FetchableURISpecTree> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<FetchableURISpecTree>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ cout << left << setw(30) << " Initial label:" << " " << key.initial_label()->text() << endl;
+ }
+
+ void visit(const MetadataSetKey<IUseFlagSet> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<IUseFlagSet>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSetKey<KeywordNameSet> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<KeywordNameSet>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSetKey<UseFlagNameSet> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<UseFlagNameSet>" << endl;
+ cout << left << setw(30) << " Value:" << " " << key.pretty_print_flat(formatter) << endl;
+ }
+
+ void visit(const MetadataSetKey<Set<std::string> > & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<Set<std::string> >" << endl;
+ cout << left << setw(30) << " Value:" << " " << join(key.value()->begin(), key.value()->end(), " ") << endl;
+ }
+
+ void visit(const MetadataSetKey<PackageIDSequence> & key)
+ {
+ cout << left << setw(30) << " Class:" << " " << "MetadataSpecTreeKey<PackageIDSequence>" << endl;
+ /* Slight trickery: a PackageIDSequence stores shared pointers
+ * to PackageID instances, so we need indirect_iterator to get
+ * an extra level of dereferencing. */
+ cout << left << setw(30) << " Value:" << " " << join(indirect_iterator(key.value()->begin()),
+ indirect_iterator(key.value()->end()), " ") << endl;
+ }
+ };
+}
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_metadata_key", "EXAMPLE_METADATA_KEY_OPTIONS", "EXAMPLE_METADATA_KEY_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ cout << **i << ":" << endl;
+
+ /* For each metadata key: */
+ for (PackageID::MetadataConstIterator k((*i)->begin_metadata()), k_end((*i)->end_metadata()) ;
+ k != k_end ; ++k)
+ {
+ /* All MetadataKey instances have a raw name, a human readable
+ * name and a type. The type is a hint to clients as to whether
+ * the key should be displayed when outputting the package (for
+ * example, 'paludis --query' shows mkt_significant keys first,
+ * then mkt_normal keys, and doesn't show mkt_dependencies
+ * without '--show-deps' or mkt_internal without
+ * '--show-metadata'. */
+ cout << left << setw(30) << " Raw name:" << " " << (*k)->raw_name() << endl;
+ cout << left << setw(30) << " Human name:" << " " << (*k)->human_name() << endl;
+ cout << left << setw(30) << " Type:" << " " << (*k)->type() << endl;
+
+ /* To get any more information out of a MetadataKey we have to
+ * use a visitor. This lets us write type-safe handling code for
+ * the appropriate MetadataKey subclass without the need for any
+ * runtime type information queries. */
+ MetadataKeyInformationVisitor v;
+ (*k)->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;
+}
+
+
+
diff --git a/doc/api/cplusplus/examples/example_name.cc b/doc/api/cplusplus/examples/example_name.cc
new file mode 100644
index 000000000..a56a17739
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_name.cc
@@ -0,0 +1,107 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_name.cc "example_name.cc" .
+ *
+ * \ingroup g_names
+ */
+
+/** \example example_name.cc
+ *
+ * This example demonstrates how to use name classes.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+namespace
+{
+ /* Try to create a name and show some information about it */
+ template <typename NameType_>
+ void show_name(const std::string & type_string, const std::string & value)
+ {
+ cout << type_string << " " << value << ":" << endl;
+ try
+ {
+ /* Names can be explicitly created from a string. If an invalid
+ * value is given, an exception is thrown. */
+ NameType_ name(value);
+
+ /* Names can be written to a stream. */
+ cout << " " << left << setw(24) << "To stream:" << " " << name << endl;
+
+ /* Names can be stringified if a raw string is needed. */
+ cout << " " << left << setw(24) << "stringify(n).length:"
+ << " " << stringify(name).length() << endl;
+ }
+ catch (const NameError & e)
+ {
+ cout << " " << left << setw(24) << "Exception:" << " '" <<
+ e.message() << "' (" << e.what() << ")" << endl;
+ }
+ cout << endl;
+ }
+}
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_name", "EXAMPLE_NAME_OPTIONS", "EXAMPLE_NAME_CMDLINE");
+
+ /* Most names are simply validated string classes. There is no implicit
+ * conversion to or from strings to increase static checking. The
+ * IUseFlag and QualifiedPackageName names are special -- they are
+ * composites, rather than simply validated strings. */
+ show_name<SetName>("SetName", "world");
+ show_name<SetName>("SetName", "not*valid");
+ show_name<PackageNamePart>("PackageNamePart", "fred");
+ show_name<PackageNamePart>("PackageNamePart", "not/valid");
+ show_name<QualifiedPackageName>("QualifiedPackageName", "cat/pkg");
+ show_name<QualifiedPackageName>("QualifiedPackageName", "not-valid");
+
+ QualifiedPackageName q1("cat/pkg"), q2(CategoryNamePart("cat") + PackageNamePart("pkg"));
+ cout << q1 << " " << (q1 == q2 ? "==" : "!=") << " " << q2 << endl;
+ cout << q1 << " has category '" << q1.category << "' and package part '" << q1.package << "'" << 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_SUCCESS;
+}
+
diff --git a/doc/api/cplusplus/examples/example_package_database.cc b/doc/api/cplusplus/examples/example_package_database.cc
new file mode 100644
index 000000000..6adb7a69a
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_package_database.cc
@@ -0,0 +1,105 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_package_database.cc "example_package_database.cc" .
+ *
+ * \ingroup g_package_database
+ */
+
+/** \example example_package_database.cc
+ *
+ * This example demonstrates how to use PackageDatabase.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <cstdlib>
+#include <set>
+#include <map>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_dep_spec_flattener", "EXAMPLE_DEP_SPEC_FLATTENER_OPTIONS", "EXAMPLE_DEP_SPEC_FLATTENER_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* The most useful PackageDatabase method is PackageDatabase::query,
+ * which is covered in other examples. But there are others: */
+ if (env->package_database()->has_repository_named(RepositoryName("gentoo")))
+ {
+ tr1::shared_ptr<const Repository> repo(env->package_database()->fetch_repository(RepositoryName("gentoo")));
+ cout << "Repository 'gentoo' exists, and has format '" << repo->format() << "'" << endl;
+ }
+
+ /* Our favourite repository is the least important non-special (e.g.
+ * virtual) installable repository. Some clients use this as a hint to
+ * not display a ::repository suffix for things from this repository. */
+ cout << "Our favourite repository is '" << env->package_database()->favourite_repository() << "'" << endl;
+
+ /* Users often expect to be able to refer to a package by its name part
+ * only (e.g. 'foo' rather than 'app-misc/foo'). This has to be
+ * disambiguated as follows: */
+ try
+ {
+ QualifiedPackageName name(env->package_database()->fetch_unique_qualified_package_name(
+ PackageNamePart("git")));
+ cout << "The only package named 'git' is '" << name << "'" << endl;
+ }
+ catch (const NoSuchPackageError & e)
+ {
+ cout << "There is no package named 'git'" << endl;
+ }
+ catch (const AmbiguousPackageNameError & e)
+ {
+ cout << "There are several packages named 'git':" << endl;
+ for (AmbiguousPackageNameError::OptionsConstIterator o(e.begin_options()), o_end(e.end_options()) ;
+ o != o_end ; ++o)
+ cout << " " << *o << 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_SUCCESS;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_package_id.cc b/doc/api/cplusplus/examples/example_package_id.cc
new file mode 100644
index 000000000..b684e3a08
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_package_id.cc
@@ -0,0 +1,160 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_package_id.cc "example_package_id.cc" .
+ *
+ * \ingroup g_package_id
+ */
+
+/** \example example_package_id.cc
+ *
+ * This example demonstrates how to use PackageID.
+ *
+ * See \ref example_action.cc "example_action.cc" for more on actions. See \ref
+ * example_metadata_key.cc "example_metadata_key.cc" for more on metadata keys.
+ * See \ref example_mask.cc "example_mask.cc" for more on masks.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <set>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::left;
+using std::setw;
+using std::hex;
+using std::boolalpha;
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_package_id", "EXAMPLE_PACKAGE_ID_OPTIONS", "EXAMPLE_PACKAGE_ID_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ /* IDs can be written to an ostream. */
+ cout << **i << ":" << endl;
+
+ /* Start by outputting some basic properties: */
+ cout << left << setw(30) << " Name:" << " " << (*i)->name() << endl;
+ cout << left << setw(30) << " Version:" << " " << (*i)->version() << endl;
+ cout << left << setw(30) << " Slot:" << " " << (*i)->slot() << endl;
+ cout << left << setw(30) << " Repository Name:" << " " << (*i)->repository()->name() << endl;
+
+ /* The PackageID::canonical_form method should be used when
+ * outputting a package (the ostream << operator uses this). */
+ cout << left << setw(30) << " idcf_full:" << " " << (*i)->canonical_form(idcf_full) << endl;
+ cout << left << setw(30) << " idcf_version:" << " " << (*i)->canonical_form(idcf_version) << endl;
+ cout << left << setw(30) << " idcf_no_version:" << " " << (*i)->canonical_form(idcf_no_version) << endl;
+
+ /* Let's see what keys we have. Other examples cover keys in depth,
+ * so we'll just use the basic methods here. */
+ cout << left << setw(30) << " Keys:" << " " << endl;
+ for (PackageID::MetadataConstIterator k((*i)->begin_metadata()), k_end((*i)->end_metadata()) ;
+ k != k_end ; ++k)
+ cout << left << setw(30) << (" " + (*k)->raw_name() + ":") << " " << (*k)->human_name() << endl;
+
+ /* And what about masks? Again, these are covered in depth
+ * elsewhere. */
+ if ((*i)->masked())
+ {
+ cout << left << setw(30) << " Masks:" << " " << endl;
+ for (PackageID::MasksConstIterator m((*i)->begin_masks()), m_end((*i)->end_masks()) ;
+ m != m_end ; ++m)
+ cout << left << setw(30) << (" " + stringify((*m)->key()) + ":") << " " << (*m)->description() << endl;
+ }
+
+ /* Let's see which actions we support. There's no particularly nice
+ * way of doing this, since it's not something we'd expect to be
+ * doing. */
+ std::set<std::string> actions;
+ {
+ SupportsActionTest<InstallAction> install_action;
+ if ((*i)->supports_action(install_action))
+ actions.insert("install");
+
+ SupportsActionTest<InstalledAction> installed_action;
+ if ((*i)->supports_action(installed_action))
+ actions.insert("installed");
+
+ SupportsActionTest<UninstallAction> uninstall_action;
+ if ((*i)->supports_action(uninstall_action))
+ actions.insert("uninstall");
+
+ SupportsActionTest<PretendAction> pretend_action;
+ if ((*i)->supports_action(pretend_action))
+ actions.insert("pretend");
+
+ SupportsActionTest<ConfigAction> config_action;
+ if ((*i)->supports_action(config_action))
+ actions.insert("config");
+
+ SupportsActionTest<UninstallAction> fetch_action;
+ if ((*i)->supports_action(fetch_action))
+ actions.insert("fetch");
+
+ SupportsActionTest<UninstallAction> info_action;
+ if ((*i)->supports_action(info_action))
+ actions.insert("info");
+ }
+ cout << left << setw(30) << " Actions:" << " " << join(actions.begin(), actions.end(), " ") << endl;
+
+ /* And various misc methods. Clients don't usually use these
+ * directly. */
+ cout << left << setw(30) << " breaks_portage:" << " " << boolalpha << (*i)->breaks_portage() << endl;
+ cout << left << setw(30) << " extra_hash_value:" << " " << "0x" << hex << (*i)->extra_hash_value() << 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;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_query.cc b/doc/api/cplusplus/examples/example_query.cc
new file mode 100644
index 000000000..161e8cc28
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_query.cc
@@ -0,0 +1,108 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_query.cc "example_query.cc" .
+ *
+ * \ingroup g_query
+ */
+
+/** \example example_query.cc
+ *
+ * This example demonstrates how to use the standard Query classes. For custom
+ * Query subclasses, see \ref example_query_delegate.cc
+ * "example_query_delegate.cc".
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+
+namespace
+{
+ /* Run a particular query, and show its results. */
+ void show_query(const tr1::shared_ptr<const Environment> & env, const Query & query)
+ {
+ /* Queries support a crude form of stringification. */
+ cout << query << ":" << endl;
+
+ /* Usually the only thing clients will do with a Query object is pass it
+ * to PackageDatabase::query. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(query, qo_order_by_version));
+
+ /* Show the results */
+ if (! ids->empty())
+ std::copy(indirect_iterator(ids->begin()), indirect_iterator(ids->end()),
+ std::ostream_iterator<const PackageID>(cout, "\n"));
+ cout << endl;
+ }
+}
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Make some queries, and display what they give. */
+ show_query(env, query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)));
+
+ /* Queries can be combined. The resulting query is optimised internally,
+ * potentially giving better performance than doing things by hand. */
+ show_query(env,
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)) &
+ query::SupportsAction<InstalledAction>());
+
+ /* Usually query::NotMasked should be combined with
+ * query::SupportsAction<InstallAction>, since installed packages aren't
+ * masked. */
+ show_query(env,
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)) &
+ query::SupportsAction<InstallAction>() &
+ query::NotMasked());
+
+ }
+ 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;
+}
+
+
diff --git a/doc/api/cplusplus/examples/example_query_delegate.cc b/doc/api/cplusplus/examples/example_query_delegate.cc
new file mode 100644
index 000000000..b006eef61
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_query_delegate.cc
@@ -0,0 +1,165 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_query_delegate.cc "example_query_delegate.cc" .
+ *
+ * \ingroup g_query
+ */
+
+/** \example example_query_delegate.cc
+ *
+ * This example demonstrates how to implement a new Query classes. For standard
+ * Query classes, see \ref example_query.cc "example_query.cc".
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+
+namespace
+{
+ /* To implement a custom query, we need two classes. First, the delegate.
+ * We only override the QueryDelegate::ids function, since we can't be more
+ * helpful at earlier levels. */
+ class DescriptionContainsDelegate :
+ public QueryDelegate
+ {
+ private:
+ const std::string _pattern;
+
+ public:
+ DescriptionContainsDelegate(const std::string & pattern) :
+ _pattern(pattern)
+ {
+ }
+
+ tr1::shared_ptr<PackageIDSequence>
+ ids(const Environment & e,
+ tr1::shared_ptr<const RepositoryNameSequence> repos,
+ tr1::shared_ptr<const QualifiedPackageNameSet> pkgs) const
+ {
+ tr1::shared_ptr<PackageIDSequence> result(new PackageIDSequence);
+
+ /* We have to iterate over every repository by hand... */
+ for (RepositoryNameSequence::ConstIterator r(repos->begin()), r_end(repos->end()) ;
+ r != r_end ; ++r)
+ {
+ /* And from each repository, we iterate over packages by
+ * hand... */
+ tr1::shared_ptr<const Repository> repo(e.package_database()->fetch_repository(*r));
+ for (QualifiedPackageNameSet::ConstIterator p(pkgs->begin()), p_end(pkgs->end()) ;
+ p != p_end ; ++p)
+ {
+ /* And finally, IDs by hand... */
+ tr1::shared_ptr<const PackageIDSequence> i(repo->package_ids(*p));
+ for (PackageIDSequence::ConstIterator v(i->begin()), v_end(i->end()) ;
+ v != v_end ; ++v)
+ {
+ /* Does our description contain the pattern? We must
+ * check for a zero pointer. */
+ if ((*v)->short_description_key())
+ if (std::string::npos != (*v)->short_description_key()->value().find(_pattern))
+ result->push_back(*v);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ std::string
+ as_human_readable_string() const
+ {
+ return "description contains '" + _pattern + "'";
+ }
+ };
+
+ /* Then we implement the Query itself. */
+ class DescriptionContains :
+ public Query
+ {
+ public:
+ DescriptionContains(const std::string & pattern) :
+ Query(tr1::shared_ptr<QueryDelegate>(new DescriptionContainsDelegate(pattern)))
+ {
+ }
+ };
+
+ /* Run a particular query, and show its results. */
+ void show_query(const tr1::shared_ptr<const Environment> & env, const Query & query)
+ {
+ /* Queries support a crude form of stringification. */
+ cout << query << ":" << endl;
+
+ /* Usually the only thing clients will do with a Query object is pass it
+ * to PackageDatabase::query. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(query, qo_order_by_version));
+
+ /* Show the results */
+ if (! ids->empty())
+ std::copy(indirect_iterator(ids->begin()), indirect_iterator(ids->end()),
+ std::ostream_iterator<const PackageID>(cout, "\n"));
+ cout << endl;
+ }
+}
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_action", "EXAMPLE_ACTION_OPTIONS", "EXAMPLE_ACTION_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Make some queries, and display what they give. */
+ show_query(env, DescriptionContains("duck"));
+
+ /* We can combine custom queries too. */
+ show_query(env,
+ query::SupportsAction<InstalledAction>() &
+ DescriptionContains("cow"));
+ }
+ 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;
+}
+
+
+
diff --git a/doc/api/cplusplus/examples/example_repository.cc b/doc/api/cplusplus/examples/example_repository.cc
new file mode 100644
index 000000000..07608a4bb
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_repository.cc
@@ -0,0 +1,119 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_repository.cc "example_repository.cc" .
+ *
+ * \ingroup g_repository
+ */
+
+/** \example example_repository.cc
+ *
+ * This example demonstrates how to use Repository.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::left;
+using std::setw;
+
+int main(int argc, char * argv[])
+{
+ int exit_status(0);
+
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_environment", "EXAMPLE_ENVIRONMENT_OPTIONS", "EXAMPLE_ENVIRONMENT_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* For each repository... */
+ for (PackageDatabase::RepositoryConstIterator r(env->package_database()->begin_repositories()),
+ r_end(env->package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ {
+ /* A repository is identified by its name. */
+ cout << left << (*r)->name() << ":" << endl;
+
+ /* Configuration and possibly additional information is available
+ * via Repository::info. */
+ tr1::shared_ptr<const RepositoryInfo> info((*r)->info(true));
+
+ cout << left << setw(30) << " Info:" << " " << endl;
+ /* RepositoryInfo is made up of a number of sections... */
+ for (RepositoryInfo::SectionConstIterator s(info->begin_sections()), s_end(info->end_sections()) ;
+ s != s_end ; ++s)
+ {
+ cout << left << setw(30) << (" " + (*s)->heading() + ":") << " " << endl;
+ /* And a section is made up of key+value pairs */
+ for (RepositoryInfoSection::KeyValueConstIterator v((*s)->begin_kvs()), v_end((*s)->end_kvs()) ;
+ v != v_end ; ++v)
+ cout << left << setw(30) << (" " + v->first + ":") << " " << v->second << endl;
+ }
+
+ /* Repositories support various methods for querying categories,
+ * packages, IDs and so on. These methods are used by
+ * PackageDatabase::query, but are also sometimes of direct use to
+ * clients. */
+ tr1::shared_ptr<const CategoryNamePartSet> cats((*r)->category_names());
+ cout << left << setw(30) << " Number of categories:" << " " << cats->size() << endl;
+ tr1::shared_ptr<const PackageIDSequence> ids((*r)->package_ids(QualifiedPackageName("sys-apps/paludis")));
+ cout << left << setw(30) << " IDs for sys-apps/paludis:" << " " <<
+ join(indirect_iterator(ids->begin()), indirect_iterator(ids->end()), " ") << endl;
+
+ /* Much of the Repository functionality is optional -- for example,
+ * not all repositories support use flags as a concept, and not all
+ * repositories are syncable, and merging only makes sense to
+ * certain repositories. We gain access to optional functionality
+ * via interface methods, all of which may return a zero pointer.
+ * Many Repository interfaces are of little direct use to clients;
+ * we cover only those that are here. */
+ if ((*r)->installed_interface)
+ cout << left << setw(30) << " Root:" << " " << (*r)->installed_interface->root() << endl;
+ if ((*r)->syncable_interface)
+ cout << left << setw(30) << " Syncable:" << " " << "yes" << 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;
+}
+
+
+
diff --git a/doc/api/cplusplus/examples/example_stringify_formatter.cc b/doc/api/cplusplus/examples/example_stringify_formatter.cc
new file mode 100644
index 000000000..6f5d3b671
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_stringify_formatter.cc
@@ -0,0 +1,108 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_stringify_formatter.cc "example_stringify_formatter.cc" .
+ *
+ * \ingroup g_formatters
+ */
+
+/** \example example_stringify_formatter.cc
+ *
+ * This example demonstrates how to use StringifyFormatter.
+ *
+ * See \ref example_formatter.cc "example_formatter.cc" for how to create
+ * a custom Formatter.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <cstdlib>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_stringify_formatter", "EXAMPLE_STRINGIFY_FORMATTER_OPTIONS", "EXAMPLE_STRINGIFY_FORMATTER_CMDLINE");
+
+ /* We start with an Environment, respecting the user's '--environment' choice. */
+ tr1::shared_ptr<Environment> env(EnvironmentMaker::get_instance()->make_from_spec(
+ CommandLine::get_instance()->a_environment.argument()));
+
+ /* Fetch package IDs for installable 'sys-apps/paludis'. */
+ tr1::shared_ptr<const PackageIDSequence> ids(env->package_database()->query(
+ query::Matches(PackageDepSpec("sys-apps/paludis", pds_pm_permissive)) &
+ query::SupportsAction<InstallAction>(),
+ qo_order_by_version));
+
+ /* For each ID: */
+ for (PackageIDSet::ConstIterator i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ cout << stringify(**i) << ":" << endl;
+
+ /* Our formatter. It has no saved state, so we can use a single
+ * formatter for all of the keys. */
+ StringifyFormatter formatter;
+
+ /* We need to check that _key() methods don't return zero. */
+ if ((*i)->iuse_key())
+ {
+ cout << " " << (*i)->iuse_key()->human_name() << ":" << endl;
+ cout << " " << (*i)->iuse_key()->pretty_print_flat(formatter) << endl;
+ }
+
+ if ((*i)->keywords_key())
+ {
+ cout << " " << (*i)->keywords_key()->human_name() << ":" << endl;
+ cout << " " << (*i)->keywords_key()->pretty_print_flat(formatter) << endl;
+ }
+
+ if ((*i)->homepage_key())
+ {
+ cout << " " << (*i)->homepage_key()->human_name() << ":" << endl;
+ cout << " " << (*i)->homepage_key()->pretty_print_flat(formatter) << 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_SUCCESS;
+}
+
+
+
+
diff --git a/doc/api/cplusplus/examples/example_version_operator.cc b/doc/api/cplusplus/examples/example_version_operator.cc
new file mode 100644
index 000000000..1bea6e27a
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_version_operator.cc
@@ -0,0 +1,116 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_version_operator.cc "example_version_operator.cc" .
+ *
+ * \ingroup g_names
+ */
+
+/** \example example_version_operator.cc
+ *
+ * This example demonstrates how to use VersionOperator.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <set>
+#include <list>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+using std::boolalpha;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_version_operator", "EXAMPLE_VERSION_OPERATOR_OPTIONS", "EXAMPLE_VERSION_OPERATOR_CMDLINE");
+
+ /* Make a set of versions */
+ std::set<VersionSpec> versions;
+ versions.insert(VersionSpec("1.0"));
+ versions.insert(VersionSpec("1.1"));
+ versions.insert(VersionSpec("1.2"));
+ versions.insert(VersionSpec("1.2-r1"));
+ versions.insert(VersionSpec("2.0"));
+
+ /* And a list of operators */
+ std::list<VersionOperator> operators;
+ operators.push_back(VersionOperator("="));
+ operators.push_back(VersionOperator(">="));
+ operators.push_back(VersionOperator("~"));
+ operators.push_back(VersionOperator("<"));
+ operators.push_back(VersionOperator("~>"));
+
+ /* Display a header */
+ cout << " " << left << setw(8) << "LHS" << " | " << left << setw(8) << "RHS";
+ for (std::list<VersionOperator>::const_iterator o(operators.begin()), o_end(operators.end()) ;
+ o != o_end ; ++o)
+ cout << " | " << setw(8) << *o;
+ cout << endl << std::string(10, '-');
+ for (unsigned x(0) ; x <= operators.size() ; ++x)
+ cout << "+" << std::string(10, '-');
+ cout << endl;
+
+ /* For each pair of versions... */
+ for (std::set<VersionSpec>::const_iterator v1(versions.begin()), v1_end(versions.end()) ;
+ v1 != v1_end ; ++v1)
+ {
+ for (std::set<VersionSpec>::const_iterator v2(versions.begin()), v2_end(versions.end()) ;
+ v2 != v2_end ; ++v2)
+ {
+ cout << " " << left << setw(8) << *v1 << " | " << left << setw(8) << *v2;
+
+ /* Apply all of our operators, and show the results */
+ for (std::list<VersionOperator>::const_iterator o(operators.begin()), o_end(operators.end()) ;
+ o != o_end ; ++o)
+ {
+ /* VersionOperator::as_version_spec_comparator returns a
+ * binary boolean functor. */
+ cout << " | " << left << setw(8) << boolalpha << (o->as_version_spec_comparator()(*v1, *v2));
+ }
+
+ 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_SUCCESS;
+}
+
+
+
diff --git a/doc/api/cplusplus/examples/example_version_spec.cc b/doc/api/cplusplus/examples/example_version_spec.cc
new file mode 100644
index 000000000..186fd798c
--- /dev/null
+++ b/doc/api/cplusplus/examples/example_version_spec.cc
@@ -0,0 +1,99 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/** \file
+ *
+ * Example \ref example_version_spec.cc "example_version_spec.cc" .
+ *
+ * \ingroup g_names
+ */
+
+/** \example example_version_spec.cc
+ *
+ * This example demonstrates how to use VersionSpec.
+ */
+
+#include <paludis/paludis.hh>
+#include "example_command_line.hh"
+#include <iostream>
+#include <iomanip>
+#include <cstdlib>
+#include <set>
+
+using namespace paludis;
+using namespace examples;
+
+using std::cout;
+using std::endl;
+using std::setw;
+using std::left;
+using std::boolalpha;
+using std::hex;
+
+int main(int argc, char * argv[])
+{
+ try
+ {
+ CommandLine::get_instance()->run(argc, argv,
+ "example_version_spec", "EXAMPLE_VERSION_SPEC_OPTIONS", "EXAMPLE_VERSION_SPEC_CMDLINE");
+
+ /* Make a set of versions */
+ std::set<VersionSpec> versions;
+ versions.insert(VersionSpec("1.0"));
+ versions.insert(VersionSpec("1.1"));
+ versions.insert(VersionSpec("1.2"));
+ versions.insert(VersionSpec("1.2-r1"));
+ versions.insert(VersionSpec("2.0"));
+ versions.insert(VersionSpec("2.0-try1"));
+ versions.insert(VersionSpec("2.0-scm"));
+ versions.insert(VersionSpec("9999"));
+
+ /* For each version... */
+ for (std::set<VersionSpec>::const_iterator v(versions.begin()), v_end(versions.end()) ;
+ v != v_end ; ++v)
+ {
+ /* Versions are stringifiable */
+ cout << *v << ":" << endl;
+
+ /* Show the output of various members. Not all of these are of much
+ * direct use. */
+ cout << " " << left << setw(24) << "Hash value:" << " " << "0x" << hex << v->hash_value() << endl;
+ cout << " " << left << setw(24) << "Remove revision:" << " " << v->remove_revision() << endl;
+ cout << " " << left << setw(24) << "Revision only:" << " " << v->revision_only() << endl;
+ cout << " " << left << setw(24) << "Bump:" << " " << v->bump() << endl;
+ cout << " " << left << setw(24) << "Is scm?" << " " << boolalpha << v->is_scm() << endl;
+ cout << " " << left << setw(24) << "Has -try?" << " " << boolalpha << v->has_try_part() << endl;
+ cout << " " << left << setw(24) << "Has -scm?" << " " << boolalpha << v->has_scm_part() << 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_SUCCESS;
+}
+
+
+
+
diff --git a/doc/api/cplusplus/groups.doxygen b/doc/api/cplusplus/groups.doxygen
new file mode 100644
index 000000000..c81a096e3
--- /dev/null
+++ b/doc/api/cplusplus/groups.doxygen
@@ -0,0 +1,370 @@
+/* vim: set ft=cpp tw=80 sw=4 et : */
+
+using namespace paludis;
+
+/** \defgroup g_paludis Paludis
+ *
+ * Paludis public API.
+ */
+
+/** \defgroup g_about About
+ *
+ * \ingroup g_paludis
+ *
+ * Information about Paludis (version, build options etc).
+ *
+ * \section Examples
+ *
+ * - \ref example_about.cc "example_about.cc"
+ */
+
+/** \defgroup g_actions Actions
+ *
+ * \ingroup g_package_id
+ *
+ * Action-related classes are used to provide the information needed by a
+ * PackageID to perform operations such as installing, uninstalling and fetching.
+ *
+ * \section Examples
+ *
+ * - \ref example_action.cc "example_action.cc"
+ */
+
+/** \defgroup g_contents Contents
+ *
+ * \ingroup g_metadata_key
+ *
+ * Contents heirarchies can be used to iterate over the content of an installed
+ * or binary package.
+ *
+ * \section Examples
+ *
+ * - \ref example_contents.cc "example_contents.cc"
+ */
+
+/** \defgroup g_dep_spec Dependency specifications
+ *
+ * \ingroup g_paludis
+ *
+ * Dependency specification classes provide an abstraction representing
+ * dependency and dependency-like (for example, SRC_URI, RESTRICT)
+ * heirarchies.
+ *
+ * \section Examples
+ *
+ * - \ref example_dep_label.cc "example_dep_label.cc"
+ * - \ref example_dep_spec.cc "example_dep_spec.cc"
+ * - \ref example_dep_tag.cc "example_dep_tag.cc"
+ * - \ref example_dep_tree.cc "example_dep_tree.cc"
+ * - \ref example_dep_spec_flattener.cc "example_dep_spec_flattener.cc"
+ */
+
+/** \defgroup g_environment Environment
+ *
+ * \ingroup g_paludis
+ *
+ * An Environment subclass is the starting point for most programs. For programs
+ * that use user configuration, EnvironmentMaker is used to obtain an instance.
+ * For programs that operate without configuration, NoConfigEnvironment should
+ * be used instead.
+ *
+ * \section Examples
+ *
+ * - \ref example_environment.cc "example_environment.cc"
+ */
+
+/** \defgroup g_exceptions Exceptions
+ *
+ * Exceptions and related utility classes.
+ *
+ * \ingroup g_paludis
+ */
+
+/** \defgroup g_formatters Formatters
+ *
+ * \ingroup g_metadata_key
+ *
+ * Formatters are used in various places (such as MetadataKey pretty_print methods)
+ * to apply user-defined formatting to parts of text generated for display. They
+ * allow clients to, for example, display accepted and unaccepted use flag names
+ * in different colours, without needing to rewrite the entire pretty printing
+ * system.
+ *
+ * \section Examples
+ *
+ * - \ref example_formatter.cc "example_formatter.cc"
+ * - \ref example_stringify_formatter.cc "example_stringify_formatter.cc"
+ */
+
+/** \defgroup g_package_id Package IDs
+ *
+ * \ingroup g_paludis
+ *
+ * A PackageID represents a particular package version in a Repository. It has
+ * various pieces of associated information, including a name, a version, an
+ * owning repository, a slot, a collection of metadata keys and a collection of
+ * masks.
+ *
+ * \section Examples
+ *
+ * - \ref example_package_id.cc "example_package_id.cc"
+ * - \ref example_action.cc "example_action.cc"
+ * - \ref example_mask.cc "example_mask.cc"
+ * - \ref example_metadata_key.cc "example_metadata_key.cc"
+ */
+
+/** \defgroup g_mask Masks
+ *
+ * \ingroup g_package_id
+ *
+ * A mask represents one reason why a PackageID is masked (not installable).
+ *
+ * \section Examples
+ *
+ * - \ref example_mask.cc "example_mask.cc"
+ */
+
+/** \defgroup g_metadata_key Metadata Keys
+ *
+ * \ingroup g_package_id
+ *
+ * A metadata key hold a piece of information about a PackageID.
+ *
+ * \section Examples
+ *
+ * - \ref example_metadata_key.cc "example_metadata_key.cc"
+ */
+
+/** \defgroup g_repository Repository
+ *
+ * \ingroup g_paludis
+ *
+ * A Repository subclass represents a repository that holds a collection of
+ * packages.
+ *
+ * \section Examples
+ *
+ * - \ref example_repository.cc "example_repository.cc"
+ */
+
+/** \defgroup g_query Query
+ *
+ * \ingroup g_package_database
+ *
+ * Queries are used by PackageDatabase::query. They provide a flexible, mergeable,
+ * efficient way of specifying which IDs should be returned in the result.
+ *
+ * \section Examples
+ *
+ * - \ref example_query.cc "example_query.cc"
+ * - \ref example_query_delegate.cc "example_query_delegate.cc"
+ * - \ref example_match_package.cc "example_match_package.cc"
+ */
+
+/** \defgroup g_package_database Package Database
+ *
+ * \ingroup g_paludis
+ *
+ * A PackageDatabase, which is owned by an Environment, contains a number of
+ * Repository instances and supports various querying methods.
+ *
+ * \section Examples
+ *
+ * - \ref example_package_database.cc "example_package_database.cc"
+ * - \ref example_query.cc "example_query.cc"
+ * - \ref example_query_delegate.cc "example_query_delegate.cc"
+ */
+
+/** \defgroup g_names Names and Versions
+ *
+ * \ingroup g_paludis
+ *
+ * Paludis uses 'smart' classes for holding names and versions, allowing for
+ * substantially more static checking and much more convenient and useful
+ * runtime checking of data.
+ *
+ * \section Examples
+ *
+ * - \ref example_name.cc "example_name.cc"
+ * - \ref example_version_spec.cc "example_version_spec.cc"
+ * - \ref example_version_operator.cc "example_version_operator.cc"
+ */
+
+/** \defgroup g_dep_list Dependency Resolution
+ *
+ * \ingroup g_paludis
+ *
+ * There are two classes that provide dependency resolution: DepList (for
+ * installing) and UninstallList (for uninstalling). Actual installing and
+ * uninstalling is usually done by InstallTask and UninstallTask respectively.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_tasks Tasks
+ *
+ * \ingroup g_paludis
+ *
+ * Tasks simplify certain common operations. For example, when installing a
+ * group of packages, a client has to handle target and dependency resolution,
+ * fetching and uninstalling appropriate packages with error handling, and all
+ * the hooks that should be called. Rather than doing this by hand, a client
+ * will typically subclass InstallTask.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_hooks Hooks
+ *
+ * \ingroup g_paludis
+ *
+ * Hooks can be used to run additional commands at various well-defined trigger
+ * points.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_digests Digests
+ *
+ * \ingroup g_paludis
+ *
+ * Paludis includes some basic digest algorithms to avoid external dependencies.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_utils Utilities
+ *
+ * \ingroup g_paludis
+ *
+ * The utilities library contains various classes that are not core package
+ * management functionality.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_config_file Configuration Files
+ *
+ * \ingroup g_utils
+ *
+ * The various ConfigFile subclasses simplify handling configuration files in
+ * various common formats.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_strings Strings
+ *
+ * \ingroup g_utils
+ *
+ * We provide various functions and classes that simplify common string handling
+ * operations.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_fs Filesystem
+ *
+ * \ingroup g_utils
+ *
+ * We provide various functions and classes that simplify various common
+ * filesystem operations.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_data_structures Data Structures
+ *
+ * \ingroup g_utils
+ *
+ * Various data structures.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_iterator Iterators
+ *
+ * \ingroup g_utils
+ *
+ * Various iterator utilities.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_oo OO Design Helpers
+ *
+ * \ingroup g_utils
+ *
+ * Various OO utility classes.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_log Logging
+ *
+ * \ingroup g_utils
+ *
+ * Paludis includes a basic logging facility.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_system System
+ *
+ * \ingroup g_utils
+ *
+ * Various utilities for interacting with lower-level system things.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_visitors Visitors
+ *
+ * \ingroup g_utils
+ *
+ * Visitors are a way of providing subtype-polymorphic behaviour without
+ * modifying the visitable class.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
+/** \defgroup g_threads Threads
+ *
+ * \ingroup g_utils
+ *
+ * Paludis includes some basic thread classes. Most users will not have threads
+ * enabled at the moment.
+ *
+ * \section Examples
+ *
+ * - None at this time.
+ */
+
diff --git a/doc/api/cplusplus/main_page.doxygen b/doc/api/cplusplus/main_page.doxygen
new file mode 100644
index 000000000..a54c41717
--- /dev/null
+++ b/doc/api/cplusplus/main_page.doxygen
@@ -0,0 +1,20 @@
+/* vim: set ft=cpp tw=80 sw=4 et : */
+
+/** \mainpage
+
+This is the Paludis core API documentation.
+
+To find your way around:
+
+- Use the <a href="modules.html">Modules</a> link, rather than trying to browse through
+ raw class lists.
+- See the <a href="examples.html">Examples</a>.
+
+Some classes you may find useful:
+
+- paludis::Environment, which is usually created using paludis::EnvironmentMaker
+- paludis::PackageDatabase
+- paludis::Repository and the associated interface classes
+- paludis::PackageID
+
+*/
diff --git a/doc/api/cplusplus/namespaces.doxygen b/doc/api/cplusplus/namespaces.doxygen
new file mode 100644
index 000000000..1888fbf42
--- /dev/null
+++ b/doc/api/cplusplus/namespaces.doxygen
@@ -0,0 +1,14 @@
+/* vim: set ft=cpp tw=80 sw=4 et : */
+
+/** \namespace paludis
+ * Paludis library code.
+ *
+ * \ingroup g_paludis
+ */
+
+/** \namespace paludis::args
+ * Commandline argument handling.
+ *
+ * \ingroup g_args
+ */
+
diff --git a/doc/api/cplusplus/references.doxygen b/doc/api/cplusplus/references.doxygen
new file mode 100644
index 000000000..3bc3e59d5
--- /dev/null
+++ b/doc/api/cplusplus/references.doxygen
@@ -0,0 +1,47 @@
+/* vim: set ft=cpp tw=80 sw=4 et : */
+
+/**
+\page References References
+
+\section ReferencesBooks Books
+
+\anchor AppCrypt
+<strong>AppCrypt</strong>: Applied Cryptography Second Edition / Bruce
+Schneier / Wiley / ISBN 0-471-11709-9
+
+\anchor EffCpp
+<strong>EffCpp</strong>: Effective C++ Third Edition / Scott Meyers /
+Addison-Wesley / ISBN 0-321-33487-6
+
+\anchor EffSTL
+<strong>EffSTL</strong>: Effective STL / Scott Meyers / Addison-Wesley / ISBN
+0-201-74962-9
+
+\anchor GoF
+<strong>GoF</strong>: Design Patterns: Elements of Reusable Object-Oriented
+Software / Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides /
+Addison-Wesley / ISBN 0-201-63361-2
+
+\anchor MCppD
+<strong>MCppD</strong>: Modern C++ Design: Generic Programming and Design
+Patterns Applied / Andrei Alexandrescu / Addison-Wesley / ISBN 0-201-70431-5
+
+\anchor TaoCP2
+<strong>TaoCP2</strong>: The Art of Computer Programming, Volume 2:
+Seminumerical Algorithms, Third Edition / Donald E. Knuth / Addison-Wesley /
+ISBN 0-201-89684-2
+
+\anchor TCppSL
+<strong>TCppSL</strong>: The C++ Standard Library / Nicolai M. Josuttis /
+Addison-Wesley / ISBN 0-201-37926-0
+
+\anchor TCppSLE
+<strong>TCppSLE</strong>: The C++ Standard Library Extensions / Pete Becker /
+Addison-Wesley / ISBN 0-321-41299-0
+
+\anchor TCppPL
+<strong>TCppPL</strong>: The C++ Programming Language Third Edition / Bjarne
+Stroustrup / Addison-Wesley / ISBN 0-201-88954-4
+
+*/
+