OSDN Git Service

Add CLI support for "update" action.
[mingw/mingw-get.git] / src / pkgbase.h
1 #ifndef PKGBASE_H
2 /*
3  * pkgbase.h
4  *
5  * $Id$
6  *
7  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
8  * Copyright (C) 2009, MinGW Project
9  *
10  *
11  * Public interface for the package directory management routines;
12  * declares the XML data structures, and their associated class APIs,
13  * which are used to describe packages and their interdependencies.
14  *
15  *
16  * This is free software.  Permission is granted to copy, modify and
17  * redistribute this software, under the provisions of the GNU General
18  * Public License, Version 3, (or, at your option, any later version),
19  * as published by the Free Software Foundation; see the file COPYING
20  * for licensing details.
21  *
22  * Note, in particular, that this software is provided "as is", in the
23  * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
24  * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
25  * PARTICULAR PURPOSE.  Under no circumstances will the author, or the
26  * MinGW Project, accept liability for any damages, however caused,
27  * arising from the use of this software.
28  *
29  */
30 #define PKGBASE_H  1
31
32 #include <tinyxml.h>
33 #include <tinystr.h>
34
35 #ifndef EXTERN_C
36 # ifdef __cplusplus
37 #  define EXTERN_C extern "C"
38 # else
39 #  define EXTERN_C
40 # endif
41 #endif
42
43 class pkgXmlNode : public TiXmlElement
44 {
45   /* A minimal emulation of the wxXmlNode class, founded on
46    * the tinyxml implementation of the TiXmlElement class, and
47    * subsequently extended by application specific features.
48    */
49   public:
50     /* Constructors...
51      */
52     inline pkgXmlNode( const char* name ):TiXmlElement( name ){}
53     inline pkgXmlNode( const pkgXmlNode& src ):TiXmlElement( src ){}
54
55     /* Accessors...
56      */
57     inline const char* GetName()
58     {
59       /* Retrieve the identifying name of the XML tag;
60        * tinyxml calls this the element "value"...
61        */
62       return Value();
63     }
64     inline pkgXmlNode* GetParent()
65     {
66       /* wxXmlNode provides this equivalant of tinyxml's
67        * Parent() method.
68        */
69       return (pkgXmlNode*)(Parent());
70     }
71     inline pkgXmlNode* GetChildren()
72     {
73       /* wxXmlNode provides only this one method to access
74        * the children of an element; it is equivalent to the
75        * FirstChild() method in tinyxml's arsenal.
76        */
77       return (pkgXmlNode*)(FirstChild());
78     }
79     inline pkgXmlNode* GetNext()
80     {
81       /* This is wxXmlNode's method for visiting other children
82        * of an element, after the first found by GetChildren();
83        * it is equivalent to tinyxml's NextSibling().
84        */
85       return (pkgXmlNode*)(NextSibling());
86     }
87     inline const char* GetPropVal( const char* name, const char* subst )
88     {
89       /* tinyxml has no direct equivalent for this wxXmlNode method,
90        * (which substitutes default "subst" text for an omitted property),
91        * but it may be trivially emulated, using the Attribute() method.
92        */
93       const char* retval = Attribute( name );
94       return retval ? retval : subst;
95     }
96
97     /* Additional methods specific to the application.
98      */
99     inline bool IsElementOfType( const char* tagname )
100     {
101       /* Confirm if the owner XML node represents a data element
102        * with the specified "tagname".
103        */
104       return strcmp( GetName(), tagname ) == 0;
105     }
106
107     /* The following pair of methods provide an iterator
108      * for enumerating the contained nodes, within the owner,
109      * which themselves exhibit a specified tagname.
110      */
111     pkgXmlNode* FindFirstAssociate( const char* tagname );
112     pkgXmlNode* FindNextAssociate( const char* tagname );
113
114     /* Specific to XML node elements of type "release",
115      * the following pair of methods retrieve the actual name of
116      * the release tarball, and its associated source code tarball,
117      * as they are named on the project download servers.
118      */
119     const char* ArchiveName();
120     const char* SourceArchiveName();
121 };
122
123 class pkgActionItem
124 {
125   /* A class implementing a bi-directionally linked list of
126    * "action" descriptors, which is to be associated with the
127    * pkgXmlDocument class, specifying actions to be performed
128    * on the managed software installation.
129    */
130   private:
131     /* Pointers to predecessor and successor in the linked list
132      * comprising the schedule of action items.
133      */
134     pkgActionItem* prev;
135     pkgActionItem* next;
136
137     /* Flags define the specific action associated with this item.
138      */
139     unsigned long flags;
140
141     /* Criteria for selection of package versions associated with
142      * this action item.
143      */
144     const char* min_wanted;
145     const char* max_wanted;
146
147     /* Pointer to the XML database entry for the package selected
148      * for processing by this action.
149      */
150     pkgXmlNode* selection;
151
152     /* Method for retrieving packages from a distribution server.
153      */
154     void DownloadArchiveFiles( pkgActionItem* );
155
156   public:
157     /* Constructor...
158      */
159     pkgActionItem( pkgActionItem* = NULL, pkgActionItem* = NULL );
160
161     /* Methods for assembling action items into a linked list.
162      */
163     pkgActionItem* Append( pkgActionItem* = NULL );
164     pkgActionItem* Insert( pkgActionItem* = NULL );
165
166     /* Methods for compiling the schedule of actions.
167      */
168     pkgActionItem* GetReference( pkgActionItem& );
169     pkgActionItem* Schedule( unsigned long, pkgActionItem& );
170
171     /* Methods for defining the selection criteria for
172      * packages to be processed.
173      */
174     const char* SetRequirements( pkgXmlNode* );
175     pkgXmlNode* SelectIfMostRecentFit( pkgXmlNode* );
176
177     /* Method specifying where downloaded packages are stored.
178      */
179     const char* ArchivePath();
180
181     /* Method for processing all scheduled actions.
182      */
183     void Execute();
184 };
185
186 class pkgXmlDocument : public TiXmlDocument
187 {
188   /* Minimal emulation of the wxXmlDocument class, founded on
189    * the tinyxml implementation of the TiXmlDocument class.
190    */
191   public:
192     /* Constructors...
193      */
194     inline pkgXmlDocument( const char* name )
195     {
196       /* tinyxml has a similar constructor, but unlike wxXmlDocument,
197        * it DOES NOT automatically load the document; force it.
198        */
199       LoadFile( name );
200
201       /* Always begin with an empty actions list.
202        */
203       actions = NULL;
204     }
205
206     /* Accessors...
207      */
208     inline bool IsOk()
209     {
210       /* tinyxml doesn't have this, but instead provides a complementary
211        * `Error()' indicator, so to simulate `IsOk()'...
212        */
213       return ! Error();
214     }
215     inline pkgXmlNode* GetRoot()
216     {
217       /* This is wxXmlDocument's method for locating the document root;
218        * it is equivalent to tinyxml's RootElement() method.
219        */
220       return (pkgXmlNode *)(RootElement());
221     }
222
223   private:
224     /* Properties specifying the schedule of actions.
225      */
226     unsigned long request;
227     pkgActionItem* actions;
228
229     /* Method to synchronise the state of the local package manifest
230      * with the master copy held on the distribution server.
231      */
232     void SyncRepository( const char*, pkgXmlNode* );
233
234   public:
235     /* Method to merge content from repository-specific package lists
236      * into the central XML package database.
237      */
238     pkgXmlNode* BindRepositories( bool );
239
240     /* Method to locate the XML database entry for a named package.
241      */
242     pkgXmlNode* FindPackageByName( const char*, const char* = NULL );
243
244     /* Method to resolve the dependencies of a specified package,
245      * by walking the chain of references specified by "requires"
246      * elements in the respective package database entries.
247      */
248     void ResolveDependencies( pkgXmlNode*, pkgActionItem* = NULL );
249
250     /* Methods for compiling a schedule of actions.
251      */
252     void Schedule( unsigned long, const char* );
253     pkgActionItem* Schedule( unsigned long, pkgActionItem&, pkgActionItem* = NULL );
254
255     /* Method to execute a sequence of scheduled actions.
256      */
257     inline void ExecuteActions(){ actions->Execute(); }
258 };
259
260 EXTERN_C const char *xmlfile( const char*, const char* = NULL );
261 EXTERN_C int has_keyword( const char*, const char* );
262
263 static inline
264 bool match_if_explicit( const char *value, const char *proto )
265 {
266   /* Helper to compare a pair of "C" strings for equality,
267    * accepting NULL as a match for anything.
268    */
269   return (value == NULL) || (proto == NULL) || (strcmp( value, proto ) == 0);
270 }
271
272 #endif /* PKGBASE_H: $RCSfile$: end of file */