Just noticed I forgot to strip some of the references to 'max-levels' out of
the documentation updates in patch.subdirs
Here's an updated patch...
diff -Naur aptitude.orig/doc/en/aptitude.xml
aptitude.subdirs/doc/en/aptitude.xml
--- aptitude.orig/doc/en/aptitude.xml 2007-12-19 12:53:15.000000000 -0500
+++ aptitude.subdirs/doc/en/aptitude.xml 2007-12-20 10:34:45.000000000
-0500
@@ -5357,7 +5357,8 @@
<para>
Group based on the whole Section field, so
categories like <quote>non-free/games</quote> will be
- created.
+ created. This is the default if no
+ <replaceable>mode</replaceable> is specified.
</para>
</listitem>
</varlistentry>
@@ -5367,10 +5368,11 @@
<listitem>
<para>
- Group based on the part of the Section field
- before the <quote><literal>/</literal></quote>; if
there is
- no <literal>/</literal>,
- <literal>main</literal> will be used instead.
+ Group based on the part of the Section field before the
+ first <literal>/</literal> character; if there is no
+ <literal>/</literal>,
+ <quote><literal>main</literal></quote> will be used
+ instead.
</para>
</listitem>
</varlistentry>
@@ -5380,10 +5382,23 @@
<listitem>
<para>
- Group based on the part of the Section field
- after the <quote><literal>/</literal></quote>; if there
is
- no <literal>/</literal>, the entire field will
- be used.
+ Group based on the part of the Section field after the
+ first <literal>/</literal> character; if there is no
+ <literal>/</literal>, the entire field will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>subdirs</literal></term>
+
+ <listitem>
+ <para>
+ Group based on the part of the Section field after the
+ first <literal>/</literal> character; if there is no
+ <literal>/</literal>, the entire field will be used; if
+ there are multiple <literal>/</literal> characters,
+ a hierarchy of groups will be formed.
</para>
</listitem>
</varlistentry>
diff -Naur aptitude.orig/src/load_grouppolicy.cc
aptitude.subdirs/src/load_grouppolicy.cc
--- aptitude.orig/src/load_grouppolicy.cc 2007-12-19 12:53:19.000000000
-0500
+++ aptitude.subdirs/src/load_grouppolicy.cc 2007-12-20 10:33:31.000000000
-0500
@@ -364,8 +364,10 @@
split_mode=pkg_grouppolicy_section_factory::split_topdir;
else if(!strcasecmp(args[0].c_str(), "subdir"))
split_mode=pkg_grouppolicy_section_factory::split_subdir;
+ else if(!strcasecmp(args[0].c_str(), "subdirs"))
+ split_mode=pkg_grouppolicy_section_factory::split_subdirs;
else
- throw GroupParseException(_("Bad section name '%s' (use 'none',
'topdir', or 'subdir')"), args[0].c_str());
+ throw GroupParseException(_("Bad section name '%s' (use 'none',
'topdir', 'subdir', or 'subdirs')"), args[0].c_str());
}
if(args.size() >= 2)
diff -Naur aptitude.orig/src/pkg_grouppolicy.cc
aptitude.subdirs/src/pkg_grouppolicy.cc
--- aptitude.orig/src/pkg_grouppolicy.cc 2007-12-19 12:53:19.000000000
-0500
+++ aptitude.subdirs/src/pkg_grouppolicy.cc 2007-12-20 10:33:31.000000000
-0500
@@ -213,81 +213,95 @@
void pkg_grouppolicy_section::add_package(const pkgCache::PkgIterator &pkg,
pkg_subtree *root)
{
- const char *section=pkg.VersionList().Section();
- const char *name=pkg.Name();
- bool maypassthrough=false; // FIXME: HACK!
-
- if(name[0] == 't' && name[1] == 'a' && name[2] == 's' && name[3] == 'k' &&
name[4] == '-')
+ // Determine Section
+ string section;
+ if(!strncmp(pkg.Name(), "task-", 5))
+ section=_("Tasks");
+ else if(pkg.VersionList().end())
+ section=_("virtual");
+ else if(!pkg.VersionList().Section())
+ section=_("Unknown");
+ else
{
- maypassthrough=true;
-
section=split_mode!=pkg_grouppolicy_section_factory::split_none?_("Tasks/Tasks"):_("Tasks");
- }
+ section=pkg.VersionList().Section();
- if(!section)
- {
- maypassthrough=true;
-
section=split_mode!=pkg_grouppolicy_section_factory::split_none?_("Unknown/Unknown"):_("Unknown");
+ // Split Section based on split_mode
+ string::size_type first_split=section.find('/');
+ if(split_mode==pkg_grouppolicy_section_factory::split_topdir)
+
section=(first_split!=section.npos?section.substr(0,first_split):_("main"));
+ else if((split_mode==pkg_grouppolicy_section_factory::split_subdir ||
+ split_mode==pkg_grouppolicy_section_factory::split_subdirs) &&
+ first_split!=section.npos)
+ section=section.substr(first_split+1);
}
- if(pkg.VersionList().end())
+ // Pass Through, if necessary
+ if(passthrough &&
+ ((!section.compare(_("Tasks"))) ||
+ (!section.compare(_("virtual"))) ||
+ (!section.compare(_("Unknown")))))
{
- maypassthrough=true;
-
section=split_mode!=pkg_grouppolicy_section_factory::split_none?_("virtual/virtual"):_("virtual");
+ if(sections.find(section)==sections.end())
+ sections[section].first=chain->instantiate(get_sig(), get_desc_sig());
+ sections[section].first->add_package(pkg, root);
}
- const char *split=strchr(section, '/');
- const char *subdir=split?split+1:section;
-
- string tag;
-
- if(split_mode==pkg_grouppolicy_section_factory::split_none)
- tag=section;
- else if(split_mode==pkg_grouppolicy_section_factory::split_topdir)
- tag=(split?string(section,split-section):string(_("main")));
- else if(split_mode==pkg_grouppolicy_section_factory::split_subdir)
- tag=subdir;
-
- section_map::iterator found=sections.find(tag);
-
- if(maypassthrough && passthrough)
- {
- if(found==sections.end())
- sections[tag].first=chain->instantiate(get_sig(), get_desc_sig());
-
- sections[tag].first->add_package(pkg, root);
- }
+ // Add Package to Tree
else
{
- if(found==sections.end())
+ pkg_subtree *current_root=root;
+ string section_id;
+ string sections_remaining=section;
+ bool done=false;
+ do
{
- pkg_subtree *newtree;
- string realtag=tag;
-
- // Go by the last element of the section for multi-level sections.
- if(tag.find('/')!=tag.npos)
- realtag=string(tag, tag.rfind('/')+1);
+ if(split_mode==pkg_grouppolicy_section_factory::split_subdirs)
+ {
+ string::size_type next_split=sections_remaining.find('/',1);
+ section_id.append(sections_remaining.substr(0,next_split));
+
section=(sections_remaining.at(0)=='/'?sections_remaining.substr(1,next_split):sections_remaining.substr(0,next_split));
+ if(next_split==sections_remaining.npos)
+ done = true;
+ else
+ sections_remaining=sections_remaining.substr(next_split);
+ }
+ else
+ {
+ section_id=section;
+ done = true;
+ }
- if(section_descriptions.find(realtag)!=section_descriptions.end())
+ section_map::iterator found=sections.find(section_id);
+ if(found==sections.end())
{
- wstring desc=section_descriptions[realtag];
+ string section_tail=section;
+ pkg_subtree *newtree;
- if(desc.find(L'\n')!=desc.npos)
- newtree=new pkg_subtree(cw::util::transcode(tag)+L" -
"+wstring(desc, 0, desc.find('\n')),
- desc,
- get_desc_sig());
+ // Go by the last element of the section for multi-level sections.
+ string::size_type last_split=section.rfind('/');
+ if(last_split!=section.npos)
+ section_tail=section.substr(last_split+1);
+
+
if(section_descriptions.find(section_tail)!=section_descriptions.end())
+ {
+ wstring desc=section_descriptions[section_tail];
+ if(desc.find(L'\n')!=desc.npos)
+ newtree=new pkg_subtree(cw::util::transcode(section)+L" -
"+wstring(desc, 0, desc.find('\n')), desc, get_desc_sig());
+ else
+ newtree=new pkg_subtree(cw::util::transcode(section)+desc);
+ }
else
- newtree=new pkg_subtree(cw::util::transcode(tag)+desc);
- }
- else
- newtree=new pkg_subtree(cw::util::transcode(tag));
+ newtree=new pkg_subtree(cw::util::transcode(section));
- sections[tag].first=chain->instantiate(get_sig(), get_desc_sig());
- sections[tag].second=newtree;
+ sections[section_id].first=chain->instantiate(get_sig(),
get_desc_sig());
+ sections[section_id].second=newtree;
- root->add_child(newtree);
- }
+ current_root->add_child(newtree);
+ }
+ current_root=sections[section_id].second;
+ } while(!done);
- sections[tag].first->add_package(pkg, sections[tag].second);
+ sections[section_id].first->add_package(pkg,
sections[section_id].second);
}
}
diff -Naur aptitude.orig/src/pkg_grouppolicy.h
aptitude.subdirs/src/pkg_grouppolicy.h
--- aptitude.orig/src/pkg_grouppolicy.h 2007-12-19 12:53:19.000000000 -0500
+++ aptitude.subdirs/src/pkg_grouppolicy.h 2007-12-20 10:33:31.000000000
-0500
@@ -117,12 +117,16 @@
bool passthrough;
public:
// How to split the 'section' value:
- static const int split_none=0;
// Don't. This gives you names like "games" and "non-free/editors".
+ static const int split_none=0;
+ // Split it and keep the first part (adding an implied "main" to
+ // packages without a first part). So you get "main", "non-free", etc.
static const int split_topdir=1;
- // Split it and keep the top-level half (adding an implied "main" to
- // packages without a first half). So you get "main", "non-free", etc.
+ // Split it and keep the second part. So you get "games", "editors", etc.
static const int split_subdir=2;
+ // Split the second part, and, in a single policy, build multiple layers of
+ // subtrees as needed.
+ static const int split_subdirs=3;
pkg_grouppolicy_section_factory(int _split_mode,
bool _passthrough,