evr.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2007-2009, Novell Inc.
00003  *
00004  * This program is licensed under the BSD license, read LICENSE.BSD
00005  * for further information
00006  */
00007 
00008 /*
00009  * evr.c
00010  *
00011  * version compare
00012  */
00013 
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include "evr.h"
00017 #include "pool.h"
00018 
00019 
00020 
00021 #if defined(DEBIAN_SEMANTICS) || defined(MULTI_SEMANTICS)
00022 
00023 #ifdef MULTI_SEMANTICS
00024 # define sat_vercmp sat_vercmp_deb
00025 #endif
00026 
00027 /* debian type version compare */
00028 int
00029 sat_vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
00030 {
00031   int r, c1, c2;
00032   while (1)
00033     {
00034       c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
00035       c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
00036       if ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
00037         {
00038           while (c1 == '0')
00039             c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
00040           while (c2 == '0')
00041             c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
00042           r = 0;
00043           while ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
00044             {
00045               if (!r)
00046                 r = c1 - c2;
00047               c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
00048               c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
00049             }
00050           if (c1 >= '0' && c1 <= '9')
00051             return 1;
00052           if (c2 >= '0' && c2 <= '9')
00053             return -1;
00054           if (r)
00055             return r < 0 ? -1 : 1;
00056         }
00057       c1 = c1 == '~' ? -1 : !c1 || (c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')  ? c1 : c1 + 256;
00058       c2 = c2 == '~' ? -1 : !c2 || (c2 >= '0' && c2 <= '9') || (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z')  ? c2 : c2 + 256;
00059       r = c1 - c2;
00060       if (r)
00061         return r < 0 ? -1 : 1;
00062       if (!c1)
00063         return 0;
00064     }
00065 }
00066 
00067 #ifdef MULTI_SEMANTICS
00068 # undef sat_vercmp
00069 #endif
00070 
00071 #endif
00072 
00073 #if !defined(DEBIAN_SEMANTICS) || defined(MULTI_SEMANTICS)
00074 
00075 /* rpm type version compare */
00076 /* note: the code assumes that *q1 and *q2 are not alphanumeric! */
00077 
00078 int
00079 sat_vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
00080 {
00081   int r = 0;
00082   const char *e1, *e2;
00083 
00084   while (s1 < q1 && s2 < q2)
00085     {
00086       while (s1 < q1 && !(*s1 >= '0' && *s1 <= '9') &&
00087           !(*s1 >= 'a' && *s1 <= 'z') && !(*s1 >= 'A' && *s1 <= 'Z'))
00088         s1++;
00089       while (s2 < q2 && !(*s2 >= '0' && *s2 <= '9') &&
00090           !(*s2 >= 'a' && *s2 <= 'z') && !(*s2 >= 'A' && *s2 <= 'Z'))
00091         s2++;
00092       if ((*s1 >= '0' && *s1 <= '9') || (*s2 >= '0' && *s2 <= '9'))
00093         {
00094           while (*s1 == '0' && s1[1] >= '0' && s1[1] <= '9')
00095             s1++;
00096           while (*s2 == '0' && s2[1] >= '0' && s2[1] <= '9')
00097             s2++;
00098           for (e1 = s1; *e1 >= '0' && *e1 <= '9'; )
00099             e1++;
00100           for (e2 = s2; *e2 >= '0' && *e2 <= '9'; )
00101             e2++;
00102           r = (e1 - s1) - (e2 - s2);
00103           if (!r)
00104             r = strncmp(s1, s2, e1 - s1);
00105           if (r)
00106             return r > 0 ? 1 : -1;
00107         }
00108       else
00109         {
00110           for (e1 = s1; (*e1 >= 'a' && *e1 <= 'z') || (*e1 >= 'A' && *e1 <= 'Z'); )
00111             e1++;
00112           for (e2 = s2; (*e2 >= 'a' && *e2 <= 'z') || (*e2 >= 'A' && *e2 <= 'Z'); )
00113             e2++;
00114           r = (e1 - s1) - (e2 - s2);
00115           if (r > 0)
00116             {
00117               r = strncmp(s1, s2, e2 - s2);
00118               return r >= 0 ? 1 : -1;
00119             }
00120           if (r < 0)
00121             {
00122               r = strncmp(s1, s2, e1 - s1);
00123               return r <= 0 ? -1 : 1;
00124             }
00125           r = strncmp(s1, s2, e1 - s1);
00126           if (r)
00127             return r > 0 ? 1 : -1;
00128         }
00129       s1 = e1;
00130       s2 = e2;
00131     }
00132   return s1 < q1 ? 1 : s2 < q2 ? -1 : 0;
00133 }
00134 
00135 #endif
00136 
00137 #if defined(MULTI_SEMANTICS)
00138 # define sat_vercmp (*(pool->disttype == DISTTYPE_DEB ? &sat_vercmp_deb : &sat_ver##cmp))
00139 #endif
00140 
00141 /* edition (e:v-r) compare */
00142 int
00143 pool_evrcmp_str(const Pool *pool, const char *evr1, const char *evr2, int mode)
00144 {
00145   int r;
00146   const char *s1, *s2;
00147   const char *r1, *r2;
00148 
00149   if (evr1 == evr2)
00150     return 0;
00151 
00152 #if 0
00153   POOL_DEBUG(DEBUG_EVRCMP, "evrcmp %s %s mode=%d\n", evr1, evr2, mode);
00154 #endif
00155   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
00156     ;
00157   for (s2 = evr2; *s2 >= '0' && *s2 <= '9'; s2++)
00158     ;
00159   if (mode == EVRCMP_MATCH && (*evr1 == ':' || *evr2 == ':'))
00160     {
00161       /* empty epoch, skip epoch check */
00162       if (*s1 == ':')
00163         evr1 = s1 + 1;
00164       if (*s2 == ':')
00165         evr2 = s2 + 1;
00166       s1 = evr1;
00167       s2 = evr2;
00168     }
00169   if (s1 == evr1 || *s1 != ':')
00170     s1 = 0;
00171   if (s2 == evr2 || *s2 != ':')
00172     s2 = 0;
00173   if (s1 && s2)
00174     {
00175       r = vercmp(evr1, s1, evr2, s2);
00176       if (r)
00177         return r;
00178       evr1 = s1 + 1;
00179       evr2 = s2 + 1;
00180     }
00181   else if (s1)
00182     {
00183       if (!pool->promoteepoch)
00184         {
00185           while (*evr1 == '0')
00186             evr1++;
00187           if (*evr1 != ':')
00188             return 1;
00189         }
00190       evr1 = s1 + 1;
00191     }
00192   else if (s2)
00193     {
00194       while (*evr2 == '0')
00195         evr2++;
00196       if (*evr2 != ':')
00197         return -1;
00198       evr2 = s2 + 1;
00199     }
00200   for (s1 = evr1, r1 = 0; *s1; s1++)
00201     if (*s1 == '-')
00202       r1 = s1;
00203   for (s2 = evr2, r2 = 0; *s2; s2++)
00204     if (*s2 == '-')
00205       r2 = s2;
00206 
00207   r = 0;
00208   if (mode != EVRCMP_MATCH || (evr1 != (r1 ? r1 : s1) && evr2 != (r2 ? r2 : s2)))
00209     r = vercmp(evr1, r1 ? r1 : s1, evr2, r2 ? r2 : s2);
00210   if (r)
00211     return r;
00212 
00213   if (mode == EVRCMP_COMPARE)
00214     {
00215       if (!r1 && r2)
00216         return -1;
00217       if (r1 && !r2)
00218         return 1;
00219     }
00220   if (mode == EVRCMP_COMPARE_EVONLY)
00221     return 0;
00222   if (r1 && r2)
00223     {
00224       if (s1 != ++r1 && s2 != ++r2)
00225         r = vercmp(r1, s1, r2, s2);
00226     }
00227   return r;
00228 }
00229 
00230 int
00231 pool_evrcmp(const Pool *pool, Id evr1id, Id evr2id, int mode)
00232 {
00233   const char *evr1, *evr2;
00234   if (evr1id == evr2id)
00235     return 0;
00236   evr1 = id2str(pool, evr1id);
00237   evr2 = id2str(pool, evr2id);
00238   return evrcmp_str(pool, evr1, evr2, mode);
00239 }
00240 
00241 int
00242 pool_evrmatch(const Pool *pool, Id evrid, const char *epoch, const char *version, const char *release)
00243 {
00244   const char *evr1;
00245   const char *s1;
00246   const char *r1;
00247   int r;
00248 
00249   evr1 = id2str(pool, evrid);
00250   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
00251     ;
00252   if (s1 != evr1 && *s1 == ':')
00253     {
00254       if (epoch)
00255         {
00256           r = vercmp(evr1, s1, epoch, epoch + strlen(epoch));
00257           if (r)
00258             return r;
00259         }
00260       evr1 = s1 + 1;
00261     }
00262   else if (epoch)
00263     {
00264       while (*epoch == '0')
00265         epoch++;
00266       if (*epoch)
00267         return -1;
00268     }
00269   for (s1 = evr1, r1 = 0; *s1; s1++)
00270     if (*s1 == '-')
00271       r1 = s1;
00272   if (version)
00273     {
00274       r = vercmp(evr1, r1 ? r1 : s1, version, version + strlen(version));
00275       if (r)
00276         return r;
00277     }
00278   if (release)
00279     {
00280       if (!r1)
00281         return -1;
00282       r = vercmp(r1 + 1, s1, release, release + strlen(release));
00283       if (r)
00284         return r;
00285     }
00286   return 0;
00287 }
00288 

Generated on Mon Dec 15 17:56:24 2014 for satsolver by  doxygen 1.5.6