aboutsummaryrefslogtreecommitdiff
path: root/0.8.0/paludis
diff options
context:
space:
mode:
Diffstat (limited to '0.8.0/paludis')
-rw-r--r--0.8.0/paludis/Makefile.am.m4100
-rw-r--r--0.8.0/paludis/about.hh.in117
-rw-r--r--0.8.0/paludis/about_TEST.cc86
-rw-r--r--0.8.0/paludis/args/Makefile.am53
-rw-r--r--0.8.0/paludis/args/args.cc27
-rw-r--r--0.8.0/paludis/args/args.hh35
-rw-r--r--0.8.0/paludis/args/args_TEST.cc176
-rw-r--r--0.8.0/paludis/args/args_dumper.cc81
-rw-r--r--0.8.0/paludis/args/args_dumper.hh80
-rw-r--r--0.8.0/paludis/args/args_error.cc45
-rw-r--r--0.8.0/paludis/args/args_error.hh87
-rw-r--r--0.8.0/paludis/args/args_group.cc78
-rw-r--r--0.8.0/paludis/args/args_group.hh117
-rw-r--r--0.8.0/paludis/args/args_handler.cc231
-rw-r--r--0.8.0/paludis/args/args_handler.hh181
-rw-r--r--0.8.0/paludis/args/args_option.cc226
-rw-r--r--0.8.0/paludis/args/args_option.hh361
-rw-r--r--0.8.0/paludis/args/args_visitor.cc97
-rw-r--r--0.8.0/paludis/args/args_visitor.hh100
-rw-r--r--0.8.0/paludis/args/bad_argument.cc35
-rw-r--r--0.8.0/paludis/args/bad_argument.hh54
-rw-r--r--0.8.0/paludis/args/man.cc81
-rw-r--r--0.8.0/paludis/args/man.hh37
-rw-r--r--0.8.0/paludis/config_file.cc453
-rw-r--r--0.8.0/paludis/config_file.hh304
-rw-r--r--0.8.0/paludis/config_file_TEST.cc332
-rwxr-xr-x0.8.0/paludis/config_file_TEST_cleanup.sh10
-rwxr-xr-x0.8.0/paludis/config_file_TEST_setup.sh9
-rw-r--r--0.8.0/paludis/contents.cc97
-rw-r--r--0.8.0/paludis/contents.hh208
-rw-r--r--0.8.0/paludis/dep_atom.cc377
-rw-r--r--0.8.0/paludis/dep_atom.hh526
-rw-r--r--0.8.0/paludis/dep_atom_TEST.cc169
-rw-r--r--0.8.0/paludis/dep_atom_flattener.cc128
-rw-r--r--0.8.0/paludis/dep_atom_flattener.hh89
-rw-r--r--0.8.0/paludis/dep_atom_pretty_printer.cc91
-rw-r--r--0.8.0/paludis/dep_atom_pretty_printer.hh81
-rw-r--r--0.8.0/paludis/dep_list.cc837
-rw-r--r--0.8.0/paludis/dep_list.hh265
-rw-r--r--0.8.0/paludis/dep_list.sr41
-rw-r--r--0.8.0/paludis/dep_list_TEST.cc1552
-rw-r--r--0.8.0/paludis/dep_tag.cc199
-rw-r--r--0.8.0/paludis/dep_tag.hh278
-rw-r--r--0.8.0/paludis/dep_tag.sr10
-rw-r--r--0.8.0/paludis/digests/Makefile.am42
-rw-r--r--0.8.0/paludis/digests/md5.cc239
-rw-r--r--0.8.0/paludis/digests/md5.hh61
-rw-r--r--0.8.0/paludis/digests/md5_TEST.cc114
-rw-r--r--0.8.0/paludis/digests/rmd160.cc231
-rw-r--r--0.8.0/paludis/digests/rmd160.hh65
-rw-r--r--0.8.0/paludis/digests/rmd160_TEST.cc116
-rw-r--r--0.8.0/paludis/digests/sha256.cc228
-rw-r--r--0.8.0/paludis/digests/sha256.hh61
-rw-r--r--0.8.0/paludis/digests/sha256_TEST.cc446
-rw-r--r--0.8.0/paludis/ebin.cc212
-rw-r--r--0.8.0/paludis/ebin.hh175
-rw-r--r--0.8.0/paludis/ebin.sr66
-rw-r--r--0.8.0/paludis/ebuild.cc382
-rw-r--r--0.8.0/paludis/ebuild.hh293
-rw-r--r--0.8.0/paludis/ebuild.sr93
-rw-r--r--0.8.0/paludis/environment.cc474
-rw-r--r--0.8.0/paludis/environment.hh304
-rw-r--r--0.8.0/paludis/environment/Makefile.am6
-rw-r--r--0.8.0/paludis/environment/default/Makefile.am47
-rw-r--r--0.8.0/paludis/environment/default/default_config.cc740
-rw-r--r--0.8.0/paludis/environment/default/default_config.hh224
-rw-r--r--0.8.0/paludis/environment/default/default_environment.cc530
-rw-r--r--0.8.0/paludis/environment/default/default_environment.hh81
-rw-r--r--0.8.0/paludis/environment/default/default_environment_TEST.cc131
-rwxr-xr-x0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/environment/default/default_environment_TEST_setup.sh80
-rw-r--r--0.8.0/paludis/environment/no_config/Makefile.am41
-rw-r--r--0.8.0/paludis/environment/no_config/no_config_environment.cc197
-rw-r--r--0.8.0/paludis/environment/no_config/no_config_environment.hh57
-rw-r--r--0.8.0/paludis/environment/no_config/no_config_environment.sr19
-rw-r--r--0.8.0/paludis/environment/test/Makefile.am21
-rw-r--r--0.8.0/paludis/environment/test/test_environment.cc85
-rw-r--r--0.8.0/paludis/environment/test/test_environment.hh84
-rw-r--r--0.8.0/paludis/files.m440
-rw-r--r--0.8.0/paludis/hashed_containers.cc108
-rw-r--r--0.8.0/paludis/hashed_containers.hh.in345
-rw-r--r--0.8.0/paludis/hashed_containers_TEST.cc50
-rw-r--r--0.8.0/paludis/libxml/Makefile.am37
-rw-r--r--0.8.0/paludis/libxml/libxml.cc41
-rw-r--r--0.8.0/paludis/libxml/libxml.hh65
-rw-r--r--0.8.0/paludis/mask_reasons.cc76
-rw-r--r--0.8.0/paludis/mask_reasons.hh71
-rw-r--r--0.8.0/paludis/match_package.cc132
-rw-r--r--0.8.0/paludis/match_package.hh149
-rw-r--r--0.8.0/paludis/name.cc298
-rw-r--r--0.8.0/paludis/name.hh363
-rw-r--r--0.8.0/paludis/name_TEST.cc209
-rw-r--r--0.8.0/paludis/package_database.cc340
-rw-r--r--0.8.0/paludis/package_database.hh300
-rw-r--r--0.8.0/paludis/package_database_TEST.cc199
-rw-r--r--0.8.0/paludis/package_database_entry.hh42
-rw-r--r--0.8.0/paludis/package_database_entry.sr22
-rw-r--r--0.8.0/paludis/paludis.cc8
-rw-r--r--0.8.0/paludis/paludis.hh.m447
-rw-r--r--0.8.0/paludis/portage_dep_lexer.cc112
-rw-r--r--0.8.0/paludis/portage_dep_lexer.hh124
-rw-r--r--0.8.0/paludis/portage_dep_lexer_TEST.cc250
-rw-r--r--0.8.0/paludis/portage_dep_parser.cc286
-rw-r--r--0.8.0/paludis/portage_dep_parser.hh197
-rw-r--r--0.8.0/paludis/portage_dep_parser_TEST.cc340
-rw-r--r--0.8.0/paludis/qa/Makefile.am.m4100
-rw-r--r--0.8.0/paludis/qa/changelog_check.cc75
-rw-r--r--0.8.0/paludis/qa/changelog_check.hh51
-rw-r--r--0.8.0/paludis/qa/check.cc32
-rw-r--r--0.8.0/paludis/qa/check.hh60
-rw-r--r--0.8.0/paludis/qa/check_result.cc44
-rw-r--r--0.8.0/paludis/qa/check_result.hh93
-rw-r--r--0.8.0/paludis/qa/check_result_TEST.cc52
-rw-r--r--0.8.0/paludis/qa/create_metadata_check.cc67
-rw-r--r--0.8.0/paludis/qa/create_metadata_check.hh56
-rw-r--r--0.8.0/paludis/qa/defaults_check.cc154
-rw-r--r--0.8.0/paludis/qa/defaults_check.hh53
-rw-r--r--0.8.0/paludis/qa/defaults_check_TEST.cc60
-rwxr-xr-x0.8.0/paludis/qa/defaults_check_TEST_cleanup.sh12
-rwxr-xr-x0.8.0/paludis/qa/defaults_check_TEST_setup.sh43
-rw-r--r--0.8.0/paludis/qa/dep_any_check.cc143
-rw-r--r--0.8.0/paludis/qa/dep_any_check.hh51
-rw-r--r--0.8.0/paludis/qa/dep_flags_check.cc174
-rw-r--r--0.8.0/paludis/qa/dep_flags_check.hh51
-rw-r--r--0.8.0/paludis/qa/dep_packages_check.cc149
-rw-r--r--0.8.0/paludis/qa/dep_packages_check.hh51
-rw-r--r--0.8.0/paludis/qa/deprecated_functions_check.cc82
-rw-r--r--0.8.0/paludis/qa/deprecated_functions_check.hh51
-rw-r--r--0.8.0/paludis/qa/deps_exist_check.cc139
-rw-r--r--0.8.0/paludis/qa/deps_exist_check.hh51
-rw-r--r--0.8.0/paludis/qa/deps_visible_check.cc142
-rw-r--r--0.8.0/paludis/qa/deps_visible_check.hh51
-rw-r--r--0.8.0/paludis/qa/description_check.cc81
-rw-r--r--0.8.0/paludis/qa/description_check.hh51
-rw-r--r--0.8.0/paludis/qa/digest_collisions_check.cc88
-rw-r--r--0.8.0/paludis/qa/digest_collisions_check.hh51
-rw-r--r--0.8.0/paludis/qa/ebuild_check.cc35
-rw-r--r--0.8.0/paludis/qa/ebuild_check.hh75
-rw-r--r--0.8.0/paludis/qa/ebuild_check.sr10
-rw-r--r--0.8.0/paludis/qa/ebuild_count_check.cc58
-rw-r--r--0.8.0/paludis/qa/ebuild_count_check.hh51
-rw-r--r--0.8.0/paludis/qa/extract_check.cc128
-rw-r--r--0.8.0/paludis/qa/extract_check.hh51
-rw-r--r--0.8.0/paludis/qa/file_check.cc33
-rw-r--r--0.8.0/paludis/qa/file_check.hh86
-rw-r--r--0.8.0/paludis/qa/file_permissions_check.cc60
-rw-r--r--0.8.0/paludis/qa/file_permissions_check.hh51
-rw-r--r--0.8.0/paludis/qa/file_permissions_check_TEST.cc90
-rwxr-xr-x0.8.0/paludis/qa/file_permissions_check_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/qa/file_permissions_check_TEST_setup.sh14
-rw-r--r--0.8.0/paludis/qa/filename_check.cc52
-rw-r--r--0.8.0/paludis/qa/filename_check.hh56
-rw-r--r--0.8.0/paludis/qa/files.m452
-rw-r--r--0.8.0/paludis/qa/files_dir_size_check.cc87
-rw-r--r--0.8.0/paludis/qa/files_dir_size_check.hh51
-rw-r--r--0.8.0/paludis/qa/glep_31_check.cc126
-rw-r--r--0.8.0/paludis/qa/glep_31_check.hh55
-rw-r--r--0.8.0/paludis/qa/glep_31_check_TEST.cc77
-rw-r--r--0.8.0/paludis/qa/gpg_check.cc62
-rw-r--r--0.8.0/paludis/qa/gpg_check.hh51
-rw-r--r--0.8.0/paludis/qa/gpg_check_TEST.cc65
-rwxr-xr-x0.8.0/paludis/qa/gpg_check_TEST_cleanup.sh8
-rwxr-xr-x0.8.0/paludis/qa/gpg_check_TEST_setup.sh9
-rw-r--r--0.8.0/paludis/qa/has_ebuilds_check.cc50
-rw-r--r--0.8.0/paludis/qa/has_ebuilds_check.hh51
-rw-r--r--0.8.0/paludis/qa/has_ebuilds_check_TEST.cc66
-rwxr-xr-x0.8.0/paludis/qa/has_ebuilds_check_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/qa/has_ebuilds_check_TEST_setup.sh12
-rw-r--r--0.8.0/paludis/qa/has_misc_files_check.cc54
-rw-r--r--0.8.0/paludis/qa/has_misc_files_check.hh51
-rw-r--r--0.8.0/paludis/qa/has_misc_files_check_TEST.cc102
-rwxr-xr-x0.8.0/paludis/qa/has_misc_files_check_TEST_cleanup.sh12
-rwxr-xr-x0.8.0/paludis/qa/has_misc_files_check_TEST_setup.sh23
-rw-r--r--0.8.0/paludis/qa/homepage_check.cc73
-rw-r--r--0.8.0/paludis/qa/homepage_check.hh51
-rw-r--r--0.8.0/paludis/qa/inherits_check.cc91
-rw-r--r--0.8.0/paludis/qa/inherits_check.hh51
-rw-r--r--0.8.0/paludis/qa/iuse_check.cc98
-rw-r--r--0.8.0/paludis/qa/iuse_check.hh56
-rw-r--r--0.8.0/paludis/qa/keywords_check.cc88
-rw-r--r--0.8.0/paludis/qa/keywords_check.hh51
-rw-r--r--0.8.0/paludis/qa/license_check.cc141
-rw-r--r--0.8.0/paludis/qa/license_check.hh51
-rw-r--r--0.8.0/paludis/qa/message.cc34
-rw-r--r--0.8.0/paludis/qa/message.hh52
-rw-r--r--0.8.0/paludis/qa/message.sr9
-rw-r--r--0.8.0/paludis/qa/message_TEST.cc42
-rw-r--r--0.8.0/paludis/qa/metadata_check.cc116
-rw-r--r--0.8.0/paludis/qa/metadata_check.hh51
-rw-r--r--0.8.0/paludis/qa/metadata_file.cc136
-rw-r--r--0.8.0/paludis/qa/metadata_file.hh51
-rw-r--r--0.8.0/paludis/qa/metadata_file_TEST.cc72
-rw-r--r--0.8.0/paludis/qa/package_dir_check.cc33
-rw-r--r--0.8.0/paludis/qa/package_dir_check.hh80
-rw-r--r--0.8.0/paludis/qa/package_name_check.cc62
-rw-r--r--0.8.0/paludis/qa/package_name_check.hh56
-rw-r--r--0.8.0/paludis/qa/package_name_check_TEST.cc104
-rwxr-xr-x0.8.0/paludis/qa/package_name_check_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/qa/package_name_check_TEST_setup.sh14
-rw-r--r--0.8.0/paludis/qa/parse_deps_check.cc97
-rw-r--r--0.8.0/paludis/qa/parse_deps_check.hh56
-rw-r--r--0.8.0/paludis/qa/pdepend_overlap_check.cc144
-rw-r--r--0.8.0/paludis/qa/pdepend_overlap_check.hh51
-rw-r--r--0.8.0/paludis/qa/qa.cc21
-rw-r--r--0.8.0/paludis/qa/qa.hh.m438
-rw-r--r--0.8.0/paludis/qa/qa_environment.cc128
-rw-r--r--0.8.0/paludis/qa/qa_environment.hh76
-rw-r--r--0.8.0/paludis/qa/qa_environment.sr14
-rw-r--r--0.8.0/paludis/qa/qa_environment_TEST.cc60
-rwxr-xr-x0.8.0/paludis/qa/qa_environment_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/qa/qa_environment_TEST_setup.sh36
-rw-r--r--0.8.0/paludis/qa/restrict_check.cc97
-rw-r--r--0.8.0/paludis/qa/restrict_check.hh51
-rw-r--r--0.8.0/paludis/qa/slot_check.cc73
-rw-r--r--0.8.0/paludis/qa/slot_check.hh51
-rw-r--r--0.8.0/paludis/qa/src_uri_check.cc193
-rw-r--r--0.8.0/paludis/qa/src_uri_check.hh51
-rw-r--r--0.8.0/paludis/qa/whitespace_check.cc123
-rw-r--r--0.8.0/paludis/qa/whitespace_check.hh51
-rw-r--r--0.8.0/paludis/qualified_package_name.sr23
-rw-r--r--0.8.0/paludis/repositories/Makefile.am5
-rw-r--r--0.8.0/paludis/repositories/cran/Makefile.am97
-rw-r--r--0.8.0/paludis/repositories/cran/cran_dep_parser.cc61
-rw-r--r--0.8.0/paludis/repositories/cran/cran_dep_parser.hh21
-rw-r--r--0.8.0/paludis/repositories/cran/cran_dep_parser_TEST.cc149
-rw-r--r--0.8.0/paludis/repositories/cran/cran_description.cc103
-rw-r--r--0.8.0/paludis/repositories/cran/cran_description.hh129
-rw-r--r--0.8.0/paludis/repositories/cran/cran_installed_repository.cc599
-rw-r--r--0.8.0/paludis/repositories/cran/cran_installed_repository.hh137
-rw-r--r--0.8.0/paludis/repositories/cran/cran_installed_repository.sr23
-rw-r--r--0.8.0/paludis/repositories/cran/cran_repository.cc637
-rw-r--r--0.8.0/paludis/repositories/cran/cran_repository.hh137
-rw-r--r--0.8.0/paludis/repositories/cran/cran_repository.sr27
-rw-r--r--0.8.0/paludis/repositories/cran/cran_repository_TEST.cc97
-rwxr-xr-x0.8.0/paludis/repositories/cran/cran_repository_TEST_cleanup.sh8
-rwxr-xr-x0.8.0/paludis/repositories/cran/cran_repository_TEST_setup.sh57
-rw-r--r--0.8.0/paludis/repositories/fake/Makefile.am31
-rw-r--r--0.8.0/paludis/repositories/fake/fake_installed_repository.cc49
-rw-r--r--0.8.0/paludis/repositories/fake/fake_installed_repository.hh41
-rw-r--r--0.8.0/paludis/repositories/fake/fake_repository.cc47
-rw-r--r--0.8.0/paludis/repositories/fake/fake_repository.hh40
-rw-r--r--0.8.0/paludis/repositories/fake/fake_repository_base.cc258
-rw-r--r--0.8.0/paludis/repositories/fake/fake_repository_base.hh146
-rw-r--r--0.8.0/paludis/repositories/nothing/Makefile.am40
-rw-r--r--0.8.0/paludis/repositories/nothing/nothing_repository.cc256
-rw-r--r--0.8.0/paludis/repositories/nothing/nothing_repository.hh116
-rw-r--r--0.8.0/paludis/repositories/nothing/nothing_repository.sr23
-rw-r--r--0.8.0/paludis/repositories/portage/Makefile.am127
-rw-r--r--0.8.0/paludis/repositories/portage/glsa.cc233
-rw-r--r--0.8.0/paludis/repositories/portage/glsa.hh97
-rw-r--r--0.8.0/paludis/repositories/portage/glsa.sr8
-rw-r--r--0.8.0/paludis/repositories/portage/make_ebin_repository.cc114
-rw-r--r--0.8.0/paludis/repositories/portage/make_ebin_repository.hh35
-rw-r--r--0.8.0/paludis/repositories/portage/make_ebuild_repository.cc159
-rw-r--r--0.8.0/paludis/repositories/portage/make_ebuild_repository.hh38
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository.cc1004
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository.hh166
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_TEST.cc666
-rwxr-xr-x0.8.0/paludis/repositories/portage/portage_repository_TEST_cleanup.sh10
-rwxr-xr-x0.8.0/paludis/repositories/portage/portage_repository_TEST_setup.sh226
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_ebin_entries.cc379
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_ebin_entries.hh71
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_ebuild_entries.cc556
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_ebuild_entries.hh70
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_entries.cc38
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_entries.hh126
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_entry.cc32
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_exceptions.cc29
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_exceptions.hh53
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_news.cc284
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_news.hh134
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_params.cc8
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_params.hh42
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_params.sr34
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_profile.cc686
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_profile.hh125
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_profile_file.cc81
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_profile_file.hh45
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_sets.cc379
-rw-r--r--0.8.0/paludis/repositories/portage/portage_repository_sets.hh80
-rw-r--r--0.8.0/paludis/repositories/portage/xml_things.cc188
-rw-r--r--0.8.0/paludis/repositories/portage/xml_things_TEST.cc92
-rwxr-xr-x0.8.0/paludis/repositories/portage/xml_things_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/repositories/portage/xml_things_TEST_setup.sh115
-rw-r--r--0.8.0/paludis/repositories/vdb/Makefile.am66
-rw-r--r--0.8.0/paludis/repositories/vdb/vdb_repository.cc1179
-rw-r--r--0.8.0/paludis/repositories/vdb/vdb_repository.hh174
-rw-r--r--0.8.0/paludis/repositories/vdb/vdb_repository.sr24
-rw-r--r--0.8.0/paludis/repositories/vdb/vdb_repository_TEST.cc238
-rwxr-xr-x0.8.0/paludis/repositories/vdb/vdb_repository_TEST_cleanup.sh11
-rwxr-xr-x0.8.0/paludis/repositories/vdb/vdb_repository_TEST_setup.sh35
-rw-r--r--0.8.0/paludis/repositories/virtuals/Makefile.am61
-rw-r--r--0.8.0/paludis/repositories/virtuals/installed_virtuals_repository.cc322
-rw-r--r--0.8.0/paludis/repositories/virtuals/installed_virtuals_repository.hh91
-rw-r--r--0.8.0/paludis/repositories/virtuals/virtuals_repository.cc338
-rw-r--r--0.8.0/paludis/repositories/virtuals/virtuals_repository.hh87
-rw-r--r--0.8.0/paludis/repositories/virtuals/vr_entry.cc26
-rw-r--r--0.8.0/paludis/repositories/virtuals/vr_entry.hh119
-rw-r--r--0.8.0/paludis/repositories/virtuals/vr_entry.sr16
-rw-r--r--0.8.0/paludis/repository.cc181
-rw-r--r--0.8.0/paludis/repository.hh849
-rw-r--r--0.8.0/paludis/repository.sr65
-rw-r--r--0.8.0/paludis/repository_config_entry.sr21
-rw-r--r--0.8.0/paludis/repository_so_loader.cc127
-rw-r--r--0.8.0/paludis/selinux/Makefile.am25
-rw-r--r--0.8.0/paludis/selinux/security_context.cc242
-rw-r--r--0.8.0/paludis/selinux/security_context.hh170
-rw-r--r--0.8.0/paludis/syncer.cc264
-rw-r--r--0.8.0/paludis/syncer.hh133
-rw-r--r--0.8.0/paludis/syncer.sr17
-rw-r--r--0.8.0/paludis/tasks/Makefile.am32
-rw-r--r--0.8.0/paludis/tasks/install_task.cc378
-rw-r--r--0.8.0/paludis/tasks/install_task.hh139
-rw-r--r--0.8.0/paludis/tasks/sync_task.cc104
-rw-r--r--0.8.0/paludis/tasks/sync_task.hh79
-rw-r--r--0.8.0/paludis/tasks/uninstall_task.cc206
-rw-r--r--0.8.0/paludis/tasks/uninstall_task.hh133
-rw-r--r--0.8.0/paludis/test_extras.cc81
-rw-r--r--0.8.0/paludis/use_config_entry.sr19
-rw-r--r--0.8.0/paludis/util/Makefile.am.m464
-rw-r--r--0.8.0/paludis/util/attributes.hh.in63
-rw-r--r--0.8.0/paludis/util/collection.hh343
-rw-r--r--0.8.0/paludis/util/collection_concrete.hh280
-rw-r--r--0.8.0/paludis/util/compare.hh160
-rw-r--r--0.8.0/paludis/util/comparison_policy.hh517
-rw-r--r--0.8.0/paludis/util/counted_ptr.hh447
-rw-r--r--0.8.0/paludis/util/counted_ptr_TEST.cc373
-rw-r--r--0.8.0/paludis/util/destringify.cc34
-rw-r--r--0.8.0/paludis/util/destringify.hh152
-rw-r--r--0.8.0/paludis/util/destringify_TEST.cc113
-rw-r--r--0.8.0/paludis/util/dir_iterator.cc171
-rw-r--r--0.8.0/paludis/util/dir_iterator.hh117
-rw-r--r--0.8.0/paludis/util/dir_iterator_TEST.cc97
-rwxr-xr-x0.8.0/paludis/util/dir_iterator_TEST_cleanup.sh9
-rwxr-xr-x0.8.0/paludis/util/dir_iterator_TEST_setup.sh6
-rw-r--r--0.8.0/paludis/util/exception.cc127
-rw-r--r--0.8.0/paludis/util/exception.hh214
-rw-r--r--0.8.0/paludis/util/fast_unique_copy.hh84
-rw-r--r--0.8.0/paludis/util/fast_unique_copy_TEST.cc121
-rw-r--r--0.8.0/paludis/util/fd_holder.hh60
-rw-r--r--0.8.0/paludis/util/fd_output_stream.hh117
-rw-r--r--0.8.0/paludis/util/files.m443
-rw-r--r--0.8.0/paludis/util/fs_entry.cc439
-rw-r--r--0.8.0/paludis/util/fs_entry.hh332
-rw-r--r--0.8.0/paludis/util/fs_entry_TEST.cc368
-rwxr-xr-x0.8.0/paludis/util/fs_entry_TEST_cleanup.sh9
-rwxr-xr-x0.8.0/paludis/util/fs_entry_TEST_setup.sh17
-rw-r--r--0.8.0/paludis/util/instantiation_policy.hh291
-rw-r--r--0.8.0/paludis/util/instantiation_policy_TEST.cc191
-rw-r--r--0.8.0/paludis/util/is_file_with_extension.cc56
-rw-r--r--0.8.0/paludis/util/is_file_with_extension.hh67
-rw-r--r--0.8.0/paludis/util/is_file_with_extension_TEST.cc94
-rwxr-xr-x0.8.0/paludis/util/is_file_with_extension_TEST_cleanup.sh9
-rwxr-xr-x0.8.0/paludis/util/is_file_with_extension_TEST_setup.sh6
-rw-r--r--0.8.0/paludis/util/iterator.hh502
-rw-r--r--0.8.0/paludis/util/iterator_TEST.cc361
-rw-r--r--0.8.0/paludis/util/join.hh67
-rw-r--r--0.8.0/paludis/util/join_TEST.cc102
-rw-r--r--0.8.0/paludis/util/log.cc156
-rw-r--r--0.8.0/paludis/util/log.hh119
-rw-r--r--0.8.0/paludis/util/log_TEST.cc74
-rw-r--r--0.8.0/paludis/util/pipe.cc37
-rw-r--r--0.8.0/paludis/util/pipe.hh72
-rw-r--r--0.8.0/paludis/util/private_implementation_pattern.hh70
-rw-r--r--0.8.0/paludis/util/pstream.cc141
-rw-r--r--0.8.0/paludis/util/pstream.hh228
-rw-r--r--0.8.0/paludis/util/pstream_TEST.cc111
-rw-r--r--0.8.0/paludis/util/random.cc43
-rw-r--r--0.8.0/paludis/util/random.hh71
-rw-r--r--0.8.0/paludis/util/random_TEST.cc121
-rw-r--r--0.8.0/paludis/util/save.hh83
-rw-r--r--0.8.0/paludis/util/save_TEST.cc68
-rw-r--r--0.8.0/paludis/util/sr.hh45
-rw-r--r--0.8.0/paludis/util/stringify.hh168
-rw-r--r--0.8.0/paludis/util/stringify_TEST.cc129
-rw-r--r--0.8.0/paludis/util/strip.cc100
-rw-r--r--0.8.0/paludis/util/strip.hh130
-rw-r--r--0.8.0/paludis/util/strip_TEST.cc123
-rw-r--r--0.8.0/paludis/util/system.cc230
-rw-r--r--0.8.0/paludis/util/system.hh168
-rw-r--r--0.8.0/paludis/util/system_TEST.cc184
-rwxr-xr-x0.8.0/paludis/util/system_TEST_cleanup.sh9
-rwxr-xr-x0.8.0/paludis/util/system_TEST_setup.sh5
-rw-r--r--0.8.0/paludis/util/test_extras.cc73
-rw-r--r--0.8.0/paludis/util/tokeniser.cc28
-rw-r--r--0.8.0/paludis/util/tokeniser.hh245
-rw-r--r--0.8.0/paludis/util/tokeniser_TEST.cc139
-rw-r--r--0.8.0/paludis/util/util.hh.m442
-rw-r--r--0.8.0/paludis/util/validated.hh124
-rw-r--r--0.8.0/paludis/util/validated_TEST.cc126
-rw-r--r--0.8.0/paludis/util/virtual_constructor.hh243
-rw-r--r--0.8.0/paludis/util/virtual_constructor_TEST.cc190
-rw-r--r--0.8.0/paludis/util/visitor.hh359
-rw-r--r--0.8.0/paludis/util/visitor_TEST.cc190
-rw-r--r--0.8.0/paludis/version_metadata.cc155
-rw-r--r--0.8.0/paludis/version_metadata.hh288
-rw-r--r--0.8.0/paludis/version_metadata.sr93
-rw-r--r--0.8.0/paludis/version_operator.cc142
-rw-r--r--0.8.0/paludis/version_operator.hh148
-rw-r--r--0.8.0/paludis/version_operator_TEST.cc114
-rw-r--r--0.8.0/paludis/version_spec.cc395
-rw-r--r--0.8.0/paludis/version_spec.hh135
-rw-r--r--0.8.0/paludis/version_spec.sr12
-rw-r--r--0.8.0/paludis/version_spec_TEST.cc313
404 files changed, 54950 insertions, 0 deletions
diff --git a/0.8.0/paludis/Makefile.am.m4 b/0.8.0/paludis/Makefile.am.m4
new file mode 100644
index 0000000..071138e
--- /dev/null
+++ b/0.8.0/paludis/Makefile.am.m4
@@ -0,0 +1,100 @@
+ifdef(`__gnu__',`',`errprint(`This is not GNU m4...
+')m4exit(1)') include(`misc/generated-file.txt')
+
+dnl vim: set ft=m4 noet :
+
+define(`filelist', `')dnl
+define(`testlist', `')dnl
+define(`headerlist', `')dnl
+define(`srlist', `')dnl
+define(`srcleanlist', `')dnl
+define(`srheaderlist', `')dnl
+define(`testscriptlist', `')dnl
+define(`addtest', `define(`testlist', testlist `$1_TEST')dnl
+$1_TEST_SOURCES = $1_TEST.cc
+$1_TEST_LDADD = \
+ ihateautomake.o \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/environment/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
+ $(DYNAMIC_LD_LIBS)
+$1_TEST_CXXFLAGS = -I$(top_srcdir)
+')dnl
+define(`addtestscript', `define(`testscriptlist', testscriptlist `$1_TEST_setup.sh $1_TEST_cleanup.sh')')dnl
+define(`addhh', `define(`filelist', filelist `$1.hh')define(`headerlist', headerlist `$1.hh')')dnl
+define(`addhhx', `define(`filelist', filelist `$1.hh')')dnl
+define(`addcc', `define(`filelist', filelist `$1.cc')')dnl
+define(`addimpl', `define(`filelist', filelist `$1-impl.hh')')dnl
+define(`addsr', `define(`srlist', srlist `$1.sr')dnl
+define(`srcleanlist', srcleanlist `$1-sr.hh $1-sr.cc')dnl
+define(`srheaderlist', srheaderlist `$1-sr.hh')dnl
+$1-sr.hh : $1.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --header $`'(srcdir)/$1.sr > $`'@
+
+$1-sr.cc : $1.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --source $`'(srcdir)/$1.sr > $`'@
+
+')dnl
+define(`addthis', `dnl
+ifelse(`$2', `hh', `addhh(`$1')', `')dnl
+ifelse(`$2', `hhx', `addhhx(`$1')', `')dnl
+ifelse(`$2', `cc', `addcc(`$1')', `')dnl
+ifelse(`$2', `sr', `addsr(`$1')', `')dnl
+ifelse(`$2', `impl', `addimpl(`$1')', `')dnl
+ifelse(`$2', `test', `addtest(`$1')', `')dnl
+ifelse(`$2', `testscript', `addtestscript(`$1')', `')')dnl
+define(`add', `addthis(`$1',`$2')addthis(`$1',`$3')addthis(`$1',`$4')dnl
+addthis(`$1',`$5')addthis(`$1',`$6')')dnl
+
+include(`paludis/files.m4')
+
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda ihateautomake.cc ihateautomake.o
+MAINTAINERCLEANFILES = Makefile.in Makefile.am about.hh paludis.hh \
+ hashed_containers.hh
+DISTCLEANFILES = srcleanlist
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+EXTRA_DIST = about.hh.in Makefile.am.m4 paludis.hh.m4 files.m4 \
+ hashed_containers.hh.in testscriptlist srlist srcleanlist
+SUBDIRS = digests util libxml . repositories environment args qa selinux tasks
+BUILT_SOURCES = srcleanlist
+
+libpaludis_la_SOURCES = filelist
+libpaludis_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+libpaludis_la_LIBADD = $(top_builddir)/paludis/util/libpaludisutil.la @DYNAMIC_LD_LIBS@
+
+TESTS = testlist
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \
+ PALUDIS_SKIP_CONFIG="yes" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ bash $(top_srcdir)/test/run_test.sh
+
+check_PROGRAMS = $(TESTS)
+check_SCRIPTS = testscriptlist
+lib_LTLIBRARIES = libpaludis.la
+paludis_includedir = $(includedir)/paludis/
+paludis_include_HEADERS = headerlist srheaderlist
+
+Makefile.am : Makefile.am.m4 files.m4
+ $(top_srcdir)/misc/do_m4.bash Makefile.am
+
+paludis.hh : paludis.hh.m4 files.m4
+ $(top_srcdir)/misc/do_m4.bash paludis.hh
+
+comparison_policy.hh : comparison_policy.hh.m4
+ $(top_srcdir)/misc/do_m4.bash comparison_policy.hh.m4
+
+ihateautomake.cc : all
+ test -f $@ || touch $@
+
diff --git a/0.8.0/paludis/about.hh.in b/0.8.0/paludis/about.hh.in
new file mode 100644
index 0000000..faa023a
--- /dev/null
+++ b/0.8.0/paludis/about.hh.in
@@ -0,0 +1,117 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+@GENERATED_FILE@
+
+#ifndef PALUDIS_GUARD_PALUDIS_ABOUT_HH
+#define PALUDIS_GUARD_PALUDIS_ABOUT_HH 1
+
+/** \file
+ * Defines constants giving the Paludis version number and information about
+ * how Paludis was built.
+ *
+ * \ingroup grpabout
+ */
+
+/**
+ * The package name (eg Paludis).
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_PACKAGE "@PACKAGE@"
+
+/**
+ * The major version (eg 0.4.1 -> 0).
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_VERSION_MAJOR @VERSION_MAJOR@
+
+/**
+ * The minor version (eg 0.4.1 -> 4).
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_VERSION_MINOR @VERSION_MINOR@
+
+/**
+ * The micro version (eg 0.4.1 -> 1).
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_VERSION_MICRO @VERSION_MICRO@
+
+/**
+ * The version, two digits per part (eg 1.3.5 -> 10305).
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_VERSION ((100 * 100 * PALUDIS_VERSION_MAJOR) \
+ + (100 * PALUDIS_VERSION_MINOR) + PALUDIS_VERSION_MICRO)
+
+/**
+ * The subversion revision, if applicable (eg "65" or "65M" or "").
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_SUBVERSION_REVISION "@SVNVERSION@"
+
+/**
+ * The CXXFLAGS used to build Paludis.
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_BUILD_CXXFLAGS "@CXXFLAGS@"
+
+/**
+ * The LDFLAGS used to build Paludis.
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_BUILD_LDFLAGS "@LDFLAGS@"
+
+/**
+ * The compiler used to build Paludis.
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_BUILD_CXX "@CXX@"
+
+/**
+ * The user who built Paludis.
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_BUILD_USER "@BUILDUSER@"
+
+/**
+ * The host on which Paludis was built.
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_BUILD_HOST "@BUILDHOST@"
+
+/**
+ * The date when Paludis was built.
+ *
+ * \ingroup grpabout
+ */
+#define PALUDIS_BUILD_DATE "@BUILDDATE@"
+
+#endif
diff --git a/0.8.0/paludis/about_TEST.cc b/0.8.0/paludis/about_TEST.cc
new file mode 100644
index 0000000..f79ac7e
--- /dev/null
+++ b/0.8.0/paludis/about_TEST.cc
@@ -0,0 +1,86 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/about.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace test;
+using namespace paludis;
+
+/**
+ * \file
+ * Test cases for about.hh .
+ *
+ * \ingroup grptestcases
+ */
+
+namespace test_cases
+{
+ /**
+ * \test Version tests.
+ *
+ * \ingroup grptestcases
+ */
+ struct VersionTest : TestCase
+ {
+ VersionTest() : TestCase("about test") { }
+
+ void run()
+ {
+ TEST_CHECK(PALUDIS_VERSION_MAJOR >= 0);
+ TEST_CHECK(PALUDIS_VERSION_MAJOR <= 9);
+
+ TEST_CHECK(PALUDIS_VERSION_MINOR >= 0);
+ TEST_CHECK(PALUDIS_VERSION_MINOR <= 99);
+
+ TEST_CHECK(PALUDIS_VERSION_MICRO >= 0);
+ TEST_CHECK(PALUDIS_VERSION_MICRO <= 99);
+
+ TEST_CHECK(PALUDIS_VERSION >= 0);
+ TEST_CHECK(PALUDIS_VERSION <= 99999);
+ TEST_CHECK_EQUAL(PALUDIS_VERSION, 10000 * PALUDIS_VERSION_MAJOR +
+ 100 * PALUDIS_VERSION_MINOR + PALUDIS_VERSION_MICRO);
+
+ TEST_CHECK(std::string(PALUDIS_SUBVERSION_REVISION) != "i am a fish");
+ }
+ } test_case_about;
+
+ /**
+ * \test Build info tests.
+ *
+ * \ingroup grptestcases
+ */
+ struct BuildInfoTest : TestCase
+ {
+ BuildInfoTest() : TestCase("build info test") { }
+
+ void run()
+ {
+ TEST_CHECK(! std::string(PALUDIS_BUILD_CXX).empty());
+ TEST_CHECK(! std::string(PALUDIS_BUILD_CXXFLAGS).empty());
+ TEST_CHECK(std::string(PALUDIS_BUILD_LDFLAGS) != "i am a fish");
+
+ TEST_CHECK(! std::string(PALUDIS_BUILD_USER).empty());
+ TEST_CHECK(! std::string(PALUDIS_BUILD_HOST).empty());
+ TEST_CHECK(! std::string(PALUDIS_BUILD_DATE).empty());
+ }
+ } test_case_build_info;
+}
+
diff --git a/0.8.0/paludis/args/Makefile.am b/0.8.0/paludis/args/Makefile.am
new file mode 100644
index 0000000..184ed7c
--- /dev/null
+++ b/0.8.0/paludis/args/Makefile.am
@@ -0,0 +1,53 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+
+TESTS = \
+ args_TEST
+
+paludis_args_includedir = $(includedir)/paludis/args/
+
+paludis_args_include_HEADERS = \
+ args.hh \
+ args_error.hh \
+ args_group.hh \
+ args_handler.hh \
+ args_option.hh \
+ bad_argument.hh \
+ args_visitor.hh \
+ args_dumper.hh \
+ man.hh
+
+libpaludisargs_la_SOURCES = $(paludis_args_include_HEADERS) \
+ args.cc \
+ args_error.cc \
+ args_group.cc \
+ args_handler.cc \
+ args_option.cc \
+ bad_argument.cc \
+ args_visitor.cc \
+ args_dumper.cc \
+ man.cc
+
+libpaludisargs_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+libpaludisargs_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+TESTS_ENVIRONMENT = env -u PALUDIS_OPTIONS \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ bash $(top_srcdir)/test/run_test.sh
+
+lib_LTLIBRARIES = libpaludisargs.la
+check_PROGRAMS = $(TESTS)
+
+test_ldadd = \
+ $(top_builddir)/test/libtest.a \
+ libpaludisargs.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(DYNAMIC_LD_LIBS)
+
+args_TEST_SOURCES = args_TEST.cc
+args_TEST_LDADD = $(test_ldadd)
+
diff --git a/0.8.0/paludis/args/args.cc b/0.8.0/paludis/args/args.cc
new file mode 100644
index 0000000..510351d
--- /dev/null
+++ b/0.8.0/paludis/args/args.cc
@@ -0,0 +1,27 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "args.hh"
+
+/** \file
+ * Implementation for args.hh .
+ *
+ * \ingroup grplibpaludisargs
+ */
+
diff --git a/0.8.0/paludis/args/args.hh b/0.8.0/paludis/args/args.hh
new file mode 100644
index 0000000..8aad3bd
--- /dev/null
+++ b/0.8.0/paludis/args/args.hh
@@ -0,0 +1,35 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_ARGS_HH
+#define PALUDIS_GUARD_ARGS_ARGS_HH 1
+
+/** \file
+ * Master include file for command line argument handling.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+#include <paludis/args/args_error.hh>
+#include <paludis/args/args_group.hh>
+#include <paludis/args/args_handler.hh>
+#include <paludis/args/args_option.hh>
+#include <paludis/args/bad_argument.hh>
+
+#endif
diff --git a/0.8.0/paludis/args/args_TEST.cc b/0.8.0/paludis/args/args_TEST.cc
new file mode 100644
index 0000000..56193ae
--- /dev/null
+++ b/0.8.0/paludis/args/args_TEST.cc
@@ -0,0 +1,176 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/args/args.hh>
+#include <paludis/args/args_error.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace paludis;
+using namespace paludis::args;
+using namespace test;
+
+/** \file
+ * Test cases for paludis::args things.
+ *
+ * \ingroup grptestcases
+ */
+
+#ifndef DOXYGEN
+
+struct CommandLine : public ArgsHandler
+{
+ ArgsGroup group_one;
+ SwitchArg arg_foo;
+ SwitchArg arg_bar;
+ SwitchArg arg_dummy;
+
+ ArgsGroup group_two;
+ SwitchArg arg_baz;
+ AliasArg arg_other_baz;
+ StringArg arg_something;
+ IntegerArg arg_somenum;
+ EnumArg arg_enum;
+
+ ArgsGroup group_three;
+ EnumArg arg_other_enum;
+ StringSetArg arg_stringset;
+
+ CommandLine();
+ ~CommandLine();
+
+ std::string app_name() const
+ {
+ return "args_TEST";
+ }
+
+ std::string app_synopsis() const
+ {
+ return "tests for args";
+ }
+
+ std::string app_description() const
+ {
+ return "Tests args";
+ }
+};
+
+CommandLine::CommandLine() :
+ group_one(this, "Group one", "Description of group one"),
+ arg_foo(&group_one, "foo", 'f', "Enable foo"),
+ arg_bar(&group_one, "bar", 'b', "Enable bar"),
+ arg_dummy(&group_one, "dummy", 'd', "Enable something else"),
+
+ group_two(this, "Group two", "Description of group two"),
+ arg_baz(&group_two, "baz", 'z', "Enable baz"),
+ arg_other_baz(&arg_baz, "other-baz"),
+ arg_something(&group_two, "something", 's', "Value of something"),
+ arg_somenum(&group_two, "num", 'n', "Some number"),
+ arg_enum(&group_two, "enum", 'e', "One of three", EnumArg::EnumArgOptions("one", "Option one")("two", "option two")("three", "option three"), "two"),
+
+ group_three(this, "Group three", "Description of group three"),
+ arg_other_enum(&group_three, "something", '\0', "Blah.", EnumArg::EnumArgOptions("a", "A")("b", "B")("c", "C"), "b"),
+ arg_stringset(&group_three, "stringset", 't', "A StringSet.")
+{
+}
+
+CommandLine::~CommandLine()
+{
+}
+
+#endif
+
+namespace test_cases
+{
+ /**
+ * \test Simple args tests.
+ *
+ * \ingroup grptestcases
+ */
+ struct ArgsTestSimple : TestCase
+ {
+ ArgsTestSimple() : TestCase("simple") { }
+
+ void run()
+ {
+ char * args[] = { "program-name", "--other-baz", "-fsne", "blah", "7", "three", "--", "--dummy",
+ "one", "two" };
+ CommandLine c1;
+ c1.run(10, args);
+ TEST_CHECK(c1.arg_foo.specified());
+ TEST_CHECK(! c1.arg_bar.specified());
+ TEST_CHECK(c1.arg_baz.specified());
+ TEST_CHECK(c1.arg_other_baz.specified());
+ TEST_CHECK(c1.arg_something.specified());
+ TEST_CHECK(c1.arg_something.argument() == "blah");
+ TEST_CHECK(c1.arg_somenum.specified());
+ TEST_CHECK(c1.arg_somenum.argument() == 7);
+ TEST_CHECK(c1.arg_enum.specified());
+ TEST_CHECK(c1.arg_enum.argument() == "three");
+ TEST_CHECK(! c1.arg_dummy.specified());
+ TEST_CHECK(! c1.arg_other_enum.specified());
+ TEST_CHECK(c1.arg_other_enum.argument() == "b");
+
+ TEST_CHECK_EQUAL(std::distance(c1.begin_parameters(), c1.end_parameters()), 3);
+ TEST_CHECK_EQUAL(*c1.begin_parameters(), "--dummy");
+ TEST_CHECK_EQUAL(*++c1.begin_parameters(), "one");
+ TEST_CHECK_EQUAL(*++(++(c1.begin_parameters())), "two");
+ }
+ } test_args_simple;
+
+ /**
+ * \test Missing parameters tests.
+ *
+ * \ingroup grptestcases
+ */
+ struct ArgsTestNoParam : TestCase
+ {
+ ArgsTestNoParam() : TestCase("Missing parameters") { }
+
+ void run()
+ {
+ char *args[] = { "program-name", "-e" };
+ CommandLine c1;
+ TEST_CHECK_THROWS(c1.run(2, args), MissingValue);
+ }
+ } test_args_no_param;
+
+ /**
+ * \test String tests.
+ *
+ * \ingroup grptestcases
+ */
+ struct ArgsTestStringSet : TestCase
+ {
+ ArgsTestStringSet() : TestCase("StringSet") { }
+
+ void run()
+ {
+ char *args[] = { "program-name", "--stringset", "one", "-t", "two", "-t", "three", "fnord" };
+ CommandLine c1;
+ c1.run(8, args);
+ TEST_CHECK(c1.arg_stringset.specified());
+ TEST_CHECK(std::find(c1.arg_stringset.args_begin(), c1.arg_stringset.args_end(), "one") != c1.arg_stringset.args_end());
+ TEST_CHECK(std::find(c1.arg_stringset.args_begin(), c1.arg_stringset.args_end(), "two") != c1.arg_stringset.args_end());
+ TEST_CHECK(std::find(c1.arg_stringset.args_begin(), c1.arg_stringset.args_end(), "three") != c1.arg_stringset.args_end());
+ TEST_CHECK(std::find(c1.arg_stringset.args_begin(), c1.arg_stringset.args_end(), "fnord") == c1.arg_stringset.args_end());
+ }
+ } test_args_string_set;
+}
+
diff --git a/0.8.0/paludis/args/args_dumper.cc b/0.8.0/paludis/args/args_dumper.cc
new file mode 100644
index 0000000..afdc747
--- /dev/null
+++ b/0.8.0/paludis/args/args_dumper.cc
@@ -0,0 +1,81 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/args/args_dumper.hh>
+#include <paludis/args/args_option.hh>
+
+#include <sstream>
+
+/** \file
+ * Implementation of ArgsDumper.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+using namespace paludis;
+using namespace paludis::args;
+
+ArgsDumper::ArgsDumper(std::ostream & os) :
+ _os(os)
+{
+}
+
+void ArgsDumper::visit(const ArgsOption * const a)
+{
+ std::stringstream p;
+ p << " --" << a->long_name();
+ if (a->short_name())
+ p << ", -" << a->short_name();
+ if (p.str().length() < 24)
+ p << std::string(24 - p.str().length(), ' ');
+ else
+ p << std::endl << std::string(24, ' ');
+ _os << p.str();
+ _os << " " << a->description() << std::endl;
+}
+
+#ifndef DOXYGEN
+#define VISIT(type) void ArgsDumper::visit(const type * const a) \
+ { visit(static_cast<const ArgsOption *>(a)); }
+
+VISIT(SwitchArg)
+VISIT(StringArg)
+VISIT(IntegerArg)
+VISIT(AliasArg)
+VISIT(StringSetArg)
+#endif
+
+void ArgsDumper::visit(const EnumArg * const a)
+{
+ visit(static_cast<const ArgsOption *>(a));
+ for (EnumArg::AllowedArgIterator it = a->begin_allowed_args(), it_end = a->end_allowed_args();
+ it != it_end; ++it)
+ {
+ std::stringstream p;
+ p << " " << (*it).first;
+ if (p.str().length() < 26)
+ p << std::string(26 - p.str().length(), ' ');
+ _os << p.str();
+ _os << " " << (*it).second;
+ if ((*it).first == a->default_arg())
+ _os << " (default)";
+ _os << std::endl;
+ }
+}
diff --git a/0.8.0/paludis/args/args_dumper.hh b/0.8.0/paludis/args/args_dumper.hh
new file mode 100644
index 0000000..c53a3b3
--- /dev/null
+++ b/0.8.0/paludis/args/args_dumper.hh
@@ -0,0 +1,80 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_ARGS_ARGS_DUMPER_HH
+#define PALUDIS_GUARD_PALUDIS_ARGS_ARGS_DUMPER_HH 1
+
+#include <iosfwd>
+#include <paludis/args/args_visitor.hh>
+#include <paludis/util/visitor.hh>
+
+namespace paludis
+{
+ namespace args
+ {
+ class ArgsOption;
+ class SwitchArg;
+ class StringArg;
+ class IntegerArg;
+ class AliasArg;
+ class EnumArg;
+
+ /**
+ * Visitor class. Prints help text appropriate to each command line option.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE ArgsDumper :
+ public ArgsVisitorTypes::ConstVisitor
+ {
+ private:
+ std::ostream & _os;
+
+ public:
+ /**
+ * Constructor.
+ */
+ ArgsDumper(std::ostream & os);
+
+ /// Visit an ArgsOption.
+ void visit(const ArgsOption * const);
+
+ /// Visit a SwitchArg.
+ void visit(const SwitchArg * const);
+
+ /// Visit a StringArg.
+ void visit(const StringArg * const);
+
+ /// Visit an IntegerArg.
+ void visit(const IntegerArg * const);
+
+ /// Visit an AliasArg.
+ void visit(const AliasArg * const);
+
+ /// Visit an EnumArg.
+ void visit(const EnumArg * const);
+
+ /// Visit a StringSetArg.
+ void visit(const StringSetArg * const);
+ };
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/args_error.cc b/0.8.0/paludis/args/args_error.cc
new file mode 100644
index 0000000..36f9ee4
--- /dev/null
+++ b/0.8.0/paludis/args/args_error.cc
@@ -0,0 +1,45 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "args_error.hh"
+
+/** \file
+ * Implementation for ArgsError.
+ *
+ * \ingroup grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+
+using namespace paludis::args;
+
+ArgsError::ArgsError(const std::string & our_message) throw () :
+ paludis::Exception("Error handling command line: " + our_message)
+{
+}
+
+BadValue::BadValue(const std::string& option, const std::string& value) throw () :
+ ArgsError("Invalid parameter '" + value + "' for argument '" + option + "'")
+{
+}
+
+MissingValue::MissingValue(const std::string & arg) throw() :
+ ArgsError("No parameter given for '" + arg + "'")
+{
+}
+
diff --git a/0.8.0/paludis/args/args_error.hh b/0.8.0/paludis/args/args_error.hh
new file mode 100644
index 0000000..2f5b631
--- /dev/null
+++ b/0.8.0/paludis/args/args_error.hh
@@ -0,0 +1,87 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_ARGS_ERROR_HH
+#define PALUDIS_GUARD_ARGS_ARGS_ERROR_HH 1
+
+#include <paludis/util/exception.hh>
+#include <string>
+
+/** \file
+ * Declaration for ArgsError.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+namespace paludis
+{
+ namespace args
+ {
+ /**
+ * Thrown if an invalid command line argument is provided.
+ *
+ * \ingroup grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+ class PALUDIS_VISIBLE ArgsError :
+ public paludis::Exception
+ {
+ protected:
+ /**
+ * Constructor.
+ */
+ ArgsError(const std::string & message) throw ();
+ };
+
+ /**
+ * Thrown if an invalid parameter is passed to a valid command line argument.
+ *
+ * \ingroup grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+ class PALUDIS_VISIBLE BadValue :
+ public ArgsError
+ {
+ public:
+ /**
+ * Constructor
+ */
+ BadValue(const std::string& option, const std::string& value) throw();
+ };
+
+ /**
+ * Thrown if an argument is specified that needs a parameter,
+ * but no parameter is given.
+ *
+ * \ingroup grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+ class PALUDIS_VISIBLE MissingValue :
+ public ArgsError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ MissingValue(const std::string & arg) throw ();
+ };
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/args_group.cc b/0.8.0/paludis/args/args_group.cc
new file mode 100644
index 0000000..45b6d74
--- /dev/null
+++ b/0.8.0/paludis/args/args_group.cc
@@ -0,0 +1,78 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "args.hh"
+#include <list>
+
+/** \file
+ * Implementation for ArgsGroup.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+using namespace paludis::args;
+
+namespace paludis
+{
+ /**
+ * Implementation data for ArgsGroup.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<ArgsGroup> :
+ InternalCounted<ArgsGroup>
+ {
+ std::list<ArgsOption *> args_options;
+ };
+}
+
+ArgsGroup::ArgsGroup(ArgsHandler * h, const std::string & our_name,
+ const std::string & our_description) :
+ PrivateImplementationPattern<ArgsGroup>(new Implementation<ArgsGroup>),
+ _name(our_name),
+ _description(our_description),
+ _handler(h)
+{
+ h->add(this);
+}
+
+void
+ArgsGroup::add(ArgsOption * const value)
+{
+ /// \bug Should check for uniqueness of short and long names.
+ _imp->args_options.push_back(value);
+}
+
+ArgsGroup::~ArgsGroup()
+{
+}
+
+ArgsGroup::Iterator
+ArgsGroup::begin() const
+{
+ return Iterator(_imp->args_options.begin());
+}
+
+ArgsGroup::Iterator
+ArgsGroup::end() const
+{
+ return Iterator(_imp->args_options.end());
+}
+
diff --git a/0.8.0/paludis/args/args_group.hh b/0.8.0/paludis/args/args_group.hh
new file mode 100644
index 0000000..62b363d
--- /dev/null
+++ b/0.8.0/paludis/args/args_group.hh
@@ -0,0 +1,117 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_ARGS_GROUP_HH
+#define PALUDIS_GUARD_ARGS_ARGS_GROUP_HH 1
+
+#include <paludis/args/args_option.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <string>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+/** \file
+ * Declaration for ArgsGroup.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+namespace paludis
+{
+
+ namespace args
+ {
+ class ArgsHandler;
+
+ /**
+ * Contains a related group of command line arguments.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE ArgsGroup :
+ private PrivateImplementationPattern<ArgsGroup>,
+ private InstantiationPolicy<ArgsGroup, instantiation_method::NonCopyableTag>
+ {
+ private:
+ const std::string _name;
+ const std::string _description;
+
+ ArgsHandler * _handler;
+
+ public:
+ ArgsHandler * handler()
+ {
+ return _handler;
+ }
+
+ /**
+ * Add an ArgsOption instance (called by the ArgsOption
+ * constructor).
+ */
+ void add(ArgsOption * const value);
+
+ ///\name Iterate over our ArgsOptions.
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<ArgsGroup, ArgsOption * const> Iterator;
+
+ Iterator begin() const;
+ Iterator end() const;
+
+ ///\}
+
+ ///\name Basic operations
+ ///\{
+
+ ArgsGroup(ArgsHandler * h, const std::string & name,
+ const std::string & description);
+
+ ~ArgsGroup();
+
+ ///\}
+
+ /**
+ * Fetch our name.
+ */
+ const std::string & name() const
+ {
+ return _name;
+ }
+
+ /**
+ * Fetch our description.
+ */
+ const std::string & description() const
+ {
+ return _description;
+ }
+
+ /**
+ * Fetch our handler.
+ */
+ ArgsHandler * handler() const
+ {
+ return _handler;
+ }
+ };
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/args_handler.cc b/0.8.0/paludis/args/args_handler.cc
new file mode 100644
index 0000000..d7ab67c
--- /dev/null
+++ b/0.8.0/paludis/args/args_handler.cc
@@ -0,0 +1,231 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "args.hh"
+#include "args_dumper.hh"
+#include <paludis/util/system.hh>
+#include <algorithm>
+#include <sstream>
+#include <list>
+#include <map>
+
+/** \file
+ * Implementation for ArgsHandler.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+using namespace paludis::args;
+
+namespace paludis
+{
+ /**
+ * Implementation data for ArgsHandler.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<ArgsHandler> :
+ InternalCounted<Implementation<ArgsHandler> >
+ {
+ std::list<ArgsGroup *> groups;
+ std::list<std::string> parameters;
+ std::list<std::string> usage_lines;
+ std::list<std::pair<std::string, std::string> > environment_lines;
+
+ std::map<std::string, ArgsOption *> longopts;
+ std::map<char, ArgsOption *> shortopts;
+ };
+}
+
+ArgsHandler::ArgsHandler() :
+ PrivateImplementationPattern<ArgsHandler>(new Implementation<ArgsHandler>)
+{
+}
+
+ArgsHandler::~ArgsHandler()
+{
+}
+
+void
+ArgsHandler::add_usage_line(const std::string & l)
+{
+ _imp->usage_lines.push_back(l);
+}
+
+void
+ArgsHandler::add_enviromnent_variable(const std::string & e, const std::string & desc)
+{
+ _imp->environment_lines.push_back(std::make_pair(e, desc));
+}
+
+void
+ArgsHandler::add(ArgsGroup * const g)
+{
+ /// \bug Should check for name uniqueness.
+ _imp->groups.push_back(g);
+}
+
+void
+ArgsHandler::run(const int argc, const char * const * const argv)
+{
+ std::list<std::string> args;
+
+ std::string env_options = paludis::getenv_with_default("PALUDIS_OPTIONS", "");
+
+ std::istringstream iss(env_options);
+ std::string option;
+ while(iss.good())
+ {
+ iss >> option;
+ if(!option.empty())
+ args.push_back(option);
+ }
+
+ args.insert(args.end(), &argv[1], &argv[argc]);
+
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string> argit(args.begin()), arge(args.end());
+
+ ArgsVisitor visitor(&argit, arge);
+
+ for ( ; argit != arge; ++argit )
+ {
+ std::string arg = *argit;
+
+ if (arg == "--")
+ {
+ ++argit;
+ break;
+ }
+ else if (0 == arg.compare(0, 2, "--"))
+ {
+ arg.erase(0, 2);
+ std::map<std::string, ArgsOption *>::iterator it = _imp->longopts.find(arg);
+ if (it == _imp->longopts.end())
+ throw BadArgument("--" + arg);
+ (*it).second->accept(&visitor);
+ }
+ else if (arg[0] == '-')
+ {
+ arg.erase(0, 1);
+ for (std::string::iterator c = arg.begin(); c != arg.end(); ++c)
+ {
+ std::map<char, ArgsOption *>::iterator it = _imp->shortopts.find(*c);
+ if (it == _imp->shortopts.end())
+ {
+ throw BadArgument(std::string("-") + *c);
+ }
+ (*it).second->accept(&visitor);
+ }
+ }
+ else
+ {
+ _imp->parameters.push_back(arg);
+ }
+ }
+
+ _imp->parameters.insert(_imp->parameters.end(),
+ argit, libwrapiter::ForwardIterator<ArgsVisitor, std::string>(args.end()));
+}
+
+void
+ArgsHandler::dump_to_stream(std::ostream & s) const
+{
+ ArgsDumper dump(s);
+ std::list<ArgsGroup *>::const_iterator g(_imp->groups.begin()), g_end(_imp->groups.end());
+ for ( ; g != g_end ; ++g)
+ {
+ s << (*g)->name() << ":" << std::endl;
+
+ std::for_each((*g)->begin(), (*g)->end(), accept_visitor(&dump));
+
+ s << std::endl;
+ }
+}
+
+ArgsHandler::ParametersIterator
+ArgsHandler::begin_parameters() const
+{
+ return ParametersIterator(_imp->parameters.begin());
+}
+
+ArgsHandler::ParametersIterator
+ArgsHandler::end_parameters() const
+{
+ return ParametersIterator(_imp->parameters.end());
+}
+
+bool
+ArgsHandler::empty() const
+{
+ return _imp->parameters.empty();
+}
+
+std::ostream &
+paludis::args::operator<< (std::ostream & s, const ArgsHandler & h)
+{
+ h.dump_to_stream(s);
+ return s;
+}
+
+void
+ArgsHandler::add_option(ArgsOption * const opt, const std::string & long_name,
+ const char short_name)
+{
+ _imp->longopts[long_name] = opt;
+ if (short_name != '\0')
+ _imp->shortopts[short_name] = opt;
+}
+
+ArgsHandler::UsageLineIterator
+ArgsHandler::begin_usage_lines() const
+{
+ return UsageLineIterator(_imp->usage_lines.begin());
+}
+
+ArgsHandler::UsageLineIterator
+ArgsHandler::end_usage_lines() const
+{
+ return UsageLineIterator(_imp->usage_lines.end());
+}
+
+ArgsHandler::EnvironmentLineIterator
+ArgsHandler::begin_environment_lines() const
+{
+ return EnvironmentLineIterator(_imp->environment_lines.begin());
+}
+
+ArgsHandler::EnvironmentLineIterator
+ArgsHandler::end_environment_lines() const
+{
+ return EnvironmentLineIterator(_imp->environment_lines.end());
+}
+
+ArgsHandler::ArgsGroupsIterator
+ArgsHandler::begin_args_groups() const
+{
+ return ArgsGroupsIterator(_imp->groups.begin());
+}
+
+ArgsHandler::ArgsGroupsIterator
+ArgsHandler::end_args_groups() const
+{
+ return ArgsGroupsIterator(_imp->groups.end());
+}
+
diff --git a/0.8.0/paludis/args/args_handler.hh b/0.8.0/paludis/args/args_handler.hh
new file mode 100644
index 0000000..85e486d
--- /dev/null
+++ b/0.8.0/paludis/args/args_handler.hh
@@ -0,0 +1,181 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_ARGS_HANDLER_HH
+#define PALUDIS_GUARD_ARGS_ARGS_HANDLER_HH 1
+
+#include <paludis/args/args_group.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+#include <iosfwd>
+#include <string>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+/** \file
+ * Declaration for ArgsHandler.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+namespace paludis
+{
+ namespace args
+ {
+ /**
+ * Handles command line arguments.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE ArgsHandler :
+ private InstantiationPolicy<ArgsHandler, instantiation_method::NonCopyableTag>,
+ private PrivateImplementationPattern<ArgsHandler>
+ {
+ friend class ArgsGroup;
+ friend std::ostream & operator<< (std::ostream &, const ArgsHandler &);
+
+ protected:
+ /**
+ * Add a new usage line.
+ */
+ void add_usage_line(const std::string & l);
+
+ /**
+ * Add a new environment line.
+ */
+ void add_enviromnent_variable(const std::string & e, const std::string & desc);
+
+ /**
+ * Add an new ArgsGroup (called by the ArgsGroup constructor).
+ */
+ void add(ArgsGroup * const);
+
+ /**
+ * Dump, for --help output (called by operator<<).
+ */
+ void dump_to_stream(std::ostream & s) const;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ArgsHandler();
+
+ virtual ~ArgsHandler();
+
+ ///\}
+
+ /**
+ * Parse command line arguments.
+ */
+ void run(const int, const char * const * const);
+
+ ///\name Iterate over our parameters (non - and -- switches and their values)
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<ArgsHandler, const std::string> ParametersIterator;
+
+ ParametersIterator begin_parameters() const;
+
+ ParametersIterator end_parameters() const;
+
+ bool empty() const;
+
+ ///\}
+
+ /**
+ * Add an ArgsOption instance.
+ */
+ void add_option(ArgsOption * const, const std::string & long_name,
+ const char short_name = '\0');
+
+ ///\name About our application (for documentation)
+ ///\{
+
+ /**
+ * What is our application name?
+ */
+ virtual std::string app_name() const = 0;
+
+ /**
+ * What is our application's Unix manual section?
+ */
+ virtual std::string man_section() const
+ {
+ return "1";
+ }
+
+ /**
+ * One line synopsis of what our application is.
+ */
+ virtual std::string app_synopsis() const = 0;
+
+ /**
+ * Long description of what our application is.
+ */
+ virtual std::string app_description() const = 0;
+
+ ///\}
+
+ ///\name Iterate over our usage lines (for documentation)
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<ArgsHandler, const std::string> UsageLineIterator;
+
+ UsageLineIterator begin_usage_lines() const;
+
+ UsageLineIterator end_usage_lines() const;
+
+ ///\}
+
+ ///\name Iterate over our environment lines (for documentation)
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<ArgsHandler,
+ const std::pair<std::string, std::string> > EnvironmentLineIterator;
+
+ EnvironmentLineIterator begin_environment_lines() const;
+
+ EnvironmentLineIterator end_environment_lines() const;
+
+ ///\}
+
+ ///\name Iterate over our groups
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<ArgsHandler, ArgsGroup * const> ArgsGroupsIterator;
+
+ ArgsGroupsIterator begin_args_groups() const;
+
+ ArgsGroupsIterator end_args_groups() const;
+
+ ///\}
+ };
+
+ /**
+ * Output an ArgsHandler to an ostream, for --help output.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ std::ostream & operator<< (std::ostream &, const ArgsHandler &) PALUDIS_VISIBLE;
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/args_option.cc b/0.8.0/paludis/args/args_option.cc
new file mode 100644
index 0000000..3ab90bd
--- /dev/null
+++ b/0.8.0/paludis/args/args_option.cc
@@ -0,0 +1,226 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "args.hh"
+#include "args_error.hh"
+#include <set>
+#include <vector>
+
+/** \file
+ * Implementation for ArgsOption.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+using namespace paludis::args;
+
+ArgsOption::ArgsOption(ArgsGroup * const g, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description) :
+ _group(g),
+ _long_name(our_long_name),
+ _short_name(our_short_name),
+ _description(our_description),
+ _specified(false)
+{
+ g->add(this);
+ g->handler()->add_option(this, our_long_name, our_short_name);
+}
+
+ArgsOption::~ArgsOption()
+{
+}
+
+SwitchArg::SwitchArg(ArgsGroup * const our_group, std::string our_long_name, char our_short_name,
+ std::string our_description) :
+ ArgsOption(our_group, our_long_name, our_short_name, our_description)
+{
+}
+
+SwitchArg::~SwitchArg()
+{
+}
+
+AliasArg::AliasArg(ArgsOption * const other, const std::string & our_long_name) :
+ ArgsOption(other->group(), our_long_name, '\0', "Alias for --" + other->long_name()),
+ _other(other)
+{
+ other->group()->handler()->add_option(other, our_long_name);
+}
+
+StringArg::StringArg(ArgsGroup * const g, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description) :
+ ArgsOption(g, our_long_name, our_short_name, our_description)
+{
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for StringSetArg.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<StringSetArg> :
+ InternalCounted<Implementation<StringSetArg> >
+ {
+ std::set<std::string> args;
+ };
+}
+
+StringSetArg::StringSetArg(ArgsGroup * const g, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description) :
+ ArgsOption(g, our_long_name, our_short_name, our_description),
+ PrivateImplementationPattern<StringSetArg>(new Implementation<StringSetArg>)
+{
+}
+
+StringSetArg::Iterator
+StringSetArg::args_begin() const
+{
+ return Iterator(_imp->args.begin());
+}
+
+StringSetArg::Iterator
+StringSetArg::args_end() const
+{
+ return Iterator(_imp->args.end());
+}
+
+void
+StringSetArg::add_argument(const std::string & arg)
+{
+ _imp->args.insert(arg);
+}
+
+IntegerArg::IntegerArg(ArgsGroup * const our_group, const std::string & our_long_name,
+ char our_short_name, const std::string & our_description) :
+ ArgsOption(our_group, our_long_name, our_short_name, our_description)
+{
+}
+
+namespace
+{
+ /**
+ * Is an arg a particular value?
+ *
+ * \ingroup grplibpaludisargs
+ */
+ struct ArgIs
+ {
+ /// The argument.
+ const std::string arg;
+
+ /// Constructor.
+ ArgIs(const std::string & a) :
+ arg(a)
+ {
+ }
+
+ /// Comparator.
+ bool operator() (const std::pair<std::string, std::string> & p) const
+ {
+ return p.first == arg;
+ }
+ };
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for EnumArg.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<EnumArg> :
+ InternalCounted<Implementation<EnumArg> >
+ {
+ std::vector<std::pair<std::string, std::string> > allowed_args;
+ };
+
+ /**
+ * Implementation data for EnumArg::EnumArgOptions.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<EnumArg::EnumArgOptions> :
+ InternalCounted<Implementation<EnumArg::EnumArgOptions> >
+ {
+ std::vector<std::pair<std::string, std::string> > options;
+ };
+}
+
+void EnumArg::set_argument(const std::string & arg)
+{
+ if (_imp->allowed_args.end() == std::find_if(_imp->allowed_args.begin(),
+ _imp->allowed_args.end(), ArgIs(arg)))
+ throw (BadValue("--" + long_name(), arg));
+
+ _argument = arg;
+}
+
+EnumArg::~EnumArg()
+{
+}
+
+EnumArg::EnumArgOptions::EnumArgOptions(std::string opt, std::string desc) :
+ PrivateImplementationPattern<EnumArgOptions>(new Implementation<EnumArgOptions>)
+{
+ _imp->options.push_back(std::make_pair(opt, desc));
+}
+
+EnumArg::EnumArgOptions & EnumArg::EnumArgOptions::operator() (std::string opt, std::string desc)
+{
+ _imp->options.push_back(std::make_pair(opt, desc));
+ return *this;
+}
+
+EnumArg::EnumArgOptions::~EnumArgOptions()
+{
+}
+
+EnumArg::EnumArg(ArgsGroup * const our_group, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description,
+ const EnumArgOptions & opts, const std::string & our_default_arg) :
+ ArgsOption(our_group, our_long_name, our_short_name, our_description),
+ PrivateImplementationPattern<EnumArg>(new Implementation<EnumArg>),
+ _argument(our_default_arg),
+ _default_arg(our_default_arg)
+{
+ _imp->allowed_args = opts._imp->options;
+}
+
+EnumArg::AllowedArgIterator
+EnumArg::begin_allowed_args() const
+{
+ return AllowedArgIterator(_imp->allowed_args.begin());
+}
+
+EnumArg::AllowedArgIterator
+EnumArg::end_allowed_args() const
+{
+ return AllowedArgIterator(_imp->allowed_args.end());
+}
+
+StringSetArg::~StringSetArg()
+{
+}
+
diff --git a/0.8.0/paludis/args/args_option.hh b/0.8.0/paludis/args/args_option.hh
new file mode 100644
index 0000000..a46ee5e
--- /dev/null
+++ b/0.8.0/paludis/args/args_option.hh
@@ -0,0 +1,361 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_ARGS_OPTION_HH
+#define PALUDIS_GUARD_ARGS_ARGS_OPTION_HH 1
+
+#include <paludis/args/args_visitor.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+/** \file
+ * Declaration for ArgsOption.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+namespace paludis
+{
+ namespace args
+ {
+ class ArgsGroup;
+
+ /**
+ * Base class for a command line option.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE ArgsOption :
+ public virtual VisitableInterface<ArgsVisitorTypes>
+ {
+ friend class ArgsHandler;
+
+ private:
+ ArgsGroup * const _group;
+
+ const std::string _long_name;
+ const char _short_name;
+ const std::string _description;
+
+ bool _specified;
+
+ ArgsOption(const ArgsOption &);
+ void operator= (const ArgsOption &);
+
+ protected:
+ /**
+ * Constructor.
+ */
+ ArgsOption(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description);
+
+ /**
+ * Destructor.
+ */
+ ~ArgsOption();
+
+ public:
+ /**
+ * Fetch our long name.
+ */
+ const std::string & long_name() const
+ {
+ return _long_name;
+ }
+
+ /**
+ * Fetch our short name (may be 0).
+ */
+ char short_name() const
+ {
+ return _short_name;
+ }
+
+ /**
+ * Fetch our description.
+ */
+ const std::string & description() const
+ {
+ return _description;
+ }
+
+ /**
+ * Fetch whether or not we were specified on the
+ * command line.
+ */
+ virtual bool specified() const
+ {
+ return _specified;
+ }
+
+ /**
+ * Set the value returned by specified().
+ */
+ virtual void set_specified(const bool value)
+ {
+ _specified = value;
+ }
+
+ /**
+ * Fetch our group.
+ */
+ ArgsGroup * group()
+ {
+ return _group;
+ }
+ };
+
+ /**
+ * A SwitchArg is an option that can either be specified or not
+ * specified, and that takes no value (for example, --help).
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE SwitchArg :
+ public ArgsOption,
+ public Visitable<SwitchArg, ArgsVisitorTypes>
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ SwitchArg(ArgsGroup * const group, std::string long_name, char short_name,
+ std::string description);
+
+ ~SwitchArg();
+ };
+
+ /**
+ * An option that takes a string argument.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE StringArg :
+ public ArgsOption,
+ public Visitable<StringArg, ArgsVisitorTypes>
+ {
+ private:
+ std::string _argument;
+
+ public:
+ /**
+ * Constructor
+ */
+ StringArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description);
+
+ /**
+ * Fetch the argument that was given to this option.
+ */
+ const std::string& argument() const { return _argument; }
+
+ /**
+ * Set the argument returned by argument().
+ */
+ void set_argument(const std::string& arg) { _argument = arg; }
+ };
+
+ /**
+ * An option that takes a set of strings.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE StringSetArg :
+ public ArgsOption,
+ public Visitable<StringSetArg, ArgsVisitorTypes>,
+ private PrivateImplementationPattern<StringSetArg>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ StringSetArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description);
+
+ ~StringSetArg();
+
+ ///\}
+
+ ///\name Iterate over our args.
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<StringArg, const std::string> Iterator;
+
+ Iterator args_begin() const;
+
+ Iterator args_end() const;
+
+ ///\}
+
+ /**
+ * Add an argument to the set.
+ */
+ void add_argument(const std::string & arg);
+ };
+
+
+ /**
+ * An AliasArg is an alias for another argument.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE AliasArg :
+ public ArgsOption,
+ public Visitable<AliasArg, ArgsVisitorTypes>
+ {
+ private:
+ ArgsOption * const _other;
+
+ public:
+ /**
+ * Constructor.
+ */
+ AliasArg(ArgsOption * const other, const std::string & new_long_name);
+
+ virtual bool specified() const
+ {
+ return _other->specified();
+ }
+
+ virtual void set_specified(const bool value)
+ {
+ _other->set_specified(value);
+ }
+ };
+
+ /**
+ * An option that takes an integer argument.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE IntegerArg :
+ public ArgsOption,
+ public Visitable<IntegerArg, ArgsVisitorTypes>
+ {
+ private:
+ int _argument;
+
+ public:
+ /**
+ * Constructor
+ */
+ IntegerArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description);
+ /**
+ * Fetch the argument that was given to this option.
+ */
+ int argument() const { return _argument; }
+
+ /**
+ * Set the argument returned by argument().
+ */
+ void set_argument(const int arg) { _argument = arg; }
+ };
+
+ /**
+ * An option that takes one of a predefined set of string arguments.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE EnumArg :
+ public ArgsOption,
+ public Visitable<EnumArg, ArgsVisitorTypes>,
+ private PrivateImplementationPattern<EnumArg>
+ {
+ private:
+ std::string _argument;
+ const std::string _default_arg;
+
+ public:
+
+ /**
+ * Helper class for passing available options and associated descriptions
+ * to the EnumArg constructor.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE EnumArgOptions :
+ private PrivateImplementationPattern<EnumArgOptions>
+ {
+ friend class EnumArg;
+
+ public:
+ /**
+ * Constructor
+ */
+ EnumArgOptions(const std::string, const std::string);
+
+ /**
+ * Destructor.
+ */
+ ~EnumArgOptions();
+
+ /**
+ * Adds another (option, description) pair.
+ */
+ EnumArgOptions & operator() (const std::string, const std::string);
+ };
+
+ /**
+ * Constructor.
+ */
+ EnumArg(ArgsGroup * const group, const std::string & long_name,
+ const char short_name, const std::string & description,
+ const EnumArgOptions & opts, const std::string & default_arg);
+
+ ~EnumArg();
+
+ /**
+ * Fetch the argument that was given to this option.
+ */
+ const std::string & argument() const
+ {
+ return _argument;
+ }
+
+ /**
+ * Set the argument returned by argument(), having verified that
+ * it is one of the arguments allowed for this option.
+ */
+ void set_argument(const std::string & arg);
+
+ /**
+ * Fetch the default option, as specified to the constructor.
+ */
+ const std::string & default_arg() const
+ {
+ return _default_arg;
+ }
+
+ ///\name Iterate over our allowed arguments and associated descriptions
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<EnumArg,
+ const std::pair<std::string, std::string> > AllowedArgIterator;
+
+ AllowedArgIterator begin_allowed_args() const;
+
+ AllowedArgIterator end_allowed_args() const;
+
+ ///\}
+ };
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/args_visitor.cc b/0.8.0/paludis/args/args_visitor.cc
new file mode 100644
index 0000000..a43f714
--- /dev/null
+++ b/0.8.0/paludis/args/args_visitor.cc
@@ -0,0 +1,97 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "args_option.hh"
+#include "args_error.hh"
+
+#include <paludis/util/visitor.hh>
+#include <paludis/util/destringify.hh>
+
+#include <sstream>
+
+/** \file
+ * Implementation for ArgsVisitor.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+using namespace paludis;
+using namespace args;
+
+ArgsVisitor::ArgsVisitor(libwrapiter::ForwardIterator<ArgsVisitor, std::string> * ai,
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string> ae) : _args_index(ai), _args_end(ae)
+{
+}
+
+const std::string &
+ArgsVisitor::get_param(const ArgsOption * const arg)
+{
+ if (++(*_args_index) == _args_end)
+ {
+ throw MissingValue("--" + arg->long_name());
+ }
+ return **_args_index;
+}
+
+void ArgsVisitor::visit(ArgsOption * const arg)
+{
+ arg->set_specified(true);
+}
+
+void ArgsVisitor::visit(StringArg * const arg)
+{
+ visit(static_cast<ArgsOption *>(arg));
+ arg->set_argument(get_param(arg));
+}
+
+void ArgsVisitor::visit(AliasArg * const arg)
+{
+ visit(static_cast<ArgsOption *>(arg));
+}
+
+void ArgsVisitor::visit(SwitchArg * const arg)
+{
+ visit(static_cast<ArgsOption *>(arg));
+}
+
+void ArgsVisitor::visit(IntegerArg * const arg)
+{
+ visit(static_cast<ArgsOption*>(arg));
+ std::string param = get_param(arg);
+ try
+ {
+ arg->set_argument(destringify<int>(param));
+ }
+ catch(DestringifyError &e)
+ {
+ throw BadValue("--" + arg->long_name(), param);
+ }
+}
+
+void ArgsVisitor::visit(EnumArg * const arg)
+{
+ visit(static_cast<ArgsOption*>(arg));
+ arg->set_argument(get_param(arg));
+}
+
+void ArgsVisitor::visit(StringSetArg * const arg)
+{
+ visit(static_cast<ArgsOption *>(arg));
+ std::string param = get_param(arg);
+ arg->add_argument(param);
+}
diff --git a/0.8.0/paludis/args/args_visitor.hh b/0.8.0/paludis/args/args_visitor.hh
new file mode 100644
index 0000000..822ae8e
--- /dev/null
+++ b/0.8.0/paludis/args/args_visitor.hh
@@ -0,0 +1,100 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006 Stephen Bennett <spb@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_ARGS_VISITOR_HH
+#define PALUDIS_GUARD_ARGS_ARGS_VISITOR_HH 1
+
+#include <paludis/util/visitor.hh>
+#include <paludis/util/attributes.hh>
+#include <string>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+/** \file
+ * Declaration for ArgsVisitor
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+namespace paludis
+{
+ namespace args
+ {
+ class ArgsOption;
+ class StringArg;
+ class AliasArg;
+ class SwitchArg;
+ class IntegerArg;
+ class EnumArg;
+ class StringSetArg;
+
+ /**
+ * Visitor types for visitors that can visit Args.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ typedef VisitorTypes<ArgsOption *, StringArg *, AliasArg *, SwitchArg *,
+ IntegerArg *, EnumArg *, StringSetArg *> ArgsVisitorTypes;
+
+ /**
+ * Visitor class. Processes command-line options as they are found.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE ArgsVisitor :
+ public ArgsVisitorTypes::Visitor
+ {
+ private:
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string> * _args_index, _args_end;
+
+ const std::string& get_param(const ArgsOption * const);
+
+ public:
+ /**
+ * Constructor
+ */
+ ArgsVisitor(libwrapiter::ForwardIterator<ArgsVisitor, std::string> *,
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string>);
+
+ /// Visit an ArgsOption.
+ void visit(ArgsOption * const);
+
+ /// Visit a StringArg.
+ void visit(StringArg * const);
+
+ /// Visit an AliasArg.
+ void visit(AliasArg * const);
+
+ /// Visit a SwitchArg.
+ void visit(SwitchArg * const);
+
+ /// Visit an IntegerArg.
+ void visit(IntegerArg * const);
+
+ /// Visit an EnumArg.
+ void visit(EnumArg * const);
+
+ /// Visit a StringSetArg.
+ void visit(StringSetArg * const);
+ };
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/bad_argument.cc b/0.8.0/paludis/args/bad_argument.cc
new file mode 100644
index 0000000..e2a9618
--- /dev/null
+++ b/0.8.0/paludis/args/bad_argument.cc
@@ -0,0 +1,35 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "bad_argument.hh"
+
+/** \file
+ * Implementation for BadArgument.
+ *
+ * \ingroup Args
+ * \ingroup Exception
+ */
+
+using namespace paludis::args;
+
+BadArgument::BadArgument(const std::string & option) throw () :
+ ArgsError("Bad argument '" + option + "'")
+{
+}
+
diff --git a/0.8.0/paludis/args/bad_argument.hh b/0.8.0/paludis/args/bad_argument.hh
new file mode 100644
index 0000000..92660e8
--- /dev/null
+++ b/0.8.0/paludis/args/bad_argument.hh
@@ -0,0 +1,54 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_ARGS_BAD_ARGUMENT_HH
+#define PALUDIS_GUARD_ARGS_BAD_ARGUMENT_HH 1
+
+#include <paludis/args/args_error.hh>
+
+/** \file
+ * Declaration for BadArgument.
+ *
+ * \ingroup grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+
+namespace paludis
+{
+ namespace args
+ {
+ /**
+ * Thrown if an unrecognised command line argument is specified.
+ *
+ * \ingroup grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+ class PALUDIS_VISIBLE BadArgument :
+ public ArgsError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ BadArgument(const std::string & option) throw ();
+ };
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/args/man.cc b/0.8.0/paludis/args/man.cc
new file mode 100644
index 0000000..522cb08
--- /dev/null
+++ b/0.8.0/paludis/args/man.cc
@@ -0,0 +1,81 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "man.hh"
+#include <ostream>
+
+using namespace paludis;
+using namespace paludis::args;
+using std::endl;
+
+void
+paludis::args::generate_man(std::ostream & f, const ArgsHandler * const h)
+{
+ f << ".TH \"" << h->app_name() << "\" "
+ << h->man_section() << endl;
+
+ f << ".SH NAME" << endl;
+ f << h->app_name() << " \\- "
+ << h->app_synopsis() << endl;
+
+ f << ".SH SYNOPSIS" << endl;
+
+ for (ArgsHandler::UsageLineIterator u(h->begin_usage_lines()),
+ u_end(h->end_usage_lines()) ; u != u_end ; ++u)
+ f << ".B " << h->app_name() << " " << *u << endl << endl;
+
+ f << ".SH DESCRIPTION" << endl;
+ f << h->app_description() << endl;
+
+ f << ".SH OPTIONS" << endl;
+
+ for (ArgsHandler::ArgsGroupsIterator a(h->begin_args_groups()),
+ a_end(h->end_args_groups()) ; a != a_end ; ++a)
+ {
+ f << ".SS \"" << (*a)->name() << "\"" << endl;
+ f << (*a)->description() << endl;
+
+ for (paludis::args::ArgsGroup::Iterator b((*a)->begin()), b_end((*a)->end()) ;
+ b != b_end ; ++b)
+ {
+ f << ".TP" << endl;
+ f << ".B \"";
+ if ((*b)->short_name())
+ f << "\\-" << (*b)->short_name() << " , ";
+ f << "\\-\\-" << (*b)->long_name() << "\"" << endl;
+ f << (*b)->description() << endl;
+ }
+ }
+
+ if (h->begin_environment_lines() !=
+ h->end_environment_lines())
+ {
+ f << ".SH ENVIRONMENT" << endl;
+
+ for (ArgsHandler::EnvironmentLineIterator a(h->begin_environment_lines()),
+ a_end(h->end_environment_lines()) ; a != a_end ; ++a)
+ {
+ f << ".TP" << endl;
+ f << ".B \"" << a->first << "\"" << endl;
+ f << a->second << endl;
+ }
+
+ }
+}
+
diff --git a/0.8.0/paludis/args/man.hh b/0.8.0/paludis/args/man.hh
new file mode 100644
index 0000000..220707e
--- /dev/null
+++ b/0.8.0/paludis/args/man.hh
@@ -0,0 +1,37 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_ARGS_MAN_HH
+#define PALUDIS_GUARD_PALUDIS_ARGS_MAN_HH 1
+
+#include <paludis/args/args.hh>
+#include <iosfwd>
+
+namespace paludis
+{
+ namespace args
+ {
+ /**
+ * Write a man page to an ostream.
+ */
+ void generate_man(std::ostream &, const ArgsHandler * const h) PALUDIS_VISIBLE;
+ }
+}
+
+#endif
diff --git a/0.8.0/paludis/config_file.cc b/0.8.0/paludis/config_file.cc
new file mode 100644
index 0000000..6bf6785
--- /dev/null
+++ b/0.8.0/paludis/config_file.cc
@@ -0,0 +1,453 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/config_file.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <fstream>
+#include <istream>
+#include <list>
+#include <map>
+
+/** \file
+ * Implementation for config_file.hh classes.
+ *
+ * \ingroup grpconfigfile
+ */
+
+using namespace paludis;
+
+ConfigFileError::ConfigFileError(const std::string & our_message) throw () :
+ ConfigurationError("Config file error: " + our_message)
+{
+}
+
+ConfigFile::ConfigFile(std::istream * const stream) :
+ _stream(stream),
+ _has_lines(false),
+ _destroy_stream(false)
+{
+}
+
+ConfigFile::ConfigFile(const std::string & our_filename) try :
+ _stream(_make_stream(our_filename)),
+ _has_lines(false),
+ _filename(our_filename),
+ _destroy_stream(true)
+{
+}
+catch (...)
+{
+ _destroy_stream = false;
+ throw;
+}
+
+ConfigFile::ConfigFile(const FSEntry & our_filename) try :
+ _stream(_make_stream(stringify(our_filename))),
+ _has_lines(false),
+ _filename(stringify(our_filename)),
+ _destroy_stream(true)
+{
+}
+catch (...)
+{
+ _destroy_stream = false;
+ throw;
+}
+
+ConfigFile::~ConfigFile()
+{
+ if (_stream && _destroy_stream)
+ delete _stream;
+}
+
+std::istream *
+ConfigFile::_make_stream(const std::string & filename)
+{
+ Context context("When creating the filestream for a ConfigFile from file '" + filename + "':");
+
+ std::ifstream * result(new std::ifstream(filename.c_str()));
+ if (! *result)
+ {
+ delete result;
+ throw ConfigFileError("Could not open '" + filename + "'");
+ }
+
+ return result;
+}
+
+void
+ConfigFile::need_lines() const
+{
+ if (_has_lines)
+ return;
+
+ std::string line, accum;
+ unsigned line_number(0);
+ while (std::getline(*_stream, line))
+ {
+ Context c("When handling line " + stringify(++line_number) +
+ (_filename.empty() ? std::string(":") : " in file '" + _filename + "':"));
+ normalise_line(line);
+
+ if (line.empty() || skip_line(line))
+ {
+ if (!accum.empty())
+ throw ConfigFileError("Line-continuation followed by a blank line or comment is invalid.");
+
+ continue;
+ }
+ if ('\\' == line.at(line.length() - 1))
+ {
+ line.erase(line.length() - 1);
+ accum += line;
+ continue;
+ }
+
+ accept_line(accum + line);
+ accum.clear();
+ }
+ if (! _stream->eof())
+ throw ConfigFileError("Error reading from file");
+ if (! accum.empty())
+ throw ConfigFileError("Line-continuation needs a continuation.");
+
+ _has_lines = true;
+ done_reading_lines();
+}
+
+void
+ConfigFile::done_reading_lines() const
+{
+}
+
+void
+ConfigFile::normalise_line(std::string & s) const
+{
+ s = strip_leading(strip_trailing(s, " \t\n"), " \t\n");
+}
+
+bool
+ConfigFile::skip_line(const std::string & s) const
+{
+ return (s.empty() || '#' == s.at(0));
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for LineConfigFile.
+ *
+ * \ingroup grplineconfigfile
+ */
+ template<>
+ struct Implementation<LineConfigFile> :
+ InternalCounted<Implementation<LineConfigFile> >
+ {
+ mutable std::list<std::string> lines;
+ };
+}
+
+LineConfigFile::LineConfigFile(std::istream * const s) :
+ ConfigFile(s),
+ PrivateImplementationPattern<LineConfigFile>(new Implementation<LineConfigFile>)
+{
+ need_lines();
+}
+
+LineConfigFile::LineConfigFile(const std::string & our_filename) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<LineConfigFile>(new Implementation<LineConfigFile>)
+{
+ need_lines();
+}
+
+LineConfigFile::LineConfigFile(const FSEntry & our_filename) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<LineConfigFile>(new Implementation<LineConfigFile>)
+{
+ need_lines();
+}
+
+LineConfigFile::~LineConfigFile()
+{
+}
+
+void
+LineConfigFile::accept_line(const std::string & s) const
+{
+ _imp->lines.push_back(s);
+}
+
+LineConfigFile::Iterator
+LineConfigFile::begin() const
+{
+ return Iterator(_imp->lines.begin());
+}
+
+LineConfigFile::Iterator
+LineConfigFile::end() const
+{
+ return Iterator(_imp->lines.end());
+}
+
+KeyValueConfigFileError::KeyValueConfigFileError(const std::string & msg,
+ const std::string & filename) throw () :
+ ConfigurationError("Key/Value config file error" +
+ (filename.empty() ? ": " : " in file '" + filename + "': ") + msg)
+{
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for KeyValueConfigFile.
+ *
+ * \ingroup grpkvconfigfile
+ */
+ template <>
+ struct Implementation<KeyValueConfigFile> :
+ InternalCounted<Implementation<KeyValueConfigFile> >
+ {
+ mutable std::map<std::string, std::string> entries;
+ mutable std::string accum;
+ mutable std::string accum_key;
+ };
+}
+
+KeyValueConfigFile::KeyValueConfigFile(std::istream * const s) :
+ ConfigFile(s),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(const std::string & our_filename) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(const FSEntry & our_filename) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(std::istream * const s,
+ AssociativeCollection<std::string, std::string>::ConstPointer m) :
+ ConfigFile(s),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ _imp->entries.insert(m->begin(), m->end());
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(const std::string & our_filename,
+ AssociativeCollection<std::string, std::string>::ConstPointer m) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ _imp->entries.insert(m->begin(), m->end());
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(const FSEntry & our_filename,
+ AssociativeCollection<std::string, std::string>::ConstPointer m) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ _imp->entries.insert(m->begin(), m->end());
+ need_lines();
+}
+
+KeyValueConfigFile::~KeyValueConfigFile()
+{
+}
+
+void
+KeyValueConfigFile::accept_line(const std::string & line) const
+{
+ if (! _imp->accum.empty())
+ {
+ std::string value(line);
+ normalise_line(value);
+
+ if (value.empty())
+ return;
+
+ _imp->accum += " ";
+ _imp->accum += value;
+
+ if (value.at(value.length() - 1) == _imp->accum.at(0))
+ {
+ _imp->entries[_imp->accum_key] = replace_variables(strip_quotes(_imp->accum));
+ _imp->accum.clear();
+ _imp->accum_key.clear();
+ }
+ }
+ else
+ {
+ std::string::size_type p(line.find('='));
+ if (std::string::npos == p)
+ _imp->entries[line] = "";
+ else
+ {
+ std::string key(line.substr(0, p)), value(line.substr(p + 1));
+ normalise_line(key);
+ normalise_line(value);
+ if (quotes_are_balanced(value))
+ _imp->entries[key] = replace_variables(strip_quotes(value));
+ else
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Line continuations should "
+ "be indicated with a backslash");
+ _imp->accum = value;
+ _imp->accum_key = key;
+ }
+ }
+ }
+}
+
+void
+KeyValueConfigFile::done_reading_lines() const
+{
+ if (! _imp->accum.empty())
+ throw KeyValueConfigFileError("Unterminated multiline quoted string");
+}
+
+std::string
+KeyValueConfigFile::replace_variables(const std::string & s) const
+{
+ std::string r;
+ std::string::size_type p(0), old_p(0);
+
+ while (p < s.length())
+ {
+ old_p = p;
+
+ if ('\\' == s[p])
+ {
+ if (++p >= s.length())
+ throw KeyValueConfigFileError("Backslash not followed by a character", filename());
+ r += s[p++];
+ }
+ else if ('$' != s[p])
+ r += s[p++];
+ else
+ {
+ std::string name;
+ if (++p >= s.length())
+ throw KeyValueConfigFileError("Dollar not followed by a character", filename());
+
+ if ('{' == s[p])
+ {
+ std::string::size_type q;
+ if (std::string::npos == ((q = s.find("}", p))))
+ throw KeyValueConfigFileError("Closing } not found", filename());
+
+ name = s.substr(p + 1, q - p - 1);
+ p = q + 1;
+ }
+ else
+ {
+ std::string::size_type q;
+ if (std::string::npos == ((q = s.find_first_not_of(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "_0123456789", p))))
+ q = s.length();
+
+ name = s.substr(p, q - p);
+ p = q;
+ }
+
+ if (name.empty())
+ throw KeyValueConfigFileError("Empty variable name", filename());
+ r += get(name);
+ }
+
+ if (p <= old_p)
+ throw InternalError(PALUDIS_HERE, "Infinite loop");
+ }
+
+ return r;
+}
+
+std::string
+KeyValueConfigFile::strip_quotes(const std::string & s) const
+{
+ if (s.empty())
+ return s;
+ if (std::string::npos != std::string("'\"").find(s[0]))
+ {
+ if (s.length() < 2)
+ throw KeyValueConfigFileError("Unterminated quote", filename());
+ if (s[s.length() - 1] != s[0])
+ throw KeyValueConfigFileError("Mismatched quote", filename());
+ return s.substr(1, s.length() - 2);
+ }
+ else
+ return s;
+}
+
+bool
+KeyValueConfigFile::quotes_are_balanced(const std::string & s) const
+{
+ if (s.empty())
+ return true;
+
+ if (std::string::npos != std::string("'\"").find(s[0]))
+ {
+ if (s.length() < 2)
+ return false;
+ if (s[s.length() - 1] != s[0])
+ return false;
+ return true;
+ }
+ else
+ return true;
+}
+
+KeyValueConfigFile::Iterator
+KeyValueConfigFile::begin() const
+{
+ return Iterator(_imp->entries.begin());
+}
+
+KeyValueConfigFile::Iterator
+KeyValueConfigFile::end() const
+{
+ return Iterator(_imp->entries.end());
+}
+
+std::string
+KeyValueConfigFile::get(const std::string & key) const
+{
+ return _imp->entries[key];
+}
+
diff --git a/0.8.0/paludis/config_file.hh b/0.8.0/paludis/config_file.hh
new file mode 100644
index 0000000..35d4fc7
--- /dev/null
+++ b/0.8.0/paludis/config_file.hh
@@ -0,0 +1,304 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_CONFIG_FILE_HH
+#define PALUDIS_GUARD_PALUDIS_CONFIG_FILE_HH 1
+
+#include <paludis/util/collection.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+#include <iosfwd>
+#include <string>
+
+/** \file
+ * Declarations for the ConfigFile classes.
+ *
+ * \ingroup grpconfigfile
+ */
+
+namespace paludis
+{
+ class FSEntry;
+
+ /**
+ * Thrown if an error occurs when reading a ConfigFile.
+ *
+ * \ingroup grpexceptions
+ * \ingroup grpconfigfile
+ */
+ class ConfigFileError : public ConfigurationError
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ConfigFileError(const std::string & message) throw ();
+
+ ///\}
+ };
+
+ /**
+ * A ConfigFile is a file containing one entry per line, with lines
+ * starting with a # being ignored and leading and trailing whitespace
+ * being discarded.
+ *
+ * \ingroup grpconfigfile
+ */
+ class ConfigFile :
+ paludis::InstantiationPolicy<ConfigFile, instantiation_method::NonCopyableTag>
+ {
+ private:
+ std::istream * const _stream;
+
+ mutable bool _has_lines;
+
+ std::string _filename;
+
+ bool _destroy_stream;
+
+ static std::istream * _make_stream(const std::string & filename);
+
+ protected:
+ /**
+ * In-place normalise a line. By default, trims leading and
+ * trailing whitespace. Child classes may override.
+ */
+ virtual void normalise_line(std::string &) const;
+
+ /**
+ * Return whether to skip a line. By default, skips on blank
+ * lines and lines starting with a #. Child classes may
+ * override. This is called on a normalised line, not a raw
+ * string.
+ */
+ virtual bool skip_line(const std::string &) const;
+
+ /**
+ * Accept a normalised line that is not to be skipped.
+ */
+ virtual void accept_line(const std::string &) const = 0;
+
+ /**
+ * Called when we've read in all our lines. By default, does
+ * nothing. Can be used for further validation.
+ */
+ virtual void done_reading_lines() const;
+
+ /**
+ * If we have not done so already, read in our lines.
+ */
+ void need_lines() const;
+
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor.
+ */
+ ConfigFile(std::istream * const stream);
+
+ /**
+ * Constructor, from a file.
+ */
+ ConfigFile(const std::string & filename);
+
+ /**
+ * Constructor, from a file.
+ */
+ ConfigFile(const FSEntry & filename);
+
+ ///\}
+
+ /**
+ * Our filename, or blank if unknown.
+ */
+ std::string filename() const
+ {
+ return _filename;
+ }
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~ConfigFile();
+
+ ///\}
+ };
+
+ /**
+ * A LineConfigFile is a ConfigFile that provides access to the
+ * normalised lines. Do not subclass.
+ *
+ * \ingroup grplineconfigfile
+ */
+ class LineConfigFile :
+ protected ConfigFile,
+ private PrivateImplementationPattern<LineConfigFile>
+ {
+ protected:
+ void accept_line(const std::string &) const;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, from a stream.
+ */
+ LineConfigFile(std::istream * const);
+
+ /**
+ * Constructor, from a filename.
+ */
+ LineConfigFile(const std::string & filename);
+
+ /**
+ * Constructor, from a filename.
+ */
+ LineConfigFile(const FSEntry & filename);
+
+ ~LineConfigFile();
+
+ ///\}
+
+ ///\name Iterate over our lines
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<LineConfigFile, const std::string> Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\}
+ };
+
+ /**
+ * A KeyValueConfigFileError is thrown if bad data is encountered in
+ * a ConfigFile.
+ *
+ * \ingroup grpkvconfigfile
+ * \ingroup grpexceptions
+ */
+ class KeyValueConfigFileError : public ConfigurationError
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ KeyValueConfigFileError(const std::string & message,
+ const std::string & filename = "") throw ();
+
+ ///\}
+ };
+
+ /**
+ * A KeyValueConfigFile is a ConfigFile that provides access to the
+ * normalised lines. Do not subclass.
+ *
+ * \ingroup grpkvconfigfile
+ */
+ class KeyValueConfigFile :
+ protected ConfigFile,
+ private PrivateImplementationPattern<KeyValueConfigFile>
+ {
+ private:
+ bool quotes_are_balanced(const std::string &) const;
+
+ protected:
+ void accept_line(const std::string &) const;
+
+ /**
+ * Handle variable replacement.
+ */
+ std::string replace_variables(const std::string &) const;
+
+ /**
+ * Handle quote removal.
+ */
+ std::string strip_quotes(const std::string &) const;
+
+ virtual void done_reading_lines() const;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, from a stream.
+ */
+ KeyValueConfigFile(std::istream * const);
+
+ /**
+ * Constructor, from a filename.
+ */
+ KeyValueConfigFile(const std::string & filename);
+
+ /**
+ * Constructor, from a filename.
+ */
+ KeyValueConfigFile(const FSEntry & filename);
+
+ /**
+ * Constructor, from a stream, with defaults.
+ */
+ KeyValueConfigFile(std::istream * const,
+ AssociativeCollection<std::string, std::string>::ConstPointer);
+
+ /**
+ * Constructor, from a filename, with defaults.
+ */
+ KeyValueConfigFile(const std::string & filename,
+ AssociativeCollection<std::string, std::string>::ConstPointer);
+
+ /**
+ * Constructor, from a filename, with defaults.
+ */
+ KeyValueConfigFile(const FSEntry & filename,
+ AssociativeCollection<std::string, std::string>::ConstPointer);
+
+ ~KeyValueConfigFile();
+
+ ///\}
+
+ ///\name Iterate over our key/values
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<KeyValueConfigFile,
+ std::pair<const std::string, std::string> > Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\}
+
+ /**
+ * Fetch the specified key, or a blank string.
+ */
+ std::string get(const std::string & key) const;
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/config_file_TEST.cc b/0.8.0/paludis/config_file_TEST.cc
new file mode 100644
index 0000000..b4abcd1
--- /dev/null
+++ b/0.8.0/paludis/config_file_TEST.cc
@@ -0,0 +1,332 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/config_file.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <sstream>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+#include <vector>
+#include <unistd.h>
+
+using namespace test;
+using namespace paludis;
+
+/** \file
+ * Test cases for config_file.hh .
+ *
+ * \ingroup grptestcases
+ * \ingroup grpconfigfile
+ */
+
+namespace
+{
+ /**
+ * A ConfigFile descendent for use in tests.
+ *
+ * \ingroup grptestcases
+ */
+ class TestFile : protected ConfigFile
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ TestFile(std::istream * const stream) :
+ ConfigFile(stream)
+ {
+ need_lines();
+ }
+
+ /**
+ * Constructor.
+ */
+ TestFile(const std::string & filename) :
+ ConfigFile(filename)
+ {
+ need_lines();
+ }
+
+ /**
+ * Constructor.
+ */
+ TestFile(const FSEntry & filename) :
+ ConfigFile(filename)
+ {
+ need_lines();
+ }
+
+ /**
+ * Our lines.
+ */
+ mutable std::vector<std::string> lines;
+
+ protected:
+ void accept_line(const std::string & s) const
+ {
+ lines.push_back(s);
+ }
+ };
+}
+
+namespace test_cases
+{
+ /**
+ * \test Test ConfigFile.
+ *
+ * \ingroup grptestcases
+ */
+ struct ConfigFileTest : TestCase
+ {
+ ConfigFileTest() : TestCase("config file") { }
+
+ void run()
+ {
+ std::stringstream s;
+ s << "one" << std::endl;
+ s << " two \t " << std::endl;
+ s << " \t " << std::endl;
+ s << "" << std::endl;
+ s << "three" << std::endl;
+ s << "# blah" << std::endl;
+ s << " # blah" << std::endl;
+ s << "#" << std::endl;
+ s << " # \t " << std::endl;
+ s << "four four" << std::endl;
+ TestFile f(&s);
+ TEST_CHECK_EQUAL(f.lines.size(), 4);
+ TEST_CHECK_EQUAL(f.lines.at(0), "one");
+ TEST_CHECK_EQUAL(f.lines.at(1), "two");
+ TEST_CHECK_EQUAL(f.lines.at(2), "three");
+ TEST_CHECK_EQUAL(f.lines.at(3), "four four");
+ }
+ } test_config_file;
+
+ /**
+ * \test Test ConfigFile with file opening.
+ *
+ * \ingroup grptestcases
+ */
+ struct ConfigFileOpenFileTest : TestCase
+ {
+ ConfigFileOpenFileTest() : TestCase("config file open file") { }
+
+ void run()
+ {
+ FSEntry ff("config_file_TEST_dir/config_file");
+ TEST_CHECK(ff.is_regular_file());
+ TestFile f(ff);
+ TEST_CHECK_EQUAL(f.lines.size(), 1);
+ TEST_CHECK_EQUAL(f.lines.at(0), "I am a fish.");
+
+ FSEntry ff2("config_file_TEST_dir/not_a_config_file");
+ TEST_CHECK(! ff2.exists());
+ TestFile * f2(0);
+ TEST_CHECK_THROWS(f2 = new TestFile(ff2), ConfigFileError);
+
+ if (0 != geteuid())
+ {
+ FSEntry ff3("config_file_TEST_dir/unreadable_file");
+ TEST_CHECK(ff3.is_regular_file());
+ TestFile * f3(0);
+ TEST_CHECK_THROWS(f3 = new TestFile(ff3), ConfigFileError);
+ }
+ }
+ } test_config_file_open_file;
+
+ /**
+ * \test Test LineConfigFile.
+ *
+ * \ingroup grptestcases
+ */
+ struct LineConfigFileTest : TestCase
+ {
+ LineConfigFileTest() : TestCase("line config file") { }
+
+ void run()
+ {
+ std::stringstream s;
+ s << "one" << std::endl;
+ s << " two \t " << std::endl;
+ s << " \t " << std::endl;
+ s << "" << std::endl;
+ s << "three" << std::endl;
+ s << "# blah" << std::endl;
+ s << " # blah" << std::endl;
+ s << "#" << std::endl;
+ s << " # \t " << std::endl;
+ s << "four four" << std::endl;
+ LineConfigFile ff(&s);
+ std::vector<std::string> f(ff.begin(), ff.end());
+
+ TEST_CHECK_EQUAL(f.size(), 4);
+ TEST_CHECK_EQUAL(f.at(0), "one");
+ TEST_CHECK_EQUAL(f.at(1), "two");
+ TEST_CHECK_EQUAL(f.at(2), "three");
+ TEST_CHECK_EQUAL(f.at(3), "four four");
+ }
+ } test_line_config_file;
+
+ /**
+ * \test Test KeyValueConfigFile basics.
+ *
+ * \ingroup grptestcases
+ */
+ struct KeyValueConfigFileTest : TestCase
+ {
+ KeyValueConfigFileTest() : TestCase("key value config file") { }
+
+ void run()
+ {
+ std::stringstream s;
+ s << "one=first" << std::endl;
+ s << "two = second" << std::endl;
+ s << "three" << std::endl;
+ s << "four = \"fourth\" " << std::endl;
+ s << "five = ''" << std::endl;
+ KeyValueConfigFile ff(&s);
+
+ TEST_CHECK_EQUAL(ff.get("one"), "first");
+ TEST_CHECK_EQUAL(ff.get("two"), "second");
+ TEST_CHECK_EQUAL(ff.get("three"), "");
+ TEST_CHECK_EQUAL(ff.get("four"), "fourth");
+ TEST_CHECK_EQUAL(ff.get("five"), "");
+ TEST_CHECK_EQUAL(ff.get("six"), "");
+ }
+ } test_key_value_config_file;
+
+ /**
+ * \test Test KeyValueConfigFile continuations.
+ *
+ * \ingroup grptestcases
+ */
+ struct KeyValueConfigFileContinuationsTest : TestCase
+ {
+ KeyValueConfigFileContinuationsTest() : TestCase("key value config file continuations") { }
+
+ void run()
+ {
+ std::stringstream s;
+ s << "one='first" << std::endl;
+ s << " first " << std::endl;
+ s << "first'" << std::endl;
+ KeyValueConfigFile ff(&s);
+
+ TEST_CHECK_EQUAL(ff.get("one"), "first first first");
+ }
+ } test_key_value_config_file_continuations;
+
+ /**
+ * \test Test KeyValueConfigFile variables.
+ *
+ * \ingroup grptestcases
+ */
+ struct KeyValueConfigFileVarsTest : TestCase
+ {
+ KeyValueConfigFileVarsTest() : TestCase("key value config file with vars") { }
+
+ void run()
+ {
+ std::stringstream s;
+ s << "x=foo" << std::endl;
+ s << "y = \"${x}\\\\${y}\\$${z}\"" << std::endl;
+ s << "z = $x$y$z" << std::endl;
+ KeyValueConfigFile ff(&s);
+
+ TEST_CHECK_EQUAL(ff.get("x"), "foo");
+ TEST_CHECK_EQUAL(ff.get("y"), "foo\\$");
+ TEST_CHECK_EQUAL(ff.get("z"), "foofoo\\$");
+
+ std::stringstream t;
+ AssociativeCollection<std::string, std::string>::Pointer t_defs(
+ new AssociativeCollection<std::string, std::string>::Concrete);
+ t_defs->insert("a", "moo");
+ t_defs->insert("d", "bar");
+ t_defs->insert("e", "baz");
+ t << "a=foo" << std::endl;
+ t << "b=$a" << std::endl;
+ t << "c=$d" << std::endl;
+ t << "d=$d" << std::endl;
+ t << "f = " << std::endl;
+ t << "g = foo \\" << std::endl;
+ t << " bar" << std::endl;
+ KeyValueConfigFile fg(&t, t_defs);
+
+ TEST_CHECK_EQUAL(fg.get("a"), "foo");
+ TEST_CHECK_EQUAL(fg.get("b"), "foo");
+ TEST_CHECK_EQUAL(fg.get("c"), "bar");
+ TEST_CHECK_EQUAL(fg.get("d"), "bar");
+ TEST_CHECK_EQUAL(fg.get("e"), "baz");
+ TEST_CHECK_EQUAL(fg.get("f"), "");
+ TEST_CHECK_EQUAL(fg.get("g"), "foo bar");
+ }
+ } test_key_value_config_file_vars;
+
+ /**
+ * \test Test KeyValueConfigFile errors.
+ *
+ * \ingroup grptestcases
+ */
+ struct KeyValueConfigFileErrorsTest : TestCase
+ {
+ KeyValueConfigFileErrorsTest() : TestCase("key value config file with errors") { }
+
+ void run()
+ {
+ std::stringstream s1;
+ s1 << "x='" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s1), ConfigurationError);
+
+ std::stringstream s2;
+ s2 << "x='moo\"" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s2), ConfigurationError);
+
+ std::stringstream s3;
+ s3 << "x=${foo" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s3), ConfigurationError);
+
+ std::stringstream s4;
+ s4 << "x=$~" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s4), ConfigurationError);
+
+ std::stringstream s5;
+ s5 << "x=abc\\" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s5), ConfigurationError);
+
+ std::stringstream s6;
+ s6 << "x=$" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s6), ConfigurationError);
+
+ std::stringstream s7;
+ s7 << "x=blah \\" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s7), ConfigurationError);
+
+ std::stringstream s8;
+ s8 << "x=blah \\" << std::endl << "# foo" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s8), ConfigurationError);
+
+ std::stringstream s9;
+ s9 << "x='blah" << std::endl << "blah" << std::endl;
+ TEST_CHECK_THROWS(KeyValueConfigFile ff(&s9), ConfigurationError);
+ }
+ } test_key_value_config_file_errors;
+}
+
diff --git a/0.8.0/paludis/config_file_TEST_cleanup.sh b/0.8.0/paludis/config_file_TEST_cleanup.sh
new file mode 100755
index 0000000..b4ed3db
--- /dev/null
+++ b/0.8.0/paludis/config_file_TEST_cleanup.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d config_file_TEST_dir ] ; then
+ rm -fr config_file_TEST_dir
+else
+ true
+fi
+
+
diff --git a/0.8.0/paludis/config_file_TEST_setup.sh b/0.8.0/paludis/config_file_TEST_setup.sh
new file mode 100755
index 0000000..a35809b
--- /dev/null
+++ b/0.8.0/paludis/config_file_TEST_setup.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir config_file_TEST_dir || exit 2
+cd config_file_TEST_dir || exit 3
+echo "I am a fish." > config_file || exit 4
+echo "I am a fish too." > unreadable_file || exit 5
+chmod a-r unreadable_file || exit 6
+
diff --git a/0.8.0/paludis/contents.cc b/0.8.0/paludis/contents.cc
new file mode 100644
index 0000000..471b6f1
--- /dev/null
+++ b/0.8.0/paludis/contents.cc
@@ -0,0 +1,97 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "contents.hh"
+#include <list>
+
+/** \file
+ * Implementation for Contents classes.
+ *
+ * \ingroup grpcontents
+ */
+
+using namespace paludis;
+
+ContentsEntry::~ContentsEntry()
+{
+}
+
+ContentsFileEntry::ContentsFileEntry(const std::string & our_name) :
+ ContentsEntry(our_name)
+{
+}
+
+ContentsDirEntry::ContentsDirEntry(const std::string & our_name) :
+ ContentsEntry(our_name)
+{
+}
+
+ContentsMiscEntry::ContentsMiscEntry(const std::string & our_name) :
+ ContentsEntry(our_name)
+{
+}
+
+ContentsSymEntry::ContentsSymEntry(const std::string & our_name, const std::string & our_target) :
+ ContentsEntry(our_name),
+ _target(our_target)
+{
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for Contents.
+ *
+ * \ingroup grpcontents
+ */
+ template<>
+ struct Implementation<Contents> :
+ InternalCounted<Implementation<Contents> >
+ {
+ std::list<ContentsEntry::ConstPointer> c;
+ };
+}
+
+Contents::Contents() :
+ PrivateImplementationPattern<Contents>(new Implementation<Contents>())
+{
+}
+
+Contents::~Contents()
+{
+}
+
+void
+Contents::add(ContentsEntry::ConstPointer c)
+{
+ _imp->c.push_back(c);
+}
+
+Contents::Iterator
+Contents::begin() const
+{
+ return Iterator(_imp->c.begin());
+}
+
+Contents::Iterator
+Contents::end() const
+{
+ return Iterator(_imp->c.end());
+}
+
diff --git a/0.8.0/paludis/contents.hh b/0.8.0/paludis/contents.hh
new file mode 100644
index 0000000..21cae7a
--- /dev/null
+++ b/0.8.0/paludis/contents.hh
@@ -0,0 +1,208 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_CONTENTS_HH
+#define PALUDIS_GUARD_PALUDIS_CONTENTS_HH 1
+
+#include <paludis/util/visitor.hh>
+#include <paludis/util/counted_ptr.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <string>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+/** \file
+ * Declarations for the Contents classes.
+ *
+ * \ingroup grpcontents
+ */
+
+namespace paludis
+{
+ struct ContentsEntry;
+ struct ContentsFileEntry;
+ struct ContentsDirEntry;
+ struct ContentsSymEntry;
+ struct ContentsMiscEntry;
+
+ /**
+ * Visit a contents heirarchy.
+ *
+ * \ingroup grpcontents
+ */
+ typedef VisitorTypes<ContentsFileEntry *, ContentsDirEntry *,
+ ContentsSymEntry *, ContentsMiscEntry *> ContentsVisitorTypes;
+
+ /**
+ * Base class for a contents entry.
+ *
+ * \ingroup grpcontents
+ */
+ class ContentsEntry :
+ private InstantiationPolicy<ContentsEntry, instantiation_method::NonCopyableTag>,
+ public InternalCounted<ContentsEntry>,
+ public virtual VisitableInterface<ContentsVisitorTypes>
+ {
+ private:
+ std::string _name;
+
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ ContentsEntry(const std::string & our_name) :
+ _name(our_name)
+ {
+ }
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~ContentsEntry();
+
+ ///\}
+
+ /// Our name.
+ std::string name() const
+ {
+ return _name;
+ }
+ };
+
+ /**
+ * A file contents entry.
+ *
+ * \ingroup grpcontents
+ */
+ class ContentsFileEntry :
+ public ContentsEntry,
+ public Visitable<ContentsFileEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsFileEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A directory contents entry.
+ *
+ * \ingroup grpcontents
+ */
+ class ContentsDirEntry :
+ public ContentsEntry,
+ public Visitable<ContentsDirEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsDirEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A misc contents entry.
+ *
+ * \ingroup grpcontents
+ */
+ class ContentsMiscEntry :
+ public ContentsEntry,
+ public Visitable<ContentsMiscEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsMiscEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A sym contents entry.
+ *
+ * \ingroup grpcontents
+ */
+ class ContentsSymEntry :
+ public ContentsEntry,
+ public Visitable<ContentsSymEntry, ContentsVisitorTypes>
+ {
+ private:
+ std::string _target;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsSymEntry(const std::string & name, const std::string & target);
+
+ ///\}
+
+ /// Our target (as per readlink).
+ std::string target() const
+ {
+ return _target;
+ }
+ };
+
+ /**
+ * A package's contents.
+ *
+ * \ingroup grpcontents
+ */
+ class Contents :
+ private InstantiationPolicy<Contents, instantiation_method::NonCopyableTag>,
+ private PrivateImplementationPattern<Contents>,
+ public InternalCounted<Contents>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ Contents();
+ ~Contents();
+
+ ///\}
+
+ /// Add a new entry.
+ void add(ContentsEntry::ConstPointer c);
+
+ ///\name Iterate over our entries
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<Contents, const ContentsEntry::ConstPointer> Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\}
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/dep_atom.cc b/0.8.0/paludis/dep_atom.cc
new file mode 100644
index 0000000..384804d
--- /dev/null
+++ b/0.8.0/paludis/dep_atom.cc
@@ -0,0 +1,377 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/dep_atom.hh>
+#include <paludis/util/log.hh>
+
+#include <list>
+#include <map>
+
+/** \file
+ * Implementation for dep_atom.hh things.
+ *
+ * \ingroup grpdepatoms
+ */
+
+using namespace paludis;
+
+DepAtom::DepAtom()
+{
+}
+
+DepAtom::~DepAtom()
+{
+}
+
+const UseDepAtom *
+DepAtom::as_use_dep_atom() const
+{
+ return 0;
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for CompositeDepAtom.
+ *
+ * \ingroup grpdepatoms
+ */
+ template<>
+ struct Implementation<CompositeDepAtom> :
+ InternalCounted<Implementation<CompositeDepAtom> >
+ {
+ std::list<DepAtom::ConstPointer> children;
+ };
+}
+
+CompositeDepAtom::CompositeDepAtom() :
+ PrivateImplementationPattern<CompositeDepAtom>(new Implementation<CompositeDepAtom>)
+{
+}
+
+CompositeDepAtom::~CompositeDepAtom()
+{
+}
+
+void
+CompositeDepAtom::add_child(DepAtom::ConstPointer c)
+{
+ _imp->children.push_back(c);
+}
+
+CompositeDepAtom::Iterator
+CompositeDepAtom::begin() const
+{
+ return Iterator(_imp->children.begin());
+}
+
+CompositeDepAtom::Iterator
+CompositeDepAtom::end() const
+{
+ return Iterator(_imp->children.end());
+}
+
+AnyDepAtom::AnyDepAtom()
+{
+}
+
+AllDepAtom::AllDepAtom()
+{
+}
+
+UseDepAtom::UseDepAtom(const UseFlagName & our_flag, bool is_inverse) :
+ _flag(our_flag),
+ _inverse(is_inverse)
+{
+}
+
+const UseDepAtom *
+UseDepAtom::as_use_dep_atom() const
+{
+ return this;
+}
+
+BlockDepAtom::BlockDepAtom(PackageDepAtom::ConstPointer a) :
+ StringDepAtom("!" + a->text()),
+ _atom(a)
+{
+}
+
+PackageDepAtom::PackageDepAtom(const QualifiedPackageName & our_package) :
+ StringDepAtom(stringify(our_package)),
+ _package(our_package),
+ _version_operator("="),
+ _version_spec(0),
+ _slot(0),
+ _repository(0),
+ _use_requirements(0),
+ _tag(0)
+{
+}
+
+PackageDepAtom::PackageDepAtom(const std::string & ss) :
+ StringDepAtom(ss),
+ _package(CategoryNamePart("later"), PackageNamePart("later")),
+ _version_operator("="),
+ _version_spec(0),
+ _slot(0),
+ _repository(0),
+ _use_requirements(0),
+ _tag(0)
+{
+ Context context("When parsing package dep atom '" + ss + "':");
+
+ try
+ {
+ std::string s(ss);
+
+ if (s.empty())
+ throw PackageDepAtomError("Got empty dep atom");
+
+ std::string::size_type use_group_p;
+ while (std::string::npos != ((use_group_p = s.rfind('['))))
+ {
+ if (s.at(s.length() - 1) != ']')
+ throw PackageDepAtomError("Mismatched []");
+
+ std::string flag(s.substr(use_group_p + 1));
+ UseFlagState state(use_enabled);
+ if (flag.length() < 2)
+ throw PackageDepAtomError("Invalid [] contents");
+ flag.erase(flag.length() - 1);
+ if ('-' == flag.at(0))
+ {
+ state = use_disabled;
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw PackageDepAtomError("Invalid [] contents");
+ }
+ UseFlagName name(flag);
+ if (0 == _use_requirements)
+ _use_requirements.assign(new UseRequirements);
+ if (! _use_requirements->insert(name, state))
+ throw PackageDepAtomError("Conflicting [] contents");
+
+ s.erase(use_group_p);
+ }
+
+ std::string::size_type repo_p;
+ if (std::string::npos != ((repo_p = s.rfind("::"))))
+ {
+ _repository.assign(new RepositoryName(s.substr(repo_p + 2)));
+ s.erase(repo_p);
+ }
+
+ std::string::size_type slot_p;
+ if (std::string::npos != ((slot_p = s.rfind(':'))))
+ {
+ _slot.assign(new SlotName(s.substr(slot_p + 1)));
+ s.erase(slot_p);
+ }
+
+ if (std::string::npos != std::string("<>=~").find(s.at(0)))
+ {
+ std::string::size_type p(1);
+ if (s.length() > 1 && std::string::npos != std::string("<>=~").find(s.at(1)))
+ ++p;
+ _version_operator = s.substr(0, p);
+
+ std::string::size_type q(p);
+
+ while (true)
+ {
+ if (p >= s.length())
+ throw PackageDepAtomError("Couldn't parse dep atom '" + ss + "'");
+ q = s.find('-', q + 1);
+ if ((std::string::npos == q) || (++q >= s.length()))
+ throw PackageDepAtomError("Couldn't parse dep atom '" + ss + "'");
+ if ((s.at(q) >= '0' && s.at(q) <= '9') || (0 == s.compare(q, 3, "scm")))
+ break;
+ }
+
+ std::string::size_type new_q(q);
+ while (true)
+ {
+ if (new_q >= s.length())
+ break;
+ new_q = s.find('-', new_q + 1);
+ if ((std::string::npos == new_q) || (++new_q >= s.length()))
+ break;
+ if (s.at(new_q) >= '0' && s.at(new_q) <= '9')
+ q = new_q;
+ }
+
+ _package = QualifiedPackageName(s.substr(p, q - p - 1));
+
+ if ('*' == s.at(s.length() - 1))
+ {
+ if (_version_operator != vo_equal)
+ Log::get_instance()->message(ll_qa, lc_context,
+ "Package dep atom '" + ss + "' uses * "
+ "with operator '" + stringify(_version_operator) +
+ "', pretending it uses the equals operator instead");
+ _version_operator = vo_equal_star;
+ _version_spec = CountedPtr<VersionSpec, count_policy::ExternalCountTag>(
+ new VersionSpec(s.substr(q, s.length() - q - 1)));
+ }
+ else
+ _version_spec = CountedPtr<VersionSpec, count_policy::ExternalCountTag>(
+ new VersionSpec(s.substr(q)));
+ }
+ else
+ _package = QualifiedPackageName(s);
+ }
+ catch (Exception &)
+ {
+ throw;
+ }
+ catch (const std::exception & e)
+ {
+ throw InternalError(PALUDIS_HERE, "caught std::exception '"
+ + stringify(e.what()) + "'");
+ }
+}
+
+PackageDepAtom::~PackageDepAtom()
+{
+}
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const PackageDepAtom & a)
+{
+ if (a.version_spec_ptr())
+ {
+ if (a.version_operator() == vo_equal_star)
+ s << "=";
+ else
+ s << a.version_operator();
+ }
+
+ s << a.package();
+
+ if (a.version_spec_ptr())
+ {
+ s << "-" << *a.version_spec_ptr();
+
+ if (a.version_operator() == vo_equal_star)
+ s << "*";
+ }
+
+ if (a.slot_ptr())
+ s << ":" << *a.slot_ptr();
+ if (a.repository_ptr())
+ s << "::" << *a.repository_ptr();
+
+ if (a.use_requirements_ptr())
+ {
+ for (UseRequirements::Iterator u(a.use_requirements_ptr()->begin()),
+ u_end(a.use_requirements_ptr()->end()) ; u != u_end ; ++u)
+ s << "[" << (u->second == use_disabled ? "-" + stringify(u->first) :
+ stringify(u->first)) << "]";
+ }
+
+ return s;
+}
+
+PackageDepAtomError::PackageDepAtomError(const std::string & msg) throw () :
+ Exception(msg)
+{
+}
+
+StringDepAtom::StringDepAtom(const std::string & s) :
+ _str(s)
+{
+}
+
+StringDepAtom::~StringDepAtom()
+{
+}
+
+
+PlainTextDepAtom::PlainTextDepAtom(const std::string & s) :
+ StringDepAtom(s)
+{
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for UseRequirements.
+ *
+ * \ingroup grpdepatoms
+ */
+ template<>
+ struct Implementation<UseRequirements> :
+ InternalCounted<Implementation<UseRequirements> >
+ {
+ std::map<UseFlagName, UseFlagState> reqs;
+ };
+}
+
+UseRequirements::UseRequirements() :
+ PrivateImplementationPattern<UseRequirements>(new Implementation<UseRequirements>)
+{
+}
+
+UseRequirements::~UseRequirements()
+{
+}
+
+UseRequirements::Iterator
+UseRequirements::begin() const
+{
+ return Iterator(_imp->reqs.begin());
+}
+
+UseRequirements::Iterator
+UseRequirements::end() const
+{
+ return Iterator(_imp->reqs.end());
+}
+
+UseRequirements::Iterator
+UseRequirements::find(const UseFlagName & u) const
+{
+ return Iterator(_imp->reqs.find(u));
+}
+
+bool
+UseRequirements::insert(const UseFlagName & u, UseFlagState s)
+{
+ return _imp->reqs.insert(std::make_pair(u, s)).second;
+}
+
+UseFlagState
+UseRequirements::state(const UseFlagName & u) const
+{
+ Iterator i(find(u));
+ if (end() == i)
+ return use_unspecified;
+ return i->second;
+}
+
+PackageDepAtom::Pointer
+PackageDepAtom::without_use_requirements() const
+{
+ std::string s(text());
+ if (std::string::npos != s.find('['))
+ s.erase(s.find('['));
+ return Pointer(new PackageDepAtom(s));
+}
+
diff --git a/0.8.0/paludis/dep_atom.hh b/0.8.0/paludis/dep_atom.hh
new file mode 100644
index 0000000..0f75734
--- /dev/null
+++ b/0.8.0/paludis/dep_atom.hh
@@ -0,0 +1,526 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_ATOM_HH 1
+
+#include <paludis/dep_tag.hh>
+#include <paludis/name.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/util/counted_ptr.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/visitor.hh>
+#include <paludis/version_operator.hh>
+#include <paludis/version_spec.hh>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+/** \file
+ * Declarations for the DepAtom classes.
+ *
+ * \ingroup grpdepatoms
+ */
+
+namespace paludis
+{
+ class DepAtom;
+ class CompositeDepAtom;
+ class PackageDepAtom;
+ class PlainTextDepAtom;
+ class AllDepAtom;
+ class AnyDepAtom;
+ class UseDepAtom;
+ class BlockDepAtom;
+
+ /**
+ * Visitor types for a visitor that can visit a DepAtom heirarchy.
+ *
+ * \ingroup grpdepatoms
+ */
+ typedef VisitorTypes<PackageDepAtom *, PlainTextDepAtom *, AllDepAtom *, AnyDepAtom *,
+ UseDepAtom *, BlockDepAtom *> DepAtomVisitorTypes;
+
+ /**
+ * Base class for a dependency atom.
+ *
+ * \ingroup grpdepatoms
+ */
+ class DepAtom :
+ public virtual VisitableInterface<DepAtomVisitorTypes>,
+ private InstantiationPolicy<DepAtom, instantiation_method::NonCopyableTag>,
+ public InternalCounted<DepAtom>
+ {
+ protected:
+ DepAtom();
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~DepAtom();
+
+ ///\}
+
+ ///\name Upcasts
+ ///\{
+
+ /**
+ * Return us as a UseDepAtom, or 0 if we are not a
+ * UseDepAtom.
+ */
+ virtual const UseDepAtom * as_use_dep_atom() const;
+
+ ///\}
+ };
+
+ /**
+ * Class for dependency atoms that have a number of child dependency
+ * atoms.
+ *
+ * \ingroup grpdepatoms
+ */
+ class CompositeDepAtom :
+ public DepAtom,
+ private PrivateImplementationPattern<CompositeDepAtom>
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ CompositeDepAtom();
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ~CompositeDepAtom();
+
+ ///\}
+
+ ///\name Modify our children
+ ///\{
+
+ /**
+ * Append a child to our collection.
+ */
+ virtual void add_child(DepAtom::ConstPointer);
+
+ ///\}
+
+ ///\name Iterate over our children
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<CompositeDepAtom, const DepAtom::ConstPointer> Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\name Pointer types
+ ///\{
+ typedef CountedPtr<CompositeDepAtom, count_policy::InternalCountTag> Pointer;
+
+ typedef CountedPtr<const CompositeDepAtom, count_policy::InternalCountTag> ConstPointer;
+ ///\}
+ };
+
+ /**
+ * Represents a "|| ( )" dependency block.
+ *
+ * \ingroup grpdepatoms
+ */
+ class AnyDepAtom :
+ public CompositeDepAtom,
+ public Visitable<AnyDepAtom, DepAtomVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ AnyDepAtom();
+
+ ///\}
+ };
+
+ /**
+ * Represents a ( first second third ) or top level group of dependency
+ * atoms.
+ *
+ * \ingroup grpdepatoms
+ */
+ class AllDepAtom :
+ public CompositeDepAtom,
+ public Visitable<AllDepAtom, DepAtomVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ AllDepAtom();
+
+ ///\}
+ };
+
+ /**
+ * Represents a use? ( ) dependency atom.
+ *
+ * \ingroup grpdepatoms
+ */
+ class UseDepAtom :
+ public CompositeDepAtom,
+ public Visitable<UseDepAtom, DepAtomVisitorTypes>
+ {
+ private:
+ const UseFlagName _flag;
+ const bool _inverse;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ UseDepAtom(const UseFlagName &, bool);
+
+ ///\}
+
+ /**
+ * Fetch our use flag name.
+ */
+ const UseFlagName & flag() const
+ {
+ return _flag;
+ }
+
+ /**
+ * Fetch whether we are a ! flag.
+ */
+ bool inverse() const
+ {
+ return _inverse;
+ }
+
+ virtual const UseDepAtom * as_use_dep_atom() const;
+ };
+
+ /**
+ * A StringDepAtom represents a non-composite dep atom with an associated
+ * piece of text.
+ *
+ * \ingroup grpdepatoms
+ */
+ class StringDepAtom :
+ public DepAtom
+ {
+ private:
+ const std::string _str;
+
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ StringDepAtom(const std::string &);
+
+ ~StringDepAtom();
+
+ ///\}
+
+ public:
+ /**
+ * Fetch our text.
+ */
+ const std::string & text() const
+ {
+ return _str;
+ }
+ };
+
+ /**
+ * A selection of USE flag requirements.
+ *
+ * \ingroup grpdepatoms
+ */
+ class UseRequirements :
+ public InternalCounted<UseRequirements>,
+ private PrivateImplementationPattern<UseRequirements>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ UseRequirements();
+ ~UseRequirements();
+
+ ///\}
+
+ ///\name Iterate over our USE requirements
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<UseRequirements,
+ const std::pair<const UseFlagName, UseFlagState> > Iterator;
+
+ Iterator begin() const;
+ Iterator end() const;
+
+ ///\}
+
+ /// Find the requirement for a particular USE flag.
+ Iterator find(const UseFlagName & u) const;
+
+ /// Insert a new requirement.
+ bool insert(const UseFlagName & u, UseFlagState s);
+
+ /// What state is desired for a particular use flag?
+ UseFlagState state(const UseFlagName &) const;
+ };
+
+ /**
+ * A PackageDepAtom represents a package name (for example,
+ * 'app-editors/vim'), possibly with associated version and SLOT
+ * restrictions.
+ *
+ * \ingroup grpdepatoms
+ */
+ class PackageDepAtom :
+ public StringDepAtom,
+ public Visitable<PackageDepAtom, DepAtomVisitorTypes>
+ {
+ private:
+ QualifiedPackageName _package;
+ VersionOperator _version_operator;
+ CountedPtr<VersionSpec, count_policy::ExternalCountTag> _version_spec;
+ CountedPtr<SlotName, count_policy::ExternalCountTag> _slot;
+ CountedPtr<RepositoryName, count_policy::ExternalCountTag> _repository;
+ UseRequirements::Pointer _use_requirements;
+ DepTag::ConstPointer _tag;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, no version or SLOT restrictions.
+ */
+ PackageDepAtom(const QualifiedPackageName & package);
+
+ /**
+ * Constructor, parse restrictions ourself.
+ */
+ PackageDepAtom(const std::string &);
+
+ ~PackageDepAtom();
+
+ ///\}
+
+ /**
+ * Fetch the package name.
+ */
+ const QualifiedPackageName & package() const
+ {
+ return _package;
+ }
+
+ /**
+ * Fetch the version operator.
+ */
+ const VersionOperator version_operator() const
+ {
+ return _version_operator;
+ }
+
+ /**
+ * Fetch the version spec (may be a zero pointer).
+ */
+ CountedPtr<VersionSpec, count_policy::ExternalCountTag> version_spec_ptr() const
+ {
+ return _version_spec;
+ }
+
+ /**
+ * Fetch the slot name (may be a zero pointer).
+ */
+ CountedPtr<SlotName, count_policy::ExternalCountTag> slot_ptr() const
+ {
+ return _slot;
+ }
+
+ /**
+ * Fetch the repo name (may be a zero pointer).
+ */
+ CountedPtr<RepositoryName, count_policy::ExternalCountTag> repository_ptr() const
+ {
+ return _repository;
+ }
+
+ /**
+ * Fetch the use requirements (may be a zero pointer).
+ */
+ UseRequirements::ConstPointer use_requirements_ptr() const
+ {
+ return _use_requirements;
+ }
+
+ ///\name Pointer types
+ ///\{
+
+ /**
+ * A non-constant smart pointer to ourself.
+ */
+ typedef CountedPtr<PackageDepAtom, count_policy::InternalCountTag> Pointer;
+
+ /**
+ * A constant smart pointer to ourself.
+ */
+ typedef CountedPtr<const PackageDepAtom, count_policy::InternalCountTag> ConstPointer;
+
+ ///\}
+
+ /**
+ * Fetch our tag.
+ */
+ DepTag::ConstPointer tag() const
+ {
+ return _tag;
+ }
+
+ /**
+ * Set our tag.
+ */
+ void set_tag(const DepTag::ConstPointer & s)
+ {
+ _tag = s;
+ }
+
+ /**
+ * Fetch a copy of ourself without the USE requirements.
+ */
+ Pointer without_use_requirements() const;
+ };
+
+ /**
+ * A PlainTextDepAtom represents a plain text entry (for example,
+ * a URI in SRC_URI).
+ *
+ * \ingroup grpdepatoms
+ */
+ class PlainTextDepAtom :
+ public StringDepAtom,
+ public Visitable<PlainTextDepAtom, DepAtomVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ PlainTextDepAtom(const std::string &);
+
+ ///\}
+
+ ///\name Pointer types
+ ///\{
+
+ /**
+ * A non-constant smart pointer to ourself.
+ */
+ typedef CountedPtr<PlainTextDepAtom, count_policy::InternalCountTag> Pointer;
+
+ /**
+ * A constant smart pointer to ourself.
+ */
+ typedef CountedPtr<const PlainTextDepAtom, count_policy::InternalCountTag> ConstPointer;
+
+ ///\}
+ };
+
+ /**
+ * Thrown if an invalid package dep atom specification is encountered.
+ *
+ * \ingroup grpexceptions
+ * \ingroup grpdepatoms
+ */
+ class PackageDepAtomError :
+ public Exception
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ PackageDepAtomError(const std::string & msg) throw ();
+
+ ///\}
+ };
+
+ /**
+ * A PackageDepAtom can be written to an ostream.
+ *
+ * \ingroup grpdepatoms
+ */
+ std::ostream & operator<< (std::ostream &, const PackageDepAtom &);
+
+ /**
+ * A BlockDepAtom represents a block on a package name (for example,
+ * 'app-editors/vim'), possibly with associated version and SLOT
+ * restrictions.
+ *
+ * \ingroup grpdepatoms
+ */
+ class BlockDepAtom :
+ public StringDepAtom,
+ public Visitable<BlockDepAtom, DepAtomVisitorTypes>
+ {
+ private:
+ PackageDepAtom::ConstPointer _atom;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, with blocking atom.
+ */
+ BlockDepAtom(PackageDepAtom::ConstPointer atom);
+
+ ///\}
+
+ /**
+ * Fetch the atom we're blocking.
+ */
+ PackageDepAtom::ConstPointer blocked_atom() const
+ {
+ return _atom;
+ }
+
+ ///\name Pointer operations
+ ///\{
+
+ /**
+ * A non-constant smart pointer to ourself.
+ */
+ typedef CountedPtr<BlockDepAtom, count_policy::InternalCountTag> Pointer;
+
+ /**
+ * A constant smart pointer to ourself.
+ */
+ typedef CountedPtr<const BlockDepAtom, count_policy::InternalCountTag> ConstPointer;
+
+ ///\}
+ };
+
+}
+
+#endif
diff --git a/0.8.0/paludis/dep_atom_TEST.cc b/0.8.0/paludis/dep_atom_TEST.cc
new file mode 100644
index 0000000..2565dc5
--- /dev/null
+++ b/0.8.0/paludis/dep_atom_TEST.cc
@@ -0,0 +1,169 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/dep_atom.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+/** \file
+ * Test cases for dep_atom.hh classes.
+ *
+ * \ingroup grptestcases
+ */
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ /**
+ * \test Test DepAtom as_ functions.
+ *
+ * \ingroup grptestcases
+ */
+ struct DepAtomAsTest : TestCase
+ {
+ DepAtomAsTest() : TestCase("dep atom as") { }
+
+ void run()
+ {
+ PackageDepAtom::Pointer x(new PackageDepAtom("foo/bar"));
+ TEST_CHECK(0 == x->as_use_dep_atom());
+
+ UseDepAtom::Pointer y(new UseDepAtom(UseFlagName("foo"), x));
+ TEST_CHECK(0 != y->as_use_dep_atom());
+ TEST_CHECK(y.raw_pointer() == y->as_use_dep_atom());
+ }
+ } test_dep_atom_as;
+
+ /**
+ * \test Test DepAtom composite functions.
+ *
+ * \ingroup grptestcases
+ */
+ struct DepAtomCompositeTest : TestCase
+ {
+ DepAtomCompositeTest() : TestCase("dep atom composite") { }
+
+ void run()
+ {
+ AllDepAtom::Pointer x(new AllDepAtom);
+ TEST_CHECK(x->begin() == x->end());
+
+ x->add_child(PackageDepAtom::Pointer(new PackageDepAtom("x/y")));
+ TEST_CHECK(x->begin() != x->end());
+ TEST_CHECK_EQUAL(1, std::distance(x->begin(), x->end()));
+
+ x->add_child(PackageDepAtom::Pointer(new PackageDepAtom("x/y")));
+ TEST_CHECK(x->begin() != x->end());
+ TEST_CHECK_EQUAL(2, std::distance(x->begin(), x->end()));
+ }
+ } test_dep_atom_composite;
+
+ /**
+ * \test Test PackageDepAtom.
+ *
+ * \ingroup grptestcases
+ */
+ struct PackageDepAtomTest : TestCase
+ {
+ PackageDepAtomTest() : TestCase("package dep atom") { }
+
+ void run()
+ {
+ PackageDepAtom a("foo/bar");
+ TEST_CHECK_STRINGIFY_EQUAL(a.package(), "foo/bar");
+ TEST_CHECK(! a.slot_ptr());
+ TEST_CHECK(! a.version_spec_ptr());
+
+ PackageDepAtom b(">=foo/bar-1.2.3");
+ TEST_CHECK_STRINGIFY_EQUAL(b.package(), "foo/bar");
+ TEST_CHECK(! b.slot_ptr());
+ TEST_CHECK(b.version_spec_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*b.version_spec_ptr(), "1.2.3");
+ TEST_CHECK_EQUAL(b.version_operator(), vo_greater_equal);
+
+ PackageDepAtom c("foo/bar:baz");
+ TEST_CHECK_STRINGIFY_EQUAL(c.package(), "foo/bar");
+ TEST_CHECK(c.slot_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*c.slot_ptr(), "baz");
+ TEST_CHECK(! c.version_spec_ptr());
+
+ PackageDepAtom d("=foo/bar-1.2*:1.2.1");
+ TEST_CHECK_STRINGIFY_EQUAL(d.package(), "foo/bar");
+ TEST_CHECK(d.slot_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*d.slot_ptr(), "1.2.1");
+ TEST_CHECK(d.version_spec_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*d.version_spec_ptr(), "1.2");
+ TEST_CHECK_EQUAL(d.version_operator(), vo_equal_star);
+
+ PackageDepAtom e("foo/bar:1.2.1");
+ TEST_CHECK_STRINGIFY_EQUAL(e.package(), "foo/bar");
+ TEST_CHECK(e.slot_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*e.slot_ptr(), "1.2.1");
+ TEST_CHECK(! e.version_spec_ptr());
+
+ PackageDepAtom f("foo/bar:0");
+ TEST_CHECK_STRINGIFY_EQUAL(f.package(), "foo/bar");
+ TEST_CHECK(f.slot_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*f.slot_ptr(), "0");
+ TEST_CHECK(! f.version_spec_ptr());
+
+ PackageDepAtom g("foo/bar-100dpi");
+ TEST_CHECK_STRINGIFY_EQUAL(g.package(), "foo/bar-100dpi");
+
+ PackageDepAtom h(">=foo/bar-100dpi-1.23");
+ TEST_CHECK_STRINGIFY_EQUAL(h.package(), "foo/bar-100dpi");
+ TEST_CHECK(h.version_spec_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*h.version_spec_ptr(), "1.23");
+ TEST_CHECK_EQUAL(h.version_operator(), vo_greater_equal);
+
+ TEST_CHECK_THROWS(PackageDepAtom(""), PackageDepAtomError);
+
+ PackageDepAtom i("foo/bar[one][-two]");
+ TEST_CHECK_STRINGIFY_EQUAL(i.package(), "foo/bar");
+ TEST_CHECK(! i.version_spec_ptr());
+ TEST_CHECK(! i.repository_ptr());
+ TEST_CHECK(! i.slot_ptr());
+ TEST_CHECK(i.use_requirements_ptr());
+ TEST_CHECK(i.use_requirements_ptr()->find(UseFlagName("one")) !=
+ i.use_requirements_ptr()->end());
+ TEST_CHECK(i.use_requirements_ptr()->find(UseFlagName("two")) !=
+ i.use_requirements_ptr()->end());
+ TEST_CHECK(i.use_requirements_ptr()->find(UseFlagName("three")) ==
+ i.use_requirements_ptr()->end());
+ TEST_CHECK(i.use_requirements_ptr()->state(UseFlagName("one")) == use_enabled);
+ TEST_CHECK(i.use_requirements_ptr()->state(UseFlagName("two")) == use_disabled);
+ TEST_CHECK(i.use_requirements_ptr()->state(UseFlagName("moo")) == use_unspecified);
+
+ PackageDepAtom j("=foo/bar-scm-r3");
+ TEST_CHECK_STRINGIFY_EQUAL(j.package(), "foo/bar");
+ TEST_CHECK(j.version_spec_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*j.version_spec_ptr(), "scm-r3");
+ TEST_CHECK_EQUAL(j.version_operator(), vo_equal);
+
+ PackageDepAtom k("=foo/bar-scm");
+ TEST_CHECK_STRINGIFY_EQUAL(k.package(), "foo/bar");
+ TEST_CHECK(k.version_spec_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(*k.version_spec_ptr(), "scm");
+ TEST_CHECK_EQUAL(k.version_operator(), vo_equal);
+ }
+ } test_package_dep_atom;
+}
+
diff --git a/0.8.0/paludis/dep_atom_flattener.cc b/0.8.0/paludis/dep_atom_flattener.cc
new file mode 100644
index 0000000..6b01eb7
--- /dev/null
+++ b/0.8.0/paludis/dep_atom_flattener.cc
@@ -0,0 +1,128 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_atom_flattener.hh>
+#include <list>
+
+/** \file
+ * Implementation of dep_atom_flattener.hh.
+ *
+ * \ingroup grpdepatomflattener
+ */
+
+using namespace paludis;
+
+namespace paludis
+{
+ /**
+ * Implementation data for DepAtomFlattener.
+ *
+ * \ingroup grpdepatomflattener
+ */
+ template<>
+ struct Implementation<DepAtomFlattener> :
+ InternalCounted<Implementation<DepAtomFlattener> >
+ {
+ const Environment * const env;
+
+ const PackageDatabaseEntry * const pkg;
+
+ DepAtom::ConstPointer a;
+
+ mutable std::list<const StringDepAtom *> atoms;
+
+ mutable bool done;
+
+ Implementation(const Environment * const e,
+ const PackageDatabaseEntry * const p,
+ DepAtom::ConstPointer aa) :
+ env(e),
+ pkg(p),
+ a(aa),
+ done(false)
+ {
+ }
+ };
+}
+
+DepAtomFlattener::DepAtomFlattener(
+ const Environment * const env,
+ const PackageDatabaseEntry * const pkg,
+ DepAtom::ConstPointer a) :
+ PrivateImplementationPattern<DepAtomFlattener>(new Implementation<DepAtomFlattener>(
+ env, pkg, a))
+{
+}
+
+DepAtomFlattener::~DepAtomFlattener()
+{
+}
+
+DepAtomFlattener::Iterator
+DepAtomFlattener::begin()
+{
+ if (! _imp->done)
+ {
+ _imp->a->accept(static_cast<DepAtomVisitorTypes::ConstVisitor *>(this));
+ _imp->done = true;
+ }
+
+ return Iterator(_imp->atoms.begin());
+}
+
+DepAtomFlattener::Iterator
+DepAtomFlattener::end() const
+{
+ return Iterator(_imp->atoms.end());
+}
+
+void DepAtomFlattener::visit(const AllDepAtom * a)
+{
+ std::for_each(a->begin(), a->end(), accept_visitor(
+ static_cast<DepAtomVisitorTypes::ConstVisitor *>(this)));
+}
+
+void DepAtomFlattener::visit(const AnyDepAtom *)
+{
+ throw InternalError(PALUDIS_HERE, "Found unexpected AnyDepAtom");
+}
+
+void DepAtomFlattener::visit(const UseDepAtom * u)
+{
+ if (_imp->env->query_use(u->flag(), _imp->pkg) ^ u->inverse())
+ std::for_each(u->begin(), u->end(), accept_visitor(
+ static_cast<DepAtomVisitorTypes::ConstVisitor *>(this)));
+}
+
+void DepAtomFlattener::visit(const PlainTextDepAtom * p)
+{
+ _imp->atoms.push_back(p);
+}
+
+void DepAtomFlattener::visit(const PackageDepAtom * p)
+{
+ _imp->atoms.push_back(p);
+}
+
+void DepAtomFlattener::visit(const BlockDepAtom * p)
+{
+ _imp->atoms.push_back(p);
+}
+
diff --git a/0.8.0/paludis/dep_atom_flattener.hh b/0.8.0/paludis/dep_atom_flattener.hh
new file mode 100644
index 0000000..be88584
--- /dev/null
+++ b/0.8.0/paludis/dep_atom_flattener.hh
@@ -0,0 +1,89 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_FLATTENER_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_ATOM_FLATTENER_HH 1
+
+#include <paludis/dep_atom.hh>
+#include <paludis/package_database.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/util/instantiation_policy.hh>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+/** \file
+ * Declarations for DepAtomFlattener.
+ *
+ * \ingroup grpdepatomflattener
+ */
+
+namespace paludis
+{
+ /**
+ * Extract the enabled components of a dep heirarchy for a particular
+ * package.
+ *
+ * This is useful for picking out SRC_URI, PROVIDE etc components. It is
+ * <b>not</b> suitable for heirarchies that can contain || ( ) blocks.
+ *
+ * \ingroup grpdepatomflattener
+ */
+ class DepAtomFlattener :
+ private InstantiationPolicy<DepAtomFlattener, instantiation_method::NonCopyableTag>,
+ protected DepAtomVisitorTypes::ConstVisitor,
+ private PrivateImplementationPattern<DepAtomFlattener>
+ {
+ protected:
+ ///\name Visit methods
+ ///{
+ void visit(const AllDepAtom *);
+ void visit(const AnyDepAtom *) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const UseDepAtom *);
+ void visit(const PlainTextDepAtom *);
+ void visit(const PackageDepAtom *);
+ void visit(const BlockDepAtom *);
+ ///}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ DepAtomFlattener(const Environment * const,
+ const PackageDatabaseEntry * const,
+ const DepAtom::ConstPointer);
+
+ ~DepAtomFlattener();
+
+ ///\}
+
+ ///\name Iterate over our dep atoms
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DepAtomFlattener, const StringDepAtom *> Iterator;
+
+ Iterator begin();
+
+ Iterator end() const;
+
+ ///\}
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/dep_atom_pretty_printer.cc b/0.8.0/paludis/dep_atom_pretty_printer.cc
new file mode 100644
index 0000000..8bc05f1
--- /dev/null
+++ b/0.8.0/paludis/dep_atom_pretty_printer.cc
@@ -0,0 +1,91 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <algorithm>
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_atom_pretty_printer.hh>
+#include <paludis/util/save.hh>
+
+/** \file
+ * Implementation of dep_atom_pretty_printer.hh.
+ *
+ * \ingroup grpdepatomprettyprinter
+ */
+
+using namespace paludis;
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const DepAtomPrettyPrinter & p)
+{
+ s << p._s.str();
+ return s;
+}
+
+void
+DepAtomPrettyPrinter::visit(const AllDepAtom * const a)
+{
+ _s << std::string(_indent, ' ') << "(" << std::endl;
+ {
+ Save<unsigned> old_indent(&_indent, _indent + 4);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ _s << std::string(_indent, ' ') << ")" << std::endl;
+}
+
+void
+DepAtomPrettyPrinter::visit(const AnyDepAtom * const a)
+{
+ _s << std::string(_indent, ' ') << "|| (" << std::endl;
+ {
+ Save<unsigned> old_indent(&_indent, _indent + 4);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ _s << std::string(_indent, ' ') << ")" << std::endl;
+}
+
+void
+DepAtomPrettyPrinter::visit(const UseDepAtom * const a)
+{
+ _s << std::string(_indent, ' ') << (a->inverse() ? "!" : "") <<
+ a->flag() << "? (" << std::endl;
+ {
+ Save<unsigned> old_indent(&_indent, _indent + 4);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ _s << std::string(_indent, ' ') << ")" << std::endl;
+}
+
+void
+DepAtomPrettyPrinter::visit(const PackageDepAtom * const p)
+{
+ _s << std::string(_indent, ' ') << *p << std::endl;
+}
+
+void
+DepAtomPrettyPrinter::visit(const PlainTextDepAtom * const p)
+{
+ _s << std::string(_indent, ' ') << p->text() << std::endl;
+}
+
+void
+DepAtomPrettyPrinter::visit(const BlockDepAtom * const b)
+{
+ _s << std::string(_indent, ' ') << "!" << *b->blocked_atom() << std::endl;
+}
+
diff --git a/0.8.0/paludis/dep_atom_pretty_printer.hh b/0.8.0/paludis/dep_atom_pretty_printer.hh
new file mode 100644
index 0000000..58af9f9
--- /dev/null
+++ b/0.8.0/paludis/dep_atom_pretty_printer.hh
@@ -0,0 +1,81 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_ATOM_PRETTY_PRINTER_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_ATOM_PRETTY_PRINTER_HH 1
+
+#include <iosfwd>
+#include <paludis/dep_atom.hh>
+
+/** \file
+ * Declarations for the DepAtomPrettyPrinter class.
+ *
+ * \ingroup grpdepatomprettyprinter
+ */
+
+namespace paludis
+{
+ /**
+ * Pretty print dependency atoms.
+ *
+ * \ingroup grpdepatomprettyprinter
+ */
+ class DepAtomPrettyPrinter :
+ public DepAtomVisitorTypes::ConstVisitor
+ {
+ friend std::ostream & operator<< (std::ostream &, const DepAtomPrettyPrinter &);
+
+ private:
+ std::stringstream _s;
+ unsigned _indent;
+
+ public:
+ /**
+ * Constructor.
+ */
+ DepAtomPrettyPrinter(unsigned initial_indent) :
+ _indent(initial_indent)
+ {
+ }
+
+ /// \name Visit functions
+ ///{
+ void visit(const AllDepAtom * const);
+
+ void visit(const AnyDepAtom * const);
+
+ void visit(const UseDepAtom * const);
+
+ void visit(const PackageDepAtom * const);
+
+ void visit(const PlainTextDepAtom * const);
+
+ void visit(const BlockDepAtom * const);
+ ///}
+ };
+
+ /**
+ * Output a DepAtomPrettyPrinter to an ostream.
+ *
+ * \ingroup grpdepatomprettyprinter
+ */
+ std::ostream & operator<< (std::ostream & s, const DepAtomPrettyPrinter & p);
+}
+
+#endif
diff --git a/0.8.0/paludis/dep_list.cc b/0.8.0/paludis/dep_list.cc
new file mode 100644
index 0000000..37a32f7
--- /dev/null
+++ b/0.8.0/paludis/dep_list.cc
@@ -0,0 +1,837 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_atom_flattener.hh>
+#include <paludis/dep_list.hh>
+#include <paludis/match_package.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/iterator.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/save.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <set>
+
+using namespace paludis;
+
+#include <paludis/dep_list-sr.cc>
+
+DepListError::DepListError(const std::string & m) throw () :
+ Exception(m)
+{
+}
+
+AllMaskedError::AllMaskedError(const std::string & q) throw () :
+ DepListError("Error searching for '" + q + "': no available versions"),
+ _query(q)
+{
+}
+
+UseRequirementsNotMetError::UseRequirementsNotMetError(const std::string & q) throw () :
+ DepListError("Error searching for '" + q + "': use requirements are not met"),
+ _query(q)
+{
+}
+
+BlockError::BlockError(const std::string & msg) throw () :
+ DepListError("Block: " + msg)
+{
+}
+
+CircularDependencyError::CircularDependencyError(const std::string & msg) throw () :
+ DepListError("Circular dependency: " + msg)
+{
+}
+
+DepListOptions::DepListOptions() :
+ reinstall(dl_reinstall_never),
+ target_type(dl_target_package),
+ upgrade(dl_upgrade_always),
+ installed_deps_pre(dl_deps_discard),
+ installed_deps_runtime(dl_deps_try_post),
+ installed_deps_post(dl_deps_try_post),
+ uninstalled_deps_pre(dl_deps_pre),
+ uninstalled_deps_runtime(dl_deps_pre_or_post),
+ uninstalled_deps_post(dl_deps_post),
+ circular(dl_circular_error),
+ dependency_tags(false)
+{
+ /* when changing the above, also see src/paludis/command_line.cc. */
+}
+
+namespace paludis
+{
+ typedef std::list<DepListEntry> MergeList;
+
+ template<>
+ struct Implementation<DepList> :
+ InternalCounted<Implementation<DepList> >
+ {
+ const Environment * const env;
+ DepListOptions opts;
+
+ MergeList merge_list;
+ MergeList::const_iterator current_merge_list_entry;
+ MergeList::iterator merge_list_insert_position;
+ long merge_list_generation;
+
+ const PackageDatabaseEntry * current_pde() const
+ {
+ if (current_merge_list_entry != merge_list.end())
+ return &current_merge_list_entry->package;
+ return 0;
+ }
+
+ Implementation(const Environment * const e, const DepListOptions & o) :
+ env(e),
+ opts(o),
+ current_merge_list_entry(merge_list.end()),
+ merge_list_insert_position(merge_list.end()),
+ merge_list_generation(0)
+ {
+ }
+ };
+}
+
+namespace
+{
+ struct GenerationGreaterThan
+ {
+ long g;
+
+ GenerationGreaterThan(long gg) :
+ g(gg)
+ {
+ }
+
+ template <typename T_>
+ bool operator() (const T_ & e) const
+ {
+ return e.generation > g;
+ }
+ };
+
+ struct RemoveTagsWithGenerationGreaterThan
+ {
+ long g;
+
+ RemoveTagsWithGenerationGreaterThan(long gg) :
+ g(gg)
+ {
+ }
+
+ void operator() (DepListEntry & e) const
+ {
+ /* see EffSTL 9 for why this is so painful */
+ if (e.tags->empty())
+ return;
+ DepListEntryTags::Pointer t(new DepListEntryTags::Concrete);
+ GenerationGreaterThan pred(g);
+ for (DepListEntryTags::Iterator i(e.tags->begin()), i_end(e.tags->end()) ;
+ i != i_end ; ++i)
+ if (! pred(*i))
+ t->insert(*i);
+ std::swap(e.tags, t);
+ }
+ };
+
+ class DepListTransaction
+ {
+ protected:
+ MergeList & _list;
+ long & _generation;
+ int _initial_generation;
+ bool _committed;
+
+ public:
+ DepListTransaction(MergeList & l, long & g) :
+ _list(l),
+ _generation(g),
+ _initial_generation(g),
+ _committed(false)
+ {
+ ++_generation;
+ }
+
+ void commit()
+ {
+ _committed = true;
+ }
+
+ ~DepListTransaction()
+ {
+ if (! _committed)
+ {
+ _list.remove_if(GenerationGreaterThan(_initial_generation));
+ std::for_each(_list.begin(), _list.end(), RemoveTagsWithGenerationGreaterThan(_initial_generation));
+ }
+ }
+ };
+
+ struct MatchDepListEntryAgainstPackageDepAtom
+ {
+ const Environment * const env;
+ const PackageDepAtom * const a;
+
+ MatchDepListEntryAgainstPackageDepAtom(const Environment * const ee,
+ const PackageDepAtom * const aa) :
+ env(ee),
+ a(aa)
+ {
+ }
+
+ bool operator() (const DepListEntry & e)
+ {
+ return match_package(env, a, e);
+ }
+ };
+
+ struct IsViableAnyDepAtomChild
+ {
+ const Environment * const env;
+ const PackageDatabaseEntry * const pde;
+
+ IsViableAnyDepAtomChild(const Environment * const e, const PackageDatabaseEntry * const p) :
+ env(e),
+ pde(p)
+ {
+ }
+
+ bool operator() (PackageDepAtom::ConstPointer atom)
+ {
+ const UseDepAtom * const u(atom->as_use_dep_atom());
+ if (0 != u)
+ return env->query_use(u->flag(), pde) ^ u->inverse();
+ else
+ return true;
+ }
+ };
+}
+
+struct DepList::QueryVisitor :
+ DepAtomVisitorTypes::ConstVisitor
+{
+ bool result;
+ const DepList * const d;
+
+ QueryVisitor(const DepList * const dd) :
+ result(true),
+ d(dd)
+ {
+ }
+
+ void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const PackageDepAtom * const);
+ void visit(const UseDepAtom * const);
+ void visit(const AnyDepAtom * const);
+ void visit(const BlockDepAtom * const);
+ void visit(const AllDepAtom * const);
+};
+
+void
+DepList::QueryVisitor::visit(const PlainTextDepAtom * const)
+{
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
+}
+
+void
+DepList::QueryVisitor::visit(const PackageDepAtom * const a)
+{
+ /* a pda matches either if we're already installed, or if we will be installed
+ * by the time the current point in the dep list is reached. */
+
+ if (! d->_imp->env->package_database()->query(*a, is_installed_only)->empty())
+ result = true;
+ else if (d->_imp->merge_list.end() != std::find_if(
+ d->_imp->merge_list.begin(),
+ d->_imp->merge_list.end(),
+ MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, a)))
+ result = true;
+ else
+ result = false;
+}
+
+void
+DepList::QueryVisitor::visit(const UseDepAtom * const a)
+{
+ /* for use? ( ) dep atoms, return true if we're not enabled, so that
+ * weird || ( ) cases work. */
+ if (d->_imp->env->query_use(a->flag(), d->_imp->current_pde()) ^ a->inverse())
+ {
+ result = true;
+ for (CompositeDepAtom::Iterator c(a->begin()), c_end(a->end()) ; c != c_end ; ++c)
+ {
+ (*c)->accept(this);
+ if (! result)
+ return;
+ }
+ }
+ else
+ result = true;
+}
+
+void
+DepList::QueryVisitor::visit(const AnyDepAtom * const a)
+{
+ /* empty || ( ) must resolve to true */
+ std::list<DepAtom::ConstPointer> viable_children;
+ std::copy(a->begin(), a->end(), filter_inserter(std::back_inserter(viable_children),
+ IsViableAnyDepAtomChild(d->_imp->env, d->_imp->current_pde())));
+
+ result = true;
+ for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
+ {
+ (*c)->accept(this);
+ if (result)
+ return;
+ }
+}
+
+void
+DepList::QueryVisitor::visit(const BlockDepAtom * const a)
+{
+ a->blocked_atom()->accept(this);
+ result = !result;
+}
+
+void
+DepList::QueryVisitor::visit(const AllDepAtom * const a)
+{
+ for (CompositeDepAtom::Iterator c(a->begin()), c_end(a->end()) ; c != c_end ; ++c)
+ {
+ (*c)->accept(this);
+ if (! result)
+ return;
+ }
+}
+
+struct DepList::AddVisitor :
+ DepAtomVisitorTypes::ConstVisitor
+{
+ DepList * const d;
+
+ AddVisitor(DepList * const dd) :
+ d(dd)
+ {
+ }
+
+ void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const PackageDepAtom * const);
+ void visit(const UseDepAtom * const);
+ void visit(const AnyDepAtom * const);
+ void visit(const BlockDepAtom * const);
+ void visit(const AllDepAtom * const);
+};
+
+void
+DepList::AddVisitor::visit(const PlainTextDepAtom * const)
+{
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
+}
+
+void
+DepList::AddVisitor::visit(const PackageDepAtom * const a)
+{
+ Context context("When adding PackageDepAtom '" + stringify(*a) + "':");
+
+ /* find already installed things */
+ PackageDatabaseEntryCollection::ConstPointer already_installed(d->_imp->env->package_database()->query(
+ *a, is_installed_only));
+
+ /* are we already on the merge list? */
+ MergeList::iterator existing_merge_list_entry(std::find_if(d->_imp->merge_list.begin(),
+ d->_imp->merge_list.end(), MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, a)));
+ if (existing_merge_list_entry != d->_imp->merge_list.end())
+ {
+ /* tag it */
+ if (a->tag())
+ existing_merge_list_entry->tags->insert(DepTagEntry::create()
+ .tag(a->tag())
+ .generation(d->_imp->merge_list_generation));
+
+ if (d->_imp->opts.dependency_tags && d->_imp->current_pde())
+ existing_merge_list_entry->tags->insert(DepTagEntry::create()
+ .tag(DepTag::Pointer(new DependencyDepTag(*d->_imp->current_pde())))
+ .generation(d->_imp->merge_list_generation));
+
+ /* have our deps been merged already, or is this a circular dep? */
+ if (dle_no_deps == existing_merge_list_entry->state)
+ {
+ /* is a sufficiently good version installed? */
+ if (! already_installed->empty())
+ return;
+
+ if (d->_imp->opts.circular == dl_circular_discard)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Dropping circular dependency on '"
+ + stringify(existing_merge_list_entry->package) + "'");
+ return;
+ }
+ throw CircularDependencyError("Atom '" + stringify(*a) + "' matched by merge list entry '" +
+ stringify(existing_merge_list_entry->package) + "', which does not yet have its "
+ "dependencies installed");
+ }
+ else
+ return;
+ }
+
+ /* find installable candidates, and find the best visible candidate */
+ const PackageDatabaseEntry * best_visible_candidate(0);
+ PackageDatabaseEntryCollection::ConstPointer installable_candidates(
+ d->_imp->env->package_database()->query(*a, is_uninstalled_only));
+
+ for (PackageDatabaseEntryCollection::ReverseIterator p(installable_candidates->rbegin()),
+ p_end(installable_candidates->rend()) ; p != p_end ; ++p)
+ if (! d->_imp->env->mask_reasons(*p).any())
+ {
+ best_visible_candidate = &*p;
+ break;
+ }
+
+ /* no installable candidates. if we're already installed, that's ok (except for top level
+ * package targets), otherwise error. */
+ if (! best_visible_candidate)
+ {
+ if (already_installed->empty())
+ {
+ if (a->use_requirements_ptr() && d->_imp->env->package_database()->query(
+ a->without_use_requirements(), is_either))
+ throw UseRequirementsNotMetError(stringify(*a));
+ else
+ throw AllMaskedError(stringify(*a));
+ }
+ else
+ {
+ // todo: top level
+ Log::get_instance()->message(ll_warning, lc_context, "No visible packages matching '"
+ + stringify(*a) + "', falling back to installed package '"
+ + stringify(*already_installed->last()) + "'");
+ d->add_already_installed_package(*already_installed->last(), a->tag());
+ return;
+ }
+ }
+
+ SlotName slot(d->_imp->env->package_database()->fetch_repository(best_visible_candidate->repository)->
+ version_metadata(best_visible_candidate->name, best_visible_candidate->version)->slot);
+ PackageDatabaseEntryCollection::Pointer already_installed_in_same_slot(
+ new PackageDatabaseEntryCollection::Concrete);
+ for (PackageDatabaseEntryCollection::Iterator aa(already_installed->begin()),
+ aa_end(already_installed->end()) ; aa != aa_end ; ++aa)
+ if (d->_imp->env->package_database()->fetch_repository(aa->repository)->
+ version_metadata(aa->name, aa->version)->slot == slot)
+ already_installed_in_same_slot->insert(*aa);
+
+ /* we have an already installed version. do we want to use it? */
+ if (! already_installed_in_same_slot->empty())
+ {
+ if (d->prefer_installed_over_uninstalled(*already_installed_in_same_slot->last(), *best_visible_candidate))
+ {
+ Log::get_instance()->message(ll_debug, lc_context, "Taking installed package '"
+ + stringify(*already_installed_in_same_slot->last()) + "' over '" + stringify(*best_visible_candidate) + "'");
+ d->add_already_installed_package(*already_installed_in_same_slot->last(), a->tag());
+ return;
+ }
+ else
+ Log::get_instance()->message(ll_debug, lc_context, "Not taking installed package '"
+ + stringify(*already_installed_in_same_slot->last()) + "' over '" + stringify(*best_visible_candidate) + "'");
+ }
+ else
+ Log::get_instance()->message(ll_debug, lc_context, "No installed packages in SLOT '"
+ + stringify(slot) + "', taking uninstalled package '" + stringify(*best_visible_candidate) + "'");
+
+ d->add_package(*best_visible_candidate, a->tag());
+}
+
+void
+DepList::AddVisitor::visit(const UseDepAtom * const a)
+{
+ if (d->_imp->env->query_use(a->flag(), d->_imp->current_pde()) ^ a->inverse())
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+}
+
+void
+DepList::AddVisitor::visit(const AnyDepAtom * const a)
+{
+ /* annoying requirement: || ( foo? ( ... ) ) resolves to empty if !foo. */
+ std::list<DepAtom::ConstPointer> viable_children;
+ std::copy(a->begin(), a->end(), filter_inserter(std::back_inserter(viable_children),
+ IsViableAnyDepAtomChild(d->_imp->env, d->_imp->current_pde())));
+
+ if (viable_children.empty())
+ return;
+
+ /* see if any of our children is already installed. if any is, add it so that
+ * any upgrades kick in */
+ for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
+ {
+ if (d->already_installed(*c))
+ {
+ d->add(*c);
+ return;
+ }
+ }
+
+ /* install first available viable option */
+ for (std::list<DepAtom::ConstPointer>::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
+ {
+ try
+ {
+ d->add(*c);
+ return;
+ }
+ catch (const DepListError & e)
+ {
+ }
+ }
+
+ Log::get_instance()->message(ll_warning, lc_context, "No resolvable item in || ( ) block. Using "
+ "first item for error message");
+ d->add(*viable_children.begin());
+}
+
+void
+DepList::AddVisitor::visit(const BlockDepAtom * const a)
+{
+ if (! d->already_installed(a->blocked_atom()))
+ return;
+
+ Context context("When checking BlockDepAtom '!" + stringify(*a->blocked_atom()) + "':");
+
+ /* special case: the provider of virtual/blah can DEPEND upon !virtual/blah. */
+ /* special case: foo/bar can DEPEND upon !foo/bar. */
+
+ if (d->_imp->current_pde())
+ {
+ if (d->_imp->current_pde()->name == a->blocked_atom()->package())
+ {
+ Log::get_instance()->message(ll_debug, lc_context, "Ignoring self block '"
+ + stringify(*a->blocked_atom()) + "' for package '"
+ + stringify(*d->_imp->current_pde()) + "'");
+ return;
+ }
+
+ VersionMetadata::ConstPointer metadata(d->_imp->env->package_database()->fetch_repository(
+ d->_imp->current_pde()->repository)->version_metadata(d->_imp->current_pde()->name,
+ d->_imp->current_pde()->version));
+ if (metadata->get_ebuild_interface())
+ {
+ bool skip(false);
+ DepAtomFlattener f(d->_imp->env, d->_imp->current_pde(), metadata->get_ebuild_interface()->provide());
+ for (DepAtomFlattener::Iterator i(f.begin()), i_end(f.end()) ; i != i_end && ! skip ; ++i)
+ if ((*i)->text() == stringify(a->blocked_atom()->package()))
+ skip = true;
+
+ if (skip)
+ {
+ Log::get_instance()->message(ll_debug, lc_context,
+ "Ignoring self block (via PROVIDE) '" + stringify(*a->blocked_atom())
+ + "' for package '" + stringify(*d->_imp->current_pde()) + "'");
+ return;
+ }
+ }
+ }
+
+ throw BlockError(stringify(*a->blocked_atom()));
+}
+
+void
+DepList::AddVisitor::visit(const AllDepAtom * const a)
+{
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+}
+
+DepList::DepList(const Environment * const e, const DepListOptions & o) :
+ PrivateImplementationPattern<DepList>(new Implementation<DepList>(e, o)),
+ options(_imp->opts)
+{
+}
+
+DepList::~DepList()
+{
+}
+
+void
+DepList::add_in_role(DepAtom::ConstPointer atom, const std::string & role)
+{
+ Context context("When adding " + role + ":");
+ add(atom);
+}
+
+void
+DepList::add(DepAtom::ConstPointer atom)
+{
+ DepListTransaction transaction(_imp->merge_list, _imp->merge_list_generation);
+ AddVisitor visitor(this);
+ atom->accept(&visitor);
+ transaction.commit();
+}
+
+void
+DepList::add_package(const PackageDatabaseEntry & p, DepTag::ConstPointer tag)
+{
+ Context context("When adding package '" + stringify(p) + "':");
+
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position);
+
+ VersionMetadata::ConstPointer metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version));
+
+ /* create our merge list entry. insert pre deps before ourself in the list. insert
+ * post deps after ourself, and after any provides. */
+ MergeList::iterator our_merge_entry_position(
+ _imp->merge_list.insert(_imp->merge_list_insert_position,
+ DepListEntry::create()
+ .package(p)
+ .metadata(metadata)
+ .generation(_imp->merge_list_generation)
+ .state(dle_no_deps)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .already_installed(false))),
+ our_merge_entry_post_position(our_merge_entry_position);
+
+ if (tag)
+ our_merge_entry_position->tags->insert(DepTagEntry::create()
+ .generation(_imp->merge_list_generation)
+ .tag(tag));
+
+ if (_imp->opts.dependency_tags && _imp->current_pde())
+ our_merge_entry_position->tags->insert(DepTagEntry::create()
+ .tag(DepTag::Pointer(new DependencyDepTag(*_imp->current_pde())))
+ .generation(_imp->merge_list_generation));
+
+ Save<MergeList::const_iterator> save_current_merge_list_entry(&_imp->current_merge_list_entry,
+ our_merge_entry_position);
+
+ _imp->merge_list_insert_position = our_merge_entry_position;
+
+ /* add provides */
+ if (metadata->get_ebuild_interface())
+ {
+ DepAtomFlattener f(_imp->env, _imp->current_pde(), metadata->get_ebuild_interface()->provide());
+ for (DepAtomFlattener::Iterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
+ {
+ PackageDepAtom::Pointer pp(new PackageDepAtom("=" + (*i)->text() + "-" + stringify(p.version)));
+ if (_imp->merge_list.end() != std::find_if(_imp->merge_list.begin(),
+ _imp->merge_list.end(), MatchDepListEntryAgainstPackageDepAtom(_imp->env,
+ pp.raw_pointer())))
+ continue;
+
+ VersionMetadata::ConstPointer m(0);
+
+ if (_imp->env->package_database()->fetch_repository(RepositoryName("virtuals"))->has_version(
+ QualifiedPackageName((*i)->text()), p.version))
+ m = _imp->env->package_database()->fetch_repository(RepositoryName("virtuals"))->version_metadata(
+ QualifiedPackageName((*i)->text()), p.version);
+ else
+ {
+ VersionMetadata::Pointer mm(0);
+ mm.assign(new VersionMetadata::Virtual(metadata->deps.parser,
+ PackageDatabaseEntry(p.name, p.version, RepositoryName("virtuals"))));
+ mm->slot = metadata->slot;
+ m = mm;
+ }
+
+ our_merge_entry_post_position = _imp->merge_list.insert(next(our_merge_entry_post_position),
+ DepListEntry(DepListEntry::create()
+ .package(PackageDatabaseEntry((*i)->text(), p.version, RepositoryName("virtuals")))
+ .metadata(m)
+ .generation(_imp->merge_list_generation)
+ .state(dle_has_all_deps)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .already_installed(false)));
+ }
+ }
+
+ /* add pre dependencies */
+ add_predeps(metadata->deps.build_depend(), _imp->opts.uninstalled_deps_pre, "build");
+ add_predeps(metadata->deps.run_depend(), _imp->opts.uninstalled_deps_runtime, "run");
+ add_predeps(metadata->deps.post_depend(), _imp->opts.uninstalled_deps_post, "post");
+
+ our_merge_entry_position->state = dle_has_pre_deps;
+ _imp->merge_list_insert_position = next(our_merge_entry_post_position);
+
+ add_postdeps(metadata->deps.build_depend(), _imp->opts.uninstalled_deps_pre, "build");
+ add_postdeps(metadata->deps.run_depend(), _imp->opts.uninstalled_deps_runtime, "run");
+ add_postdeps(metadata->deps.post_depend(), _imp->opts.uninstalled_deps_post, "post");
+
+ our_merge_entry_position->state = dle_has_all_deps;
+}
+
+void
+DepList::add_predeps(DepAtom::ConstPointer d, const DepListDepsOption opt, const std::string & s)
+{
+ if (dl_deps_pre == opt || dl_deps_pre_or_post == opt)
+ {
+ try
+ {
+ add_in_role(d, s + " dependencies as pre dependencies");
+ }
+ catch (const DepListError & e)
+ {
+ if (dl_deps_pre == opt)
+ throw;
+ else
+ Log::get_instance()->message(ll_warning, lc_context, "Dropping " + s + " dependencies to "
+ "post dependencies because of exception '" + e.message() + "' (" + e.what() + ")");
+ }
+ }
+}
+
+void
+DepList::add_postdeps(DepAtom::ConstPointer d, const DepListDepsOption opt, const std::string & s)
+{
+ if (dl_deps_pre_or_post == opt || dl_deps_post == opt || dl_deps_try_post == opt)
+ {
+ try
+ {
+ add_in_role(d, s + " dependencies as post dependencies");
+ }
+ catch (const DepListError & e)
+ {
+ if (dl_deps_try_post != opt)
+ throw;
+ else
+ Log::get_instance()->message(ll_warning, lc_context, "Ignoring " + s +
+ " dependencies due to exception '" + e.message() + "' (" + e.what() + ")");
+ }
+ }
+}
+
+void
+DepList::add_already_installed_package(const PackageDatabaseEntry & p, DepTag::ConstPointer tag)
+{
+ Context context("When adding installed package '" + stringify(p) + "':");
+
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position);
+ VersionMetadata::ConstPointer metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version));
+
+ MergeList::iterator our_merge_entry(_imp->merge_list.insert(_imp->merge_list_insert_position,
+ DepListEntry::create()
+ .package(p)
+ .metadata(metadata)
+ .generation(_imp->merge_list_generation)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .state(dle_has_pre_deps)
+ .already_installed(true)));
+
+ if (tag)
+ our_merge_entry->tags->insert(DepTagEntry::create()
+ .generation(_imp->merge_list_generation)
+ .tag(tag));
+
+ if (_imp->opts.dependency_tags && _imp->current_pde())
+ our_merge_entry->tags->insert(DepTagEntry::create()
+ .tag(DepTag::Pointer(new DependencyDepTag(*_imp->current_pde())))
+ .generation(_imp->merge_list_generation));
+
+ Save<MergeList::const_iterator> save_current_merge_list_entry(&_imp->current_merge_list_entry,
+ our_merge_entry);
+
+ add_predeps(metadata->deps.build_depend(), _imp->opts.installed_deps_pre, "build");
+ add_predeps(metadata->deps.run_depend(), _imp->opts.installed_deps_runtime, "run");
+ add_predeps(metadata->deps.post_depend(), _imp->opts.installed_deps_post, "post");
+
+ our_merge_entry->state = dle_has_pre_deps;
+ _imp->merge_list_insert_position = next(our_merge_entry);
+
+ add_postdeps(metadata->deps.build_depend(), _imp->opts.installed_deps_pre, "build");
+ add_postdeps(metadata->deps.run_depend(), _imp->opts.installed_deps_runtime, "run");
+ add_postdeps(metadata->deps.post_depend(), _imp->opts.installed_deps_post, "post");
+}
+
+bool
+DepList::prefer_installed_over_uninstalled(const PackageDatabaseEntry & installed,
+ const PackageDatabaseEntry & uninstalled)
+{
+ if (dl_target_package == _imp->opts.target_type)
+ if (! _imp->current_pde())
+ return false;
+
+ if (dl_reinstall_always == _imp->opts.reinstall)
+ return false;
+
+ if (dl_upgrade_as_needed == _imp->opts.upgrade)
+ return true;
+
+ /* use != rather than > to correctly force a downgrade when packages are
+ * removed. */
+ if (uninstalled.version != installed.version)
+ return false;
+
+ if (dl_reinstall_if_use_changed == _imp->opts.reinstall)
+ {
+ const EbuildVersionMetadata * const evm_i(_imp->env->package_database()->fetch_repository(
+ installed.repository)->version_metadata(installed.name, installed.version)->get_ebuild_interface());
+ const EbuildVersionMetadata * const evm_u(_imp->env->package_database()->fetch_repository(
+ uninstalled.repository)->version_metadata(uninstalled.name, uninstalled.version)->get_ebuild_interface());
+
+ std::set<std::string> use_i, use_u, use_common;
+ if (evm_i)
+ WhitespaceTokeniser::get_instance()->tokenise(evm_i->iuse, std::inserter(use_i, use_i.end()));
+ if (evm_u)
+ WhitespaceTokeniser::get_instance()->tokenise(evm_u->iuse, std::inserter(use_u, use_u.end()));
+
+ std::set_intersection(use_i.begin(), use_i.end(), use_u.begin(), use_u.end(),
+ std::inserter(use_common, use_common.end()));
+
+ for (std::set<std::string>::const_iterator f(use_common.begin()), f_end(use_common.end()) ;
+ f != f_end ; ++f)
+ if (_imp->env->query_use(UseFlagName(*f), &installed) != _imp->env->query_use(UseFlagName(*f), &uninstalled))
+ return false;
+ }
+
+ return true;
+}
+
+bool
+DepList::already_installed(DepAtom::ConstPointer atom) const
+{
+ return already_installed(atom.raw_pointer());
+}
+
+bool
+DepList::already_installed(const DepAtom * const atom) const
+{
+ QueryVisitor visitor(this);
+ atom->accept(&visitor);
+ return visitor.result;
+}
+
+DepList::Iterator
+DepList::begin() const
+{
+ return Iterator(_imp->merge_list.begin());
+}
+
+DepList::Iterator
+DepList::end() const
+{
+ return Iterator(_imp->merge_list.end());
+}
+
diff --git a/0.8.0/paludis/dep_list.hh b/0.8.0/paludis/dep_list.hh
new file mode 100644
index 0000000..f87b833
--- /dev/null
+++ b/0.8.0/paludis/dep_list.hh
@@ -0,0 +1,265 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_LIST_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_HH 1
+
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_tag.hh>
+#include <paludis/name.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/version_spec.hh>
+
+#include <iosfwd>
+#include <bitset>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+namespace paludis
+{
+ enum DepListTargetType
+ {
+ dl_target_package,
+ dl_target_set
+ };
+
+ enum DepListReinstallOption
+ {
+ dl_reinstall_never,
+ dl_reinstall_always,
+ dl_reinstall_if_use_changed
+ };
+
+ enum DepListUpgradeOption
+ {
+ dl_upgrade_always,
+ dl_upgrade_as_needed
+ };
+
+ enum DepListDepsOption
+ {
+ dl_deps_discard,
+ dl_deps_pre,
+ dl_deps_pre_or_post,
+ dl_deps_post,
+ dl_deps_try_post
+ };
+
+ enum DepListCircularOption
+ {
+ dl_circular_error,
+ dl_circular_discard
+ };
+
+ enum DepListEntryState
+ {
+ dle_no_deps,
+ dle_has_pre_deps,
+ dle_has_all_deps
+ };
+
+#include <paludis/dep_list-sr.hh>
+
+ /**
+ * Thrown if an error occurs whilst building a DepList.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ */
+ class DepListError : public Exception
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ DepListError(const std::string &) throw ();
+
+ ///\}
+ };
+
+ /**
+ * Thrown if all versions of a particular atom are masked.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ */
+ class AllMaskedError : public DepListError
+ {
+ private:
+ std::string _query;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ AllMaskedError(const std::string & query) throw ();
+
+ virtual ~AllMaskedError() throw ()
+ {
+ }
+
+ ///\}
+
+ /**
+ * Our query.
+ */
+ const std::string & query() const
+ {
+ return _query;
+ }
+ };
+
+ /**
+ * Thrown if all versions of a particular atom are masked,
+ * but would not be if use requirements were not in effect.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ */
+ class UseRequirementsNotMetError : public DepListError
+ {
+ private:
+ std::string _query;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ UseRequirementsNotMetError(const std::string & query) throw ();
+
+ virtual ~UseRequirementsNotMetError() throw ()
+ {
+ }
+
+ ///\}
+
+ /**
+ * Our query.
+ */
+ const std::string & query() const
+ {
+ return _query;
+ }
+ };
+
+ /**
+ * Thrown if a block is encountered.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ */
+ class BlockError : public DepListError
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ BlockError(const std::string & msg) throw ();
+
+ ///\}
+ };
+
+ /**
+ * Thrown if a circular dependency is encountered.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ */
+ class CircularDependencyError : public DepListError
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ CircularDependencyError(const std::string & msg) throw ();
+
+ ///\}
+ };
+
+ /**
+ * Holds a list of dependencies in merge order.
+ *
+ * \ingroup grpdepresolver
+ */
+ class DepList :
+ private InstantiationPolicy<DepList, instantiation_method::NonCopyableTag>,
+ private PrivateImplementationPattern<DepList>
+ {
+ protected:
+ class AddVisitor;
+ class QueryVisitor;
+
+ friend class AddVisitor;
+ friend class QueryVisitor;
+
+ void add_in_role(DepAtom::ConstPointer, const std::string & role);
+ bool prefer_installed_over_uninstalled(const PackageDatabaseEntry &,
+ const PackageDatabaseEntry &);
+ void add_package(const PackageDatabaseEntry &, DepTag::ConstPointer);
+ void add_already_installed_package(const PackageDatabaseEntry &, DepTag::ConstPointer);
+ void add_predeps(DepAtom::ConstPointer, const DepListDepsOption, const std::string &);
+ void add_postdeps(DepAtom::ConstPointer, const DepListDepsOption, const std::string &);
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ DepList(const Environment * const, const DepListOptions &);
+
+ virtual ~DepList();
+
+ ///\}
+
+ /**
+ * Our options.
+ */
+ DepListOptions & options;
+
+ /**
+ * Add the packages required to resolve an additional dependency
+ * atom.
+ */
+ void add(DepAtom::ConstPointer);
+
+ /**
+ * Is an atom structure already installed?
+ */
+ bool already_installed(DepAtom::ConstPointer) const;
+
+ /**
+ * Is an atom structure already installed (overloaded for raw pointer)?
+ */
+ bool already_installed(const DepAtom * const) const;
+
+ ///\name Iterate over our dependency list entries.
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<DepList, const DepListEntry> Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\}
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/dep_list.sr b/0.8.0/paludis/dep_list.sr
new file mode 100644
index 0000000..abc6c94
--- /dev/null
+++ b/0.8.0/paludis/dep_list.sr
@@ -0,0 +1,41 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_DepListOptions()
+{
+ key reinstall DepListReinstallOption
+ key target_type DepListTargetType
+ key upgrade DepListUpgradeOption
+
+ key installed_deps_pre DepListDepsOption
+ key installed_deps_runtime DepListDepsOption
+ key installed_deps_post DepListDepsOption
+
+ key uninstalled_deps_pre DepListDepsOption
+ key uninstalled_deps_runtime DepListDepsOption
+ key uninstalled_deps_post DepListDepsOption
+
+ key circular DepListCircularOption
+
+ key dependency_tags bool
+
+ extra_constructors <<END
+ DepListOptions();
+END
+
+ allow_named_args
+}
+
+make_class_DepListEntry()
+{
+ key package PackageDatabaseEntry
+ key metadata VersionMetadata::ConstPointer
+ key tags DepListEntryTags::Pointer
+
+ key generation long
+ key state DepListEntryState
+ key already_installed bool
+
+ allow_named_args
+}
+
diff --git a/0.8.0/paludis/dep_list_TEST.cc b/0.8.0/paludis/dep_list_TEST.cc
new file mode 100644
index 0000000..c24a4f6
--- /dev/null
+++ b/0.8.0/paludis/dep_list_TEST.cc
@@ -0,0 +1,1552 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/paludis.hh>
+#include <paludis/repositories/fake/fake_repository.hh>
+#include <paludis/repositories/fake/fake_installed_repository.hh>
+#include <paludis/repositories/virtuals/virtuals_repository.hh>
+#include <paludis/environment/test/test_environment.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+#include <string>
+#include <list>
+#include <ostream>
+
+using namespace paludis;
+using namespace test;
+
+namespace paludis
+{
+ std::ostream &
+ operator<< (std::ostream & s, const DepListEntry & e)
+ {
+ s << e.package.name << "-" << e.package.version << ":" <<
+ e.metadata->slot << "::" << e.package.repository;
+ return s;
+ }
+}
+
+namespace test_cases
+{
+ /**
+ * Convenience base class used by many of the DepList tests.
+ *
+ * \ingroup Test
+ */
+ class DepListTestCaseBase :
+ public TestCase
+ {
+ protected:
+ TestEnvironment env;
+ FakeRepository::Pointer repo;
+ VirtualsRepository::Pointer virtuals_repo;
+ std::list<std::string> expected;
+ std::string merge_target;
+ bool done_populate;
+
+ /**
+ * Constructor.
+ */
+ DepListTestCaseBase(const int i) :
+ TestCase("dep list " + stringify(i)),
+ env(),
+ repo(new FakeRepository(RepositoryName("repo"))),
+ virtuals_repo(new VirtualsRepository(&env)),
+ done_populate(false)
+ {
+ env.package_database()->add_repository(repo);
+ env.package_database()->add_repository(virtuals_repo);
+ }
+
+ /**
+ * Populate our repo member.
+ */
+ virtual void populate_repo() = 0;
+
+ /**
+ * Populate our expected member.
+ */
+ virtual void populate_expected() = 0;
+
+ /**
+ * Check expected is what we got.
+ */
+ virtual void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.add(PortageDepParser::parse(merge_target));
+ TEST_CHECK(true);
+
+ unsigned n(0);
+ std::list<std::string>::const_iterator exp(expected.begin());
+ DepList::Iterator got(d.begin());
+ while (true)
+ {
+ TestMessageSuffix s(stringify(n++), true);
+
+ TEST_CHECK((exp == expected.end()) == (got == d.end()));
+ if (got == d.end())
+ break;
+ TEST_CHECK_STRINGIFY_EQUAL(*got, *exp);
+ ++exp;
+ ++got;
+ }
+ }
+
+ public:
+ void run()
+ {
+ if (! done_populate)
+ {
+ populate_repo();
+ populate_expected();
+ done_populate = true;
+ }
+ check_lists();
+ }
+ };
+
+ /**
+ * Convenience sub base class used by the numbered DepList tests.
+ *
+ * \ingroup Test
+ */
+ template <int i_>
+ struct DepListTestCase : DepListTestCaseBase
+ {
+ /**
+ * Constructor.
+ */
+ DepListTestCase() :
+ DepListTestCaseBase(i_)
+ {
+ }
+ };
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase1 : DepListTestCase<1>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_1;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase2 : DepListTestCase<2>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_2;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase3 : DepListTestCase<3>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_3;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase4 : DepListTestCase<4>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_4;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase5 : DepListTestCase<5>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_5;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase6 : DepListTestCase<6>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_6;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase7 : DepListTestCase<7>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "four", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/four-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_7;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase8 : DepListTestCase<8>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/four cat/three";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "four", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/four-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_8;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase9 : DepListTestCase<9>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/four cat/two";
+ repo->add_version("cat", "four", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/four-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_9;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase10 : DepListTestCase<10>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_10;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase11 : DepListTestCase<11>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "|| ( cat/two cat/four )";
+ repo->add_version("cat", "four", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_11;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase12 : DepListTestCase<12>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( ( cat/two cat/three ) cat/four )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ repo->add_version("cat", "four", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_12;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase13 : DepListTestCase<13>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three cat/four";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ repo->add_version("cat", "four", "1")->deps.build_depend_string = "|| ( ( cat/two cat/three ) cat/five )";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/four-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_13;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase14 : DepListTestCase<14>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_14;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase15 : DepListTestCase<15>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_15;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase16 : DepListTestCase<16>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two:slot2";
+ repo->add_version("cat", "two", "1.1")->slot = SlotName("slot1");
+ repo->add_version("cat", "two", "1.2")->slot = SlotName("slot2");
+ repo->add_version("cat", "two", "1.3")->slot = SlotName("slot3");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1.2:slot2::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_16;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase17 : DepListTestCase<17>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "<cat/two-1.2-r2:slot2";
+ repo->add_version("cat", "two", "1.1")->slot = SlotName("slot1");
+ repo->add_version("cat", "two", "1.2")->slot = SlotName("slot2");
+ repo->add_version("cat", "two", "1.2-r1")->slot = SlotName("slot2");
+ repo->add_version("cat", "two", "1.2-r2")->slot = SlotName("slot2");
+ repo->add_version("cat", "two", "1.3")->slot = SlotName("slot3");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1.2-r1:slot2::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_17;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase18 : DepListTestCase<18>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( )";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_18;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase19 : DepListTestCase<19>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "enabled? ( cat/two )";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_19;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase20 : DepListTestCase<20>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "!enabled? ( cat/two )";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_20;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase21 : DepListTestCase<21>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "disabled? ( cat/two )";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_21;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase22 : DepListTestCase<22>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "!disabled? ( cat/two )";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_22;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase23 : DepListTestCase<23>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( enabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_23;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase24 : DepListTestCase<24>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( !enabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_24;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase25 : DepListTestCase<25>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( disabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_25;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase26 : DepListTestCase<26>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( !disabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_26;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase27 : DepListTestCase<27>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( enabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_27;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase28 : DepListTestCase<28>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( !enabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_28;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase29 : DepListTestCase<29>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( disabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_29;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase30 : DepListTestCase<30>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( !disabled? ( cat/two ) cat/three )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_30;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase31 : DepListTestCase<31>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( enabled? ( cat/three ) cat/two )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_31;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase32 : DepListTestCase<32>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( !enabled? ( cat/three ) cat/two )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_32;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase33 : DepListTestCase<33>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( disabled? ( cat/three ) cat/two )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_33;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase34 : DepListTestCase<34>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three || ( !disabled? ( cat/three ) cat/two )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_34;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase35 : DepListTestCase<35>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( enabled1? ( cat/two ) enabled2? ( cat/three ) )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_35;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase36 : DepListTestCase<36>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( !enabled1? ( cat/two ) enabled2? ( cat/three ) )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_36;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase37 : DepListTestCase<37>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( !enabled1? ( cat/two ) !enabled2? ( cat/three ) )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_37;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase38 : DepListTestCase<38>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "!cat/two";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_38;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase39 : DepListTestCase<39>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two !cat/two";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_39;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase40 : DepListTestCase<40>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "!cat/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_40;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase41 : DepListTestCase<41>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/three cat/two";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "!cat/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_41;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase42 : DepListTestCase<42>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/one";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_42;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase43 : DepListTestCase<43>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1")->deps.run_depend_string = "cat/one";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_43;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase44 : DepListTestCase<44>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two cat/two )";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_44;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase45 : DepListTestCase<45>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two[enabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "enabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_45;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase46 : DepListTestCase<46>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two[-disabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "disabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_46;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase47 : DepListTestCase<47>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two[disabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "disabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_47;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase48 : DepListTestCase<48>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two[-enabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "enabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_48;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase49 : DepListTestCase<49>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two cat/two[enabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "enabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_49;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase50 : DepListTestCase<50>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two cat/two[-disabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "disabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_50;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase51 : DepListTestCase<51>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two cat/two[disabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "disabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_51;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase52 : DepListTestCase<52>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "( cat/two cat/two[-enabled] )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->iuse = "enabled";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_52;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase53 : DepListTestCase<53>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_53;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase54 : DepListTestCase<54>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_54;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase55 : DepListTestCase<55>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/one";
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_55;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase56 : DepListTestCase<56>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two || ( cat/three cat/four )";
+ repo->add_version("cat", "two", "1")->get_ebuild_interface()->provide_string = "cat/four";
+ repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target="cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("cat/four-1:0::virtuals");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_56;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase57 : DepListTestCase<57>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps.post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/one";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/two-1:0::repo");
+ }
+ } test_dep_list_57;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCase58 : DepListTestCase<58>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->get_ebuild_interface()->provide_string = "cat/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("cat/two-1:0::virtuals");
+ }
+ } test_dep_list_58;
+
+ /**
+ * \test Test DepList transactional add behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCaseTransactionalAdd : TestCase
+ {
+ DepListTestCaseTransactionalAdd() : TestCase("dep list transactional add") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/four cat/two";
+ repo->add_version("cat", "four", "1");
+ repo->add_version("cat", "five", "1")->deps.build_depend_string = "cat/six cat/seven";
+ repo->add_version("cat", "six", "1");
+ repo->add_version("cat", "seven", "1")->deps.build_depend_string = "cat/doesnotexist";
+
+ DepList d(&env, DepListOptions());
+ d.add(PortageDepParser::parse("cat/one"));
+ TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "),
+ "cat/four-1:0::repo cat/two-1:0::repo cat/three-1:0::repo cat/one-1:0::repo");
+
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse("cat/five")), DepListError);
+
+ TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "),
+ "cat/four-1:0::repo cat/two-1:0::repo cat/three-1:0::repo cat/one-1:0::repo");
+ }
+ } test_dep_list_transactional_add;
+
+ /**
+ * \test Test DepList transactional add behaviour on PDEPENDs.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCaseTransactionalAddPost : TestCase
+ {
+ DepListTestCaseTransactionalAddPost() : TestCase("dep list transactional add post") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+
+ repo->add_version("cat", "one", "1")->deps.build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps.build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps.build_depend_string = "cat/four cat/two";
+ repo->add_version("cat", "four", "1");
+ repo->add_version("cat", "five", "1")->deps.build_depend_string = "cat/six cat/seven";
+ repo->add_version("cat", "six", "1");
+ repo->add_version("cat", "seven", "1")->deps.post_depend_string = "cat/doesnotexist";
+
+ DepList d(&env, DepListOptions());
+ d.add(PortageDepParser::parse("cat/one"));
+ TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "),
+ "cat/four-1:0::repo cat/two-1:0::repo cat/three-1:0::repo cat/one-1:0::repo");
+
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse("cat/five")), DepListError);
+
+ TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "),
+ "cat/four-1:0::repo cat/two-1:0::repo cat/three-1:0::repo cat/one-1:0::repo");
+ }
+ } test_dep_list_transactional_add_post;
+
+ /**
+ * \test Test DepList transactional forced downgrade of installed package behaviour.
+ *
+ * \ingroup Test
+ */
+ struct DepListTestCaseForcedDowngradeOfInstalled : TestCase
+ {
+ DepListTestCaseForcedDowngradeOfInstalled() : TestCase("dep list forced downgrade of installed") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ FakeRepository::Pointer repo(new FakeRepository(RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "one", "1");
+
+ FakeInstalledRepository::Pointer installed_repo(
+ new FakeInstalledRepository(RepositoryName("installed_repo")));
+ env.package_database()->add_repository(installed_repo);
+ installed_repo->add_version("cat", "one", "2");
+
+ DepList d(&env, DepListOptions());
+ d.add(PortageDepParser::parse("cat/one"));
+ TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "), "cat/one-1:0::repo");
+ }
+ } test_dep_list_forced_downgrade_of_installed;
+}
+
diff --git a/0.8.0/paludis/dep_tag.cc b/0.8.0/paludis/dep_tag.cc
new file mode 100644
index 0000000..caf2418
--- /dev/null
+++ b/0.8.0/paludis/dep_tag.cc
@@ -0,0 +1,199 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "dep_tag.hh"
+#include <paludis/util/compare.hh>
+
+/** \file
+ * Implementation for DepTag, DepTagCategory etc.
+ *
+ * \ingroup grpdeptag
+ */
+
+using namespace paludis;
+
+#include <paludis/dep_tag-sr.cc>
+
+namespace
+{
+ /**
+ * Create the DepTagCategory for GLSAs.
+ *
+ * \see register_glsa_dep_tag
+ *
+ * \ingroup grpdeptag
+ */
+ DepTagCategory::ConstPointer
+ make_glsa_dep_tag()
+ {
+ return DepTagCategory::ConstPointer(new DepTagCategory(
+ true,
+ "glsa",
+ "Security advisories",
+ "Your system is potentially affected by these security issues:",
+ "Please read the advisories carefully and take appropriate action."));
+ }
+
+ /**
+ * Register the GLSA dep tag category instance.
+ *
+ * \ingroup grpdeptag
+ */
+ static const DepTagCategoryMaker::RegisterMaker register_glsa_dep_tag("glsa",
+ &make_glsa_dep_tag);
+
+ /**
+ * Create the DepTagCategory for general sets.
+ *
+ * \see register_general_set_dep_tag
+ *
+ * \ingroup grpdeptag
+ */
+ DepTagCategory::ConstPointer
+ make_general_set_dep_tag()
+ {
+ return DepTagCategory::ConstPointer(new DepTagCategory(
+ true,
+ "general",
+ "General sets",
+ "",
+ ""));
+ }
+
+ /**
+ * Register the general set dep tag category instance.
+ *
+ * \ingroup grpdeptag
+ */
+ static const DepTagCategoryMaker::RegisterMaker register_general_set_dep_tag("general",
+ &make_general_set_dep_tag);
+
+ /**
+ * Create the DepTagCategory for dependency sets.
+ *
+ * \see register_dependency_set_dep_tag
+ *
+ * \ingroup grpdeptag
+ */
+ DepTagCategory::ConstPointer
+ make_dependency_set_dep_tag()
+ {
+ return DepTagCategory::ConstPointer(new DepTagCategory(
+ false,
+ "dependency",
+ "Dependencies",
+ "",
+ ""));
+ }
+
+ /**
+ * Register the general set dep tag category instance.
+ *
+ * \ingroup grpdeptag
+ */
+ static const DepTagCategoryMaker::RegisterMaker register_dependency_set_dep_tag("dependency",
+ &make_dependency_set_dep_tag);
+}
+
+DepTagCategory::DepTagCategory(
+ bool vis,
+ const std::string & our_id,
+ const std::string & t, const std::string & pre,
+ const std::string & post) :
+ _visible(vis),
+ _id(our_id),
+ _title(t),
+ _pre_text(pre),
+ _post_text(post)
+{
+}
+
+NoSuchDepTagCategory::NoSuchDepTagCategory(const std::string & s) throw () :
+ Exception("No such dep tag category '" + s + "'")
+{
+}
+
+DepTag::DepTag() :
+ ComparisonPolicy<DepTag, comparison_mode::FullComparisonTag,
+ comparison_method::CompareByMemberFetchFunctionTag<std::string> >(&DepTag::short_text)
+{
+}
+
+DepTag::~DepTag()
+{
+}
+
+GLSADepTag::GLSADepTag(const std::string & id, const std::string & our_glsa_title) :
+ _id(id),
+ _glsa_title(our_glsa_title)
+{
+}
+
+std::string
+GLSADepTag::short_text() const
+{
+ return "GLSA-" + _id;
+}
+
+std::string
+GLSADepTag::category() const
+{
+ return "glsa";
+}
+
+std::string
+GLSADepTag::glsa_title() const
+{
+ return _glsa_title;
+}
+
+GeneralSetDepTag::GeneralSetDepTag(const std::string & id) :
+ _id(id)
+{
+}
+
+std::string
+GeneralSetDepTag::short_text() const
+{
+ return _id;
+}
+
+std::string
+GeneralSetDepTag::category() const
+{
+ return "general";
+}
+
+DependencyDepTag::DependencyDepTag(const PackageDatabaseEntry & pde) :
+ _dbe(pde)
+{
+}
+
+std::string
+DependencyDepTag::short_text() const
+{
+ return stringify(_dbe);
+}
+
+std::string
+DependencyDepTag::category() const
+{
+ return "dependency";
+}
+
diff --git a/0.8.0/paludis/dep_tag.hh b/0.8.0/paludis/dep_tag.hh
new file mode 100644
index 0000000..d897e8d
--- /dev/null
+++ b/0.8.0/paludis/dep_tag.hh
@@ -0,0 +1,278 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEP_TAG_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_TAG_HH 1
+
+/** \file
+ * Declarations for the DepTag and DepTagCategory classes.
+ *
+ * \ingroup grpdeptag
+ */
+
+#include <string>
+#include <paludis/package_database_entry.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/visitor.hh>
+#include <paludis/util/counted_ptr.hh>
+#include <paludis/util/virtual_constructor.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/collection.hh>
+#include <paludis/util/sr.hh>
+
+namespace paludis
+{
+ /**
+ * A DepTagCategory is identified by its name and has associated display
+ * information for a DepTag's category.
+ *
+ * It is usually accessed via DepTagCategoryMaker.
+ *
+ * \see DepTagCategoryMaker
+ * \see DepTag
+ *
+ * \ingroup grpdeptag
+ */
+ class DepTagCategory :
+ InstantiationPolicy<DepTagCategory, instantiation_method::NonCopyableTag>,
+ public InternalCounted<DepTagCategory>
+ {
+ private:
+ bool _visible;
+ const std::string _id;
+ const std::string _title;
+ const std::string _pre_text;
+ const std::string _post_text;
+
+ public:
+ /**
+ * Constructor.
+ */
+ DepTagCategory(
+ bool visible,
+ const std::string & id,
+ const std::string & t,
+ const std::string & pre,
+ const std::string & post);
+
+ /**
+ * Should we be displayed in a tag category summary?
+ */
+ bool visible() const
+ {
+ return _visible;
+ }
+
+ /**
+ * Fetch our short ID (for example, 'GLSA').
+ */
+ std::string id() const
+ {
+ return _id;
+ }
+
+ /**
+ * Fetch our title (for example, 'Security advisories'), or an
+ * empty string if we're untitled.
+ */
+ std::string title() const
+ {
+ return _title;
+ }
+
+ /**
+ * Fetch our pre list text, or an empty string.
+ */
+ std::string pre_text() const
+ {
+ return _pre_text;
+ }
+
+ /**
+ * Fetch our post list text, or an empty string.
+ */
+ std::string post_text() const
+ {
+ return _post_text;
+ }
+ };
+
+ /**
+ * Thrown if DepTagCategoryMaker cannot find the named DepTagCategory.
+ *
+ * \ingroup grpexceptions
+ * \ingroup grpdeptag
+ */
+ class NoSuchDepTagCategory :
+ public Exception
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ NoSuchDepTagCategory(const std::string &) throw ();
+ };
+
+ /**
+ * Virtual constructor for accessing DepTagCategory instances.
+ *
+ * \ingroup grpdeptag
+ */
+ typedef VirtualConstructor<std::string, DepTagCategory::ConstPointer (*) (),
+ virtual_constructor_not_found::ThrowException<NoSuchDepTagCategory> > DepTagCategoryMaker;
+
+ class DepTag;
+ class GLSADepTag;
+ class GeneralSetDepTag;
+ class DependencyDepTag;
+
+ /**
+ * Visitor class for visiting the different DepTag subclasses.
+ *
+ * \ingroup grpdeptag
+ */
+ typedef VisitorTypes<GLSADepTag *, GeneralSetDepTag *, DependencyDepTag *> DepTagVisitorTypes;
+
+ /**
+ * A DepTag can be associated with a PackageDepAtom, and is transferred
+ * onto any associated DepListEntry instances.
+ *
+ * It is used for tagging dep list entries visually, for example to
+ * indicate an associated GLSA.
+ *
+ * \ingroup grpdeptag
+ */
+ class DepTag :
+ InstantiationPolicy<DepTag, instantiation_method::NonCopyableTag>,
+ public InternalCounted<DepTag>,
+ public virtual VisitableInterface<DepTagVisitorTypes>,
+ public ComparisonPolicy<DepTag,
+ comparison_mode::FullComparisonTag,
+ comparison_method::CompareByMemberFetchFunctionTag<std::string> >
+ {
+ protected:
+ /**
+ * Constructor.
+ */
+ DepTag();
+
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~DepTag();
+
+ /**
+ * Fetch our short text (for example, 'GLSA-1234') that is
+ * displayed with the dep list entry.
+ */
+ virtual std::string short_text() const = 0;
+
+ /**
+ * Fetch our DepTagCategory's tag.
+ */
+ virtual std::string category() const = 0;
+
+ /**
+ * Compare, by short_text only.
+ */
+ };
+
+ /**
+ * DepTag subclass for GLSAs.
+ *
+ * \ingroup grpdeptag
+ */
+ class GLSADepTag :
+ public DepTag,
+ public Visitable<GLSADepTag, DepTagVisitorTypes>
+ {
+ private:
+ const std::string _id;
+ const std::string _glsa_title;
+
+ public:
+ /**
+ * Constructor.
+ */
+ GLSADepTag(const std::string & id, const std::string & glsa_title);
+
+ virtual std::string short_text() const;
+
+ virtual std::string category() const;
+
+ /**
+ * Fetch our GLSA title (for example, 'Yet another PHP remote access
+ * hole').
+ */
+ std::string glsa_title() const;
+ };
+
+ /**
+ * DepTag subclass for general sets.
+ *
+ * \ingroup grpdeptag
+ */
+ class GeneralSetDepTag :
+ public DepTag,
+ public Visitable<GeneralSetDepTag, DepTagVisitorTypes>
+ {
+ private:
+ const std::string _id;
+
+ public:
+ /**
+ * Constructor.
+ */
+ GeneralSetDepTag(const std::string & id);
+
+ virtual std::string short_text() const;
+
+ virtual std::string category() const;
+ };
+
+ /**
+ * DepTag subclass for dependencies.
+ *
+ * \ingroup grpdeptag
+ */
+ class DependencyDepTag :
+ public DepTag,
+ public Visitable<DependencyDepTag, DepTagVisitorTypes>
+ {
+ private:
+ const PackageDatabaseEntry _dbe;
+
+ public:
+ /**
+ * Constructor.
+ */
+ DependencyDepTag(const PackageDatabaseEntry & dbe);
+
+ virtual std::string short_text() const;
+
+ virtual std::string category() const;
+ };
+
+#include <paludis/dep_tag-sr.hh>
+
+ typedef SortedCollection<DepTagEntry> DepListEntryTags;
+}
+
+#endif
diff --git a/0.8.0/paludis/dep_tag.sr b/0.8.0/paludis/dep_tag.sr
new file mode 100644
index 0000000..2dfd21b
--- /dev/null
+++ b/0.8.0/paludis/dep_tag.sr
@@ -0,0 +1,10 @@
+make_class_DepTagEntry()
+{
+ key tag DepTag::ConstPointer
+ key generation long
+
+ allow_named_args
+ comparison_operators "all" "*tag"
+}
+
+
diff --git a/0.8.0/paludis/digests/Makefile.am b/0.8.0/paludis/digests/Makefile.am
new file mode 100644
index 0000000..4d00875
--- /dev/null
+++ b/0.8.0/paludis/digests/Makefile.am
@@ -0,0 +1,42 @@
+MAINTAINERCLEANFILES = Makefile.in
+CLEANFILES = *~
+SUBDIRS = .
+
+libexecprogdir = $(libexecdir)/paludis/digests/
+
+paludis_digests_includedir = $(includedir)/paludis/digests/
+
+paludis_digests_include_HEADERS = \
+ sha256.hh \
+ rmd160.hh \
+ md5.hh
+
+libpaludisdigests_la_SOURCES = \
+ $(paludis_digests_include_HEADERS) \
+ sha256.cc \
+ rmd160.cc \
+ md5.cc
+
+libpaludisdigests_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+
+lib_LTLIBRARIES = libpaludisdigests.la
+
+TESTS = sha256_TEST rmd160_TEST md5_TEST
+EXTRA_DIST = sha256_TEST.cc rmd160_TEST.cc md5_TEST.cc
+
+check_PROGRAMS = $(TESTS)
+
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+
+sha256_TEST_SOURCES = sha256_TEST.cc
+sha256_TEST_CXXFLAGS = -I$(top_srcdir)
+sha256_TEST_LDADD = $(top_builddir)/test/libtest.a libpaludisdigests.la
+
+rmd160_TEST_SOURCES = rmd160_TEST.cc
+rmd160_TEST_CXXFLAGS = -I$(top_srcdir)
+rmd160_TEST_LDADD = $(top_builddir)/test/libtest.a libpaludisdigests.la
+
+md5_TEST_SOURCES = md5_TEST.cc
+md5_TEST_CXXFLAGS = -I$(top_srcdir)
+md5_TEST_LDADD = $(top_builddir)/test/libtest.a libpaludisdigests.la
+
diff --git a/0.8.0/paludis/digests/md5.cc b/0.8.0/paludis/digests/md5.cc
new file mode 100644
index 0000000..4109ada
--- /dev/null
+++ b/0.8.0/paludis/digests/md5.cc
@@ -0,0 +1,239 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/digests/md5.hh>
+#include <sstream>
+#include <istream>
+#include <iomanip>
+
+using namespace paludis;
+
+/*
+ * Implemented based upon the description in RFC1321.
+ */
+
+namespace
+{
+ inline uint32_t _rl(uint32_t x, unsigned int shift) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _rl(uint32_t x, unsigned int shift)
+ {
+ return (x << shift) | (x >> (32 - shift));
+ }
+
+ inline uint32_t _f(uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _f(uint32_t x, uint32_t y, uint32_t z)
+ {
+ return (x & y) | (~x & z);
+ }
+
+ inline uint32_t _g(uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _g(uint32_t x, uint32_t y, uint32_t z)
+ {
+ return (x & z) | (y & ~z);
+ }
+
+ inline uint32_t _h(uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _h(uint32_t x, uint32_t y, uint32_t z)
+ {
+ return x ^ y ^ z;
+ }
+
+ inline uint32_t _i(uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _i(uint32_t x, uint32_t y, uint32_t z)
+ {
+ return y ^ (x | ~z);
+ }
+
+ inline uint32_t _x(unsigned i, const uint8_t * const block) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _x(unsigned i, const uint8_t * const block)
+ {
+ return
+ (block[(i << 2) + 3] << 24) |
+ (block[(i << 2) + 2] << 16) |
+ (block[(i << 2) + 1] << 8) |
+ (block[(i << 2) + 0]);
+ }
+
+ inline uint32_t _e(const uint32_t x) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _e(const uint32_t x)
+ {
+ return
+ ((x & 0xff) << 24) |
+ ((x & 0xff00) << 8) |
+ ((x & 0xff0000) >> 8) |
+ ((x & 0xff000000) >> 24);
+ }
+}
+
+void
+MD5::_update(const uint8_t * const block)
+{
+ uint32_t a(_r[0]), b(_r[1]), c(_r[2]), d(_r[3]), f, g, t;
+
+ for (int i(0) ; i < 16 ; ++i)
+ {
+ f = _f(b, c, d);
+ g = i;
+
+ t = d;
+ d = c;
+ c = b;
+ b = _rl(a + f + _t[i] + _x(g, block), _s[i]) + b;
+ a = t;
+ }
+
+ for (int i(16) ; i < 32 ; ++i)
+ {
+ f = _g(b, c, d);
+ g = (5 * i + 1) & 0x0f;
+
+ t = d;
+ d = c;
+ c = b;
+ b = _rl(a + f + _t[i] + _x(g, block), _s[i]) + b;
+ a = t;
+ }
+
+ for (int i(32) ; i < 48 ; ++i)
+ {
+ f = _h(b, c, d);
+ g = (3 * i + 5) & 0x0f;
+
+ t = d;
+ d = c;
+ c = b;
+ b = _rl(a + f + _t[i] + _x(g, block), _s[i]) + b;
+ a = t;
+ }
+
+ for (int i(48) ; i < 64 ; ++i)
+ {
+ f = _i(b, c, d);
+ g = (7 * i) & 0x0f;
+
+ t = d;
+ d = c;
+ c = b;
+ b = _rl(a + f + _t[i] + _x(g, block), _s[i]) + b;
+ a = t;
+ }
+
+ _r[0] += a;
+ _r[1] += b;
+ _r[2] += c;
+ _r[3] += d;
+}
+
+MD5::MD5(std::istream & stream) :
+ _size(0),
+ _done_one_pad(false)
+{
+ _r[0] = 0x67452301;
+ _r[1] = 0xefcdab89;
+ _r[2] = 0x98badcfe;
+ _r[3] = 0x10325476;
+
+ uint8_t buffer[64];
+ int c, s(0);
+ while (-1 != ((c = _get(stream))))
+ {
+ buffer[s++] = c;
+ if (64 == s)
+ {
+ _update(&buffer[0]);
+ s = 0;
+ }
+ }
+ while (56 != s)
+ {
+ buffer[s++] = 0;
+ if (64 == s)
+ {
+ _update(&buffer[0]);
+ s = 0;
+ }
+ }
+
+ buffer[56] = static_cast<uint8_t>(_size >> (0 * 8));
+ buffer[57] = static_cast<uint8_t>(_size >> (1 * 8));
+ buffer[58] = static_cast<uint8_t>(_size >> (2 * 8));
+ buffer[59] = static_cast<uint8_t>(_size >> (3 * 8));
+ buffer[60] = static_cast<uint8_t>(_size >> (4 * 8));
+ buffer[61] = static_cast<uint8_t>(_size >> (5 * 8));
+ buffer[62] = static_cast<uint8_t>(_size >> (6 * 8));
+ buffer[63] = static_cast<uint8_t>(_size >> (7 * 8));
+ _update(&buffer[0]);
+}
+
+std::string
+MD5::hexsum() const
+{
+ std::stringstream result;
+
+ for (int j(0) ; j < 4 ; ++j)
+ result << std::hex << std::right << std::setw(8) << std::setfill('0') <<
+ _e(static_cast<unsigned int>(_r[j])) << std::flush;
+
+ return result.str();
+}
+
+int
+MD5::_get(std::istream & stream)
+{
+ char c;
+ if (stream.get(c))
+ {
+ _size += 8;
+ return static_cast<unsigned char>(c);
+ }
+ else if (! _done_one_pad)
+ {
+ _done_one_pad = true;
+ return 0x80;
+ }
+ else
+ return -1;
+}
+
+const uint8_t MD5::_s[64] = {
+ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
+ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
+ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
+ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
+};
+
+const uint32_t MD5::_t[64] = {
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+};
+
diff --git a/0.8.0/paludis/digests/md5.hh b/0.8.0/paludis/digests/md5.hh
new file mode 100644
index 0000000..e4da004
--- /dev/null
+++ b/0.8.0/paludis/digests/md5.hh
@@ -0,0 +1,61 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_EBUILD_DIGESTS_MD5_HH
+#define PALUDIS_GUARD_EBUILD_DIGESTS_MD5_HH 1
+
+#include <iosfwd>
+#include <string>
+#include <inttypes.h>
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ /**
+ * MD5 digest class.
+ *
+ * \ingroup grplibpaludisdigests
+ */
+ class PALUDIS_VISIBLE MD5
+ {
+ private:
+ static const uint32_t _t[64];
+ static const uint8_t _s[64];
+ uint32_t _r[4];
+ uint64_t _size;
+ bool _done_one_pad;
+
+ void _update(const uint8_t * const block);
+
+ inline int _get(std::istream & stream);
+
+ public:
+ /**
+ * Constructor.
+ */
+ MD5(std::istream & stream);
+
+ /**
+ * Our checksum, as a string of hex characters.
+ */
+ std::string hexsum() const;
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/digests/md5_TEST.cc b/0.8.0/paludis/digests/md5_TEST.cc
new file mode 100644
index 0000000..cb4f86e
--- /dev/null
+++ b/0.8.0/paludis/digests/md5_TEST.cc
@@ -0,0 +1,114 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/digests/md5.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace
+{
+ /**
+ * \name Test utilities
+ * \ingroup grptestcases
+ * \{
+ */
+
+ unsigned char dehex_c(unsigned char c)
+ {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c + 10 - 'a';
+ else
+ throw "meh!";
+ }
+
+ std::string dehex(const std::string & s)
+ {
+ std::string result;
+ std::string::size_type p(0);
+ while (p < s.length())
+ {
+ unsigned char c;
+ c = (dehex_c(s.at(p)) << 4) + dehex_c(s.at(p + 1));
+ result.append(1, c);
+ p += 2;
+ }
+ return result;
+ }
+
+ /**
+ * \}
+ */
+}
+
+namespace test_cases
+{
+ /**
+ * \name Test cases for paludis::digests::MD5
+ * \ingroup grptestcases
+ * \{
+ */
+
+ struct MD5TestCase : TestCase
+ {
+ std::string data;
+ std::string expected;
+
+ MD5TestCase(const std::string & s, const std::string & d,
+ const std::string & e) :
+ TestCase("md5 " + s),
+ data(d),
+ expected(e)
+ {
+ }
+
+ void run()
+ {
+ std::stringstream ss(data);
+ MD5 s(ss);
+ TEST_CHECK_EQUAL(s.hexsum(), expected);
+ }
+ };
+
+ MD5TestCase t_0("empty", "", "d41d8cd98f00b204e9800998ecf8427e");
+ MD5TestCase t_1("a", "a", "0cc175b9c0f1b6a831c399e269772661");
+ MD5TestCase t_2("abc", "abc", "900150983cd24fb0d6963f7d28e17f72");
+ MD5TestCase t_3("message digest", "message digest", "f96b697d7cb7938d525a2f31aaf161d0");
+ MD5TestCase t_4("a..z", "abcdefghijklmnopqrstuvwxyz",
+ "c3fcd3d76192e4007dfb496cca67e13b");
+ MD5TestCase t_6("A...Za...z0...9",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "d174ab98d277d9f5a5611c2c9f419d9f");
+ MD5TestCase t_7("8 times 1234567890",
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ "57edf4a22be3c955ac49da2e2107b67a");
+ MD5TestCase t_8("one million times a",
+ std::string(1000000, 'a'),
+ "7707d6ae4e027c70eea2a935c2296f21");
+
+ /**
+ * \}
+ */
+}
+
+
diff --git a/0.8.0/paludis/digests/rmd160.cc b/0.8.0/paludis/digests/rmd160.cc
new file mode 100644
index 0000000..dde3e74
--- /dev/null
+++ b/0.8.0/paludis/digests/rmd160.cc
@@ -0,0 +1,231 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "rmd160.hh"
+#include <paludis/util/attributes.hh>
+#include <sstream>
+#include <istream>
+#include <iomanip>
+
+using namespace paludis;
+
+/*
+ * Implemented based upon the description at:
+ * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
+ */
+
+namespace
+{
+ inline uint32_t rl(uint32_t x, unsigned int shift) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t rl(uint32_t x, unsigned int shift)
+ {
+ return (x << shift) | (x >> (32 - shift));
+ }
+
+ inline uint32_t _f(uint32_t j, uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _f(uint32_t j, uint32_t x, uint32_t y, uint32_t z)
+ {
+ switch (j / 16)
+ {
+ case 0:
+ return x ^ y ^ z;
+
+ case 1:
+ return (x & y) | (~x & z);
+
+ case 2:
+ return (x | ~y) ^ z;
+
+ case 3:
+ return (x & z) | (y & ~z);
+
+ case 4:
+ return x ^ (y | ~z);
+ }
+
+ throw 0;
+ }
+
+ inline uint32_t _x(unsigned i, const uint8_t * const block) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _x(unsigned i, const uint8_t * const block)
+ {
+ return
+ (block[(i << 2) + 3] << 24) |
+ (block[(i << 2) + 2] << 16) |
+ (block[(i << 2) + 1] << 8) |
+ (block[(i << 2) + 0]);
+ }
+
+ inline uint32_t _e(const uint32_t x) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t _e(const uint32_t x)
+ {
+ return
+ ((x & 0xff) << 24) |
+ ((x & 0xff00) << 8) |
+ ((x & 0xff0000) >> 8) |
+ ((x & 0xff000000) >> 24);
+ }
+}
+
+void
+RMD160::_update(const uint8_t * const block)
+{
+ uint32_t a(_h[0]), b(_h[1]), c(_h[2]), d(_h[3]), e(_h[4]);
+ uint32_t ap(_h[0]), bp(_h[1]), cp(_h[2]), dp(_h[3]), ep(_h[4]);
+ uint32_t t;
+
+ for (unsigned j(0) ; j <= 79 ; ++j)
+ {
+ t = a + _f(j, b, c, d) + _x(_r[j], block) + _k[j / 16];
+ t = rl(t, _s[j]) + e;
+ a = e;
+ e = d;
+ d = rl(c, 10);
+ c = b;
+ b = t;
+
+ t = ap + _f(79 - j, bp, cp, dp) + _x(_rp[j], block) + _kp[j / 16];
+ t = rl(t, _sp[j]) + ep;
+ ap = ep;
+ ep = dp;
+ dp = rl(cp, 10);
+ cp = bp;
+ bp = t;
+ }
+
+ t = _h[1] + c + dp;
+ _h[1] = _h[2] + d + ep;
+ _h[2] = _h[3] + e + ap;
+ _h[3] = _h[4] + a + bp;
+ _h[4] = _h[0] + b + cp;
+ _h[0] = t;
+}
+
+RMD160::RMD160(std::istream & stream) :
+ _size(0),
+ _done_one_pad(false)
+{
+ _h[0] = 0x67452301;
+ _h[1] = 0xefcdab89;
+ _h[2] = 0x98badcfe;
+ _h[3] = 0x10325476;
+ _h[4] = 0xc3d2e1f0;
+
+ uint8_t buffer[64];
+ int c, s(0);
+ while (-1 != ((c = _get(stream))))
+ {
+ buffer[s++] = c;
+ if (64 == s)
+ {
+ _update(&buffer[0]);
+ s = 0;
+ }
+ }
+ while (56 != s)
+ {
+ buffer[s++] = 0;
+ if (64 == s)
+ {
+ _update(&buffer[0]);
+ s = 0;
+ }
+ }
+
+ buffer[56] = static_cast<uint8_t>(_size >> (0 * 8));
+ buffer[57] = static_cast<uint8_t>(_size >> (1 * 8));
+ buffer[58] = static_cast<uint8_t>(_size >> (2 * 8));
+ buffer[59] = static_cast<uint8_t>(_size >> (3 * 8));
+ buffer[60] = static_cast<uint8_t>(_size >> (4 * 8));
+ buffer[61] = static_cast<uint8_t>(_size >> (5 * 8));
+ buffer[62] = static_cast<uint8_t>(_size >> (6 * 8));
+ buffer[63] = static_cast<uint8_t>(_size >> (7 * 8));
+ _update(&buffer[0]);
+}
+
+std::string
+RMD160::hexsum() const
+{
+ std::stringstream result;
+
+ for (int j(0) ; j < 5 ; ++j)
+ result << std::hex << std::right << std::setw(8) << std::setfill('0') <<
+ _e(static_cast<unsigned int>(_h[j])) << std::flush;
+
+ return result.str();
+}
+
+int
+RMD160::_get(std::istream & stream)
+{
+ char c;
+ if (stream.get(c))
+ {
+ _size += 8;
+ return static_cast<unsigned char>(c);
+ }
+ else if (! _done_one_pad)
+ {
+ _done_one_pad = true;
+ return 0x80;
+ }
+ else
+ return -1;
+}
+
+const uint8_t RMD160::_r[80] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
+ 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
+ 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
+ 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+};
+
+const uint8_t RMD160::_rp[80] = {
+ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
+ 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
+ 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
+ 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
+ 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+};
+
+const uint8_t RMD160::_s[80] = {
+ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
+ 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
+ 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
+ 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
+ 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+};
+
+const uint8_t RMD160::_sp[80] = {
+ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
+ 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
+ 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
+ 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
+ 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+};
+
+const uint32_t RMD160::_k[5] = {
+ 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e
+};
+
+const uint32_t RMD160::_kp[5] = {
+ 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000
+};
+
diff --git a/0.8.0/paludis/digests/rmd160.hh b/0.8.0/paludis/digests/rmd160.hh
new file mode 100644
index 0000000..dddae28
--- /dev/null
+++ b/0.8.0/paludis/digests/rmd160.hh
@@ -0,0 +1,65 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_EBUILD_DIGESTS_RMD160_HH
+#define PALUDIS_GUARD_EBUILD_DIGESTS_RMD160_HH 1
+
+#include <iosfwd>
+#include <string>
+#include <inttypes.h>
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ /**
+ * RMD160 digest class.
+ *
+ * \ingroup grplibpaludisdigests
+ */
+ class PALUDIS_VISIBLE RMD160
+ {
+ private:
+ static const uint8_t _r[80], _rp[80];
+ static const uint8_t _s[80], _sp[80];
+ static const uint32_t _k[5], _kp[5];
+
+ uint32_t _h[5];
+ uint64_t _size;
+ bool _done_one_pad;
+
+ void _update(const uint8_t * const block);
+
+ inline int _get(std::istream & stream);
+
+ public:
+ /**
+ * Constructor.
+ */
+ RMD160(std::istream & stream);
+
+ /**
+ * Our checksum, as a string of hex characters.
+ */
+ std::string hexsum() const;
+ };
+
+}
+
+#endif
+
diff --git a/0.8.0/paludis/digests/rmd160_TEST.cc b/0.8.0/paludis/digests/rmd160_TEST.cc
new file mode 100644
index 0000000..d9e33dc
--- /dev/null
+++ b/0.8.0/paludis/digests/rmd160_TEST.cc
@@ -0,0 +1,116 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/digests/rmd160.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace test;
+using namespace paludis;
+
+namespace
+{
+ /**
+ * \name Test utilities
+ * \ingroup grptestcases
+ * \{
+ */
+
+ unsigned char dehex_c(unsigned char c)
+ {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c + 10 - 'a';
+ else
+ throw "meh!";
+ }
+
+ std::string dehex(const std::string & s)
+ {
+ std::string result;
+ std::string::size_type p(0);
+ while (p < s.length())
+ {
+ unsigned char c;
+ c = (dehex_c(s.at(p)) << 4) + dehex_c(s.at(p + 1));
+ result.append(1, c);
+ p += 2;
+ }
+ return result;
+ }
+
+ /**
+ * \}
+ */
+}
+
+namespace test_cases
+{
+ /**
+ * \name Test cases for paludis::digests::RMD160
+ * \ingroup grptestcases
+ * \{
+ */
+
+ struct RMD160TestCase : TestCase
+ {
+ std::string data;
+ std::string expected;
+
+ RMD160TestCase(const std::string & s, const std::string & d,
+ const std::string & e) :
+ TestCase("rmd160 " + s),
+ data(d),
+ expected(e)
+ {
+ }
+
+ void run()
+ {
+ std::stringstream ss(data);
+ RMD160 s(ss);
+ TEST_CHECK_EQUAL(s.hexsum(), expected);
+ }
+ };
+
+ RMD160TestCase t_0("empty", "", "9c1185a5c5e9fc54612808977ee8f548b2258d31");
+ RMD160TestCase t_1("a", "a", "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
+ RMD160TestCase t_2("abc", "abc", "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
+ RMD160TestCase t_3("message digest", "message digest", "5d0689ef49d2fae572b881b123a85ffa21595f36");
+ RMD160TestCase t_4("a..z", "abcdefghijklmnopqrstuvwxyz",
+ "f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
+ RMD160TestCase t_5("abcdbcde...nopq",
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "12a053384a9c0c88e405a06c27dcf49ada62eb2b");
+ RMD160TestCase t_6("A...Za...z0...9",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "b0e20b6e3116640286ed3a87a5713079b21f5189");
+ RMD160TestCase t_7("8 times 1234567890",
+ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ "9b752e45573d4b39f4dbd3323cab82bf63326bfb");
+ RMD160TestCase t_8("one million times a",
+ std::string(1000000, 'a'),
+ "52783243c1697bdbe16d37f97f68f08325dc1528");
+
+ /**
+ * \}
+ */
+}
+
diff --git a/0.8.0/paludis/digests/sha256.cc b/0.8.0/paludis/digests/sha256.cc
new file mode 100644
index 0000000..e574921
--- /dev/null
+++ b/0.8.0/paludis/digests/sha256.cc
@@ -0,0 +1,228 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "sha256.hh"
+#include <paludis/util/attributes.hh>
+#include <istream>
+#include <iomanip>
+#include <sstream>
+
+using namespace paludis;
+
+/*
+ * Implemented based upon the description at:
+ * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf
+ */
+
+namespace
+{
+ inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z)
+ {
+ return (x & y) ^ (~x & z);
+ }
+
+ inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
+ {
+ return (x & y) ^ (x & z) ^ (y & z);
+ }
+
+ inline uint32_t rr(uint32_t x, unsigned int shift) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t rr(uint32_t x, unsigned int shift)
+ {
+ return (x >> shift) | (x << (32 - shift));
+ }
+
+ inline uint32_t sigma0(uint32_t x) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t sigma0(uint32_t x)
+ {
+ return rr(x, 2) ^ rr(x, 13) ^ rr(x, 22);
+ }
+
+ inline uint32_t sigma1(uint32_t x) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t sigma1(uint32_t x)
+ {
+ return rr(x, 6) ^ rr(x, 11) ^ rr(x, 25);
+ }
+
+ inline uint32_t lsigma0(uint32_t x) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t lsigma0(uint32_t x)
+ {
+ return rr(x, 7) ^ rr(x, 18) ^ (x >> 3);
+ }
+
+ inline uint32_t lsigma1(uint32_t x) PALUDIS_ATTRIBUTE((always_inline));
+ inline uint32_t lsigma1(uint32_t x)
+ {
+ return rr(x, 17) ^ rr(x, 19) ^ (x >> 10);
+ }
+
+ inline void wload(unsigned j, const uint8_t * const block,
+ uint32_t * const dest) PALUDIS_ATTRIBUTE((always_inline));
+ inline void wload(unsigned j, const uint8_t * const block,
+ uint32_t * const dest)
+ {
+ dest[j] =
+ (block[(j << 2) + 0] << 24) |
+ (block[(j << 2) + 1] << 16) |
+ (block[(j << 2) + 2] << 8) |
+ (block[(j << 2) + 3]);
+ }
+
+ inline void wblend(unsigned j, uint32_t * const dest) PALUDIS_ATTRIBUTE((always_inline));
+ inline void wblend(unsigned j, uint32_t * const dest)
+ {
+ dest[j] = lsigma1(dest[j - 2]) + dest[j - 7] + lsigma0(dest[j - 15]) + dest[j - 16];
+ }
+}
+
+void
+SHA256::_update(const uint8_t * const block)
+{
+ uint32_t a(_h[0]), b(_h[1]), c(_h[2]), d(_h[3]), e(_h[4]), f(_h[5]),
+ g(_h[6]), h(_h[7]);
+
+ uint32_t w[64];
+
+ for (uint32_t j(0) ; j < 16 ; ++j)
+ wload(j, block, &w[0]);
+
+ for (uint32_t j(16) ; j <= 63 ; ++j)
+ wblend(j, &w[0]);
+
+ for (uint32_t j(0) ; j <= 63 ; ++j)
+ {
+ uint32_t t1(h + sigma1(e) + ch(e, f, g) + _k[j] + w[j]);
+ uint32_t t2(sigma0(a) + maj(a, b, c));
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+
+ _h[0] += a;
+ _h[1] += b;
+ _h[2] += c;
+ _h[3] += d;
+ _h[4] += e;
+ _h[5] += f;
+ _h[6] += g;
+ _h[7] += h;
+}
+
+SHA256::SHA256(std::istream & stream) :
+ _size(0),
+ _done_one_pad(false)
+{
+ _h[0] = 0x6a09e667;
+ _h[1] = 0xbb67ae85;
+ _h[2] = 0x3c6ef372;
+ _h[3] = 0xa54ff53a;
+ _h[4] = 0x510e527f;
+ _h[5] = 0x9b05688c;
+ _h[6] = 0x1f83d9ab;
+ _h[7] = 0x5be0cd19;
+
+ uint8_t buffer[64];
+ int c, s(0);
+ while (-1 != ((c = _get(stream))))
+ {
+ buffer[s++] = c;
+ if (64 == s)
+ {
+ _update(&buffer[0]);
+ s = 0;
+ }
+ }
+ while (56 != s)
+ {
+ buffer[s++] = 0;
+ if (64 == s)
+ {
+ _update(&buffer[0]);
+ s = 0;
+ }
+ }
+
+ buffer[56] = static_cast<uint8_t>(_size >> (7 * 8));
+ buffer[57] = static_cast<uint8_t>(_size >> (6 * 8));
+ buffer[58] = static_cast<uint8_t>(_size >> (5 * 8));
+ buffer[59] = static_cast<uint8_t>(_size >> (4 * 8));
+ buffer[60] = static_cast<uint8_t>(_size >> (3 * 8));
+ buffer[61] = static_cast<uint8_t>(_size >> (2 * 8));
+ buffer[62] = static_cast<uint8_t>(_size >> (1 * 8));
+ buffer[63] = static_cast<uint8_t>(_size >> (0 * 8));
+ _update(&buffer[0]);
+}
+
+std::string
+SHA256::hexsum() const
+{
+ std::stringstream result;
+
+ for (int j(0) ; j < 8 ; ++j)
+ result << std::hex << std::right << std::setw(8) << std::setfill('0') <<
+ static_cast<unsigned int>(_h[j]) << std::flush;
+
+ return result.str();
+}
+
+int
+SHA256::_get(std::istream & stream)
+{
+ char c;
+ if (stream.get(c))
+ {
+ _size += 8;
+ return static_cast<unsigned char>(c);
+ }
+ else if (! _done_one_pad)
+ {
+ _done_one_pad = true;
+ return 0x80;
+ }
+ else
+ return -1;
+}
+
+const uint32_t
+paludis::SHA256::_k[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
diff --git a/0.8.0/paludis/digests/sha256.hh b/0.8.0/paludis/digests/sha256.hh
new file mode 100644
index 0000000..72852c3
--- /dev/null
+++ b/0.8.0/paludis/digests/sha256.hh
@@ -0,0 +1,61 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_EBUILD_DIGESTS_SHA256_HH
+#define PALUDIS_GUARD_EBUILD_DIGESTS_SHA256_HH 1
+
+#include <iosfwd>
+#include <string>
+#include <paludis/util/attributes.hh>
+#include <inttypes.h>
+
+namespace paludis
+{
+ /**
+ * SHA256 digest class.
+ *
+ * \ingroup grplibpaludisdigests
+ */
+ class PALUDIS_VISIBLE SHA256
+ {
+ private:
+ static const uint32_t _k[64];
+
+ uint32_t _h[8];
+ uint64_t _size;
+ bool _done_one_pad;
+
+ void _update(const uint8_t * const block);
+
+ inline int _get(std::istream & stream);
+
+ public:
+ /**
+ * Constructor.
+ */
+ SHA256(std::istream & stream);
+
+ /**
+ * Our checksum, as a string of hex characters.
+ */
+ std::string hexsum() const;
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/digests/sha256_TEST.cc b/0.8.0/paludis/digests/sha256_TEST.cc
new file mode 100644
index 0000000..794a4ea
--- /dev/null
+++ b/0.8.0/paludis/digests/sha256_TEST.cc
@@ -0,0 +1,446 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/digests/sha256.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace test;
+using namespace paludis;
+
+/** \file
+ * Test cases for paludis::digests::SHA256.
+ *
+ * \ingroup grptestcases
+ */
+
+namespace
+{
+ /**
+ * \name Test utilities
+ * \ingroup grptestcases
+ * \{
+ */
+
+ unsigned char dehex_c(unsigned char c)
+ {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c + 10 - 'a';
+ else
+ throw "meh!";
+ }
+
+ std::string dehex(const std::string & s)
+ {
+ std::string result;
+ std::string::size_type p(0);
+ while (p < s.length())
+ {
+ unsigned char c;
+ c = (dehex_c(s.at(p)) << 4) + dehex_c(s.at(p + 1));
+ result.append(1, c);
+ p += 2;
+ }
+ return result;
+ }
+
+ /**
+ * \}
+ */
+}
+
+namespace test_cases
+{
+ /**
+ * \name Test cases for paludis::digests::SHA256
+ * \ingroup grptestcases
+ * \{
+ */
+
+ struct SHA256TestCase : TestCase
+ {
+ std::string data;
+ std::string expected;
+
+ SHA256TestCase(const std::string & s, const std::string & d,
+ const std::string & e) :
+ TestCase("sha256 " + s),
+ data(d),
+ expected(e)
+ {
+ }
+
+ void run()
+ {
+ std::stringstream ss(data);
+ SHA256 s(ss);
+ TEST_CHECK_EQUAL(s.hexsum(), expected);
+ }
+ };
+
+ SHA256TestCase t1("empty", "",
+ "e3b0c442""98fc1c14""9afbf4c8""996fb924"
+ "27ae41e4""649b934c""a495991b""7852b855");
+ SHA256TestCase t2("abc", "abc",
+ "ba7816bf""8f01cfea""414140de""5dae2223"
+ "b00361a3""96177a9c""b410ff61""f20015ad");
+ SHA256TestCase t3("abcd...", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "248d6a61""d20638b8""e5c02693""0c3e6039"
+ "a33ce459""64ff2167""f6ecedd4""19db06c1");
+
+ /*
+ * the following tests are from:
+ * http://csrc.ncsl.nist.gov/cryptval/
+ */
+
+ SHA256TestCase t_11_SHA256ShortMsg("t 11 SHA256ShortMsg",
+ dehex("bd"), "68325720aabd7c82f30f554b313d0570c95accbb"
+ "7dc4b5aae11204c08ffe732b");
+
+ SHA256TestCase t_14_SHA256ShortMsg("t 14 SHA256ShortMsg",
+ dehex("5fd4"), "7c4fbf484498d21b487b9d61de8914b2eadaf269"
+ "8712936d47c3ada2558f6788");
+
+ SHA256TestCase t_17_SHA256ShortMsg("t 17 SHA256ShortMsg",
+ dehex("b0bd69"), "4096804221093ddccfbf46831490ea63e9e99414"
+ "858f8d75ff7f642c7ca61803");
+
+ SHA256TestCase t_20_SHA256ShortMsg("t 20 SHA256ShortMsg",
+ dehex("c98c8e55"), "7abc22c0ae5af26ce93dbb94433a0e0b2e119d01"
+ "4f8e7f65bd56c61ccccd9504");
+
+ SHA256TestCase t_23_SHA256ShortMsg("t 23 SHA256ShortMsg",
+ dehex("81a723d966"), "7516fb8bb11350df2bf386bc3c33bd0f52cb4c67"
+ "c6e4745e0488e62c2aea2605");
+
+ SHA256TestCase t_26_SHA256ShortMsg("t 26 SHA256ShortMsg",
+ dehex("c97a2db566e5"), "0eb0281b27a4604709b0513b43ad29fdcff9a7a9"
+ "58554abc689d7fe35af703e4");
+
+ SHA256TestCase t_29_SHA256ShortMsg("t 29 SHA256ShortMsg",
+ dehex("f53210aa6ed72e"), "dee684641421d1ba5a65c71f986a117cbb3d619a"
+ "052a0b3409306c629575c00f");
+
+ SHA256TestCase t_32_SHA256ShortMsg("t 32 SHA256ShortMsg",
+ dehex("0df1cd526b5a4edd"), "47f527210d6e8f940b5082fec01b7305908fa2b4"
+ "9ea3ae597c19a3986097153c");
+
+ SHA256TestCase t_35_SHA256ShortMsg("t 35 SHA256ShortMsg",
+ dehex("b80233e2c53ab32cc3"), "c60d239cc6da3ad31f4de0c2d58a73ccf3f9279e"
+ "504fa60ad55a31dcf686f3ca");
+
+ SHA256TestCase t_38_SHA256ShortMsg("t 38 SHA256ShortMsg",
+ dehex("5d54ed5b52d879aeb5dd"), "e0164d90dbfcf173bb88044fac596ccd03b8d247"
+ "c79907aaa5701767fad7b576");
+
+ SHA256TestCase t_41_SHA256ShortMsg("t 41 SHA256ShortMsg",
+ dehex("df866ecb67ab00515f6247"), "dc990ef3109a7bcf626199db9ab7801213ceb0ad"
+ "2ee398963b5061e39c05c7b5");
+
+ SHA256TestCase t_44_SHA256ShortMsg("t 44 SHA256ShortMsg",
+ dehex("0757de9485a2eaea51126077"), "c1c9a4daadcc8678835872c7f1f8824376ac7b41"
+ "2e1fc2285069b41afd51397e");
+
+ SHA256TestCase t_47_SHA256ShortMsg("t 47 SHA256ShortMsg",
+ dehex("7c66f5d443c11cfb39dd0aa715"), "6840619417b4d8ecaa7902f8eaf2e82be2638dec"
+ "97cb7e8fcc377007cc176718");
+
+ SHA256TestCase t_50_SHA256ShortMsg("t 50 SHA256ShortMsg",
+ dehex("329624fed35639fe54957b7d47a9"), "0f5308ff22b828e18bd65afbc427e3c1a6789628"
+ "32519df5f2f803f68f55e10b");
+
+ SHA256TestCase t_53_SHA256ShortMsg("t 53 SHA256ShortMsg",
+ dehex("c34e59652acc043873ecf6a4ab1060"), "0fdf1604ac0d717ec9587b4de5444aaade807589"
+ "d90eb326eaf6acb58a051e79");
+
+ SHA256TestCase t_56_SHA256ShortMsg("t 56 SHA256ShortMsg",
+ dehex("fdf4700984ee11b70af1880d0e0fefd4"), "b01ae16eed3b4a770f127b98469ba26fe3d8e9f5"
+ "9d8a2983214afe6cff0e6b6c");
+
+ SHA256TestCase t_59_SHA256ShortMsg("t 59 SHA256ShortMsg",
+ dehex("ea40aadbefedb0e0d78d067c6cd65c2c87"), "36157bbe61931d58a3a644953eaf131bbc2591c6"
+ "73a1f20353f51ca5054fc1c2");
+
+ SHA256TestCase t_62_SHA256ShortMsg("t 62 SHA256ShortMsg",
+ dehex("6d1092004670efab3af483d265d8e7b3da73"), "67fbf35d360d72b101410794ccf197106c0e784a"
+ "fa9c80206a550b600dbf1f16");
+
+ SHA256TestCase t_65_SHA256ShortMsg("t 65 SHA256ShortMsg",
+ dehex("55a10148ae7b09ac4e71df438135bc70e873eb"), "cbe7965513af46dfd596dc5839cb82a5c6c73280"
+ "34b1dd0042a9f4b71fb14430");
+
+ SHA256TestCase t_68_SHA256ShortMsg("t 68 SHA256ShortMsg",
+ dehex("a03f8fcd777bd933b4b0af8c5ce3d61308565649"), "ddfce4e8c7b38845e2a81b7fc27a06366467a9e1"
+ "11316014013f9701e2413ce0");
+
+ SHA256TestCase t_71_SHA256ShortMsg("t 71 SHA256ShortMsg",
+ dehex("8e5d6cba8d4b206381e33ca7339bec504f3d6119"
+ "ba"), "92f678a3e59d0dd3610eec3222b8c6ebd28eead5"
+ "30723fbd226747534da22b6c");
+
+ SHA256TestCase t_74_SHA256ShortMsg("t 74 SHA256ShortMsg",
+ dehex("96db1b62eed85f2628d0c25da534401fe80d13d0"
+ "9beb"), "725bab4457c789d6a4cc4736b9c2c662cda18407"
+ "150844d74d6aa4efd72dbb05");
+
+ SHA256TestCase t_77_SHA256ShortMsg("t 77 SHA256ShortMsg",
+ dehex("1c482a45dfbcda549729126b533477edfaf7476f"
+ "de498f"), "6523f24f225b996aad1a8b317e6e0f8e97673dcf"
+ "f3fd62a27ff9f3888ea1302d");
+
+ SHA256TestCase t_80_SHA256ShortMsg("t 80 SHA256ShortMsg",
+ dehex("0f677d8e4c6d6a057492670d99adb870adf68a36"
+ "ead37919"), "44acbbc6b48bf37ee088b9c8546fc46e5a5f0d63"
+ "7b5e444f628de186144087fd");
+
+ SHA256TestCase t_83_SHA256ShortMsg("t 83 SHA256ShortMsg",
+ dehex("c09056d597816542bffe4bb33e475dfb2d629301"
+ "6906ddc18c"), "f4baeaef70588a0820d63c2401dd84f98adf7366"
+ "782d196f8698d7dfd3db1c29");
+
+ SHA256TestCase t_86_SHA256ShortMsg("t 86 SHA256ShortMsg",
+ dehex("72f313fdcf52d0749c9937cc2e53f50b44d65a54"
+ "4876bab7d2f8"), "cfa67aa52fd675fca985f69f9ca58af62baead8c"
+ "39723bb6bfbae8a5d4bb9beb");
+
+ SHA256TestCase t_89_SHA256ShortMsg("t 89 SHA256ShortMsg",
+ dehex("09f6fe6cbe6744149f792a4a827e4e8909627abf"
+ "75301bf7bbd7f5"), "657633891dc6274d6aeda78e7313dfb960eac9a2"
+ "4d29293a057b9746a18de4ec");
+
+ SHA256TestCase t_92_SHA256ShortMsg("t 92 SHA256ShortMsg",
+ dehex("9e1cfeb335bc331744247df4bbd56876a7f69298"
+ "aaf6b9e7a8731889"), "930058dd21cb48b2cf90eaca55322ddf48582687"
+ "838a584928440504a2fde578");
+
+ SHA256TestCase t_95_SHA256ShortMsg("t 95 SHA256ShortMsg",
+ dehex("b8913001efb1b7f4bd975e349c5b2cbe66045bf0"
+ "d2fb019b3bc0f059a4"), "a0eb0b7fad1d1b6de4f9096724a621720538a9c3"
+ "f2f6d11134d68cb9ee52fc88");
+
+ SHA256TestCase t_98_SHA256ShortMsg("t 98 SHA256ShortMsg",
+ dehex("8f08537d50928c911a68b071d65b9e8f038264d3"
+ "b62c5f33de18a484cde9"), "10aad5cd4484387373577a881974f1a550782108"
+ "bc88b4e2e8085e9c3e938bbb");
+
+ SHA256TestCase t_101_SHA256ShortMsg("t 101 SHA256ShortMsg",
+ dehex("fd846162c4da936d004ffe0cbe844d940f1c2953"
+ "157cf4765dceba2a6f4c64"), "c13ba769aea0e478816f2f608b5cec3fe14672ea"
+ "033088a8641cfe69b4ff57cb");
+
+ SHA256TestCase t_104_SHA256ShortMsg("t 104 SHA256ShortMsg",
+ dehex("8cf53d90077df9a043bf8d10b470b144784411c9"
+ "3a4d504556834dae3ea4a5bb"), "56059e8cb3c2978b198208bf5ca1e1ea5659b737"
+ "a506324b7cec75b5ebaf057d");
+
+ SHA256TestCase t_107_SHA256ShortMsg("t 107 SHA256ShortMsg",
+ dehex("1bbc2b15253c126e301f9f64b97be4ce13e96337"
+ "687e2e78fbfd4c8daf4a5fa1cd"), "d973b5dcdae4cf2599f4db4068e4aa354f22d890"
+ "1adc463ca3938c465578147b");
+
+ SHA256TestCase t_110_SHA256ShortMsg("t 110 SHA256ShortMsg",
+ dehex("c1bdb3bfc65dfe9a393331266c58d05fb9c8b747"
+ "6bb717dadc29bc43dabd91504fc9"), "57844e1d762e6b7bb86dbfcc5c5a59578d39cc66"
+ "5d1ddbe4de03a61778061af1");
+
+ SHA256TestCase t_113_SHA256ShortMsg("t 113 SHA256ShortMsg",
+ dehex("26eb621a45bd9c9c764ccbb672b99f2a8379c7bb"
+ "f4fb07eec58a8b0ea4747b72196ccf"), "73dc27bd45daccd0f811381230cf7f2a1d3ed120"
+ "2e9a770af733146b1e166315");
+
+ SHA256TestCase t_116_SHA256ShortMsg("t 116 SHA256ShortMsg",
+ dehex("7e3e3986109162e0c56357048bbd86ff49b93644"
+ "b7fb064e7280968650978466f02c9adf"), "682c474799f5103252c3e2efef7f747783e514b5"
+ "4e93b8303b0e07ee4218f78e");
+
+ SHA256TestCase t_119_SHA256ShortMsg("t 119 SHA256ShortMsg",
+ dehex("763c1a9ea50bd72bfc516989ddf3eff2f208f64f"
+ "ccea3cf0ca8dba7f3d10e237c99226510f"), "54d6cb2b09825eab064c8952113b9897a3344737"
+ "cd186a8e6be0a0b258da3e57");
+
+ SHA256TestCase t_122_SHA256ShortMsg("t 122 SHA256ShortMsg",
+ dehex("e1a7ffea8417e7cd49b96e355fd44f3f7a150fab"
+ "6dd8343dfba3b262eaf3a6175a3c4607552b"), "83baa80caade404c446833ecef2e595bba6dce2c"
+ "b7f7422fad2972a9fe327aca");
+
+ SHA256TestCase t_125_SHA256ShortMsg("t 125 SHA256ShortMsg",
+ dehex("692a18effad8317a11a5cddb917f7389e1be6dba"
+ "34572a300e52e056047e758bc363a0be53784c"), "0c0c6a6b27a6d7a7a5130d70db3b8bc1bd8001d1"
+ "03efe72f45b082cadbd03742");
+
+ SHA256TestCase t_128_SHA256ShortMsg("t 128 SHA256ShortMsg",
+ dehex("73fda1e1cb7dc9a9ece858d040d7105cc126eab1"
+ "53fb0bb55703f4317dfff97bd980f4523aee3a09"), "9878f8804e00828b39261843f2b3eda19a7e9b9f"
+ "f4cc2e23f7ea1f62f4491ff2");
+
+ SHA256TestCase t_131_SHA256ShortMsg("t 131 SHA256ShortMsg",
+ dehex("2321d88c19e3e6a8309a09a5428c01991e164468"
+ "23f13b2f0db4ade30e9a7c3521868fb99b440f48"
+ "02"), "f1bd3a8a74c8f0093038499ef63794d86fc6d826"
+ "02a802a435718e61e7b396cc");
+
+ SHA256TestCase t_134_SHA256ShortMsg("t 134 SHA256ShortMsg",
+ dehex("b9eaebda29172b052bcc1e3a9c7f2eced43c084a"
+ "86f89f61e7237425137c167aac29e4cac4071afa"
+ "fd3f"), "ea43ec91285145d8f29915b227a0e35c89f90d96"
+ "8f9a14332dad275cfd52d619");
+
+ SHA256TestCase t_137_SHA256ShortMsg("t 137 SHA256ShortMsg",
+ dehex("332daf07d3a6775b18572549a6e12b8a27d81b7c"
+ "4abcc5bd0b2b9ff936546b0026af131cd3ecd8a1"
+ "0c29ab"), "a573959ba6b1c3bebfd6288c806b72a65650d23b"
+ "d46d123816a2a6a0e47d1e66");
+
+ SHA256TestCase t_140_SHA256ShortMsg("t 140 SHA256ShortMsg",
+ dehex("30ac7eace1f2e41034c25a3d3e2db979c23dfaa7"
+ "a4914b0da147625b3e1f12e9fedc1c41d8ee47dd"
+ "e84fb332"), "c0c3f40d34e711bfadf517b3a78140e379fba5f7"
+ "edf2c1bc3ce82469dae4d2d5");
+
+ SHA256TestCase t_143_SHA256ShortMsg("t 143 SHA256ShortMsg",
+ dehex("02c3964c4ad9c4af97d373099302c2cd770ad06c"
+ "7d8bd11c970161d861e917a854265e223da28031"
+ "ee38041534"), "c13c622bf08a3d3cf1fd6fa5e26e505e551b1643"
+ "bc5a0f59ed29541235218f77");
+
+ SHA256TestCase t_146_SHA256ShortMsg("t 146 SHA256ShortMsg",
+ dehex("b9eed82edcf0c7ba69f6f6ac5722cb61daecaf30"
+ "437511582117ad36ad410ebc6582511ef6e32dce"
+ "5f7a30ab543c"), "6ac64caaeda4763d28a44b363823a6b819285410"
+ "fb4162af6ca657396f6028d0");
+
+ SHA256TestCase t_149_SHA256ShortMsg("t 149 SHA256ShortMsg",
+ dehex("b574865024828bf651df070ac0cec1849aa64709"
+ "01d2e30fa01dcb43862d9827344cf900f46fa9ef"
+ "6d709e5e759f84"), "4c839e8f8f373c25a9a3351257c6152258ff8e6a"
+ "88dad42f30f2bbecab56c20b");
+
+ SHA256TestCase t_152_SHA256ShortMsg("t 152 SHA256ShortMsg",
+ dehex("eebcf5cd6b12c90db64ff71a0e08ccd956e170a5"
+ "0dad769480d6b1fb3eff4934cde90f9e9b930ee6"
+ "37a66285c10f4e8a"), "c117b9dce689c399ec99008788cd5d24d8396fab"
+ "7d96315c4f3fe6d56da63bb3");
+
+ SHA256TestCase t_155_SHA256ShortMsg("t 155 SHA256ShortMsg",
+ dehex("1b7a73770d168da45bf2e512eee45153e02f4dfe"
+ "3b42e50304a3d63d7826f0469562be8fdc6569b0"
+ "56a7dafcd53d1f597c"), "0b42cfc3dd3d3198f06c30e087837ec6a6dd35d0"
+ "8e54e886c682709f8f42457a");
+
+ SHA256TestCase t_158_SHA256ShortMsg("t 158 SHA256ShortMsg",
+ dehex("0072ae2f3bda67736b9c66e2130260b3a4847bc3"
+ "968e037cb6835efcc2014273336725cd5a94f592"
+ "aef20a0a65b459a4415b"), "217cf25b8b343c28336b1c1e9bed29e0c96045bc"
+ "93daf426e490b608b0905c90");
+
+ SHA256TestCase t_161_SHA256ShortMsg("t 161 SHA256ShortMsg",
+ dehex("2ac748680f3bc1bf098c4be38c7194643b0d009e"
+ "51c43630404cdfaf9807aa9b299094916c9466c3"
+ "1fe37fa630c6d3eadc9434"), "3ea59e2e79513679a22e962f22408306f7e8f6e5"
+ "62c2f1f210e279fad8eaacc6");
+
+ SHA256TestCase t_164_SHA256ShortMsg("t 164 SHA256ShortMsg",
+ dehex("893d1a8863d234ee50e5a8c7650a4de047230ad0"
+ "3d268dde8921401ff97b79dfb97cf2426b0f782b"
+ "79c7e75daa2155e1f4098ea7"), "f7808e03e5d5af43c2bffb66e35d1ecbd79f4d8f"
+ "ec44f821f73a235d17c70a89");
+
+ SHA256TestCase t_167_SHA256ShortMsg("t 167 SHA256ShortMsg",
+ dehex("cf673b96eaf241cfa3e262dc6fe65f08bcc2be56"
+ "d8a2c9710eaddae212ded6859f0ff83e5e57d0e8"
+ "0a968b8ed24e74defeb5bbdad6"), "9bdb7cf0492ace4620a47660acd127f951767b07"
+ "38b5504451d6ed56e4fa3cbd");
+
+ SHA256TestCase t_170_SHA256ShortMsg("t 170 SHA256ShortMsg",
+ dehex("0d545be1f47b966214691c21278704e89a17d52d"
+ "d96aeeeacc5325a9a1ddafdecd39407a4dfa72bd"
+ "32856b4c5cc2ba838618830c8399"), "ad53e0db7e63211c8b00947908ce29660c4376e2"
+ "44e19cd30a659af65dc6f1fe");
+
+ SHA256TestCase t_173_SHA256ShortMsg("t 173 SHA256ShortMsg",
+ dehex("9eabfcd3603337df3dcd119d6287a9bc8bb94d65"
+ "0ef29bcf1b32e60d425adc2a35e06577d0c7ce24"
+ "56cf260efee9e8d8aeeddb3d068f37"), "83eeed2dfeb8d2604ab5ec1ac9b5dcab8cc22225"
+ "18468bc5c24c16ce72e70687");
+
+ SHA256TestCase t_176_SHA256ShortMsg("t 176 SHA256ShortMsg",
+ dehex("2fc7b9e8b8dcaac64ecef4c5f91877543ac36ae4"
+ "94d9faf84b1d347b6cf925570db84043d6f500dc"
+ "c153cef81d6f2437d913f3dbffad42d9"), "6ef7e9f12267ebc4901267da147effdcdebcd6ec"
+ "5393c7f62ec4c4f06ca72649");
+
+ SHA256TestCase t_179_SHA256ShortMsg("t 179 SHA256ShortMsg",
+ dehex("cf95929ab732f9ef5e8c3e6b4ed753852ee74e4f"
+ "ddf31b56c29a6ec95d23fcde2209eb7288b787f0"
+ "5d9036735c32ae2f01fc650d9cce4995a5"), "3e5854169da065407fa465a4694f3fcb1d141480"
+ "a8f84c970a0f63364ec8f590");
+
+ SHA256TestCase t_182_SHA256ShortMsg("t 182 SHA256ShortMsg",
+ dehex("826378013988684c40f4d917c7ed8b72aba66fd6"
+ "8f085d0b2eb20948ef3f349dbbc71f8e0ba84501"
+ "4586495a48902ee44505c673d2f76d473950"), "5b506b823ef6658939aca22f52bbe5a4b849c31b"
+ "8fa1d09139352e501137bc04");
+
+ SHA256TestCase t_185_SHA256ShortMsg("t 185 SHA256ShortMsg",
+ dehex("0cab6d38ce9849fcbd589f7235a6d2c2cb933e26"
+ "e1ca6f4e78189104452c280c069b024e16276937"
+ "3f409d5cd0cb8160f0239418325d23ee6ad1bd"), "92943076cda4c46718e55df64d7580e12b8fb2c2"
+ "911e87851246ccf6791fa3e6");
+
+ SHA256TestCase t_188_SHA256ShortMsg("t 188 SHA256ShortMsg",
+ dehex("3fb4a8c5b57c14731179256608614c95c9725dda"
+ "d5fbfa99111d4fa319d3015ad830601556e8e4c6"
+ "d012d7da0e2c4f60f1605f6e4c058ec0f46988a3"), "8e90da3eb146935264576f874fcc5a64b7a90ab6"
+ "c8a36c15d855b0179f52f899");
+
+ SHA256TestCase t_191_SHA256ShortMsg("t 191 SHA256ShortMsg",
+ dehex("9050a6d002c90f6036c592b0f6b866713e7894d2"
+ "9645f4a19e0858b3ebd8078711c26d2601ca104d"
+ "962dc6ce6ae92634ee7f3ca6baf8810e2126097a"
+ "09"), "03c516677735ae83dbe5a7e4c22c1ac1bfedcd46"
+ "e7dd785f8bfe38e148eda632");
+
+ SHA256TestCase t_194_SHA256ShortMsg("t 194 SHA256ShortMsg",
+ dehex("d659ec136bacfa0b5c906aabedc93c01c5f1efa3"
+ "f370a1432ea8778461703f0c67c454da12bac2da"
+ "73b8abb755e5eaf10bddf52f6ca908d61bee80da"
+ "0c64"), "fff2852957a0eeb577e73fd7d827f650261dfb9a"
+ "8a65f52df4bbbc9b2d0ae50e");
+
+ SHA256TestCase t_197_SHA256ShortMsg("t 197 SHA256ShortMsg",
+ dehex("b498555658332b197bc5cb7adc5c1997aabbdcf1"
+ "f7ffcc2b6b82eb0f350019d247f8e399c3559d3b"
+ "b04eb049f28b344c7989c24db83f839b59028dc8"
+ "2fa670"), "bfbbf242f79bff4ae0aafb4ccf69b24fdca4342d"
+ "83db1dfd1822c74a9e218e8d");
+
+ SHA256TestCase t_200_SHA256ShortMsg("t 200 SHA256ShortMsg",
+ dehex("3592ecfd1eac618fd390e7a9c24b656532509367"
+ "c21a0eac1212ac83c0b20cd896eb72b801c4d212"
+ "c5452bbbf09317b50c5c9fb1997553d2bbc29bb4"
+ "2f5748ad"), "105a60865830ac3a371d3843324d4bb5fa8ec0e0"
+ "2ddaa389ad8da4f10215c454");
+
+ /**
+ * \}
+ */
+}
+
diff --git a/0.8.0/paludis/ebin.cc b/0.8.0/paludis/ebin.cc
new file mode 100644
index 0000000..1c1b664
--- /dev/null
+++ b/0.8.0/paludis/ebin.cc
@@ -0,0 +1,212 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/ebin.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/pstream.hh>
+#include <paludis/util/log.hh>
+#include <paludis/environment.hh>
+#include <paludis/config_file.hh>
+#include <paludis/portage_dep_parser.hh>
+#include <sys/resource.h>
+#include <sys/time.h>
+
+/** \file
+ * Implementation for ebin.hh things.
+ *
+ * \ingroup grpebininterface
+ */
+
+using namespace paludis;
+
+#include <paludis/ebin-sr.cc>
+
+EbinCommand::EbinCommand(const EbinCommandParams & p) :
+ params(p)
+{
+}
+
+EbinCommand::~EbinCommand()
+{
+}
+
+bool
+EbinCommand::success()
+{
+ return true;
+}
+
+bool
+EbinCommand::use_sandbox() const
+{
+ return true;
+}
+
+bool
+EbinCommand::failure()
+{
+ return false;
+}
+
+bool
+EbinCommand::operator() ()
+{
+ std::string ebin_cmd(getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis") +
+ "/ebuild.bash '" +
+ stringify(params.ebin_dir) + "/" +
+ stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version) +
+ ".ebin' " + commands());
+
+ if (use_sandbox())
+ ebin_cmd = make_sandbox_command(ebin_cmd);
+
+ MakeEnvCommand cmd(extend_command(make_env_command(ebin_cmd)
+ ("P", stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version.remove_revision()))
+ ("PV", stringify(params.db_entry->version.remove_revision()))
+ ("PR", stringify(params.db_entry->version.revision_only()))
+ ("PN", stringify(params.db_entry->name.package))
+ ("PVR", stringify(params.db_entry->version))
+ ("PF", stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version))
+ ("CATEGORY", stringify(params.db_entry->name.category))
+ ("REPOSITORY", stringify(params.db_entry->repository))
+ ("SRC_REPOSITORY", stringify(params.src_repository))
+ ("PKGDIR", stringify(params.pkgdir))
+ ("PALUDIS_TMPDIR", stringify(params.buildroot))
+ ("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
+ ("PALUDIS_BASHRC_FILES", params.environment->bashrc_files())
+ ("PALUDIS_HOOK_DIRS", params.environment->hook_dirs())
+ ("PALUDIS_COMMAND", params.environment->paludis_command())
+ ("KV", kernel_version())
+ ("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))));
+
+ if (do_run_command(add_portage_vars(cmd)))
+ return success();
+ else
+ return failure();
+}
+
+MakeEnvCommand
+EbinCommand::add_portage_vars(const MakeEnvCommand & cmd) const
+{
+ return cmd
+ ("PORTAGE_BASHRC", "/dev/null")
+ ("PORTAGE_BUILDDIR", stringify(params.buildroot) + "/" +
+ stringify(params.db_entry->name.category) + "/" +
+ stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version))
+ ("PORTAGE_CALLER", params.environment->paludis_command())
+ ("PORTAGE_GID", "0")
+ ("PORTAGE_INST_GID", "0")
+ ("PORTAGE_INST_UID", "0")
+ ("PORTAGE_MASTER_PID", stringify(::getpid()))
+ ("PORTAGE_NICENCESS", stringify(::getpriority(PRIO_PROCESS, 0)))
+ ("PORTAGE_TMPDIR", stringify(params.buildroot))
+ ("PORTAGE_TMPFS", "/dev/shm")
+ ("PORTAGE_WORKDIR_MODE", "0700");
+}
+
+bool
+EbinCommand::do_run_command(const std::string & cmd)
+{
+ return 0 == run_command(cmd);
+}
+
+std::string
+EbinFetchCommand::commands() const
+{
+ return "fetch_bin";
+}
+
+bool
+EbinFetchCommand::failure()
+{
+ throw PackageFetchActionError("Fetch failed for '" + stringify(
+ *params.db_entry) + "'");
+}
+
+MakeEnvCommand
+EbinFetchCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ MakeEnvCommand result(cmd
+ ("B", fetch_params.b)
+ ("FLAT_BIN_URI", fetch_params.flat_bin_uri)
+ ("ROOT", fetch_params.root)
+ ("PALUDIS_PROFILE_DIR", stringify(*fetch_params.profiles->begin()))
+ ("PALUDIS_PROFILE_DIRS", join(fetch_params.profiles->begin(),
+ fetch_params.profiles->end(), " ")));
+
+ return result;
+}
+
+EbinFetchCommand::EbinFetchCommand(const EbinCommandParams & p,
+ const EbinFetchCommandParams & f) :
+ EbinCommand(p),
+ fetch_params(f)
+{
+}
+
+std::string
+EbinInstallCommand::commands() const
+{
+ return "init_bin unpack_bin setup strip preinst merge postinst tidyup";
+}
+
+bool
+EbinInstallCommand::failure()
+{
+ throw PackageInstallActionError("Install failed for '" + stringify(
+ *params.db_entry) + "'");
+}
+
+MakeEnvCommand
+EbinInstallCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ MakeEnvCommand result(cmd
+ ("B", install_params.b)
+ ("USE", install_params.use)
+ ("USE_EXPAND", install_params.use_expand)
+ ("ROOT", install_params.root)
+ ("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
+ install_params.disable_cfgpro ? "/" : "")
+ ("PALUDIS_PROFILE_DIR", stringify(*install_params.profiles->begin()))
+ ("PALUDIS_PROFILE_DIRS", join(install_params.profiles->begin(),
+ install_params.profiles->end(), " "))
+ ("SLOT", stringify(install_params.slot)));
+
+ for (AssociativeCollection<std::string, std::string>::Iterator
+ i(install_params.expand_vars->begin()),
+ j(install_params.expand_vars->end()) ; i != j ; ++i)
+ result = result(i->first, i->second);
+
+ return result;
+}
+
+EbinInstallCommand::EbinInstallCommand(const EbinCommandParams & p,
+ const EbinInstallCommandParams & f) :
+ EbinCommand(p),
+ install_params(f)
+{
+}
+
+
diff --git a/0.8.0/paludis/ebin.hh b/0.8.0/paludis/ebin.hh
new file mode 100644
index 0000000..51a470e
--- /dev/null
+++ b/0.8.0/paludis/ebin.hh
@@ -0,0 +1,175 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_EBIN_HH
+#define PALUDIS_GUARD_PALUDIS_EBIN_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/sr.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/util/collection.hh>
+#include <paludis/package_database.hh>
+#include <string>
+
+/** \file
+ * Declarations for the EbinCommand classes.
+ *
+ * \ingroup grpebininterface
+ */
+
+namespace paludis
+{
+ class Environment;
+ class MakeEnvCommand;
+
+#include <paludis/ebin-sr.hh>
+
+ /**
+ * An EbinCommand is the base class from which specific ebin
+ * command interfaces are descended.
+ *
+ * \ingroup grpebininterface
+ */
+ class EbinCommand :
+ private InstantiationPolicy<EbinCommand, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ /**
+ * Our parameters.
+ */
+ const EbinCommandParams params;
+
+ /**
+ * Constructor.
+ */
+ EbinCommand(const EbinCommandParams &);
+
+ /**
+ * Override in descendents: which commands (for example, 'prerm
+ * unmerge postrm') do we give to ebin.bash?
+ */
+ virtual std::string commands() const = 0;
+
+ /**
+ * Actions to be taken after a successful command.
+ *
+ * The return value of this function is used for the return value
+ * of operator().
+ */
+ virtual bool success();
+
+ /**
+ * Should the sandbox, if available, be used?
+ */
+ virtual bool use_sandbox() const;
+
+ /**
+ * Actions to be taken after a failed command.
+ *
+ * The return value of this function is used for the return value
+ * of operator(). In some descendents, this function throws and
+ * does not return.
+ */
+ virtual bool failure() = 0;
+
+ /**
+ * Run the specified command. Can be overridden if, for example,
+ * the command output needs to be captured.
+ *
+ * \return Whether the command succeeded.
+ */
+ virtual bool do_run_command(const std::string &);
+
+ /**
+ * Add Portage emulation vars.
+ */
+ virtual MakeEnvCommand add_portage_vars(const MakeEnvCommand &) const;
+
+ /**
+ * Extend the command to be run.
+ */
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &) = 0;
+
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~EbinCommand();
+
+ /**
+ * Run the command.
+ */
+ virtual bool operator() ();
+ };
+
+ /**
+ * An EbinFetchCommand is used to download and verify the digests for a
+ * particular ebin in a PortageRepository. On failure it throws.
+ *
+ * \ingroup grpebininterface
+ */
+ class EbinFetchCommand :
+ public EbinCommand
+ {
+ protected:
+ /// Parameters for fetch.
+ const EbinFetchCommandParams fetch_params;
+
+ virtual std::string commands() const;
+
+ virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbinFetchCommand(const EbinCommandParams &, const EbinFetchCommandParams &);
+ };
+
+ /**
+ * An EbinInstallCommand is used to install an ebin from a
+ * PortageRepository. On failure it throws.
+ *
+ * \ingroup grpebininterface
+ */
+ class EbinInstallCommand :
+ public EbinCommand
+ {
+ protected:
+ /// Parameters for install.
+ const EbinInstallCommandParams install_params;
+
+ virtual std::string commands() const;
+
+ virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbinInstallCommand(const EbinCommandParams &, const EbinInstallCommandParams &);
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/ebin.sr b/0.8.0/paludis/ebin.sr
new file mode 100644
index 0000000..20c1837
--- /dev/null
+++ b/0.8.0/paludis/ebin.sr
@@ -0,0 +1,66 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_EbinCommandParams()
+{
+ key ebin_dir "FSEntry"
+ key environment "const Environment *"
+ key db_entry "const PackageDatabaseEntry *"
+ key src_repository "RepositoryName"
+ key pkgdir "FSEntry"
+ key buildroot "FSEntry"
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbinCommand.
+ *
+ * \see EbinCommand
+ * \ingroup grpebininterface
+ */
+END
+
+ allow_named_args
+}
+
+make_class_EbinFetchCommandParams()
+{
+ key b std::string
+ key flat_bin_uri std::string
+ key root std::string
+ key profiles FSEntryCollection::ConstPointer
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbinFetchCommand.
+ *
+ * \see EbinFetchCommand
+ * \ingroup grpebininterface
+ */
+END
+
+ allow_named_args
+}
+
+make_class_EbinInstallCommandParams()
+{
+ key b std::string
+ key use std::string
+ key use_expand std::string
+ key root std::string
+ key profiles FSEntryCollection::ConstPointer
+ key expand_vars "AssociativeCollection<std::string, std::string>::ConstPointer"
+ key disable_cfgpro bool
+ key slot SlotName
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbinInstallCommand.
+ *
+ * \see EbinInstallCommand
+ * \ingroup grpebininterface
+ */
+END
+
+ allow_named_args
+}
+
diff --git a/0.8.0/paludis/ebuild.cc b/0.8.0/paludis/ebuild.cc
new file mode 100644
index 0000000..cfabc99
--- /dev/null
+++ b/0.8.0/paludis/ebuild.cc
@@ -0,0 +1,382 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/about.hh>
+#include <paludis/ebuild.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/pstream.hh>
+#include <paludis/util/log.hh>
+#include <paludis/environment.hh>
+#include <paludis/config_file.hh>
+#include <paludis/portage_dep_parser.hh>
+#include <sys/resource.h>
+#include <sys/time.h>
+
+/** \file
+ * Implementation for ebuild.hh things.
+ *
+ * \ingroup grpebuildinterface
+ */
+
+using namespace paludis;
+
+#include <paludis/ebuild-sr.cc>
+
+EbuildCommand::EbuildCommand(const EbuildCommandParams & p) :
+ params(p)
+{
+}
+
+EbuildCommand::~EbuildCommand()
+{
+}
+
+bool
+EbuildCommand::success()
+{
+ return true;
+}
+
+bool
+EbuildCommand::use_sandbox() const
+{
+ return true;
+}
+
+bool
+EbuildCommand::failure()
+{
+ return false;
+}
+
+bool
+EbuildCommand::operator() ()
+{
+ std::string ebuild_cmd(getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis") +
+ "/ebuild.bash '" +
+ stringify(params.ebuild_dir) + "/" +
+ stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version) +
+ ".ebuild' " + commands());
+
+ if (use_sandbox())
+ ebuild_cmd = make_sandbox_command(ebuild_cmd);
+
+ MakeEnvCommand cmd(extend_command(make_env_command(ebuild_cmd)
+ ("P", stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version.remove_revision()))
+ ("PV", stringify(params.db_entry->version.remove_revision()))
+ ("PR", stringify(params.db_entry->version.revision_only()))
+ ("PN", stringify(params.db_entry->name.package))
+ ("PVR", stringify(params.db_entry->version))
+ ("PF", stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version))
+ ("CATEGORY", stringify(params.db_entry->name.category))
+ ("REPOSITORY", stringify(params.db_entry->repository))
+ ("FILESDIR", stringify(params.files_dir))
+ ("ECLASSDIR", stringify(*params.eclassdirs->begin()))
+ ("ECLASSDIRS", join(params.eclassdirs->begin(),
+ params.eclassdirs->end(), " "))
+ ("PORTDIR", stringify(params.portdir))
+ ("DISTDIR", stringify(params.distdir))
+ ("PKGMANAGER", PALUDIS_PACKAGE "-" + stringify(PALUDIS_VERSION_MAJOR) + "." +
+ stringify(PALUDIS_VERSION_MINOR) + "." +
+ stringify(PALUDIS_VERSION_MICRO) +
+ (std::string(PALUDIS_SUBVERSION_REVISION).empty() ?
+ std::string("") : "-r" + std::string(PALUDIS_SUBVERSION_REVISION)))
+ ("PALUDIS_TMPDIR", stringify(params.buildroot))
+ ("PALUDIS_CONFIG_DIR", SYSCONFDIR "/paludis/")
+ ("PALUDIS_BASHRC_FILES", params.environment->bashrc_files())
+ ("PALUDIS_HOOK_DIRS", params.environment->hook_dirs())
+ ("PALUDIS_COMMAND", params.environment->paludis_command())
+ ("KV", kernel_version())
+ ("PALUDIS_EBUILD_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))));
+
+ if (do_run_command(add_portage_vars(cmd)))
+ return success();
+ else
+ return failure();
+}
+
+MakeEnvCommand
+EbuildCommand::add_portage_vars(const MakeEnvCommand & cmd) const
+{
+ return cmd
+ ("PORTAGE_ACTUAL_DISTDIR", stringify(params.distdir))
+ ("PORTAGE_BASHRC", "/dev/null")
+ ("PORTAGE_BUILDDIR", stringify(params.buildroot) + "/" +
+ stringify(params.db_entry->name.category) + "/" +
+ stringify(params.db_entry->name.package) + "-" +
+ stringify(params.db_entry->version))
+ ("PORTAGE_CALLER", params.environment->paludis_command())
+ ("PORTAGE_GID", "0")
+ ("PORTAGE_INST_GID", "0")
+ ("PORTAGE_INST_UID", "0")
+ ("PORTAGE_MASTER_PID", stringify(::getpid()))
+ ("PORTAGE_NICENCESS", stringify(::getpriority(PRIO_PROCESS, 0)))
+ ("PORTAGE_TMPDIR", stringify(params.buildroot))
+ ("PORTAGE_TMPFS", "/dev/shm")
+ ("PORTAGE_WORKDIR_MODE", "0700");
+}
+
+bool
+EbuildCommand::do_run_command(const std::string & cmd)
+{
+ return 0 == run_command(cmd);
+}
+
+EbuildMetadataCommand::EbuildMetadataCommand(const EbuildCommandParams & p) :
+ EbuildCommand(p),
+ _metadata(0)
+{
+}
+
+std::string
+EbuildMetadataCommand::commands() const
+{
+ return "metadata";
+}
+
+bool
+EbuildMetadataCommand::failure()
+{
+ return EbuildCommand::failure();
+}
+
+MakeEnvCommand
+EbuildMetadataCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ return cmd;
+}
+
+bool
+EbuildMetadataCommand::do_run_command(const std::string & cmd)
+{
+ PStream prog(cmd);
+ KeyValueConfigFile f(&prog);
+ _metadata.assign(new VersionMetadata::Ebuild(PortageDepParser::parse_depend));
+
+ bool ok(false);
+ try
+ {
+ _metadata->deps.build_depend_string = f.get("DEPEND");
+ _metadata->deps.run_depend_string = f.get("RDEPEND");
+ _metadata->slot = SlotName(f.get("SLOT"));
+ _metadata->get_ebuild_interface()->src_uri = f.get("SRC_URI");
+ _metadata->get_ebuild_interface()->restrict_string = f.get("RESTRICT");
+ _metadata->homepage = f.get("HOMEPAGE");
+ _metadata->license_string = f.get("LICENSE");
+ _metadata->description = f.get("DESCRIPTION");
+ _metadata->get_ebuild_interface()->keywords = f.get("KEYWORDS");
+ _metadata->get_ebuild_interface()->eclass_keywords = f.get("E_KEYWORDS");
+ _metadata->get_ebuild_interface()->inherited = f.get("INHERITED");
+ _metadata->get_ebuild_interface()->iuse = f.get("IUSE");
+ _metadata->deps.post_depend_string = f.get("PDEPEND");
+ _metadata->get_ebuild_interface()->provide_string = f.get("PROVIDE");
+ _metadata->eapi = f.get("EAPI");
+
+ if (0 == prog.exit_status())
+ ok = true;
+ }
+ catch (const NameError & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Caught exception '" +
+ stringify(e.message()) + "' (" + stringify(e.what()) +
+ ") when generating cache for '" + stringify(*params.db_entry) + "'");
+ }
+
+ if (ok)
+ return true;
+ else
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Could not generate cache for '"
+ + stringify(*params.db_entry) + "'");
+ _metadata->eapi = "UNKNOWN";
+
+ return false;
+ }
+}
+
+EbuildVariableCommand::EbuildVariableCommand(const EbuildCommandParams & p,
+ const std::string & var) :
+ EbuildCommand(p),
+ _var(var)
+{
+}
+
+std::string
+EbuildVariableCommand::commands() const
+{
+ return "variable";
+}
+
+bool
+EbuildVariableCommand::failure()
+{
+ return EbuildCommand::failure();
+}
+
+MakeEnvCommand
+EbuildVariableCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ return cmd("PALUDIS_VARIABLE", _var);
+}
+
+bool
+EbuildVariableCommand::do_run_command(const std::string & cmd)
+{
+ PStream prog(cmd);
+ _result = strip_trailing_string(
+ std::string((std::istreambuf_iterator<char>(prog)),
+ std::istreambuf_iterator<char>()), "\n");
+
+ return (0 == prog.exit_status());
+}
+
+std::string
+EbuildFetchCommand::commands() const
+{
+ if (fetch_params.no_fetch)
+ return "nofetch";
+ else
+ return "fetch";
+}
+
+bool
+EbuildFetchCommand::failure()
+{
+ throw PackageFetchActionError("Fetch failed for '" + stringify(
+ *params.db_entry) + "'");
+}
+
+MakeEnvCommand
+EbuildFetchCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ MakeEnvCommand result(cmd
+ ("A", fetch_params.a)
+ ("AA", fetch_params.aa)
+ ("USE", fetch_params.use)
+ ("USE_EXPAND", fetch_params.use_expand)
+ ("FLAT_SRC_URI", fetch_params.flat_src_uri)
+ ("ROOT", fetch_params.root)
+ ("PALUDIS_PROFILE_DIR", stringify(*fetch_params.profiles->begin()))
+ ("PALUDIS_PROFILE_DIRS", join(fetch_params.profiles->begin(),
+ fetch_params.profiles->end(), " ")));
+
+ for (AssociativeCollection<std::string, std::string>::Iterator
+ i(fetch_params.expand_vars->begin()),
+ j(fetch_params.expand_vars->end()) ; i != j ; ++i)
+ result = result(i->first, i->second);
+
+ return result;
+}
+
+EbuildFetchCommand::EbuildFetchCommand(const EbuildCommandParams & p,
+ const EbuildFetchCommandParams & f) :
+ EbuildCommand(p),
+ fetch_params(f)
+{
+}
+
+std::string
+EbuildInstallCommand::commands() const
+{
+ return "init setup unpack compile test install strip preinst "
+ "merge postinst tidyup";
+}
+
+bool
+EbuildInstallCommand::failure()
+{
+ throw PackageInstallActionError("Install failed for '" + stringify(
+ *params.db_entry) + "'");
+}
+
+MakeEnvCommand
+EbuildInstallCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ MakeEnvCommand result(cmd
+ ("A", install_params.a)
+ ("AA", install_params.aa)
+ ("USE", install_params.use)
+ ("USE_EXPAND", install_params.use_expand)
+ ("ROOT", install_params.root)
+ ("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
+ install_params.disable_cfgpro ? "/" : "")
+ ("PALUDIS_PROFILE_DIR", stringify(*install_params.profiles->begin()))
+ ("PALUDIS_PROFILE_DIRS", join(install_params.profiles->begin(),
+ install_params.profiles->end(), " "))
+ ("SLOT", stringify(install_params.slot)));
+
+ for (AssociativeCollection<std::string, std::string>::Iterator
+ i(install_params.expand_vars->begin()),
+ j(install_params.expand_vars->end()) ; i != j ; ++i)
+ result = result(i->first, i->second);
+
+ return result;
+}
+
+EbuildInstallCommand::EbuildInstallCommand(const EbuildCommandParams & p,
+ const EbuildInstallCommandParams & f) :
+ EbuildCommand(p),
+ install_params(f)
+{
+}
+
+std::string
+EbuildUninstallCommand::commands() const
+{
+ if (uninstall_params.unmerge_only)
+ return "unmerge";
+ else
+ return "prerm unmerge postrm";
+}
+
+bool
+EbuildUninstallCommand::failure()
+{
+ throw PackageUninstallActionError("Uninstall failed for '" + stringify(
+ *params.db_entry) + "'");
+}
+
+MakeEnvCommand
+EbuildUninstallCommand::extend_command(const MakeEnvCommand & cmd)
+{
+ MakeEnvCommand result(cmd
+ ("ROOT", uninstall_params.root)
+ ("PALUDIS_EBUILD_OVERRIDE_CONFIG_PROTECT_MASK",
+ uninstall_params.disable_cfgpro ? "/" : ""));
+
+ if (uninstall_params.load_environment)
+ result = result
+ ("PALUDIS_LOAD_ENVIRONMENT", stringify(*uninstall_params.load_environment))
+ ("PALUDIS_SKIP_INHERIT", "yes");
+
+ return result;
+}
+
+EbuildUninstallCommand::EbuildUninstallCommand(const EbuildCommandParams & p,
+ const EbuildUninstallCommandParams & f) :
+ EbuildCommand(p),
+ uninstall_params(f)
+{
+}
+
diff --git a/0.8.0/paludis/ebuild.hh b/0.8.0/paludis/ebuild.hh
new file mode 100644
index 0000000..b09a16a
--- /dev/null
+++ b/0.8.0/paludis/ebuild.hh
@@ -0,0 +1,293 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_EBUILD_HH
+#define PALUDIS_GUARD_PALUDIS_EBUILD_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/util/collection.hh>
+#include <paludis/package_database.hh>
+#include <string>
+
+/** \file
+ * Declarations for the EbuildCommand classes.
+ *
+ * \ingroup grpebuildinterface
+ */
+
+namespace paludis
+{
+ /**
+ * Keys for EbuildCommandParams.
+ *
+ * \see EbuildCommandParams
+ *
+ * \ingroup grpebuildinterface
+ */
+ enum EbuildCommandParamsKeys
+ {
+ ecpk_environment,
+ ecpk_db_entry,
+ ecpk_ebuild_dir,
+ ecpk_files_dir,
+ ecpk_eclassdirs,
+ ecpk_portdir,
+ ecpk_distdir,
+ ecpk_buildroot,
+ last_ecpk
+ };
+
+ class Environment;
+ class MakeEnvCommand;
+
+#include <paludis/ebuild-sr.hh>
+
+ /**
+ * An EbuildCommand is the base class from which specific ebuild
+ * command interfaces are descended.
+ *
+ * \ingroup grpebuildinterface
+ */
+ class EbuildCommand :
+ private InstantiationPolicy<EbuildCommand, instantiation_method::NonCopyableTag>
+ {
+ protected:
+ /**
+ * Our parameters.
+ */
+ const EbuildCommandParams params;
+
+ /**
+ * Constructor.
+ */
+ EbuildCommand(const EbuildCommandParams &);
+
+ /**
+ * Override in descendents: which commands (for example, 'prerm
+ * unmerge postrm') do we give to ebuild.bash?
+ */
+ virtual std::string commands() const = 0;
+
+ /**
+ * Actions to be taken after a successful command.
+ *
+ * The return value of this function is used for the return value
+ * of operator().
+ */
+ virtual bool success();
+
+ /**
+ * Should the sandbox, if available, be used?
+ */
+ virtual bool use_sandbox() const;
+
+ /**
+ * Actions to be taken after a failed command.
+ *
+ * The return value of this function is used for the return value
+ * of operator(). In some descendents, this function throws and
+ * does not return.
+ */
+ virtual bool failure() = 0;
+
+ /**
+ * Run the specified command. Can be overridden if, for example,
+ * the command output needs to be captured.
+ *
+ * \return Whether the command succeeded.
+ */
+ virtual bool do_run_command(const std::string &);
+
+ /**
+ * Add Portage emulation vars.
+ */
+ virtual MakeEnvCommand add_portage_vars(const MakeEnvCommand &) const;
+
+ /**
+ * Extend the command to be run.
+ */
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &) = 0;
+
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~EbuildCommand();
+
+ /**
+ * Run the command.
+ */
+ virtual bool operator() ();
+ };
+
+ /**
+ * An EbuildMetadataCommand is used to generate metadata for a particular
+ * ebuild in a PortageRepository.
+ *
+ * \ingroup grpebuildinterface
+ */
+ class EbuildMetadataCommand :
+ public EbuildCommand
+ {
+ private:
+ VersionMetadata::Ebuild::Pointer _metadata;
+
+ protected:
+ virtual std::string commands() const;
+
+ virtual bool failure();
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ virtual bool do_run_command(const std::string &);
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbuildMetadataCommand(const EbuildCommandParams &);
+
+ /**
+ * Return a pointer to our generated metadata. If operator() has not
+ * yet been called, will be a zero pointer.
+ */
+ VersionMetadata::Pointer metadata() const
+ {
+ return _metadata;
+ }
+ };
+
+ /**
+ * An EbuildVariableCommand is used to fetch the value of an environment
+ * variable for a particular ebuild in a PortageRepository.
+ *
+ * \ingroup grpebuildinterface
+ */
+ class EbuildVariableCommand :
+ public EbuildCommand
+ {
+ private:
+ std::string _result;
+ const std::string _var;
+
+ protected:
+ virtual std::string commands() const;
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ virtual bool do_run_command(const std::string &);
+
+ virtual bool failure();
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbuildVariableCommand(const EbuildCommandParams &, const std::string &);
+
+ /**
+ * Fetch our result.
+ */
+ std::string result() const
+ {
+ return _result;
+ }
+ };
+
+ /**
+ * An EbuildFetchCommand is used to download and verify the digests for a
+ * particular ebuild in a PortageRepository. On failure it throws.
+ *
+ * \ingroup grpebuildinterface
+ */
+ class EbuildFetchCommand :
+ public EbuildCommand
+ {
+ protected:
+ /// Parameters for fetch.
+ const EbuildFetchCommandParams fetch_params;
+
+ virtual std::string commands() const;
+
+ virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbuildFetchCommand(const EbuildCommandParams &, const EbuildFetchCommandParams &);
+ };
+
+ /**
+ * An EbuildInstallCommand is used to install an ebuild from a
+ * PortageRepository. On failure it throws.
+ *
+ * \ingroup grpebuildinterface
+ */
+ class EbuildInstallCommand :
+ public EbuildCommand
+ {
+ protected:
+ /// Parameters for install.
+ const EbuildInstallCommandParams install_params;
+
+ virtual std::string commands() const;
+
+ virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbuildInstallCommand(const EbuildCommandParams &, const EbuildInstallCommandParams &);
+ };
+
+ /**
+ * An EbuildUninstallCommand is used to uninstall a package in a VDBRepository.
+ *
+ * \ingroup grpebuildinterface
+ */
+ class EbuildUninstallCommand :
+ public EbuildCommand
+ {
+ protected:
+ /// Parameters for uninstall.
+ const EbuildUninstallCommandParams uninstall_params;
+
+ virtual std::string commands() const;
+
+ virtual bool failure() PALUDIS_ATTRIBUTE((noreturn));
+
+ virtual MakeEnvCommand extend_command(const MakeEnvCommand &);
+
+ public:
+ /**
+ * Constructor.
+ */
+ EbuildUninstallCommand(const EbuildCommandParams &, const EbuildUninstallCommandParams &);
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/ebuild.sr b/0.8.0/paludis/ebuild.sr
new file mode 100644
index 0000000..d2845b4
--- /dev/null
+++ b/0.8.0/paludis/ebuild.sr
@@ -0,0 +1,93 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_EbuildCommandParams()
+{
+ key environment "const Environment *"
+ key db_entry "const PackageDatabaseEntry *"
+ key ebuild_dir FSEntry
+ key files_dir FSEntry
+ key eclassdirs FSEntryCollection::ConstPointer
+ key portdir FSEntry
+ key distdir FSEntry
+ key buildroot FSEntry
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbuildCommand.
+ *
+ * \see EbuildCommand
+ * \ingroup grpebuildinterface
+ */
+END
+
+ allow_named_args
+}
+
+make_class_EbuildFetchCommandParams()
+{
+ key a std::string
+ key aa std::string
+ key use std::string
+ key use_expand std::string
+ key flat_src_uri std::string
+ key root std::string
+ key profiles FSEntryCollection::ConstPointer
+ key expand_vars "AssociativeCollection<std::string, std::string>::ConstPointer"
+ key no_fetch bool
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbuildFetchCommand.
+ *
+ * \see EbuildFetchCommand
+ * \ingroup grpebuildinterface
+ */
+END
+
+ allow_named_args
+}
+
+make_class_EbuildInstallCommandParams()
+{
+ key a std::string
+ key aa std::string
+ key use std::string
+ key use_expand std::string
+ key root std::string
+ key profiles FSEntryCollection::ConstPointer
+ key expand_vars "AssociativeCollection<std::string, std::string>::ConstPointer"
+ key disable_cfgpro bool
+ key slot SlotName
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbuildInstallCommand.
+ *
+ * \see EbuildInstallCommand
+ * \ingroup grpebuildinterface
+ */
+END
+
+ allow_named_args
+}
+
+make_class_EbuildUninstallCommandParams()
+{
+ key root std::string
+ key disable_cfgpro bool
+ key unmerge_only bool
+ key load_environment "const FSEntry *"
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an EbuildUninstallCommand.
+ *
+ * \see EbuildUninstallCommand
+ * \ingroup grpebuildinterface
+ */
+END
+
+ allow_named_args
+}
+
diff --git a/0.8.0/paludis/environment.cc b/0.8.0/paludis/environment.cc
new file mode 100644
index 0000000..ff1bf4d
--- /dev/null
+++ b/0.8.0/paludis/environment.cc
@@ -0,0 +1,474 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/package_database.hh>
+#include <paludis/dep_atom.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/save.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/util/collection_concrete.hh>
+
+#include <set>
+#include <list>
+
+/** \file
+ * Implementation of Environment.
+ *
+ * \ingroup grpenvironment
+ */
+
+using namespace paludis;
+
+Environment::Environment(PackageDatabase::Pointer d) :
+ _package_database(d),
+ _has_provide_map(false)
+{
+}
+
+Environment::~Environment()
+{
+}
+
+namespace
+{
+ /**
+ * Check whether licences for a package are accepted.
+ */
+ struct LicenceChecker :
+ DepAtomVisitorTypes::ConstVisitor
+ {
+ /// Are all necessary licences ok?
+ bool ok;
+
+ /// Our environment.
+ const Environment * const env;
+
+ /// Our package database.
+ const PackageDatabaseEntry * const db_entry;
+
+ /// Constructor
+ LicenceChecker(const Environment * const e, const PackageDatabaseEntry * const d) :
+ ok(true),
+ env(e),
+ db_entry(d)
+ {
+ }
+
+ ///\name Visit methods
+ ///{
+ void visit(const AllDepAtom * atom)
+ {
+ std::for_each(atom->begin(), atom->end(), accept_visitor(this));
+ }
+
+ void visit(const AnyDepAtom * atom)
+ {
+ bool local_ok(false);
+
+ if (atom->begin() == atom->end())
+ local_ok = true;
+ else
+ {
+ for (CompositeDepAtom::Iterator i(atom->begin()), i_end(atom->end()) ;
+ i != i_end ; ++i)
+ {
+ Save<bool> save_ok(&ok, true);
+ (*i)->accept(this);
+ local_ok |= ok;
+ }
+ }
+
+ ok &= local_ok;
+ }
+
+ void visit(const UseDepAtom * atom)
+ {
+ if (env->query_use(atom->flag(), db_entry))
+ std::for_each(atom->begin(), atom->end(), accept_visitor(this));
+ }
+
+ void visit(const PlainTextDepAtom * atom)
+ {
+ if (! env->accept_license(atom->text(), db_entry))
+ ok = false;
+ }
+
+ void visit(const PackageDepAtom *) PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "Encountered PackageDepAtom in licence?");
+ }
+
+ void visit(const BlockDepAtom *) PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "Encountered BlockDepAtom in licence?");
+ }
+ ///}
+ };
+}
+
+MaskReasons
+Environment::mask_reasons(const PackageDatabaseEntry & e) const
+{
+ Context context("When checking mask reasons for '" + stringify(e) + "'");
+
+ MaskReasons result;
+ VersionMetadata::ConstPointer metadata(package_database()->fetch_repository(
+ e.repository)->version_metadata(e.name, e.version));
+
+ if (metadata->eapi != "0" && metadata->eapi != ""
+ && metadata->eapi != "paludis-1" && metadata->eapi != "CRAN-0")
+ result.set(mr_eapi);
+ else
+ {
+ if (metadata->get_virtual_interface())
+ {
+ result |= mask_reasons(metadata->get_virtual_interface()->virtual_for);
+ if (result.any())
+ result.set(mr_by_association);
+ }
+
+ if (metadata->get_ebuild_interface())
+ {
+ std::set<KeywordName> keywords;
+ WhitespaceTokeniser::get_instance()->tokenise(
+ metadata->get_ebuild_interface()->keywords,
+ create_inserter<KeywordName>(std::inserter(keywords, keywords.end())));
+
+ result.set(mr_keyword);
+ for (std::set<KeywordName>::const_iterator i(keywords.begin()),
+ i_end(keywords.end()) ; i != i_end ; ++i)
+ if (accept_keyword(*i, &e))
+ {
+ result.reset(mr_keyword);
+ break;
+ }
+ }
+
+ LicenceChecker lc(this, &e);
+ metadata->license()->accept(&lc);
+ if (! lc.ok)
+ result.set(mr_license);
+
+ if (! query_user_unmasks(e))
+ {
+ if (query_user_masks(e))
+ result.set(mr_user_mask);
+
+ const Repository * const repo(package_database()->fetch_repository(
+ e.repository).raw_pointer());
+
+ if (repo->mask_interface)
+ {
+ if (repo->mask_interface->query_profile_masks(e.name,
+ e.version))
+ result.set(mr_profile_mask);
+
+ if (repo->mask_interface->query_repository_masks(e.name,
+ e.version))
+ result.set(mr_repository_mask);
+ }
+ }
+ }
+
+ return result;
+}
+
+DepAtom::Pointer
+Environment::package_set(const std::string & s) const
+{
+ /* favour local sets first */
+ CompositeDepAtom::Pointer result(local_package_set(s));
+ if (0 != result)
+ return result;
+
+ /* these sets always exist, even if empty */
+ if (s == "everything" || s == "system" || s == "world" || s == "security")
+ result.assign(new AllDepAtom);
+
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ {
+ if (! (*r)->sets_interface)
+ continue;
+
+ DepAtom::Pointer add((*r)->sets_interface->package_set(s));
+ if (0 != add)
+ {
+ if (! result)
+ result.assign(new AllDepAtom);
+ result->add_child(add);
+ }
+
+ if ("everything" == s || "world" == s)
+ {
+ add = (*r)->sets_interface->package_set("system");
+ if (0 != add)
+ result->add_child(add);
+ }
+ }
+
+ return result;
+}
+
+namespace
+{
+ /**
+ * Find package targets that are appropriate for adding to or removing
+ * from the world file.
+ */
+ struct WorldTargetFinder :
+ DepAtomVisitorTypes::ConstVisitor
+ {
+ /// Matches
+ std::list<const PackageDepAtom *> items;
+
+ /// Callback object pointer, may be 0.
+ Environment::WorldCallbacks * const w;
+
+ /// Are we inside a || ( ) group?
+ bool inside_any;
+
+ /// Are we inside a use? ( ) group?
+ bool inside_use;
+
+ /// Constructor.
+ WorldTargetFinder(Environment::WorldCallbacks * const ww) :
+ w(ww),
+ inside_any(false),
+ inside_use(false)
+ {
+ }
+
+ ///\name Visit methods
+ ///{
+ void visit(const AllDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void visit(const AnyDepAtom * a)
+ {
+ Save<bool> save_inside_any(&inside_any, true);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void visit(const UseDepAtom * a)
+ {
+ Save<bool> save_inside_use(&inside_use, true);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void visit(const PlainTextDepAtom *)
+ {
+ }
+
+ void visit(const PackageDepAtom * a)
+ {
+ if (inside_any)
+ {
+ if (w)
+ w->skip_callback(a, "inside || ( ) block");
+ }
+ else if (inside_use)
+ {
+ if (w)
+ w->skip_callback(a, "inside use? ( ) block");
+ }
+ else if (a->slot_ptr())
+ {
+ if (w)
+ w->skip_callback(a, ":slot restrictions");
+ }
+ else if (a->version_spec_ptr())
+ {
+ if (w)
+ w->skip_callback(a, "version restrictions");
+ }
+ else
+ {
+ items.push_back(a);
+ if (w)
+ w->add_callback(a);
+ }
+ }
+
+ void visit(const BlockDepAtom *)
+ {
+ }
+ ///}
+
+ };
+}
+
+void
+Environment::add_appropriate_to_world(DepAtom::ConstPointer a,
+ Environment::WorldCallbacks * const ww) const
+{
+ WorldTargetFinder w(ww);
+ a->accept(&w);
+ for (std::list<const PackageDepAtom *>::const_iterator i(w.items.begin()),
+ i_end(w.items.end()) ; i != i_end ; ++i)
+ {
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ if ((*r)->world_interface)
+ (*r)->world_interface->add_to_world((*i)->package());
+ }
+}
+
+void
+Environment::remove_appropriate_from_world(DepAtom::ConstPointer a,
+ Environment::WorldCallbacks * const ww) const
+{
+ WorldTargetFinder w(ww);
+ a->accept(&w);
+ for (std::list<const PackageDepAtom *>::const_iterator i(w.items.begin()),
+ i_end(w.items.end()) ; i != i_end ; ++i)
+ {
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ if ((*r)->world_interface)
+ (*r)->world_interface->remove_from_world((*i)->package());
+
+ ww->remove_callback(*i);
+ }
+}
+
+Hook::Hook(const std::string & n) :
+ _name(n)
+{
+}
+
+Hook
+Hook::operator() (const std::string & k, const std::string & v) const
+{
+ Hook result(*this);
+ result._extra_env.insert(std::make_pair(k, v));
+ return result;
+}
+
+bool
+Environment::query_use(const UseFlagName & f, const PackageDatabaseEntry * e) const
+{
+ /* first check package database use masks... */
+ const Repository * const repo((e ?
+ package_database()->fetch_repository(e->repository).raw_pointer() :
+ 0));
+
+ if (repo && repo->use_interface)
+ {
+ if (repo->use_interface->query_use_mask(f, e))
+ return false;
+ if (repo->use_interface->query_use_force(f, e))
+ return true;
+ }
+
+ /* check use: package database config */
+ if (repo && repo->use_interface)
+ {
+ switch (repo->use_interface->query_use(f, e))
+ {
+ case use_disabled:
+ case use_unspecified:
+ return false;
+
+ case use_enabled:
+ return true;
+ }
+
+ throw InternalError(PALUDIS_HERE, "bad state");
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+Environment::accept_keyword(const KeywordName & keyword, const PackageDatabaseEntry * const) const
+{
+ if (keyword == KeywordName("*"))
+ return true;
+
+ return false;
+}
+
+bool
+Environment::accept_license(const std::string &, const PackageDatabaseEntry * const) const
+{
+ return true;
+}
+
+bool
+Environment::query_user_masks(const PackageDatabaseEntry &) const
+{
+ return false;
+}
+
+bool
+Environment::query_user_unmasks(const PackageDatabaseEntry &) const
+{
+ return false;
+}
+
+std::string
+Environment::bashrc_files() const
+{
+ return "";
+}
+
+
+std::string
+Environment::hook_dirs() const
+{
+ return "";
+}
+
+namespace
+{
+ static const std::multimap<std::string, std::string> environment_mirrors;
+}
+
+Environment::MirrorIterator
+Environment::begin_mirrors(const std::string &) const
+{
+ return MirrorIterator(environment_mirrors.begin());
+}
+
+Environment::MirrorIterator
+Environment::end_mirrors(const std::string &) const
+{
+ return MirrorIterator(environment_mirrors.end());
+}
+
+void
+Environment::perform_hook(const Hook &) const
+{
+}
+
+UseFlagNameCollection::ConstPointer
+Environment::known_use_expand_names(const UseFlagName &, const PackageDatabaseEntry *) const
+{
+ return UseFlagNameCollection::ConstPointer(new UseFlagNameCollection::Concrete);
+}
+
diff --git a/0.8.0/paludis/environment.hh b/0.8.0/paludis/environment.hh
new file mode 100644
index 0000000..75924d8
--- /dev/null
+++ b/0.8.0/paludis/environment.hh
@@ -0,0 +1,304 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_ENVIRONMENT_HH
+#define PALUDIS_GUARD_PALUDIS_ENVIRONMENT_HH 1
+
+#include <paludis/mask_reasons.hh>
+#include <paludis/name.hh>
+#include <paludis/package_database.hh>
+#include <paludis/util/counted_ptr.hh>
+#include <paludis/util/instantiation_policy.hh>
+
+/** \file
+ * Declarations for the Environment class.
+ *
+ * \ingroup grpenvironment
+ */
+
+namespace paludis
+{
+ struct EnvironmentMirrorIteratorTag;
+
+ typedef libwrapiter::ForwardIterator<EnvironmentMirrorIteratorTag,
+ const std::pair<const std::string, std::string> > EnvironmentMirrorIterator;
+
+ /**
+ * Represents the data for an Environment hook call.
+ *
+ * \ingroup grpenvironment
+ */
+ class Hook
+ {
+ private:
+ std::map<std::string, std::string> _extra_env;
+
+ std::string _name;
+
+ public:
+ /// Constructor.
+ Hook(const std::string & name);
+
+ /// Perform the hook.
+ Hook operator() (const std::string & key, const std::string & value) const;
+
+ /// Iterate over extra environment data.
+ typedef std::map<std::string, std::string>::const_iterator Iterator;
+
+ /// Start of extra environment data.
+ Iterator begin() const
+ {
+ return _extra_env.begin();
+ }
+
+ /// End of extra environment data.
+ Iterator end() const
+ {
+ return _extra_env.end();
+ }
+
+ /// Our name.
+ std::string name() const
+ {
+ return _name;
+ }
+ };
+
+ /**
+ * Represents a working environment, which contains an available packages
+ * database and provides various methods for querying package visibility
+ * and options.
+ *
+ * \ingroup grpenvironment
+ */
+ class Environment :
+ private InstantiationPolicy<Environment, instantiation_method::NonCopyableTag>
+ {
+ private:
+ PackageDatabase::Pointer _package_database;
+
+ mutable bool _has_provide_map;
+
+ mutable std::map<QualifiedPackageName, QualifiedPackageName> _provide_map;
+
+ protected:
+ /**
+ * Constructor.
+ */
+ Environment(PackageDatabase::Pointer);
+
+ /**
+ * Local package set, or zero.
+ */
+ virtual CompositeDepAtom::Pointer local_package_set(const std::string &) const
+ {
+ return AllDepAtom::Pointer(0);
+ }
+
+ /**
+ * Change our package database.
+ */
+ void change_package_database(PackageDatabase::Pointer _p)
+ {
+ _package_database = _p;
+ }
+
+ public:
+ /**
+ * Does the user want the specified USE flag set for a
+ * particular package?
+ *
+ * Default behaviour: all USE flags turned off, unless overridden by
+ * the repository for the pde.
+ */
+ virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry *) const;
+
+ /**
+ * Fetch any known use expand names (excluding prefix) that start with a
+ * given prefix.
+ *
+ * Default behaviour: no names known.
+ */
+ virtual UseFlagNameCollection::ConstPointer known_use_expand_names(const UseFlagName &,
+ const PackageDatabaseEntry *) const;
+
+ /**
+ * Is the specified KEYWORD accepted?
+ *
+ * Default behaviour: only "*" accepted.
+ */
+ virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const;
+
+ /**
+ * Is the specified LICENSE accepted?
+ *
+ * Default behaviour: yes.
+ */
+ virtual bool accept_license(const std::string &, const PackageDatabaseEntry * const) const;
+
+ /**
+ * Fetch the masks for a particular package.
+ */
+ MaskReasons mask_reasons(const PackageDatabaseEntry &) const;
+
+ /**
+ * Are there any user masks on a package?
+ *
+ * Default behaviour: no.
+ */
+ virtual bool query_user_masks(const PackageDatabaseEntry &) const;
+
+ /**
+ * Are there any user unmasks on a package?
+ *
+ * Default behaviour: no.
+ */
+ virtual bool query_user_unmasks(const PackageDatabaseEntry &) const;
+
+ /**
+ * Fetch our package database.
+ */
+ PackageDatabase::Pointer package_database() const
+ {
+ return _package_database;
+ }
+
+ /**
+ * Our bashrc files.
+ *
+ * Default behaviour: none.
+ */
+ virtual std::string bashrc_files() const;
+
+ /**
+ * Our hook directories.
+ *
+ * Default behaviour: none.
+ */
+ virtual std::string hook_dirs() const;
+
+ /**
+ * How to run paludis.
+ */
+ virtual std::string paludis_command() const = 0;
+
+ /**
+ * Destructor.
+ */
+ virtual ~Environment();
+
+ /**
+ * Iterator over named mirror entries.
+ */
+ typedef EnvironmentMirrorIterator MirrorIterator;
+
+ /**
+ * Iterator to the start of our mirrors.
+ *
+ * Default behaviour: no mirrors. If specialising, also do
+ * Environment::end_mirrors.
+ */
+ virtual MirrorIterator begin_mirrors(const std::string & mirror) const;
+
+ /**
+ * Iterator to past the end of our mirrors.
+ *
+ * Default behaviour: no mirrors. If specialising, also do
+ * Environment::begin_mirrors.
+ */
+ virtual MirrorIterator end_mirrors(const std::string & mirror) const;
+
+ /**
+ * Fetch a named package set.
+ */
+ DepAtom::Pointer package_set(const std::string &) const;
+
+ /**
+ * Subclass for callbacks used by add_appropriate_to_world and
+ * remove_appropriate_from_world.
+ *
+ * \ingroup grpenvironment
+ */
+ class WorldCallbacks
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ WorldCallbacks()
+ {
+ }
+
+ ///\}
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ virtual ~WorldCallbacks()
+ {
+ }
+
+ ///\}
+
+ /**
+ * Called when adding an entry to world.
+ */
+ virtual void add_callback(const PackageDepAtom *)
+ {
+ }
+
+ /**
+ * Called when skipping adding an entry to world.
+ */
+ virtual void skip_callback(const PackageDepAtom *,
+ const std::string &)
+ {
+ }
+
+ /**
+ * Called when removing an entry to world.
+ */
+ virtual void remove_callback(const PackageDepAtom *)
+ {
+ }
+ };
+
+ /**
+ * Add packages to world, if they are not there already, and if they are
+ * not a restricted atom.
+ */
+ void
+ add_appropriate_to_world(DepAtom::ConstPointer a, WorldCallbacks * const) const;
+
+ /**
+ * Remove packages from world, if they are there.
+ */
+ void remove_appropriate_from_world(DepAtom::ConstPointer, WorldCallbacks * const) const;
+
+ /**
+ * Perform a hook.
+ *
+ * Default behaviour: nothing happens.
+ */
+ virtual void perform_hook(const Hook & hook) const;
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/environment/Makefile.am b/0.8.0/paludis/environment/Makefile.am
new file mode 100644
index 0000000..66c2ccb
--- /dev/null
+++ b/0.8.0/paludis/environment/Makefile.am
@@ -0,0 +1,6 @@
+SUBDIRS = default no_config test
+
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in
+
+
diff --git a/0.8.0/paludis/environment/default/Makefile.am b/0.8.0/paludis/environment/default/Makefile.am
new file mode 100644
index 0000000..9ca00d0
--- /dev/null
+++ b/0.8.0/paludis/environment/default/Makefile.am
@@ -0,0 +1,47 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+libpaludisdefaultenvironment_la_SOURCES = \
+ default_config.cc default_config.hh \
+ default_environment.cc default_environment.hh
+
+libpaludisdefaultenvironment_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+libpaludisdefaultenvironment_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/libpaludis.la
+
+lib_LTLIBRARIES = libpaludisdefaultenvironment.la
+paludis_environment_default_includedir = $(includedir)/paludis/environment/test
+paludis_environment_default_include_HEADERS = default_config.hh default_environment.hh
+
+EXTRA_DIST = \
+ default_environment_TEST_setup.sh \
+ default_environment_TEST.cc \
+ default_environment_TEST_cleanup.sh
+
+TESTS = default_environment_TEST
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \
+ PALUDIS_SKIP_CONFIG="yes" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ bash $(top_srcdir)/test/run_test.sh
+
+check_PROGRAMS = $(TESTS)
+check_SCRIPTS = default_environment_TEST_setup.sh default_environment_TEST_cleanup.sh
+
+default_environment_TEST_SOURCES = default_environment_TEST.cc
+default_environment_TEST_LDADD = \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ libpaludisdefaultenvironment.la
+
diff --git a/0.8.0/paludis/environment/default/default_config.cc b/0.8.0/paludis/environment/default/default_config.cc
new file mode 100644
index 0000000..a605280
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_config.cc
@@ -0,0 +1,740 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/environment/default/default_config.hh>
+#include <paludis/config_file.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/compare.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/iterator.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/is_file_with_extension.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/sr.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <fstream>
+#include <algorithm>
+#include <sstream>
+#include <list>
+#include <map>
+
+#include <ctype.h>
+
+/** \file
+ * Implementation of default_config.hh classes.
+ *
+ * \ingroup grpdefaultconfig
+ */
+
+using namespace paludis;
+
+#include <paludis/repository_config_entry-sr.cc>
+#include <paludis/use_config_entry-sr.cc>
+
+namespace paludis
+{
+ /**
+ * Implementation data for DefaultConfig.
+ *
+ * \ingroup grpdefaultconfig
+ */
+ template<>
+ struct Implementation<DefaultConfig> :
+ InternalCounted<DefaultConfig>,
+ InstantiationPolicy<DefaultConfig, instantiation_method::NonCopyableTag>
+ {
+ static std::string config_suffix;
+ static bool config_suffix_can_be_set;
+ std::string paludis_command;
+ std::string root;
+ std::string config_dir;
+ std::string bashrc_files;
+
+ std::list<RepositoryConfigEntry> repos;
+
+ std::map<QualifiedPackageName, std::vector<
+ std::pair<PackageDepAtom::ConstPointer, KeywordName> > > keywords;
+
+ const std::vector<std::pair<PackageDepAtom::ConstPointer, KeywordName> > empty_keywords;
+
+ std::vector<KeywordName> default_keywords;
+
+ std::map<QualifiedPackageName, std::vector<
+ std::pair<PackageDepAtom::ConstPointer, std::string> > > licenses;
+
+ const std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > empty_licenses;
+
+ std::vector<std::string> default_licenses;
+
+ std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> > user_masks;
+
+ std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> > user_unmasks;
+
+ std::vector<PackageDepAtom::ConstPointer> empty_masks;
+
+ std::map<QualifiedPackageName, std::vector<UseConfigEntry> > use;
+
+ std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > empty_use_prefixes;
+
+ std::map<QualifiedPackageName, std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > >
+ use_prefixes_that_have_minus_star;
+
+ std::vector<UseConfigEntry> empty_use;
+
+ std::vector<std::pair<UseFlagName, UseFlagState> > default_use;
+
+ std::vector<std::string> default_use_prefixes_that_have_minus_star;
+
+ std::multimap<std::string, std::string> mirrors;
+
+ Implementation();
+ };
+
+ Implementation<DefaultConfig>::Implementation() :
+ paludis_command("paludis"),
+ config_dir("(unset)")
+ {
+ }
+
+ std::string Implementation<DefaultConfig>::config_suffix;
+ bool Implementation<DefaultConfig>::config_suffix_can_be_set(true);
+}
+
+DefaultConfigError::DefaultConfigError(const std::string & msg) throw () :
+ ConfigurationError("Default configuration error: " + msg)
+{
+}
+
+DefaultConfig::DefaultConfig() :
+ PrivateImplementationPattern<DefaultConfig>(new Implementation<DefaultConfig>)
+{
+ Context context("When loading default configuration:");
+
+ if (! getenv_with_default("PALUDIS_SKIP_CONFIG", "").empty())
+ {
+ _imp->config_suffix_can_be_set = false;
+ return;
+ }
+
+ /* indirection */
+ std::string root_prefix;
+ std::string local_config_suffix;
+ if (! _imp->config_suffix.empty())
+ local_config_suffix = "-" + _imp->config_suffix;
+
+ FSEntry local_config_dir(FSEntry(getenv_with_default("PALUDIS_HOME", getenv_or_error("HOME"))) /
+ (".paludis" + local_config_suffix)), old_config_dir(local_config_dir);
+ if (! local_config_dir.exists())
+ local_config_dir = (FSEntry(SYSCONFDIR) / ("paludis" + local_config_suffix));
+ if (! local_config_dir.exists())
+ throw DefaultConfigError("Can't find configuration directory (tried '"
+ + stringify(old_config_dir) + "', '" + stringify(local_config_dir) + "')");
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "DefaultConfig initial directory is '"
+ + stringify(local_config_dir) + "'");
+
+ if ((local_config_dir / "specpath").exists())
+ {
+ KeyValueConfigFile specpath(local_config_dir / "specpath");
+ root_prefix = specpath.get("root");
+ local_config_suffix = specpath.get("config-suffix");
+
+ if (! root_prefix.empty() && stringify(FSEntry(root_prefix).realpath()) != "/")
+ {
+ local_config_dir = FSEntry(root_prefix) / SYSCONFDIR / ("paludis" + local_config_suffix);
+ if (! local_config_dir.exists())
+ throw DefaultConfigError("Can't find configuration directory under root ("
+ "tried '" + stringify(local_config_dir) + "'");
+ }
+ }
+
+ _imp->root = root_prefix;
+ _imp->config_dir = stringify(local_config_dir);
+
+ AssociativeCollection<std::string, std::string>::Pointer conf_vars(
+ new AssociativeCollection<std::string, std::string>::Concrete);
+ conf_vars->insert("ROOT", root_prefix);
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "DefaultConfig real directory is '"
+ + stringify(local_config_dir) + "', root prefix is '" + root_prefix +
+ "', config suffix is '" + local_config_suffix + "'");
+
+ /* repositories */
+ {
+ std::list<FSEntry> dirs;
+ dirs.push_back(local_config_dir / "repositories");
+
+ std::list<FSEntry> repo_files;
+ for (std::list<FSEntry>::const_iterator dir(dirs.begin()), dir_end(dirs.end()) ;
+ dir != dir_end ; ++dir)
+ {
+ if (! dir->exists())
+ continue;
+
+ std::copy(DirIterator(*dir), DirIterator(),
+ filter_inserter(std::back_inserter(repo_files), IsFileWithExtension(".conf")));
+ }
+
+ for (std::list<FSEntry>::const_iterator repo_file(repo_files.begin()), repo_file_end(repo_files.end()) ;
+ repo_file != repo_file_end ; ++repo_file)
+ {
+ Context local_context("When reading repository file '" + stringify(*repo_file) + "':");
+
+ KeyValueConfigFile k(*repo_file, conf_vars);
+
+ std::string format(k.get("format"));
+ if (format.empty())
+ throw DefaultConfigError("Key 'format' not specified or empty");
+
+ int importance(0);
+ if (! k.get("importance").empty())
+ importance = destringify<int>(k.get("importance"));
+
+ AssociativeCollection<std::string, std::string>::Pointer keys(
+ new AssociativeCollection<std::string, std::string>::Concrete(k.begin(), k.end()));
+
+ keys->erase("repo_file");
+ keys->insert("repo_file", stringify(*repo_file));
+
+ keys->erase("root");
+ keys->insert("root", root_prefix);
+
+ _imp->repos.push_back(RepositoryConfigEntry(format, importance, keys));
+ }
+
+ if (_imp->repos.empty())
+ throw DefaultConfigError("No repositories specified");
+
+ /* add virtuals repositories */
+ _imp->repos.push_back(RepositoryConfigEntry("installed_virtuals", -1,
+ AssociativeCollection<std::string, std::string>::Pointer(0)));
+ _imp->repos.push_back(RepositoryConfigEntry("virtuals", -2,
+ AssociativeCollection<std::string, std::string>::Pointer(0)));
+
+ _imp->repos.sort();
+ }
+
+ /* keywords */
+ {
+ std::list<FSEntry> files;
+ files.push_back(local_config_dir / "keywords.conf");
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading keywords file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ LineConfigFile f(*file);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+ if ("*" == tokens.at(0))
+ std::copy(next(tokens.begin()), tokens.end(),
+ create_inserter<KeywordName>(std::back_inserter(_imp->default_keywords)));
+ else
+ {
+ PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0)));
+ for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ _imp->keywords[a->package()].push_back(std::make_pair(a, *t));
+ }
+ }
+ }
+
+ if (_imp->default_keywords.empty())
+ throw DefaultConfigError("No default keywords specified (a keywords.conf file should "
+ "contain an entry in the form '* keyword')");
+ }
+
+ /* licenses */
+ {
+ std::list<FSEntry> files;
+ files.push_back(local_config_dir / "licenses.conf");
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading licenses file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ LineConfigFile f(*file);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+ if ("*" == tokens.at(0))
+ std::copy(next(tokens.begin()), tokens.end(), std::back_inserter(_imp->default_licenses));
+ else
+ {
+ PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0)));
+ for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ _imp->licenses[a->package()].push_back(std::make_pair(a, *t));
+ }
+ }
+ }
+
+ if (_imp->default_licenses.empty())
+ throw DefaultConfigError("No default licenses specified (a licenses.conf file should "
+ "contain an entry in the form '* license license', or '* *' if you don't want any "
+ "license filtering)");
+ }
+
+ /* user mask */
+ {
+ std::list<FSEntry> files;
+ files.push_back(local_config_dir / "package_mask.conf");
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading package_mask file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ LineConfigFile f(*file);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ PackageDepAtom::ConstPointer a(new PackageDepAtom(*line));
+ _imp->user_masks[a->package()].push_back(a);
+ }
+ }
+ }
+
+ /* user unmask */
+ {
+ std::list<FSEntry> files;
+ files.push_back(local_config_dir / "package_unmask.conf");
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading package_unmask file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ LineConfigFile f(*file);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ PackageDepAtom::ConstPointer a(new PackageDepAtom(*line));
+ _imp->user_unmasks[a->package()].push_back(a);
+ }
+ }
+ }
+
+ /* use */
+ {
+ std::list<FSEntry> files;
+ files.push_back(local_config_dir / "use.conf");
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading use file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ LineConfigFile f(*file);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+
+ std::string prefix;
+ if ("*" == tokens.at(0))
+ {
+ for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ {
+ if ('-' == t->at(0))
+ {
+ if (*t == "-*")
+ {
+ _imp->default_use_prefixes_that_have_minus_star.push_back(prefix);
+ if (prefix.empty())
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Using '* -*' in use.conf is dangerous. You have been warned.");
+ }
+ else
+ _imp->default_use.push_back(std::make_pair(UseFlagName(
+ prefix + t->substr(1)), use_disabled));
+ }
+ else if (':' == t->at(t->length() - 1))
+ {
+ prefix.clear();
+ std::transform(t->begin(), previous(t->end()), std::back_inserter(prefix),
+ &::tolower);
+ prefix.append("_");
+ }
+ else
+ _imp->default_use.push_back(std::make_pair(UseFlagName(
+ prefix + *t), use_enabled));
+ }
+ }
+ else
+ {
+ PackageDepAtom::ConstPointer a(new PackageDepAtom(tokens.at(0)));
+ for (std::vector<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ {
+ if ('-' == t->at(0))
+ {
+ if ("-*" == *t)
+ _imp->use_prefixes_that_have_minus_star[a->package()].push_back(
+ std::make_pair(a, prefix));
+ else
+ _imp->use[a->package()].push_back(UseConfigEntry(
+ a, UseFlagName(prefix + t->substr(1)), use_disabled));
+ }
+ else if (':' == t->at(t->length() - 1))
+ {
+ prefix.clear();
+ std::transform(t->begin(), previous(t->end()), std::back_inserter(prefix),
+ &::tolower);
+ prefix.append("_");
+ }
+ else
+ _imp->use[a->package()].push_back(UseConfigEntry(
+ a, UseFlagName(prefix + *t), use_enabled));
+ }
+ }
+ }
+ }
+
+ if (_imp->default_keywords.empty())
+ throw DefaultConfigError("No default keywords specified (a keywords.conf file should "
+ "contain an entry in the form '* keyword')");
+ }
+
+ /* mirrors */
+ {
+ std::list<FSEntry> files;
+ files.push_back(local_config_dir / "mirrors.conf");
+
+ for (std::list<FSEntry>::const_iterator file(files.begin()), file_end(files.end()) ;
+ file != file_end ; ++file)
+ {
+ Context local_context("When reading mirrors file '" + stringify(*file) + "':");
+
+ if (! file->is_regular_file())
+ continue;
+
+ LineConfigFile f(*file);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> m;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(m));
+ if (m.size() < 2)
+ continue;
+ for (std::vector<std::string>::const_iterator mm(next(m.begin())),
+ mm_end(m.end()) ; mm != mm_end ; ++mm)
+ _imp->mirrors.insert(std::make_pair(m.at(0), *mm));
+ }
+ }
+ }
+
+ _imp->bashrc_files = stringify(local_config_dir / "bashrc");
+
+ _imp->config_suffix_can_be_set = false;
+}
+
+DefaultConfig::~DefaultConfig()
+{
+}
+
+void
+DefaultConfig::set_config_suffix(const std::string & s)
+{
+ if (! Implementation<DefaultConfig>::config_suffix_can_be_set)
+ throw InternalError(PALUDIS_HERE, "DefaultConfig::set_config_suffix called after "
+ "DefaultConfig has been instantiated.");
+
+ static const std::string allowed_chars(
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-_+:");
+
+ if (std::string::npos != s.find_first_not_of(allowed_chars))
+ throw DefaultConfigError("Invalid config suffix '" + s + "'");
+
+ if (! s.empty())
+ if ('-' == s.at(0) || '-' == s.at(s.length() - 1))
+ throw DefaultConfigError("Invalid config suffix '" + s + "'");
+
+ Implementation<DefaultConfig>::config_suffix = s;
+}
+
+std::string
+DefaultConfig::bashrc_files() const
+{
+ return _imp->bashrc_files;
+}
+
+std::string
+DefaultConfig::config_suffix()
+{
+ return Implementation<DefaultConfig>::config_suffix;
+}
+
+DefaultConfig::RepositoryIterator
+DefaultConfig::begin_repositories() const
+{
+ return RepositoryIterator(_imp->repos.begin());
+}
+
+DefaultConfig::RepositoryIterator
+DefaultConfig::end_repositories() const
+{
+ return RepositoryIterator(_imp->repos.end());
+}
+
+DefaultConfig::PackageKeywordsIterator
+DefaultConfig::begin_package_keywords(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<
+ std::pair<PackageDepAtom::ConstPointer, KeywordName> > >::const_iterator r;
+ if (_imp->keywords.end() != ((r = _imp->keywords.find(d))))
+ return PackageKeywordsIterator(r->second.begin());
+ else
+ return PackageKeywordsIterator(_imp->empty_keywords.begin());
+}
+
+DefaultConfig::PackageKeywordsIterator
+DefaultConfig::end_package_keywords(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<
+ std::pair<PackageDepAtom::ConstPointer, KeywordName> > >::const_iterator r;
+ if (_imp->keywords.end() != ((r = _imp->keywords.find(d))))
+ return PackageKeywordsIterator(r->second.end());
+ else
+ return PackageKeywordsIterator(_imp->empty_keywords.end());
+}
+
+DefaultConfig::DefaultKeywordsIterator
+DefaultConfig::begin_default_keywords() const
+{
+ return DefaultKeywordsIterator(_imp->default_keywords.begin());
+}
+
+DefaultConfig::DefaultKeywordsIterator
+DefaultConfig::end_default_keywords() const
+{
+ return DefaultKeywordsIterator(_imp->default_keywords.end());
+}
+
+DefaultConfig::PackageLicensesIterator
+DefaultConfig::begin_package_licenses(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<
+ std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r;
+ if (_imp->licenses.end() != ((r = _imp->licenses.find(d))))
+ return PackageLicensesIterator(r->second.begin());
+ else
+ return PackageLicensesIterator(_imp->empty_licenses.begin());
+}
+
+DefaultConfig::PackageLicensesIterator
+DefaultConfig::end_package_licenses(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<
+ std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r;
+ if (_imp->licenses.end() != ((r = _imp->licenses.find(d))))
+ return PackageLicensesIterator(r->second.end());
+ else
+ return PackageLicensesIterator(_imp->empty_licenses.end());
+}
+
+DefaultConfig::DefaultLicensesIterator
+DefaultConfig::begin_default_licenses() const
+{
+ return DefaultLicensesIterator(_imp->default_licenses.begin());
+}
+
+DefaultConfig::DefaultLicensesIterator
+DefaultConfig::end_default_licenses() const
+{
+ return DefaultLicensesIterator(_imp->default_licenses.end());
+}
+
+DefaultConfig::UserMasksIterator
+DefaultConfig::begin_user_masks(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r;
+ if (_imp->user_masks.end() != ((r = _imp->user_masks.find(d))))
+ return UserMasksIterator(indirect_iterator<const PackageDepAtom>(r->second.begin()));
+ else
+ return UserMasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.begin()));
+}
+
+DefaultConfig::UserMasksIterator
+DefaultConfig::end_user_masks(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r;
+ if (_imp->user_masks.end() != ((r = _imp->user_masks.find(d))))
+ return UserMasksIterator(indirect_iterator<const PackageDepAtom>(r->second.end()));
+ else
+ return UserMasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.end()));
+}
+
+DefaultConfig::UserUnmasksIterator
+DefaultConfig::begin_user_unmasks(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r;
+ if (_imp->user_unmasks.end() != ((r = _imp->user_unmasks.find(d))))
+ return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(r->second.begin()));
+ else
+ return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.begin()));
+}
+
+DefaultConfig::UserUnmasksIterator
+DefaultConfig::end_user_unmasks(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<PackageDepAtom::ConstPointer> >::const_iterator r;
+ if (_imp->user_unmasks.end() != ((r = _imp->user_unmasks.find(d))))
+ return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(r->second.end()));
+ else
+ return UserUnmasksIterator(indirect_iterator<const PackageDepAtom>(_imp->empty_masks.end()));
+}
+
+DefaultConfig::UseConfigIterator
+DefaultConfig::begin_use_config(const QualifiedPackageName & q) const
+{
+ std::map<QualifiedPackageName, std::vector<UseConfigEntry> >::const_iterator r;
+ if (_imp->use.end() != ((r = _imp->use.find(q))))
+ return UseConfigIterator(r->second.begin());
+ else
+ return UseConfigIterator(_imp->empty_use.begin());
+}
+
+DefaultConfig::UseConfigIterator
+DefaultConfig::end_use_config(const QualifiedPackageName & q) const
+{
+ std::map<QualifiedPackageName, std::vector<UseConfigEntry> >::const_iterator r;
+ if (_imp->use.end() != ((r = _imp->use.find(q))))
+ return UseConfigIterator(r->second.end());
+ else
+ return UseConfigIterator(_imp->empty_use.end());
+}
+
+DefaultConfig::DefaultUseIterator
+DefaultConfig::begin_default_use() const
+{
+ return DefaultUseIterator(_imp->default_use.begin());
+}
+
+DefaultConfig::DefaultUseIterator
+DefaultConfig::end_default_use() const
+{
+ return DefaultUseIterator(_imp->default_use.end());
+}
+
+std::string
+DefaultConfig::paludis_command() const
+{
+ return _imp->paludis_command;
+}
+
+void
+DefaultConfig::set_paludis_command(const std::string & s)
+{
+ _imp->paludis_command = s;
+}
+
+std::string
+DefaultConfig::root() const
+{
+ return _imp->root;
+}
+
+std::string
+DefaultConfig::config_dir() const
+{
+ return _imp->config_dir;
+}
+
+DefaultConfig::MirrorIterator
+DefaultConfig::begin_mirrors(const std::string & m) const
+{
+ return MirrorIterator(_imp->mirrors.lower_bound(m));
+}
+
+DefaultConfig::MirrorIterator
+DefaultConfig::end_mirrors(const std::string & m) const
+{
+ return MirrorIterator(_imp->mirrors.upper_bound(m));
+}
+
+DefaultConfig::UseMinusStarIterator
+DefaultConfig::begin_use_prefixes_with_minus_star() const
+{
+ return UseMinusStarIterator(_imp->default_use_prefixes_that_have_minus_star.begin());
+}
+
+DefaultConfig::UseMinusStarIterator
+DefaultConfig::end_use_prefixes_with_minus_star() const
+{
+ return UseMinusStarIterator(_imp->default_use_prefixes_that_have_minus_star.end());
+}
+
+DefaultConfig::PackageUseMinusStarIterator
+DefaultConfig::begin_package_use_prefixes_with_minus_star(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r;
+ if (_imp->use_prefixes_that_have_minus_star.end() != ((r = _imp->use_prefixes_that_have_minus_star.find(d))))
+ return PackageUseMinusStarIterator(r->second.begin());
+ else
+ return PackageUseMinusStarIterator(_imp->empty_use_prefixes.begin());
+}
+
+DefaultConfig::PackageUseMinusStarIterator
+DefaultConfig::end_package_use_prefixes_with_minus_star(const QualifiedPackageName & d) const
+{
+ std::map<QualifiedPackageName, std::vector<std::pair<PackageDepAtom::ConstPointer, std::string> > >::const_iterator r;
+ if (_imp->use_prefixes_that_have_minus_star.end() != ((r = _imp->use_prefixes_that_have_minus_star.find(d))))
+ return PackageUseMinusStarIterator(r->second.end());
+ else
+ return PackageUseMinusStarIterator(_imp->empty_use_prefixes.end());
+}
+
+
diff --git a/0.8.0/paludis/environment/default/default_config.hh b/0.8.0/paludis/environment/default/default_config.hh
new file mode 100644
index 0000000..03a09f5
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_config.hh
@@ -0,0 +1,224 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEFAULT_CONFIG_HH
+#define PALUDIS_GUARD_PALUDIS_DEFAULT_CONFIG_HH 1
+
+#include <paludis/dep_atom.hh>
+#include <paludis/name.hh>
+#include <paludis/util/collection.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/sr.hh>
+
+#include <string>
+
+/** \file
+ * Declarations for the DefaultConfig class and related utilities.
+ *
+ * \ingroup grpdefaultconfig
+ */
+
+namespace paludis
+{
+ struct EnvironmentMirrorIteratorTag;
+
+ typedef libwrapiter::ForwardIterator<EnvironmentMirrorIteratorTag,
+ const std::pair<const std::string, std::string> > EnvironmentMirrorIterator;
+
+ /**
+ * A DefaultConfigError is thrown if a configuration error is encountered
+ * by DefaultConfig.
+ *
+ * \ingroup grpexceptions
+ * \ingroup grpdefaultconfig
+ */
+ class PALUDIS_VISIBLE DefaultConfigError : public ConfigurationError
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ DefaultConfigError(const std::string & msg) throw ();
+ };
+
+#include <paludis/repository_config_entry-sr.hh>
+#include <paludis/use_config_entry-sr.hh>
+
+ /**
+ * DefaultConfig is used by DefaultEnvironment to access the user's
+ * configuration settings from on-disk configuration files.
+ *
+ * \ingroup grpdefaultconfig
+ */
+ class PALUDIS_VISIBLE DefaultConfig :
+ public InstantiationPolicy<DefaultConfig, instantiation_method::SingletonAsNeededTag>,
+ private PrivateImplementationPattern<DefaultConfig>
+ {
+ friend class InstantiationPolicy<DefaultConfig, instantiation_method::SingletonAsNeededTag>;
+
+ private:
+ DefaultConfig();
+
+ ~DefaultConfig();
+
+ public:
+ /**
+ * Set config suffix. Must be called before we do anything, or not
+ * at all.
+ */
+ static void set_config_suffix(const std::string &);
+
+ /**
+ * Get config suffix.
+ */
+ static std::string config_suffix();
+
+ ///\name Iterate over our repositories
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const RepositoryConfigEntry> RepositoryIterator;
+
+ RepositoryIterator begin_repositories() const;
+
+ RepositoryIterator end_repositories() const;
+
+ ///}
+
+ ///\name Iterate over our default and per-package keywords
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig,
+ const std::pair<PackageDepAtom::ConstPointer, KeywordName> > PackageKeywordsIterator;
+
+ PackageKeywordsIterator begin_package_keywords(const QualifiedPackageName & d) const;
+
+ PackageKeywordsIterator end_package_keywords(const QualifiedPackageName & d) const;
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const KeywordName> DefaultKeywordsIterator;
+
+ DefaultKeywordsIterator begin_default_keywords() const;
+
+ DefaultKeywordsIterator end_default_keywords() const;
+
+ ///}
+
+ ///\name Iterate over our default and per-package licenses
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig,
+ const std::pair<PackageDepAtom::ConstPointer, std::string> > PackageLicensesIterator;
+
+ PackageLicensesIterator begin_package_licenses(const QualifiedPackageName & d) const;
+
+ PackageLicensesIterator end_package_licenses(const QualifiedPackageName & d) const;
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const std::string> DefaultLicensesIterator;
+
+ DefaultLicensesIterator begin_default_licenses() const;
+
+ DefaultLicensesIterator end_default_licenses() const;
+
+ ///}
+
+ ///\name Iterate over our masks and unmasks
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const PackageDepAtom> UserMasksIterator;
+
+ UserMasksIterator begin_user_masks(const QualifiedPackageName & d) const;
+
+ UserMasksIterator end_user_masks(const QualifiedPackageName & d) const;
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const PackageDepAtom> UserUnmasksIterator;
+
+ UserUnmasksIterator begin_user_unmasks(const QualifiedPackageName & d) const;
+
+ UserUnmasksIterator end_user_unmasks(const QualifiedPackageName & d) const;
+
+ ///}
+
+ ///\name Iterate over our default and per-package use flags
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const UseConfigEntry> UseConfigIterator;
+
+ UseConfigIterator begin_use_config(const QualifiedPackageName & q) const;
+
+ UseConfigIterator end_use_config(const QualifiedPackageName & q) const;
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig,
+ const std::pair<UseFlagName, UseFlagState> > DefaultUseIterator;
+
+ DefaultUseIterator begin_default_use() const;
+
+ DefaultUseIterator end_default_use() const;
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig, const std::string> UseMinusStarIterator;
+
+ UseMinusStarIterator begin_use_prefixes_with_minus_star() const;
+ UseMinusStarIterator end_use_prefixes_with_minus_star() const;
+
+ typedef libwrapiter::ForwardIterator<DefaultConfig,
+ const std::pair<PackageDepAtom::ConstPointer, std::string> > PackageUseMinusStarIterator;
+
+ PackageUseMinusStarIterator begin_package_use_prefixes_with_minus_star(const QualifiedPackageName &) const;
+ PackageUseMinusStarIterator end_package_use_prefixes_with_minus_star(const QualifiedPackageName &) const;
+
+ ///}
+
+ /**
+ * Our bashrc files.
+ */
+ std::string bashrc_files() const;
+
+ /**
+ * The paludis command.
+ */
+ std::string paludis_command() const;
+
+ /**
+ * Set the paludis command.
+ */
+ void set_paludis_command(const std::string & s);
+
+ /**
+ * The ROOT.
+ */
+ std::string root() const;
+
+ /**
+ * The config directory.
+ */
+ std::string config_dir() const;
+
+ ///\name Iterate over our mirrors
+ ///\{
+
+ typedef EnvironmentMirrorIterator MirrorIterator;
+
+ MirrorIterator begin_mirrors(const std::string & m) const;
+
+ MirrorIterator end_mirrors(const std::string & m) const;
+
+ ///\}
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/environment/default/default_environment.cc b/0.8.0/paludis/environment/default/default_environment.cc
new file mode 100644
index 0000000..a0a1f01
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_environment.cc
@@ -0,0 +1,530 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <list>
+#include <paludis/config_file.hh>
+#include <paludis/environment/default/default_config.hh>
+#include <paludis/environment/default/default_environment.hh>
+#include <paludis/match_package.hh>
+#include <paludis/package_database.hh>
+#include <paludis/repository.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/is_file_with_extension.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/system.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/util/dir_iterator.hh>
+#include <vector>
+
+using namespace paludis;
+
+DefaultEnvironment::DefaultEnvironment() :
+ Environment(PackageDatabase::Pointer(new PackageDatabase(this)))
+{
+ Context context("When loading default environment:");
+
+ for (DefaultConfig::RepositoryIterator r(DefaultConfig::get_instance()->begin_repositories()),
+ r_end(DefaultConfig::get_instance()->end_repositories()) ; r != r_end ; ++r)
+ package_database()->add_repository(
+ RepositoryMaker::get_instance()->find_maker(r->format)(
+ this, package_database().raw_pointer(), r->keys));
+}
+
+DefaultEnvironment::~DefaultEnvironment()
+{
+}
+
+bool
+DefaultEnvironment::query_use(const UseFlagName & f, const PackageDatabaseEntry * e) const
+{
+ /* first check package database use masks... */
+ const Repository * const repo((e ?
+ package_database()->fetch_repository(e->repository).raw_pointer() :
+ 0));
+
+ if (repo && repo->use_interface)
+ {
+ if (repo->use_interface->query_use_mask(f, e))
+ return false;
+ if (repo->use_interface->query_use_force(f, e))
+ return true;
+ }
+
+ /* check use: per package user config */
+ if (e)
+ {
+ UseFlagState s(use_unspecified);
+
+ for (DefaultConfig::UseConfigIterator
+ u(DefaultConfig::get_instance()->begin_use_config(e->name)),
+ u_end(DefaultConfig::get_instance()->end_use_config(e->name)) ;
+ u != u_end ; ++u)
+ {
+ if (f != u->flag_name)
+ continue;
+
+ if (! match_package(this, *u->dep_atom, *e))
+ continue;
+
+ switch (u->flag_state)
+ {
+ case use_enabled:
+ s = use_enabled;
+ continue;
+
+ case use_disabled:
+ s = use_disabled;
+ continue;
+
+ case use_unspecified:
+ continue;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad state");
+ }
+
+ do
+ {
+ switch (s)
+ {
+ case use_enabled:
+ return true;
+
+ case use_disabled:
+ return false;
+
+ case use_unspecified:
+ continue;
+ }
+ throw InternalError(PALUDIS_HERE, "Bad state");
+ } while (false);
+
+ /* and the -* bit */
+ for (DefaultConfig::PackageUseMinusStarIterator
+ i(DefaultConfig::get_instance()->begin_package_use_prefixes_with_minus_star(e->name)),
+ i_end(DefaultConfig::get_instance()->end_package_use_prefixes_with_minus_star(e->name)) ;
+ i != i_end ; ++i)
+ {
+ if (! match_package(this, *i->first, *e))
+ continue;
+
+ if (0 == i->second.compare(0, i->second.length(), stringify(f), 0, i->second.length()))
+ return false;
+ }
+ }
+
+ /* check use: general user config */
+ do
+ {
+ UseFlagState state(use_unspecified);
+
+ for (DefaultConfig::DefaultUseIterator
+ u(DefaultConfig::get_instance()->begin_default_use()),
+ u_end(DefaultConfig::get_instance()->end_default_use()) ;
+ u != u_end ; ++u)
+ if (f == u->first)
+ state = u->second;
+
+ switch (state)
+ {
+ case use_enabled:
+ return true;
+
+ case use_disabled:
+ return false;
+
+ case use_unspecified:
+ continue;
+ }
+
+ throw InternalError(PALUDIS_HERE, "bad state " + stringify(state));
+ } while (false);
+
+ /* and -* again. slight gotcha: "* -*" should not override use expand things. if it
+ * does, USERLAND etc get emptied. */
+ bool consider_minus_star(true);
+ if (e && repo && repo->use_interface)
+ {
+ UseFlagNameCollection::ConstPointer prefixes(repo->use_interface->use_expand_prefixes());
+ for (UseFlagNameCollection::Iterator i(prefixes->begin()), i_end(prefixes->end()) ;
+ i != i_end ; ++i)
+ if (0 == i->data().compare(0, i->data().length(), stringify(f), 0, i->data().length()))
+ {
+ consider_minus_star = false;
+ break;
+ }
+ }
+
+ for (DefaultConfig::UseMinusStarIterator
+ i(DefaultConfig::get_instance()->begin_use_prefixes_with_minus_star()),
+ i_end(DefaultConfig::get_instance()->end_use_prefixes_with_minus_star()) ;
+ i != i_end ; ++i)
+ {
+ if ((! consider_minus_star) && i->empty())
+ continue;
+ if (0 == i->compare(0, i->length(), stringify(f), 0, i->length()))
+ return false;
+ }
+
+ /* check use: package database config */
+ if (repo && repo->use_interface)
+ {
+ switch (repo->use_interface->query_use(f, e))
+ {
+ case use_disabled:
+ case use_unspecified:
+ return false;
+
+ case use_enabled:
+ return true;
+ }
+
+ throw InternalError(PALUDIS_HERE, "bad state");
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+DefaultEnvironment::accept_keyword(const KeywordName & keyword, const PackageDatabaseEntry * const d) const
+{
+ if (keyword == KeywordName("*"))
+ return true;
+
+ Context context("When checking accept_keyword of '" + stringify(keyword) +
+ (d ? "' for " + stringify(*d) : stringify("'")) + ":");
+
+ bool result(false);
+
+ if (d)
+ for (DefaultConfig::PackageKeywordsIterator
+ k(DefaultConfig::get_instance()->begin_package_keywords(d->name)),
+ k_end(DefaultConfig::get_instance()->end_package_keywords(d->name)) ;
+ k != k_end ; ++k)
+ {
+ if (! match_package(this, k->first, d))
+ continue;
+
+ result |= k->second == keyword;
+ }
+
+ result |= DefaultConfig::get_instance()->end_default_keywords() !=
+ std::find(DefaultConfig::get_instance()->begin_default_keywords(),
+ DefaultConfig::get_instance()->end_default_keywords(),
+ keyword);
+
+ return result;
+}
+
+bool
+DefaultEnvironment::accept_license(const std::string & license, const PackageDatabaseEntry * const d) const
+{
+ if (license == "*")
+ return true;
+
+ Context context("When checking license of '" + license +
+ (d ? "' for " + stringify(*d) : stringify("'")) + ":");
+
+ bool result(false);
+
+ if (d)
+ for (DefaultConfig::PackageLicensesIterator
+ k(DefaultConfig::get_instance()->begin_package_licenses(d->name)),
+ k_end(DefaultConfig::get_instance()->end_package_licenses(d->name)) ;
+ k != k_end ; ++k)
+ {
+ if (! match_package(this, k->first, d))
+ continue;
+
+ result |= k->second == license;
+ result |= k->second == "*";
+ }
+
+ result |= DefaultConfig::get_instance()->end_default_licenses() !=
+ std::find(DefaultConfig::get_instance()->begin_default_licenses(),
+ DefaultConfig::get_instance()->end_default_licenses(),
+ license);
+
+ result |= DefaultConfig::get_instance()->end_default_licenses() !=
+ std::find(DefaultConfig::get_instance()->begin_default_licenses(),
+ DefaultConfig::get_instance()->end_default_licenses(),
+ "*");
+
+ return result;
+}
+
+bool
+DefaultEnvironment::query_user_masks(const PackageDatabaseEntry & d) const
+{
+ for (DefaultConfig::UserMasksIterator
+ k(DefaultConfig::get_instance()->begin_user_masks(d.name)),
+ k_end(DefaultConfig::get_instance()->end_user_masks(d.name)) ;
+ k != k_end ; ++k)
+ {
+ if (! match_package(this, *k, d))
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool
+DefaultEnvironment::query_user_unmasks(const PackageDatabaseEntry & d) const
+{
+ for (DefaultConfig::UserMasksIterator
+ k(DefaultConfig::get_instance()->begin_user_unmasks(d.name)),
+ k_end(DefaultConfig::get_instance()->end_user_unmasks(d.name)) ;
+ k != k_end ; ++k)
+ {
+ if (! match_package(this, *k, d))
+ continue;
+
+ return true;
+ }
+
+ return false;
+}
+
+std::string
+DefaultEnvironment::bashrc_files() const
+{
+ return DefaultConfig::get_instance()->bashrc_files();
+}
+
+std::string
+DefaultEnvironment::paludis_command() const
+{
+ return DefaultConfig::get_instance()->paludis_command();
+}
+
+namespace
+{
+ void add_one_hook(const std::string & base, std::list<FSEntry> & result)
+ {
+ try
+ {
+ FSEntry r(base);
+ if (r.is_directory())
+ {
+ Log::get_instance()->message(ll_debug, lc_no_context, "Adding hook directory '"
+ + base + "'");
+ result.push_back(r);
+ }
+ else
+ Log::get_instance()->message(ll_debug, lc_no_context, "Skipping hook directory candidate '"
+ + base + "'");
+ }
+ catch (const FSError & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context, "Caught exception '" +
+ e.message() + "' (" + e.what() + ") when checking hook "
+ "directory '" + base + "'");
+ }
+ }
+
+ const std::list<FSEntry> & get_hook_dirs()
+ {
+ static std::list<FSEntry> result;
+ static bool done_hooks(false);
+ if (! done_hooks)
+ {
+ add_one_hook(DefaultConfig::get_instance()->config_dir() + "/hooks", result);
+ if (getenv_with_default("PALUDIS_NO_GLOBAL_HOOKS", "").empty())
+ {
+ add_one_hook(LIBEXECDIR "/paludis/hooks", result);
+ add_one_hook(DATADIR "/paludis/hooks", result);
+ }
+ done_hooks = true;
+ }
+ return result;
+ }
+
+ struct Hooker
+ {
+ Hook hook;
+ std::string paludis_command;
+
+ Hooker(const Hook & h, const std::string & p) :
+ hook(h),
+ paludis_command(p)
+ {
+ }
+
+ void operator() (const FSEntry & f) const;
+ };
+
+ void
+ Hooker::operator() (const FSEntry & f) const
+ {
+ Context context("When running hook script '" + stringify(f) +
+ "' for hook '" + hook.name() + "':");
+ Log::get_instance()->message(ll_debug, lc_no_context, "Starting hook script '" +
+ stringify(f) + "' for '" + hook.name() + "'");
+
+ MakeEnvCommand cmd(make_env_command("bash '" + stringify(f) + "'")
+ ("ROOT", DefaultConfig::get_instance()->root())
+ ("HOOK", hook.name())
+ ("HOOK_LOG_LEVEL", stringify(Log::get_instance()->log_level()))
+ ("HOOK_CONFIG_SUFFIX", DefaultConfig::config_suffix())
+ ("PALUDIS_EBUILD_DIR", getenv_with_default("PALUDIS_EBUILD_DIR", LIBEXECDIR "/paludis"))
+ ("PALUDIS_COMMAND", paludis_command));
+
+ for (Hook::Iterator h(hook.begin()), h_end(hook.end()) ; h != h_end ; ++h)
+ cmd = cmd(h->first, h->second);
+
+ int exit_status(run_command(cmd));
+ if (0 == exit_status)
+ Log::get_instance()->message(ll_debug, lc_no_context, "Hook '" + stringify(f)
+ + "' returned success '" + stringify(exit_status) + "'");
+ else
+ Log::get_instance()->message(ll_warning, lc_no_context, "Hook '" + stringify(f)
+ + "' returned failure '" + stringify(exit_status) + "'");
+ }
+}
+
+void
+DefaultEnvironment::perform_hook(const Hook & hook) const
+{
+ Context context("When triggering hook '" + hook.name() + "'");
+ Log::get_instance()->message(ll_debug, lc_no_context, "Starting hook '" + hook.name() + "'");
+
+ const std::list<FSEntry> & hook_dirs_ref(get_hook_dirs());
+
+ for (std::list<FSEntry>::const_iterator h(hook_dirs_ref.begin()),
+ h_end(hook_dirs_ref.end()) ; h != h_end ; ++h)
+ {
+ FSEntry hh(*h / hook.name());
+ if (! hh.is_directory())
+ continue;
+
+ std::list<FSEntry> hooks;
+ std::copy(DirIterator(hh), DirIterator(),
+ filter_inserter(std::back_inserter(hooks), IsFileWithExtension(".bash")));
+ std::for_each(hooks.begin(), hooks.end(), Hooker(hook, paludis_command()));
+ }
+}
+
+std::string
+DefaultEnvironment::hook_dirs() const
+{
+ const std::list<FSEntry> & hook_dirs_ref(get_hook_dirs());
+ return join(hook_dirs_ref.begin(), hook_dirs_ref.end(), " ");
+}
+
+CompositeDepAtom::Pointer
+DefaultEnvironment::local_package_set(const std::string & s) const
+{
+ Context context("When looking for package set '" + s + "' in default environment:");
+
+ FSEntry ff(FSEntry(DefaultConfig::get_instance()->config_dir()) / "sets" / (s + ".conf"));
+ if (ff.exists())
+ {
+ LineConfigFile f(ff);
+ AllDepAtom::Pointer result(new AllDepAtom);
+ GeneralSetDepTag::Pointer tag(new GeneralSetDepTag(s));
+
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+
+ if (1 == tokens.size())
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Line '" + *line + "' in set file '"
+ + stringify(ff) + "' does not specify '*' or '?', assuming '*'");
+ PackageDepAtom::Pointer atom(new PackageDepAtom(tokens.at(0)));
+ atom->set_tag(tag);
+ result->add_child(atom);
+ }
+ else if ("*" == tokens.at(0))
+ {
+ PackageDepAtom::Pointer atom(new PackageDepAtom(tokens.at(1)));
+ atom->set_tag(tag);
+ result->add_child(atom);
+ }
+ else if ("?" == tokens.at(0))
+ {
+ PackageDepAtom::Pointer p(new PackageDepAtom(tokens.at(1)));
+ p->set_tag(tag);
+ if (! package_database()->query(
+ PackageDepAtom::Pointer(new PackageDepAtom(p->package())),
+ is_installed_only)->empty())
+ result->add_child(p);
+ }
+ else
+ Log::get_instance()->message(ll_warning, lc_context, "Line '" + *line + "' in set file '"
+ + stringify(ff) + "' does not start with '*' or '?' token, skipping");
+
+ if (tokens.size() > 2)
+ Log::get_instance()->message(ll_warning, lc_context, "Line '" + *line + "' in set file '"
+ + stringify(ff) + "' has trailing garbage");
+ }
+
+ return result;
+ }
+
+ return DepAtom::Pointer(0);
+}
+
+DefaultEnvironment::MirrorIterator
+DefaultEnvironment::begin_mirrors(const std::string & mirror) const
+{
+ return DefaultConfig::get_instance()->begin_mirrors(mirror);
+}
+
+DefaultEnvironment::MirrorIterator
+DefaultEnvironment::end_mirrors(const std::string & mirror) const
+{
+ return DefaultConfig::get_instance()->end_mirrors(mirror);
+}
+
+UseFlagNameCollection::ConstPointer
+DefaultEnvironment::known_use_expand_names(const UseFlagName & prefix, const PackageDatabaseEntry * pde) const
+{
+ UseFlagNameCollection::Pointer result(new UseFlagNameCollection::Concrete);
+
+ std::string prefix_lower;
+ std::transform(prefix.data().begin(), prefix.data().end(), std::back_inserter(prefix_lower), &::tolower);
+ for (DefaultConfig::DefaultUseIterator i(DefaultConfig::get_instance()->begin_default_use()),
+ i_end(DefaultConfig::get_instance()->end_default_use()) ; i != i_end ; ++i)
+ if (i->first.data().length() > prefix_lower.length() &&
+ 0 == i->first.data().compare(0, prefix_lower.length(), prefix_lower, 0, prefix_lower.length()))
+ result->insert(i->first);
+
+ if (pde)
+ for (DefaultConfig::UseConfigIterator i(DefaultConfig::get_instance()->begin_use_config(pde->name)),
+ i_end(DefaultConfig::get_instance()->end_use_config(pde->name)) ; i != i_end ; ++i)
+ if (i->flag_name.data().length() > prefix_lower.length() &&
+ 0 == i->flag_name.data().compare(0, prefix_lower.length(), prefix_lower, 0, prefix_lower.length()))
+ result->insert(i->flag_name);
+
+ Log::get_instance()->message(ll_debug, lc_no_context, "DefaultEnvironment::known_use_expand_names("
+ + stringify(prefix) + ", " + (pde ? stringify(*pde) : stringify("0")) + ") -> ("
+ + join(result->begin(), result->end(), ", ") + ")");
+ return result;
+}
+
diff --git a/0.8.0/paludis/environment/default/default_environment.hh b/0.8.0/paludis/environment/default/default_environment.hh
new file mode 100644
index 0000000..058a246
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_environment.hh
@@ -0,0 +1,81 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_DEFAULT_ENVIRONMENT_HH
+#define PALUDIS_GUARD_PALUDIS_DEFAULT_ENVIRONMENT_HH 1
+
+#include <paludis/package_database.hh>
+#include <paludis/environment.hh>
+
+/** \file
+ * Declarations for the DefaultEnvironment class.
+ *
+ * \ingroup grpdefaultenvironment
+ */
+
+namespace paludis
+{
+ /**
+ * The DefaultEnvironment is an Environment that corresponds to the normal
+ * operating evironment.
+ *
+ * \ingroup grpdefaultenvironment
+ */
+ class PALUDIS_VISIBLE DefaultEnvironment :
+ public Environment,
+ public InstantiationPolicy<DefaultEnvironment, instantiation_method::SingletonAsNeededTag>
+ {
+ friend class InstantiationPolicy<DefaultEnvironment, instantiation_method::SingletonAsNeededTag>;
+
+ private:
+ DefaultEnvironment();
+
+ ~DefaultEnvironment();
+
+ protected:
+ CompositeDepAtom::Pointer local_package_set(const std::string &) const;
+
+ public:
+ virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry *) const;
+
+ virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const;
+
+ virtual bool accept_license(const std::string &, const PackageDatabaseEntry * const) const;
+
+ virtual bool query_user_masks(const PackageDatabaseEntry &) const;
+
+ virtual bool query_user_unmasks(const PackageDatabaseEntry &) const;
+
+ virtual std::string bashrc_files() const;
+
+ virtual std::string hook_dirs() const;
+
+ virtual std::string paludis_command() const;
+
+ virtual UseFlagNameCollection::ConstPointer known_use_expand_names(const UseFlagName &,
+ const PackageDatabaseEntry *) const;
+
+ virtual void perform_hook(const Hook & hook) const;
+
+ virtual MirrorIterator begin_mirrors(const std::string & mirror) const;
+
+ virtual MirrorIterator end_mirrors(const std::string & mirror) const;
+ };
+}
+#endif
diff --git a/0.8.0/paludis/environment/default/default_environment_TEST.cc b/0.8.0/paludis/environment/default/default_environment_TEST.cc
new file mode 100644
index 0000000..fcad357
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_environment_TEST.cc
@@ -0,0 +1,131 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "default_environment.hh"
+#include "default_config.hh"
+#include <paludis/util/fs_entry.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <cstdlib>
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ struct TestDefaultEnvironmentUse : TestCase
+ {
+ TestDefaultEnvironmentUse() : TestCase("use") { }
+
+ void run()
+ {
+ setenv("PALUDIS_HOME", stringify(FSEntry::cwd() / "default_environment_TEST_dir" / "home1").c_str(), 1);
+ unsetenv("PALUDIS_SKIP_CONFIG");
+ DefaultConfig::destroy_instance();
+ DefaultEnvironment::destroy_instance();
+
+ Environment * env(DefaultEnvironment::get_instance());
+
+ TEST_CHECK(env->query_use(UseFlagName("foo"), 0));
+ TEST_CHECK(! env->query_use(UseFlagName("foofoo"), 0));
+
+ PackageDatabaseEntry pde(QualifiedPackageName("cat-one/pkg-one"), VersionSpec("1"), RepositoryName("foo"));
+ TEST_CHECK(env->query_use(UseFlagName("foo"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("foofoo"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("moo"), &pde));
+
+ TEST_CHECK(env->query_use(UseFlagName("more_exp_one"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("exp_two"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("exp_one"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("third_exp_two"), &pde));
+
+ PackageDatabaseEntry f(QualifiedPackageName("cat-one/pkg-two"), VersionSpec("3"), RepositoryName("foo"));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &f));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_two"), &f));
+ }
+ } default_environment_use_test;
+
+ struct TestDefaultEnvironmentUseMinusStar : TestCase
+ {
+ TestDefaultEnvironmentUseMinusStar() : TestCase("use -*") { }
+
+ void run()
+ {
+ setenv("PALUDIS_HOME", stringify(FSEntry::cwd() / "default_environment_TEST_dir" / "home2").c_str(), 1);
+ unsetenv("PALUDIS_SKIP_CONFIG");
+ DefaultConfig::destroy_instance();
+ DefaultEnvironment::destroy_instance();
+
+ Environment * env(DefaultEnvironment::get_instance());
+
+ TEST_CHECK(env->query_use(UseFlagName("foo"), 0));
+ TEST_CHECK(! env->query_use(UseFlagName("foofoo"), 0));
+
+ PackageDatabaseEntry pde(QualifiedPackageName("cat-one/pkg-one"), VersionSpec("1"), RepositoryName("foo"));
+ TEST_CHECK(env->query_use(UseFlagName("foo"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("foofoo"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("moo"), &pde));
+
+ TEST_CHECK(env->query_use(UseFlagName("more_exp_one"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("exp_two"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("exp_one"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("third_exp_two"), &pde));
+
+ PackageDatabaseEntry f(QualifiedPackageName("cat-one/pkg-two"), VersionSpec("3"), RepositoryName("foo"));
+ TEST_CHECK(! env->query_use(UseFlagName("third_exp_one"), &f));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_two"), &f));
+ }
+ } default_environment_use_test_minus_star;
+
+ struct TestDefaultEnvironmentUseMinusPartialStar : TestCase
+ {
+ TestDefaultEnvironmentUseMinusPartialStar() : TestCase("use -* partial") { }
+
+ void run()
+ {
+ setenv("PALUDIS_HOME", stringify(FSEntry::cwd() / "default_environment_TEST_dir" / "home3").c_str(), 1);
+ unsetenv("PALUDIS_SKIP_CONFIG");
+ DefaultConfig::destroy_instance();
+ DefaultEnvironment::destroy_instance();
+
+ Environment * env(DefaultEnvironment::get_instance());
+
+ TEST_CHECK(env->query_use(UseFlagName("foo"), 0));
+ TEST_CHECK(! env->query_use(UseFlagName("foofoo"), 0));
+
+ PackageDatabaseEntry pde(QualifiedPackageName("cat-one/pkg-one"), VersionSpec("1"), RepositoryName("foo"));
+ TEST_CHECK(env->query_use(UseFlagName("foo"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("foofoo"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("moo"), &pde));
+
+ TEST_CHECK(env->query_use(UseFlagName("more_exp_one"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("exp_two"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("exp_one"), &pde));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_one"), &pde));
+ TEST_CHECK(! env->query_use(UseFlagName("third_exp_two"), &pde));
+
+ PackageDatabaseEntry f(QualifiedPackageName("cat-one/pkg-two"), VersionSpec("3"), RepositoryName("foo"));
+ TEST_CHECK(! env->query_use(UseFlagName("third_exp_one"), &f));
+ TEST_CHECK(env->query_use(UseFlagName("third_exp_two"), &f));
+ }
+ } default_environment_use_test_minus_star_partial;
+}
+
diff --git a/0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh b/0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh
new file mode 100755
index 0000000..3cd5c8d
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_environment_TEST_cleanup.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d default_environment_TEST_dir ] ; then
+ rm -fr default_environment_TEST_dir
+else
+ true
+fi
+
+
+
diff --git a/0.8.0/paludis/environment/default/default_environment_TEST_setup.sh b/0.8.0/paludis/environment/default/default_environment_TEST_setup.sh
new file mode 100755
index 0000000..bb19c8a
--- /dev/null
+++ b/0.8.0/paludis/environment/default/default_environment_TEST_setup.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir default_environment_TEST_dir || exit 2
+cd default_environment_TEST_dir || exit 3
+
+mkdir -p repo/{profile,profiles,cat-one/pkg-one}
+cat <<END > repo/profiles/repo_name
+foo
+END
+cat <<END > repo/profiles/categories
+cat-one
+END
+cat <<END > repo/profile/make.defaults
+ARCH="foo"
+USE="moo"
+USE_EXPAND="EXP MORE_EXP THIRD_EXP"
+EXP="one"
+MORE_EXP="one"
+THIRD_EXP="one"
+END
+
+mkdir -p home1/.paludis/repositories
+cat <<END > home1/.paludis/use.conf
+* foo bar baz -fnord
+* EXP: two
+>=cat-one/pkg-two-2 THIRD_EXP: two
+END
+cat <<END > home1/.paludis/keywords.conf
+* keyword
+END
+cat <<END > home1/.paludis/licenses.conf
+* keyword
+END
+cat <<END > home1/.paludis/repositories/foo.conf
+format = portage
+location = `pwd`/repo
+profiles = `pwd`/repo/profile
+cache = /var/empty
+END
+
+mkdir -p home2/.paludis/repositories
+cat <<END > home2/.paludis/use.conf
+* -* foo bar baz -fnord
+* EXP: -* two
+>=cat-one/pkg-two-2 THIRD_EXP: -* two
+END
+cat <<END > home2/.paludis/keywords.conf
+* keyword
+END
+cat <<END > home2/.paludis/licenses.conf
+* *
+END
+cat <<END > home2/.paludis/repositories/foo.conf
+format = portage
+location = `pwd`/repo
+profiles = `pwd`/repo/profile
+cache = /var/empty
+END
+
+mkdir -p home3/.paludis/repositories
+cat <<END > home3/.paludis/use.conf
+* foo bar baz -fnord
+* EXP: -* two
+>=cat-one/pkg-two-2 THIRD_EXP: -* two
+END
+cat <<END > home3/.paludis/keywords.conf
+* keyword
+END
+cat <<END > home3/.paludis/licenses.conf
+* *
+END
+cat <<END > home3/.paludis/repositories/foo.conf
+format = portage
+location = `pwd`/repo
+profiles = `pwd`/repo/profile
+cache = /var/empty
+END
+
+
diff --git a/0.8.0/paludis/environment/no_config/Makefile.am b/0.8.0/paludis/environment/no_config/Makefile.am
new file mode 100644
index 0000000..4c45031
--- /dev/null
+++ b/0.8.0/paludis/environment/no_config/Makefile.am
@@ -0,0 +1,41 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda ihateautomake.cc ihateautomake.o
+DISTCLEANFILES = no_config_environment-sr.hh no_config_environment-sr.cc
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+libpaludisnoconfigenvironment_la_SOURCES = \
+ no_config_environment.cc no_config_environment.hh
+
+libpaludisnoconfigenvironment_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+libpaludisnoconfigenvironment_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/repositories/portage/libpaludisportagerepository.la
+
+lib_LTLIBRARIES = libpaludisnoconfigenvironment.la
+paludis_environment_no_config_includedir = $(includedir)/paludis/environment/no_config
+paludis_environment_no_config_include_HEADERS = \
+ no_config_environment.hh \
+ no_config_environment-sr.hh
+
+EXTRA_DIST = \
+ no_config_environment-sr.hh \
+ no_config_environment-sr.cc \
+ no_config_environment.sr
+
+BUILT_SOURCES = \
+ no_config_environment-sr.hh \
+ no_config_environment-sr.cc
+
+no_config_environment-sr.hh : no_config_environment.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/no_config_environment.sr > $@
+
+no_config_environment-sr.cc : no_config_environment.sr $(top_srcdir)/misc/make_sr.bash
+ $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/no_config_environment.sr > $@
+
+
diff --git a/0.8.0/paludis/environment/no_config/no_config_environment.cc b/0.8.0/paludis/environment/no_config/no_config_environment.cc
new file mode 100644
index 0000000..b9022fa
--- /dev/null
+++ b/0.8.0/paludis/environment/no_config/no_config_environment.cc
@@ -0,0 +1,197 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "no_config_environment.hh"
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/util/log.hh>
+#include <paludis/repositories/portage/portage_repository.hh>
+#include <paludis/config_file.hh>
+#include <set>
+
+using namespace paludis;
+
+#include <paludis/environment/no_config/no_config_environment-sr.cc>
+
+namespace paludis
+{
+ template<>
+ struct Implementation<NoConfigEnvironment> :
+ InternalCounted<Implementation<NoConfigEnvironment> >
+ {
+ const FSEntry top_level_dir;
+ bool accept_unstable;
+ std::set<KeywordName> accepted_keywords;
+ std::list<NoConfigEnvironmentProfilesDescLine> profiles;
+
+ Implementation(Environment * const env, const NoConfigEnvironmentParams & params) :
+ top_level_dir(params.repository_dir),
+ accept_unstable(params.accept_unstable)
+ {
+ Context context("When initialising NoConfigEnvironment at '" + stringify(params.repository_dir) + "':");
+
+ try
+ {
+ LineConfigFile profiles_desc(params.repository_dir / "profiles" / "profiles.desc");
+ for (LineConfigFile::Iterator line(profiles_desc.begin()), line_end(profiles_desc.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens));
+
+ if (tokens.size() != 3)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Skipping invalid line '"
+ + *line + "'");
+ continue;
+ }
+
+ profiles.push_back(NoConfigEnvironmentProfilesDescLine::create()
+ .path(params.repository_dir / "profiles" / tokens.at(1))
+ .status(tokens.at(2))
+ .arch(tokens.at(0))
+ .db(PackageDatabase::Pointer(new PackageDatabase(env))));
+ }
+ }
+ catch (const ConfigFileError & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Could not load profiles.desc due to exception '"
+ + e.message() + "' (" + e.what() + ")");
+ }
+
+ if (profiles.empty())
+ profiles.push_back(NoConfigEnvironmentProfilesDescLine::create()
+ .path(params.repository_dir / "profiles" / "base")
+ .status("default")
+ .arch("default")
+ .db(PackageDatabase::Pointer(new PackageDatabase(env))));
+
+ for (std::list<NoConfigEnvironmentProfilesDescLine>::iterator
+ p(profiles.begin()), p_end(profiles.end()) ; p != p_end ; ++p)
+ {
+ AssociativeCollection<std::string, std::string>::Pointer keys(
+ new AssociativeCollection<std::string, std::string>::Concrete);
+
+ keys->insert("format", "portage");
+ keys->insert("location", stringify(params.repository_dir));
+ keys->insert("profiles", stringify(p->path));
+
+ p->db->add_repository(RepositoryMaker::get_instance()->find_maker("portage")(env,
+ p->db.raw_pointer(), keys));
+ p->db->add_repository(RepositoryMaker::get_instance()->find_maker("virtuals")(env,
+ p->db.raw_pointer(), AssociativeCollection<std::string, std::string>::Pointer(0)));
+ }
+ }
+ };
+
+ /* This goat is for Dave Wickham */
+}
+
+NoConfigEnvironment::NoConfigEnvironment(const NoConfigEnvironmentParams & params) :
+ PrivateImplementationPattern<NoConfigEnvironment>(
+ new Implementation<NoConfigEnvironment>(this, params)),
+ Environment(_imp->profiles.begin()->db)
+{
+ /* do this to load accepted_keywords etc */
+ set_profile(ProfilesIterator(_imp->profiles.begin()));
+}
+
+NoConfigEnvironment::~NoConfigEnvironment()
+{
+}
+
+std::string
+NoConfigEnvironment::paludis_command() const
+{
+ return "false";
+}
+
+FSEntry
+NoConfigEnvironment::main_repository_dir() const
+{
+ return _imp->top_level_dir;
+}
+
+void
+NoConfigEnvironment::set_profile(const NoConfigEnvironment::ProfilesIterator & i)
+{
+ change_package_database(i->db);
+
+ _imp->accepted_keywords.clear();
+ _imp->accepted_keywords.insert(KeywordName("*"));
+ _imp->accepted_keywords.insert(KeywordName(i->arch));
+ if (_imp->accept_unstable)
+ _imp->accepted_keywords.insert(KeywordName("~" + i->arch));
+}
+
+void
+NoConfigEnvironment::set_profile(const FSEntry & location)
+{
+ Context context("When setting NoConfigEnvironment profile to '" + stringify(location) + "':");
+
+ for (ProfilesIterator i(begin_profiles()), i_end(end_profiles()) ; i != i_end ; ++i)
+ if (i->path == location)
+ {
+ set_profile(i);
+ return;
+ }
+
+ Log::get_instance()->message(ll_warning, lc_context, "No profiles.desc entry found, faking it");
+
+ PackageDatabase::Pointer db(new PackageDatabase(this));
+ AssociativeCollection<std::string, std::string>::Pointer keys(
+ new AssociativeCollection<std::string, std::string>::Concrete);
+
+ keys->insert("format", "portage");
+ keys->insert("location", stringify(_imp->top_level_dir));
+ keys->insert("profiles", stringify(location));
+
+ PortageRepository::Pointer p(RepositoryMaker::get_instance()->find_maker("portage")(this,
+ db.raw_pointer(), keys));
+ db->add_repository(RepositoryMaker::get_instance()->find_maker("virtuals")(this,
+ db.raw_pointer(), AssociativeCollection<std::string, std::string>::Pointer(0)));
+ db->add_repository(p);
+
+ _imp->accepted_keywords.clear();
+ _imp->accepted_keywords.insert(KeywordName("*"));
+ _imp->accepted_keywords.insert(KeywordName(p->profile_variable("ARCH")));
+ if (_imp->accept_unstable)
+ _imp->accepted_keywords.insert(KeywordName("~" + p->profile_variable("ARCH")));
+
+ change_package_database(db);
+}
+
+bool
+NoConfigEnvironment::accept_keyword(const KeywordName & k, const PackageDatabaseEntry * const) const
+{
+ return _imp->accepted_keywords.end() != _imp->accepted_keywords.find(k);
+}
+
+NoConfigEnvironment::ProfilesIterator
+NoConfigEnvironment::begin_profiles() const
+{
+ return ProfilesIterator(_imp->profiles.begin());
+}
+
+NoConfigEnvironment::ProfilesIterator
+NoConfigEnvironment::end_profiles() const
+{
+ return ProfilesIterator(_imp->profiles.end());
+}
+
diff --git a/0.8.0/paludis/environment/no_config/no_config_environment.hh b/0.8.0/paludis/environment/no_config/no_config_environment.hh
new file mode 100644
index 0000000..37837f1
--- /dev/null
+++ b/0.8.0/paludis/environment/no_config/no_config_environment.hh
@@ -0,0 +1,57 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_ENVIRONMENT_NO_CONFIG_NO_CONFIG_ENVIRONMENT_HH
+#define PALUDIS_GUARD_PALUDIS_ENVIRONMENT_NO_CONFIG_NO_CONFIG_ENVIRONMENT_HH 1
+
+#include <paludis/environment.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+namespace paludis
+{
+#include <paludis/environment/no_config/no_config_environment-sr.hh>
+
+ class PALUDIS_VISIBLE NoConfigEnvironment :
+ private PrivateImplementationPattern<NoConfigEnvironment>,
+ public Environment
+ {
+ public:
+ NoConfigEnvironment(const NoConfigEnvironmentParams & params);
+
+ virtual ~NoConfigEnvironment();
+
+ virtual std::string paludis_command() const;
+
+ FSEntry main_repository_dir() const;
+
+ virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const;
+
+ typedef libwrapiter::ForwardIterator<NoConfigEnvironment, const NoConfigEnvironmentProfilesDescLine> ProfilesIterator;
+ ProfilesIterator begin_profiles() const;
+ ProfilesIterator end_profiles() const;
+
+ void set_profile(const FSEntry & location);
+ void set_profile(const ProfilesIterator & iter);
+
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/environment/no_config/no_config_environment.sr b/0.8.0/paludis/environment/no_config/no_config_environment.sr
new file mode 100644
index 0000000..0db14bb
--- /dev/null
+++ b/0.8.0/paludis/environment/no_config/no_config_environment.sr
@@ -0,0 +1,19 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_NoConfigEnvironmentParams()
+{
+ key repository_dir "FSEntry"
+ key accept_unstable bool
+ allow_named_args
+}
+
+make_class_NoConfigEnvironmentProfilesDescLine()
+{
+ key path FSEntry
+ key arch std::string
+ key status std::string
+ key db PackageDatabase::Pointer
+ allow_named_args
+}
+
diff --git a/0.8.0/paludis/environment/test/Makefile.am b/0.8.0/paludis/environment/test/Makefile.am
new file mode 100644
index 0000000..b48bf1b
--- /dev/null
+++ b/0.8.0/paludis/environment/test/Makefile.am
@@ -0,0 +1,21 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda ihateautomake.cc ihateautomake.o
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+libpaludistestenvironment_la_SOURCES = \
+ test_environment.cc test_environment.hh
+
+libpaludistestenvironment_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+libpaludistestenvironment_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/libpaludis.la
+
+lib_LTLIBRARIES = libpaludistestenvironment.la
+paludis_environment_test_includedir = $(includedir)/paludis/environment/test
+paludis_environment_test_include_HEADERS = test_environment.hh
+
diff --git a/0.8.0/paludis/environment/test/test_environment.cc b/0.8.0/paludis/environment/test/test_environment.cc
new file mode 100644
index 0000000..7e1ce46
--- /dev/null
+++ b/0.8.0/paludis/environment/test/test_environment.cc
@@ -0,0 +1,85 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/environment/test/test_environment.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <map>
+#include <string>
+
+/** \file
+ * Implementation of TestEnvironment.
+ *
+ * \ingroup grptestenvironment
+ */
+
+using namespace paludis;
+
+TestEnvironment::TestEnvironment() :
+ Environment(PackageDatabase::Pointer(new PackageDatabase(this)))
+{
+}
+
+bool
+TestEnvironment::query_use(const UseFlagName & u, const PackageDatabaseEntry *) const
+{
+ return (std::string::npos != u.data().find("enabled"));
+}
+
+bool
+TestEnvironment::accept_keyword(const KeywordName & k, const PackageDatabaseEntry * const) const
+{
+ return k == KeywordName("test");
+}
+
+bool
+TestEnvironment::accept_license(const std::string &, const PackageDatabaseEntry * const) const
+{
+ return true;
+}
+
+bool
+TestEnvironment::query_user_masks(const PackageDatabaseEntry &) const
+{
+ return false;
+}
+
+bool
+TestEnvironment::query_user_unmasks(const PackageDatabaseEntry &) const
+{
+ return false;
+}
+
+namespace
+{
+ static const std::multimap<std::string, std::string> test_environment_mirrors;
+}
+
+TestEnvironment::MirrorIterator
+TestEnvironment::begin_mirrors(const std::string &) const
+{
+ return MirrorIterator(test_environment_mirrors.begin());
+}
+
+TestEnvironment::MirrorIterator
+TestEnvironment::end_mirrors(const std::string &) const
+{
+ return MirrorIterator(test_environment_mirrors.end());
+}
+
+
diff --git a/0.8.0/paludis/environment/test/test_environment.hh b/0.8.0/paludis/environment/test/test_environment.hh
new file mode 100644
index 0000000..d9b1178
--- /dev/null
+++ b/0.8.0/paludis/environment/test/test_environment.hh
@@ -0,0 +1,84 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_TEST_ENVIRONMENT_HH
+#define PALUDIS_GUARD_PALUDIS_TEST_ENVIRONMENT_HH 1
+
+#include <paludis/package_database_entry.hh>
+#include <paludis/environment.hh>
+
+/** \file
+ * Declarations for the TestEnvironment class.
+ *
+ * \ingroup grptestenvironment
+ */
+
+namespace paludis
+{
+ /**
+ * A TestEnvironment is an environment used during testing that lets us
+ * control all the options rather than reading them from configuration
+ * files.
+ *
+ * \ingroup grptestenvironment
+ */
+ class PALUDIS_VISIBLE TestEnvironment : public Environment
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ TestEnvironment();
+
+ virtual bool query_use(const UseFlagName &, const PackageDatabaseEntry *) const;
+
+ virtual bool accept_keyword(const KeywordName &, const PackageDatabaseEntry * const) const;
+
+ virtual bool query_user_masks(const PackageDatabaseEntry &) const;
+
+ virtual bool query_user_unmasks(const PackageDatabaseEntry &) const;
+
+ virtual bool accept_license(const std::string &, const PackageDatabaseEntry * const) const;
+
+ virtual std::string bashrc_files() const
+ {
+ return "";
+ }
+
+ virtual std::string hook_dirs() const
+ {
+ return "";
+ }
+
+ virtual std::string paludis_command() const
+ {
+ return "false";
+ }
+
+ virtual void perform_hook(const Hook &) const
+ {
+ }
+
+ virtual MirrorIterator begin_mirrors(const std::string &) const;
+
+ virtual MirrorIterator end_mirrors(const std::string &) const;
+ };
+}
+
+#endif
diff --git a/0.8.0/paludis/files.m4 b/0.8.0/paludis/files.m4
new file mode 100644
index 0000000..8aaccc7
--- /dev/null
+++ b/0.8.0/paludis/files.m4
@@ -0,0 +1,40 @@
+dnl vim: set ft=m4 et :
+dnl This file is used by Makefile.am.m4 and paludis.hh.m4. You should
+dnl use the provided autogen.bash script to do all the hard work.
+dnl
+dnl This file is used to avoid having to make lots of repetitive changes in
+dnl Makefile.am every time we add a source or test file. The first parameter is
+dnl the base filename with no extension; later parameters can be `hh', `cc',
+dnl `test', `impl', `testscript'. Note that there isn't much error checking done
+dnl on this file at present...
+
+add(`about', `hh', `test')
+add(`config_file', `hh', `cc', `test', `testscript')
+add(`contents', `hh', `cc')
+add(`dep_atom', `hh', `cc', `test')
+add(`dep_atom_flattener', `hh', `cc')
+add(`dep_atom_pretty_printer', `hh', `cc')
+add(`dep_list', `hh', `cc', `test', `sr')
+add(`dep_tag', `hh', `cc', `sr')
+add(`ebin', `hh', `cc', `sr')
+add(`ebuild', `hh', `cc', `sr')
+add(`environment', `hh', `cc')
+add(`hashed_containers', `hhx', `cc', `test')
+add(`mask_reasons', `hh', `cc')
+add(`match_package', `hh', `cc')
+add(`name', `hh', `cc', `test')
+add(`package_database', `hh', `cc', `test')
+add(`package_database_entry', `hh', `sr')
+add(`paludis', `hh', `cc')
+add(`portage_dep_lexer', `hh', `cc', `test')
+add(`portage_dep_parser', `hh', `cc', `test')
+add(`qualified_package_name', `sr')
+add(`repository', `hh', `cc', `sr')
+add(`repository_config_entry', `sr')
+add(`repository_so_loader', `cc')
+add(`syncer', `hh', `cc', `sr')
+add(`use_config_entry', `sr')
+add(`version_metadata', `hh', `cc', `sr')
+add(`version_operator', `hh', `cc', `test')
+add(`version_spec', `hh', `cc', `sr', `test')
+
diff --git a/0.8.0/paludis/hashed_containers.cc b/0.8.0/paludis/hashed_containers.cc
new file mode 100644
index 0000000..6c905ab
--- /dev/null
+++ b/0.8.0/paludis/hashed_containers.cc
@@ -0,0 +1,108 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "hashed_containers.hh"
+
+/** \file
+ * Implementation for hashed_containers.hh.
+ *
+ * \ingroup grphashedcontainers
+ */
+
+using namespace paludis;
+
+#if PALUDIS_HAVE_TR1_HASHES || PALUDIS_HAVE_EXT_HASHES || PALUDIS_HAVE_STD_HASHES
+
+#ifndef DOXYGEN
+
+std::size_t
+CRCHash<QualifiedPackageName>::operator() (const QualifiedPackageName & val) const
+{
+ const std::string & s1(val.category.data()), s2(val.package.data());
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < s1.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s1[t];
+ }
+
+ for (std::string::size_type t(0) ; t < s2.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s2[t];
+ }
+
+ return h;
+}
+
+std::size_t
+CRCHash<std::string>::operator() (const std::string & val) const
+{
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < val.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= val[t];
+ }
+
+ return h;
+}
+
+std::size_t
+CRCHash<std::pair<QualifiedPackageName, VersionSpec> >::operator() (
+ const std::pair<QualifiedPackageName, VersionSpec> & val) const
+{
+ const std::string & s1(val.first.category.data()),
+ s2(val.first.package.data());
+
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < s1.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s1[t];
+ }
+
+ for (std::string::size_type t(0) ; t < s2.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s2[t];
+ }
+
+ h ^= val.second.hash_value();
+
+ return h;
+}
+
+#endif
+
+#endif
+
diff --git a/0.8.0/paludis/hashed_containers.hh.in b/0.8.0/paludis/hashed_containers.hh.in
new file mode 100644
index 0000000..756f879
--- /dev/null
+++ b/0.8.0/paludis/hashed_containers.hh.in
@@ -0,0 +1,345 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+@GENERATED_FILE@
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_HASHED_CONTAINERS_HH
+#define PALUDIS_GUARD_PALUDIS_HASHED_CONTAINERS_HH 1
+
+/** \file
+ * Declarations for the MakeHashedMap and MakeHashedSet classes, and related
+ * utilities.
+ *
+ * \ingroup grphashedcontainers
+ */
+
+/**
+ * Non-zero if we have std::tr1:: hashes (g++-4).
+ *
+ * \ingroup grphashedcontainers
+ */
+#define PALUDIS_HAVE_TR1_HASHES @HAVE_TR1_HASHES@
+
+/**
+ * Non-zero if we have __gnu_cxx:: hashes under ext/ (g++-3).
+ *
+ * \ingroup grphashedcontainers
+ */
+#define PALUDIS_HAVE_EXT_HASHES @HAVE_EXT_HASHES@
+
+
+/**
+ * Non-zero if we have std:: hashes (icc70).
+ *
+ * \ingroup grphashedcontainers
+ */
+#define PALUDIS_HAVE_STD_HASHES @HAVE_STD_HASHES@
+
+#include <paludis/name.hh>
+#include <paludis/util/validated.hh>
+#include <paludis/version_spec.hh>
+
+#if PALUDIS_HAVE_TR1_HASHES
+# include <tr1/unordered_set>
+# include <tr1/unordered_map>
+#elif PALUDIS_HAVE_EXT_HASHES
+# include <ext/hash_set>
+# include <ext/hash_map>
+#elif PALUDIS_HAVE_STD_HASHES
+# include <hash_set>
+# include <hash_map>
+#else
+# include <set>
+# include <map>
+#endif
+
+#include <limits>
+#include <string>
+#include <functional>
+
+namespace paludis
+{
+ /**
+ * Hash function base template.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <typename T_>
+ struct CRCHash;
+
+ /**
+ * Make a hashed map of some kind from Key_ to Value_.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <typename Key_, typename Value_>
+ struct MakeHashedMap
+ {
+#if PALUDIS_HAVE_TR1_HASHES
+ /// Our map type.
+ typedef std::tr1::unordered_map<Key_, Value_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_EXT_HASHES
+ /// Our map type.
+ typedef __gnu_cxx::hash_map<Key_, Value_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_STD_HASHES
+ /// Our map type.
+ typedef std::hash_map<Key_, Value_, CRCHash<Key_> > Type;
+
+#else
+ /// Our map type.
+ typedef std::map<Key_, Value_> Type;
+#endif
+ };
+
+ /**
+ * Make a hashed map of some kind from Key_ to Value_.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <typename Key_, typename Value_>
+ struct MakeHashedMultiMap
+ {
+#if PALUDIS_HAVE_TR1_HASHES
+ /// Our map type.
+ typedef std::tr1::unordered_multimap<Key_, Value_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_EXT_HASHES
+ /// Our map type.
+ typedef __gnu_cxx::hash_multimap<Key_, Value_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_STD_HASHES
+ /// Our map type.
+ typedef std::hash_multimap<Key_, Value_, CRCHash<Key_> > Type;
+
+#else
+ /// Our map type.
+ typedef std::multimap<Key_, Value_> Type;
+#endif
+ };
+
+ /**
+ * Make a hashed set of some kind of Key_.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <typename Key_>
+ struct MakeHashedSet
+ {
+#if PALUDIS_HAVE_TR1_HASHES
+ /// Our set type.
+ typedef std::tr1::unordered_set<Key_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_EXT_HASHES
+ /// Our set type.
+ typedef __gnu_cxx::hash_set<Key_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_STD_HASHES
+ /// Our set type.
+ typedef std::hash_set<Key_, CRCHash<Key_> > Type;
+
+#else
+ /// Our set type.
+ typedef std::set<Key_> Type;
+#endif
+ };
+
+ /**
+ * Make a hashed set of some kind of Key_.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <typename Key_>
+ struct MakeHashedMultiSet
+ {
+#if PALUDIS_HAVE_TR1_HASHES
+ /// Our set type.
+ typedef std::tr1::unordered_multiset<Key_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_EXT_HASHES
+ /// Our set type.
+ typedef __gnu_cxx::hash_multiset<Key_, CRCHash<Key_> > Type;
+
+#elif PALUDIS_HAVE_STD_HASHES
+ /// Our set type.
+ typedef std::hash_multiset<Key_, CRCHash<Key_> > Type;
+
+#else
+ /// Our set type.
+ typedef std::multiset<Key_> Type;
+#endif
+ };
+
+#if PALUDIS_HAVE_TR1_HASHES || PALUDIS_HAVE_EXT_HASHES || PALUDIS_HAVE_STD_HASHES
+ namespace hashed_containers_internals
+ {
+ /**
+ * Base definitions for our CRCHash.
+ *
+ * \ingroup grphashedcontainers
+ */
+ struct CRCHashBase
+ {
+ /// Shift value.
+ static const std::size_t h_shift = std::numeric_limits<std::size_t>::digits - 5;
+
+ /// Mask value.
+ static const std::size_t h_mask = static_cast<std::size_t>(0x1f) << h_shift;
+ };
+ }
+
+ /**
+ * Hash, for QualifiedPackageName.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <>
+ class CRCHash<QualifiedPackageName> :
+ public std::unary_function<QualifiedPackageName, std::size_t>,
+ protected hashed_containers_internals::CRCHashBase
+ {
+ public:
+ /// Hash function.
+ std::size_t operator() (const QualifiedPackageName & val) const;
+
+#if (! PALUDIS_HAVE_TR1_HASHES) && (! PALUDIS_HAVE_EXT_HASHES)
+ enum
+ {
+ min_buckets = 32,
+ bucket_size = 4
+ };
+
+ bool operator() (const QualifiedPackageName & i1, const QualifiedPackageName & i2) const
+ {
+ return i1 < i2;
+ }
+#endif
+ };
+
+ /**
+ * Hash, for a validated string type.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <typename Validated_>
+ class CRCHash<Validated<std::string, Validated_> > :
+ public std::unary_function<Validated<std::string, Validated_>, std::size_t>,
+ protected hashed_containers_internals::CRCHashBase
+ {
+ public:
+ /// Hash function.
+ std::size_t operator() (const Validated<std::string, Validated_> & val) const;
+
+#if (! PALUDIS_HAVE_TR1_HASHES) && (! PALUDIS_HAVE_EXT_HASHES)
+ enum
+ {
+ min_buckets = 32,
+ bucket_size = 4
+ };
+
+ bool operator() (const Validated<std::string, Validated_> i1,
+ const Validated<std::string, Validated_> & i2) const
+ {
+ return i1 < i2;
+ }
+#endif
+ };
+
+
+ /**
+ * Hash, for a string.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template<>
+ class CRCHash<std::string> :
+ public std::unary_function<std::string, std::size_t>,
+ protected hashed_containers_internals::CRCHashBase
+ {
+ public:
+ /// Hash function.
+ std::size_t operator() (const std::string & val) const;
+
+#if (! PALUDIS_HAVE_TR1_HASHES) && (! PALUDIS_HAVE_EXT_HASHES)
+ enum
+ {
+ min_buckets = 32,
+ bucket_size = 4
+ };
+
+ bool operator() (const std::string & i1, const std::string & i2) const
+ {
+ return i1 < i2;
+ }
+#endif
+ };
+
+ /**
+ * Hash, for a QualifiedPackageName + VersionSpec pair.
+ *
+ * \ingroup grphashedcontainers
+ */
+ template <>
+ class CRCHash<std::pair<QualifiedPackageName, VersionSpec> > :
+ public std::unary_function<std::pair<QualifiedPackageName, VersionSpec>, std::size_t>,
+ protected hashed_containers_internals::CRCHashBase
+ {
+ public:
+ /// Hash function.
+ std::size_t operator() (const std::pair<QualifiedPackageName, VersionSpec> & val) const;
+
+#if (! PALUDIS_HAVE_TR1_HASHES) && (! PALUDIS_HAVE_EXT_HASHES)
+ enum
+ {
+ min_buckets = 32,
+ bucket_size = 4
+ };
+
+ bool operator() (const std::pair<QualifiedPackageName, VersionSpec> & i1,
+ const std::pair<QualifiedPackageName, VersionSpec> & i2) const
+ {
+ return i1 < i2;
+ }
+#endif
+ };
+
+ template <typename Validated_>
+ std::size_t
+ CRCHash<Validated<std::string, Validated_> >::operator() (const Validated<std::string, Validated_> & val) const
+ {
+ const std::string & s1(val.data());
+ std::size_t h(0);
+
+ for (std::string::size_type t(0) ; t < s1.length() ; ++t)
+ {
+ std::size_t hh(h & h_mask);
+ h <<= 5;
+ h ^= (hh >> h_shift);
+ h ^= s1[t];
+ }
+
+ return h;
+ }
+
+#endif
+
+}
+
+#endif
diff --git a/0.8.0/paludis/hashed_containers_TEST.cc b/0.8.0/paludis/hashed_containers_TEST.cc
new file mode 100644
index 0000000..bd60664
--- /dev/null
+++ b/0.8.0/paludis/hashed_containers_TEST.cc
@@ -0,0 +1,50 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "hashed_containers.hh"
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ /**
+ * \test Test HashSet.
+ *
+ * \ingroup grptestcases
+ */
+ struct HashSetTestQPN : TestCase
+ {
+ HashSetTestQPN() : TestCase("hash set qpn") { }
+
+ void run()
+ {
+ MakeHashedSet<QualifiedPackageName>::Type s;
+ TEST_CHECK(s.empty());
+ TEST_CHECK(s.end() == s.find(QualifiedPackageName("foo/bar")));
+ TEST_CHECK(s.insert(QualifiedPackageName("foo/bar")).second);
+ TEST_CHECK(s.end() != s.find(QualifiedPackageName("foo/bar")));
+ TEST_CHECK(! s.empty());
+ TEST_CHECK(! s.insert(QualifiedPackageName("foo/bar")).second);
+ }
+ } test_hash_set_qpn;
+}
+
diff --git a/0.8.0/paludis/libxml/Makefile.am b/0.8.0/paludis/libxml/Makefile.am
new file mode 100644
index 0000000..35f0307
--- /dev/null
+++ b/0.8.0/paludis/libxml/Makefile.am
@@ -0,0 +1,37 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+MAINTAINERCLEANFILES = Makefile.in
+AM_CXXFLAGS = -I$(top_srcdir) -I$(top_builddir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\"
+SUBDIRS = .
+
+TESTS =
+
+TESTS_ENVIRONMENT = env \
+ PALUDIS_EBUILD_DIR="$(top_srcdir)/ebuild/" \
+ PALUDIS_SKIP_CONFIG="yes" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ bash $(top_srcdir)/test/run_test.sh
+
+check_PROGRAMS = $(TESTS)
+check_SCRIPTS =
+
+if NEED_XML
+
+lib_LTLIBRARIES = libpaludislibxml.la
+paludis_libxml_includedir = $(includedir)/paludis/libxml
+paludis_libxml_include_HEADERS = \
+ libxml.hh
+libpaludislibxml_la_SOURCES = $(paludis_libxml_include_HEADERS) \
+ libxml.cc
+libpaludislibxml_la_CXXFLAGS = @LIBXML2DEPS_CFLAGS@
+libpaludislibxml_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ @LIBXML2DEPS_LIBS@
+
+endif
+
+EXTRA_DIST = libxml.hh libxml.cc
+
diff --git a/0.8.0/paludis/libxml/libxml.cc b/0.8.0/paludis/libxml/libxml.cc
new file mode 100644
index 0000000..74c6461
--- /dev/null
+++ b/0.8.0/paludis/libxml/libxml.cc
@@ -0,0 +1,41 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/libxml/libxml.hh>
+#include <list>
+#include <paludis/util/join.hh>
+#include <paludis/util/tokeniser.hh>
+
+std::string
+paludis::retarded_libxml_string_to_string(const xmlChar * s)
+{
+ if (s)
+ return std::string(reinterpret_cast<const char *>(s));
+ else
+ return "";
+}
+
+std::string
+paludis::normalise(const std::string & s)
+{
+ std::list<std::string> words;
+ WhitespaceTokeniser::get_instance()->tokenise(s, std::back_inserter(words));
+ return join(words.begin(), words.end(), " ");
+}
+
diff --git a/0.8.0/paludis/libxml/libxml.hh b/0.8.0/paludis/libxml/libxml.hh
new file mode 100644
index 0000000..7f53a85
--- /dev/null
+++ b/0.8.0/paludis/libxml/libxml.hh
@@ -0,0 +1,65 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_QA_LIBXML_UTILS_HH
+#define PALUDIS_GUARD_PALUDIS_QA_LIBXML_UTILS_HH 1
+
+#include <libxml/parser.h>
+#include <paludis/util/attributes.hh>
+#include <string>
+
+namespace paludis
+{
+ template <typename PtrType_>
+ class LibXmlPtrHolder
+ {
+ private:
+ PtrType_ _ptr;
+ void (* _free_func) (PtrType_);
+
+ LibXmlPtrHolder(const LibXmlPtrHolder &);
+ void operator= (const LibXmlPtrHolder &);
+
+ public:
+ LibXmlPtrHolder(PtrType_ ptr, void (* free_func) (PtrType_)) :
+ _ptr(ptr),
+ _free_func(free_func)
+ {
+ }
+
+ ~LibXmlPtrHolder()
+ {
+ if (0 != _ptr)
+ _free_func(_ptr);
+ }
+
+ operator PtrType_ () const
+ {
+ return _ptr;
+ }
+ };
+
+ std::string
+ retarded_libxml_string_to_string(const xmlChar * s) PALUDIS_VISIBLE;
+
+ std::string normalise(const std::string & s) PALUDIS_VISIBLE;
+}
+
+
+#endif
diff --git a/0.8.0/paludis/mask_reasons.cc b/0.8.0/paludis/mask_reasons.cc
new file mode 100644
index 0000000..0f7aae2
--- /dev/null
+++ b/0.8.0/paludis/mask_reasons.cc
@@ -0,0 +1,76 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include <paludis/mask_reasons.hh>
+#include <paludis/util/exception.hh>
+#include <ostream>
+
+/** \file
+ * Implementation of MaskReason classes.
+ *
+ * \ingroup grpmaskreasons
+ */
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const MaskReason & r)
+{
+ do
+ {
+ switch (r)
+ {
+ case mr_keyword:
+ s << "keyword";
+ continue;
+
+ case mr_user_mask:
+ s << "user mask";
+ continue;
+
+ case mr_profile_mask:
+ s << "profile mask";
+ continue;
+
+ case mr_repository_mask:
+ s << "repository mask";
+ continue;
+
+ case mr_eapi:
+ s << "EAPI";
+ continue;
+
+ case mr_license:
+ s << "license";
+ continue;
+
+ case mr_by_association:
+ s << "by association";
+ continue;
+
+ case last_mr:
+ ;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad MaskReason value");
+ }
+ while (false);
+
+ return s;
+}
+
diff --git a/0.8.0/paludis/mask_reasons.hh b/0.8.0/paludis/mask_reasons.hh
new file mode 100644
index 0000000..699fc6f
--- /dev/null
+++ b/0.8.0/paludis/mask_reasons.hh
@@ -0,0 +1,71 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_MASK_REASONS_HH
+#define PALUDIS_GUARD_PALUDIS_MASK_REASONS_HH 1
+
+#include <bitset>
+#include <iosfwd>
+
+/** \file
+ * Declarations for MaskReasons and related classes.
+ *
+ * \ingroup grpmaskreasons
+ */
+
+namespace paludis
+{
+ /**
+ * Each value represents one reason for a package being
+ * masked.
+ *
+ * \see MaskReasons
+ *
+ * \ingroup grpmaskreasons
+ */
+ enum MaskReason
+ {
+ mr_keyword, ///< no keyword match
+ mr_user_mask, ///< user package.mask
+ mr_profile_mask, ///< profile package.mask
+ mr_repository_mask, ///< repository package.mask
+ mr_eapi, ///< unknown eapi
+ mr_license, ///< unaccepted license
+ mr_licence = mr_license, ///< convenience alias for those who can spell,
+ mr_by_association, ///< masked by association with another package (for virtuals)
+ last_mr ///< number of entries
+ };
+
+ /**
+ * A collection of reasons for why a package is masked.
+ *
+ * \ingroup grpmaskreasons
+ */
+ typedef std::bitset<last_mr> MaskReasons;
+
+ /**
+ * Stringify a MaskReason.
+ *
+ * \ingroup grpmaskreasons
+ */
+ std::ostream &
+ operator<< (std::ostream &, const MaskReason &);
+}
+
+#endif
diff --git a/0.8.0/paludis/match_package.cc b/0.8.0/paludis/match_package.cc
new file mode 100644
index 0000000..b0e25ab
--- /dev/null
+++ b/0.8.0/paludis/match_package.cc
@@ -0,0 +1,132 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/match_package.hh>
+
+/** \file
+ * Implementation for match_package.hh.
+ *
+ * \ingroup grpmatchpackage
+ */
+
+using namespace paludis;
+
+bool
+match_package_internals::do_match(
+ const Environment * const env,
+ const PackageDepAtom * const atom,
+ const PackageDatabaseEntry * const entry)
+{
+ if (atom->package() != entry->name)
+ return false;
+
+ if (atom->version_spec_ptr() && ! (((entry->version).*
+ (atom->version_operator().as_version_spec_operator()))
+ (*atom->version_spec_ptr())))
+ return false;
+
+ if (atom->repository_ptr())
+ if (*atom->repository_ptr() != entry->repository)
+ return false;
+
+ if (atom->slot_ptr() || atom->use_requirements_ptr())
+ {
+ VersionMetadata::ConstPointer metadata(env->package_database()->fetch_repository(
+ entry->repository)->version_metadata(
+ entry->name, entry->version));
+
+ if (atom->slot_ptr())
+ if (*atom->slot_ptr() != SlotName(metadata->slot))
+ return false;
+
+ if (atom->use_requirements_ptr())
+ {
+ for (UseRequirements::Iterator u(atom->use_requirements_ptr()->begin()),
+ u_end(atom->use_requirements_ptr()->end()) ; u != u_end ; ++u)
+ {
+ switch (u->second)
+ {
+ case use_unspecified:
+ continue;
+
+ case use_enabled:
+ if (! env->query_use(u->first, entry))
+ return false;
+ continue;
+
+ case use_disabled:
+ if (env->query_use(u->first, entry))
+ return false;
+ continue;
+ }
+ throw InternalError(PALUDIS_HERE, "bad UseFlagState");
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+match_package_internals::do_match(
+ const Environment * const env,
+ const PackageDepAtom * const atom,
+ const DepListEntry * const entry)
+{
+ if (atom->package() != entry->package.name)
+ return false;
+
+ if (atom->version_spec_ptr() && ! (((entry->package.version).*
+ (atom->version_operator().as_version_spec_operator()))
+ (*atom->version_spec_ptr())))
+ return false;
+
+ if (atom->repository_ptr() && (*atom->repository_ptr() != entry->package.repository))
+ return false;
+
+ if (atom->slot_ptr() && (*atom->slot_ptr() != entry->metadata->slot))
+ return false;
+
+ if (atom->use_requirements_ptr())
+ {
+ for (UseRequirements::Iterator u(atom->use_requirements_ptr()->begin()),
+ u_end(atom->use_requirements_ptr()->end()) ; u != u_end ; ++u)
+ {
+ switch (u->second)
+ {
+ case use_unspecified:
+ continue;
+
+ case use_enabled:
+ if (! env->query_use(u->first, &entry->package))
+ return false;
+ continue;
+
+ case use_disabled:
+ if (env->query_use(u->first, &entry->package))
+ return false;
+ continue;
+ }
+ throw InternalError(PALUDIS_HERE, "bad UseFlagState");
+ }
+ }
+
+ return true;
+}
+
diff --git a/0.8.0/paludis/match_package.hh b/0.8.0/paludis/match_package.hh
new file mode 100644
index 0000000..5999ab9
--- /dev/null
+++ b/0.8.0/paludis/match_package.hh
@@ -0,0 +1,149 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+#ifndef PALUDIS_GUARD_PALUDIS_MATCH_PACKAGE_HH
+#define PALUDIS_GUARD_PALUDIS_MATCH_PACKAGE_HH 1
+
+/** \file
+ * Declare the match_package function.
+ *
+ * Do not merge this file into dep_atom. It will cause all sorts of horrible
+ * circular dependency issues. Avoid including this file in headers if at all
+ * possible.
+ *
+ * \ingroup grpmatchpackage
+ */
+
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_list.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ /**
+ * For internal use by match_package.
+ *
+ * \ingroup grpmatchpackage
+ */
+ namespace match_package_internals
+ {
+ /**
+ * Do the match on a PackageDatabaseEntry.
+ *
+ * \ingroup grpmatchpackage
+ */
+ bool do_match(
+ const Environment * const env,
+ const PackageDepAtom * const atom,
+ const PackageDatabaseEntry * const entry)
+ PALUDIS_ATTRIBUTE((nonnull(1, 2, 3)));
+
+ /**
+ * Do the match on a DepListEntry.
+ *
+ * \ingroup grpmatchpackage
+ */
+ bool do_match(
+ const Environment * const env,
+ const PackageDepAtom * const atom,
+ const DepListEntry * const entry)
+ PALUDIS_ATTRIBUTE((nonnull(2, 3)));
+
+ /**
+ * Normalise env type.
+ *
+ * \ingroup grpmatchpackage
+ */
+ inline const Environment * sanitise_env(const Environment * env)
+ {
+ return env;
+ }
+
+ /**
+ * Normalise DB type.
+ *
+ * \ingroup grpmatchpackage
+ */
+ template <typename P1_>
+ inline const Environment * sanitise_env(const CountedPtr<const Environment, P1_> env)
+ {
+ return env.raw_pointer();
+ }
+
+ /**
+ * Normalise atom type.
+ *
+ * \ingroup grpmatchpackage
+ */
+ inline const PackageDepAtom * sanitise_atom(const PackageDepAtom * atom)
+ {
+ return atom;
+ }
+