OSDN Git Service

Add XML database bindings and preliminary action executive for CLI.
[mingw/mingw-get.git] / src / pkgspec.cpp
1 /*
2  * pkgspec.cpp
3  *
4  * $Id$
5  *
6  * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7  * Copyright (C) 2009, MinGW Project
8  *
9  *
10  * Implementation for the "pkgTarName" class, as declared in header
11  * file "pkginfo.h".
12  *
13  *
14  * This is free software.  Permission is granted to copy, modify and
15  * redistribute this software, under the provisions of the GNU General
16  * Public License, Version 3, (or, at your option, any later version),
17  * as published by the Free Software Foundation; see the file COPYING
18  * for licensing details.
19  *
20  * Note, in particular, that this software is provided "as is", in the
21  * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
22  * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
23  * PARTICULAR PURPOSE.  Under no circumstances will the author, or the
24  * MinGW Project, accept liability for any damages, however caused,
25  * arising from the use of this software.
26  *
27  */
28 #include "pkginfo.h"
29 #include "vercmp.h"
30
31 #include <string.h>
32
33 /* Constructors...
34  */
35 pkgSpecs::pkgSpecs( const char *tarname )
36 {
37   /* Parse the given tarball name, storing its constituent element
38    * decomposition within the class' local "pkginfo" array structure.
39    */
40   content = get_pkginfo( tarname ? tarname : "", specs );
41 }
42
43 pkgSpecs::pkgSpecs( pkgXmlNode *release )
44 {
45   /* Retrieve the "tarname" from an XML "release" specification,
46    * then construct the "pkgSpecs" as if it were specified directly.
47    */
48   const char *tarname = release ? release->GetPropVal( "tarname", NULL ) : NULL;
49   content = get_pkginfo( tarname ? tarname : "", specs );
50 }
51
52 /* Copy constructor...
53  */
54 static
55 void *clone_specs( char *content, pkginfo_t const src, pkginfo_t dst )
56 {
57   /* Local helper function performs a deep copy of the "content" buffer,
58    * and assigns the "specs" pointers to refer to it; this is the action
59    * required to implement the copy constructor, and it is also used by
60    * the assignment operator implentation.
61    */
62   char *rtn;
63   int count = PACKAGE_TAG_COUNT;
64
65   /* Find the last allocated pointer in the source "specs" list; this
66    * tells us where to find the last string in the "content" buffer...
67    */
68   while( (count > 0) && (src[--count] == NULL) )
69     ;
70
71   /* ...whence we may compute the size of the buffer, and allocate
72    * a new buffer, into which to copy the data.
73    */
74   count = src[count] + strlen( src[count] ) - content;
75   if( (rtn = (char *)(malloc( count + 1))) != NULL )
76   {
77     /* On successful buffer allocation, copy the data,
78      * then walk the list of pointers...
79      */
80     rtn = (char *)(memcpy( rtn, content, count ));
81     for( count = 0; count < PACKAGE_TAG_COUNT; ++count )
82     {
83       if( src[count] == NULL )
84         /*
85          * ...propagating NULL pointers "as are"...
86          */
87         dst[count] = NULL;
88
89       else
90         /* ...and non-NULL adjusted, as necessary,
91          * to point into the copied data buffer...
92          */
93         dst[count] = (char *)(rtn) + (src[count] - content);
94     }
95   }
96   /* ...ultimately, returning the base address of the new buffer.
97    */
98   return (void *)(rtn);
99 }
100 /* Formal implementation of the copy constructor...
101  */
102 pkgSpecs::pkgSpecs( const pkgSpecs& src )
103 {
104   /* ...requires no more than a call to the local helper function.
105    */
106   content = clone_specs( (char *)(src.content), src.specs, specs );
107 }
108
109 /* Assignment operator...
110  */
111 pkgSpecs& pkgSpecs::operator=( const pkgSpecs& rhs )
112 {
113   /* Provided the lhs and rhs represent distinct objects...
114    */
115   if( this != &rhs )
116   {
117     /* ...this is much the same as the copy constructor, except that,
118      * while the constructor is guaranteed to be creating a new object,
119      * assignment may be replacing an existing lhs object; this will
120      * own a dynamically allocated data buffer, which must be freed,
121      * to avoid leaking memory.
122      */
123     free( content );
124     content = clone_specs( (char *)(rhs.content), rhs.specs, specs );
125   }
126   return *this;
127 }
128
129 /* Destructor...
130  */
131 pkgSpecs::~pkgSpecs()
132 {
133   /* Need to free the dynamic memory associated with the "specs" array,
134    * and in which the actual tarname decomposition is stored.
135    */
136   free( content );
137 }
138
139 /* Comparison operators...
140  */
141 static inline
142 pkgVersionInfo version( pkgSpecs& pkg )
143 {
144   /* Local helper, to construct package version descriptors
145    * for use in version comparison operator implementations.
146    */
147   return pkgVersionInfo( pkg.GetPackageVersion(), pkg.GetPackageBuild() );
148 }
149
150 bool pkgSpecs::operator<( pkgSpecs& rhs )
151 {
152   /* Check if the given package release is less recent, as indicated
153    * by its version and build date/serial number, than another.
154    */
155   return version( *this ) < version( rhs );
156 }
157
158 bool pkgSpecs::operator<=( pkgSpecs& rhs )
159 {
160   /* Check if the given package release is no more recent, as indicated
161    * by its version and build date/serial number, than another.
162    */
163   return version( *this ) <= version( rhs );
164 }
165
166 bool pkgSpecs::operator>=( pkgSpecs& rhs )
167 {
168   /* Check if the given package release is no less recent, as indicated
169    * by its version and build date/serial number, than another.
170    */
171   return version( *this ) >= version( rhs );
172 }
173
174 bool pkgSpecs::operator>( pkgSpecs& rhs )
175 {
176   /* Check if the given package release is more recent, as indicated
177    * by its version and build date/serial number, than another.
178    */
179   return version( *this ) > version( rhs );
180 }
181
182 /* $RCSfile$: end of file */