[Aptitude-svn-commit] r3659 - in branches/aptitude-0.3/aptitude: .
src/generic
Daniel Burrows
dburrows at costa.debian.org
Thu Jul 21 19:07:01 UTC 2005
Author: dburrows
Date: Thu Jul 21 19:06:56 2005
New Revision: 3659
Added:
branches/aptitude-0.3/aptitude/src/generic/tags.cc
branches/aptitude-0.3/aptitude/src/generic/tags.h
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/generic/Makefile.am
branches/aptitude-0.3/aptitude/src/generic/apt.cc
Log:
Debtags implementation.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Thu Jul 21 19:06:56 2005
@@ -1,5 +1,9 @@
2005-07-21 Daniel Burrows <dburrows at debian.org>
+ * src/generic/Makefile.am, src/generic/apt.cc, src/generic/tags.cc, src/generic/tags.h:
+
+ Add backend support for parsing the new tag database.
+
* src/generic/tasks.cc, src/generic/apt.h:
Lift the stuff to order versions by their file location
Modified: branches/aptitude-0.3/aptitude/src/generic/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/Makefile.am (original)
+++ branches/aptitude-0.3/aptitude/src/generic/Makefile.am Thu Jul 21 19:06:56 2005
@@ -40,6 +40,8 @@
pkg_hier.cc \
rev_dep_iterator.h \
strhash.h \
+ tags.h \
+ tags.cc \
tasks.h \
tasks.cc \
undo.h \
Modified: branches/aptitude-0.3/aptitude/src/generic/apt.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/apt.cc (original)
+++ branches/aptitude-0.3/aptitude/src/generic/apt.cc Thu Jul 21 19:06:56 2005
@@ -26,6 +26,7 @@
#include "config_signal.h"
#include "pkg_hier.h"
#include "rev_dep_iterator.h"
+#include "tags.h"
#include "tasks.h"
#include "undo.h"
@@ -249,6 +250,7 @@
apt_undos->clear_items();
load_tasks(*progress_bar);
+ load_tags(*progress_bar);
if(user_pkg_hier)
{
Added: branches/aptitude-0.3/aptitude/src/generic/tags.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/generic/tags.cc Thu Jul 21 19:06:56 2005
@@ -0,0 +1,214 @@
+// tags.cc
+//
+// Copyright (C) 2005 Daniel Burrows
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program 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; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include "tags.h"
+
+#include "../aptitude.h"
+
+#include "apt.h"
+
+#include <utility>
+
+#include <ctype.h>
+#include <string.h>
+
+#include <sigc++/functors/mem_fun.h>
+
+#include <apt-pkg/pkgrecords.h>
+#include <apt-pkg/tagfile.h>
+
+using namespace std;
+
+// NB: this does the wrong thing if spaces occur within a tag (they
+// generate a new hierarchy level), but such tags are invalid anyway.
+tag::const_iterator &tag::const_iterator::operator++()
+{
+ start = finish;
+ while(start != limit && (isspace(*start) || (*start)==':'))
+ ++start;
+
+ if(start == limit)
+ finish = limit;
+ else
+ {
+ finish = start+1;
+ while(finish != limit && !(isspace(*finish) || (*finish) == ':'))
+ ++finish;
+ }
+
+ return *this;
+}
+
+tag::const_iterator tag::begin() const
+{
+ tag::const_iterator rval(start, start, finish);
+
+ ++rval;
+
+ return rval;
+}
+
+int tag::cmp(const tag &other) const
+{
+ const_iterator myT=begin(), otherT=other.begin();
+
+ while(myT != end() && otherT != other.end())
+ {
+ // avoid operator* and its concomitant copies
+ size_t myN=myT.finish-myT.start;
+ size_t otherN=otherT.finish-otherT.start;
+
+ int res = strncmp(myT.start, otherT.start, min(myN, otherN));
+
+ // If there was a difference, break out.
+ if(res != 0)
+ return res;
+ else if(myN<otherN)
+ return -1;
+ else if(myN>otherN)
+ return 1;
+
+ ++myT;
+ ++otherT;
+ }
+
+ if(otherT != end())
+ return -1;
+ else if(myT != end())
+ return 1;
+ else
+ return 0;
+}
+
+tag_list::const_iterator &tag_list::const_iterator::operator++()
+{
+ start = finish;
+
+ while(start != limit && (*start) != ',')
+ ++start;
+
+ if(start != limit) // Push past the comma.
+ ++start;
+
+ if(start == limit)
+ finish = limit;
+ else
+ {
+ // Eat everything up to the next comma.
+ finish = start+1;
+ while(finish != limit && (*finish) != ',')
+ ++finish;
+ }
+
+ return *this;
+}
+
+tag_list::const_iterator tag_list::begin() const
+{
+ const_iterator rval(start, start, finish);
+ ++rval;
+ return rval;
+}
+
+typedef set<tag> db_entry;
+
+// The database is built eagerly, since the common use case is
+// to scan everything in sight right away and this makes it easy
+// to provide a progress bar to the user.
+db_entry *tagDB;
+
+static void insert_tags(const pkgCache::VerIterator &ver,
+ const pkgCache::VerFileIterator &vf)
+{
+ set<tag> *tags = tagDB + ver.ParentPkg()->ID;
+
+ const char *recstart=0, *recend=0;
+ const char *tagstart, *tagend;
+ pkgTagSection sec;
+
+ assert(apt_package_records);
+ assert(tagDB);
+
+ apt_package_records->Lookup(vf).GetRec(recstart, recend);
+ if(!recstart || !recend)
+ return;
+ if(!sec.Scan(recstart, recend-recstart))
+ return;
+
+ if(!sec.Find("Tag", tagstart, tagend))
+ return;
+
+ tag_list lst(tagstart, tagend);
+
+ for(tag_list::const_iterator t=lst.begin(); t!=lst.end(); ++t)
+ tags->insert(*t);
+}
+
+static void reset_tags()
+{
+ delete[] tagDB;
+ tagDB = NULL;
+}
+
+const set<tag> *get_tags(const pkgCache::PkgIterator &pkg)
+{
+ if(!apt_cache_file || !tagDB)
+ return NULL;
+
+ return tagDB + pkg->ID;
+}
+
+bool initialized_reset_signal;
+void load_tags(OpProgress &progress)
+{
+ assert(apt_cache_file && apt_package_records);
+
+ if(!initialized_reset_signal)
+ {
+ cache_closed.connect(sigc::ptr_fun(reset_tags));
+ cache_reload_failed.connect(sigc::ptr_fun(reset_tags));
+ initialized_reset_signal = true;
+ }
+
+ tagDB = new db_entry[(*apt_cache_file)->Head().PackageCount];
+
+ std::vector<loc_pair> verfiles;
+
+ for(pkgCache::PkgIterator p = (*apt_cache_file)->PkgBegin();
+ !p.end(); ++p)
+ for(pkgCache::VerIterator v = p.VersionList(); !v.end(); ++v)
+ for(pkgCache::VerFileIterator vf = v.FileList();
+ !vf.end(); ++vf)
+ verfiles.push_back(loc_pair(v, vf));
+
+ sort(verfiles.begin(), verfiles.end(), location_compare());
+
+ progress.OverallProgress(0, verfiles.size(), 1,
+ _("Building tag database"));
+ size_t n=0;
+ for(std::vector<loc_pair>::iterator i=verfiles.begin();
+ i!=verfiles.end(); ++i)
+ {
+ insert_tags(i->first, i->second);
+ ++n;
+ progress.OverallProgress(n, verfiles.size(), 1, _("Building tag database"));
+ }
+
+ progress.Done();
+}
Added: branches/aptitude-0.3/aptitude/src/generic/tags.h
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/generic/tags.h Thu Jul 21 19:06:56 2005
@@ -0,0 +1,191 @@
+// tags.h -*-c++-*-
+//
+// Copyright (C) 2005 Daniel Burrows
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program 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; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+//
+// A parser for tags.
+
+#ifndef TAGS_H
+#define TAGS_H
+
+#include <set>
+#include <string>
+
+#include <apt-pkg/pkgcache.h>
+
+class OpProgress;
+
+class tag
+{
+ const char *start, *finish;
+
+ int cmp(const tag &other) const;
+public:
+ class const_iterator
+ {
+ const char *start, *finish, *limit;
+
+ friend class tag;
+ public:
+ const_iterator(const char *_start, const char *_finish,
+ const char *_limit)
+ :start(_start), finish(_finish), limit(_limit)
+ {
+ }
+
+ const_iterator &operator++();
+
+ const_iterator &operator=(const const_iterator &other)
+ {
+ start = other.start;
+ finish = other.finish;
+ limit = other.limit;
+
+ return *this;
+ }
+
+ bool operator==(const const_iterator &other) const
+ {
+ return start == other.start && finish == other.finish && limit == other.limit;
+ }
+
+ bool operator!=(const const_iterator &other) const
+ {
+ return start != other.start || finish != other.finish || limit != other.limit;
+ }
+
+ std::string operator*() const
+ {
+ return std::string(start, finish-start);
+ }
+ };
+
+ tag(const char *_start, const char *_finish)
+ :start(_start), finish(_finish)
+ {
+ }
+
+ tag &operator=(const tag &other)
+ {
+ start = other.start;
+ finish = other.finish;
+
+ return *this;
+ }
+
+ bool operator<(const tag &other) const
+ {
+ return cmp(other) < 0;
+ }
+
+ bool operator<=(const tag &other) const
+ {
+ return cmp(other) < 0;
+ }
+
+ bool operator==(const tag &other) const
+ {
+ return cmp(other) == 0;
+ }
+
+ bool operator!=(const tag &other) const
+ {
+ return cmp(other) != 0;
+ }
+
+ bool operator>(const tag &other) const
+ {
+ return cmp(other) == 0;
+ }
+
+ bool operator>=(const tag &other) const
+ {
+ return cmp(other) == 0;
+ }
+
+ const_iterator begin() const;
+ const_iterator end() const
+ {
+ return const_iterator(finish, finish, finish);
+ }
+};
+
+class tag_list
+{
+ const char *start, *finish;
+public:
+ class const_iterator
+ {
+ const char *start, *finish, *limit;
+ public:
+ const_iterator(const char *_start, const char *_finish,
+ const char *_limit)
+ :start(_start), finish(_finish), limit(_limit)
+ {
+ }
+
+ const_iterator operator=(const const_iterator &other)
+ {
+ start = other.start;
+ finish = other.finish;
+ limit = other.limit;
+
+ return *this;
+ }
+
+ bool operator==(const const_iterator &other)
+ {
+ return other.start == start && other.finish == finish && other.limit == limit;
+ }
+
+ bool operator!=(const const_iterator &other)
+ {
+ return other.start != start || other.finish != finish || other.limit != limit;
+ }
+
+ const_iterator &operator++();
+
+ tag operator*()
+ {
+ return tag(start, finish);
+ }
+ };
+
+ tag_list(const char *_start, const char *_finish)
+ :start(_start), finish(_finish)
+ {
+ }
+
+ tag_list &operator=(const tag_list &other)
+ {
+ start = other.start;
+ finish = other.finish;
+
+ return *this;
+ }
+
+ const_iterator begin() const;
+ const_iterator end() const {return const_iterator(finish, finish, finish);}
+};
+
+// Grab the tags for the given package:
+const std::set<tag> *get_tags(const pkgCache::PkgIterator &pkg);
+
+// Load tags for all packages (call before get_tags)
+void load_tags(OpProgress &progress);
+
+#endif
More information about the Aptitude-svn-commit
mailing list