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,

Reply via email to