OSDN Git Service

Eliminate invalid comparisons of "this" with nullptr.
[mingw/mingw-get.git] / src / pkgbase.h
index 39a810b..e87c0df 100644 (file)
@@ -4,8 +4,8 @@
  *
  * $Id$
  *
- * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
- * Copyright (C) 2009, 2010, 2011, MinGW Project
+ * Written by Keith Marshall <keith@users.osdn.me>
+ * Copyright (C) 2009-2013, 2020, MinGW.org Project
  *
  *
  * Public interface for the package directory management routines;
  * arising from the use of this software.
  *
  */
+#include "pkgimpl.h"
+#if IMPLEMENTATION_LEVEL == PACKAGE_BASE_COMPONENT
 #define PKGBASE_H  1
 
 #include <tinyxml.h>
 #include <tinystr.h>
 
-#ifndef EXTERN_C
-# ifdef __cplusplus
-#  define EXTERN_C extern "C"
-# else
-#  define EXTERN_C
-# endif
-#endif
-
-/* Adopt sensible defaults for matching subsystem and file names...
+/* Define an API for registering environment variables.
  */
-#ifdef _WIN32
-  /*
-   * The MS-Windows file system is intrinsically case insensitive,
-   * so we prefer to match both subsystem and file names in a case
-   * insensitive manner...
-   */
-# ifndef CASE_INSENSITIVE_SUBSYSTEMS
-#  define CASE_INSENSITIVE_SUBSYSTEMS  1
-# endif
-# ifndef CASE_INSENSITIVE_FILESYSTEM
-#  define CASE_INSENSITIVE_FILESYSTEM  1
-# endif
-  /*
-   * The preferred name for MS-Windows' case insensitive string
-   * matching function, equivalent to POSIX strcasecmp().
-   */
-# define strcasecmp  stricmp
-#else
-  /* On other systems, we prefer to adopt case sensitive matching
-   * strategies for subsystem and file names.
-   */
-# ifndef CASE_INSENSITIVE_SUBSYSTEMS
-#  define CASE_INSENSITIVE_SUBSYSTEMS  0
-# endif
-# ifndef CASE_INSENSITIVE_FILESYSTEM
-#  define CASE_INSENSITIVE_FILESYSTEM  0
-# endif
-#endif
+EXTERN_C int pkgPutEnv( int, char* );
 
+#define PKG_PUTENV_DIRSEP_MSW          (0x01)
+#define PKG_PUTENV_DIRSEP_POSIX        (0x02)
+#define PKG_PUTENV_SCAN_VARNAME        (0x04)
+#define PKG_PUTENV_NAME_TOUPPER        (0x08)
+
+#define PKG_PUTENV_FLAGS_MASK          (0x0F)
+
+/* Begin class declarations.
+ */
 class pkgSpecs;
