diff options
Diffstat (limited to 'src')
27 files changed, 584 insertions, 592 deletions
diff --git a/src/cmdline/cmdline_action.cc b/src/cmdline/cmdline_action.cc index 4a8393cb..9f42e421 100644 --- a/src/cmdline/cmdline_action.cc +++ b/src/cmdline/cmdline_action.cc @@ -220,7 +220,7 @@ namespace bool cmdline_applyaction(cmdline_pkgaction_type action, pkgCache::PkgIterator pkg, - std::set<pkgCache::PkgIterator> &seen_virtual_packages, + pkgset &seen_virtual_packages, pkgset &to_install, pkgset &to_hold, pkgset &to_remove, pkgset &to_purge, int verbose, @@ -232,86 +232,99 @@ bool cmdline_applyaction(cmdline_pkgaction_type action, const shared_ptr<terminal_metrics> &term_metrics) { // Handle virtual packages. - if(!pkg.ProvidesList().end()) + if(!pkg.ProvidesList().end() && pkg.VersionList().end()) { - if(pkg.VersionList().end()) - { - const bool seen_in_first_pass = - seen_virtual_packages.find(pkg) != seen_virtual_packages.end(); + const bool seen_in_first_pass = + seen_virtual_packages.find(pkg) != seen_virtual_packages.end(); - if(!seen_in_first_pass) - { - for(pkgCache::PrvIterator prv=pkg.ProvidesList(); !prv.end(); ++prv) - { - if(prv.OwnerPkg().CurrentVer()==prv.OwnerVer()) - { - if(verbose>0) + if(!seen_in_first_pass) + { + switch(action) + { + case cmdline_install: + case cmdline_installauto: + for(pkgCache::PrvIterator prv=pkg.ProvidesList(); + prv.end() == false; + ++prv) + { + if(prv.OwnerPkg().CurrentVer() == prv.OwnerVer()) + { + if(verbose > 0) printf(_("Note: \"%s\", providing the virtual package\n" " \"%s\", is already installed.\n"), prv.OwnerPkg().FullName(true).c_str(), pkg.FullName(true).c_str()); - return true; - } - else if((*apt_cache_file)[prv.OwnerPkg()].InstVerIter(*apt_cache_file)==prv.OwnerVer()) - { - if(verbose>0) + return true; + } + else if((*apt_cache_file)[prv.OwnerPkg()].InstVerIter(*apt_cache_file)==prv.OwnerVer()) + { + if(verbose > 0) printf(_("Note: \"%s\", providing the virtual package\n" " \"%s\", is already going to be installed.\n"), prv.OwnerPkg().FullName(true).c_str(), pkg.FullName(true).c_str()); - return true; - } - } - } + return true; + } + } + break; + default: + break; + } + } - seen_virtual_packages.insert(pkg); + seen_virtual_packages.insert(pkg); - // See if there's only one possible package to install. - pkgvector cands; + // See if there's only one possible package to install. + pkgvector cands; - for(pkgCache::PrvIterator prv=pkg.ProvidesList(); - !prv.end(); ++prv) - { - if((*apt_cache_file)[prv.OwnerPkg()].CandidateVerIter(*apt_cache_file)==prv.OwnerVer()) - cands.push_back(prv.OwnerPkg()); - } + for(pkgCache::PrvIterator prv=pkg.ProvidesList(); + !prv.end(); ++prv) + { + if((*apt_cache_file)[prv.OwnerPkg()].CandidateVerIter(*apt_cache_file)==prv.OwnerVer()) + cands.push_back(prv.OwnerPkg()); + } - if(cands.size()==0) - { - if(!seen_in_first_pass) - printf(_("\"%s\" exists in the package database, but it is not a\n" - "real package and no package provides it.\n"), - pkg.FullName(true).c_str()); - return false; - } - else if(cands.size()>1) - { - if(!seen_in_first_pass) - { - printf(_("\"%s\" is a virtual package provided by:\n"), - pkg.FullName(true).c_str()); - cmdline_show_pkglist(cands, term_metrics); - printf(_("You must choose one to install.\n")); - } - return false; - } - else if(cands.size()==1) - { - if(!seen_in_first_pass) - { - printf(_("Note: selecting \"%s\" instead of the\n" - "virtual package \"%s\"\n"), - cands[0].FullName(true).c_str(), - pkg.FullName(true).c_str()); - } - pkg = cands[0]; - } - } + if(cands.size()==0) + { + if(!seen_in_first_pass) + printf(_("\"%s\" exists in the package database, but it is not a\n" + "real package and no package provides it.\n"), + pkg.FullName(true).c_str()); + return false; + } + else if(cands.size()>1) + { + if(!seen_in_first_pass) + { + printf(_("\"%s\" is a virtual package provided by:\n"), + pkg.FullName(true).c_str()); + cmdline_show_pkglist(cands, term_metrics); + printf(_("You must choose one to install.\n")); + printf("\n"); + _error->Error(_("Package '%s' has no installation candidate"), + pkg.FullName(true).c_str()); + } + return false; + } + else if(cands.size()==1) + { + if(!seen_in_first_pass) + { + printf(_("Note: selecting \"%s\" instead of the\n" + " virtual package \"%s\"\n"), + cands[0].FullName(true).c_str(), pkg.Name()); + } + pkg = cands[0]; + } } pkgCache::VerIterator ver=pkg.CurrentVer(); if(action==cmdline_install || action == cmdline_installauto) - ver=cmdline_find_ver(pkg, source, sourcestr); + { + ver=cmdline_find_ver(pkg, source, sourcestr); + if(ver.end() == true) + return false; + } pkgDepCache::StateCache &pkg_state((*apt_cache_file)[pkg]); @@ -479,57 +492,32 @@ bool cmdline_applyaction(string s, if(!cmdline_parse_source(s, source, package, sourcestr)) return false; - // Handle task installation. Won't work if tasksel isn't installed. - aptitude::apt::task task; - string arch; - if(cmdline_parse_task(package, task, arch) == true) - { - printf(_("Note: selecting the task \"%s: %s\" for installation\n"), - task.name.c_str(), cw::util::transcode(task.shortdesc).c_str()); - - pkgset pkgset; - aptitude::apt::get_task_packages(&pkgset, task, arch); - for(pkgset::iterator pkg = pkgset.begin(); - pkg != pkgset.end(); - ++pkg) - { - rval = cmdline_applyaction(action, *pkg, - seen_virtual_packages, - to_install, to_hold, to_remove, to_purge, - verbose, source, - sourcestr, - policy, arch_only, - allow_auto, - term_metrics) && rval; - } - - // break out. - return rval; - } - // This is harmless for other commands, but it won't make sense. if(source == cmdline_version_version && action != cmdline_install && action != cmdline_forbid_version && action != cmdline_installauto && action != cmdline_build_depends) - { - printf(_("You can only specify a package version with an 'install' command or a 'forbid-version' command.\n")); - return false; - } + return _error->Error(_("You can only specify a package version with an" + " 'install' command or a 'forbid-version' command")); if(source == cmdline_version_archive && action != cmdline_install && action != cmdline_installauto && action != cmdline_build_depends) - { - printf(_("You can only specify a package archive with an 'install' command.\n")); - return false; - } + return _error->Error(_("You can only specify a package archive with an" + " 'install' command")); pkgset pkgset; - if(aptitude::cmdline::pkgset_from_string(&pkgset, package) == false) + if(aptitude::cmdline::pkgset_from_string(&pkgset, package, + GlobalError::ERROR, + GlobalError::WARNING) == false) { + // pkgset_from_string generates a warning for patterns with no + // matches. + if(is_pattern(package) == true) + return false; + // Assume the user asked for a source package. if(action == cmdline_build_depends) return cmdline_do_build_depends(package, diff --git a/src/cmdline/cmdline_action.h b/src/cmdline/cmdline_action.h index 37510d31..663dd05a 100644 --- a/src/cmdline/cmdline_action.h +++ b/src/cmdline/cmdline_action.h @@ -102,7 +102,7 @@ namespace aptitude */ bool cmdline_applyaction(cmdline_pkgaction_type action, pkgCache::PkgIterator pkg, - std::set<pkgCache::PkgIterator> &seen_virtual_packages, + pkgset &seen_virtual_packages, pkgset &to_install, pkgset &to_hold, pkgset &to_remove, pkgset &to_purge, int verbose, diff --git a/src/cmdline/cmdline_changelog.cc b/src/cmdline/cmdline_changelog.cc index 17c79fca..3c01fc49 100644 --- a/src/cmdline/cmdline_changelog.cc +++ b/src/cmdline/cmdline_changelog.cc @@ -177,7 +177,6 @@ void set_name(temp::name n, temp::name *target) single_download_progress::failure(msg); _error->Error(_("Changelog download failed: %s"), msg.c_str()); - _error->DumpErrors(); out_changelog_file = temp::name(); aptitude::cmdline::exit_main(); @@ -290,17 +289,16 @@ void do_cmdline_changelog(const vector<string> &packages, string default_release = aptcfg->Find("APT::Default-Release"); + _error->PushToStack(); for(vector<string>::const_iterator i=packages.begin(); i!=packages.end(); ++i) { // We need to do this because some code (see above) checks - // PendingError to see whether everything is OK. In addition, - // dumping errors means we get sensible error message output - // (this will be true even if the PendingError check is removed - // ... which it arguably should be). - _error->DumpErrors(); + // PendingError to see whether everything is OK. + _error->MergeWithStack(); + _error->PushToStack(); string input=*i; - cmdline_version_source source; + cmdline_version_source source = cmdline_version_cand; string package, sourcestr; if(!cmdline_parse_source(input, source, package, sourcestr)) @@ -429,7 +427,7 @@ void do_cmdline_changelog(const vector<string> &packages, _error->Error(_("Couldn't run pager %s"), pager); } - _error->DumpErrors(); + _error->MergeWithStack(); } // TODO: fetch them all in one go. @@ -437,16 +435,13 @@ int cmdline_changelog(int argc, char *argv[]) { shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); OpProgress progress; apt_init(&progress, false); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; vector<string> packages; for(int i=1; i<argc; ++i) @@ -454,7 +449,5 @@ int cmdline_changelog(int argc, char *argv[]) do_cmdline_changelog(packages, term); - _error->DumpErrors(); - - return 0; + return _error->PendingError() ? 100 : 0; } diff --git a/src/cmdline/cmdline_changelog.h b/src/cmdline/cmdline_changelog.h index 580b8fb4..2be98d5f 100644 --- a/src/cmdline/cmdline_changelog.h +++ b/src/cmdline/cmdline_changelog.h @@ -40,7 +40,7 @@ namespace aptitude /** \brief Display the changelog of each of the given package specifiers. * * The specifiers are literal package names, with optional version/archive - * descriptors. DumpErrors() is called after each changelog is displayed. + * descriptors. */ void do_cmdline_changelog(const std::vector<std::string> &packages, const boost::shared_ptr<aptitude::cmdline::terminal_metrics> &term_metrics); diff --git a/src/cmdline/cmdline_check_resolver.cc b/src/cmdline/cmdline_check_resolver.cc index cc112c0e..01077801 100644 --- a/src/cmdline/cmdline_check_resolver.cc +++ b/src/cmdline/cmdline_check_resolver.cc @@ -157,17 +157,14 @@ namespace int cmdline_check_resolver(int argc, char *argv[], const char *status_fname) { - _error->DumpErrors(); + consume_errors(); OpProgress progress; apt_init(&progress, true, status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; aptitude_universe u(*apt_cache_file); diff --git a/src/cmdline/cmdline_clean.cc b/src/cmdline/cmdline_clean.cc index 3a9670f7..7037b560 100644 --- a/src/cmdline/cmdline_clean.cc +++ b/src/cmdline/cmdline_clean.cc @@ -53,12 +53,12 @@ int cmdline_clean(int argc, char *argv[], bool simulate) { const string archivedir = aptcfg->FindDir("Dir::Cache::archives"); - _error->DumpErrors(); + consume_errors(); if(argc != 1) { - fprintf(stderr, _("E: The clean command takes no arguments\n")); - return -1; + _error->Error(_("The clean command takes no arguments")); + return 100; } if(simulate) @@ -77,20 +77,13 @@ int cmdline_clean(int argc, char *argv[], bool simulate) } if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; pkgAcquire fetcher; fetcher.Clean(archivedir); fetcher.Clean(archivedir+"partial/"); - int rval=_error->PendingError() ? -1 : 0; - - _error->DumpErrors(); - - return rval; + return _error->PendingError() ? 100 : 0; } // Shamelessly stolen from apt-get: @@ -127,12 +120,12 @@ int cmdline_autoclean(int argc, char *argv[], bool simulate) const string archivedir = aptcfg->FindDir("Dir::Cache::archives"); const shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); if(argc != 1) { - fprintf(stderr, _("E: The autoclean command takes no arguments\n")); - return -1; + _error->Error(_("The autoclean command takes no arguments")); + return 100; } // Lock the archive directory @@ -144,8 +137,7 @@ int cmdline_autoclean(int argc, char *argv[], bool simulate) if (_error->PendingError() == true) { _error->Error(_("Unable to lock the download directory")); - _error->DumpErrors(); - return -1; + return 100; } } @@ -154,19 +146,14 @@ int cmdline_autoclean(int argc, char *argv[], bool simulate) apt_init(progress.get(), false); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; LogCleaner cleaner(simulate); int rval=0; if(!(cleaner.Go(archivedir, *apt_cache_file) && cleaner.Go(archivedir+"partial/", *apt_cache_file)) || _error->PendingError()) - rval=-1; - - _error->DumpErrors(); + rval = 100; if(simulate) printf(_("Would free %sB of disk space\n"), @@ -177,4 +164,3 @@ int cmdline_autoclean(int argc, char *argv[], bool simulate) return rval; } - diff --git a/src/cmdline/cmdline_do_action.cc b/src/cmdline/cmdline_do_action.cc index 8d088379..36ded861 100644 --- a/src/cmdline/cmdline_do_action.cc +++ b/src/cmdline/cmdline_do_action.cc @@ -1,6 +1,7 @@ // cmdline_do_action.cc // // Copyright (C) 2004, 2010 Daniel Burrows +// Copyright (C) 2012 Daniel Hartwig // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as @@ -101,7 +102,7 @@ int cmdline_do_action(int argc, char *argv[], { shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); cmdline_pkgaction_type default_action=cmdline_install; @@ -157,8 +158,7 @@ int cmdline_do_action(int argc, char *argv[], { // Should never happen. _error->Error(_("Invalid operation %s"), argv[0]); - _error->DumpErrors(); - return -1; + return 100; } if(resolver_mode == resolver_mode_default) @@ -178,10 +178,7 @@ int cmdline_do_action(int argc, char *argv[], upgrade_mode == no_upgrade), status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; // In case we aren't root. if(!simulate) @@ -190,10 +187,7 @@ int cmdline_do_action(int argc, char *argv[], apt_cache_file->ReleaseLock(); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; pkgPolicy policy(&(*apt_cache_file)->GetCache()); ReadPinFile(policy); @@ -230,8 +224,8 @@ int cmdline_do_action(int argc, char *argv[], { if(argc != 1) { - cerr << _("Unexpected pattern argument following \"keep-all\"") << endl; - return -1; + _error->Error(_("Unexpected pattern argument following \"keep-all\"")); + return 100; } for(pkgCache::PkgIterator i=(*apt_cache_file)->PkgBegin(); @@ -334,6 +328,9 @@ int cmdline_do_action(int argc, char *argv[], } } + if(_error->PendingError() == true) + return 100; + if(resolver_mode == resolver_mode_safe) { if(!aptitude::cmdline::safe_resolve_deps(verbose, @@ -342,8 +339,9 @@ int cmdline_do_action(int argc, char *argv[], safe_resolver_show_actions, term)) { - fprintf(stderr, _("Unable to safely resolve dependencies, try running with --full-resolver.\n")); - return -1; + _error->Error(_("Unable to safely resolve dependencies, try" + " running with --full-resolver")); + return 100; } } @@ -366,10 +364,7 @@ int cmdline_do_action(int argc, char *argv[], aptitude::cmdline::apply_user_tags(user_tags); if(!(*apt_cache_file)->save_selection_list(*progress)) - { - _error->DumpErrors(); - return -1; - } + return 100; else return 0; } @@ -391,14 +386,18 @@ int cmdline_do_action(int argc, char *argv[], download_install_manager m(download_only, sigc::ptr_fun(&run_dpkg_directly)); + // FIXME: Temporary work-around for bug #677175 in apt. + const size_t prev_err_stack_count = _error->StackCount(); + int rval = (cmdline_do_download(&m, verbose, term, term, term, term) - == download_manager::success ? 0 : -1); + == download_manager::success ? 0 : 100); - if(_error->PendingError()) - rval = -1; + while(_error->StackCount() > prev_err_stack_count) + _error->MergeWithStack(); - _error->DumpErrors(); + if(_error->PendingError()) + rval = 100; return rval; } diff --git a/src/cmdline/cmdline_download.cc b/src/cmdline/cmdline_download.cc index e3ccb80c..8eede4d6 100644 --- a/src/cmdline/cmdline_download.cc +++ b/src/cmdline/cmdline_download.cc @@ -42,28 +42,23 @@ int cmdline_download(int argc, char *argv[]) if(argc<=1) { - printf(_("download: you must specify at least one package to download\n")); - return -1; + _error->Error(_("download: you must specify at least one package to download")); + return 100; } - _error->DumpErrors(); + consume_errors(); shared_ptr<OpProgress> progress = make_text_progress(false, term, term, term); apt_init(progress.get(), false); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; pkgSourceList list; if(!list.ReadMainList()) { _error->Error(_("Couldn't read source list")); - - _error->DumpErrors(); - return -1; + return 100; } std::pair<download_signal_log *, boost::shared_ptr<acquire_download_progress> > @@ -76,7 +71,7 @@ int cmdline_download(int argc, char *argv[]) for(int i=1; i<argc; ++i) { - cmdline_version_source source; + cmdline_version_source source = cmdline_version_cand; string name, sourcestr; if(!cmdline_parse_source(argv[i], source, name, sourcestr)) continue; @@ -103,7 +98,8 @@ int cmdline_download(int argc, char *argv[]) continue; if(!ver.Downloadable()) - _error->Error(_("No downloadable files for %s version %s; perhaps it is a local or obsolete package?"), + _error->Error(_("No downloadable files for %s version %s;" + " perhaps it is a local or obsolete package?"), name.c_str(), ver.VerStr()); get_archive(&fetcher, &list, apt_package_records, @@ -113,10 +109,7 @@ int cmdline_download(int argc, char *argv[]) if(fetcher.Run()!=pkgAcquire::Continue) // We failed or were cancelled - { - _error->DumpErrors(); - return -1; - } + return 100; return 0; } diff --git a/src/cmdline/cmdline_dump_resolver.cc b/src/cmdline/cmdline_dump_resolver.cc index 44f0e2b1..0c4e66ae 100644 --- a/src/cmdline/cmdline_dump_resolver.cc +++ b/src/cmdline/cmdline_dump_resolver.cc @@ -31,17 +31,14 @@ using namespace std; int cmdline_dump_resolver(int argc, char *argv[], const char *status_fname) { - _error->DumpErrors(); + consume_errors(); OpProgress progress; apt_init(&progress, true, status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; aptitude_universe u(*apt_cache_file); diff --git a/src/cmdline/cmdline_extract_cache_subset.cc b/src/cmdline/cmdline_extract_cache_subset.cc index e4620534..dde531a8 100644 --- a/src/cmdline/cmdline_extract_cache_subset.cc +++ b/src/cmdline/cmdline_extract_cache_subset.cc @@ -54,8 +54,9 @@ namespace aptitude { if(argc < 2) { - fprintf(stderr, _("extract-cache-entries: at least one argument is required (the directory\nto which to write files).\n")); - return -1; + _error->Error(_("extract-cache-entries: at least one argument is" + " required (the directory\nto which to write files)")); + return 100; } const shared_ptr<terminal_io> term = create_terminal(); @@ -66,12 +67,8 @@ namespace aptitude apt_init(progress.get(), true); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; - bool ok = true; pkgset packages; if(argc == 2) { @@ -82,22 +79,22 @@ namespace aptitude else { for(int i = 2; i < argc; ++i) - ok &= pkgset_from_string(&packages, argv[i]); + pkgset_from_string(&packages, argv[i]); } - if(!ok) + if(_error->PendingError() == true) + return 100; + + if(packages.size() == 0) { - _error->DumpErrors(); - return 2; + printf(_("No packages were selected by the given search pattern;" + " nothing to do.\n")); + return 0; } aptitude::apt::make_truncated_state_copy(out_dir, packages); - bool copy_ok = !_error->PendingError(); - - _error->DumpErrors(); - - return copy_ok ? 0 : 1; + return _error->PendingError() == true ? 100 : 0; } } } diff --git a/src/cmdline/cmdline_forget_new.cc b/src/cmdline/cmdline_forget_new.cc index e1485f52..4d3aadb4 100644 --- a/src/cmdline/cmdline_forget_new.cc +++ b/src/cmdline/cmdline_forget_new.cc @@ -47,14 +47,14 @@ int cmdline_forget_new(int argc, char *argv[], { const shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); // NB: perhaps we should allow forgetting the new state of just // a few packages? if(argc != 1) { - fprintf(stderr, _("E: The forget-new command takes no arguments\n")); - return -1; + _error->Error(_("The forget-new command takes no arguments")); + return 100; } shared_ptr<OpProgress> progress = make_text_progress(false, term, term, term); @@ -62,10 +62,7 @@ int cmdline_forget_new(int argc, char *argv[], apt_init(progress.get(), false, status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; // In case we aren't root. if(!simulate) @@ -74,10 +71,7 @@ int cmdline_forget_new(int argc, char *argv[], apt_cache_file->ReleaseLock(); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; if(simulate) printf(_("Would forget what packages are new\n")); @@ -88,11 +82,7 @@ int cmdline_forget_new(int argc, char *argv[], (*apt_cache_file)->save_selection_list(*progress); if(_error->PendingError()) - { - _error->DumpErrors(); - - return -1; - } + return 100; } return 0; diff --git a/src/cmdline/cmdline_prompt.cc b/src/cmdline/cmdline_prompt.cc index 25fadaa7..150c98fb 100644 --- a/src/cmdline/cmdline_prompt.cc +++ b/src/cmdline/cmdline_prompt.cc @@ -475,7 +475,10 @@ static bool prompt_essential(const shared_ptr<terminal_metrics> &term_metrics) if(!ok) { - printf(_("WARNING: Performing this action will probably cause your system to break!\n Do NOT continue unless you know EXACTLY what you are doing!\n")); + printf(_("WARNING: Performing this action will probably cause your" + " system to break!\n" + " Do NOT continue unless you know EXACTLY what you" + " are doing!\n")); string untranslated_prompt = N_("I am aware that this is a very bad idea"); string prompt = _(untranslated_prompt.c_str()); @@ -739,8 +742,8 @@ bool cmdline_show_preview(bool as_upgrade, pkgset &to_install, printf(_("Need to get %sB of archives. "), SizeToStr(f.DebBytes).c_str()); } - else - _error->DumpErrors(); + // else + // _error->DumpErrors(); if((*apt_cache_file)->UsrSize() >=0) printf(_("After unpacking %sB will be used.\n"), diff --git a/src/cmdline/cmdline_resolver.cc b/src/cmdline/cmdline_resolver.cc index d4f1ff14..22b97aac 100644 --- a/src/cmdline/cmdline_resolver.cc +++ b/src/cmdline/cmdline_resolver.cc @@ -887,7 +887,7 @@ cmdline_resolve_deps(pkgset &to_install, aptitude_solution sol = calculate_current_solution(true, term_metrics); if(_error->PendingError()) - _error->DumpErrors(); + _error->DumpErrors(); if(sol != lastsol || redisplay) { @@ -1111,7 +1111,8 @@ cmdline_resolve_deps(pkgset &to_install, } catch(cwidget::util::Exception &e) { - cout << _("*** ERROR: search aborted by fatal exception. You may continue\n searching, but some solutions will be unreachable.") + cout << _("*** ERROR: search aborted by fatal exception. You may continue\n" + " searching, but some solutions will be unreachable.") << endl << endl << e.errmsg(); diff --git a/src/cmdline/cmdline_search.cc b/src/cmdline/cmdline_search.cc index cae90e9f..0d670cdb 100644 --- a/src/cmdline/cmdline_search.cc +++ b/src/cmdline/cmdline_search.cc @@ -126,8 +126,6 @@ namespace search_progress_display->done(); - _error->DumpErrors(); - std::sort(output.begin(), output.end(), aptitude::cmdline::package_results_lt(sort_policy)); output.erase(std::unique(output.begin(), output.end(), @@ -154,7 +152,7 @@ namespace delete p; } - return 0; + return output.empty() ? 1 : 0; } } @@ -171,13 +169,10 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, pkg_sortpolicy *s=parse_sortpolicy(sort); - if(!s) - { - _error->DumpErrors(); - return -1; - } + if(s == NULL) + return 100; - _error->DumpErrors(); + consume_errors(); const unsigned int screen_width = term->get_screen_width(); if(!width.empty()) @@ -191,9 +186,8 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, if(!cw::util::transcode(display_format.c_str(), wdisplay_format)) { - _error->DumpErrors(); - fprintf(stderr, _("iconv of %s failed.\n"), display_format.c_str()); - return -1; + _error->Error(_("iconv of %s failed"), display_format.c_str()); + return 100; } boost::scoped_ptr<column_definition_list> columns; @@ -202,15 +196,12 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, pkg_item::pkg_columnizer::defaults)); if(columns.get() == NULL) - { - _error->DumpErrors(); - return -1; - } + return 100; if(argc<=1) { - fprintf(stderr, _("search: You must provide at least one search term\n")); - return -1; + _error->Error(_("search: You must provide at least one search term")); + return 100; } shared_ptr<OpProgress> progress = @@ -219,10 +210,7 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, apt_init(progress.get(), true, status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; vector<ref_ptr<pattern> > matchers; @@ -232,11 +220,7 @@ int cmdline_search(int argc, char *argv[], const char *status_fname, ref_ptr<pattern> m = parse(arg); if(!m.valid()) - { - _error->DumpErrors(); - - return -1; - } + return 100; matchers.push_back(m); } diff --git a/src/cmdline/cmdline_show.cc b/src/cmdline/cmdline_show.cc index 279da823..018c07c7 100644 --- a/src/cmdline/cmdline_show.cc +++ b/src/cmdline/cmdline_show.cc @@ -527,13 +527,20 @@ bool do_cmdline_show_target(const pkgCache::PkgIterator &pkg, bool has_explicit_source, const shared_ptr<terminal_metrics> &term_metrics) { - if(verbose == 0 || has_explicit_source) + if(has_explicit_source == true) { - // HACK: default to current-or-candidate behavior. This should be - // done in a more up-front way :-(. - if(source == cmdline_version_cand) - source = cmdline_version_curr_or_cand; + pkgCache::VerIterator ver = cmdline_find_ver(pkg, source, sourcestr, + GlobalError::NOTICE); + if(ver.end() == true) + return false; + + show_version(ver, verbose, term_metrics); + } + else if(verbose == 0) + { + _error->PushToStack(); pkgCache::VerIterator ver = cmdline_find_ver(pkg, source, sourcestr); + _error->RevertToStack(); if(ver.end()) ver = pkg.VersionList(); @@ -554,7 +561,7 @@ bool do_cmdline_show_target(const pkgCache::PkgIterator &pkg, bool do_cmdline_show(string s, int verbose, const shared_ptr<terminal_metrics> &term_metrics) { - cmdline_version_source source; + cmdline_version_source source = cmdline_version_curr_or_cand; string name, sourcestr; string default_release = aptcfg->Find("APT::Default-Release"); bool has_explicit_source = false; @@ -593,23 +600,23 @@ int cmdline_show(int argc, char *argv[], int verbose) { shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); shared_ptr<OpProgress> progress = make_text_progress(true, term, term, term); apt_init(progress.get(), false); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; + bool found_any = false; for(int i=1; i<argc; ++i) - do_cmdline_show(argv[i], verbose, term); - - int rval = _error->PendingError() == true ? -1 : 0; + found_any |= do_cmdline_show(argv[i], verbose, term); - _error->DumpErrors(GlobalError::DEBUG); + if(!found_any) + { + _error->Error(_("No packages found")); + return 100; + } - return rval; + return _error->PendingError() ? 100 : 0; } diff --git a/src/cmdline/cmdline_simulate.cc b/src/cmdline/cmdline_simulate.cc index e63bd632..445e85ae 100644 --- a/src/cmdline/cmdline_simulate.cc +++ b/src/cmdline/cmdline_simulate.cc @@ -71,11 +71,11 @@ int cmdline_simulate(bool as_upgrade, pkgPackageManager::OrderResult Res=PM.DoInstall(); if(Res==pkgPackageManager::Failed) - return -1; + return 100; else if(Res!=pkgPackageManager::Completed) { _error->Error(_("Internal Error, Ordering didn't finish")); - return -1; + return 100; } else return 0; diff --git a/src/cmdline/cmdline_update.cc b/src/cmdline/cmdline_update.cc index e5035e38..119f6647 100644 --- a/src/cmdline/cmdline_update.cc +++ b/src/cmdline/cmdline_update.cc @@ -48,29 +48,27 @@ int cmdline_update(int argc, char *argv[], int verbose) { shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); if(argc!=1) { - fprintf(stderr, _("E: The update command takes no arguments\n")); - return -1; + _error->Error(_("The update command takes no arguments")); + return 100; } // Don't exit if there's an error: it probably means that there // was a problem loading the package lists, so go ahead and try to // download new ones. - _error->DumpErrors(); + consume_errors(); download_update_manager m; m.pre_autoclean_hook.connect(sigc::ptr_fun(print_autoclean_msg)); int rval = (cmdline_do_download(&m, verbose, term, term, term, term) - == download_manager::success ? 0 : -1); + == download_manager::success ? 0 : 100); if(_error->PendingError()) - rval = -1; - - _error->DumpErrors(); + rval = 100; return rval; } diff --git a/src/cmdline/cmdline_user_tag.cc b/src/cmdline/cmdline_user_tag.cc index ca61d783..3474cd9a 100644 --- a/src/cmdline/cmdline_user_tag.cc +++ b/src/cmdline/cmdline_user_tag.cc @@ -93,58 +93,50 @@ namespace aptitude action = action_remove; else { - fprintf(stderr, "Internal error: cmdline_user_tag encountered an unknown command name \"%s\"\n", - argv[0]); - return -1; + _error->Error("Internal error: cmdline_user_tag encountered an" + " unknown command name \"%s\"\n", + argv[0]); + return 100; } if(argc < 3) { - fprintf(stderr, - _("%s: too few arguments; expected at least a tag name and a package.\n"), - argv[0]); - return -1; + _error->Error(_("%s: too few arguments; expected at least a tag" + " name and a package.\n"), + argv[0]); + return 100; } - _error->DumpErrors(); + consume_errors(); OpProgress progress; apt_init(&progress, true); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; std::string tag(argv[1]); - bool all_ok = true; + pkgset pkgset; for(int i = 2; i < argc; ++i) - { - pkgset packages; - if(pkgset_from_string(&packages, argv[i]) == false) - all_ok = false; - else - { - for(pkgset::const_iterator it = packages.begin(); - it != packages.end(); - ++it) - do_user_tag(action, tag, *it, verbose); - } - } + pkgset_from_string(&pkgset, argv[i]); + + if(pkgset.empty() == true) + { + _error->Error(_("No packages found")); + return 100; + } - if(all_ok == false) - _error->DumpErrors(); + for(pkgset::const_iterator it = pkgset.begin(); + it != pkgset.end(); + ++it) + do_user_tag(action, tag, *it, verbose); shared_ptr<OpProgress> text_progress = make_text_progress(false, term, term, term); if(!(*apt_cache_file)->save_selection_list(*text_progress)) - return 1; - - if(!all_ok) - return 2; + return 100; - return 0; + return _error->PendingError() == true ? 100 : 0; } } } diff --git a/src/cmdline/cmdline_util.cc b/src/cmdline/cmdline_util.cc index d7b1dcb4..9fc39b55 100644 --- a/src/cmdline/cmdline_util.cc +++ b/src/cmdline/cmdline_util.cc @@ -39,6 +39,7 @@ #include <generic/apt/matching/match.h> #include <generic/apt/matching/parse.h> #include <generic/apt/matching/pattern.h> +#include <generic/apt/matching/serialize.h> #include <generic/apt/tasks.h> // System includes: @@ -71,15 +72,16 @@ using boost::shared_ptr; namespace { - const int no_install_run_from_ui_preview_return = -1; - const int ui_preview_install_failed_return = -1; + const int no_install_run_from_ui_preview_return = 1; + const int ui_preview_install_failed_return = 100; // Completion routine for the UI preview; causes the program to - // return 0 if the install succeded and 1 otherwise. + // return 0 if the install succeded, 1 if the user cancelled, + // and 100 otherwise. // // There's a question in my mind of what to do if the user cancels // the preview or runs multiple previews. At the moment we return - // -1 if the preview is cancelled and the result of the last install + // 1 if the preview is cancelled and the result of the last install // run otherwise. void ui_preview_complete(bool success, int *result) { @@ -150,7 +152,8 @@ void cmdline_show_pkglist(pkgvector &items, pkgCache::VerIterator cmdline_find_ver(pkgCache::PkgIterator pkg, cmdline_version_source source, - string sourcestr) + string sourcestr, + GlobalError::MsgType error_type) { switch(source) { @@ -165,9 +168,13 @@ pkgCache::VerIterator cmdline_find_ver(pkgCache::PkgIterator pkg, if(candver.end()) { if(source == cmdline_version_cand) - printf(_("No candidate version found for %s\n"), pkg.FullName(true).c_str()); + _error->Insert(error_type, + _("No candidate version found for %s"), + pkg.FullName(true).c_str()); else - printf(_("No current or candidate version found for %s\n"), pkg.FullName(true).c_str()); + _error->Insert(error_type, + _("No current or candidate version found for %s"), + pkg.FullName(true).c_str()); } return candver; @@ -191,9 +198,10 @@ pkgCache::VerIterator cmdline_find_ver(pkgCache::PkgIterator pkg, return ver; } - printf(_("Unable to find an archive \"%s\" for the package \"%s\"\n"), - sourcestr.c_str(), - pkg.FullName(true).c_str()); + _error->Insert(error_type, + _("Unable to find an archive \"%s\" for the package \"%s\""), + sourcestr.c_str(), + pkg.FullName(true).c_str()); return pkgCache::VerIterator(*apt_cache_file, 0); case cmdline_version_version: @@ -201,14 +209,15 @@ pkgCache::VerIterator cmdline_find_ver(pkgCache::PkgIterator pkg, if(sourcestr==ver.VerStr()) return ver; - printf(_("Unable to find a version \"%s\" for the package \"%s\"\n"), - sourcestr.c_str(), - pkg.FullName(true).c_str()); + _error->Insert(error_type, + _("Unable to find a version \"%s\" for the package \"%s\""), + sourcestr.c_str(), + pkg.FullName(true).c_str()); return pkgCache::VerIterator(*apt_cache_file, 0); default: - printf(_("Internal error: invalid value %i passed to cmdline_find_ver!\n"), - source); + _error->Error(_("Internal error: invalid value %i passed to cmdline_find_ver!"), + source); return pkg.VersionList(); } } @@ -220,7 +229,7 @@ bool cmdline_parse_source(const string &input, { string scratch=input; - source=cmdline_version_cand; + // source=cmdline_version_cand; sourcestr=""; if(scratch.find('/')!=scratch.npos) @@ -236,10 +245,8 @@ bool cmdline_parse_source(const string &input, if(scratch.find('=')!=scratch.npos) { if(source==cmdline_version_archive) - { - printf(_("You cannot specify both an archive and a version for a package\n")); - return false; - } + return _error->Error(_("You cannot specify both an archive and a" + " version for a package")); source=cmdline_version_version; string::size_type loc=scratch.rfind('='); @@ -253,30 +260,6 @@ bool cmdline_parse_source(const string &input, return true; } -bool cmdline_parse_task(string pattern, - aptitude::apt::task &task, - string &arch) -{ - const string::size_type archfound = pattern.find_last_of(':'); - arch = "native"; - if(archfound != string::npos) - { - arch = pattern.substr(archfound+1); - pattern.erase(archfound); - } - - if(pattern[pattern.length() - 1] != '^') - return false; - pattern.erase(pattern.length() - 1); - - const aptitude::apt::task *t = aptitude::apt::find_task(pattern); - if(t == NULL) - return _error->Error(_("Couldn't find task '%s'"), pattern.c_str()); - - task = *t; - return true; -} - namespace { /** \brief Used to display some statistics about how the cache @@ -465,7 +448,7 @@ download_manager::result cmdline_do_download(download_manager *m, // otherwise. OpProgress tmpProgress; // Dump errors so we don't spuriously think we failed. - _error->DumpErrors(); + consume_errors(); apt_load_cache(&tmpProgress, false, NULL); initial_stats = compute_apt_stats(); } @@ -480,7 +463,7 @@ download_manager::result cmdline_do_download(download_manager *m, // Dump errors here because prepare() might check for pending errors // and think something failed. - _error->DumpErrors(); + consume_errors(); if(!m->prepare(*progress, *log.get(), log.get())) return download_manager::failure; @@ -584,38 +567,53 @@ namespace aptitude if(apt_source_list == NULL) return NULL; + source_package rval = source_package(); + bool done = false; + + _error->PushToStack(); for(pkgSourceList::const_iterator i = apt_source_list->begin(); - i != apt_source_list->end(); ++i) + done != true && i != apt_source_list->end(); + ++i) { if((*i)->GetDist() != archive) continue; vector<pkgIndexFile *> *indexes = (*i)->GetIndexFiles(); - for(vector<pkgIndexFile *>::const_iterator j = indexes->begin(); - j != indexes->end(); ++j) + for(vector<pkgIndexFile *>::const_iterator j = indexes->begin(); + done != true && j != indexes->end(); + ++j) { std::auto_ptr<pkgSrcRecords::Parser> p((*j)->CreateSrcParser()); if(_error->PendingError()) - return source_package(); - if(p.get() != 0) + done = true; + else if(p.get() != 0) { // Step through the file until we reach the end or find // the package: while(p.get()->Step() == true) { if(_error->PendingError() == true) - return source_package(); + { + done = true; + break; + } if(p.get()->Package() == source_name) - return source_package(p.get()); + { + rval = source_package(p.get()); + done = true; + break; + } } } } } - return source_package(); + _error->RevertToStack(); + + return rval; } source_package find_source_package(const std::string &package, @@ -652,7 +650,6 @@ namespace aptitude // version. case cmdline_version_archive: - _error->DumpErrors(); rval = find_source_by_archive(source_package_name, version_source_string); break; @@ -670,7 +667,8 @@ namespace aptitude { pkgCache::VerIterator ver = cmdline_find_ver(pkg, version_source, - version_source_string); + version_source_string, + GlobalError::NOTICE); if(!ver.end()) { @@ -719,7 +717,6 @@ namespace aptitude break; // We would have tried already if it was possible. case cmdline_version_archive: - _error->DumpErrors(); rval = find_source_by_archive(source_package_name, version_source_string); break; @@ -868,52 +865,129 @@ namespace aptitude return pkg; } - bool pkgset_from_pattern(pkgset *packages, const string &pattern, - GlobalError::MsgType error_type) + bool pkgset_from_task(pkgset * const pkgset, string pattern, + GlobalError::MsgType error_type) { - using aptitude::matching::pkg_results_list; - using aptitude::matching::search_cache; - using cwidget::util::ref_ptr; + const string::size_type archfound = pattern.find_last_of(':'); + string arch = "native"; + if(archfound != string::npos) + { + arch = pattern.substr(archfound+1); + pattern.erase(archfound); + } - if(aptitude::matching::is_pattern(pattern) == false) + if(pattern[pattern.length() - 1] != '^') return false; + pattern.erase(pattern.length() - 1); - ref_ptr<aptitude::matching::pattern> p(aptitude::matching::parse(pattern)); - if(p.valid() == false) + const aptitude::apt::task *t = aptitude::apt::find_task(pattern); + if(t == NULL) return _error->Insert(error_type, - _("Unable to parse pattern '%s'"), pattern.c_str()); + _("Couldn't find task '%s'"), pattern.c_str()); + + printf(_("Note: selecting the task \"%s: %s\" for installation\n"), + t->name.c_str(), cw::util::transcode(t->shortdesc).c_str()); + + aptitude::apt::get_task_packages(pkgset, *t, arch); + return true; + } - pkg_results_list matches; - ref_ptr<search_cache> search_info(search_cache::create()); - search(p, search_info, - matches, - *apt_cache_file, - *apt_package_records); + bool pkgset_from_pattern(pkgset * const pkgset, + cw::util::ref_ptr<aptitude::matching::pattern> pattern, + string pattern_str, + GlobalError::MsgType error_type) + { + namespace m = aptitude::matching; + + m::pkg_results_list matches; + cw::util::ref_ptr<m::search_cache> search_info(m::search_cache::create()); + m::search(pattern, + search_info, + matches, + *apt_cache_file, + *apt_package_records); if(matches.empty() == true) - return _error->Insert(error_type, - _("Couldn't find any package for pattern '%s'"), - pattern.c_str()); + { + if(pattern_str.empty() == true) + pattern_str = m::serialize_pattern(pattern); + return _error->Insert(error_type, + _("Couldn't find any package for pattern '%s'"), + pattern_str.c_str()); + } - for(pkg_results_list::const_iterator it = matches.begin(); + for(m::pkg_results_list::const_iterator it = matches.begin(); it != matches.end(); ++it) + pkgset->insert(it->first); + + return true; + } + + bool pkgset_from_regex(pkgset * const pkgset, string pattern, + GlobalError::MsgType error_type) + { + namespace m = aptitude::matching; + using cw::util::ref_ptr; + + static const char * const isregex = ".?+|[^$"; + if(pattern.find_first_of(isregex) == std::string::npos) + return false; + + std::string regex = pattern; + size_t archfound = regex.find_last_of(':'); + std::string arch = "native"; + if(archfound != std::string::npos) { - packages->insert(it->first); + arch = regex.substr(archfound+1); + if(arch.find_first_of(isregex) == std::string::npos) + regex.erase(archfound); + else + archfound = std::string::npos; } - return true; + + ref_ptr<m::pattern> p = m::pattern::make_name(regex); + if(p.valid() == false) + return false; + if(archfound != std::string::npos) + p = m::pattern::make_and(p, m::pattern::make_architecture(arch)); + + return pkgset_from_pattern(pkgset, p, pattern, error_type); + } + + bool pkgset_from_pattern(pkgset * const pkgset, string pattern, + GlobalError::MsgType error_type) + { + namespace m = aptitude::matching; + using cwidget::util::ref_ptr; + + if(m::is_pattern(pattern) == false) + return false; + + ref_ptr<m::pattern> p(m::parse(pattern)); + if(p.valid() == false) + return false; + + return pkgset_from_pattern(pkgset, p, pattern, error_type); } - bool pkgset_from_string(pkgset *packages, const string &str, - GlobalError::MsgType error_type) + bool pkgset_from_string(pkgset * const pkgset, string str, + GlobalError::MsgType error_type, + GlobalError::MsgType pattern_error_type) { bool found = true; _error->PushToStack(); - pkgCache::PkgIterator pkg = pkg_from_name(str, error_type); - if(pkg.end() == false) - packages->insert(pkg); - else if(pkgset_from_pattern(packages, str, error_type) == false) + if(aptitude::matching::is_pattern(str) == false) + { + pkgCache::PkgIterator pkg = pkg_from_name(str, error_type); + if(pkg.end() == false) + pkgset->insert(pkg); + else if(pkgset_from_task(pkgset, str, error_type) == false && + pkgset_from_regex(pkgset, str, error_type) == false) + found = false; + } + else if(pkgset_from_pattern(pkgset, str, pattern_error_type) == false) found = false; if(found == true) diff --git a/src/cmdline/cmdline_util.h b/src/cmdline/cmdline_util.h index 2e10b005..77b18140 100644 --- a/src/cmdline/cmdline_util.h +++ b/src/cmdline/cmdline_util.h @@ -66,7 +66,8 @@ void cmdline_show_stringlist(strvector &items, */ pkgCache::VerIterator cmdline_find_ver(pkgCache::PkgIterator pkg, cmdline_version_source source, - string sourcestr); + string sourcestr, + GlobalError::MsgType error_type = GlobalError::ERROR); /** Starts up the visual UI in preview mode, and exits with status 0 * when the UI shuts down. @@ -95,10 +96,6 @@ bool cmdline_parse_source(const string &input, string &package, string &sourcestr); -bool cmdline_parse_task(std::string pattern, - aptitude::apt::task &task, - std::string &arch); - /** Run the given download and post-download commands using the * standard command-line UI. Runs the preparation routine, the * actual download, and the post-download commands. @@ -444,12 +441,21 @@ namespace aptitude } }; + bool pkgset_from_task(pkgset * const pkgset, string pattern, + GlobalError::MsgType error_type = GlobalError::ERROR); + + /** \brief Fill a pkgset using the given regex to match package + * names. + */ + bool pkgset_from_regex(pkgset * const pkgset, string pattern, + GlobalError::MsgType error_type = GlobalError::ERROR); + /** \brief Fill a pkgset using the given matching pattern. * * This does not try any string as a search pattern, only those * which contain explicit search terms or regex characters. */ - bool pkgset_from_pattern(pkgset *packages, const string &pattern, + bool pkgset_from_pattern(pkgset * const pkgset, string pattern, GlobalError::MsgType error_type = GlobalError::ERROR); /** \brief Fill a pkgset using the given string. If the @@ -461,8 +467,9 @@ namespace aptitude * TODO: Should be replaced with cacheset functions once we have * become more compatible with them. */ - bool pkgset_from_string(pkgset *packages, const string &str, - GlobalError::MsgType error_type = GlobalError::ERROR); + bool pkgset_from_string(pkgset * const pkgset, string str, + GlobalError::MsgType error_type = GlobalError::ERROR, + GlobalError::MsgType pattern_error_type = GlobalError::NOTICE); } } diff --git a/src/cmdline/cmdline_versions.cc b/src/cmdline/cmdline_versions.cc index 57e95d17..ba6df3fa 100644 --- a/src/cmdline/cmdline_versions.cc +++ b/src/cmdline/cmdline_versions.cc @@ -51,6 +51,7 @@ #include <sigc++/bind.h> #include <cwidget/generic/util/ref_ptr.h> +#include <cwidget/generic/util/ssprintf.h> #include <vector> @@ -252,7 +253,7 @@ namespace const shared_ptr<terminal_metrics> &term_metrics, const shared_ptr<terminal_output> &term_output) { - // Set to -1 if any exact-name matches fail. Also set to -1 if + // Set to 100 if any exact-name matches fail. Also set to 1 if // there are no results at all. int return_value = 0; @@ -291,16 +292,16 @@ namespace if(output_size == output.size() && (*pIt)->get_type() == m::pattern::exact_name) { - return_value = 1; - _error->Error(_("No such package \"%s\""), + return_value = 100; + _error->Error(_("Unable to locate package %s"), (*pIt)->get_exact_name_name().c_str()); } } search_progress_display->done(); - if(output.empty()) - return_value = 2; + if(output.empty() && return_value == 0) + return_value = 1; // Decide how and whether to group the results. Not initialized // so the compiler will check that we always assign a value. @@ -388,7 +389,7 @@ namespace break; default: - _error->Error("Internal error: invalid show-package-names option."); + _error->Error("Internal error: invalid show-package-names option"); do_show_package_names = package_names_should_auto_show; break; } @@ -544,12 +545,9 @@ int cmdline_versions(int argc, char *argv[], const char *status_fname, pkg_sortpolicy *sort_policy = parse_sortpolicy(sort); if(!sort_policy) - { - _error->DumpErrors(); - return -1; - } + return 100; - _error->DumpErrors(); + consume_errors(); const unsigned int screen_width = term->get_screen_width(); if(!width.empty()) @@ -563,9 +561,8 @@ int cmdline_versions(int argc, char *argv[], const char *status_fname, if(!cw::util::transcode(display_format.c_str(), wdisplay_format)) { - _error->DumpErrors(); - fprintf(stderr, _("iconv of %s failed.\n"), display_format.c_str()); - return -1; + _error->Error(_("iconv of %s failed"), display_format.c_str()); + return 100; } boost::scoped_ptr<cw::config::column_definition_list> columns; @@ -574,15 +571,12 @@ int cmdline_versions(int argc, char *argv[], const char *status_fname, pkg_item::pkg_columnizer::defaults)); if(columns.get() == NULL) - { - _error->DumpErrors(); - return -1; - } + return 100; if(argc <= 1) { - fprintf(stderr, _("versions: You must provide at least one package selector\n")); - return -1; + _error->Error(_("versions: You must provide at least one package selector")); + return 100; } OpProgress progress; @@ -590,28 +584,34 @@ int cmdline_versions(int argc, char *argv[], const char *status_fname, apt_init(&progress, true, status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; std::vector<cw::util::ref_ptr<m::pattern> > matchers; + bool parsing_arguments_failed = false; + for(int i = 1; i < argc; ++i) { const char * const arg = argv[i]; - cw::util::ref_ptr<m::pattern> m = m::parse(arg); - if(!m.valid()) - { - _error->DumpErrors(); - - return -1; - } - - matchers.push_back(m); + cw::util::ref_ptr<m::pattern> m; + const pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(arg); + if(pkg.end() == false) + m = m::pattern::make_exact_name(pkg.Name()); + else if(m::is_pattern(arg) == true) + m = m::parse(arg); + else + _error->Error(_("Unable to locate package %s"), arg); + + if(m.valid() == false) + parsing_arguments_failed = true; + else + matchers.push_back(m); } + if(parsing_arguments_failed == true) + return 100; + return do_search_versions(matchers, sort_policy, *columns, diff --git a/src/cmdline/cmdline_why.cc b/src/cmdline/cmdline_why.cc index 2fccc43a..402cc272 100644 --- a/src/cmdline/cmdline_why.cc +++ b/src/cmdline/cmdline_why.cc @@ -1355,13 +1355,14 @@ int cmdline_why(int argc, char *argv[], { const shared_ptr<terminal_io> term = create_terminal(); - _error->DumpErrors(); + consume_errors(); if(argc < 2) { - fprintf(stderr, _("%s: this command requires at least one argument (the package to query).\n"), - argv[0]); - return -1; + _error->Error(_("%s: this command requires at least one argument (the" + " package to query)"), + argv[0]); + return 100; } OpProgress progress; @@ -1369,10 +1370,7 @@ int cmdline_why(int argc, char *argv[], apt_init(&progress, true, status_fname); if(_error->PendingError()) - { - _error->DumpErrors(); - return -1; - } + return 100; // Keep track of whether any argument couldn't be parsed, but // don't bail until we finish parsing, so we can display all @@ -1381,10 +1379,10 @@ int cmdline_why(int argc, char *argv[], const char *pkgname = argv[argc - 1]; bool is_removal = is_why_not; - pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(argv[argc - 1]); + pkgCache::PkgIterator pkg = (*apt_cache_file)->FindPkg(pkgname); if(pkg.end()) { - _error->Error(_("No package named \"%s\" exists."), pkgname); + _error->Error(_("Unable to locate package %s"), pkgname); parsing_arguments_failed = true; } @@ -1406,13 +1404,9 @@ int cmdline_why(int argc, char *argv[], matchers.push_back(p); } - - - _error->DumpErrors(); - int rval; if(parsing_arguments_failed) - rval = -1; + rval = 100; else rval = do_why(matchers, pkg, diff --git a/src/generic/apt/download_install_manager.cc b/src/generic/apt/download_install_manager.cc index 9c779f86..7c9aa835 100644 --- a/src/generic/apt/download_install_manager.cc +++ b/src/generic/apt/download_install_manager.cc @@ -39,7 +39,8 @@ using namespace std; download_install_manager::download_install_manager(bool _download_only, const run_dpkg_in_terminal_func &_run_dpkg_in_terminal) - : log(NULL), download_only(_download_only), pm(new pkgDPkgPM(*apt_cache_file)), + : log(NULL), download_only(_download_only), + pm(new pkgDPkgPM(*apt_cache_file)), run_dpkg_in_terminal(_run_dpkg_in_terminal) { } @@ -102,7 +103,7 @@ bool download_install_manager::prepare(OpProgress &progress, download_manager::result download_install_manager::finish_pre_dpkg(pkgAcquire::RunResult res) { - if(res != pkgAcquire::Continue) + if(res == pkgAcquire::Failed) return failure; bool failed=false; @@ -110,15 +111,18 @@ download_manager::result download_install_manager::finish_pre_dpkg(pkgAcquire::R i != fetcher->ItemsEnd(); ++i) { if((*i)->Status == pkgAcquire::Item::StatDone && - (*i)->Complete) + (*i)->Complete == true) continue; if((*i)->Status == pkgAcquire::Item::StatIdle) - continue; + { + // Transient = true; + continue; + } failed=true; - _error->Error(_("Failed to fetch %s: %s"), (*i)->DescURI().c_str(), (*i)->ErrorText.c_str()); - break; + _error->Warning(_("Failed to fetch %s: %s"), + (*i)->DescURI().c_str(), (*i)->ErrorText.c_str()); } if(download_only) @@ -148,13 +152,17 @@ download_manager::result download_install_manager::finish_pre_dpkg(pkgAcquire::R // control the code at dpkg's end), them's the breaks. apt_cache_file->ReleaseLock(); - result rval = success; + download_manager::result rval; const pkgPackageManager::OrderResult pre_fork_result = pm->DoInstallPreFork(); - if(pre_fork_result == pkgPackageManager::Failed) - rval = failure; + switch(pre_fork_result) + { + case pkgPackageManager::Completed: rval = success; break; + case pkgPackageManager::Failed: rval = failure; break; + case pkgPackageManager::Incomplete: rval = do_again; break; + } return rval; } @@ -171,7 +179,7 @@ pkgPackageManager::OrderResult download_install_manager::run_dpkg(int status_fd) switch(pmres) { case pkgPackageManager::Failed: - _error->DumpErrors(); + _error->DumpErrors(std::cerr, GlobalError::WARNING, false); cerr << _("A package failed to install. Trying to recover:") << endl; if(system("DPKG_NO_TSTP=1 dpkg --configure -a") != 0) { /* ignore */ } break; @@ -191,16 +199,15 @@ void download_install_manager::finish_post_dpkg(pkgPackageManager::OrderResult d OpProgress *progress, const sigc::slot1<void, result> &k) { - result rval = success; - + result rval; switch(dpkg_result) { case pkgPackageManager::Failed: rval = failure; break; case pkgPackageManager::Completed: + rval = success; break; - case pkgPackageManager::Incomplete: rval = do_again; break; @@ -208,15 +215,23 @@ void download_install_manager::finish_post_dpkg(pkgPackageManager::OrderResult d fetcher->Shutdown(); + if(_error->PendingError() == true) + rval = failure; + // Get the archives again. This was necessary for multi-CD // installs, according to my comments in an old commit log in the // Subversion repository. - if(!pm->GetArchives(fetcher, &src_list, apt_package_records)) - rval = failure; - else if(!apt_cache_file->GainLock()) + if(rval == do_again) + { + if(!pm->GetArchives(fetcher, &src_list, apt_package_records)) + rval = failure; + } + + if(!apt_cache_file->GainLock()) // This really shouldn't happen. { - _error->Error(_("Could not regain the system lock! (Perhaps another apt or dpkg is running?)")); + _error->Error(_("Could not regain the system lock! (Perhaps another" + " apt or dpkg is running?)")); rval = failure; } @@ -257,7 +272,7 @@ void download_install_manager::finish(pkgAcquire::RunResult result, { const download_manager::result pre_res = finish_pre_dpkg(result); - if(pre_res == success && !download_only) + if(pre_res != failure && !download_only) { run_dpkg_in_terminal(sigc::mem_fun(*this, &download_install_manager::run_dpkg), sigc::bind(sigc::mem_fun(*this, &download_install_manager::finish_post_dpkg), @@ -268,7 +283,6 @@ void download_install_manager::finish(pkgAcquire::RunResult result, else { pkgPackageManager::OrderResult res; - switch(pre_res) { case success: @@ -278,7 +292,6 @@ void download_install_manager::finish(pkgAcquire::RunResult result, res = pkgPackageManager::Incomplete; break; case failure: - default: res = pkgPackageManager::Failed; break; } diff --git a/src/generic/apt/matching/pattern.cc b/src/generic/apt/matching/pattern.cc index 75339e1d..5743a2a7 100644 --- a/src/generic/apt/matching/pattern.cc +++ b/src/generic/apt/matching/pattern.cc @@ -79,9 +79,7 @@ namespace aptitude bool is_pattern(const std::string &s) { - // regex characters are ".?+*|[^$" - // pattern characters are "~?" - return s.find_first_of("~?.?+*|[^$") != s.npos; + return s.find_first_of("~?") != s.npos; } } } diff --git a/src/generic/apt/matching/pattern.h b/src/generic/apt/matching/pattern.h index 96d48550..5aad42f8 100644 --- a/src/generic/apt/matching/pattern.h +++ b/src/generic/apt/matching/pattern.h @@ -2021,8 +2021,8 @@ namespace aptitude * This is used in situations where it would be counterintuitive * for all strings to be treated as search patterns, but where we * want search patterns to be available. Strings are considered - * to be seach patterns if they contain a tilde (~), a question - * mark (?), or any regex characters (.?+*|[^$). + * to be seach patterns if they contain a tilde (~) or a question + * mark (?). * * \return \b true if the string qualifies as a search pattern. */ diff --git a/src/main.cc b/src/main.cc index e7007243..47b305d4 100644 --- a/src/main.cc +++ b/src/main.cc @@ -440,7 +440,9 @@ namespace { // ForTranslators: both the translated and the untranslated // log level names are accepted here. - _error->Error(_("Unknown log level name \"%s\" (expected \"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\", or \"off\")."), + _error->Error(_("Unknown log level name \"%s\" (expected \"trace\"," + " \"debug\", \"info\", \"warn\", \"error\"," + " \"fatal\", or \"off\")."), level_name.c_str()); return; } @@ -449,7 +451,7 @@ namespace if(!targetLogger) { - _error->Error(_("Invalid logger name \"%s\"."), + _error->Error(_("Invalid logger name \"%s\""), logger_name.c_str()); return; } @@ -511,27 +513,6 @@ namespace } } -// Ensure that the cache is always closed when main() exits. Without -// this, there might be dangling flyweights hanging around, and those -// can trigger aborts when the static flyweight pool is destroyed. -// -// TBH, I think it might be worth writing our own flyweight stand-in -// to avoid this particular bit of stupid. On the other hand, it -// might be better to fully shut down the cache all the time, to -// better detect leaks and so on? I'm undecided -- and it shouldn't -// take too long to clear out the cache. -struct close_cache_on_exit -{ - close_cache_on_exit() - { - } - - ~close_cache_on_exit() - { - apt_shutdown(); - } -}; - void do_message_logged(std::ostream &out, const char *sourceFilename, int sourceLineNumber, @@ -628,7 +609,16 @@ int main(int argc, const char *argv[]) const char * const rootdir = getenv("APT_ROOT_DIR"); apt_preinit(rootdir); - close_cache_on_exit close_on_exit; + // Ensure that the cache is always closed when main() exits. Without + // this, there might be dangling flyweights hanging around, and those + // can trigger aborts when the static flyweight pool is destroyed. + // + // TBH, I think it might be worth writing our own flyweight stand-in + // to avoid this particular bit of stupid. On the other hand, it + // might be better to fully shut down the cache all the time, to + // better detect leaks and so on? I'm undecided -- and it shouldn't + // take too long to clear out the cache. + atexit(&apt_shutdown); // NOTE: this can of course be spoofed. Anyone bothering to is off their // rocker. @@ -664,7 +654,7 @@ int main(int argc, const char *argv[]) if(cmdl.Parse(argc, argv) == false) { _error->DumpErrors(); - return 1; + return 100; } if(aptcfg->FindB("help", false) == true) @@ -755,10 +745,10 @@ int main(int argc, const char *argv[]) if(read_user_tag_applications(user_tags) == false) { _error->DumpErrors(); - return 1; + return 100; } - group_by_option group_by_mode; + group_by_option group_by_mode = group_by_auto; try { group_by_mode = parse_group_by_option(group_by_mode_string); @@ -766,10 +756,9 @@ int main(int argc, const char *argv[]) catch(std::exception &ex) { _error->Error("%s", ex.what()); - group_by_mode = group_by_auto; } - show_package_names_option show_package_names_mode; + show_package_names_option show_package_names_mode = show_package_names_auto; if(show_package_names_mode_string == "never" || show_package_names_mode_string == P_("--show-package-names|never")) show_package_names_mode = show_package_names_never; @@ -780,14 +769,11 @@ int main(int argc, const char *argv[]) show_package_names_mode_string == P_("--show-package-names|always")) show_package_names_mode = show_package_names_always; else - { - _error->Error("%s", - (boost::format(_("Invalid package names display mode \"%s\" (should be \"never\", \"auto\", or \"always\").")) - % show_package_names_mode_string).str().c_str()); - show_package_names_mode = show_package_names_auto; - } + _error->Error(_("Invalid package names display mode \"%s\" (should be" + " \"never\", \"auto\", or \"always\")."), + show_package_names_mode_string.c_str()); - aptitude::why::roots_string_mode why_display_mode; + aptitude::why::roots_string_mode why_display_mode = aptitude::why::no_summary; if(show_why_summary_mode == "no-summary" || show_why_summary_mode == _("no-summary")) why_display_mode = aptitude::why::no_summary; else if(show_why_summary_mode == "first-package" || show_why_summary_mode == _("first-package")) @@ -799,13 +785,13 @@ int main(int argc, const char *argv[]) else if(show_why_summary_mode == "all-packages-with-dep-versions" || show_why_summary_mode == _("all-packages-with-dep-versions")) why_display_mode = aptitude::why::show_chain_with_versions; else - { - // ForTranslators: "why" here is the aptitude command name and - // should not be translated. - _error->Error(_("Invalid \"why\" summary mode \"%s\": expected \"no-summary\", \"first-package\", \"first-package-and-type\", \"all-packages\", or \"all-packages-with-dep-versions\"."), - show_why_summary_mode.c_str()); - why_display_mode = aptitude::why::no_summary; - } + // ForTranslators: "why" here is the aptitude command name and + // should not be translated. + _error->Error(_("Invalid \"why\" summary mode \"%s\": expected" + " \"no-summary\", \"first-package\"," + " \"first-package-and-type\", \"all-packages\"," + " or \"all-packages-with-dep-versions\"."), + show_why_summary_mode.c_str()); apply_config_file_logging_levels(aptcfg); @@ -840,28 +826,21 @@ int main(int argc, const char *argv[]) ++num_startup_actions; if(num_startup_actions > 1) - { - fprintf(stderr, "%s", - _("Only one of --auto-clean-on-startup, --clean-on-startup, -i, and -u may be specified\n")); - usage(); - exit(1); - } + _error->Error(_("Only one of --auto-clean-on-startup," + " --clean-on-startup, -i, and -u may be specified")); } if((update_only || install_only || autoclean_only || clean_only) && cmdline_mode == true) - { - fprintf(stderr, "%s\n", - _("-u, -i, and --clean-on-startup may not be specified in command-line mode (eg, with 'install')")); - usage(); - exit(1); - } + _error->Error(_("-u, -i, --clean-on-startup, and --autoclean-on-startup" + " may not be specified in command-line mode (eg, with" + " 'install')")); // Abort now if there were any errors. if(_error->PendingError() == true) { _error->DumpErrors(); - return 1; + return 100; } _error->MergeWithStack(); @@ -869,44 +848,41 @@ int main(int argc, const char *argv[]) // Possibly run off and do other commands. if(cmdline_mode == true) { + using namespace aptitude::cmdline; + try { // Connect up the "please consume errors" routine for the // command-line. - consume_errors.connect(sigc::mem_fun(_error, (void (GlobalError::*)()) &GlobalError::DumpErrors)); - - if(update_only || install_only || autoclean_only || clean_only) - { - fprintf(stderr, "%s\n", - _("-u, -i, and --clean-on-startup may not be specified with a command")); - usage(); - exit(1); - } + consume_errors.connect( + sigc::mem_fun(_error, + (void (GlobalError::*)()) &GlobalError::PushToStack)); int filec = cmdl.FileSize(); char **filev = const_cast<char **>(cmdl.FileList); + int rval = 0; // TODO: warn the user if they passed --full-resolver to // something other than "upgrade" or do_action. if(!strcasecmp(filev[0], "update")) - return cmdline_update(filec, filev, verbose); + rval = cmdline_update(filec, filev, verbose); else if(!strcasecmp(filev[0], "clean")) - return cmdline_clean(filec, filev, simulate); + rval = cmdline_clean(filec, filev, simulate); else if(!strcasecmp(filev[0], "autoclean")) - return cmdline_autoclean(filec, filev, simulate); + rval = cmdline_autoclean(filec, filev, simulate); else if(!strcasecmp(filev[0], "forget-new")) - return cmdline_forget_new(filec, filev, + rval = cmdline_forget_new(filec, filev, status_fname, simulate); else if(!strcasecmp(filev[0], "search")) - return cmdline_search(filec, filev, + rval = cmdline_search(filec, filev, status_fname, package_display_format, width, sort_policy, disable_columns, debug_search); else if(!strcasecmp(filev[0], "versions")) - return cmdline_versions(filec, filev, + rval = cmdline_versions(filec, filev, status_fname, version_display_format, width, sort_policy, @@ -915,11 +891,11 @@ int main(int argc, const char *argv[]) group_by_mode, show_package_names_mode); else if(!strcasecmp(filev[0], "why")) - return cmdline_why(filec, filev, + rval = cmdline_why(filec, filev, status_fname, verbose, why_display_mode, false); else if(!strcasecmp(filev[0], "why-not")) - return cmdline_why(filec, filev, + rval = cmdline_why(filec, filev, status_fname, verbose, why_display_mode, true); else if( (!strcasecmp(filev[0], "install")) || @@ -939,71 +915,75 @@ int main(int argc, const char *argv[]) (!strcasecmp(filev[0], "keep-all")) || (!strcasecmp(filev[0], "build-dep")) || (!strcasecmp(filev[0], "build-depends"))) - { - return cmdline_do_action(filec, filev, - status_fname, - simulate, assume_yes, download_only, - fix_broken, showvers, showdeps, - showsize, showwhy, - visual_preview, always_prompt, - resolver_mode, safe_resolver_show_resolver_actions, - safe_resolver_no_new_installs, safe_resolver_no_new_upgrades, - user_tags, - arch_only, queue_only, verbose); - } + rval = cmdline_do_action(filec, filev, + status_fname, + simulate, assume_yes, download_only, + fix_broken, showvers, showdeps, + showsize, showwhy, + visual_preview, always_prompt, + resolver_mode, safe_resolver_show_resolver_actions, + safe_resolver_no_new_installs, safe_resolver_no_new_upgrades, + user_tags, + arch_only, queue_only, verbose); else if(!strcasecmp(filev[0], "add-user-tag") || !strcasecmp(filev[0], "remove-user-tag")) - return aptitude::cmdline::cmdline_user_tag(filec, filev, - quiet, verbose); + rval = cmdline_user_tag(filec, filev, + quiet, verbose); else if(!strcasecmp(filev[0], "extract-cache-subset")) - return aptitude::cmdline::extract_cache_subset(filec, - filev); + rval = extract_cache_subset(filec, filev); else if(!strcasecmp(filev[0], "download")) - return cmdline_download(filec, filev); + rval = cmdline_download(filec, filev); else if(!strcasecmp(filev[0], "changelog")) - return cmdline_changelog(filec, filev); + rval = cmdline_changelog(filec, filev); else if(!strcasecmp(filev[0], "moo")) - return cmdline_moo(filec, filev, verbose); + rval = cmdline_moo(filec, filev, verbose); else if(!strcasecmp(filev[0], "show")) - return cmdline_show(filec, filev, verbose); + rval = cmdline_show(filec, filev, verbose); else if(!strcasecmp(filev[0], "dump-resolver")) - return cmdline_dump_resolver(filec, filev, status_fname); + rval = cmdline_dump_resolver(filec, filev, status_fname); else if(!strcasecmp(filev[0], "check-resolver")) - return cmdline_check_resolver(filec, filev, status_fname); + rval = cmdline_check_resolver(filec, filev, status_fname); else if(!strcasecmp(filev[0], "help")) - { - usage(); - exit(0); - } + usage(); // Debugging/profiling commands: else if(!strcasecmp(filev[0], "nop")) { OpTextProgress p(aptcfg->FindI("Quiet", 0)); - _error->DumpErrors(); apt_init(&p, true); - exit(0); } else if(!strcasecmp(filev[0], "nop-noselections")) { OpTextProgress p(aptcfg->FindI("Quiet", 0)); - _error->DumpErrors(); apt_init(&p, false); - exit(0); } else if(!strcasecmp(filev[0], "dump-config")) { OpTextProgress p(aptcfg->FindI("Quiet", 0)); apt_init(&p, false); _config->Dump(std::cout); - _error->DumpErrors(); - exit(0); } else { - fprintf(stderr, _("Unknown command \"%s\"\n"), filev[0]); - usage(); - exit(1); + _error->Error(_("Unknown command \"%s\""), filev[0]); + rval = 100; } + + while(_error->StackCount() > 0) + _error->MergeWithStack(); + + if(_error->PendingError() == true && rval == 0) + rval = 100; + + // Do not dump errors if user aborted. + if(rval == 1) + return rval; + + if(aptcfg->FindI("quiet", 0) > 0) + _error->DumpErrors(); + else + _error->DumpErrors(GlobalError::DEBUG); + + return rval; } catch(StdinEOFException) { @@ -1017,7 +997,7 @@ int main(int argc, const char *argv[]) std::string backtrace = e.get_backtrace(); if(!backtrace.empty()) fprintf(stderr, _("Backtrace:\n%s\n"), backtrace.c_str()); - return -1; + return 100; } } @@ -1103,11 +1083,11 @@ int main(int argc, const char *argv[]) if(!backtrace.empty()) fprintf(stderr, _("Backtrace:\n%s\n"), backtrace.c_str()); - return -1; + return 100; } - // The cache is closed when the close_on_exit object declared - // above is destroyed. + // The cache is closed by apt_shutdown, which was registered + // earlier with atexit(3). return 0; } @@ -1257,7 +1257,8 @@ namespace void install_or_remove_packages() { boost::shared_ptr<download_install_manager> m = - boost::make_shared<download_install_manager>(false, sigc::ptr_fun(&run_dpkg_with_cwidget_suspended)); + boost::make_shared<download_install_manager>(false, + sigc::ptr_fun(&run_dpkg_with_cwidget_suspended)); m->post_forget_new_hook.connect(package_states_changed.make_slot()); |