aboutsummaryrefslogtreecommitdiff
path: root/0.18.0/paludis
diff options
context:
space:
mode:
Diffstat (limited to '0.18.0/paludis')
-rw-r--r--0.18.0/paludis/Makefile.am.m4127
-rw-r--r--0.18.0/paludis/about.hh.in117
-rw-r--r--0.18.0/paludis/about_TEST.cc83
-rw-r--r--0.18.0/paludis/args/Makefile.am69
-rw-r--r--0.18.0/paludis/args/args.cc27
-rw-r--r--0.18.0/paludis/args/args.hh35
-rw-r--r--0.18.0/paludis/args/args_TEST.cc178
-rw-r--r--0.18.0/paludis/args/args_dumper.cc95
-rw-r--r--0.18.0/paludis/args/args_dumper.hh79
-rw-r--r--0.18.0/paludis/args/args_error.cc45
-rw-r--r--0.18.0/paludis/args/args_error.hh87
-rw-r--r--0.18.0/paludis/args/args_group.cc77
-rw-r--r--0.18.0/paludis/args/args_group.hh118
-rw-r--r--0.18.0/paludis/args/args_handler.cc249
-rw-r--r--0.18.0/paludis/args/args_handler.hh194
-rw-r--r--0.18.0/paludis/args/args_option.cc325
-rw-r--r--0.18.0/paludis/args/args_option.hh435
-rw-r--r--0.18.0/paludis/args/args_visitor.cc132
-rw-r--r--0.18.0/paludis/args/args_visitor.hh104
-rw-r--r--0.18.0/paludis/args/bad_argument.cc35
-rw-r--r--0.18.0/paludis/args/bad_argument.hh54
-rw-r--r--0.18.0/paludis/args/man.cc297
-rw-r--r--0.18.0/paludis/args/man.hh56
-rw-r--r--0.18.0/paludis/config_file.cc451
-rw-r--r--0.18.0/paludis/config_file.hh310
-rw-r--r--0.18.0/paludis/config_file_TEST.cc323
-rwxr-xr-x0.18.0/paludis/config_file_TEST_cleanup.sh10
-rwxr-xr-x0.18.0/paludis/config_file_TEST_setup.sh9
-rw-r--r--0.18.0/paludis/contents.cc119
-rw-r--r--0.18.0/paludis/contents.hh267
-rw-r--r--0.18.0/paludis/dep_atom.cc441
-rw-r--r--0.18.0/paludis/dep_atom.hh525
-rw-r--r--0.18.0/paludis/dep_atom_TEST.cc167
-rw-r--r--0.18.0/paludis/dep_atom_flattener.cc127
-rw-r--r--0.18.0/paludis/dep_atom_flattener.hh90
-rw-r--r--0.18.0/paludis/dep_atom_pretty_printer.cc103
-rw-r--r--0.18.0/paludis/dep_atom_pretty_printer.hh87
-rw-r--r--0.18.0/paludis/dep_list/Makefile.am140
-rw-r--r--0.18.0/paludis/dep_list/dep_list.cc1589
-rw-r--r--0.18.0/paludis/dep_list/dep_list.hh140
-rw-r--r--0.18.0/paludis/dep_list/dep_list.sr73
-rw-r--r--0.18.0/paludis/dep_list/dep_list_TEST.cc1510
-rw-r--r--0.18.0/paludis/dep_list/dep_list_TEST.hh171
-rw-r--r--0.18.0/paludis/dep_list/dep_list_TEST_blockers.cc361
-rw-r--r--0.18.0/paludis/dep_list/exceptions.cc59
-rw-r--r--0.18.0/paludis/dep_list/exceptions.hh171
-rw-r--r--0.18.0/paludis/dep_list/options.cc27
-rw-r--r--0.18.0/paludis/dep_list/options.hh41
-rw-r--r--0.18.0/paludis/dep_list/options.se275
-rw-r--r--0.18.0/paludis/dep_list/range_rewriter.cc102
-rw-r--r--0.18.0/paludis/dep_list/range_rewriter.hh55
-rw-r--r--0.18.0/paludis/dep_list/range_rewriter_TEST.cc53
-rw-r--r--0.18.0/paludis/dep_list/uninstall_list.cc439
-rw-r--r--0.18.0/paludis/dep_list/uninstall_list.hh69
-rw-r--r--0.18.0/paludis/dep_list/uninstall_list.sr44
-rw-r--r--0.18.0/paludis/dep_list/uninstall_list_TEST.cc394
-rw-r--r--0.18.0/paludis/dep_tag.cc189
-rw-r--r--0.18.0/paludis/dep_tag.hh308
-rw-r--r--0.18.0/paludis/dep_tag.sr23
-rw-r--r--0.18.0/paludis/digests/Makefile.am53
-rw-r--r--0.18.0/paludis/digests/md5.cc239
-rw-r--r--0.18.0/paludis/digests/md5.hh61
-rw-r--r--0.18.0/paludis/digests/md5_TEST.cc112
-rw-r--r--0.18.0/paludis/digests/rmd160.cc231
-rw-r--r--0.18.0/paludis/digests/rmd160.hh65
-rw-r--r--0.18.0/paludis/digests/rmd160_TEST.cc114
-rw-r--r--0.18.0/paludis/digests/sha256.cc228
-rw-r--r--0.18.0/paludis/digests/sha256.hh61
-rw-r--r--0.18.0/paludis/digests/sha256_TEST.cc443
-rw-r--r--0.18.0/paludis/ebuild.cc463
-rw-r--r--0.18.0/paludis/ebuild.hh329
-rw-r--r--0.18.0/paludis/ebuild.sr117
-rw-r--r--0.18.0/paludis/environment.cc592
-rw-r--r--0.18.0/paludis/environment.hh362
-rw-r--r--0.18.0/paludis/environment/Makefile.am8
-rw-r--r--0.18.0/paludis/environment/default/Makefile.am106
-rw-r--r--0.18.0/paludis/environment/default/default_config.cc1030
-rw-r--r--0.18.0/paludis/environment/default/default_config.hh275
-rw-r--r--0.18.0/paludis/environment/default/default_environment.cc750
-rw-r--r--0.18.0/paludis/environment/default/default_environment.hh88
-rw-r--r--0.18.0/paludis/environment/default/default_environment_TEST.cc131
-rwxr-xr-x0.18.0/paludis/environment/default/default_environment_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/environment/default/default_environment_TEST_setup.sh83
-rw-r--r--0.18.0/paludis/environment/default/repository_config_entry.sr22
-rw-r--r--0.18.0/paludis/environment/default/use_config_entry.sr106
-rw-r--r--0.18.0/paludis/environment/no_config/Makefile.am59
-rw-r--r--0.18.0/paludis/environment/no_config/no_config_environment.cc251
-rw-r--r--0.18.0/paludis/environment/no_config/no_config_environment.hh86
-rw-r--r--0.18.0/paludis/environment/no_config/no_config_environment.sr12
-rw-r--r--0.18.0/paludis/environment/test/Makefile.am39
-rw-r--r--0.18.0/paludis/environment/test/test_environment.cc86
-rw-r--r--0.18.0/paludis/environment/test/test_environment.hh85
-rw-r--r--0.18.0/paludis/files.m437
-rw-r--r--0.18.0/paludis/hashed_containers.cc108
-rw-r--r--0.18.0/paludis/hashed_containers.hh.in345
-rw-r--r--0.18.0/paludis/hashed_containers_TEST.cc62
-rw-r--r--0.18.0/paludis/host_tuple_name.cc237
-rw-r--r--0.18.0/paludis/host_tuple_name.hh244
-rw-r--r--0.18.0/paludis/host_tuple_name.sr27
-rw-r--r--0.18.0/paludis/host_tuple_name_TEST.cc242
-rw-r--r--0.18.0/paludis/mask_reasons.cc76
-rw-r--r--0.18.0/paludis/mask_reasons.hh71
-rw-r--r--0.18.0/paludis/match_package.cc190
-rw-r--r--0.18.0/paludis/match_package.hh43
-rw-r--r--0.18.0/paludis/name.cc330
-rw-r--r--0.18.0/paludis/name.hh415
-rw-r--r--0.18.0/paludis/name.sr24
-rw-r--r--0.18.0/paludis/name_TEST.cc200
-rw-r--r--0.18.0/paludis/package_database.cc482
-rw-r--r--0.18.0/paludis/package_database.hh336
-rw-r--r--0.18.0/paludis/package_database_TEST.cc226
-rw-r--r--0.18.0/paludis/package_database_entry.cc58
-rw-r--r--0.18.0/paludis/package_database_entry.hh61
-rw-r--r--0.18.0/paludis/package_database_entry.sr23
-rw-r--r--0.18.0/paludis/paludis.cc8
-rw-r--r--0.18.0/paludis/paludis.hh.m449
-rw-r--r--0.18.0/paludis/portage_dep_lexer.cc111
-rw-r--r--0.18.0/paludis/portage_dep_lexer.hh124
-rw-r--r--0.18.0/paludis/portage_dep_lexer_TEST.cc242
-rw-r--r--0.18.0/paludis/portage_dep_parser.cc292
-rw-r--r--0.18.0/paludis/portage_dep_parser.hh201
-rw-r--r--0.18.0/paludis/portage_dep_parser_TEST.cc224
-rw-r--r--0.18.0/paludis/qa/Makefile.am.m4128
-rw-r--r--0.18.0/paludis/qa/categories_check.cc103
-rw-r--r--0.18.0/paludis/qa/categories_check.hh53
-rw-r--r--0.18.0/paludis/qa/changelog_check.cc75
-rw-r--r--0.18.0/paludis/qa/changelog_check.hh53
-rw-r--r--0.18.0/paludis/qa/check.cc32
-rw-r--r--0.18.0/paludis/qa/check.hh60
-rw-r--r--0.18.0/paludis/qa/check_result.cc44
-rw-r--r--0.18.0/paludis/qa/check_result.hh98
-rw-r--r--0.18.0/paludis/qa/check_result_TEST.cc52
-rw-r--r--0.18.0/paludis/qa/create_metadata_check.cc67
-rw-r--r--0.18.0/paludis/qa/create_metadata_check.hh58
-rw-r--r--0.18.0/paludis/qa/defaults_check.cc154
-rw-r--r--0.18.0/paludis/qa/defaults_check.hh55
-rw-r--r--0.18.0/paludis/qa/defaults_check_TEST.cc69
-rwxr-xr-x0.18.0/paludis/qa/defaults_check_TEST_cleanup.sh12
-rwxr-xr-x0.18.0/paludis/qa/defaults_check_TEST_setup.sh51
-rw-r--r--0.18.0/paludis/qa/dep_any_check.cc146
-rw-r--r--0.18.0/paludis/qa/dep_any_check.hh53
-rw-r--r--0.18.0/paludis/qa/dep_flags_check.cc192
-rw-r--r--0.18.0/paludis/qa/dep_flags_check.hh53
-rw-r--r--0.18.0/paludis/qa/dep_packages_check.cc157
-rw-r--r--0.18.0/paludis/qa/dep_packages_check.hh53
-rw-r--r--0.18.0/paludis/qa/deprecated_functions.txt2
-rw-r--r--0.18.0/paludis/qa/deprecated_functions_check.cc110
-rw-r--r--0.18.0/paludis/qa/deprecated_functions_check.hh53
-rw-r--r--0.18.0/paludis/qa/deps_exist_check.cc134
-rw-r--r--0.18.0/paludis/qa/deps_exist_check.hh53
-rw-r--r--0.18.0/paludis/qa/deps_visible_check.cc246
-rw-r--r--0.18.0/paludis/qa/deps_visible_check.hh53
-rw-r--r--0.18.0/paludis/qa/deps_visible_check_TEST.cc114
-rwxr-xr-x0.18.0/paludis/qa/deps_visible_check_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/qa/deps_visible_check_TEST_setup.sh57
-rw-r--r--0.18.0/paludis/qa/description_check.cc81
-rw-r--r--0.18.0/paludis/qa/description_check.hh53
-rw-r--r--0.18.0/paludis/qa/digest_collisions_check.cc88
-rw-r--r--0.18.0/paludis/qa/digest_collisions_check.hh53
-rw-r--r--0.18.0/paludis/qa/ebuild_check.cc73
-rw-r--r--0.18.0/paludis/qa/ebuild_check.hh100
-rw-r--r--0.18.0/paludis/qa/ebuild_check.sr10
-rw-r--r--0.18.0/paludis/qa/ebuild_count_check.cc58
-rw-r--r--0.18.0/paludis/qa/ebuild_count_check.hh53
-rw-r--r--0.18.0/paludis/qa/extract_check.cc120
-rw-r--r--0.18.0/paludis/qa/extract_check.hh53
-rw-r--r--0.18.0/paludis/qa/file_check.cc59
-rw-r--r--0.18.0/paludis/qa/file_check.hh105
-rw-r--r--0.18.0/paludis/qa/file_permissions_check.cc60
-rw-r--r--0.18.0/paludis/qa/file_permissions_check.hh53
-rw-r--r--0.18.0/paludis/qa/file_permissions_check_TEST.cc90
-rwxr-xr-x0.18.0/paludis/qa/file_permissions_check_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/qa/file_permissions_check_TEST_setup.sh14
-rw-r--r--0.18.0/paludis/qa/filename_check.cc52
-rw-r--r--0.18.0/paludis/qa/filename_check.hh58
-rw-r--r--0.18.0/paludis/qa/files.m466
-rw-r--r--0.18.0/paludis/qa/files_dir_size_check.cc87
-rw-r--r--0.18.0/paludis/qa/files_dir_size_check.hh53
-rw-r--r--0.18.0/paludis/qa/glep_31_check.cc126
-rw-r--r--0.18.0/paludis/qa/glep_31_check.hh57
-rw-r--r--0.18.0/paludis/qa/glep_31_check_TEST.cc77
-rw-r--r--0.18.0/paludis/qa/gpg_check.cc86
-rw-r--r--0.18.0/paludis/qa/gpg_check.hh53
-rw-r--r--0.18.0/paludis/qa/gpg_check_TEST.cc65
-rwxr-xr-x0.18.0/paludis/qa/gpg_check_TEST_cleanup.sh8
-rwxr-xr-x0.18.0/paludis/qa/gpg_check_TEST_setup.sh9
-rw-r--r--0.18.0/paludis/qa/has_ebuilds_check.cc50
-rw-r--r--0.18.0/paludis/qa/has_ebuilds_check.hh53
-rw-r--r--0.18.0/paludis/qa/has_ebuilds_check_TEST.cc66
-rwxr-xr-x0.18.0/paludis/qa/has_ebuilds_check_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/qa/has_ebuilds_check_TEST_setup.sh12
-rw-r--r--0.18.0/paludis/qa/has_misc_files_check.cc54
-rw-r--r--0.18.0/paludis/qa/has_misc_files_check.hh53
-rw-r--r--0.18.0/paludis/qa/has_misc_files_check_TEST.cc102
-rwxr-xr-x0.18.0/paludis/qa/has_misc_files_check_TEST_cleanup.sh12
-rwxr-xr-x0.18.0/paludis/qa/has_misc_files_check_TEST_setup.sh23
-rw-r--r--0.18.0/paludis/qa/header_check.cc94
-rw-r--r--0.18.0/paludis/qa/header_check.hh53
-rw-r--r--0.18.0/paludis/qa/homepage_check.cc73
-rw-r--r--0.18.0/paludis/qa/homepage_check.hh53
-rw-r--r--0.18.0/paludis/qa/inherits_blacklist.txt10
-rw-r--r--0.18.0/paludis/qa/inherits_check.cc104
-rw-r--r--0.18.0/paludis/qa/inherits_check.hh53
-rw-r--r--0.18.0/paludis/qa/iuse_blacklist.txt6
-rw-r--r--0.18.0/paludis/qa/iuse_check.cc117
-rw-r--r--0.18.0/paludis/qa/iuse_check.hh58
-rw-r--r--0.18.0/paludis/qa/keywords_check.cc88
-rw-r--r--0.18.0/paludis/qa/keywords_check.hh53
-rw-r--r--0.18.0/paludis/qa/license_check.cc132
-rw-r--r--0.18.0/paludis/qa/license_check.hh53
-rw-r--r--0.18.0/paludis/qa/message.cc70
-rw-r--r--0.18.0/paludis/qa/message.hh70
-rw-r--r--0.18.0/paludis/qa/message.sr18
-rw-r--r--0.18.0/paludis/qa/message_TEST.cc42
-rw-r--r--0.18.0/paludis/qa/metadata_check.cc115
-rw-r--r--0.18.0/paludis/qa/metadata_check.hh53
-rw-r--r--0.18.0/paludis/qa/metadata_file.cc156
-rw-r--r--0.18.0/paludis/qa/metadata_file.hh57
-rw-r--r--0.18.0/paludis/qa/metadata_file_TEST.cc82
-rw-r--r--0.18.0/paludis/qa/package_dir_check.cc58
-rw-r--r--0.18.0/paludis/qa/package_dir_check.hh100
-rw-r--r--0.18.0/paludis/qa/package_name_check.cc62
-rw-r--r--0.18.0/paludis/qa/package_name_check.hh58
-rw-r--r--0.18.0/paludis/qa/package_name_check_TEST.cc104
-rwxr-xr-x0.18.0/paludis/qa/package_name_check_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/qa/package_name_check_TEST_setup.sh14
-rw-r--r--0.18.0/paludis/qa/parse_deps_check.cc97
-rw-r--r--0.18.0/paludis/qa/parse_deps_check.hh58
-rw-r--r--0.18.0/paludis/qa/pdepend_overlap_check.cc136
-rw-r--r--0.18.0/paludis/qa/pdepend_overlap_check.hh53
-rw-r--r--0.18.0/paludis/qa/per_profile_ebuild_check.cc42
-rw-r--r--0.18.0/paludis/qa/per_profile_ebuild_check.hh101
-rw-r--r--0.18.0/paludis/qa/per_profile_ebuild_check.sr13
-rw-r--r--0.18.0/paludis/qa/profile_check.cc42
-rw-r--r--0.18.0/paludis/qa/profile_check.hh108
-rw-r--r--0.18.0/paludis/qa/profile_check.sr12
-rw-r--r--0.18.0/paludis/qa/profile_paths_exist_check.cc88
-rw-r--r--0.18.0/paludis/qa/profile_paths_exist_check.hh59
-rw-r--r--0.18.0/paludis/qa/profiles_check.cc42
-rw-r--r--0.18.0/paludis/qa/profiles_check.hh105
-rw-r--r--0.18.0/paludis/qa/qa.cc21
-rw-r--r--0.18.0/paludis/qa/qa.hh.m438
-rw-r--r--0.18.0/paludis/qa/qa_environment.cc60
-rw-r--r--0.18.0/paludis/qa/qa_environment.hh57
-rw-r--r--0.18.0/paludis/qa/qa_environment.sr14
-rw-r--r--0.18.0/paludis/qa/qa_environment_TEST.cc60
-rwxr-xr-x0.18.0/paludis/qa/qa_environment_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/qa/qa_environment_TEST_setup.sh36
-rw-r--r--0.18.0/paludis/qa/repo_name_check.cc88
-rw-r--r--0.18.0/paludis/qa/repo_name_check.hh54
-rw-r--r--0.18.0/paludis/qa/restrict_check.cc98
-rw-r--r--0.18.0/paludis/qa/restrict_check.hh53
-rw-r--r--0.18.0/paludis/qa/slot_check.cc73
-rw-r--r--0.18.0/paludis/qa/slot_check.hh53
-rw-r--r--0.18.0/paludis/qa/src_uri_check.cc188
-rw-r--r--0.18.0/paludis/qa/src_uri_check.hh53
-rw-r--r--0.18.0/paludis/qa/subshell_die_check.cc82
-rw-r--r--0.18.0/paludis/qa/subshell_die_check.hh53
-rw-r--r--0.18.0/paludis/qa/subshell_die_check_TEST.cc54
-rwxr-xr-x0.18.0/paludis/qa/subshell_die_check_TEST_cleanup.sh12
-rwxr-xr-x0.18.0/paludis/qa/subshell_die_check_TEST_setup.sh43
-rw-r--r--0.18.0/paludis/qa/suspicious_depend.txt6
-rw-r--r--0.18.0/paludis/qa/suspicious_rdepend.txt19
-rw-r--r--0.18.0/paludis/qa/variable_assigns_check.cc111
-rw-r--r--0.18.0/paludis/qa/variable_assigns_check.hh53
-rw-r--r--0.18.0/paludis/qa/whitespace_check.cc123
-rw-r--r--0.18.0/paludis/qa/whitespace_check.hh53
-rw-r--r--0.18.0/paludis/repositories/Makefile.am57
-rw-r--r--0.18.0/paludis/repositories/cran/Makefile.am117
-rw-r--r--0.18.0/paludis/repositories/cran/cran_dep_parser.cc61
-rw-r--r--0.18.0/paludis/repositories/cran/cran_dep_parser.hh24
-rw-r--r--0.18.0/paludis/repositories/cran/cran_dep_parser_TEST.cc65
-rw-r--r--0.18.0/paludis/repositories/cran/cran_description.cc109
-rw-r--r--0.18.0/paludis/repositories/cran/cran_description.hh144
-rw-r--r--0.18.0/paludis/repositories/cran/cran_installed_repository.cc725
-rw-r--r--0.18.0/paludis/repositories/cran/cran_installed_repository.hh144
-rw-r--r--0.18.0/paludis/repositories/cran/cran_installed_repository.sr23
-rw-r--r--0.18.0/paludis/repositories/cran/cran_repository.cc618
-rw-r--r--0.18.0/paludis/repositories/cran/cran_repository.hh132
-rw-r--r--0.18.0/paludis/repositories/cran/cran_repository.sr27
-rw-r--r--0.18.0/paludis/repositories/cran/cran_repository_TEST.cc97
-rwxr-xr-x0.18.0/paludis/repositories/cran/cran_repository_TEST_cleanup.sh8
-rwxr-xr-x0.18.0/paludis/repositories/cran/cran_repository_TEST_setup.sh57
-rw-r--r--0.18.0/paludis/repositories/cran/cran_version_metadata.cc47
-rw-r--r--0.18.0/paludis/repositories/cran/cran_version_metadata.hh41
-rw-r--r--0.18.0/paludis/repositories/cran/registration.cc42
-rw-r--r--0.18.0/paludis/repositories/fake/Makefile.am45
-rw-r--r--0.18.0/paludis/repositories/fake/fake_installed_repository.cc106
-rw-r--r--0.18.0/paludis/repositories/fake/fake_installed_repository.hh51
-rw-r--r--0.18.0/paludis/repositories/fake/fake_repository.cc99
-rw-r--r--0.18.0/paludis/repositories/fake/fake_repository.hh56
-rw-r--r--0.18.0/paludis/repositories/fake/fake_repository_base.cc346
-rw-r--r--0.18.0/paludis/repositories/fake/fake_repository_base.hh186
-rw-r--r--0.18.0/paludis/repositories/gems/Makefile.am148
-rw-r--r--0.18.0/paludis/repositories/gems/cache.cc338
-rw-r--r--0.18.0/paludis/repositories/gems/cache.hh52
-rw-r--r--0.18.0/paludis/repositories/gems/cache.sr18
-rw-r--r--0.18.0/paludis/repositories/gems/cache_TEST.cc93
-rwxr-xr-x0.18.0/paludis/repositories/gems/cache_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/repositories/gems/cache_TEST_setup.sh33
-rw-r--r--0.18.0/paludis/repositories/gems/gems_repository.cc290
-rw-r--r--0.18.0/paludis/repositories/gems/gems_repository.hh65
-rw-r--r--0.18.0/paludis/repositories/gems/gems_repository.sr20
-rw-r--r--0.18.0/paludis/repositories/gems/gems_repository_TEST.cc51
-rwxr-xr-x0.18.0/paludis/repositories/gems/gems_repository_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/repositories/gems/gems_repository_TEST_setup.sh5
-rw-r--r--0.18.0/paludis/repositories/gems/gems_repository_exceptions.cc35
-rw-r--r--0.18.0/paludis/repositories/gems/gems_repository_exceptions.hh46
-rw-r--r--0.18.0/paludis/repositories/gems/gems_version_metadata.cc43
-rw-r--r--0.18.0/paludis/repositories/gems/gems_version_metadata.hh44
-rw-r--r--0.18.0/paludis/repositories/gems/make_gems_repository.cc64
-rw-r--r--0.18.0/paludis/repositories/gems/make_gems_repository.hh32
-rw-r--r--0.18.0/paludis/repositories/gems/registration.cc40
-rw-r--r--0.18.0/paludis/repositories/gems/yaml.cc368
-rw-r--r--0.18.0/paludis/repositories/gems/yaml.hh130
-rw-r--r--0.18.0/paludis/repositories/gems/yaml_TEST.cc145
-rw-r--r--0.18.0/paludis/repositories/nothing/Makefile.am61
-rw-r--r--0.18.0/paludis/repositories/nothing/nothing_repository.cc258
-rw-r--r--0.18.0/paludis/repositories/nothing/nothing_repository.hh112
-rw-r--r--0.18.0/paludis/repositories/nothing/nothing_repository.sr25
-rw-r--r--0.18.0/paludis/repositories/nothing/registration.cc40
-rw-r--r--0.18.0/paludis/repositories/portage/Makefile.am239
-rw-r--r--0.18.0/paludis/repositories/portage/ebuild_entries.cc526
-rw-r--r--0.18.0/paludis/repositories/portage/ebuild_entries.hh70
-rw-r--r--0.18.0/paludis/repositories/portage/ebuild_flat_metadata_cache.cc147
-rw-r--r--0.18.0/paludis/repositories/portage/ebuild_flat_metadata_cache.hh67
-rw-r--r--0.18.0/paludis/repositories/portage/eclass_mtimes.cc68
-rw-r--r--0.18.0/paludis/repositories/portage/eclass_mtimes.hh55
-rw-r--r--0.18.0/paludis/repositories/portage/glsa.cc251
-rw-r--r--0.18.0/paludis/repositories/portage/glsa.hh113
-rw-r--r--0.18.0/paludis/repositories/portage/glsa.sr8
-rw-r--r--0.18.0/paludis/repositories/portage/make_ebuild_repository.cc165
-rw-r--r--0.18.0/paludis/repositories/portage/make_ebuild_repository.hh44
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository.cc1160
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository.hh187
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository.sr10
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_TEST.cc665
-rwxr-xr-x0.18.0/paludis/repositories/portage/portage_repository_TEST_cleanup.sh10
-rwxr-xr-x0.18.0/paludis/repositories/portage/portage_repository_TEST_setup.sh226
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_entries.cc43
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_entries.hh133
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_entry.cc32
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_exceptions.cc29
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_exceptions.hh53
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_news.cc282
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_news.hh135
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_params.cc8
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_params.hh42
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_params.sr36
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_profile.cc715
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_profile.hh127
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_profile_file.cc85
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_profile_file.hh52
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_sets.cc370
-rw-r--r--0.18.0/paludis/repositories/portage/portage_repository_sets.hh80
-rw-r--r--0.18.0/paludis/repositories/portage/portage_virtual_version_metadata.cc45
-rw-r--r--0.18.0/paludis/repositories/portage/portage_virtual_version_metadata.hh38
-rw-r--r--0.18.0/paludis/repositories/portage/registration.cc62
-rw-r--r--0.18.0/paludis/repositories/portage/use_desc.cc95
-rw-r--r--0.18.0/paludis/repositories/portage/use_desc.hh59
-rw-r--r--0.18.0/paludis/repositories/portage/xml_things.cc219
-rw-r--r--0.18.0/paludis/repositories/portage/xml_things.hh30
-rw-r--r--0.18.0/paludis/repositories/portage/xml_things_TEST.cc92
-rwxr-xr-x0.18.0/paludis/repositories/portage/xml_things_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/repositories/portage/xml_things_TEST_setup.sh115
-rw-r--r--0.18.0/paludis/repositories/repository_maker.cc151
-rw-r--r--0.18.0/paludis/repositories/repository_maker.hh92
-rw-r--r--0.18.0/paludis/repositories/vdb/Makefile.am90
-rw-r--r--0.18.0/paludis/repositories/vdb/registration.cc40
-rw-r--r--0.18.0/paludis/repositories/vdb/vdb_repository.cc1530
-rw-r--r--0.18.0/paludis/repositories/vdb/vdb_repository.hh203
-rw-r--r--0.18.0/paludis/repositories/vdb/vdb_repository.sr26
-rw-r--r--0.18.0/paludis/repositories/vdb/vdb_repository_TEST.cc249
-rwxr-xr-x0.18.0/paludis/repositories/vdb/vdb_repository_TEST_cleanup.sh11
-rwxr-xr-x0.18.0/paludis/repositories/vdb/vdb_repository_TEST_setup.sh35
-rw-r--r--0.18.0/paludis/repositories/vdb/vdb_version_metadata.cc65
-rw-r--r--0.18.0/paludis/repositories/vdb/vdb_version_metadata.hh50
-rw-r--r--0.18.0/paludis/repositories/virtuals/Makefile.am79
-rw-r--r--0.18.0/paludis/repositories/virtuals/installed_virtuals_repository.cc297
-rw-r--r--0.18.0/paludis/repositories/virtuals/installed_virtuals_repository.hh99
-rw-r--r--0.18.0/paludis/repositories/virtuals/registration.cc42
-rw-r--r--0.18.0/paludis/repositories/virtuals/virtuals_repository.cc383
-rw-r--r--0.18.0/paludis/repositories/virtuals/virtuals_repository.hh100
-rw-r--r--0.18.0/paludis/repositories/virtuals/vr_entry.cc26
-rw-r--r--0.18.0/paludis/repositories/virtuals/vr_entry.hh164
-rw-r--r--0.18.0/paludis/repositories/virtuals/vr_entry.sr16
-rw-r--r--0.18.0/paludis/repository.cc277
-rw-r--r--0.18.0/paludis/repository.hh1204
-rw-r--r--0.18.0/paludis/repository.sr71
-rw-r--r--0.18.0/paludis/repository_name_cache.cc201
-rw-r--r--0.18.0/paludis/repository_name_cache.hh90
-rw-r--r--0.18.0/paludis/repository_name_cache_TEST.cc171
-rwxr-xr-x0.18.0/paludis/repository_name_cache_TEST_cleanup.sh10
-rwxr-xr-x0.18.0/paludis/repository_name_cache_TEST_setup.sh22
-rw-r--r--0.18.0/paludis/selinux/Makefile.am44
-rw-r--r--0.18.0/paludis/selinux/security_context.cc241
-rw-r--r--0.18.0/paludis/selinux/security_context.hh167
-rw-r--r--0.18.0/paludis/syncer.cc106
-rw-r--r--0.18.0/paludis/syncer.hh139
-rw-r--r--0.18.0/paludis/syncer.sr37
-rw-r--r--0.18.0/paludis/tasks/Makefile.am68
-rw-r--r--0.18.0/paludis/tasks/exceptions.cc34
-rw-r--r--0.18.0/paludis/tasks/exceptions.hh52
-rw-r--r--0.18.0/paludis/tasks/find_unused_packages_task.cc86
-rw-r--r--0.18.0/paludis/tasks/find_unused_packages_task.hh69
-rw-r--r--0.18.0/paludis/tasks/install_task.cc521
-rw-r--r--0.18.0/paludis/tasks/install_task.hh159
-rw-r--r--0.18.0/paludis/tasks/report_task.cc245
-rw-r--r--0.18.0/paludis/tasks/report_task.hh84
-rw-r--r--0.18.0/paludis/tasks/stage_builder_task.cc124
-rw-r--r--0.18.0/paludis/tasks/stage_builder_task.hh143
-rw-r--r--0.18.0/paludis/tasks/stage_options.sr19
-rw-r--r--0.18.0/paludis/tasks/sync_task.cc108
-rw-r--r--0.18.0/paludis/tasks/sync_task.hh85
-rw-r--r--0.18.0/paludis/tasks/uninstall_task.cc356
-rw-r--r--0.18.0/paludis/tasks/uninstall_task.hh163
-rw-r--r--0.18.0/paludis/test_extras.cc77
-rw-r--r--0.18.0/paludis/util/Makefile.am.m482
-rw-r--r--0.18.0/paludis/util/attributes.hh.in87
-rw-r--r--0.18.0/paludis/util/collection.hh376
-rw-r--r--0.18.0/paludis/util/collection_concrete.hh316
-rw-r--r--0.18.0/paludis/util/compare.hh162
-rw-r--r--0.18.0/paludis/util/comparison_policy.hh524
-rw-r--r--0.18.0/paludis/util/destringify.cc34
-rw-r--r--0.18.0/paludis/util/destringify.hh153
-rw-r--r--0.18.0/paludis/util/destringify_TEST.cc108
-rw-r--r--0.18.0/paludis/util/dir_iterator.cc167
-rw-r--r--0.18.0/paludis/util/dir_iterator.hh118
-rw-r--r--0.18.0/paludis/util/dir_iterator_TEST.cc97
-rwxr-xr-x0.18.0/paludis/util/dir_iterator_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/util/dir_iterator_TEST_setup.sh6
-rw-r--r--0.18.0/paludis/util/exception.cc150
-rw-r--r--0.18.0/paludis/util/exception.hh227
-rw-r--r--0.18.0/paludis/util/fast_unique_copy.hh84
-rw-r--r--0.18.0/paludis/util/fast_unique_copy_TEST.cc121
-rw-r--r--0.18.0/paludis/util/fd_holder.hh68
-rw-r--r--0.18.0/paludis/util/fd_output_stream.hh120
-rw-r--r--0.18.0/paludis/util/files.m442
-rw-r--r--0.18.0/paludis/util/fs_entry.cc480
-rw-r--r--0.18.0/paludis/util/fs_entry.hh343
-rw-r--r--0.18.0/paludis/util/fs_entry_TEST.cc386
-rwxr-xr-x0.18.0/paludis/util/fs_entry_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/util/fs_entry_TEST_setup.sh21
-rw-r--r--0.18.0/paludis/util/instantiation_policy.hh245
-rw-r--r--0.18.0/paludis/util/instantiation_policy_TEST.cc165
-rw-r--r--0.18.0/paludis/util/is_file_with_extension.cc56
-rw-r--r--0.18.0/paludis/util/is_file_with_extension.hh67
-rw-r--r--0.18.0/paludis/util/is_file_with_extension_TEST.cc91
-rwxr-xr-x0.18.0/paludis/util/is_file_with_extension_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/util/is_file_with_extension_TEST_setup.sh6
-rw-r--r--0.18.0/paludis/util/iterator.hh507
-rw-r--r--0.18.0/paludis/util/iterator_TEST.cc348
-rw-r--r--0.18.0/paludis/util/join.hh67
-rw-r--r--0.18.0/paludis/util/join_TEST.cc98
-rw-r--r--0.18.0/paludis/util/log.cc163
-rw-r--r--0.18.0/paludis/util/log.hh124
-rw-r--r--0.18.0/paludis/util/log_TEST.cc74
-rw-r--r--0.18.0/paludis/util/pipe.cc37
-rw-r--r--0.18.0/paludis/util/pipe.hh73
-rw-r--r--0.18.0/paludis/util/private_implementation_pattern.hh108
-rw-r--r--0.18.0/paludis/util/pstream.cc142
-rw-r--r--0.18.0/paludis/util/pstream.hh231
-rw-r--r--0.18.0/paludis/util/pstream_TEST.cc106
-rw-r--r--0.18.0/paludis/util/random.cc43
-rw-r--r--0.18.0/paludis/util/random.hh72
-rw-r--r--0.18.0/paludis/util/random_TEST.cc119
-rw-r--r--0.18.0/paludis/util/save.hh85
-rw-r--r--0.18.0/paludis/util/save_TEST.cc66
-rw-r--r--0.18.0/paludis/util/sr.hh62
-rw-r--r--0.18.0/paludis/util/stringify.hh166
-rw-r--r--0.18.0/paludis/util/stringify_TEST.cc123
-rw-r--r--0.18.0/paludis/util/strip.cc100
-rw-r--r--0.18.0/paludis/util/strip.hh131
-rw-r--r--0.18.0/paludis/util/strip_TEST.cc118
-rw-r--r--0.18.0/paludis/util/system.cc256
-rw-r--r--0.18.0/paludis/util/system.hh170
-rw-r--r--0.18.0/paludis/util/system_TEST.cc176
-rwxr-xr-x0.18.0/paludis/util/system_TEST_cleanup.sh9
-rwxr-xr-x0.18.0/paludis/util/system_TEST_setup.sh5
-rw-r--r--0.18.0/paludis/util/test_extras.cc72
-rw-r--r--0.18.0/paludis/util/tokeniser.cc28
-rw-r--r--0.18.0/paludis/util/tokeniser.hh246
-rw-r--r--0.18.0/paludis/util/tokeniser_TEST.cc136
-rw-r--r--0.18.0/paludis/util/util.hh.m442
-rw-r--r--0.18.0/paludis/util/validated.hh125
-rw-r--r--0.18.0/paludis/util/validated_TEST.cc126
-rw-r--r--0.18.0/paludis/util/virtual_constructor.hh219
-rw-r--r--0.18.0/paludis/util/virtual_constructor_TEST.cc189
-rw-r--r--0.18.0/paludis/util/visitor.hh396
-rw-r--r--0.18.0/paludis/util/visitor_TEST.cc187
-rw-r--r--0.18.0/paludis/version_metadata.cc100
-rw-r--r--0.18.0/paludis/version_metadata.hh74
-rw-r--r--0.18.0/paludis/version_metadata.sr202
-rw-r--r--0.18.0/paludis/version_operator.cc154
-rw-r--r--0.18.0/paludis/version_operator.hh149
-rw-r--r--0.18.0/paludis/version_operator_TEST.cc112
-rw-r--r--0.18.0/paludis/version_requirements.cc49
-rw-r--r--0.18.0/paludis/version_requirements.hh57
-rw-r--r--0.18.0/paludis/version_requirements.sr13
-rw-r--r--0.18.0/paludis/version_spec.cc535
-rw-r--r--0.18.0/paludis/version_spec.hh155
-rw-r--r--0.18.0/paludis/version_spec.sr12
-rw-r--r--0.18.0/paludis/version_spec_TEST.cc399
503 files changed, 68027 insertions, 0 deletions
diff --git a/0.18.0/paludis/Makefile.am.m4 b/0.18.0/paludis/Makefile.am.m4
new file mode 100644
index 000000000..e777aa646
--- /dev/null
+++ b/0.18.0/paludis/Makefile.am.m4
@@ -0,0 +1,127 @@
+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 \
+ $(top_builddir)/paludis/environment/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
+ libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.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 . dep_list 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
+
+libpaludismanpagethings_la_SOURCES = name.cc
+
+if ! MONOLITHIC
+
+libpaludis_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+libpaludismanpagethings_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+endif
+
+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
+
+if MONOLITHIC
+
+noinst_LTLIBRARIES = libpaludis.la libpaludismanpagethings.la
+
+else
+
+lib_LTLIBRARIES = libpaludis.la
+noinst_LTLIBRARIES = libpaludismanpagethings.la
+
+endif
+
+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 $@
+
+changequote(`<', `>')
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
+
diff --git a/0.18.0/paludis/about.hh.in b/0.18.0/paludis/about.hh.in
new file mode 100644
index 000000000..faa023a76
--- /dev/null
+++ b/0.18.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.18.0/paludis/about_TEST.cc b/0.18.0/paludis/about_TEST.cc
new file mode 100644
index 000000000..5815b5f24
--- /dev/null
+++ b/0.18.0/paludis/about_TEST.cc
@@ -0,0 +1,83 @@
+/* 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 .
+ *
+ */
+
+namespace test_cases
+{
+ /**
+ * \test Version tests.
+ *
+ */
+ 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.
+ *
+ */
+ 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.18.0/paludis/args/Makefile.am b/0.18.0/paludis/args/Makefile.am
new file mode 100644
index 000000000..6e80c155b
--- /dev/null
+++ b/0.18.0/paludis/args/Makefile.am
@@ -0,0 +1,69 @@
+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
+
+if ! MONOLITHIC
+
+libpaludisargs_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+endif
+
+TESTS_ENVIRONMENT = env PALUDIS_OPTIONS="" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ bash $(top_srcdir)/test/run_test.sh
+
+if MONOLITHIC
+
+noinst_LTLIBRARIES = libpaludisargs.la
+
+else
+
+lib_LTLIBRARIES = libpaludisargs.la
+
+endif
+
+check_PROGRAMS = $(TESTS)
+
+test_ldadd = \
+ libpaludisargs.la \
+ $(top_builddir)/test/libtest.a \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+args_TEST_SOURCES = args_TEST.cc
+args_TEST_LDADD = $(test_ldadd)
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
+
diff --git a/0.18.0/paludis/args/args.cc b/0.18.0/paludis/args/args.cc
new file mode 100644
index 000000000..510351dd2
--- /dev/null
+++ b/0.18.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.18.0/paludis/args/args.hh b/0.18.0/paludis/args/args.hh
new file mode 100644
index 000000000..8aad3bd9e
--- /dev/null
+++ b/0.18.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.18.0/paludis/args/args_TEST.cc b/0.18.0/paludis/args/args_TEST.cc
new file mode 100644
index 000000000..d7c6de192
--- /dev/null
+++ b/0.18.0/paludis/args/args_TEST.cc
@@ -0,0 +1,178 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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.
+ *
+ */
+
+#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;
+ StringArg arg_monkey;
+ AliasArg arg_other_monkey;
+ 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_monkey(&group_two, "monkey", 'm', "A monkey?"),
+ arg_other_monkey(&arg_monkey, "other-monkey"),
+ 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.
+ *
+ */
+ struct ArgsTestSimple : TestCase
+ {
+ ArgsTestSimple() : TestCase("simple") { }
+
+ void run()
+ {
+ const char * args[] = { "program-name", "--other-monkey", "chimp", "--other-baz",
+ "-fsne", "blah", "7", "three", "--", "--dummy", "one", "two" };
+ CommandLine c1;
+ c1.run(12, 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(c1.arg_monkey.specified());
+ TEST_CHECK(c1.arg_monkey.argument() == "chimp");
+
+ 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.
+ *
+ */
+ struct ArgsTestNoParam : TestCase
+ {
+ ArgsTestNoParam() : TestCase("Missing parameters") { }
+
+ void run()
+ {
+ const char *args[] = { "program-name", "-e" };
+ CommandLine c1;
+ TEST_CHECK_THROWS(c1.run(2, args, "", "", ""), MissingValue);
+ }
+ } test_args_no_param;
+
+ /**
+ * \test String tests.
+ *
+ */
+ struct ArgsTestStringSet : TestCase
+ {
+ ArgsTestStringSet() : TestCase("StringSet") { }
+
+ void run()
+ {
+ const 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.begin_args(), c1.arg_stringset.end_args(), "one") != c1.arg_stringset.end_args());
+ TEST_CHECK(std::find(c1.arg_stringset.begin_args(), c1.arg_stringset.end_args(), "two") != c1.arg_stringset.end_args());
+ TEST_CHECK(std::find(c1.arg_stringset.begin_args(), c1.arg_stringset.end_args(), "three") != c1.arg_stringset.end_args());
+ TEST_CHECK(std::find(c1.arg_stringset.begin_args(), c1.arg_stringset.end_args(), "fnord") == c1.arg_stringset.end_args());
+ }
+ } test_args_string_set;
+}
+
diff --git a/0.18.0/paludis/args/args_dumper.cc b/0.18.0/paludis/args/args_dumper.cc
new file mode 100644
index 000000000..5c0e0ac87
--- /dev/null
+++ b/0.18.0/paludis/args/args_dumper.cc
@@ -0,0 +1,95 @@
+/* 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, 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_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;
+}
+
+#define VISIT(type) void ArgsDumper::visit(const type * const a) \
+ { visit(static_cast<const ArgsOption *>(a)); }
+
+VISIT(SwitchArg)
+VISIT(StringArg)
+VISIT(IntegerArg)
+VISIT(AliasArg)
+
+void ArgsDumper::visit(const StringSetArg * const a)
+{
+ visit(static_cast<const ArgsOption *>(a));
+
+ if (a->begin_allowed_args() != a->end_allowed_args())
+ for (StringSetArg::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;
+ _os << std::endl;
+ }
+}
+
+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.18.0/paludis/args/args_dumper.hh b/0.18.0/paludis/args/args_dumper.hh
new file mode 100644
index 000000000..c1cd9c151
--- /dev/null
+++ b/0.18.0/paludis/args/args_dumper.hh
@@ -0,0 +1,79 @@
+/* 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, 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_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.18.0/paludis/args/args_error.cc b/0.18.0/paludis/args/args_error.cc
new file mode 100644
index 000000000..36f9ee4aa
--- /dev/null
+++ b/0.18.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.18.0/paludis/args/args_error.hh b/0.18.0/paludis/args/args_error.hh
new file mode 100644
index 000000000..2f5b63189
--- /dev/null
+++ b/0.18.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.18.0/paludis/args/args_group.cc b/0.18.0/paludis/args/args_group.cc
new file mode 100644
index 000000000..eaa0eea9b
--- /dev/null
+++ b/0.18.0/paludis/args/args_group.cc
@@ -0,0 +1,77 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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>
+ {
+ 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.18.0/paludis/args/args_group.hh b/0.18.0/paludis/args/args_group.hh
new file mode 100644
index 000000000..bd125a21e
--- /dev/null
+++ b/0.18.0/paludis/args/args_group.hh
@@ -0,0 +1,118 @@
+/* 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
+ * \nosubgrouping
+ */
+ 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.18.0/paludis/args/args_handler.cc b/0.18.0/paludis/args/args_handler.cc
new file mode 100644
index 000000000..f1287c127
--- /dev/null
+++ b/0.18.0/paludis/args/args_handler.cc
@@ -0,0 +1,249 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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 <paludis/util/join.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>
+ {
+ 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_environment_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, const std::string & env_var,
+ const std::string & env_prefix)
+{
+ run(argc, argv, "", env_var, env_prefix);
+}
+
+void
+ArgsHandler::run(const int argc, const char * const * const argv,
+ const std::string & client,
+ const std::string & env_var,
+ const std::string & env_prefix)
+{
+ std::list<std::string> args;
+ std::string env_options;
+
+ setenv("PALUDIS_CLIENT", client.c_str(), 1);
+
+ if (! env_var.empty())
+ env_options = paludis::getenv_with_default(env_var, "");
+
+ 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, env_prefix);
+
+ 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()));
+
+ if (! env_prefix.empty())
+ setenv((env_prefix + "_PARAMS").c_str(), join(_imp->parameters.begin(),
+ _imp->parameters.end(), " ").c_str(), 1);
+}
+
+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.18.0/paludis/args/args_handler.hh b/0.18.0/paludis/args/args_handler.hh
new file mode 100644
index 000000000..4f4115702
--- /dev/null
+++ b/0.18.0/paludis/args/args_handler.hh
@@ -0,0 +1,194 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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
+ * \nosubgrouping
+ */
+ 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_environment_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();
+
+ ///\}
+
+ /**
+ * \deprecated Use the five arg form.
+ */
+ void run(const int, const char * const * const, const std::string & env_var = "",
+ const std::string & env_prefix = "") PALUDIS_ATTRIBUTE((deprecated));
+
+ /**
+ * Parse command line arguments. The third argument is used to
+ * set PALUDIS_CLIENT. The fourth argument is the name of an
+ * environment variable holding arguments which are prepended
+ * to the command line arguments. The fifth argument is used as
+ * a prefix to export our command line via the environment.
+ */
+ void run(const int, const char * const * const,
+ const std::string & client, const std::string & env_var,
+ const std::string & env_prefix);
+
+ ///\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.18.0/paludis/args/args_option.cc b/0.18.0/paludis/args/args_option.cc
new file mode 100644
index 000000000..6731f7407
--- /dev/null
+++ b/0.18.0/paludis/args/args_option.cc
@@ -0,0 +1,325 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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>
+#include <algorithm>
+
+/** \file
+ * Implementation for ArgsOption.
+ *
+ * \ingroup grplibpaludisargs
+ */
+
+using namespace paludis::args;
+
+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;
+ }
+ };
+}
+
+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 o, const std::string & our_long_name) :
+ ArgsOption(o->group(), our_long_name, '\0', "Alias for --" + o->long_name()),
+ _other(o)
+{
+ o->group()->handler()->add_option(o, 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),
+ _validator(0)
+{
+}
+
+StringArg::StringArg(ArgsGroup * const g, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description,
+ void (* v) (const std::string &)) :
+ ArgsOption(g, our_long_name, our_short_name, our_description),
+ _validator(v)
+{
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for StringSetArg.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<StringSetArg>
+ {
+ std::set<std::string> args;
+ std::vector<std::pair<std::string, std::string> > allowed_args;
+ };
+
+ /**
+ * Implementation data for StringSetArg::StringSetArgOptions.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<StringSetArg::StringSetArgOptions>
+ {
+ std::vector<std::pair<std::string, std::string> > options;
+ };
+}
+
+StringSetArg::StringSetArg(ArgsGroup * const g, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description,
+ const StringSetArgOptions & opts) :
+ ArgsOption(g, our_long_name, our_short_name, our_description),
+ PrivateImplementationPattern<StringSetArg>(new Implementation<StringSetArg>),
+ _validator(0)
+{
+ std::copy(opts._imp->options.begin(), opts._imp->options.end(),
+ std::back_inserter(_imp->allowed_args));
+}
+
+StringSetArg::StringSetArg(ArgsGroup * const g, const std::string & our_long_name,
+ const char our_short_name, const std::string & our_description,
+ const StringSetArgOptions & opts, void (* v) (const std::string &)) :
+ ArgsOption(g, our_long_name, our_short_name, our_description),
+ PrivateImplementationPattern<StringSetArg>(new Implementation<StringSetArg>),
+ _validator(v)
+{
+ std::copy(opts._imp->options.begin(), opts._imp->options.end(),
+ std::back_inserter(_imp->allowed_args));
+}
+
+StringSetArg::Iterator
+StringSetArg::begin_args() const
+{
+ return Iterator(_imp->args.begin());
+}
+
+StringSetArg::Iterator
+StringSetArg::end_args() const
+{
+ return Iterator(_imp->args.end());
+}
+
+void
+StringSetArg::add_argument(const std::string & arg)
+{
+ Context context("When handling argument '" + arg + "' for '--" + long_name() + "':");
+
+ if (! _imp->allowed_args.empty())
+ if (_imp->allowed_args.end() == std::find_if(_imp->allowed_args.begin(),
+ _imp->allowed_args.end(), ArgIs(arg)))
+ throw (BadValue("--" + long_name(), arg));
+
+ if (_validator)
+ (*_validator)(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 paludis
+{
+ /**
+ * Implementation data for EnumArg.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<EnumArg>
+ {
+ std::vector<std::pair<std::string, std::string> > allowed_args;
+ };
+
+ /**
+ * Implementation data for EnumArg::EnumArgOptions.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ template<>
+ struct Implementation<EnumArg::EnumArgOptions>
+ {
+ std::vector<std::pair<std::string, std::string> > options;
+ };
+}
+
+StringSetArg::StringSetArgOptions::StringSetArgOptions(std::string opt, std::string desc) :
+ PrivateImplementationPattern<StringSetArgOptions>(new Implementation<StringSetArgOptions>)
+{
+ _imp->options.push_back(std::make_pair(opt, desc));
+}
+
+StringSetArg::StringSetArgOptions &
+StringSetArg::StringSetArgOptions::operator() (std::string opt, std::string desc)
+{
+ _imp->options.push_back(std::make_pair(opt, desc));
+ return *this;
+}
+
+StringSetArg::StringSetArgOptions::StringSetArgOptions(const StringSetArg::StringSetArgOptions & o) :
+ PrivateImplementationPattern<StringSetArgOptions>(new Implementation<StringSetArgOptions>)
+{
+ std::copy(o._imp->options.begin(), o._imp->options.end(),
+ std::back_inserter(_imp->options));
+}
+
+StringSetArg::StringSetArgOptions::~StringSetArgOptions()
+{
+}
+
+StringSetArg::StringSetArgOptions::StringSetArgOptions() :
+ PrivateImplementationPattern<StringSetArgOptions>(new Implementation<StringSetArgOptions>)
+{
+}
+
+void
+EnumArg::set_argument(const std::string & arg)
+{
+ Context context("When handling argument '" + arg + "' for '--" + long_name() + "':");
+
+ 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;
+}
+
+void
+StringArg::set_argument(const std::string & arg)
+{
+ Context context("When handling argument '" + arg + "' for '--" + long_name() + "':");
+
+ if (_validator)
+ (*_validator)(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()
+{
+}
+
+StringSetArg::AllowedArgIterator
+StringSetArg::begin_allowed_args() const
+{
+ return AllowedArgIterator(_imp->allowed_args.begin());
+}
+
+StringSetArg::AllowedArgIterator
+StringSetArg::end_allowed_args() const
+{
+ return AllowedArgIterator(_imp->allowed_args.end());
+}
+
diff --git a/0.18.0/paludis/args/args_option.hh b/0.18.0/paludis/args/args_option.hh
new file mode 100644
index 000000000..c152a4b90
--- /dev/null
+++ b/0.18.0/paludis/args/args_option.hh
@@ -0,0 +1,435 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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;
+ void (* _validator) (const std::string &);
+
+ public:
+ /**
+ * Constructor
+ */
+ StringArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description);
+
+ /**
+ * Constructor with validator.
+ */
+ StringArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description,
+ void (* validator) (const std::string &));
+
+ /**
+ * 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);
+ };
+
+ /**
+ * An option that takes a set of strings.
+ *
+ * \ingroup grplibpaludisargs
+ * \nosubgrouping
+ */
+ class PALUDIS_VISIBLE StringSetArg :
+ public ArgsOption,
+ public Visitable<StringSetArg, ArgsVisitorTypes>,
+ private PrivateImplementationPattern<StringSetArg>
+ {
+ private:
+ void (* _validator) (const std::string &);
+
+ public:
+ /**
+ * Helper class for passing available options and associated descriptions
+ * to the StringSetArg constructor.
+ *
+ * \ingroup grplibpaludisargs
+ */
+ class PALUDIS_VISIBLE StringSetArgOptions :
+ private PrivateImplementationPattern<StringSetArgOptions>
+ {
+ friend class StringSetArg;
+
+ public:
+ /**
+ * Constructor
+ */
+ StringSetArgOptions(const std::string, const std::string);
+
+ /**
+ * Blank constructor
+ */
+ explicit StringSetArgOptions();
+
+ /**
+ * Copy constructor
+ */
+ StringSetArgOptions(const StringSetArgOptions &);
+
+ /**
+ * Destructor.
+ */
+ ~StringSetArgOptions();
+
+ /**
+ * Adds another (option, description) pair.
+ */
+ StringSetArgOptions & operator() (const std::string, const std::string);
+ };
+
+ ///\name Basic operations
+ ///\{
+
+ StringSetArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description,
+ const StringSetArgOptions & options = StringSetArgOptions());
+
+ StringSetArg(ArgsGroup * const, const std::string & long_name,
+ const char short_name, const std::string & description,
+ const StringSetArgOptions & options,
+ void (* validator) (const std::string &));
+
+ ~StringSetArg();
+
+ ///\}
+
+ ///\name Iterate over our args.
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<StringArg, const std::string> Iterator;
+
+ Iterator begin_args() const;
+
+ Iterator end_args() const;
+
+ ///\}
+
+ /**
+ * Add an argument to the set.
+ */
+ void add_argument(const std::string & arg);
+
+ ///\name Iterate over our allowed arguments and associated descriptions
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<StringSetArg,
+ const std::pair<std::string, std::string> > AllowedArgIterator;
+
+ AllowedArgIterator begin_allowed_args() const;
+
+ AllowedArgIterator end_allowed_args() const;
+
+ ///\}
+ };
+
+
+ /**
+ * 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);
+ }
+
+ ArgsOption * other() const
+ {
+ return _other;
+ }
+ };
+
+ /**
+ * 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
+ * \nosubgrouping
+ */
+ 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.18.0/paludis/args/args_visitor.cc b/0.18.0/paludis/args/args_visitor.cc
new file mode 100644
index 000000000..4eb20a418
--- /dev/null
+++ b/0.18.0/paludis/args/args_visitor.cc
@@ -0,0 +1,132 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+/*
+ * Copyright (c) 2005, 2006, 2007 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 <paludis/util/system.hh>
+#include <paludis/util/join.hh>
+
+#include <algorithm>
+#include <sstream>
+#include <stdlib.h>
+
+/** \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,
+ const std::string & env_prefix) :
+ _args_index(ai),
+ _args_end(ae),
+ _env_prefix(env_prefix)
+{
+}
+
+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);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), "1", 1);
+}
+
+void ArgsVisitor::visit(StringArg * const arg)
+{
+ visit(static_cast<ArgsOption *>(arg));
+ std::string p(get_param(arg));
+ arg->set_argument(p);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), p.c_str(), 1);
+}
+
+void ArgsVisitor::visit(AliasArg * const arg)
+{
+ arg->other()->accept(this);
+}
+
+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
+ {
+ int a(destringify<int>(param));
+ arg->set_argument(a);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), stringify(a).c_str(), 1);
+ }
+ catch (const DestringifyError &)
+ {
+ throw BadValue("--" + arg->long_name(), param);
+ }
+}
+
+void ArgsVisitor::visit(EnumArg * const arg)
+{
+ visit(static_cast<ArgsOption*>(arg));
+ std::string p(get_param(arg));
+ arg->set_argument(p);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), p.c_str(), 1);
+}
+
+void ArgsVisitor::visit(StringSetArg * const arg)
+{
+ visit(static_cast<ArgsOption *>(arg));
+ std::string param = get_param(arg);
+ arg->add_argument(param);
+
+ if (! _env_prefix.empty())
+ setenv(env_name(arg->long_name()).c_str(), join(arg->begin_args(),
+ arg->end_args(), " ").c_str(), 1);
+}
+
+std::string
+ArgsVisitor::env_name(const std::string & long_name) const
+{
+ std::string result(_env_prefix + "_" + long_name);
+ std::replace(result.begin(), result.end(), '-', '_');
+ return result;
+}
+
diff --git a/0.18.0/paludis/args/args_visitor.hh b/0.18.0/paludis/args/args_visitor.hh
new file mode 100644
index 000000000..e60769ece
--- /dev/null
+++ b/0.18.0/paludis/args/args_visitor.hh
@@ -0,0 +1,104 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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;
+ std::string _env_prefix;
+
+ const std::string & get_param(const ArgsOption * const);
+
+ std::string env_name(const std::string & long_name) const;
+
+ public:
+ /**
+ * Constructor
+ */
+ ArgsVisitor(libwrapiter::ForwardIterator<ArgsVisitor, std::string> *,
+ libwrapiter::ForwardIterator<ArgsVisitor, std::string>,
+ const std::string & env_prefix = "");
+
+ /// 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.18.0/paludis/args/bad_argument.cc b/0.18.0/paludis/args/bad_argument.cc
new file mode 100644
index 000000000..4aa116718
--- /dev/null
+++ b/0.18.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 grplibpaludisargs
+ * \ingroup grpexceptions
+ */
+
+using namespace paludis::args;
+
+BadArgument::BadArgument(const std::string & option) throw () :
+ ArgsError("Bad argument '" + option + "'")
+{
+}
+
diff --git a/0.18.0/paludis/args/bad_argument.hh b/0.18.0/paludis/args/bad_argument.hh
new file mode 100644
index 000000000..92660e82b
--- /dev/null
+++ b/0.18.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.18.0/paludis/args/man.cc b/0.18.0/paludis/args/man.cc
new file mode 100644
index 000000000..0997eff4d
--- /dev/null
+++ b/0.18.0/paludis/args/man.cc
@@ -0,0 +1,297 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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>
+#include <sstream>
+
+using namespace paludis;
+using namespace paludis::args;
+using std::endl;
+
+namespace
+{
+ struct ExtraText :
+ ArgsVisitorTypes::ConstVisitor
+ {
+ std::stringstream s;
+ ManFormat mf;
+
+ ExtraText(ManFormat m) :
+ mf(m)
+ {
+ }
+
+ void visit(const ArgsOption * const)
+ {
+ }
+
+ void visit(const StringArg * const)
+ {
+ }
+
+ void visit(const AliasArg * const)
+ {
+ }
+
+ void visit(const SwitchArg * const)
+ {
+ }
+
+ void visit(const IntegerArg * const)
+ {
+ }
+
+ void visit(const EnumArg * const e)
+ {
+ if (e->begin_allowed_args() == e->end_allowed_args())
+ return;
+
+ switch (mf)
+ {
+ case mf_man:
+ break;
+
+ case mf_html:
+ s << "<dl>" << endl;
+ break;
+ }
+
+ for (EnumArg::AllowedArgIterator a(e->begin_allowed_args()), a_end(e->end_allowed_args()) ;
+ a != a_end ; ++a)
+ {
+ switch (mf)
+ {
+ case mf_man:
+ s << ".RS" << endl;
+ s << ".TP" << endl;
+ s << ".B \"" << a->first << "\"" << endl;
+ s << a->second << endl;
+ s << ".RE" << endl;
+ break;
+
+ case mf_html:
+ s << "<dt>" << a->first << "</dt>" << endl;
+ s << "<dd>" << a->second << "</dd>" << endl;
+ break;
+ }
+ }
+
+ switch (mf)
+ {
+ case mf_man:
+ break;
+
+ case mf_html:
+ s << "</dl>" << endl;
+ break;
+ }
+ }
+
+ void visit(const StringSetArg * const e)
+ {
+ for (StringSetArg::AllowedArgIterator a(e->begin_allowed_args()), a_end(e->end_allowed_args()) ;
+ a != a_end ; ++a)
+ {
+ s << ".RS" << endl;
+ s << ".TP" << endl;
+ s << ".B \"" << a->first << "\"" << endl;
+ s << ".BR" << endl;
+ s << a->second << endl;
+ s << ".RE" << endl;
+ }
+ }
+ };
+
+ std::ostream &
+ operator<< (std::ostream & s, const ExtraText & t)
+ {
+ s << t.s.str();
+ return s;
+ }
+}
+
+void
+paludis::args::generate_man(std::ostream & f, const ArgsHandler * const h)
+{
+ generate_man(f, h, mf_man);
+}
+
+void
+paludis::args::generate_man(std::ostream & f, const ArgsHandler * const h,
+ const ManFormat mf)
+{
+ switch (mf)
+ {
+ case mf_man:
+ 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;
+ break;
+
+ case mf_html:
+ f << "<h1>" << h->app_name() << "(" << h->man_section() << ")" << "</h1>" << endl;
+ f << "<h2>Name</h2>" << endl;
+ f << "<p>" << h->app_name() << " - " << h->app_synopsis() << "</p>" << endl;
+ f << "<h2>Synopsis</h2>" << endl;
+ break;
+ }
+
+ for (ArgsHandler::UsageLineIterator u(h->begin_usage_lines()),
+ u_end(h->end_usage_lines()) ; u != u_end ; ++u)
+ {
+ switch (mf)
+ {
+ case mf_man:
+ f << ".B " << h->app_name() << " " << *u << endl << endl;
+ break;
+
+ case mf_html:
+ f << "<p>" << h->app_name() << " " << *u << "</p>" << endl;
+ break;
+ }
+ }
+
+ switch (mf)
+ {
+ case mf_man:
+ f << ".SH DESCRIPTION" << endl;
+ f << h->app_description() << endl;
+ f << ".SH OPTIONS" << endl;
+ break;
+
+ case mf_html:
+ f << "<h2>Description</h2>" << endl;
+ f << "<p>" << h->app_description() << "</p>" << endl;
+ f << "<h2>Options</h2>" << endl;
+ break;
+ }
+
+ for (ArgsHandler::ArgsGroupsIterator a(h->begin_args_groups()),
+ a_end(h->end_args_groups()) ; a != a_end ; ++a)
+ {
+ switch (mf)
+ {
+ case mf_man:
+ f << ".SS \"" << (*a)->name() << "\"" << endl;
+ f << (*a)->description() << endl;
+ break;
+
+ case mf_html:
+ f << "<h3>" << (*a)->name() << "</h3>" << endl;
+ f << "<p>" << (*a)->description() << "</p>" << endl;
+ f << "<dl>";
+ break;
+ }
+
+ for (paludis::args::ArgsGroup::Iterator b((*a)->begin()), b_end((*a)->end()) ;
+ b != b_end ; ++b)
+ {
+ switch (mf)
+ {
+ case mf_man:
+ f << ".TP" << endl;
+ f << ".B \"";
+ if ((*b)->short_name())
+ f << "\\-" << (*b)->short_name() << " , ";
+ f << "\\-\\-" << (*b)->long_name() << "\"" << endl;
+ f << (*b)->description() << endl;
+ break;
+
+ case mf_html:
+ f << "<dt>";
+ if ((*b)->short_name())
+ f << "-" << (*b)->short_name() << ", ";
+ f << "--" << (*b)->long_name() << "</dt>" << endl;
+ f << "<dd>" << (*b)->description() << endl;
+
+ break;
+ }
+
+ ExtraText t(mf);
+ (*b)->accept(&t);
+ f << t;
+
+ switch (mf)
+ {
+ case mf_man:
+ break;
+
+ case mf_html:
+ f << "</dd>" << endl;
+ break;
+ }
+ }
+
+ switch (mf)
+ {
+ case mf_man:
+ break;
+
+ case mf_html:
+ f << "</dl>";
+ break;
+ }
+ }
+
+ if (h->begin_environment_lines() != h->end_environment_lines())
+ {
+ switch (mf)
+ {
+ case mf_man:
+ f << ".SH ENVIRONMENT" << endl;
+ break;
+
+ case mf_html:
+ f << "<h2>Environment</h2>" << endl;
+ f << "<dl>" << endl;
+ break;
+ }
+
+ for (ArgsHandler::EnvironmentLineIterator a(h->begin_environment_lines()),
+ a_end(h->end_environment_lines()) ; a != a_end ; ++a)
+ {
+ switch (mf)
+ {
+ case mf_man:
+ f << ".TP" << endl;
+ f << ".B \"" << a->first << "\"" << endl;
+ f << a->second << endl;
+ break;
+
+ case mf_html:
+ f << "<dt>" << a->first << "</dt>" << endl;
+ f << "<dd>" << a->second << "</dd>" << endl;
+ break;
+ }
+ }
+
+ switch (mf)
+ {
+ case mf_man:
+ break;
+
+ case mf_html:
+ f << "</dl>" << endl;
+ break;
+ }
+ }
+}
+
diff --git a/0.18.0/paludis/args/man.hh b/0.18.0/paludis/args/man.hh
new file mode 100644
index 000000000..356d4ce8a
--- /dev/null
+++ b/0.18.0/paludis/args/man.hh
@@ -0,0 +1,56 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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
+ {
+ /**
+ * Format for generate_man.
+ */
+ enum ManFormat
+ {
+ mf_man,
+ mf_html
+ };
+
+ /**
+ * Write a man page to an ostream.
+ *
+ * \deprecated Use the three arg form.
+ */
+ void generate_man(std::ostream &, const ArgsHandler * const h) PALUDIS_VISIBLE
+ PALUDIS_ATTRIBUTE((deprecated));
+
+ /**
+ * Write a man page to an ostream.
+ *
+ * \deprecated Use the three arg form.
+ */
+ void generate_man(std::ostream &, const ArgsHandler * const h, const ManFormat) PALUDIS_VISIBLE;
+ }
+}
+
+#endif
diff --git a/0.18.0/paludis/config_file.cc b/0.18.0/paludis/config_file.cc
new file mode 100644
index 000000000..7b60aa5b5
--- /dev/null
+++ b/0.18.0/paludis/config_file.cc
@@ -0,0 +1,451 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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>
+ {
+ 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>
+ {
+ 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,
+ std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> > m) :
+ ConfigFile(s),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ _imp->entries.insert(m->begin(), m->end());
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(const std::string & our_filename,
+ std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> > m) :
+ ConfigFile(our_filename),
+ PrivateImplementationPattern<KeyValueConfigFile>(new Implementation<KeyValueConfigFile>)
+{
+ _imp->entries.insert(m->begin(), m->end());
+ need_lines();
+}
+
+KeyValueConfigFile::KeyValueConfigFile(const FSEntry & our_filename,
+ std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> > 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.18.0/paludis/config_file.hh b/0.18.0/paludis/config_file.hh
new file mode 100644
index 000000000..73cc2e00d
--- /dev/null
+++ b/0.18.0/paludis/config_file.hh
@@ -0,0 +1,310 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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>
+#include <tr1/memory>
+
+/** \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
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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,
+ std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> >);
+
+ /**
+ * Constructor, from a filename, with defaults.
+ */
+ KeyValueConfigFile(const std::string & filename,
+ std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> >);
+
+ /**
+ * Constructor, from a filename, with defaults.
+ */
+ KeyValueConfigFile(const FSEntry & filename,
+ std::tr1::shared_ptr<const AssociativeCollection<std::string, std::string> >);
+
+ ~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.18.0/paludis/config_file_TEST.cc b/0.18.0/paludis/config_file_TEST.cc
new file mode 100644
index 000000000..c921f8b33
--- /dev/null
+++ b/0.18.0/paludis/config_file_TEST.cc
@@ -0,0 +1,323 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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 grpconfigfile
+ */
+
+namespace
+{
+ /**
+ * A ConfigFile descendent for use in tests.
+ *
+ */
+ 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.
+ *
+ */
+ 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.
+ *
+ */
+ 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.
+ *
+ */
+ 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.
+ *
+ */
+ 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.
+ *
+ */
+ 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.
+ *
+ */
+ 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;
+ std::tr1::shared_ptr<AssociativeCollection<std::string, std::string> > 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.
+ *
+ */
+ 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.18.0/paludis/config_file_TEST_cleanup.sh b/0.18.0/paludis/config_file_TEST_cleanup.sh
new file mode 100755
index 000000000..b4ed3dbde
--- /dev/null
+++ b/0.18.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.18.0/paludis/config_file_TEST_setup.sh b/0.18.0/paludis/config_file_TEST_setup.sh
new file mode 100755
index 000000000..a35809b84
--- /dev/null
+++ b/0.18.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.18.0/paludis/contents.cc b/0.18.0/paludis/contents.cc
new file mode 100644
index 000000000..b271fd32d
--- /dev/null
+++ b/0.18.0/paludis/contents.cc
@@ -0,0 +1,119 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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)
+{
+}
+
+ContentsFifoEntry::ContentsFifoEntry(const std::string & our_name) :
+ ContentsEntry(our_name)
+{
+}
+
+ContentsDevEntry::ContentsDevEntry(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>
+ {
+ std::list<std::tr1::shared_ptr<const ContentsEntry> > c;
+ };
+}
+
+Contents::Contents() :
+ PrivateImplementationPattern<Contents>(new Implementation<Contents>())
+{
+}
+
+Contents::~Contents()
+{
+}
+
+void
+Contents::add(std::tr1::shared_ptr<const ContentsEntry> 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());
+}
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const ContentsSymEntry & e)
+{
+ s << e.name() << " -> " << e.target();
+ return s;
+}
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const ContentsEntry & e)
+{
+ s << e.name();
+ return s;
+}
diff --git a/0.18.0/paludis/contents.hh b/0.18.0/paludis/contents.hh
new file mode 100644
index 000000000..8e8040b12
--- /dev/null
+++ b/0.18.0/paludis/contents.hh
@@ -0,0 +1,267 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <string>
+#include <tr1/memory>
+
+#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 ContentsFifoEntry;
+ struct ContentsDevEntry;
+ struct ContentsMiscEntry;
+
+ /**
+ * Visit a contents heirarchy.
+ *
+ * \ingroup grpcontents
+ */
+ typedef VisitorTypes<ContentsFileEntry *, ContentsDirEntry *,
+ ContentsSymEntry *, ContentsFifoEntry *, ContentsDevEntry *, ContentsMiscEntry *> ContentsVisitorTypes;
+
+ /**
+ * Base class for a contents entry.
+ *
+ * \ingroup grpcontents
+ * \nosubgrouping
+ */
+ class ContentsEntry :
+ private InstantiationPolicy<ContentsEntry, instantiation_method::NonCopyableTag>,
+ 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
+ * \nosubgrouping
+ */
+ class ContentsFileEntry :
+ public ContentsEntry,
+ public Visitable<ContentsFileEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsFileEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A directory contents entry.
+ *
+ * \ingroup grpcontents
+ * \nosubgrouping
+ */
+ class ContentsDirEntry :
+ public ContentsEntry,
+ public Visitable<ContentsDirEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsDirEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A misc contents entry.
+ *
+ * \ingroup grpcontents
+ * \nosubgrouping
+ */
+ class ContentsMiscEntry :
+ public ContentsEntry,
+ public Visitable<ContentsMiscEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsMiscEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A fifo contents entry.
+ *
+ * \ingroup grpcontents
+ * \nosubgrouping
+ */
+ class ContentsFifoEntry :
+ public ContentsEntry,
+ public Visitable<ContentsFifoEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsFifoEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A device contents entry.
+ *
+ * \ingroup grpcontents
+ * \nosubgrouping
+ */
+ class ContentsDevEntry :
+ public ContentsEntry,
+ public Visitable<ContentsDevEntry, ContentsVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ ContentsDevEntry(const std::string & name);
+
+ ///\}
+ };
+
+ /**
+ * A sym contents entry.
+ *
+ * \ingroup grpcontents
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ class Contents :
+ private InstantiationPolicy<Contents, instantiation_method::NonCopyableTag>,
+ private PrivateImplementationPattern<Contents>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ Contents();
+ ~Contents();
+
+ ///\}
+
+ /// Add a new entry.
+ void add(std::tr1::shared_ptr<const ContentsEntry> c);
+
+ ///\name Iterate over our entries
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<Contents, const std::tr1::shared_ptr<const ContentsEntry> > Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\}
+ };
+
+ /**
+ * Write a ContentsSymEntry to a stream
+ *
+ * \ingroup grpcontents
+ */
+ std::ostream & operator<< (std::ostream &, const ContentsSymEntry &);
+
+ /**
+ * Write a ContentsEntry to a stream
+ *
+ * \ingroup grpcontents
+ */
+ std::ostream & operator<< (std::ostream &, const ContentsEntry &);
+
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_atom.cc b/0.18.0/paludis/dep_atom.cc
new file mode 100644
index 000000000..dd3941f63
--- /dev/null
+++ b/0.18.0/paludis/dep_atom.cc
@@ -0,0 +1,441 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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 <paludis/util/collection_concrete.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;
+}
+
+const PackageDepAtom *
+DepAtom::as_package_dep_atom() const
+{
+ return 0;
+}
+
+namespace paludis
+{
+ /**
+ * Implementation data for CompositeDepAtom.
+ *
+ * \ingroup grpdepatoms
+ */
+ template<>
+ struct Implementation<CompositeDepAtom>
+ {
+ std::list<std::tr1::shared_ptr<const DepAtom> > children;
+ };
+}
+
+CompositeDepAtom::CompositeDepAtom() :
+ PrivateImplementationPattern<CompositeDepAtom>(new Implementation<CompositeDepAtom>)
+{
+}
+
+CompositeDepAtom::~CompositeDepAtom()
+{
+}
+
+void
+CompositeDepAtom::add_child(std::tr1::shared_ptr<const DepAtom> 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;
+}
+
+const PackageDepAtom *
+PackageDepAtom::as_package_dep_atom() const
+{
+ return this;
+}
+
+BlockDepAtom::BlockDepAtom(std::tr1::shared_ptr<const PackageDepAtom> a) :
+ StringDepAtom("!" + a->text()),
+ _atom(a)
+{
+}
+
+PackageDepAtom::PackageDepAtom(const QualifiedPackageName & our_package) :
+ StringDepAtom(stringify(our_package)),
+ _package(our_package),
+ _version_requirements_mode(vr_and)
+{
+}
+
+PackageDepAtom::PackageDepAtom(const PackageDepAtom & other) :
+ VisitableInterface<DepAtomVisitorTypes>(other),
+ StringDepAtom(stringify(other)),
+ Visitable<PackageDepAtom, DepAtomVisitorTypes>(other),
+ _package(other._package),
+ _version_requirements(new VersionRequirements::Concrete),
+ _version_requirements_mode(other._version_requirements_mode),
+ _slot(other._slot),
+ _repository(other._repository),
+ _use_requirements(other._use_requirements),
+ _tag(other._tag)
+{
+ std::copy(other._version_requirements->begin(), other._version_requirements->end(),
+ _version_requirements->inserter());
+}
+
+PackageDepAtom::PackageDepAtom(const std::string & ss) :
+ StringDepAtom(ss),
+ _package(CategoryNamePart("later"), PackageNamePart("later")),
+ _version_requirements_mode(vr_and)
+{
+ 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.reset(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.reset(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.reset(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;
+ VersionOperator op(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));
+
+ _version_requirements.reset(new VersionRequirements::Concrete);
+
+ if ('*' == s.at(s.length() - 1))
+ {
+ if (op != vo_equal)
+ Log::get_instance()->message(ll_qa, lc_context,
+ "Package dep atom '" + ss + "' uses * "
+ "with operator '" + stringify(op) +
+ "', pretending it uses the equals operator instead");
+ op = vo_equal_star;
+ _version_requirements->push_back(VersionRequirement(op, VersionSpec(s.substr(q, s.length() - q - 1))));
+ }
+ else
+ _version_requirements->push_back(VersionRequirement(op, 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 PlainTextDepAtom & a)
+{
+ s << a.text();
+ return s;
+}
+
+std::ostream &
+paludis::operator<< (std::ostream & s, const PackageDepAtom & a)
+{
+ if (a.version_requirements_ptr())
+ {
+ bool need_op(false);
+ for (VersionRequirements::Iterator r(a.version_requirements_ptr()->begin()),
+ r_end(a.version_requirements_ptr()->end()) ; r != r_end ; ++r)
+ {
+ if (need_op)
+ {
+ switch (a.version_requirements_mode())
+ {
+ case vr_and:
+ s << "&";
+ break;
+
+ case vr_or:
+ s << "|";
+ break;
+
+ case last_vr:
+ ;
+ }
+ }
+
+ if (r->version_operator == vo_equal_star)
+ s << "=";
+ else
+ s << r->version_operator;
+
+ need_op = true;
+ }
+ }
+
+ s << a.package();
+
+ if (a.version_requirements_ptr())
+ {
+ bool need_comma(false), need_hyphen(true);
+ for (VersionRequirements::Iterator r(a.version_requirements_ptr()->begin()),
+ r_end(a.version_requirements_ptr()->end()) ; r != r_end ; ++r)
+ {
+ if (need_comma)
+ s << ",";
+
+ if (need_hyphen)
+ {
+ s << "-";
+ need_hyphen = false;
+ }
+
+ s << r->version_spec;
+
+ if (r->version_operator == vo_equal_star)
+ s << "*";
+
+ need_comma = true;
+ }
+ }
+
+ 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>
+ {
+ 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;
+}
+
+std::tr1::shared_ptr<PackageDepAtom>
+PackageDepAtom::without_use_requirements() const
+{
+ std::string s(text());
+ if (std::string::npos != s.find('['))
+ s.erase(s.find('['));
+ return std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom(s));
+}
+
diff --git a/0.18.0/paludis/dep_atom.hh b/0.18.0/paludis/dep_atom.hh
new file mode 100644
index 000000000..d58a36425
--- /dev/null
+++ b/0.18.0/paludis/dep_atom.hh
@@ -0,0 +1,525 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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/instantiation_policy.hh>
+#include <paludis/util/visitor.hh>
+#include <paludis/version_requirements.hh>
+#include <paludis/version_operator.hh>
+#include <paludis/version_spec.hh>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+#include <tr1/memory>
+
+/** \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
+ * \nosubgrouping
+ */
+ class DepAtom :
+ public virtual VisitableInterface<DepAtomVisitorTypes>,
+ private InstantiationPolicy<DepAtom, instantiation_method::NonCopyableTag>
+ {
+ 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;
+
+ /**
+ * Return us as a PackageDepAtom, or 0 if we are not a
+ * UseDepAtom.
+ */
+ virtual const PackageDepAtom * as_package_dep_atom() const;
+
+ ///\}
+ };
+
+ /**
+ * Class for dependency atoms that have a number of child dependency
+ * atoms.
+ *
+ * \ingroup grpdepatoms
+ * \nosubgrouping
+ */
+ 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(std::tr1::shared_ptr<const DepAtom>);
+
+ ///\}
+
+ ///\name Iterate over our children
+ ///\{
+
+ typedef libwrapiter::ForwardIterator<CompositeDepAtom, const std::tr1::shared_ptr<const DepAtom> > Iterator;
+
+ Iterator begin() const;
+
+ Iterator end() const;
+
+ ///\}
+ };
+
+ /**
+ * Represents a "|| ( )" dependency block.
+ *
+ * \ingroup grpdepatoms
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ class AllDepAtom :
+ public CompositeDepAtom,
+ public Visitable<AllDepAtom, DepAtomVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ AllDepAtom();
+
+ ///\}
+ };
+
+ /**
+ * Represents a use? ( ) dependency atom.
+ *
+ * \ingroup grpdepatoms
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ class 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
+ * \nosubgrouping
+ */
+ class PackageDepAtom :
+ public StringDepAtom,
+ public Visitable<PackageDepAtom, DepAtomVisitorTypes>
+ {
+ private:
+ QualifiedPackageName _package;
+ std::tr1::shared_ptr<VersionRequirements> _version_requirements;
+ VersionRequirementsMode _version_requirements_mode;
+ std::tr1::shared_ptr<SlotName> _slot;
+ std::tr1::shared_ptr<RepositoryName> _repository;
+ std::tr1::shared_ptr<UseRequirements> _use_requirements;
+ std::tr1::shared_ptr<const DepTag> _tag;
+
+ const PackageDepAtom & operator= (const PackageDepAtom &);
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, no version or SLOT restrictions.
+ */
+ PackageDepAtom(const QualifiedPackageName & package);
+
+ /**
+ * Constructor, parse restrictions ourself.
+ */
+ PackageDepAtom(const std::string &);
+
+ /**
+ * Copy constructor.
+ */
+ PackageDepAtom(const PackageDepAtom &);
+
+ ~PackageDepAtom();
+
+ ///\}
+
+ /**
+ * Fetch the package name.
+ */
+ const QualifiedPackageName & package() const
+ {
+ return _package;
+ }
+
+ /**
+ * Fetch the version requirements (may be a zero pointer).
+ */
+ std::tr1::shared_ptr<const VersionRequirements> version_requirements_ptr() const
+ {
+ return _version_requirements;
+ }
+
+ /**
+ * Fetch the version requirements (may be a zero pointer).
+ */
+ std::tr1::shared_ptr<VersionRequirements> version_requirements_ptr()
+ {
+ return _version_requirements;
+ }
+
+ /**
+ * Fetch the version requirements mode.
+ */
+ VersionRequirementsMode version_requirements_mode() const
+ {
+ return _version_requirements_mode;
+ }
+
+ /**
+ * Set the version requirements mode.
+ */
+ void set_version_requirements_mode(const VersionRequirementsMode m)
+ {
+ _version_requirements_mode = m;
+ }
+
+ /**
+ * Fetch the slot name (may be a zero pointer).
+ */
+ std::tr1::shared_ptr<const SlotName> slot_ptr() const
+ {
+ return _slot;
+ }
+
+ /**
+ * Fetch the repo name (may be a zero pointer).
+ */
+ std::tr1::shared_ptr<const RepositoryName> repository_ptr() const
+ {
+ return _repository;
+ }
+
+ /**
+ * Fetch the use requirements (may be a zero pointer).
+ */
+ std::tr1::shared_ptr<const UseRequirements> use_requirements_ptr() const
+ {
+ return _use_requirements;
+ }
+
+ /**
+ * Fetch our tag.
+ */
+ std::tr1::shared_ptr<const DepTag> tag() const
+ {
+ return _tag;
+ }
+
+ /**
+ * Set our tag.
+ */
+ void set_tag(const std::tr1::shared_ptr<const DepTag> & s)
+ {
+ _tag = s;
+ }
+
+ /**
+ * Fetch a copy of ourself without the USE requirements.
+ */
+ std::tr1::shared_ptr<PackageDepAtom> without_use_requirements() const;
+
+ virtual const PackageDepAtom * as_package_dep_atom() const;
+ };
+
+ /**
+ * A PlainTextDepAtom represents a plain text entry (for example,
+ * a URI in SRC_URI).
+ *
+ * \ingroup grpdepatoms
+ * \nosubgrouping
+ */
+ class PlainTextDepAtom :
+ public StringDepAtom,
+ public Visitable<PlainTextDepAtom, DepAtomVisitorTypes>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ PlainTextDepAtom(const std::string &);
+
+ ///\}
+ };
+
+ /**
+ * A PlainTextDepAtom can be written to an ostream.
+ *
+ * \ingroup grpdepatoms
+ */
+ std::ostream & operator<< (std::ostream &, const PlainTextDepAtom &);
+
+ /**
+ * Thrown if an invalid package dep atom specification is encountered.
+ *
+ * \ingroup grpexceptions
+ * \ingroup grpdepatoms
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ class BlockDepAtom :
+ public StringDepAtom,
+ public Visitable<BlockDepAtom, DepAtomVisitorTypes>
+ {
+ private:
+ std::tr1::shared_ptr<const PackageDepAtom> _atom;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, with blocking atom.
+ */
+ BlockDepAtom(std::tr1::shared_ptr<const PackageDepAtom> atom);
+
+ ///\}
+
+ /**
+ * Fetch the atom we're blocking.
+ */
+ std::tr1::shared_ptr<const PackageDepAtom> blocked_atom() const
+ {
+ return _atom;
+ }
+ };
+
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_atom_TEST.cc b/0.18.0/paludis/dep_atom_TEST.cc
new file mode 100644
index 000000000..72d43f266
--- /dev/null
+++ b/0.18.0/paludis/dep_atom_TEST.cc
@@ -0,0 +1,167 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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.
+ *
+ */
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ /**
+ * \test Test DepAtom as_ functions.
+ *
+ */
+ struct DepAtomAsTest : TestCase
+ {
+ DepAtomAsTest() : TestCase("dep atom as") { }
+
+ void run()
+ {
+ std::tr1::shared_ptr<PackageDepAtom> x(new PackageDepAtom("foo/bar"));
+ TEST_CHECK(0 == x->as_use_dep_atom());
+
+ std::tr1::shared_ptr<UseDepAtom> y(new UseDepAtom(UseFlagName("foo"), x));
+ TEST_CHECK(0 != y->as_use_dep_atom());
+ TEST_CHECK(y.get() == y->as_use_dep_atom());
+ }
+ } test_dep_atom_as;
+
+ /**
+ * \test Test DepAtom composite functions.
+ *
+ */
+ struct DepAtomCompositeTest : TestCase
+ {
+ DepAtomCompositeTest() : TestCase("dep atom composite") { }
+
+ void run()
+ {
+ std::tr1::shared_ptr<AllDepAtom> x(new AllDepAtom);
+ TEST_CHECK(x->begin() == x->end());
+
+ x->add_child(std::tr1::shared_ptr<PackageDepAtom>(new PackageDepAtom("x/y")));
+ TEST_CHECK(x->begin() != x->end());
+ TEST_CHECK_EQUAL(1, std::distance(x->begin(), x->end()));
+
+ x->add_child(std::tr1::shared_ptr<PackageDepAtom>(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.
+ *
+ */
+ 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_requirements_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_requirements_ptr());
+ TEST_CHECK_EQUAL(std::distance(b.version_requirements_ptr()->begin(),
+ b.version_requirements_ptr()->end()), 1);
+ TEST_CHECK_STRINGIFY_EQUAL(b.version_requirements_ptr()->begin()->version_spec, "1.2.3");
+ TEST_CHECK_EQUAL(b.version_requirements_ptr()->begin()->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_requirements_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_requirements_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(d.version_requirements_ptr()->begin()->version_spec, "1.2");
+ TEST_CHECK_EQUAL(d.version_requirements_ptr()->begin()->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_requirements_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_requirements_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_requirements_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(h.version_requirements_ptr()->begin()->version_spec, "1.23");
+ TEST_CHECK_EQUAL(h.version_requirements_ptr()->begin()->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_requirements_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_requirements_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(j.version_requirements_ptr()->begin()->version_spec, "scm-r3");
+ TEST_CHECK_EQUAL(j.version_requirements_ptr()->begin()->version_operator, vo_equal);
+
+ PackageDepAtom k("=foo/bar-scm");
+ TEST_CHECK_STRINGIFY_EQUAL(k.package(), "foo/bar");
+ TEST_CHECK(k.version_requirements_ptr());
+ TEST_CHECK_STRINGIFY_EQUAL(k.version_requirements_ptr()->begin()->version_spec, "scm");
+ TEST_CHECK_EQUAL(k.version_requirements_ptr()->begin()->version_operator, vo_equal);
+ }
+ } test_package_dep_atom;
+}
+
diff --git a/0.18.0/paludis/dep_atom_flattener.cc b/0.18.0/paludis/dep_atom_flattener.cc
new file mode 100644
index 000000000..6cd0218ba
--- /dev/null
+++ b/0.18.0/paludis/dep_atom_flattener.cc
@@ -0,0 +1,127 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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>
+ {
+ const Environment * const env;
+
+ const PackageDatabaseEntry * const pkg;
+
+ std::tr1::shared_ptr<const DepAtom> a;
+
+ mutable std::list<const StringDepAtom *> atoms;
+
+ mutable bool done;
+
+ Implementation(const Environment * const e,
+ const PackageDatabaseEntry * const p,
+ std::tr1::shared_ptr<const DepAtom> aa) :
+ env(e),
+ pkg(p),
+ a(aa),
+ done(false)
+ {
+ }
+ };
+}
+
+DepAtomFlattener::DepAtomFlattener(
+ const Environment * const env,
+ const PackageDatabaseEntry * const pkg,
+ std::tr1::shared_ptr<const DepAtom> 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.18.0/paludis/dep_atom_flattener.hh b/0.18.0/paludis/dep_atom_flattener.hh
new file mode 100644
index 000000000..32d076931
--- /dev/null
+++ b/0.18.0/paludis/dep_atom_flattener.hh
@@ -0,0 +1,90 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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
+ * \nosubgrouping
+ */
+ 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 std::tr1::shared_ptr<const DepAtom>);
+
+ ~DepAtomFlattener();
+
+ ///\}
+
+ ///\name Iterate over our dep atoms
+ ///{
+
+ typedef libwrapiter::ForwardIterator<DepAtomFlattener, const StringDepAtom *> Iterator;
+
+ Iterator begin();
+
+ Iterator end() const;
+
+ ///\}
+ };
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_atom_pretty_printer.cc b/0.18.0/paludis/dep_atom_pretty_printer.cc
new file mode 100644
index 000000000..bda808f2c
--- /dev/null
+++ b/0.18.0/paludis/dep_atom_pretty_printer.cc
@@ -0,0 +1,103 @@
+/* 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 << indent() << "(" << newline();
+ {
+ Save<unsigned> old_indent(&_indent, _indent + 4);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ _s << indent() << ")" << newline();
+}
+
+void
+DepAtomPrettyPrinter::visit(const AnyDepAtom * const a)
+{
+ _s << indent() << "|| (" << newline();
+ {
+ Save<unsigned> old_indent(&_indent, _indent + 4);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ _s << indent() << ")" << newline();
+}
+
+void
+DepAtomPrettyPrinter::visit(const UseDepAtom * const a)
+{
+ _s << indent() << (a->inverse() ? "!" : "") <<
+ a->flag() << "? (" << newline();
+ {
+ Save<unsigned> old_indent(&_indent, _indent + 4);
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ _s << indent() << ")" << newline();
+}
+
+void
+DepAtomPrettyPrinter::visit(const PackageDepAtom * const p)
+{
+ _s << indent() << *p << newline();
+}
+
+void
+DepAtomPrettyPrinter::visit(const PlainTextDepAtom * const p)
+{
+ _s << indent() << p->text() << newline();
+}
+
+void
+DepAtomPrettyPrinter::visit(const BlockDepAtom * const b)
+{
+ _s << indent() << "!" << *b->blocked_atom() << newline();
+}
+
+std::string
+DepAtomPrettyPrinter::newline() const
+{
+ return _use_newlines ? "\n" : " ";
+}
+
+std::string
+DepAtomPrettyPrinter::indent() const
+{
+ return _use_newlines ? std::string(_indent, ' ') : "";
+}
+
diff --git a/0.18.0/paludis/dep_atom_pretty_printer.hh b/0.18.0/paludis/dep_atom_pretty_printer.hh
new file mode 100644
index 000000000..f612e0710
--- /dev/null
+++ b/0.18.0/paludis/dep_atom_pretty_printer.hh
@@ -0,0 +1,87 @@
+/* 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;
+ bool _use_newlines;
+
+ std::string newline() const;
+ std::string indent() const;
+
+ public:
+ /**
+ * Constructor.
+ */
+ DepAtomPrettyPrinter(unsigned initial_indent,
+ bool use_newlines = true) :
+ _indent(initial_indent),
+ _use_newlines(use_newlines)
+ {
+ }
+
+ /// \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.18.0/paludis/dep_list/Makefile.am b/0.18.0/paludis/dep_list/Makefile.am
new file mode 100644
index 000000000..c20a8e2b1
--- /dev/null
+++ b/0.18.0/paludis/dep_list/Makefile.am
@@ -0,0 +1,140 @@
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+DISTCLEANFILES = \
+ dep_list-sr.hh dep_list-sr.cc \
+ uninstall_list-sr.hh uninstall_list-sr.cc \
+ options-se.hh options-se.cc
+BUILT_SOURCES = $(DISTCLEANFILES)
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CXXFLAGS = -I$(top_srcdir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+paludis_dep_list_includedir = $(includedir)/paludis/dep_list
+paludis_dep_list_include_HEADERS = \
+ dep_list.hh \
+ uninstall_list.hh \
+ exceptions.hh \
+ options.hh \
+ dep_list-sr.hh \
+ uninstall_list-sr.hh \
+ range_rewriter.hh \
+ options-se.hh
+
+libpaludisdeplist_la_SOURCES = \
+ options.cc options.hh \
+ exceptions.cc exceptions.hh \
+ dep_list.cc dep_list.hh \
+ uninstall_list.cc uninstall_list.hh \
+ range_rewriter.cc range_rewriter.hh
+
+libpaludisdeplist_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+
+if ! MONOLITHIC
+
+libpaludisdeplist_la_LIBADD = \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/libpaludis.la
+
+endif
+
+if MONOLITHIC
+
+noinst_LTLIBRARIES = libpaludisdeplist.la
+
+else
+
+lib_LTLIBRARIES = libpaludisdeplist.la
+
+endif
+
+EXTRA_DIST = \
+ dep_list_TEST.cc \
+ dep_list_TEST.hh \
+ dep_list_TEST_blockers.cc \
+ uninstall_list_TEST.cc \
+ range_rewriter_TEST.cc \
+ dep_list.sr dep_list-sr.hh dep_list-sr.cc \
+ uninstall_list.sr uninstall_list-sr.hh uninstall_list-sr.cc \
+ options.se options-se.hh options-se.cc
+
+TESTS = \
+ dep_list_TEST \
+ dep_list_TEST_blockers \
+ uninstall_list_TEST \
+ range_rewriter_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)
+
+dep_list_TEST_SOURCES = dep_list_TEST.cc
+dep_list_TEST_LDADD = \
+ $(top_builddir)/paludis/environment/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludisdeplist.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+dep_list_TEST_blockers_SOURCES = dep_list_TEST_blockers.cc
+dep_list_TEST_blockers_LDADD = \
+ $(top_builddir)/paludis/environment/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludisdeplist.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+uninstall_list_TEST_SOURCES = uninstall_list_TEST.cc
+uninstall_list_TEST_LDADD = \
+ $(top_builddir)/paludis/environment/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludisdeplist.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+range_rewriter_TEST_SOURCES = range_rewriter_TEST.cc
+range_rewriter_TEST_LDADD = \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludisdeplist.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
+dep_list-sr.hh : dep_list.sr $(top_srcdir)/misc/make_sr.bash
+ if ! $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/dep_list.sr > $@ ; then rm -f $@ ; exit 1 ; fi
+
+dep_list-sr.cc : dep_list.sr $(top_srcdir)/misc/make_sr.bash
+ if ! $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/dep_list.sr > $@ ; then rm -f $@ ; exit 1 ; fi
+
+uninstall_list-sr.hh : uninstall_list.sr $(top_srcdir)/misc/make_sr.bash
+ if ! $(top_srcdir)/misc/make_sr.bash --header $(srcdir)/uninstall_list.sr > $@ ; then rm -f $@ ; exit 1 ; fi
+
+uninstall_list-sr.cc : uninstall_list.sr $(top_srcdir)/misc/make_sr.bash
+ if ! $(top_srcdir)/misc/make_sr.bash --source $(srcdir)/uninstall_list.sr > $@ ; then rm -f $@ ; exit 1 ; fi
+
+options-se.hh : options.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --header $(srcdir)/options.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
+options-se.cc : options.se $(top_srcdir)/misc/make_se.bash
+ if ! $(top_srcdir)/misc/make_se.bash --source $(srcdir)/options.se > $@ ; then rm -f $@ ; exit 1 ; fi
+
diff --git a/0.18.0/paludis/dep_list/dep_list.cc b/0.18.0/paludis/dep_list/dep_list.cc
new file mode 100644
index 000000000..45454feea
--- /dev/null
+++ b/0.18.0/paludis/dep_list/dep_list.cc
@@ -0,0 +1,1589 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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_atom_pretty_printer.hh>
+#include <paludis/dep_list/dep_list.hh>
+#include <paludis/dep_list/exceptions.hh>
+#include <paludis/dep_list/range_rewriter.hh>
+#include <paludis/match_package.hh>
+#include <paludis/hashed_containers.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/dep_list-sr.cc>
+
+DepListOptions::DepListOptions() :
+ reinstall(dl_reinstall_never),
+ reinstall_scm(dl_reinstall_scm_never),
+ target_type(dl_target_package),
+ upgrade(dl_upgrade_always),
+ downgrade(dl_downgrade_as_needed),
+ new_slots(dl_new_slots_always),
+ fall_back(dl_fall_back_as_needed_except_targets),
+ 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),
+ uninstalled_deps_suggested(dl_deps_try_post),
+ suggested(dl_suggested_show),
+ circular(dl_circular_error),
+ use(dl_use_deps_standard),
+ blocks(dl_blocks_accumulate),
+ dependency_tags(false)
+{
+ /* when changing the above, also see src/paludis/command_line.cc. */
+}
+
+namespace paludis
+{
+ typedef std::list<DepListEntry> MergeList;
+ typedef MakeHashedMultiMap<QualifiedPackageName, MergeList::iterator>::Type MergeListIndex;
+
+ template<>
+ struct Implementation<DepList>
+ {
+ const Environment * const env;
+ std::tr1::shared_ptr<DepListOptions> opts;
+
+ MergeList merge_list;
+ MergeList::const_iterator current_merge_list_entry;
+ MergeList::iterator merge_list_insert_position;
+ long merge_list_generation;
+
+ MergeListIndex merge_list_index;
+
+ std::tr1::shared_ptr<const DepAtom> current_top_level_target;
+
+ bool throw_on_blocker;
+
+ 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(new DepListOptions(o)),
+ current_merge_list_entry(merge_list.end()),
+ merge_list_insert_position(merge_list.end()),
+ merge_list_generation(0),
+ throw_on_blocker(o.blocks == dl_blocks_error)
+ {
+ }
+ };
+}
+
+namespace
+{
+ class FakedVirtualVersionMetadata :
+ public VersionMetadata,
+ public VersionMetadataVirtualInterface
+ {
+ public:
+ FakedVirtualVersionMetadata(const SlotName & s, const PackageDatabaseEntry & e) :
+ VersionMetadata(
+ VersionMetadataBase(s, "", "", "paludis-1"),
+ VersionMetadataCapabilities::create()
+ .cran_interface(0)
+ .virtual_interface(this)
+ .ebuild_interface(0)
+ .deps_interface(0)
+ .origins_interface(0)
+ .license_interface(0)),
+ VersionMetadataVirtualInterface(e)
+ {
+ }
+ };
+
+ 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;
+ std::tr1::shared_ptr<DepListEntryTags> 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;
+ MergeListIndex & _index;
+ long & _generation;
+ int _initial_generation;
+ bool _committed;
+
+ public:
+ DepListTransaction(MergeList & l, MergeListIndex & i, long & g) :
+ _list(l),
+ _index(i),
+ _generation(g),
+ _initial_generation(g),
+ _committed(false)
+ {
+ ++_generation;
+ }
+
+ void commit()
+ {
+ _committed = true;
+ }
+
+ ~DepListTransaction()
+ {
+ if (_committed)
+ return;
+
+ /* See EffSTL 9 */
+ GenerationGreaterThan pred(_initial_generation);
+ for (MergeList::iterator i(_list.begin()) ; i != _list.end() ; )
+ {
+ if (! pred(*i))
+ ++i;
+ else
+ {
+ for (std::pair<MergeListIndex::iterator, MergeListIndex::iterator> p(
+ _index.equal_range(i->package.name)) ; p.first != p.second ; )
+ if (p.first->second == i)
+ _index.erase(p.first++);
+ else
+ ++p.first;
+
+ _list.erase(i++);
+ }
+ }
+
+ 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 std::pair<const QualifiedPackageName, MergeList::const_iterator> & e)
+ {
+ switch (e.second->kind)
+ {
+ case dlk_virtual:
+ case dlk_package:
+ case dlk_provided:
+ case dlk_already_installed:
+ case dlk_subpackage:
+ return match_package(*env, *a, e.second->package);
+
+ case dlk_block:
+ case dlk_masked:
+ case dlk_suggested:
+ return false;
+
+ case last_dlk:
+ ;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad e.second->kind");
+ }
+ };
+
+ 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() (std::tr1::shared_ptr<const DepAtom> 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 IsInterestingPDADepAtomChild
+ {
+ const Environment * const env;
+
+ IsInterestingPDADepAtomChild(const Environment * const e) :
+ env(e)
+ {
+ }
+
+ bool operator() (std::tr1::shared_ptr<const DepAtom> atom)
+ {
+ const PackageDepAtom * const u(atom->as_package_dep_atom());
+ if (0 != u)
+ {
+ return ! env->package_database()->query(PackageDepAtom(u->package()),
+ is_installed_only, qo_whatever)->empty();
+ }
+ else
+ return false;
+ }
+ };
+}
+
+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 if we'll be installed by the time we reach the current point. This
+ * means that merely being installed is not enough, if we'll have our version changed
+ * by something in the merge list. */
+
+ result = false;
+
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> matches(d->_imp->env->package_database()->query(
+ *a, is_installed_only, qo_whatever));
+
+ for (PackageDatabaseEntryCollection::Iterator m(matches->begin()), m_end(matches->end()) ;
+ m != m_end ; ++m)
+ {
+ /* check that we haven't been replaced by something in the same slot */
+ std::tr1::shared_ptr<const VersionMetadata> vm(d->_imp->env->package_database()->fetch_repository(m->repository)->
+ version_metadata(m->name, m->version));
+ SlotName slot(vm->slot);
+
+ std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p(
+ d->_imp->merge_list_index.equal_range(a->package()));
+
+ bool replaced(false);
+ PackageDepAtom atom(a->package());
+ while (p.second != ((p.first = std::find_if(p.first, p.second,
+ MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, &atom)))))
+ {
+ if (p.first->second->metadata->slot != slot)
+ p.first = next(p.first);
+ else
+ {
+ replaced = true;
+ break;
+ }
+ }
+
+ if (! replaced)
+ {
+ result = true;
+ return;
+ }
+ }
+
+ /* check the merge list for any new packages that match */
+ std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p(
+ d->_imp->merge_list_index.equal_range(a->package()));
+
+ if (p.second != std::find_if(p.first, p.second,
+ MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, a)))
+ {
+ result = true;
+ return;
+ }
+}
+
+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<std::tr1::shared_ptr<const DepAtom> > viable_children;
+ std::copy(a->begin(), a->end(), filter_inserter(std::back_inserter(viable_children),
+ IsViableAnyDepAtomChild(d->_imp->env, d->_imp->current_pde())));
+
+ RangeRewriter r;
+ std::for_each(viable_children.begin(), viable_children.end(), accept_visitor(&r));
+ if (r.atom())
+ {
+ viable_children.clear();
+ viable_children.push_back(r.atom());
+ }
+
+ result = true;
+ for (std::list<std::tr1::shared_ptr<const DepAtom> >::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,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<AddVisitor, AllDepAtom>
+{
+ 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);
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<AddVisitor, AllDepAtom>::visit;
+};
+
+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 */
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> already_installed(d->_imp->env->package_database()->query(
+ *a, is_installed_only, qo_order_by_version));
+
+ /* are we already on the merge list? */
+ std::pair<MergeListIndex::iterator, MergeListIndex::iterator> q(
+ d->_imp->merge_list_index.equal_range(a->package()));
+ MergeListIndex::iterator qq(std::find_if(q.first, q.second,
+ MatchDepListEntryAgainstPackageDepAtom(d->_imp->env, a)));
+
+ MergeList::iterator existing_merge_list_entry(qq == q.second ? d->_imp->merge_list.end() : qq->second);
+ 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(std::tr1::shared_ptr<DepTag>(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_qa, lc_context, "Dropping circular dependency on '"
+ + stringify(existing_merge_list_entry->package) + "'");
+ return;
+ }
+ else if (d->_imp->opts->circular == dl_circular_discard_silently)
+ 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);
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> installable_candidates(
+ d->_imp->env->package_database()->query(*a, is_installable_only, qo_order_by_version));
+
+ 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;
+ }
+
+ /* are we allowed to override mask reasons? */
+ if (! best_visible_candidate && d->_imp->opts->override_masks.any())
+ {
+ DepListOverrideMask next(static_cast<DepListOverrideMask>(0));
+ DepListOverrideMasks masks_to_override;
+
+ do
+ {
+ while (next != last_dl_override)
+ {
+ if (masks_to_override.test(next))
+ next = static_cast<DepListOverrideMask>(static_cast<int>(next) + 1);
+ else if (d->_imp->opts->override_masks.test(next))
+ {
+ masks_to_override.set(next);
+ break;
+ }
+ else
+ next = static_cast<DepListOverrideMask>(static_cast<int>(next) + 1);
+ }
+
+ if (next == last_dl_override)
+ break;
+
+ MaskReasons mask_mask;
+ if (masks_to_override.test(dl_override_repository_masks))
+ mask_mask.set(mr_repository_mask);
+ if (masks_to_override.test(dl_override_profile_masks))
+ mask_mask.set(mr_profile_mask);
+ if (masks_to_override.test(dl_override_licenses))
+ mask_mask.set(mr_license);
+ mask_mask.set(mr_by_association);
+ mask_mask.flip();
+
+ bool override_tilde_keywords(masks_to_override.test(dl_override_tilde_keywords));
+ bool override_unkeyworded(masks_to_override.test(dl_override_unkeyworded));
+
+ for (PackageDatabaseEntryCollection::ReverseIterator p(installable_candidates->rbegin()),
+ p_end(installable_candidates->rend()) ; p != p_end ; ++p)
+ {
+ if (! (d->_imp->env->mask_reasons(*p, override_tilde_keywords, override_unkeyworded)
+ & mask_mask).any())
+ {
+ d->add_error_package(*p, dlk_masked);
+ best_visible_candidate = &*p;
+ break;
+ }
+ }
+ } while (! best_visible_candidate);
+ }
+
+ /* no installable candidates. if we're already installed, that's ok (except for top level
+ * package targets), otherwise error. */
+ if (! best_visible_candidate)
+ {
+ bool can_fall_back;
+ do
+ {
+ switch (d->_imp->opts->fall_back)
+ {
+ case dl_fall_back_never:
+ can_fall_back = false;
+ continue;
+
+ case dl_fall_back_as_needed_except_targets:
+ if (! d->_imp->current_pde())
+ can_fall_back = false;
+ else if (already_installed->empty())
+ can_fall_back = true;
+ else
+ can_fall_back = ! d->is_top_level_target(*already_installed->last());
+
+ continue;
+
+ case dl_fall_back_as_needed:
+ can_fall_back = true;
+ continue;
+
+ case last_dl_fall_back:
+ ;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad fall_back value '" + stringify(d->_imp->opts->fall_back) + "'");
+ } while (false);
+
+ if (already_installed->empty() || ! can_fall_back)
+ {
+ if (! a->use_requirements_ptr())
+ throw AllMaskedError(stringify(*a));
+
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> match_except_reqs(d->_imp->env->package_database()->query(
+ *a->without_use_requirements(), is_any, qo_whatever));
+
+ for (PackageDatabaseEntryCollection::Iterator i(match_except_reqs->begin()),
+ i_end(match_except_reqs->end()) ; i != i_end ; ++i)
+ if (! (d->_imp->env->mask_reasons(*i).any()))
+ throw UseRequirementsNotMetError(stringify(*a));
+
+ throw AllMaskedError(stringify(*a));
+ }
+ else
+ {
+ 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;
+ }
+ }
+
+ std::tr1::shared_ptr<const VersionMetadata> best_visible_candidate_metadata(
+ d->_imp->env->package_database()->fetch_repository(best_visible_candidate->repository)->
+ version_metadata(best_visible_candidate->name, best_visible_candidate->version));
+ SlotName slot(best_visible_candidate_metadata->slot);
+ std::string best_visible_candidate_as_string(stringify(*best_visible_candidate));
+ if (best_visible_candidate_metadata->virtual_interface)
+ best_visible_candidate_as_string.append(" (for " + stringify(
+ best_visible_candidate_metadata->virtual_interface->virtual_for) + ")");
+
+ std::tr1::shared_ptr<PackageDatabaseEntryCollection> 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->push_back(*aa);
+ /* no need to sort already_installed_in_same_slot here, although if the above is
+ * changed then check that this still holds... */
+
+ /* 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 '" +
+ best_visible_candidate_as_string + "'");
+ 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 '" +
+ best_visible_candidate_as_string + "'");
+ }
+ else if ((! already_installed->empty()) && (dl_new_slots_as_needed == d->_imp->opts->new_slots))
+ {
+ /* we have an already installed, but not in the same slot, and our options
+ * allow us to take this. */
+ if (d->prefer_installed_over_uninstalled(*already_installed->last(), *best_visible_candidate))
+ {
+ Log::get_instance()->message(ll_debug, lc_context, "Taking installed package '"
+ + stringify(*already_installed->last()) + "' over '" + best_visible_candidate_as_string
+ + "' (in different slot)");
+ d->add_already_installed_package(*already_installed->last(), a->tag());
+ return;
+ }
+ else
+ Log::get_instance()->message(ll_debug, lc_context, "Not taking installed package '"
+ + stringify(*already_installed->last()) + "' over '" +
+ best_visible_candidate_as_string + "' (in different slot)");
+ }
+ else
+ Log::get_instance()->message(ll_debug, lc_context, "No installed packages in SLOT '"
+ + stringify(slot) + "', taking uninstalled package '" + best_visible_candidate_as_string + "'");
+
+ /* if this is a downgrade, make sure that that's ok */
+ switch (d->_imp->opts->downgrade)
+ {
+ case dl_downgrade_as_needed:
+ break;
+
+ case dl_downgrade_error:
+ case dl_downgrade_warning:
+ {
+ std::tr1::shared_ptr<PackageDatabaseEntryCollection> are_we_downgrading(
+ d->_imp->env->package_database()->query(PackageDepAtom(
+ stringify(a->package()) + ":" + stringify(slot)),
+ is_installed_only, qo_order_by_version));
+
+ if (are_we_downgrading->empty())
+ break;
+
+ if (are_we_downgrading->last()->version <= best_visible_candidate->version)
+ break;
+
+ std::tr1::shared_ptr<const VersionMetadata> are_we_downgrading_last_metadata(
+ d->_imp->env->package_database()->fetch_repository(
+ are_we_downgrading->last()->repository)->version_metadata(
+ are_we_downgrading->last()->name, are_we_downgrading->last()->version));
+ std::string are_we_downgrading_last_as_string(stringify(*are_we_downgrading->last()));
+ if (are_we_downgrading_last_metadata->virtual_interface)
+ are_we_downgrading_last_as_string.append(" (for " + stringify(
+ are_we_downgrading_last_metadata->virtual_interface->virtual_for) + ")");
+
+ if (d->_imp->opts->downgrade == dl_downgrade_error)
+ throw DowngradeNotAllowedError(best_visible_candidate_as_string,
+ are_we_downgrading_last_as_string);
+
+ Log::get_instance()->message(ll_warning, lc_context, "Downgrade to '" +
+ best_visible_candidate_as_string
+ + "' from '" + are_we_downgrading_last_as_string + "' forced");
+ }
+ break;
+
+ case last_dl_downgrade:
+ ;
+ }
+
+ d->add_package(*best_visible_candidate, a->tag());
+}
+
+void
+DepList::AddVisitor::visit(const UseDepAtom * const a)
+{
+ if (d->_imp->opts->use == dl_use_deps_standard)
+ {
+ if (d->_imp->env->query_use(a->flag(), d->_imp->current_pde()) ^ a->inverse())
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ else
+ {
+ RepositoryUseInterface * u(0);
+ if ((! d->_imp->current_pde()) || (! ((u = d->_imp->env->package_database()->fetch_repository(
+ d->_imp->current_pde()->repository)->use_interface))))
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ else if (a->inverse())
+ {
+ if (! u->query_use_force(a->flag(), d->_imp->current_pde()))
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+ else
+ {
+ if (! u->query_use_mask(a->flag(), d->_imp->current_pde()))
+ 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<std::tr1::shared_ptr<const DepAtom> > 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;
+
+ RangeRewriter r;
+ std::for_each(viable_children.begin(), viable_children.end(), accept_visitor(&r));
+ if (r.atom())
+ {
+ viable_children.clear();
+ viable_children.push_back(r.atom());
+ }
+
+ /* see if any of our children is already installed. if any is, add it so that
+ * any upgrades kick in */
+ for (std::list<std::tr1::shared_ptr<const DepAtom> >::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
+ {
+ if (d->already_installed(**c))
+ {
+ d->add(*c);
+ return;
+ }
+ }
+
+ /* if we have something like || ( a >=b-2 ) and b-1 is installed, try to go for
+ * the b-2 bit first */
+ std::list<std::tr1::shared_ptr<const DepAtom> > pda_children;
+ std::copy(viable_children.begin(), viable_children.end(),
+ filter_inserter(std::back_inserter(pda_children), IsInterestingPDADepAtomChild(d->_imp->env)));
+
+ for (std::list<std::tr1::shared_ptr<const DepAtom> >::const_iterator c(pda_children.begin()),
+ c_end(pda_children.end()) ; c != c_end ; ++c)
+ {
+ try
+ {
+ Save<bool> save_t(&d->_imp->throw_on_blocker,
+ dl_blocks_discard_completely != d->_imp->opts->blocks);
+ Save<DepListOverrideMasks> save_o(&d->_imp->opts->override_masks, DepListOverrideMasks());
+ d->add(*c);
+ return;
+ }
+ catch (const DepListError &)
+ {
+ }
+ }
+
+ /* install first available viable option */
+ for (std::list<std::tr1::shared_ptr<const DepAtom> >::const_iterator c(viable_children.begin()),
+ c_end(viable_children.end()) ; c != c_end ; ++c)
+ {
+ try
+ {
+ Save<bool> save_t(&d->_imp->throw_on_blocker,
+ dl_blocks_discard_completely != d->_imp->opts->blocks);
+ Save<DepListOverrideMasks> save_o(&d->_imp->opts->override_masks, DepListOverrideMasks());
+ d->add(*c);
+ return;
+ }
+ catch (const DepListError &)
+ {
+ }
+ }
+
+ Log::get_instance()->message(ll_debug, lc_context, "No resolvable item in || ( ) block. Using "
+ "first item for error message");
+ {
+ Context block_context("Inside || ( ) block with other options:");
+ d->add(*viable_children.begin());
+ }
+}
+
+void
+DepList::AddVisitor::visit(const BlockDepAtom * const a)
+{
+ if (dl_blocks_discard_completely == d->_imp->opts->blocks)
+ return;
+
+ Context context("When checking BlockDepAtom '!" + stringify(*a->blocked_atom()) + "':");
+
+ PackageDepAtom just_package(a->blocked_atom()->package());
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> already_installed(d->_imp->env->package_database()->query(
+ just_package, is_installed_only, qo_whatever));
+
+ std::list<MergeList::const_iterator> will_be_installed;
+ MatchDepListEntryAgainstPackageDepAtom m(d->_imp->env, &just_package);
+ for (std::pair<MergeListIndex::const_iterator, MergeListIndex::const_iterator> p(
+ d->_imp->merge_list_index.equal_range(a->blocked_atom()->package())) ;
+ p.first != p.second ; ++p.first)
+ {
+ if (d->_imp->current_merge_list_entry != d->_imp->merge_list.end())
+ {
+ if (d->_imp->current_merge_list_entry == p.first->second)
+ continue;
+
+ if (d->_imp->current_merge_list_entry->associated_entry == &*p.first->second)
+ continue;
+ }
+
+ if (m(*p.first))
+ will_be_installed.push_back(p.first->second);
+ }
+
+ if (already_installed->empty() && will_be_installed.empty())
+ return;
+
+ for (PackageDatabaseEntryCollection::Iterator aa(already_installed->begin()),
+ aa_end(already_installed->end()) ; aa != aa_end ; ++aa)
+ {
+ if (! match_package(*d->_imp->env, *a->blocked_atom(), *aa))
+ continue;
+
+ std::tr1::shared_ptr<const VersionMetadata> metadata(d->_imp->env->package_database()->fetch_repository(
+ aa->repository)->version_metadata(aa->name, aa->version));
+ bool replaced(false);
+ for (std::list<MergeList::const_iterator>::const_iterator r(will_be_installed.begin()),
+ r_end(will_be_installed.end()) ; r != r_end && ! replaced ; ++r)
+ if ((*r)->metadata->slot == metadata->slot)
+ {
+ /* if it's a virtual, it only replaces if it's the same package. */
+ if ((*r)->metadata->virtual_interface)
+ {
+ if ((*r)->metadata->virtual_interface->virtual_for.name == aa->name)
+ replaced = true;
+ }
+ else
+ replaced = true;
+ }
+
+ if (replaced)
+ continue;
+
+ /* ignore if it's a virtual/blah (not <virtual/blah-1) block and it's blocking
+ * ourself */
+ if (! (a->blocked_atom()->version_requirements_ptr() || a->blocked_atom()->slot_ptr()
+ || a->blocked_atom()->use_requirements_ptr() || a->blocked_atom()->repository_ptr())
+ && d->_imp->current_pde())
+ {
+ if (aa->name == d->_imp->current_pde()->name)
+ continue;
+
+ if (metadata->virtual_interface &&
+ metadata->virtual_interface->virtual_for.name == d->_imp->current_pde()->name)
+ continue;
+ }
+
+ switch (d->_imp->throw_on_blocker ? dl_blocks_error : d->_imp->opts->blocks)
+ {
+ case dl_blocks_error:
+ throw BlockError(stringify(*a->blocked_atom()));
+
+ case dl_blocks_discard:
+ Log::get_instance()->message(ll_warning, lc_context, "Discarding block '!"
+ + stringify(*a->blocked_atom()) + "'");
+ break;
+
+ case dl_blocks_discard_completely:
+ break;
+
+ case dl_blocks_accumulate:
+ d->add_error_package(*aa, dlk_block);
+ break;
+
+ case last_dl_blocks:
+ break;
+ }
+ }
+
+ for (std::list<MergeList::const_iterator>::const_iterator r(will_be_installed.begin()),
+ r_end(will_be_installed.end()) ; r != r_end ; ++r)
+ {
+ if (! match_package(*d->_imp->env, *a->blocked_atom(), (*r)->package))
+ continue;
+
+ /* ignore if it's a virtual/blah (not <virtual/blah-1) block and it's blocking
+ * ourself */
+ if (! (a->blocked_atom()->version_requirements_ptr() || a->blocked_atom()->slot_ptr()
+ || a->blocked_atom()->use_requirements_ptr() || a->blocked_atom()->repository_ptr())
+ && d->_imp->current_pde())
+ {
+ if ((*r)->package.name == d->_imp->current_pde()->name)
+ continue;
+
+ if ((*r)->metadata->virtual_interface &&
+ (*r)->metadata->virtual_interface->virtual_for.name == d->_imp->current_pde()->name)
+ continue;
+ }
+
+ throw BlockError(stringify(*a->blocked_atom()));
+ }
+}
+
+struct DepList::ShowSuggestVisitor :
+ DepAtomVisitorTypes::ConstVisitor,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AllDepAtom>,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AnyDepAtom>
+{
+ DepList * const d;
+
+ ShowSuggestVisitor(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 BlockDepAtom * const);
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AllDepAtom>::visit;
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AnyDepAtom>::visit;
+};
+
+void
+DepList::ShowSuggestVisitor::visit(const PlainTextDepAtom * const)
+{
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
+}
+
+void
+DepList::ShowSuggestVisitor::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::ShowSuggestVisitor::visit(const BlockDepAtom * const)
+{
+}
+
+void
+DepList::ShowSuggestVisitor::visit(const PackageDepAtom * const a)
+{
+ Context context("When adding suggested dep '" + stringify(*a) + "':");
+
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> matches(d->_imp->env->package_database()->query(
+ *a, is_installable_only, qo_order_by_version));
+ if (matches->empty())
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Nothing found for '" + stringify(*a) + "'");
+ return;
+ }
+
+ for (PackageDatabaseEntryCollection::Iterator m(matches->begin()), m_end(matches->end()) ;
+ m != m_end ; ++m)
+ {
+ if (d->_imp->env->mask_reasons(*m).any())
+ continue;
+
+ d->add_suggested_package(*m);
+ return;
+ }
+
+ Log::get_instance()->message(ll_warning, lc_context, "Nothing visible found for '" + stringify(*a) + "'");
+}
+
+DepList::DepList(const Environment * const e, const DepListOptions & o) :
+ PrivateImplementationPattern<DepList>(new Implementation<DepList>(e, o))
+{
+}
+
+DepList::~DepList()
+{
+}
+
+std::tr1::shared_ptr<DepListOptions>
+DepList::options()
+{
+ return _imp->opts;
+}
+
+void
+DepList::clear()
+{
+ DepListOptions o(*options());
+ _imp.reset(new Implementation<DepList>(_imp->env, o));
+}
+
+void
+DepList::add_in_role(std::tr1::shared_ptr<const DepAtom> atom, const std::string & role)
+{
+ Context context("When adding " + role + ":");
+ add(atom);
+}
+
+void
+DepList::add(std::tr1::shared_ptr<const DepAtom> atom)
+{
+ DepListTransaction transaction(_imp->merge_list, _imp->merge_list_index, _imp->merge_list_generation);
+
+ Save<std::tr1::shared_ptr<const DepAtom> > save_current_top_level_target(&_imp->current_top_level_target,
+ _imp->current_top_level_target ? _imp->current_top_level_target : atom);
+
+ AddVisitor visitor(this);
+ atom->accept(&visitor);
+ transaction.commit();
+}
+
+void
+DepList::add_package(const PackageDatabaseEntry & p, std::tr1::shared_ptr<const DepTag> tag)
+{
+ Context context("When adding package '" + stringify(p) + "':");
+
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position);
+
+ std::tr1::shared_ptr<const VersionMetadata> 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(std::tr1::shared_ptr<DepListEntryTags>(new DepListEntryTags::Concrete))
+ .destinations(std::tr1::shared_ptr<RepositoryNameCollection>(new RepositoryNameCollection::Concrete))
+ .associated_entry(0)
+ .kind(metadata->virtual_interface ? dlk_virtual : dlk_package))),
+ our_merge_entry_post_position(our_merge_entry_position);
+
+ _imp->merge_list_index.insert(std::make_pair(p.name, 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(std::tr1::shared_ptr<DepTag>(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->ebuild_interface)
+ {
+ DepAtomFlattener f(_imp->env, _imp->current_pde(), metadata->ebuild_interface->provide());
+ for (DepAtomFlattener::Iterator i(f.begin()), i_end(f.end()) ; i != i_end ; ++i)
+ {
+ std::tr1::shared_ptr<PackageDepAtom> pp(new PackageDepAtom("=" + (*i)->text() + "-" + stringify(p.version)));
+
+ std::pair<MergeListIndex::iterator, MergeListIndex::iterator> z(
+ _imp->merge_list_index.equal_range(pp->package()));
+ MergeListIndex::iterator zz(std::find_if(z.first, z.second,
+ MatchDepListEntryAgainstPackageDepAtom(_imp->env, pp.get())));
+
+ if (z.first != z.second)
+ continue;
+
+ std::tr1::shared_ptr<const VersionMetadata> m;
+
+ 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
+ {
+ std::tr1::shared_ptr<VersionMetadata> mm(new FakedVirtualVersionMetadata(metadata->slot,
+ PackageDatabaseEntry(p.name, p.version, RepositoryName("virtuals"))));
+ 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(std::tr1::shared_ptr<DepListEntryTags>(new DepListEntryTags::Concrete))
+ .destinations(std::tr1::shared_ptr<RepositoryNameCollection>(new RepositoryNameCollection::Concrete))
+ .associated_entry(&*_imp->current_merge_list_entry)
+ .kind(dlk_provided)));
+ _imp->merge_list_index.insert(std::make_pair((*i)->text(), our_merge_entry_post_position));
+ }
+ }
+
+ if (metadata->deps_interface)
+ {
+ /* add suggests */
+ if (_imp->opts->suggested == dl_suggested_show)
+ {
+ Context c("When showing suggestions:");
+ Save<MergeList::iterator> suggest_save_merge_list_insert_position(&_imp->merge_list_insert_position,
+ next(our_merge_entry_position));
+ ShowSuggestVisitor visitor(this);
+ metadata->deps_interface->suggested_depend()->accept(&visitor);
+ }
+
+ /* add pre dependencies */
+ add_predeps(metadata->deps_interface->build_depend(), _imp->opts->uninstalled_deps_pre, "build");
+ add_predeps(metadata->deps_interface->run_depend(), _imp->opts->uninstalled_deps_runtime, "run");
+ add_predeps(metadata->deps_interface->post_depend(), _imp->opts->uninstalled_deps_post, "post");
+ if (_imp->opts->suggested == dl_suggested_install)
+ add_predeps(metadata->deps_interface->suggested_depend(), _imp->opts->uninstalled_deps_suggested, "suggest");
+ }
+
+ our_merge_entry_position->state = dle_has_pre_deps;
+ _imp->merge_list_insert_position = next(our_merge_entry_post_position);
+
+ if (metadata->deps_interface)
+ {
+ /* add post dependencies */
+ add_postdeps(metadata->deps_interface->build_depend(), _imp->opts->uninstalled_deps_pre, "build");
+ add_postdeps(metadata->deps_interface->run_depend(), _imp->opts->uninstalled_deps_runtime, "run");
+ add_postdeps(metadata->deps_interface->post_depend(), _imp->opts->uninstalled_deps_post, "post");
+
+ if (_imp->opts->suggested == dl_suggested_install)
+ add_postdeps(metadata->deps_interface->suggested_depend(), _imp->opts->uninstalled_deps_suggested, "suggest");
+ }
+
+ our_merge_entry_position->state = dle_has_all_deps;
+}
+
+void
+DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKind kind)
+{
+ std::pair<MergeListIndex::iterator, MergeListIndex::const_iterator> pp(
+ _imp->merge_list_index.equal_range(p.name));
+
+ for ( ; pp.second != pp.first ; ++pp.first)
+ {
+ if (pp.first->second->kind == kind && pp.first->second->package == p)
+ {
+ if (_imp->current_pde())
+ pp.first->second->tags->insert(DepTagEntry::create()
+ .tag(std::tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .generation(_imp->merge_list_generation));
+ return;
+ }
+ }
+
+ MergeList::iterator our_merge_entry_position(
+ _imp->merge_list.insert(_imp->merge_list.begin(),
+ DepListEntry::create()
+ .package(p)
+ .metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version))
+ .generation(_imp->merge_list_generation)
+ .state(dle_has_all_deps)
+ .tags(std::tr1::shared_ptr<DepListEntryTags>(new DepListEntryTags::Concrete))
+ .destinations(std::tr1::shared_ptr<RepositoryNameCollection>(new RepositoryNameCollection::Concrete))
+ .associated_entry(&*_imp->current_merge_list_entry)
+ .kind(kind)));
+
+ if (_imp->current_pde())
+ our_merge_entry_position->tags->insert(DepTagEntry::create()
+ .tag(std::tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .generation(_imp->merge_list_generation));
+
+ _imp->merge_list_index.insert(std::make_pair(p.name, our_merge_entry_position));
+}
+
+void
+DepList::add_suggested_package(const PackageDatabaseEntry & p)
+{
+ std::pair<MergeListIndex::iterator, MergeListIndex::const_iterator> pp(
+ _imp->merge_list_index.equal_range(p.name));
+
+ for ( ; pp.second != pp.first ; ++pp.first)
+ {
+ if ((pp.first->second->kind == dlk_suggested || pp.first->second->kind == dlk_already_installed
+ || pp.first->second->kind == dlk_package || pp.first->second->kind == dlk_provided
+ || pp.first->second->kind == dlk_subpackage) && pp.first->second->package == p)
+ return;
+ }
+
+ MergeList::iterator our_merge_entry_position(
+ _imp->merge_list.insert(_imp->merge_list_insert_position,
+ DepListEntry::create()
+ .package(p)
+ .metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version))
+ .generation(_imp->merge_list_generation)
+ .state(dle_has_all_deps)
+ .tags(std::tr1::shared_ptr<DepListEntryTags>(new DepListEntryTags::Concrete))
+ .destinations(std::tr1::shared_ptr<RepositoryNameCollection>(new RepositoryNameCollection::Concrete))
+ .associated_entry(&*_imp->current_merge_list_entry)
+ .kind(dlk_suggested)));
+
+ if (_imp->current_pde())
+ our_merge_entry_position->tags->insert(DepTagEntry::create()
+ .tag(std::tr1::shared_ptr<DepTag>(new DependencyDepTag(*_imp->current_pde())))
+ .generation(_imp->merge_list_generation));
+
+ _imp->merge_list_index.insert(std::make_pair(p.name, our_merge_entry_position));
+}
+
+void
+DepList::add_predeps(std::tr1::shared_ptr<const DepAtom> 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(std::tr1::shared_ptr<const DepAtom> 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
+ {
+ try
+ {
+ add_in_role(d, s + " dependencies as post dependencies");
+ }
+ catch (const CircularDependencyError &)
+ {
+ Save<DepListCircularOption> save_circular(&_imp->opts->circular,
+ _imp->opts->circular == dl_circular_discard_silently ?
+ dl_circular_discard_silently : dl_circular_discard);
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position,
+ _imp->merge_list.end());
+ add_in_role(d, s + " dependencies as post dependencies with cycle breaking");
+ }
+ }
+ 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, std::tr1::shared_ptr<const DepTag> tag)
+{
+ Context context("When adding installed package '" + stringify(p) + "':");
+
+ Save<MergeList::iterator> save_merge_list_insert_position(&_imp->merge_list_insert_position);
+ std::tr1::shared_ptr<const VersionMetadata> 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(std::tr1::shared_ptr<DepListEntryTags>(new DepListEntryTags::Concrete))
+ .state(dle_has_pre_deps)
+ .destinations(std::tr1::shared_ptr<RepositoryNameCollection>(new RepositoryNameCollection::Concrete))
+ .associated_entry(0)
+ .kind(dlk_already_installed)));
+ _imp->merge_list_index.insert(std::make_pair(p.name, our_merge_entry));
+
+ 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(std::tr1::shared_ptr<DepTag>(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);
+
+ if (metadata->deps_interface)
+ {
+ add_predeps(metadata->deps_interface->build_depend(), _imp->opts->installed_deps_pre, "build");
+ add_predeps(metadata->deps_interface->run_depend(), _imp->opts->installed_deps_runtime, "run");
+ add_predeps(metadata->deps_interface->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);
+
+ if (metadata->deps_interface)
+ {
+ add_postdeps(metadata->deps_interface->build_depend(), _imp->opts->installed_deps_pre, "build");
+ add_postdeps(metadata->deps_interface->run_depend(), _imp->opts->installed_deps_runtime, "run");
+ add_postdeps(metadata->deps_interface->post_depend(), _imp->opts->installed_deps_post, "post");
+ }
+}
+
+namespace
+{
+ bool is_scm(const QualifiedPackageName & n)
+ {
+ std::string pkg(stringify(n.package));
+ switch (pkg.length())
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return false;
+
+ default:
+ if (0 == pkg.compare(pkg.length() - 6, 6, "-darcs"))
+ return true;
+
+ case 5:
+ if (0 == pkg.compare(pkg.length() - 5, 5, "-live"))
+ return true;
+
+ case 4:
+ if (0 == pkg.compare(pkg.length() - 4, 4, "-cvs"))
+ return true;
+ if (0 == pkg.compare(pkg.length() - 4, 4, "-svn"))
+ return true;
+ return false;
+ }
+ }
+}
+
+bool
+DepList::prefer_installed_over_uninstalled(const PackageDatabaseEntry & installed,
+ const PackageDatabaseEntry & uninstalled)
+{
+ do
+ {
+ switch (_imp->opts->target_type)
+ {
+ case dl_target_package:
+ if (! _imp->current_pde())
+ return false;
+
+ if (is_top_level_target(uninstalled))
+ return false;
+
+ continue;
+
+ case dl_target_set:
+ continue;
+
+ case last_dl_target:
+ ;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad target_type value '" + stringify(_imp->opts->target_type) + "'");
+ } while (false);
+
+ if (dl_reinstall_always == _imp->opts->reinstall)
+ return false;
+
+ if (dl_upgrade_as_needed == _imp->opts->upgrade)
+ return true;
+
+ if (dl_reinstall_scm_never != _imp->opts->reinstall_scm)
+ if (uninstalled.version == installed.version &&
+ (installed.version.is_scm() || is_scm(installed.name)))
+ {
+ static time_t current_time(time(0)); /* static to avoid weirdness */
+ time_t installed_time(_imp->env->package_database()->fetch_repository(installed.repository
+ )->installed_interface->installed_time(installed.name, installed.version));
+ do
+ {
+ switch (_imp->opts->reinstall_scm)
+ {
+ case dl_reinstall_scm_always:
+ return false;
+
+ case dl_reinstall_scm_daily:
+ if (current_time - installed_time > (24 * 60 * 60))
+ return false;
+ continue;
+
+ case dl_reinstall_scm_weekly:
+ if (current_time - installed_time > (24 * 60 * 60 * 7))
+ return false;
+ continue;
+
+ case dl_reinstall_scm_never:
+ ; /* nothing */
+
+ case last_dl_reinstall_scm:
+ ;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad value for opts->reinstall_scm");
+ } while (false);
+ }
+
+ /* 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 VersionMetadataEbuildInterface * const evm_i(_imp->env->package_database()->fetch_repository(
+ installed.repository)->version_metadata(installed.name, installed.version)->ebuild_interface);
+ const VersionMetadataEbuildInterface * const evm_u(_imp->env->package_database()->fetch_repository(
+ uninstalled.repository)->version_metadata(uninstalled.name, uninstalled.version)->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(std::tr1::shared_ptr<const DepAtom> atom, const bool) const
+{
+ return already_installed(*atom.get());
+}
+
+bool
+DepList::already_installed(const DepAtom * const atom, const bool) const
+{
+ return already_installed(*atom);
+}
+
+bool
+DepList::already_installed(const DepAtom & 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());
+}
+
+bool
+DepList::is_top_level_target(const PackageDatabaseEntry & e) const
+{
+ if (! _imp->current_top_level_target)
+ throw InternalError(PALUDIS_HERE, "current_top_level_target not set?");
+
+ return match_package_in_heirarchy(*_imp->env, *_imp->current_top_level_target, e);
+}
+
+namespace
+{
+ struct IsError
+ {
+ bool operator() (const DepListEntry & e) const
+ {
+ switch (e.kind)
+ {
+ case dlk_virtual:
+ case dlk_package:
+ case dlk_provided:
+ case dlk_already_installed:
+ case dlk_subpackage:
+ case dlk_suggested:
+ return false;
+
+ case dlk_block:
+ case dlk_masked:
+ return true;
+
+ case last_dlk:
+ ;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad e.kind");
+ }
+ };
+}
+
+bool
+DepList::has_errors() const
+{
+ return end() != std::find_if(begin(), end(), IsError());
+}
+
diff --git a/0.18.0/paludis/dep_list/dep_list.hh b/0.18.0/paludis/dep_list/dep_list.hh
new file mode 100644
index 000000000..da140e025
--- /dev/null
+++ b/0.18.0/paludis/dep_list/dep_list.hh
@@ -0,0 +1,140 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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/dep_list/options.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
+{
+
+#include <paludis/dep_list/dep_list-sr.hh>
+
+ /**
+ * Holds a list of dependencies in merge order.
+ *
+ * \ingroup grpdepresolver
+ * \nosubgrouping
+ */
+ class DepList :
+ private InstantiationPolicy<DepList, instantiation_method::NonCopyableTag>,
+ private PrivateImplementationPattern<DepList>
+ {
+ protected:
+ class AddVisitor;
+ class QueryVisitor;
+ class ShowSuggestVisitor;
+
+ friend class AddVisitor;
+ friend class QueryVisitor;
+ friend class ShowSuggestVisitor;
+
+ void add_in_role(std::tr1::shared_ptr<const DepAtom>, const std::string & role);
+ bool prefer_installed_over_uninstalled(const PackageDatabaseEntry &,
+ const PackageDatabaseEntry &);
+
+ void add_package(const PackageDatabaseEntry &, std::tr1::shared_ptr<const DepTag>);
+ void add_already_installed_package(const PackageDatabaseEntry &, std::tr1::shared_ptr<const DepTag>);
+ void add_error_package(const PackageDatabaseEntry &, const DepListEntryKind);
+ void add_suggested_package(const PackageDatabaseEntry &);
+
+ void add_predeps(std::tr1::shared_ptr<const DepAtom>, const DepListDepsOption, const std::string &);
+ void add_postdeps(std::tr1::shared_ptr<const DepAtom>, const DepListDepsOption, const std::string &);
+
+ bool is_top_level_target(const PackageDatabaseEntry &) const;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ DepList(const Environment * const, const DepListOptions &);
+
+ virtual ~DepList();
+
+ ///\}
+
+ /**
+ * Our options.
+ */
+ std::tr1::shared_ptr<DepListOptions> options();
+
+ /**
+ * Add the packages required to resolve an additional dependency
+ * atom.
+ */
+ void add(std::tr1::shared_ptr<const DepAtom>);
+
+ /**
+ * Clear the list.
+ */
+ void clear();
+
+ /**
+ * Return whether an atom structure already installed.
+ *
+ * \deprecated Use the one arg form.
+ */
+ bool already_installed(std::tr1::shared_ptr<const DepAtom>, const bool dummy) const
+ PALUDIS_ATTRIBUTE((deprecated));
+
+ /**
+ * Return whether an atom structure already installed (overloaded for raw pointer).
+ *
+ * \deprecated Use the one arg form.
+ */
+ bool already_installed(const DepAtom * const, const bool dummy) const
+ PALUDIS_ATTRIBUTE((deprecated));
+
+ /**
+ * Return whether an atom structure already installed.
+ */
+ bool already_installed(const DepAtom &) const;
+
+ /**
+ * Whether we have any errors.
+ */
+ bool has_errors() 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.18.0/paludis/dep_list/dep_list.sr b/0.18.0/paludis/dep_list/dep_list.sr
new file mode 100644
index 000000000..1cf038150
--- /dev/null
+++ b/0.18.0/paludis/dep_list/dep_list.sr
@@ -0,0 +1,73 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_DepListOptions()
+{
+ key reinstall DepListReinstallOption
+ key reinstall_scm DepListReinstallScmOption
+ key target_type DepListTargetType
+ key upgrade DepListUpgradeOption
+ key downgrade DepListDowngradeOption
+ key new_slots DepListNewSlotsOption
+ key fall_back DepListFallBackOption
+
+ 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 uninstalled_deps_suggested DepListDepsOption
+
+ key suggested DepListSuggestedOption
+ key circular DepListCircularOption
+ key use DepListUseOption
+ key blocks DepListBlocksOption
+ key override_masks DepListOverrideMasks
+
+ key dependency_tags bool
+
+ extra_constructors <<END
+ DepListOptions();
+END
+
+ allow_named_args
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for a DepList.
+ *
+ * \see DepList
+ * \ingroup grpdepresolver
+ * \nosubgrouping
+ */
+END
+}
+
+make_class_DepListEntry()
+{
+ key kind DepListEntryKind
+
+ key package PackageDatabaseEntry
+ key associated_entry "const DepListEntry *"
+ key metadata "std::tr1::shared_ptr<const VersionMetadata>"
+ key tags "std::tr1::shared_ptr<DepListEntryTags>"
+ key destinations "std::tr1::shared_ptr<RepositoryNameCollection>"
+
+ key generation long
+ key state DepListEntryState
+
+ allow_named_args
+
+ doxygen_comment << "END"
+ /**
+ * An entry in a DepList.
+ *
+ * \see DepList
+ * \ingroup grpdepresolver
+ * \nosubgrouping
+ */
+END
+}
+
diff --git a/0.18.0/paludis/dep_list/dep_list_TEST.cc b/0.18.0/paludis/dep_list/dep_list_TEST.cc
new file mode 100644
index 000000000..9be6851e3
--- /dev/null
+++ b/0.18.0/paludis/dep_list/dep_list_TEST.cc
@@ -0,0 +1,1510 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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_list_TEST.hh"
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ /**
+ * Convenience sub base class used by the numbered DepList tests.
+ *
+ */
+ template <int i_>
+ struct DepListTestCase : DepListTestCaseBase
+ {
+ /**
+ * Constructor.
+ */
+ DepListTestCase() :
+ DepListTestCaseBase("dep list " + stringify(i_))
+ {
+ }
+ };
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ 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.
+ *
+ */
+ struct DepListTestCase2 : DepListTestCase<2>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase3 : DepListTestCase<3>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase4 : DepListTestCase<4>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase5 : DepListTestCase<5>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase6 : DepListTestCase<6>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase7 : DepListTestCase<7>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase8 : DepListTestCase<8>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "cat/four cat/three";
+ repo->add_version("cat", "three", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase9 : DepListTestCase<9>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase10 : DepListTestCase<10>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase11 : DepListTestCase<11>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase12 : DepListTestCase<12>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase13 : DepListTestCase<13>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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_interface->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.
+ *
+ */
+ struct DepListTestCase14 : DepListTestCase<14>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase15 : DepListTestCase<15>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase16 : DepListTestCase<16>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase17 : DepListTestCase<17>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase18 : DepListTestCase<18>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase19 : DepListTestCase<19>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase20 : DepListTestCase<20>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase21 : DepListTestCase<21>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase22 : DepListTestCase<22>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase23 : DepListTestCase<23>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase24 : DepListTestCase<24>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase25 : DepListTestCase<25>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase26 : DepListTestCase<26>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase27 : DepListTestCase<27>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase28 : DepListTestCase<28>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase29 : DepListTestCase<29>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase30 : DepListTestCase<30>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase31 : DepListTestCase<31>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase32 : DepListTestCase<32>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase33 : DepListTestCase<33>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase34 : DepListTestCase<34>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase35 : DepListTestCase<35>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase36 : DepListTestCase<36>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase37 : DepListTestCase<37>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase42 : DepListTestCase<42>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase43 : DepListTestCase<43>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "|| ( cat/two cat/three )";
+ repo->add_version("cat", "two", "1")->deps_interface->post_depend_string = "cat/one";
+ 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_43;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase44 : DepListTestCase<44>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase45 : DepListTestCase<45>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two[enabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase46 : DepListTestCase<46>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two[-disabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase47 : DepListTestCase<47>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two[disabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase48 : DepListTestCase<48>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two[-enabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase49 : DepListTestCase<49>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two cat/two[enabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase50 : DepListTestCase<50>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two cat/two[-disabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase51 : DepListTestCase<51>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two cat/two[disabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase52 : DepListTestCase<52>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "( cat/two cat/two[-enabled] )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase53 : DepListTestCase<53>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase54 : DepListTestCase<54>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase55 : DepListTestCase<55>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase56 : DepListTestCase<56>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two || ( cat/three cat/four )";
+ repo->add_version("cat", "two", "1")->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.
+ *
+ */
+ struct DepListTestCase57 : DepListTestCase<57>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->post_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "cat/three";
+ repo->add_version("cat", "three", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCase58 : DepListTestCase<58>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->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 resolution behaviour.
+ *
+ */
+ struct DepListTestCase59 : DepListTestCase<59>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "|| ( cat/two >=cat/three-2 )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "2");
+ installed_repo->add_version("cat", "three", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/three-2:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_59;
+
+ /**
+ * \test Test DepList resolution behaviour.
+ *
+ */
+ struct DepListTestCase60 : DepListTestCase<60>
+ {
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "|| ( cat/two >=cat/three-3 )";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "2");
+ installed_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_60;
+
+ /**
+ * \test Test DepList transactional add behaviour.
+ *
+ */
+ struct DepListTestCaseTransactionalAdd : TestCase
+ {
+ DepListTestCaseTransactionalAdd() : TestCase("dep list transactional add") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps_interface->build_depend_string = "cat/four cat/two";
+ repo->add_version("cat", "four", "1");
+ repo->add_version("cat", "five", "1")->deps_interface->build_depend_string = "cat/six cat/seven";
+ repo->add_version("cat", "six", "1");
+ repo->add_version("cat", "seven", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCaseTransactionalAddPost : TestCase
+ {
+ DepListTestCaseTransactionalAddPost() : TestCase("dep list transactional add post") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "cat/four";
+ repo->add_version("cat", "three", "1")->deps_interface->build_depend_string = "cat/four cat/two";
+ repo->add_version("cat", "four", "1");
+ repo->add_version("cat", "five", "1")->deps_interface->build_depend_string = "cat/six cat/seven";
+ repo->add_version("cat", "six", "1");
+ repo->add_version("cat", "seven", "1")->deps_interface->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.
+ *
+ */
+ struct DepListTestCaseForcedDowngradeOfInstalled : TestCase
+ {
+ DepListTestCaseForcedDowngradeOfInstalled() : TestCase("dep list forced downgrade of installed") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "one", "1");
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, 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;
+
+ /**
+ * \test Test DepList fall back never.
+ */
+ struct DepListTestCaseFallBackNever : TestCase
+ {
+ DepListTestCaseFallBackNever() : TestCase("dep list fall back never") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, RepositoryName("installed_repo")));
+ env.package_database()->add_repository(installed_repo);
+ installed_repo->add_version("cat", "two", "2");
+
+ DepList d(&env, DepListOptions());
+ d.options()->fall_back = dl_fall_back_never;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse("cat/one")), DepListError);
+ }
+ } test_dep_list_fall_back_never;
+
+ /**
+ * \test Test DepList fall back as needed.
+ */
+ struct DepListTestCaseFallBackAsNeeded : TestCase
+ {
+ DepListTestCaseFallBackAsNeeded() : TestCase("dep list fall back as needed") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, RepositoryName("installed_repo")));
+ env.package_database()->add_repository(installed_repo);
+ installed_repo->add_version("cat", "two", "2");
+
+ DepList d(&env, DepListOptions());
+ d.options()->fall_back = dl_fall_back_as_needed;
+ d.add(PortageDepParser::parse("cat/one"));
+ d.add(PortageDepParser::parse("cat/two"));
+ TEST_CHECK_EQUAL(join(d.begin(), d.end(), " "), "cat/two-2:0::installed_repo cat/one-1:0::repo");
+ }
+ } test_dep_list_fall_back_as_needed;
+
+ /**
+ * \test Test DepList fall back as needed.
+ */
+ struct DepListTestCaseFallBackAsNeededNotTargets : TestCase
+ {
+ DepListTestCaseFallBackAsNeededNotTargets() : TestCase("dep list fall back as needed not targets") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, RepositoryName("installed_repo")));
+ env.package_database()->add_repository(installed_repo);
+ installed_repo->add_version("cat", "two", "2");
+ installed_repo->add_version("cat", "three", "3");
+
+ DepList d1(&env, DepListOptions());
+ d1.options()->fall_back = dl_fall_back_as_needed_except_targets;
+ d1.add(PortageDepParser::parse("cat/one"));
+ TEST_CHECK_EQUAL(join(d1.begin(), d1.end(), " "), "cat/two-2:0::installed_repo cat/one-1:0::repo");
+ TEST_CHECK_THROWS(d1.add(PortageDepParser::parse("cat/three")), DepListError);
+
+ DepList d2(&env, DepListOptions());
+ d2.options()->fall_back = dl_fall_back_as_needed_except_targets;
+ TEST_CHECK_THROWS(d2.add(PortageDepParser::parse("cat/two")), DepListError);
+
+ DepList d3(&env, DepListOptions());
+ d3.options()->fall_back = dl_fall_back_as_needed_except_targets;
+ TEST_CHECK_THROWS(d3.add(PortageDepParser::parse("( cat/one cat/two )")), DepListError);
+
+ DepList d4(&env, DepListOptions());
+ d4.options()->fall_back = dl_fall_back_as_needed_except_targets;
+ TEST_CHECK_THROWS(d4.add(PortageDepParser::parse("( cat/one cat/three )")), DepListError);
+ }
+ } test_dep_list_fall_back_as_needed_not_targets;
+
+ /**
+ * \test Test DepList upgrade as needed.
+ */
+ struct DepListTestCaseUpgradeAsNeeded : TestCase
+ {
+ DepListTestCaseUpgradeAsNeeded() : TestCase("dep list upgrade as needed") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "2");
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, RepositoryName("installed_repo")));
+ env.package_database()->add_repository(installed_repo);
+ installed_repo->add_version("cat", "two", "0");
+
+ DepList d1(&env, DepListOptions());
+ d1.options()->upgrade = dl_upgrade_as_needed;
+ d1.add(PortageDepParser::parse("cat/one"));
+ TEST_CHECK_EQUAL(join(d1.begin(), d1.end(), " "), "cat/two-0:0::installed_repo cat/one-1:0::repo");
+
+ DepList d2(&env, DepListOptions());
+ d2.options()->upgrade = dl_upgrade_as_needed;
+ d2.add(PortageDepParser::parse("( cat/one cat/two )"));
+ TEST_CHECK_EQUAL(join(d2.begin(), d2.end(), " "), "cat/two-2:0::repo cat/one-1:0::repo");
+ }
+ } test_dep_list_upgrade_as_needed;
+
+ /**
+ * \test Test DepList reinstall scm.
+ */
+ struct DepListTestCaseReinstallSCM : TestCase
+ {
+ DepListTestCaseReinstallSCM() : TestCase("dep list reinstall scm") { }
+
+ void run()
+ {
+ TestEnvironment env;
+
+ std::tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&env, RepositoryName("repo")));
+ env.package_database()->add_repository(repo);
+ repo->add_version("cat", "zero", "1")->deps_interface->build_depend_string =
+ "( cat/one cat/two cat/three-live cat/four-cvs cat/five-svn cat/six-darcs )";
+ repo->add_version("cat", "one", "scm");
+ repo->add_version("cat", "two", "2");
+ repo->add_version("cat", "three-live", "0");
+ repo->add_version("cat", "four-cvs", "0");
+ repo->add_version("cat", "five-svn", "0");
+ repo->add_version("cat", "six-darcs", "0");
+
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo(
+ new FakeInstalledRepository(&env, RepositoryName("installed_repo")));
+ env.package_database()->add_repository(installed_repo);
+ installed_repo->add_version("cat", "one", "scm");
+ installed_repo->add_version("cat", "two", "2");
+ installed_repo->add_version("cat", "three-live", "0");
+ installed_repo->add_version("cat", "four-cvs", "0");
+ installed_repo->add_version("cat", "five-svn", "0");
+ installed_repo->add_version("cat", "six-darcs", "0");
+
+ DepList d1(&env, DepListOptions());
+ d1.options()->reinstall_scm = dl_reinstall_scm_always;
+ d1.add(PortageDepParser::parse("cat/zero"));
+ TEST_CHECK_EQUAL(join(d1.begin(), d1.end(), " "), "cat/one-scm:0::repo cat/two-2:0::installed_repo "
+ "cat/three-live-0:0::repo cat/four-cvs-0:0::repo cat/five-svn-0:0::repo cat/six-darcs-0:0::repo "
+ "cat/zero-1:0::repo");
+ }
+ } test_dep_list_upgrade_reinstall_scm;
+}
+
diff --git a/0.18.0/paludis/dep_list/dep_list_TEST.hh b/0.18.0/paludis/dep_list/dep_list_TEST.hh
new file mode 100644
index 000000000..31a7c8b4d
--- /dev/null
+++ b/0.18.0/paludis/dep_list/dep_list_TEST.hh
@@ -0,0 +1,171 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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_DEP_LIST_TEST_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_DEP_LIST_TEST_HH 1
+
+#include <paludis/dep_list/dep_list.hh>
+#include <paludis/dep_list/exceptions.hh>
+#include <paludis/portage_dep_parser.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/repositories/virtuals/installed_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
+{
+ class DepListEntry;
+ std::ostream &
+ operator<< (std::ostream & s, const DepListEntry & e)
+ {
+ s << e.package.name << "-" << e.package.version << ":" <<
+ e.metadata->slot << "::" << e.package.repository;
+
+ switch (e.kind)
+ {
+ case dlk_virtual:
+ case dlk_package:
+ case dlk_provided:
+ case dlk_already_installed:
+ case dlk_subpackage:
+ case dlk_suggested:
+ break;
+
+ case dlk_block:
+ s << "(!)";
+ break;
+
+ case dlk_masked:
+ s << "(M)";
+ break;
+
+ case last_dlk:
+ ;
+ }
+
+ return s;
+ }
+}
+
+namespace test_cases
+{
+ /**
+ * Convenience base class used by many of the DepList tests.
+ *
+ */
+ class DepListTestCaseBase :
+ public TestCase
+ {
+ protected:
+ TestEnvironment env;
+ std::tr1::shared_ptr<FakeRepository> repo;
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo;
+ std::tr1::shared_ptr<VirtualsRepository> virtuals_repo;
+ std::tr1::shared_ptr<InstalledVirtualsRepository> installed_virtuals_repo;
+ std::list<std::string> expected;
+ std::string merge_target;
+ bool done_populate;
+
+ /**
+ * Constructor.
+ */
+ DepListTestCaseBase(const std::string & s) :
+ TestCase(s),
+ env(),
+ repo(new FakeRepository(&env, RepositoryName("repo"))),
+ installed_repo(new FakeInstalledRepository(&env, RepositoryName("installed"))),
+ virtuals_repo(new VirtualsRepository(&env)),
+ installed_virtuals_repo(new InstalledVirtualsRepository(&env)),
+ done_populate(false)
+ {
+ env.package_database()->add_repository(repo);
+ env.package_database()->add_repository(installed_repo);
+ env.package_database()->add_repository(virtuals_repo);
+ env.package_database()->add_repository(installed_virtuals_repo);
+ }
+
+ /**
+ * Populate our repo member.
+ */
+ virtual void populate_repo() = 0;
+
+ /**
+ * Populate our expected member.
+ */
+ virtual void populate_expected() = 0;
+
+ virtual void set_options(DepListOptions &)
+ {
+ }
+
+ /**
+ * Check expected is what we got.
+ */
+ virtual void check_lists()
+ {
+ DepList d(&env, DepListOptions());
+ set_options(*d.options());
+ d.add(PortageDepParser::parse(merge_target));
+ TEST_CHECK(true);
+
+ TestMessageSuffix s("d={ " + join(d.begin(), d.end(), ", ") + " }", false);
+
+ unsigned n(0);
+ std::list<std::string>::const_iterator exp(expected.begin());
+ DepList::Iterator got(d.begin());
+ while (true)
+ {
+ TestMessageSuffix sx(stringify(n++), true);
+
+ TEST_CHECK((exp == expected.end()) == (got == d.end()));
+ if (got == d.end())
+ break;
+ TEST_CHECK_STRINGIFY_EQUAL(*got, *exp);
+ ++exp;
+ ++got;
+ }
+
+ d.clear();
+ TEST_CHECK(d.begin() == d.end());
+ }
+
+ public:
+ void run()
+ {
+ if (! done_populate)
+ {
+ populate_repo();
+ populate_expected();
+ done_populate = true;
+ }
+ check_lists();
+ }
+ };
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_list/dep_list_TEST_blockers.cc b/0.18.0/paludis/dep_list/dep_list_TEST_blockers.cc
new file mode 100644
index 000000000..5e138bc87
--- /dev/null
+++ b/0.18.0/paludis/dep_list/dep_list_TEST_blockers.cc
@@ -0,0 +1,361 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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_list_TEST.hh"
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ struct DepListTestCaseBasicBlock : DepListTestCaseBase
+ {
+ DepListTestCaseBasicBlock() : DepListTestCaseBase("block") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "!cat/two";
+ installed_repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.options()->blocks = dl_blocks_error;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+
+ d.options()->blocks = dl_blocks_accumulate;
+ d.add(PortageDepParser::parse(merge_target));
+ TEST_CHECK_EQUAL(std::distance(d.begin(), d.end()), 2);
+ TEST_CHECK_EQUAL(d.begin()->kind, dlk_block);
+ TEST_CHECK_STRINGIFY_EQUAL(d.begin()->package, "cat/two-1::installed");
+ TEST_CHECK_EQUAL(next(d.begin())->kind, dlk_package);
+ TEST_CHECK_STRINGIFY_EQUAL(next(d.begin())->package, "cat/one-1::repo");
+ }
+ } test_dep_list_basic_block;
+
+ struct DepListTestCaseListBlock : DepListTestCaseBase
+ {
+ DepListTestCaseListBlock() : DepListTestCaseBase("block on list ignore") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "!cat/two";
+ }
+
+ 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_list_block;
+
+ struct DepListTestCaseSelfBlock : DepListTestCaseBase
+ {
+ DepListTestCaseSelfBlock() : DepListTestCaseBase("self block via provide on list") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ std::tr1::shared_ptr<VersionMetadata> two_m(repo->add_version("cat", "two", "1"));
+ two_m->deps_interface->build_depend_string = "!virtual/two";
+ two_m->ebuild_interface->provide_string = "virtual/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::repo");
+ expected.push_back("virtual/two-1:0::virtuals");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_self_block_list;
+
+ struct DepListTestCaseProvidedBlock : DepListTestCaseBase
+ {
+ DepListTestCaseProvidedBlock() : DepListTestCaseBase("provided block") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ std::tr1::shared_ptr<VersionMetadata> two_m(repo->add_version("cat", "two", "1"));
+ two_m->deps_interface->build_depend_string = "!virtual/two";
+ two_m->ebuild_interface->provide_string = "virtual/two";
+ installed_repo->add_version("other", "two", "1")->ebuild_interface->provide_string = "virtual/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.options()->blocks = dl_blocks_error;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+
+ d.options()->blocks = dl_blocks_accumulate;
+ d.add(PortageDepParser::parse(merge_target));
+ TEST_CHECK_EQUAL(std::distance(d.begin(), d.end()), 4);
+ TEST_CHECK_EQUAL(d.begin()->kind, dlk_block);
+ TEST_CHECK_STRINGIFY_EQUAL(d.begin()->package, "virtual/two-1::installed_virtuals");
+ TEST_CHECK_EQUAL(next(d.begin())->kind, dlk_package);
+ TEST_CHECK_STRINGIFY_EQUAL(next(d.begin())->package, "cat/two-1::repo");
+ TEST_CHECK_EQUAL(next(next(d.begin()))->kind, dlk_provided);
+ TEST_CHECK_STRINGIFY_EQUAL(next(next(d.begin()))->package, "virtual/two-1::virtuals");
+ TEST_CHECK_EQUAL(next(next(next(d.begin())))->kind, dlk_package);
+ TEST_CHECK_STRINGIFY_EQUAL(next(next(next(d.begin())))->package, "cat/one-1::repo");
+ }
+ } test_dep_list_provided_block;
+
+ struct DepListTestCaseBlockOnList : DepListTestCaseBase
+ {
+ DepListTestCaseBlockOnList() : DepListTestCaseBase("block on list") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two cat/three";
+ repo->add_version("cat", "two", "1");
+ repo->add_version("cat", "three", "1")->deps_interface->build_depend_string = "!cat/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.options()->blocks = dl_blocks_error;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_block_on_list;
+
+ struct DepListTestCaseNoBlockOnReplaced : DepListTestCaseBase
+ {
+ DepListTestCaseNoBlockOnReplaced() : DepListTestCaseBase("no block on replaced") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = ">=cat/two-2 cat/three";
+ repo->add_version("cat", "two", "2");
+ repo->add_version("cat", "three", "1")->deps_interface->build_depend_string = "!<cat/two-2";
+ installed_repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-2:0::repo");
+ expected.push_back("cat/three-1:0::repo");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_no_block_on_replaced;
+
+ struct DepListTestCaseNoBlockOnNoUpgrade : DepListTestCaseBase
+ {
+ DepListTestCaseNoBlockOnNoUpgrade() : DepListTestCaseBase("no block on no upgrade") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "1")->deps_interface->build_depend_string = "!cat/two";
+ installed_repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-1:0::installed");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_no_block_on_no_upgrade;
+
+ struct DepListTestCaseNoBlockOnNoUpgradeViaProvided : DepListTestCaseBase
+ {
+ DepListTestCaseNoBlockOnNoUpgradeViaProvided() : DepListTestCaseBase("no block on no upgrade via provided") { }
+
+ void populate_repo()
+ {
+ std::tr1::shared_ptr<VersionMetadata> one_m(repo->add_version("cat", "one", "1"));
+ one_m->ebuild_interface->provide_string = "virtual/one";
+ one_m->deps_interface->build_depend_string = "!virtual/one";
+ one_m->deps_interface->run_depend_string = "!virtual/one";
+ std::tr1::shared_ptr<VersionMetadata> i_one_m(installed_repo->add_version("cat", "one", "1"));
+ i_one_m->ebuild_interface->provide_string = "virtual/one";
+ i_one_m->deps_interface->run_depend_string = "!virtual/one";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "virtual/one";
+ expected.push_back("cat/one-1:0::installed");
+ expected.push_back("virtual/one-1:0::virtuals");
+ }
+ } test_dep_list_no_block_on_no_upgrade_via_provided;
+
+ struct DepListTestCaseNoBlockOnNoReinstallViaProvided : DepListTestCaseBase
+ {
+ DepListTestCaseNoBlockOnNoReinstallViaProvided() : DepListTestCaseBase("no block on no reinstall via provided") { }
+
+ void populate_repo()
+ {
+ std::tr1::shared_ptr<VersionMetadata> one_m(repo->add_version("cat", "one", "1"));
+ one_m->ebuild_interface->provide_string = "virtual/one";
+ one_m->deps_interface->build_depend_string = "!virtual/one";
+ one_m->deps_interface->run_depend_string = "!virtual/one";
+ std::tr1::shared_ptr<VersionMetadata> i_one_m(installed_repo->add_version("cat", "one", "1"));
+ i_one_m->ebuild_interface->provide_string = "virtual/one";
+ i_one_m->deps_interface->run_depend_string = "!virtual/one";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "virtual/one";
+ expected.push_back("cat/one-1:0::repo");
+ expected.push_back("virtual/one-1:0::virtuals");
+ }
+
+ virtual void set_options(DepListOptions & p)
+ {
+ p.reinstall = dl_reinstall_always;
+ }
+ } test_dep_list_no_block_on_no_reinstall_via_provided;
+
+ struct DepListTestCaseNoBlockOnReplacedProvide : DepListTestCaseBase
+ {
+ DepListTestCaseNoBlockOnReplacedProvide() : DepListTestCaseBase("no block on replaced provide") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ std::tr1::shared_ptr<VersionMetadata> two_m(repo->add_version("cat", "two", "2"));
+ two_m->ebuild_interface->provide_string = "virtual/two";
+ two_m->deps_interface->build_depend_string = "!virtual/two";
+ installed_repo->add_version("cat", "two", "1")->ebuild_interface->provide_string = "virtual/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ expected.push_back("cat/two-2:0::repo");
+ expected.push_back("virtual/two-2:0::virtuals");
+ expected.push_back("cat/one-1:0::repo");
+ }
+ } test_dep_list_no_block_on_replaced_provide;
+
+ struct DepListTestCaseRestrictedOlderSelf : DepListTestCaseBase
+ {
+ DepListTestCaseRestrictedOlderSelf() : DepListTestCaseBase("restricted older self") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ repo->add_version("cat", "two", "2")->deps_interface->build_depend_string = "!<cat/two-2";
+ installed_repo->add_version("cat", "two", "1");
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.options()->blocks = dl_blocks_error;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_restricted_older_self;
+
+ struct DepListTestCaseRestrictedOlderSelfProvide : DepListTestCaseBase
+ {
+ DepListTestCaseRestrictedOlderSelfProvide() : DepListTestCaseBase("restricted older self provide") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ std::tr1::shared_ptr<VersionMetadata> two_m(repo->add_version("cat", "two", "2"));
+ two_m->deps_interface->build_depend_string = "!<virtual/two-2";
+ two_m->ebuild_interface->provide_string = "virtual/two";
+ installed_repo->add_version("cat", "two", "1")->ebuild_interface->provide_string = "virtual/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.options()->blocks = dl_blocks_error;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_restricted_older_self_provide;
+
+ struct DepListTestCaseRestrictedOlderOtherProvide : DepListTestCaseBase
+ {
+ DepListTestCaseRestrictedOlderOtherProvide() : DepListTestCaseBase("restricted older other provide") { }
+
+ void populate_repo()
+ {
+ repo->add_version("cat", "one", "1")->deps_interface->build_depend_string = "cat/two";
+ std::tr1::shared_ptr<VersionMetadata> two_m(repo->add_version("cat", "two", "2"));
+ two_m->deps_interface->build_depend_string = "!<virtual/two-2";
+ two_m->ebuild_interface->provide_string = "virtual/two";
+ installed_repo->add_version("other", "two", "1")->ebuild_interface->provide_string = "virtual/two";
+ }
+
+ void populate_expected()
+ {
+ merge_target = "cat/one";
+ }
+
+ void check_lists()
+ {
+ TEST_CHECK(true);
+ DepList d(&env, DepListOptions());
+ d.options()->blocks = dl_blocks_error;
+ TEST_CHECK_THROWS(d.add(PortageDepParser::parse(merge_target)), DepListError);
+ TEST_CHECK(d.begin() == d.end());
+ }
+ } test_dep_list_restricted_older_other_provide;
+}
+
+
diff --git a/0.18.0/paludis/dep_list/exceptions.cc b/0.18.0/paludis/dep_list/exceptions.cc
new file mode 100644
index 000000000..489bc2894
--- /dev/null
+++ b/0.18.0/paludis/dep_list/exceptions.cc
@@ -0,0 +1,59 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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 "exceptions.hh"
+
+using namespace paludis;
+
+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)
+{
+}
+
+DowngradeNotAllowedError::DowngradeNotAllowedError(const std::string & to, const std::string & from) throw () :
+ DepListError("Downgrade to '" + to + "' from '" + from + "' forbidden")
+{
+}
+
+DowngradeNotAllowedError::~DowngradeNotAllowedError() throw ()
+{
+}
+
diff --git a/0.18.0/paludis/dep_list/exceptions.hh b/0.18.0/paludis/dep_list/exceptions.hh
new file mode 100644
index 000000000..8bcd1fdd8
--- /dev/null
+++ b/0.18.0/paludis/dep_list/exceptions.hh
@@ -0,0 +1,171 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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_EXCEPTIONS_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_EXCEPTIONS_HH 1
+
+#include <paludis/util/exception.hh>
+
+namespace paludis
+{
+ /**
+ * Thrown if an error occurs whilst building a DepList.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ 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 downgrade is forced and we're not allowed to downgrade.
+ *
+ * \ingroup grpexceptions
+ * \ingroup grpdepresolver
+ * \nosubgrouping
+ */
+ class DowngradeNotAllowedError : public DepListError
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ DowngradeNotAllowedError(const std::string & to, const std::string & from) throw ();
+
+ virtual ~DowngradeNotAllowedError() throw ();
+
+ ///\}
+ };
+
+ /**
+ * Thrown if a block is encountered.
+ *
+ * \ingroup grpdepresolver
+ * \ingroup grpexceptions
+ * \nosubgrouping
+ */
+ 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
+ * \nosubgrouping
+ */
+ class CircularDependencyError : public DepListError
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ CircularDependencyError(const std::string & msg) throw ();
+
+ ///\}
+ };
+
+
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_list/options.cc b/0.18.0/paludis/dep_list/options.cc
new file mode 100644
index 000000000..48354a845
--- /dev/null
+++ b/0.18.0/paludis/dep_list/options.cc
@@ -0,0 +1,27 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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 "options.hh"
+#include <ostream>
+#include <paludis/util/exception.hh>
+
+using namespace paludis;
+
+#include <paludis/dep_list/options-se.cc>
+
diff --git a/0.18.0/paludis/dep_list/options.hh b/0.18.0/paludis/dep_list/options.hh
new file mode 100644
index 000000000..84b55f0a7
--- /dev/null
+++ b/0.18.0/paludis/dep_list/options.hh
@@ -0,0 +1,41 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006, 2007 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_OPTIONS_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_OPTIONS_HH 1
+
+#include <iosfwd>
+#include <paludis/util/attributes.hh>
+#include <bitset>
+
+namespace paludis
+{
+
+#include <paludis/dep_list/options-se.hh>
+
+ /**
+ * Set of masks that can be overridden.
+ *
+ * \ingroup grpdepresolver
+ * \see DepListOverrideMask
+ */
+ typedef std::bitset<last_dl_override> DepListOverrideMasks;
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_list/options.se b/0.18.0/paludis/dep_list/options.se
new file mode 100644
index 000000000..b8c635d82
--- /dev/null
+++ b/0.18.0/paludis/dep_list/options.se
@@ -0,0 +1,275 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_DepListTargetType()
+{
+ prefix dl_target
+
+ key dl_target_package "A package, so force reinstalls."
+ key dl_target_set "A set, so don't force reinstalls."
+
+ doxygen_comment << "END"
+ /**
+ * Type of target being handled at the top level.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListReinstallOption()
+{
+ prefix dl_reinstall
+
+ key dl_reinstall_never "Never"
+ key dl_reinstall_always "Always"
+ key dl_reinstall_if_use_changed "If a USE flag has changed"
+
+ doxygen_comment << "END"
+ /**
+ * When we should reinstall.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListFallBackOption()
+{
+ prefix dl_fall_back
+
+ key dl_fall_back_as_needed_except_targets "As needed, except for targets"
+ key dl_fall_back_as_needed "As needed"
+ key dl_fall_back_never "Never"
+
+ doxygen_comment << "END"
+ /**
+ * When we should fall back to an installed package.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListReinstallScmOption()
+{
+ prefix dl_reinstall_scm
+
+ key dl_reinstall_scm_never "Never"
+ key dl_reinstall_scm_always "Always"
+ key dl_reinstall_scm_daily "Daily"
+ key dl_reinstall_scm_weekly "Weekly"
+
+ doxygen_comment << "END"
+ /**
+ * When we should reinstall SCM packages.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListUpgradeOption()
+{
+ prefix dl_upgrade
+
+ key dl_upgrade_always "Always"
+ key dl_upgrade_as_needed "Only as needed"
+
+ doxygen_comment << "END"
+ /**
+ * When we should upgrade.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListDowngradeOption()
+{
+ prefix dl_downgrade
+ key dl_downgrade_as_needed "As needed"
+ key dl_downgrade_warning "As needed, but warn"
+ key dl_downgrade_error "Refuse to downgrade"
+
+ doxygen_comment << "END"
+ /**
+ * What to do when we downgrade.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListNewSlotsOption()
+{
+ prefix dl_new_slots
+
+ key dl_new_slots_always "Always"
+ key dl_new_slots_as_needed "Only where necessary"
+
+ doxygen_comment << "END"
+ /**
+ * When we should pull in a new slot.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListDepsOption()
+{
+ prefix dl_deps
+
+ key dl_deps_discard "Discard it"
+ key dl_deps_pre "As a pre dependency"
+ key dl_deps_pre_or_post "As a pre dependency with fallback to post"
+ key dl_deps_post "As a post dependency"
+ key dl_deps_try_post "As an optional post dependency"
+
+ doxygen_comment << "END"
+ /**
+ * How we should handle a dep class.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListSuggestedOption()
+{
+ prefix dl_suggested
+ key dl_suggested_show "Show"
+ key dl_suggested_discard "Discard"
+ key dl_suggested_install "Install"
+
+ doxygen_comment << "END"
+ /**
+ * How we should handle suggested deps.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListCircularOption()
+{
+ prefix dl_circular
+
+ key dl_circular_error "As an error"
+ key dl_circular_discard "Discard them"
+ key dl_circular_discard_silently "Discard them silently"
+
+ doxygen_comment << "END"
+ /**
+ * How we should handle circular deps.
+ *
+ * \see DepListOptions
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListBlocksOption()
+{
+ prefix dl_blocks
+
+ key dl_blocks_accumulate "Accumulate them and show all errors together"
+ key dl_blocks_error "Error on the first one"
+ key dl_blocks_discard "Discard (dangerous)"
+ key dl_blocks_discard_completely "Discard completely (not for user visible use)"
+
+ doxygen_comment <<"END"
+ /**
+ * How we handle blocks.
+ *
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListUseOption()
+{
+ prefix dl_use_deps
+ key dl_use_deps_standard "Behave as standard"
+ key dl_use_deps_take_all "Take both sides of use conditionals except on masks"
+
+ doxygen_comment <<"END"
+ /**
+ * How we handle use deps.
+ *
+ * Not for end user use. Used by adjutrix and qa.
+ *
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListEntryState()
+{
+ prefix dle
+
+ key dle_no_deps "Dependencies have yet to be added"
+ key dle_has_pre_deps "Predependencies have been added"
+ key dle_has_all_deps "All dependencies have been added"
+
+ doxygen_comment <<"END"
+ /**
+ * State of a DepListEntry.
+ *
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListEntryKind()
+{
+ prefix dlk
+
+ key dlk_package "A package to be installed"
+ key dlk_subpackage "A package to be installed as part of the previous dlk_package"
+ key dlk_already_installed "An already installed package"
+ key dlk_virtual "A virtual package"
+ key dlk_provided "A package provided by the previous dlk_package"
+ key dlk_suggested "A package suggested by the previous dlk_package"
+ key dlk_block "A blocked package that must be removed"
+ key dlk_masked "A masked package that must be unmasked"
+
+ doxygen_comment <<"END"
+ /**
+ * Kind of a DepListEntry.
+ *
+ * \ingroup grpdepresolver
+ */
+END
+}
+
+make_enum_DepListOverrideMask()
+{
+ prefix dl_override
+
+ key dl_override_licenses "Override unaccepted licences"
+ key dl_override_tilde_keywords "Override ~keywords"
+ key dl_override_unkeyworded "Override unkeyworded"
+ key dl_override_repository_masks "Override repository masks"
+ key dl_override_profile_masks "Override profile masks"
+
+ doxygen_comment <<"END"
+ /**
+ * Masks that can be overridden.
+ *
+ * \ingroup grpdepresolver
+ * \see DepListOverrideMasks
+ */
+END
+}
+
diff --git a/0.18.0/paludis/dep_list/range_rewriter.cc b/0.18.0/paludis/dep_list/range_rewriter.cc
new file mode 100644
index 000000000..3b4d263d2
--- /dev/null
+++ b/0.18.0/paludis/dep_list/range_rewriter.cc
@@ -0,0 +1,102 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 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 "range_rewriter.hh"
+
+using namespace paludis;
+
+RangeRewriter::RangeRewriter() :
+ _invalid(false)
+{
+}
+
+RangeRewriter::~RangeRewriter()
+{
+}
+
+void
+RangeRewriter::visit(const AllDepAtom * a)
+{
+ if (a->begin() != a->end())
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const AnyDepAtom * a)
+{
+ if (a->begin() != a->end())
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const UseDepAtom *)
+{
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const PlainTextDepAtom *)
+{
+ _invalid = true;
+}
+
+void
+RangeRewriter::visit(const PackageDepAtom * a)
+{
+ if (_invalid)
+ return;
+
+ if (a->use_requirements_ptr() || a->slot_ptr() || a->use_requirements_ptr() || ! a->version_requirements_ptr())
+ {
+ _invalid = true;
+ return;
+ }
+
+ if (a->version_requirements_mode() != vr_or && 1 != std::distance(a->version_requirements_ptr()->begin(),
+ a->version_requirements_ptr()->end()))
+ {
+ _invalid = true;
+ return;
+ }
+
+ if (_atom)
+ {
+ if (a->package() != _atom->package())
+ {
+ _invalid = true;
+ return;
+ }
+
+ for (VersionRequirements::Iterator v(a->version_requirements_ptr()->begin()),
+ v_end(a->version_requirements_ptr()->end()) ; v != v_end ; ++v)
+ _atom->version_requirements_ptr()->push_back(*v);
+ }
+ else
+ {
+ _atom.reset(new PackageDepAtom(*a));
+ _atom->set_version_requirements_mode(vr_or);
+ }
+}
+
+void
+RangeRewriter::visit(const BlockDepAtom *)
+{
+ _invalid = true;
+}
+
diff --git a/0.18.0/paludis/dep_list/range_rewriter.hh b/0.18.0/paludis/dep_list/range_rewriter.hh
new file mode 100644
index 000000000..9a3ef5cdb
--- /dev/null
+++ b/0.18.0/paludis/dep_list/range_rewriter.hh
@@ -0,0 +1,55 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 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_RANGE_REWRITER_HH
+#define PALUDIS_GUARD_PALUDIS_DEP_LIST_RANGE_REWRITER_HH 1
+
+#include <paludis/dep_atom.hh>
+
+namespace paludis
+{
+ class RangeRewriter :
+ public DepAtomVisitorTypes::ConstVisitor
+ {
+ private:
+ std::tr1::shared_ptr<PackageDepAtom> _atom;
+ bool _invalid;
+
+ public:
+ RangeRewriter();
+ virtual ~RangeRewriter();
+
+ std::tr1::shared_ptr<const PackageDepAtom> atom() const
+ {
+ if (_invalid)
+ return std::tr1::shared_ptr<const PackageDepAtom>();
+
+ return _atom;
+ }
+
+ void visit(const AllDepAtom *);
+ void visit(const AnyDepAtom *);
+ void visit(const UseDepAtom *);
+ void visit(const PlainTextDepAtom *);
+ void visit(const PackageDepAtom *);
+ void visit(const BlockDepAtom *);
+ };
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_list/range_rewriter_TEST.cc b/0.18.0/paludis/dep_list/range_rewriter_TEST.cc
new file mode 100644
index 000000000..50ea97d3a
--- /dev/null
+++ b/0.18.0/paludis/dep_list/range_rewriter_TEST.cc
@@ -0,0 +1,53 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 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_list/range_rewriter.hh>
+#include <paludis/dep_atom.hh>
+#include <paludis/dep_atom_pretty_printer.hh>
+#include <paludis/portage_dep_parser.hh>
+
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+
+using namespace test;
+using namespace paludis;
+
+namespace test_cases
+{
+ struct RangeRewriterTestCase :
+ TestCase
+ {
+ RangeRewriterTestCase() : TestCase("range rewriter") { }
+
+ void run()
+ {
+ std::tr1::shared_ptr<const CompositeDepAtom> p(PortageDepParser::parse_depend("=a/b-1 =a/b-2"));
+
+ RangeRewriter r;
+ TEST_CHECK(! r.atom());
+ std::for_each(p->begin(), p->end(), accept_visitor(&r));
+ TEST_CHECK(r.atom());
+
+ DepAtomPrettyPrinter w(0, false);
+ r.atom()->accept(&w);
+ TEST_CHECK_STRINGIFY_EQUAL(w, "=|=a/b-1,2 ");
+ }
+ } test_range_rewriter;
+}
+
diff --git a/0.18.0/paludis/dep_list/uninstall_list.cc b/0.18.0/paludis/dep_list/uninstall_list.cc
new file mode 100644
index 000000000..ac91104c2
--- /dev/null
+++ b/0.18.0/paludis/dep_list/uninstall_list.cc
@@ -0,0 +1,439 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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 "uninstall_list.hh"
+
+using namespace paludis;
+
+#include <paludis/dep_list/uninstall_list-sr.cc>
+#include <paludis/environment.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/log.hh>
+#include <paludis/hashed_containers.hh>
+#include <paludis/match_package.hh>
+#include <list>
+#include <algorithm>
+
+namespace paludis
+{
+ template<>
+ class CRCHash<PackageDatabaseEntry> :
+ public CRCHash<std::string>
+ {
+ public:
+ /// Hash function.
+ std::size_t operator() (const PackageDatabaseEntry & val) const
+ {
+ return CRCHash<std::string>::operator() (stringify(val));
+ }
+
+#if (! PALUDIS_HAVE_TR1_HASHES) && (! PALUDIS_HAVE_EXT_HASHES)
+ bool operator() (const PackageDatabaseEntry & lhs,
+ const PackageDatabaseEntry & rhs) const
+ {
+ return stringify(lhs) < stringify(rhs);
+ }
+#endif
+ };
+
+ template<>
+ struct Implementation<UninstallList>
+ {
+ const Environment * const env;
+ UninstallListOptions options;
+ std::list<UninstallListEntry> uninstall_list;
+
+ mutable MakeHashedMap<PackageDatabaseEntry, std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> >::Type
+ dep_collector_cache;
+
+ Implementation(const Environment * const e, const UninstallListOptions & o) :
+ env(e),
+ options(o)
+ {
+ }
+ };
+}
+
+namespace
+{
+ struct MatchUninstallListEntry
+ {
+ PackageDatabaseEntry e;
+
+ MatchUninstallListEntry(const PackageDatabaseEntry & ee) :
+ e(ee)
+ {
+ }
+
+ bool operator() (const UninstallListEntry & f)
+ {
+ return f.package == e;
+ }
+ };
+}
+
+UninstallList::UninstallList(const Environment * const env, const UninstallListOptions & o) :
+ PrivateImplementationPattern<UninstallList>(new Implementation<UninstallList>(env, o)),
+ options(_imp->options)
+{
+}
+
+UninstallList::~UninstallList()
+{
+}
+
+void
+UninstallList::add(const PackageDatabaseEntry & e, const PackageDatabaseEntry * const t)
+{
+ std::list<UninstallListEntry>::iterator i;
+ if (_imp->uninstall_list.end() != ((i = std::find_if(_imp->uninstall_list.begin(),
+ _imp->uninstall_list.end(), MatchUninstallListEntry(e)))))
+ {
+ if (t)
+ i->tags->insert(std::tr1::shared_ptr<DepTag>(new DependencyDepTag(*t)));
+
+ return;
+ }
+
+ Context context("When adding '" + stringify(e) + "' to the uninstall list:");
+
+ add_package(e, t);
+
+ if (_imp->options.with_dependencies)
+ add_dependencies(e);
+
+ move_package_to_end(e);
+
+ if (_imp->options.with_unused_dependencies)
+ add_unused_dependencies();
+}
+
+void
+UninstallList::add_unused()
+{
+ Context context("When finding unused packages:");
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> world(collect_world()),
+ everything(collect_all_installed());
+
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection>
+ world_plus_deps(new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete),
+ unused(new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+
+ world_plus_deps->insert(world->begin(), world->end());
+
+ std::size_t old_size(0);
+ while (old_size != world_plus_deps->size())
+ {
+ old_size = world_plus_deps->size();
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> new_world_deps(collect_depped_upon(world_plus_deps));
+ world_plus_deps->insert(new_world_deps->begin(), new_world_deps->end());
+ }
+
+ std::set_difference(everything->begin(), everything->end(),
+ world_plus_deps->begin(), world_plus_deps->end(), unused->inserter(),
+ ArbitrarilyOrderedPackageDatabaseEntryCollectionComparator());
+
+ for (PackageDatabaseEntryCollection::Iterator i(unused->begin()),
+ i_end(unused->end()) ; i != i_end ; ++i)
+ add_package(*i, 0);
+}
+
+UninstallList::Iterator
+UninstallList::begin() const
+{
+ return Iterator(_imp->uninstall_list.begin());
+}
+
+UninstallList::Iterator
+UninstallList::end() const
+{
+ return Iterator(_imp->uninstall_list.end());
+}
+
+UninstallListOptions::UninstallListOptions() :
+ with_unused_dependencies(false),
+ with_dependencies(false)
+{
+}
+
+void
+UninstallList::add_package(const PackageDatabaseEntry & e, const PackageDatabaseEntry * t)
+{
+ Context context("When adding package '" + stringify(e) + "' to the uninstall list:");
+
+ std::tr1::shared_ptr<const VersionMetadata> m(_imp->env->package_database()->fetch_repository(
+ e.repository)->version_metadata(e.name, e.version));
+
+ std::list<UninstallListEntry>::iterator i(_imp->uninstall_list.insert(
+ _imp->uninstall_list.end(), UninstallListEntry(
+ e, m->virtual_interface, std::tr1::shared_ptr<SortedCollection<std::tr1::shared_ptr<DepTag> > >(
+ new SortedCollection<std::tr1::shared_ptr<DepTag> >::Concrete))));
+ if (t)
+ i->tags->insert(std::tr1::shared_ptr<DepTag>(new DependencyDepTag(*t)));
+}
+
+void
+UninstallList::move_package_to_end(const PackageDatabaseEntry & e)
+{
+ Context context("When removing package '" + stringify(e) + "' from the uninstall list:");
+
+ std::list<UninstallListEntry>::iterator i(std::find_if(_imp->uninstall_list.begin(),
+ _imp->uninstall_list.end(), MatchUninstallListEntry(e)));
+ if (_imp->uninstall_list.end() != i)
+ _imp->uninstall_list.splice(_imp->uninstall_list.end(), _imp->uninstall_list, i);
+}
+
+std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>
+UninstallList::collect_all_installed() const
+{
+ Context context("When collecting all installed packages:");
+
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> result(
+ new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+ for (PackageDatabase::RepositoryIterator i(_imp->env->package_database()->begin_repositories()),
+ i_end(_imp->env->package_database()->end_repositories()) ; i != i_end ; ++i)
+ {
+ if (! (*i)->installed_interface)
+ continue;
+
+ std::tr1::shared_ptr<const CategoryNamePartCollection> cats((*i)->category_names());
+ for (CategoryNamePartCollection::Iterator c(cats->begin()), c_end(cats->end()) ;
+ c != c_end ; ++c)
+ {
+ std::tr1::shared_ptr<const QualifiedPackageNameCollection> pkgs((*i)->package_names(*c));
+ for (QualifiedPackageNameCollection::Iterator p(pkgs->begin()), p_end(pkgs->end()) ;
+ p != p_end ; ++p)
+ {
+ std::tr1::shared_ptr<const VersionSpecCollection> vers((*i)->version_specs(*p));
+ for (VersionSpecCollection::Iterator v(vers->begin()), v_end(vers->end()) ;
+ v != v_end ; ++v)
+ result->insert(PackageDatabaseEntry(*p, *v, (*i)->name()));
+ }
+ }
+ }
+
+ return result;
+}
+
+namespace
+{
+ struct DepCollector :
+ DepAtomVisitorTypes::ConstVisitor,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<DepCollector, AllDepAtom>,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<DepCollector, AnyDepAtom>
+ {
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<DepCollector, AllDepAtom>::visit;
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<DepCollector, AnyDepAtom>::visit;
+
+ const Environment * const env;
+ const PackageDatabaseEntry pkg;
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> matches;
+
+ DepCollector(const Environment * const ee, const PackageDatabaseEntry & e) :
+ env(ee),
+ pkg(e),
+ matches(new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete)
+ {
+ }
+
+ void visit(const PackageDepAtom * const a)
+ {
+ std::tr1::shared_ptr<const PackageDatabaseEntryCollection> m(env->package_database()->query(
+ *a, is_installed_only, qo_order_by_version));
+ matches->insert(m->begin(), m->end());
+ }
+
+ void visit(const UseDepAtom * const u)
+ {
+ if (env->query_use(UseFlagName(u->flag()), &pkg) ^ u->inverse())
+ std::for_each(u->begin(), u->end(), accept_visitor(this));
+ }
+
+ void visit(const BlockDepAtom * const)
+ {
+ }
+
+ void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn))
+ {
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
+ }
+ };
+}
+
+std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>
+UninstallList::collect_depped_upon(std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> targets) const
+{
+ Context context("When collecting depended upon packages:");
+
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> result(
+ new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+
+ for (PackageDatabaseEntryCollection::Iterator i(targets->begin()), i_end(targets->end()) ;
+ i != i_end ; ++i)
+ {
+ Context local_context("When collecting depended upon packages for '" + stringify(*i) + "':");
+
+ MakeHashedMap<PackageDatabaseEntry,
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> >::Type::const_iterator
+ cache(_imp->dep_collector_cache.find(*i));
+
+ if (cache == _imp->dep_collector_cache.end())
+ {
+ DepCollector c(_imp->env, *i);
+ std::tr1::shared_ptr<const VersionMetadata> metadata(_imp->env->package_database()->fetch_repository(
+ i->repository)->version_metadata(i->name, i->version));
+ if (metadata->deps_interface)
+ {
+ metadata->deps_interface->build_depend()->accept(&c);
+ metadata->deps_interface->run_depend()->accept(&c);
+ metadata->deps_interface->post_depend()->accept(&c);
+ metadata->deps_interface->suggested_depend()->accept(&c);
+ }
+ cache = _imp->dep_collector_cache.insert(std::make_pair(*i,
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>(c.matches))).first;
+ }
+
+ result->insert(cache->second->begin(), cache->second->end());
+ }
+
+ return result;
+}
+
+void
+UninstallList::add_unused_dependencies()
+{
+ Context context("When adding unused dependencies:");
+
+ bool added(true);
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> everything(collect_all_installed());
+ while (added)
+ {
+ added = false;
+
+ /* find packages that're depped upon by anything in our uninstall list */
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> uninstall_list_targets(
+ new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+ for (std::list<UninstallListEntry>::const_iterator i(_imp->uninstall_list.begin()),
+ i_end(_imp->uninstall_list.end()) ; i != i_end ; ++i)
+ uninstall_list_targets->insert(i->package);
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> depped_upon_list(
+ collect_depped_upon(uninstall_list_targets));
+
+ /* find packages that're depped upon by anything not in our uninstall list */
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> everything_except_uninstall_list_targets(
+ new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+ std::set_difference(everything->begin(), everything->end(),
+ uninstall_list_targets->begin(), uninstall_list_targets->end(),
+ everything_except_uninstall_list_targets->inserter(),
+ ArbitrarilyOrderedPackageDatabaseEntryCollectionComparator());
+
+ Log::get_instance()->message(ll_debug, lc_context, "everything_except_uninstall_list_targets is '"
+ + join(everything_except_uninstall_list_targets->begin(),
+ everything_except_uninstall_list_targets->end(), " ") + "'");
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> depped_upon_not_list(
+ collect_depped_upon(everything_except_uninstall_list_targets));
+
+ /* find unused dependencies */
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> unused_dependencies(
+ new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+ std::set_difference(depped_upon_list->begin(), depped_upon_list->end(),
+ depped_upon_not_list->begin(), depped_upon_not_list->end(), unused_dependencies->inserter(),
+ ArbitrarilyOrderedPackageDatabaseEntryCollectionComparator());
+
+ /* if any of them aren't already on the list, and aren't in world, add them and recurse */
+ std::tr1::shared_ptr<DepAtom> world(_imp->env->package_set(SetName("world")));
+ for (PackageDatabaseEntryCollection::Iterator i(unused_dependencies->begin()),
+ i_end(unused_dependencies->end()) ; i != i_end ; ++i)
+ {
+ if (match_package_in_heirarchy(*_imp->env, *world, *i))
+ continue;
+
+ if (_imp->uninstall_list.end() != std::find_if(_imp->uninstall_list.begin(),
+ _imp->uninstall_list.end(), MatchUninstallListEntry(*i)))
+ continue;
+
+ add_package(*i, 0);
+ added = true;
+ }
+ }
+}
+
+void
+UninstallList::add_dependencies(const PackageDatabaseEntry & e)
+{
+ Context context("When adding things that depend upon '" + stringify(e) + "':");
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> everything(collect_all_installed());
+ for (PackageDatabaseEntryCollection::Iterator i(everything->begin()),
+ i_end(everything->end()) ; i != i_end ; ++i)
+ {
+ Context local_context("When seeing whether '" + stringify(*i) + "' has a dep:");
+
+ MakeHashedMap<PackageDatabaseEntry,
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> >::Type::const_iterator
+ cache(_imp->dep_collector_cache.find(*i));
+
+ if (cache == _imp->dep_collector_cache.end())
+ {
+ DepCollector c(_imp->env, *i);
+ std::tr1::shared_ptr<const VersionMetadata> metadata(_imp->env->package_database()->fetch_repository(
+ i->repository)->version_metadata(i->name, i->version));
+ if (metadata->deps_interface)
+ {
+ metadata->deps_interface->build_depend()->accept(&c);
+ metadata->deps_interface->run_depend()->accept(&c);
+ metadata->deps_interface->post_depend()->accept(&c);
+ metadata->deps_interface->suggested_depend()->accept(&c);
+ }
+ cache = _imp->dep_collector_cache.insert(std::make_pair(*i,
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>(c.matches))).first;
+ }
+
+ if (cache->second->end() == cache->second->find(e))
+ continue;
+
+ Log::get_instance()->message(ll_debug, lc_context, "Adding '" + stringify(*i) +
+ "' because it depends upon '" + stringify(e) + "'");
+
+ add(*i, &e);
+ }
+}
+
+std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection>
+UninstallList::collect_world() const
+{
+ Context local_context("When collecting world packages:");
+
+ std::tr1::shared_ptr<ArbitrarilyOrderedPackageDatabaseEntryCollection> result(
+ new ArbitrarilyOrderedPackageDatabaseEntryCollection::Concrete);
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> everything(collect_all_installed());
+
+ std::tr1::shared_ptr<DepAtom> world(_imp->env->package_set(SetName("world")));
+ for (PackageDatabaseEntryCollection::Iterator i(everything->begin()),
+ i_end(everything->end()) ; i != i_end ; ++i)
+ if (match_package_in_heirarchy(*_imp->env, *world, *i))
+ result->insert(*i);
+
+ return result;
+}
+
diff --git a/0.18.0/paludis/dep_list/uninstall_list.hh b/0.18.0/paludis/dep_list/uninstall_list.hh
new file mode 100644
index 000000000..dede3e5ae
--- /dev/null
+++ b/0.18.0/paludis/dep_list/uninstall_list.hh
@@ -0,0 +1,69 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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_UNUSED_LIST_HH
+#define PALUDIS_GUARD_PALUDIS_UNUSED_LIST_HH 1
+
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/sr.hh>
+#include <paludis/package_database_entry.hh>
+#include <paludis/dep_tag.hh>
+
+#include <libwrapiter/libwrapiter_forward_iterator.hh>
+
+namespace paludis
+{
+#include <paludis/dep_list/uninstall_list-sr.hh>
+
+ class Environment;
+
+ class UninstallList :
+ private PrivateImplementationPattern<UninstallList>,
+ public InstantiationPolicy<UninstallList, instantiation_method::NonCopyableTag>
+ {
+ private:
+ void add_package(const PackageDatabaseEntry &, const PackageDatabaseEntry *);
+ void move_package_to_end(const PackageDatabaseEntry &);
+ void add_unused_dependencies();
+ void add_dependencies(const PackageDatabaseEntry &);
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> collect_depped_upon(
+ const std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> targets) const;
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> collect_all_installed() const;
+
+ std::tr1::shared_ptr<const ArbitrarilyOrderedPackageDatabaseEntryCollection> collect_world() const;
+
+ public:
+ UninstallList(const Environment * const, const UninstallListOptions &);
+ virtual ~UninstallList();
+
+ UninstallListOptions & options;
+
+ void add(const PackageDatabaseEntry &, const PackageDatabaseEntry * const = 0);
+ void add_unused();
+
+ typedef libwrapiter::ForwardIterator<UninstallList, const UninstallListEntry> Iterator;
+ Iterator begin() const;
+ Iterator end() const;
+ };
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_list/uninstall_list.sr b/0.18.0/paludis/dep_list/uninstall_list.sr
new file mode 100644
index 000000000..9a9380731
--- /dev/null
+++ b/0.18.0/paludis/dep_list/uninstall_list.sr
@@ -0,0 +1,44 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et :
+
+make_class_UninstallListOptions()
+{
+ key with_unused_dependencies bool
+ key with_dependencies bool
+
+ extra_constructors <<END
+ UninstallListOptions();
+END
+
+ allow_named_args
+
+ doxygen_comment << "END"
+ /**
+ * Parameters for an UninstallList.
+ *
+ * \see UninstallList
+ * \ingroup grpuninstalllist
+ * \nosubgrouping
+ */
+END
+}
+
+make_class_UninstallListEntry()
+{
+ key package PackageDatabaseEntry
+ key skip_uninstall bool
+ key tags "std::tr1::shared_ptr<SortedCollection<std::tr1::shared_ptr<DepTag> > >"
+
+ allow_named_args
+
+ doxygen_comment << "END"
+ /**
+ * An entry in an UninstallList.
+ *
+ * \see UninstallList
+ * \ingroup grpdepresolver
+ * \nosubgrouping
+ */
+END
+}
+
diff --git a/0.18.0/paludis/dep_list/uninstall_list_TEST.cc b/0.18.0/paludis/dep_list/uninstall_list_TEST.cc
new file mode 100644
index 000000000..2be33644c
--- /dev/null
+++ b/0.18.0/paludis/dep_list/uninstall_list_TEST.cc
@@ -0,0 +1,394 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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_list/uninstall_list.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 <paludis/portage_dep_parser.hh>
+#include <paludis/util/collection_concrete.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 UninstallListEntry & e)
+ {
+ s << e.package;
+ return s;
+ }
+}
+
+namespace test_cases
+{
+ /**
+ * Convenience base class used by many of the UninstallList tests.
+ *
+ */
+ class UninstallListTestCaseBase :
+ public TestCase
+ {
+ protected:
+ TestEnvironment env;
+ std::tr1::shared_ptr<FakeInstalledRepository> installed_repo;
+ std::tr1::shared_ptr<VirtualsRepository> virtuals_repo;
+ std::tr1::shared_ptr<PackageDatabaseEntryCollection> targets;
+ std::list<std::string> expected;
+ bool done_populate;
+
+ /**
+ * Constructor.
+ */
+ UninstallListTestCaseBase(const std::string & s) :
+ TestCase("uninstall list " + s),
+ env(),
+ installed_repo(new FakeInstalledRepository(&env, RepositoryName("installed"))),
+ virtuals_repo(new VirtualsRepository(&env)),
+ targets(new PackageDatabaseEntryCollection::Concrete),
+ done_populate(false)
+ {
+ env.package_database()->add_repository(installed_repo);
+ env.package_database()->add_repository(virtuals_repo);
+ }
+
+ /**
+ * Populate our repo member.
+ */
+ virtual void populate_repo() = 0;
+
+ /**
+ * Populate our targets.
+ */
+ virtual void populate_targets() = 0;
+
+ void add_target(const std::string & p, const std::string & v)
+ {
+ targets->push_back(PackageDatabaseEntry(
+ QualifiedPackageName(p),
+ VersionSpec(v),
+ RepositoryName("installed")));
+ }
+
+ /**
+ * Populate our expected member.
+ */
+ virtual void populate_expected() = 0;
+
+ /**
+ * Check expected is what we got.
+ */
+ virtual void check_lists()
+ {
+ TEST_CHECK(true);
+ UninstallList d(&env, options());
+ for (PackageDatabaseEntryCollection::Iterator i(targets->begin()),
+ i_end(targets->end()) ; i != i_end ; ++i)
+ d.add(*i);
+ TEST_CHECK(true);
+
+ unsigned n(0);
+ std::list<std::string>::const_iterator exp(expected.begin());
+ UninstallList::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;
+ }
+ }
+
+ virtual UninstallListOptions options()
+ {
+ return UninstallListOptions();
+ }
+
+ public:
+ void run()
+ {
+ if (! done_populate)
+ {
+ populate_repo();
+ populate_targets();
+ populate_expected();
+ done_populate = true;
+ }
+ check_lists();
+ }
+ };
+
+ struct UninstallListSimpleTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListSimpleTest() : UninstallListTestCaseBase("simple") { }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ }
+ } uninstall_list_simple_test;
+
+ struct UninstallListRepeatTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListRepeatTest() : UninstallListTestCaseBase("repeat") { }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ }
+ } uninstall_list_repeat_test;
+
+ struct UninstallListWithUnusedDepsTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListWithUnusedDepsTest() : UninstallListTestCaseBase("with unused deps") { }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1")->deps_interface->build_depend_string = "foo/baz";
+ installed_repo->add_version("foo", "baz", "2");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ expected.push_back("foo/baz-2::installed");
+ }
+
+ UninstallListOptions options()
+ {
+ return UninstallListOptions::create()
+ .with_unused_dependencies(true)
+ .with_dependencies(false);
+ }
+ } uninstall_list_with_unused_deps_test;
+
+ struct UninstallListWithUnusedDepsRecursiveTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListWithUnusedDepsRecursiveTest() : UninstallListTestCaseBase("with unused deps recursive") { }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1")->deps_interface->build_depend_string = "foo/baz";
+ installed_repo->add_version("foo", "baz", "2")->deps_interface->build_depend_string = "foo/moo";
+ installed_repo->add_version("foo", "moo", "3");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ expected.push_back("foo/baz-2::installed");
+ expected.push_back("foo/moo-3::installed");
+ }
+
+ UninstallListOptions options()
+ {
+ return UninstallListOptions::create()
+ .with_unused_dependencies(true)
+ .with_dependencies(false);
+ }
+ } uninstall_list_with_unused_deps_recursive_test;
+
+ struct UninstallListWithUnusedDepsWithUsedTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListWithUnusedDepsWithUsedTest() : UninstallListTestCaseBase("with unused deps with used") { }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1")->deps_interface->build_depend_string = "foo/baz foo/oink";
+ installed_repo->add_version("foo", "baz", "2");
+ installed_repo->add_version("foo", "moo", "3")->deps_interface->build_depend_string = "foo/oink";
+ installed_repo->add_version("foo", "oink", "1");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ expected.push_back("foo/baz-2::installed");
+ }
+
+ UninstallListOptions options()
+ {
+ return UninstallListOptions::create()
+ .with_unused_dependencies(true)
+ .with_dependencies(false);
+ }
+ } uninstall_list_with_unused_deps_with_used_test;
+
+ struct UninstallListWithUnusedDepsWithCrossUsedTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListWithUnusedDepsWithCrossUsedTest() :
+ UninstallListTestCaseBase("with unused deps with cross used") { }
+
+ void populate_targets()
+ {
+ add_target("foo/moo", "3");
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1")->deps_interface->build_depend_string = "foo/baz foo/oink";
+ installed_repo->add_version("foo", "baz", "2");
+ installed_repo->add_version("foo", "moo", "3")->deps_interface->build_depend_string = "foo/oink";
+ installed_repo->add_version("foo", "oink", "1");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/moo-3::installed");
+ expected.push_back("foo/bar-1::installed");
+ expected.push_back("foo/baz-2::installed");
+ expected.push_back("foo/oink-1::installed");
+ }
+
+ UninstallListOptions options()
+ {
+ return UninstallListOptions::create()
+ .with_unused_dependencies(true)
+ .with_dependencies(false);
+ }
+ } uninstall_list_with_unused_deps_with_cross_used_test;
+
+ struct UninstallListWithUnusedDepsWorldTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListWithUnusedDepsWorldTest() :
+ UninstallListTestCaseBase("with unused deps world")
+ {
+ installed_repo->add_package_set(SetName("world"), PortageDepParser::parse(
+ "foo/moo"));
+ }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1")->deps_interface->build_depend_string = "foo/baz foo/moo";
+ installed_repo->add_version("foo", "baz", "2");
+ installed_repo->add_version("foo", "moo", "2");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ expected.push_back("foo/baz-2::installed");
+ }
+
+ UninstallListOptions options()
+ {
+ return UninstallListOptions::create()
+ .with_unused_dependencies(true)
+ .with_dependencies(false);
+ }
+ } uninstall_list_with_unused_deps_world_test;
+
+ struct UninstallListWithUnusedDepsWorldTargetTest :
+ public UninstallListTestCaseBase
+ {
+ UninstallListWithUnusedDepsWorldTargetTest() :
+ UninstallListTestCaseBase("with unused deps world target")
+ {
+ installed_repo->add_package_set(SetName("world"), PortageDepParser::parse(
+ "foo/bar foo/moo"));
+ }
+
+ void populate_targets()
+ {
+ add_target("foo/bar", "1");
+ }
+
+ void populate_repo()
+ {
+ installed_repo->add_version("foo", "bar", "1")->deps_interface->build_depend_string = "foo/baz foo/moo";
+ installed_repo->add_version("foo", "baz", "2");
+ installed_repo->add_version("foo", "moo", "2");
+ }
+
+ void populate_expected()
+ {
+ expected.push_back("foo/bar-1::installed");
+ expected.push_back("foo/baz-2::installed");
+ }
+
+ UninstallListOptions options()
+ {
+ return UninstallListOptions::create()
+ .with_unused_dependencies(true)
+ .with_dependencies(false);
+ }
+ } uninstall_list_with_unused_deps_world_target_test;
+}
+
+
diff --git a/0.18.0/paludis/dep_tag.cc b/0.18.0/paludis/dep_tag.cc
new file mode 100644
index 000000000..77c68856c
--- /dev/null
+++ b/0.18.0/paludis/dep_tag.cc
@@ -0,0 +1,189 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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
+ */
+ std::tr1::shared_ptr<const DepTagCategory>
+ make_glsa_dep_tag()
+ {
+ return std::tr1::shared_ptr<const DepTagCategory>(new DepTagCategory(
+ true,
+ "glsa",
+ "Security advisories",
+ "Your system is potentially affected by these security issues:",
+ "Please read the advisories carefully and take appropriate action."));
+ }
+
+ /**
+ * Create the DepTagCategory for general sets.
+ *
+ * \see register_general_set_dep_tag
+ *
+ * \ingroup grpdeptag
+ */
+ std::tr1::shared_ptr<const DepTagCategory>
+ make_general_set_dep_tag()
+ {
+ return std::tr1::shared_ptr<const DepTagCategory>(new DepTagCategory(
+ true,
+ "general",
+ "General sets",
+ "",
+ ""));
+ }
+
+ /**
+ * Create the DepTagCategory for dependency sets.
+ *
+ * \see register_dependency_set_dep_tag
+ *
+ * \ingroup grpdeptag
+ */
+ std::tr1::shared_ptr<const DepTagCategory>
+ make_dependency_set_dep_tag()
+ {
+ return std::tr1::shared_ptr<const DepTagCategory>(new DepTagCategory(
+ false,
+ "dependency",
+ "Dependencies",
+ "",
+ ""));
+ }
+}
+
+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 SetName & id, const std::string & r) :
+ _id(id),
+ _source(r)
+{
+}
+
+std::string
+GeneralSetDepTag::short_text() const
+{
+ return stringify(_id);
+}
+
+std::string
+GeneralSetDepTag::category() const
+{
+ return "general";
+}
+
+std::string
+GeneralSetDepTag::source() const
+{
+ return _source;
+}
+
+DependencyDepTag::DependencyDepTag(const PackageDatabaseEntry & pde) :
+ _dbe(pde)
+{
+}
+
+std::string
+DependencyDepTag::short_text() const
+{
+ return stringify(_dbe);
+}
+
+std::string
+DependencyDepTag::category() const
+{
+ return "dependency";
+}
+
+DepTagCategoryMaker::DepTagCategoryMaker()
+{
+ register_maker("glsa", &make_glsa_dep_tag);
+ register_maker("general", &make_general_set_dep_tag);
+ register_maker("dependency", &make_dependency_set_dep_tag);
+}
+
diff --git a/0.18.0/paludis/dep_tag.hh b/0.18.0/paludis/dep_tag.hh
new file mode 100644
index 000000000..6c7b3a4f9
--- /dev/null
+++ b/0.18.0/paludis/dep_tag.hh
@@ -0,0 +1,308 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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 <paludis/package_database_entry.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/util/visitor.hh>
+#include <paludis/util/virtual_constructor.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/collection.hh>
+#include <paludis/util/sr.hh>
+
+#include <string>
+#include <tr1/memory>
+
+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
+ * \nosubgrouping
+ */
+ class DepTagCategory :
+ private InstantiationPolicy<DepTagCategory, instantiation_method::NonCopyableTag>
+ {
+ private:
+ bool _visible;
+ const std::string _id;
+ const std::string _title;
+ const std::string _pre_text;
+ const std::string _post_text;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ 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
+ * \nosubgrouping
+ */
+ class NoSuchDepTagCategory :
+ public Exception
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ NoSuchDepTagCategory(const std::string &) throw ();
+
+ ///\}
+ };
+
+ /**
+ * Virtual constructor for accessing DepTagCategory instances.
+ *
+ * \ingroup grpdeptag
+ */
+ class DepTagCategoryMaker :
+ public VirtualConstructor<std::string, std::tr1::shared_ptr<const DepTagCategory> (*) (),
+ virtual_constructor_not_found::ThrowException<NoSuchDepTagCategory> >,
+ public InstantiationPolicy<DepTagCategoryMaker, instantiation_method::SingletonTag>
+ {
+ friend class InstantiationPolicy<DepTagCategoryMaker, instantiation_method::SingletonTag>;
+
+ private:
+ DepTagCategoryMaker();
+ };
+
+ class DepTag;
+ class GLSADepTag;
+ class GeneralSetDepTag;
+ class DependencyDepTag;
+
+ /**
+ * Visitor class for visiting the different DepTag subclasses.
+ *
+ * \ingroup grpdeptag
+ * \see DepTag
+ */
+ 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
+ * \nosubgrouping
+ */
+ class DepTag :
+ InstantiationPolicy<DepTag, instantiation_method::NonCopyableTag>,
+ public virtual VisitableInterface<DepTagVisitorTypes>,
+ public ComparisonPolicy<DepTag,
+ comparison_mode::FullComparisonTag,
+ comparison_method::CompareByMemberFetchFunctionTag<std::string> >
+ {
+ protected:
+ ///\name Basic operations
+ ///\{
+
+ DepTag();
+
+ public:
+ 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;
+ };
+
+ /**
+ * DepTag subclass for GLSAs.
+ *
+ * \ingroup grpdeptag
+ * \nosubgrouping
+ */
+ class GLSADepTag :
+ public DepTag,
+ public Visitable<GLSADepTag, DepTagVisitorTypes>
+ {
+ private:
+ const std::string _id;
+ const std::string _glsa_title;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ 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
+ * \nosubgrouping
+ */
+ class GeneralSetDepTag :
+ public DepTag,
+ public Visitable<GeneralSetDepTag, DepTagVisitorTypes>
+ {
+ private:
+ const SetName _id;
+ const std::string _source;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ GeneralSetDepTag(const SetName & id, const std::string & source);
+
+ ///\}
+
+ virtual std::string short_text() const;
+
+ virtual std::string category() const;
+
+ /**
+ * From which repository or environment did we originate?
+ */
+ std::string source() const;
+ };
+
+ /**
+ * DepTag subclass for dependencies.
+ *
+ * \ingroup grpdeptag
+ * \nosubgrouping
+ */
+ class DependencyDepTag :
+ public DepTag,
+ public Visitable<DependencyDepTag, DepTagVisitorTypes>
+ {
+ private:
+ const PackageDatabaseEntry _dbe;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ DependencyDepTag(const PackageDatabaseEntry & dbe);
+
+ ///\}
+
+ virtual std::string short_text() const;
+
+ virtual std::string category() const;
+ };
+
+#include <paludis/dep_tag-sr.hh>
+
+ /**
+ * Tags attached to a DepListEntry.
+ *
+ * \ingroup grpdeptag
+ */
+ typedef SortedCollection<DepTagEntry> DepListEntryTags;
+}
+
+#endif
diff --git a/0.18.0/paludis/dep_tag.sr b/0.18.0/paludis/dep_tag.sr
new file mode 100644
index 000000000..474e52511
--- /dev/null
+++ b/0.18.0/paludis/dep_tag.sr
@@ -0,0 +1,23 @@
+make_class_DepTagEntry()
+{
+ key tag "std::tr1::shared_ptr<const DepTag>"
+ key generation long
+
+ allow_named_args
+ comparison_operators "all" "*tag"
+
+ doxygen_comment << "END"
+ /**
+ * Tags associated with a DepListEntry.
+ *
+ * The generation key is used internally by DepList. Its value is of no interest
+ * to outside clients.
+ *
+ * \see DepListEntry
+ * \ingroup grpdepresolver
+ * \nosubgrouping
+ */
+END
+}
+
+
diff --git a/0.18.0/paludis/digests/Makefile.am b/0.18.0/paludis/digests/Makefile.am
new file mode 100644
index 000000000..65c5ae4a4
--- /dev/null
+++ b/0.18.0/paludis/digests/Makefile.am
@@ -0,0 +1,53 @@
+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
+
+if MONOLITHIC
+
+noinst_LTLIBRARIES = libpaludisdigests.la
+
+else
+
+lib_LTLIBRARIES = libpaludisdigests.la
+
+endif
+
+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
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
diff --git a/0.18.0/paludis/digests/md5.cc b/0.18.0/paludis/digests/md5.cc
new file mode 100644
index 000000000..4109ada0c
--- /dev/null
+++ b/0.18.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.18.0/paludis/digests/md5.hh b/0.18.0/paludis/digests/md5.hh
new file mode 100644
index 000000000..e4da004bd
--- /dev/null
+++ b/0.18.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.18.0/paludis/digests/md5_TEST.cc b/0.18.0/paludis/digests/md5_TEST.cc
new file mode 100644
index 000000000..a839963fa
--- /dev/null
+++ b/0.18.0/paludis/digests/md5_TEST.cc
@@ -0,0 +1,112 @@
+/* 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
+ * \{
+ */
+
+ 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
+ * \{
+ */
+
+ 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.18.0/paludis/digests/rmd160.cc b/0.18.0/paludis/digests/rmd160.cc
new file mode 100644
index 000000000..dde3e742a
--- /dev/null
+++ b/0.18.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.18.0/paludis/digests/rmd160.hh b/0.18.0/paludis/digests/rmd160.hh
new file mode 100644
index 000000000..dddae2894
--- /dev/null
+++ b/0.18.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.18.0/paludis/digests/rmd160_TEST.cc b/0.18.0/paludis/digests/rmd160_TEST.cc
new file mode 100644
index 000000000..5ae5bd915
--- /dev/null
+++ b/0.18.0/paludis/digests/rmd160_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/rmd160.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace test;
+using namespace paludis;
+
+namespace
+{
+ /**
+ * \name Test utilities
+ * \{
+ */
+
+ 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
+ * \{
+ */
+
+ 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.18.0/paludis/digests/sha256.cc b/0.18.0/paludis/digests/sha256.cc
new file mode 100644
index 000000000..e574921f6
--- /dev/null
+++ b/0.18.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.18.0/paludis/digests/sha256.hh b/0.18.0/paludis/digests/sha256.hh
new file mode 100644
index 000000000..72852c384
--- /dev/null
+++ b/0.18.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.18.0/paludis/digests/sha256_TEST.cc b/0.18.0/paludis/digests/sha256_TEST.cc
new file mode 100644
index 000000000..542b1daad
--- /dev/null
+++ b/0.18.0/paludis/digests/sha256_TEST.cc
@@ -0,0 +1,443 @@
+/* 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.
+ *
+ */
+
+namespace
+{
+ /**
+ * \name Test utilities
+ * \{
+ */
+
+ 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
+ * \{
+ */
+
+ 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.18.0/paludis/ebuild.cc b/0.18.0/paludis/ebuild.cc
new file mode 100644
index 000000000..92810e404
--- /dev/null
+++ b/0.18.0/paludis/ebuild.cc
@@ -0,0 +1,463 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006, 2007 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>
+#include <unistd.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_FETCHERS_DIRS", params.environment->fetchers_dirs())
+ ("PALUDIS_SYNCERS_DIRS", params.environment->syncers_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)
+{
+}
+
+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.reset(new EbuildVersionMetadata);
+
+ bool ok(false);
+ try
+ {
+ _metadata->build_depend_string = f.get("DEPEND");
+ _metadata->run_depend_string = f.get("RDEPEND");
+ _metadata->slot = SlotName(f.get("SLOT"));
+ _metadata->src_uri = f.get("SRC_URI");
+ _metadata->restrict_string = f.get("RESTRICT");
+ _metadata->homepage = f.get("HOMEPAGE");
+ _metadata->license_interface->license_string = f.get("LICENSE");
+ _metadata->description = f.get("DESCRIPTION");
+ _metadata->keywords = f.get("KEYWORDS");
+ _metadata->eclass_keywords = f.get("E_KEYWORDS");
+ _metadata->inherited = f.get("INHERITED");
+ _metadata->iuse = f.get("IUSE");
+ _metadata->post_depend_string = f.get("PDEPEND");
+ _metadata->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";
+}