+class pkgDirectory;
+
+class pkgProgressMeter
+{
+  /* An abstract base class, from which the controller class
+   * for a progress meter dialogue window may be derived.
+   */
+  public:
+    virtual void SetValue( int ) = 0;
+    virtual void SetRange( int, int ) = 0;
+    virtual int Annotate( const char *, ... ) = 0;
+};
 
 class pkgXmlNode : public TiXmlElement
 {
@@ -86,24 +74,20 @@ class pkgXmlNode : public TiXmlElement
     inline pkgXmlNode( const pkgXmlNode& src ):TiXmlElement( src ){}
 
     /* Accessors...
-     *
-     * Note that tinyxml is generally careless about checking for
-     * possible dereferencing of NULL pointers; thus, many of these
-     * wrappers include appropriate checks, to prevent this.
      */
     inline const char* GetName()
     {
       /* Retrieve the identifying name of the XML tag;
        * tinyxml calls this the element "value"...
        */
-      return this ? Value() : NULL;
+      return Value();
     }
     inline pkgXmlNode* GetParent()
     {
       /* wxXmlNode provides this equivalant of tinyxml's
        * Parent() method.
        */
-      return this ? (pkgXmlNode*)(Parent()) : NULL;
+      return (pkgXmlNode*)(Parent());
     }
     inline pkgXmlNode* GetChildren()
     {
@@ -111,7 +95,7 @@ class pkgXmlNode : public TiXmlElement
        * the children of an element; it is equivalent to the
        * FirstChild() method in tinyxml's arsenal.
        */
-      return this ? (pkgXmlNode*)(FirstChild()) : NULL;
+      return (pkgXmlNode*)(FirstChild());
     }
     inline pkgXmlNode* GetNext()
     {
@@ -119,7 +103,7 @@ class pkgXmlNode : public TiXmlElement
        * of an element, after the first found by GetChildren();
        * it is equivalent to tinyxml's NextSibling().
        */
-      return this ? (pkgXmlNode*)(NextSibling()) : NULL;
+      return (pkgXmlNode*)(NextSibling());
     }
     inline const char* GetPropVal( const char* name, const char* subst )
     {
@@ -127,15 +111,16 @@ class pkgXmlNode : public TiXmlElement
        * (which substitutes default "subst" text for an omitted property),
        * but it may be trivially emulated, using the Attribute() method.
        */
-      const char* retval = this ? Attribute( name ) : subst;
-      return retval ? retval : subst;
+      const char *retval;
+      if( (retval = Attribute( name )) == NULL ) return subst;
+      return retval;
     }
     inline pkgXmlNode* AddChild( TiXmlNode *child )
     {
       /* This is wxXmlNode's method for adding a child node, it is
        * equivalent to tinyxml's LinkEndChild() method.
        */
-      return this ? (pkgXmlNode*)(LinkEndChild( child )) : NULL;
+      return (pkgXmlNode*)(LinkEndChild( child ));
     }
     inline bool DeleteChild( pkgXmlNode *child )
     {
@@ -144,7 +129,7 @@ class pkgXmlNode : public TiXmlElement
        * simply use the RemoveChild method here, where for wxXmlNode, we
        * would use RemoveChild followed by `delete child'.
        */
-      return this ? RemoveChild( child ) : false;
+      return RemoveChild( child );
     }
 
     /* Additional methods specific to the application.
@@ -153,22 +138,38 @@ class pkgXmlNode : public TiXmlElement
     {
       /* Convenience method to retrieve a pointer to the document root.
        */
-      return this ? (pkgXmlNode*)(GetDocument()->RootElement()) : NULL;
+      return (pkgXmlNode*)(GetDocument()->RootElement());
     }
     inline bool IsElementOfType( const char* tagname )
     {
       /* Confirm if the owner XML node represents a data element
        * with the specified "tagname".
        */
-      return this ? strcmp( GetName(), tagname ) == 0 : false;
+      return strcmp( GetName(), tagname ) == 0;
     }
 
+    /* Methods to determine which packages should be displayed
+     * in the package list pane of the GUI client.
+     */
+    inline bool IsVisibleGroupMember();
+    inline bool IsVisibleClass();
+
     /* Methods for retrieving the system root management records
      * for a specified installed subsystem.
      */
     pkgXmlNode *GetSysRoot( const char* );
     pkgXmlNode *GetInstallationRecord( const char* );
 
+    /* Methods for mapping the package group hierarchy.
+     */
+    inline void SetPackageGroupHierarchyMapper();
+    inline void MapPackageGroupHierarchy( pkgXmlNode* );
+
+    /* Type definition for a helper function, which must be assigned
+     * to the package group hierarchy mapper, in order to enable it.
+     */
+    typedef void (*GroupHierarchyMapper)( pkgXmlNode*, pkgXmlNode* );
+
     /* The following pair of methods provide an iterator
      * for enumerating the contained nodes, within the owner,
      * which themselves exhibit a specified tagname.
@@ -207,6 +208,11 @@ class pkgXmlNode : public TiXmlElement
      */
     int InvokeScript( int, const char* );
     int DispatchScript( int, const char*, const char*, pkgXmlNode* );
+
+    /* Hook via which the requisite helper function is attached
+     * to the package group hierarchy mapper.
+     */
+    static GroupHierarchyMapper PackageGroupHierarchyMapper;
 };
 
 enum { to_remove = 0, to_install, selection_types };
@@ -240,10 +246,6 @@ class pkgActionItem
      */
     pkgXmlNode* selection[ selection_types ];
 
-    /* Method to display the URI whence a package may be downloaded.
-     */
-    void PrintURI( const char* );
-
     /* Methods for retrieving packages from a distribution server.
      */
     void DownloadArchiveFiles( pkgActionItem* );
@@ -266,13 +268,22 @@ class pkgActionItem
     {
       return flags & required;
     }
+    pkgActionItem* GetReference( pkgXmlNode* );
     pkgActionItem* GetReference( pkgActionItem& );
     pkgActionItem* Schedule( unsigned long, pkgActionItem& );
+    inline pkgActionItem* SuppressRedundantUpgrades( void );
+    inline void CancelScheduledAction( void );
     inline void SetPrimary( pkgActionItem* );
 
+    /* Method to enumerate and identify pending changes,
+     * and/or check for residual unapplied changes.
+     */
+    unsigned long EnumeratePendingActions( int = 0 );
+
     /* Methods for defining the selection criteria for
      * packages to be processed.
      */
+    void ApplyBounds( pkgXmlNode *, const char * );
     pkgXmlNode* SelectIfMostRecentFit( pkgXmlNode* );
     const char* SetRequirements( pkgXmlNode*, pkgSpecs* );
     inline void SelectPackage( pkgXmlNode *pkg, int opt = to_install )
@@ -289,14 +300,31 @@ class pkgActionItem
     }
     void ConfirmInstallationStatus();
 
+    /* Method to display the URI whence a package may be downloaded.
+     */
+    void PrintURI( const char*, int (*)( const char* ) = puts );
+
     /* Methods to download and unpack one or more source archives.
      */
     void GetSourceArchive( pkgXmlNode*, unsigned long );
     void GetScheduledSourceArchives( unsigned long );
 
-    /* Method for processing all scheduled actions.
+    /* Methods for processing all scheduled actions.
+     */
+    void Execute( bool = true );
+    inline void DownloadArchiveFiles( void );
+
+    /* Method to manipulate error trapping, control, and state
+     * flags for the schedule of actions.
+     */
+    void Assert( unsigned long, unsigned long = ~0UL, pkgActionItem* = NULL );
+
+    /* Method to filter actions from an action list: the default is to
+     * clear ALL entries; specify a value of ACTION_MASK for the second
+     * argument, to filter out entries with no assigned action.
      */
-    void Execute();
+    pkgActionItem *Clear( pkgActionItem* = NULL, unsigned long = 0UL );
+    pkgActionItem *Clear( unsigned long mask ){ return Clear( this, mask ); }
 
     /* Destructor...
      */
@@ -311,8 +339,8 @@ class pkgXmlDocument : public TiXmlDocument
   public:
     /* Constructors...
      */
-    inline pkgXmlDocument(){}
-    inline pkgXmlDocument( const char* name )
+    inline pkgXmlDocument(): progress_meter( NULL ){}
+    inline pkgXmlDocument( const char* name ): progress_meter( NULL )
     {
       /* tinyxml has a similar constructor, but unlike wxXmlDocument,
        * it DOES NOT automatically load the document; force it.
@@ -374,6 +402,12 @@ class pkgXmlDocument : public TiXmlDocument
     pkgActionItem* actions;
 
   public:
+    /* Method to interpret user preferences for mingw-get processing
+     * options, which are specified within profile.xml rather than on
+     * the command line.
+     */
+    void EstablishPreferences( const char* = NULL );
+
     /* Method to synchronise the state of the local package manifest
      * with the master copy held on the distribution server.
      */
@@ -398,8 +432,9 @@ class pkgXmlDocument : public TiXmlDocument
      */
     pkgXmlNode* FindPackageByName( const char*, const char* = NULL );
 
-    /* Method to display information about packages.
+    /* Methods to retrieve and display information about packages.
      */
+    pkgDirectory *CatalogueAllPackages();
     void DisplayPackageInfo( int, char** );
 
     /* Method to resolve the dependencies of a specified package,
@@ -410,13 +445,20 @@ class pkgXmlDocument : public TiXmlDocument
 
     /* Methods for compiling a schedule of actions.
      */
-    void Schedule( unsigned long, const char* );
+    pkgActionItem* Schedule( unsigned long = 0UL, const char* = NULL );
     pkgActionItem* Schedule( unsigned long, pkgActionItem&, pkgActionItem* = NULL );
     void RescheduleInstalledPackages( unsigned long );
 
     /* Method to execute a sequence of scheduled actions.
      */
-    inline void ExecuteActions(){ actions->Execute(); }
+    inline void ExecuteActions(){ if( actions ) actions->Execute(); }
+
+    /* Method to clear the list of scheduled actions.
+     */
+    inline pkgActionItem* ClearScheduledActions( unsigned long mask = 0UL )
+    {
+      return actions = actions->Clear( mask );
+    }
 
     /* Methods to retrieve and optionally extract source archives
      * for a collection of dependent packages.
@@ -426,11 +468,40 @@ class pkgXmlDocument : public TiXmlDocument
     {
       actions->GetScheduledSourceArchives( category );
     }
+
+  /* Facility for monitoring of XML document processing operations.
+   */
+  private:
+    pkgProgressMeter* progress_meter;
+
+  public:
+    inline pkgProgressMeter *ProgressMeter( void )
+    {
+      return progress_meter;
+    }
+    inline pkgProgressMeter *AttachProgressMeter( pkgProgressMeter *attachment )
+    {
+      if( progress_meter == NULL )
+       progress_meter = attachment;
+      return progress_meter;
+    }
+    inline void DetachProgressMeter( pkgProgressMeter *attachment )
+    {
+      if( attachment == progress_meter )
+       progress_meter = NULL;
+    }
 };
 
 EXTERN_C const char *xmlfile( const char*, const char* = NULL );
 EXTERN_C int has_keyword( const char*, const char* );
 
+#undef  USES_SAFE_STRCMP
+#define USES_SAFE_STRCMP  1
+
+#endif /* PACKAGE_BASE_COMPONENT */
+
+#if USES_SAFE_STRCMP && ! HAVE_SAFE_STRCMP
+
 typedef int (*strcmp_function)( const char *, const char * );
 
 static inline
@@ -454,6 +525,37 @@ bool safe_strcmp( strcmp_function strcmp, const char *value, const char *proto )
 /* Further safe_strcmp() aliases provide for matching subsystem names,
  * with implementation dependent case sensitivity...
  */
+#ifdef _WIN32
+  /* The MS-Windows file system is intrinsically case insensitive,
+   * so we prefer to match both subsystem and file names in a case
+   * insensitive manner...
+   */
+# ifndef CASE_INSENSITIVE_SUBSYSTEMS
+#  define CASE_INSENSITIVE_SUBSYSTEMS  1
+# endif
+# ifndef CASE_INSENSITIVE_FILESYSTEM
+#  define CASE_INSENSITIVE_FILESYSTEM  1
+# endif
+# ifndef __MINGW32__
+  /* The preferred name for MS-Windows' case insensitive string
+   * matching function, equivalent to POSIX strcasecmp(); MinGW's
+   * string.h will have established this mapping already, so we
+   * don't introduce a (possibly incompatible) redefinition.
+   */
+#  define strcasecmp _stricmp
+# endif
+#else
+  /* On other systems, we prefer to adopt case sensitive matching
+   * strategies for subsystem and file names.
+   */
+# ifndef CASE_INSENSITIVE_SUBSYSTEMS
+#  define CASE_INSENSITIVE_SUBSYSTEMS  0
+# endif
+# ifndef CASE_INSENSITIVE_FILESYSTEM
+#  define CASE_INSENSITIVE_FILESYSTEM  0
+# endif
+#endif
+
 #if CASE_INSENSITIVE_SUBSYSTEMS
 # define subsystem_strcmp( A, B )  safe_strcmp( strcasecmp, (A), (B) )
 #else
@@ -468,4 +570,9 @@ bool safe_strcmp( strcmp_function strcmp, const char *value, const char *proto )
 # define pkg_strcmp( A, B )  safe_strcmp( strcmp, (A), (B) )
 #endif
 
+#undef  HAVE_SAFE_STRCMP
+#define HAVE_SAFE_STRCMP  1
+#endif
+
+
 #endif /* PKGBASE_H: $RCSfile$: end of file */