All pastes #983331 Raw Edit

Untitled

public cpp v1 · immutable
·published 2008-04-13 08:13 UTC
rendered paste body
// Include Files                                                        /*{{{*/#include <stdlib.h>#include <ctype.h>#include <stdio.h>#include <string.h>                                                                        /*}}}*/#define order(x) ((x) == '~' ? -1    \                : isdigit((x)) ? 0   \                : !(x) ? 0           \                : isalpha((x)) ? (x) \                : (x) + 256)int CmpFragment(const char *A,const char *AEnd,                                     const char *B,const char *BEnd){   if (A >= AEnd && B >= BEnd)      return 0;   if (A >= AEnd)   {      if (*B == '~') return 1;      return -1;   }   if (B >= BEnd)   {      if (*A == '~') return -1;      return 1;   }   /* Iterate over the whole string      What this does is to split the whole string into groups of      numeric and non numeric portions. For instance:         a67bhgs89      Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:         2.7.2-linux-1      Has '2', '.', '7', '.' ,'-linux-','1' */   const char *lhs = A;   const char *rhs = B;   while (lhs != AEnd && rhs != BEnd)   {      int first_diff = 0;      while (lhs != AEnd && rhs != BEnd &&             (!isdigit(*lhs) || !isdigit(*rhs)))      {         int vc = order(*lhs);         int rc = order(*rhs);         if (vc != rc)            return vc - rc;         lhs++; rhs++;      }      while (*lhs == '0')         lhs++;      while (*rhs == '0')         rhs++;      while (isdigit(*lhs) && isdigit(*rhs))      {         if (!first_diff)            first_diff = *lhs - *rhs;         lhs++;         rhs++;      }      if (isdigit(*lhs))         return 1;      if (isdigit(*rhs))         return -1;      if (first_diff)         return first_diff;   }   // The strings must be equal   if (lhs == AEnd && rhs == BEnd)      return 0;   // lhs is shorter   if (lhs == AEnd)   {      if (*rhs == '~') return 1;      return -1;   }   // rhs is shorter   if (rhs == BEnd)   {      if (*lhs == '~') return -1;      return 1;   }   // Shouldnt happen   return 1;}                                                                        /*}}}*/// debVS::CmpVersion - Comparison for versions                          /*{{{*/// ---------------------------------------------------------------------/* This fragments the version into E:V-R triples and compares each    portion separately. */int DoCmpVersion(const char *A,const char *AEnd,                                      const char *B,const char *BEnd){   // Strip off the epoch and compare it    const char *lhs = A;   const char *rhs = B;   for (;lhs != AEnd && *lhs != ':'; lhs++);   for (;rhs != BEnd && *rhs != ':'; rhs++);   if (lhs == AEnd)      lhs = A;   if (rhs == BEnd)      rhs = B;      // Special case: a zero epoch is the same as no epoch,   // so remove it.   if (lhs != A)   {      for (; *A == '0'; ++A);      if (A == lhs)      {         ++A;         ++lhs;      }   }   if (rhs != B)   {      for (; *B == '0'; ++B);      if (B == rhs)      {         ++B;         ++rhs;      }   }   // Compare the epoch   int Res = CmpFragment(A,lhs,B,rhs);   if (Res != 0)      return Res;   // Skip the :   if (lhs != A)      lhs++;   if (rhs != B)      rhs++;      // Find the last -    const char *dlhs = AEnd-1;   const char *drhs = BEnd-1;   for (;dlhs > lhs && *dlhs != '-'; dlhs--);   for (;drhs > rhs && *drhs != '-'; drhs--);   if (!getenv ("BLANKON_UBUNTU_MODE"))    {      if (strstr(dlhs, "blankon"))         for (dlhs--; dlhs > lhs && *dlhs != '-'; dlhs--);      if (strstr(drhs, "blankon"))         for (drhs--; drhs > rhs && *drhs != '-'; drhs--);   }   if (dlhs == lhs)      dlhs = AEnd;   if (drhs == rhs)      drhs = BEnd;      // Compare the main version   Res = CmpFragment(lhs,dlhs,rhs,drhs);   if (Res != 0)      return Res;      // Skip the -   if (dlhs != lhs)      dlhs++;   if (drhs != rhs)      drhs++;   if (getenv ("BLANKON_UBUNTU_MODE"))      return CmpFragment(dlhs,AEnd,drhs,BEnd);        if (dlhs >= AEnd && drhs >= BEnd)      return 0;   if (strstr (dlhs, "blankon") && strstr (drhs, "blankon") == 0)      return 1;   if (strstr (drhs, "blankon") && strstr (dlhs, "blankon") == 0)      return -1;      return CmpFragment(dlhs,AEnd,drhs,BEnd);}                                                                        /*}}}*/int main(int argc, char** argv) {        int res;        char *a = argv[1];        char *b = argv[2];        res = DoCmpVersion(a, a+strlen(a), b, b+strlen(b));        printf("%d\n", res);}