vercmp.c 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * vercmp.c - comparison of version numbers
  4. *
  5. * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
  6. *
  7. * This is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2,
  10. * or (at your option) any later version.
  11. *
  12. * This is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public
  18. * License along with dpkg; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <ctype.h>
  22. #include <string.h>
  23. #include <config.h>
  24. #include <dpkg.h>
  25. #include <dpkg-db.h>
  26. #include "parsedump.h"
  27. int epochsdiffer(const struct versionrevision *a,
  28. const struct versionrevision *b) {
  29. return a->epoch != b->epoch;
  30. }
  31. static int verrevcmp(const char *ival, const char *iref) {
  32. static char empty[] = "";
  33. int vc, rc;
  34. long vl, rl;
  35. char *vp, *rp;
  36. char *val, *ref;
  37. memcpy(&val,&ival,sizeof(char*));
  38. memcpy(&ref,&iref,sizeof(char*));
  39. if (!val) val= empty;
  40. if (!ref) ref= empty;
  41. for (;;) {
  42. vp= val; while (*vp && !isdigit(*vp)) vp++;
  43. rp= ref; while (*rp && !isdigit(*rp)) rp++;
  44. for (;;) {
  45. vc= val == vp ? 0 : *val++;
  46. rc= ref == rp ? 0 : *ref++;
  47. if (!rc && !vc) break;
  48. if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
  49. if (rc && !isalpha(rc)) rc += 256;
  50. if (vc != rc) return vc - rc;
  51. }
  52. val= vp;
  53. ref= rp;
  54. vl=0; if (isdigit(*vp)) vl= strtol(val,&val,10);
  55. rl=0; if (isdigit(*rp)) rl= strtol(ref,&ref,10);
  56. if (vl != rl) return vl - rl;
  57. if (!*val && !*ref) return 0;
  58. if (!*val) return -1;
  59. if (!*ref) return +1;
  60. }
  61. }
  62. int versioncompare(const struct versionrevision *version,
  63. const struct versionrevision *refversion) {
  64. int r;
  65. if (version->epoch > refversion->epoch) return 1;
  66. if (version->epoch < refversion->epoch) return -1;
  67. r= verrevcmp(version->version,refversion->version); if (r) return r;
  68. return verrevcmp(version->revision,refversion->revision);
  69. }
  70. int versionsatisfied3(const struct versionrevision *it,
  71. const struct versionrevision *ref,
  72. enum depverrel verrel) {
  73. int r;
  74. if (verrel == dvr_none) return 1;
  75. r= versioncompare(it,ref);
  76. switch (verrel) {
  77. case dvr_earlierequal: return r <= 0;
  78. case dvr_laterequal: return r >= 0;
  79. case dvr_earlierstrict: return r < 0;
  80. case dvr_laterstrict: return r > 0;
  81. case dvr_exact: return r == 0;
  82. default: internerr("unknown verrel");
  83. }
  84. return 0;
  85. }
  86. int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
  87. return versionsatisfied3(&it->version,&against->version,against->verrel);
  88. }