*
* $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
{
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()
{
* 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()
{
* 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 )
{
* (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 )
{
* 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.
{
/* 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.
*/
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 };
*/
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* );
{
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 )
}
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...
*/
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.
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.
*/
*/
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,
/* 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.
{
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
/* 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
# 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 */