OSDN Git Service

Fix error in counting of catalogue files during loading.
[mingw/mingw-get.git] / src / pkgbind.cpp
index f6066c6..2f55fde 100644 (file)
@@ -4,7 +4,7 @@
  * $Id$
  *
  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, 2010, 2011, MinGW Project
+ * Copyright (C) 2009, 2010, 2011, 2012, MinGW.org Project
  *
  *
  * Implementation of repository binding for the pkgXmlDocument class.
@@ -40,6 +40,9 @@ class pkgRepository
    * of package lists, from any specified repository.
    */
   public:
+    static void Reset( void ){ count = total = 0; }
+    static void IncrementTotal( void ){ ++total; }
+
     pkgRepository( pkgXmlDocument*, pkgXmlNode*, pkgXmlNode*, bool );
     ~pkgRepository(){};
 
@@ -50,9 +53,16 @@ class pkgRepository
     pkgXmlNode *dbase;
     pkgXmlNode *repository;
     pkgXmlDocument *owner;
+    static int count, total;
     bool force_update;
 };
 
+/* Don't forget that we MUST explicitly allocate static storage for
+ * static property values declared within the pkgRepository class.
+ */
+int pkgRepository::count;
+int pkgRepository::total;
+
 pkgRepository::pkgRepository
 /*
  * Constructor...
@@ -74,16 +84,57 @@ void pkgRepository::GetPackageList( const char *dname )
     const char *dfile;
     if( (dfile = xmlfile( dname )) != NULL )
     {
+      /* We've identified a further "package-list" file; update the
+       * count of such files processed, to include this one.
+       */
+      ++count;
+
       /* Check for a locally cached copy of the "package-list" file...
        */
+      const char *mode = "Loading";
+      const char *fmt = "%s catalogue: %s.xml; (item %d of %d)\n";
       if( force_update || (access( dfile, F_OK ) != 0) )
       {
        /* When performing an "update", or if no local copy is available...
         * Force a "sync", to fetch a copy from the public host.
         */
-       dmh_printf( "Update catalogue: %s.xml\n", dname );
+       const char *mode = force_update ? "Updating" : "Downloading";
+       if( owner->ProgressMeter() != NULL )
+         /*
+          * Progress of the "update" is being metered; annotate the
+          * metering display accordingly...
+          */
+         owner->ProgressMeter()->Annotate( fmt, mode, dname, count, total );
+
+       else
+         /* Progress is not being explicitly metered, but the user
+          * may still appreciate a minimal progress report...
+          */
+         dmh_printf( fmt, mode, dname, count, total );
+
+       /* During the actual fetch, collect any generated diagnostics
+        * for the current catalogue file into a message digest, so
+        * that the GUI may present them in a single message box.
+        */
+       dmh_control( DMH_BEGIN_DIGEST );
        owner->SyncRepository( dname, repository );
       }
+      else if( owner->ProgressMeter() != NULL )
+       /*
+        * This is a simple request to load a local copy of the
+        * catalogue file; progress metering is in effect, so we
+        * annotate the metering display accordingly...
+        */
+       owner->ProgressMeter()->Annotate( fmt, mode, dname, count, total );
+
+      else if( pkgOptions()->Test( OPTION_VERBOSE ) > 1 )
+       /*
+        * Similarly, this is a request to load a local copy of
+        * the catalogue; progress metering is not in effect, but
+        * the user has requested verbose diagnostics, so issue
+        * a diagnostic progress report.
+        */
+       dmh_printf( fmt, mode, dname, count, total );
 
       /* We SHOULD now have a locally cached copy of the package-list;
        * attempt to merge it into the active profile database...
@@ -94,8 +145,6 @@ void pkgRepository::GetPackageList( const char *dname )
        /* We successfully loaded the XML catalogue; refer to its
         * root element...
         */
-       if( pkgOptions()->Test( OPTION_VERBOSE ) > 1 )
-         dmh_printf( "Load catalogue: %s.xml\n", dname );
        pkgXmlNode *catalogue, *pkglist;
        if( (catalogue = merge.GetRoot()) != NULL )
        {
@@ -118,7 +167,31 @@ void pkgRepository::GetPackageList( const char *dname )
          /* Recursively incorporate any additional package lists,
           * which may be specified within the current catalogue...
           */
-         GetPackageList( catalogue->FindFirstAssociate( package_list_key ) );
+         catalogue = catalogue->FindFirstAssociate( package_list_key );
+         if( (pkglist = catalogue) != NULL )
+           do {
+                /* ...updating the total catalogue reference count,
+                 * to include all extra catalogue files specified.
+                 */
+                ++total;
+                pkglist = pkglist->FindNextAssociate( package_list_key );
+              } while( pkglist != NULL );
+
+         /* Flush any message digest which has been accumulated
+          * for the last catalogue processed...
+          */
+         dmh_control( DMH_END_DIGEST );
+         if( owner->ProgressMeter() != NULL )
+         {
+           /* ...and update the progress meter display, if any,
+            * to reflect current progress.
+            */
+           owner->ProgressMeter()->SetRange( 0, total );
+           owner->ProgressMeter()->SetValue( count );
+         }
+         /* Proceed to process the embedded catalogues.
+          */
+         GetPackageList( catalogue );
        }
       }
       else
@@ -135,6 +208,10 @@ void pkgRepository::GetPackageList( const char *dname )
       free( (void *)(dfile) );
     }
   }
+  /* Ensure that any accumulated diagnostics, pertaining to catalogue
+   * processing, have been displayed before wrapping up.
+   */
+  dmh_control( DMH_END_DIGEST );
 }
 
 void pkgRepository::GetPackageList( pkgXmlNode *catalogue )
@@ -182,6 +259,7 @@ pkgXmlNode *pkgXmlDocument::BindRepositories( bool force_update )
     /* Sanity check passed...
      * Walk the XML data tree, selecting "repository" specifications...
      */
+    pkgRepository::Reset();
     pkgXmlNode *repository = dbase->FindFirstAssociate( repository_key );
     while( repository != NULL )
     {
@@ -190,18 +268,25 @@ pkgXmlNode *pkgXmlDocument::BindRepositories( bool force_update )
       pkgRepository client( this, dbase, repository, force_update );
       pkgXmlNode *catalogue = repository->FindFirstAssociate( package_list_key );
       if( catalogue == NULL )
-       /*
-        * This repository specification doesn't identify any named
+      {
+       /* This repository specification doesn't identify any named
         * package list, so try the default, (which is named to match
         * the XML key name for the "package-list" element)...
         */
+       pkgRepository::IncrementTotal();
        client.GetPackageList( package_list_key );
-
+      }
       else
-       /* At least one package list catalogue is specified; load it,
+      { /* At least one package list catalogue is specified; load it,
         * and any others which are explicitly identified...
         */
+       pkgXmlNode *ref = catalogue;
+       do { pkgRepository::IncrementTotal();
+            ref = ref->FindNextAssociate( package_list_key );
+          } while( ref != NULL );
+
        client.GetPackageList( catalogue );
+      }
 
       /* Similarly, a complete distribution may draw from an arbitrary set
        * of distinct repositories; move on, to process the next repository