versiontest.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: versiontest.cc,v 1.2 2001/02/20 07:03:18 jgg Exp $
  4. /* ######################################################################
  5. Version Test - Simple program to run through a file and comare versions.
  6. Each version is compared and the result is checked against an expected
  7. result in the file. The format of the file is
  8. a b Res
  9. Where Res is -1, 1, 0. dpkg -D=1 --compare-versions a "<" b can be
  10. used to determine what Res should be. # at the start of the line
  11. is a comment and blank lines are skipped
  12. ##################################################################### */
  13. /*}}}*/
  14. #define APT_COMPATIBILITY 1
  15. #include <system.h>
  16. #include <apt-pkg/error.h>
  17. #include <apt-pkg/version.h>
  18. #include <iostream.h>
  19. #include <fstream.h>
  20. static int verrevcmp(const char *val, const char *ref)
  21. {
  22. int vc, rc;
  23. long vl, rl;
  24. const char *vp, *rp;
  25. if (!val)
  26. val = "";
  27. if (!ref)
  28. ref = "";
  29. for (;;)
  30. {
  31. vp = val;
  32. while (*vp && !isdigit(*vp))
  33. vp++;
  34. rp = ref;
  35. while (*rp && !isdigit(*rp))
  36. rp++;
  37. for (;;)
  38. {
  39. vc= val == vp ? 0 : *val++;
  40. rc= ref == rp ? 0 : *ref++;
  41. if (!rc && !vc)
  42. break;
  43. if (vc && !isalpha(vc))
  44. vc += 256; /* assumes ASCII character set */
  45. if (rc && !isalpha(rc))
  46. rc += 256;
  47. if (vc != rc)
  48. return vc - rc;
  49. }
  50. val = vp;
  51. ref = rp;
  52. vl = 0;
  53. if (isdigit(*vp))
  54. vl = strtol(val,(char**)&val,10);
  55. rl = 0;
  56. if (isdigit(*rp))
  57. rl = strtol(ref,(char**)&ref,10);
  58. if (vl != rl)
  59. return vl - rl;
  60. if (!*val && !*ref)
  61. return 0;
  62. if (!*val)
  63. return -1;
  64. if (!*ref)
  65. return +1;
  66. }
  67. }
  68. #if 0
  69. static int verrevcmp(const char *val, const char *ref)
  70. {
  71. int vc, rc;
  72. long vl, rl;
  73. const char *vp, *rp;
  74. if (!val) val= "";
  75. if (!ref) ref= "";
  76. for (;;)
  77. {
  78. vp= val; while (*vp && !isdigit(*vp) && *vp != '~') vp++;
  79. rp= ref; while (*rp && !isdigit(*rp) && *rp != '~') rp++;
  80. for (;;)
  81. {
  82. vc= val == vp ? 0 : *val++;
  83. rc= ref == rp ? 0 : *ref++;
  84. if (!rc && !vc) break;
  85. if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
  86. if (rc && !isalpha(rc)) rc += 256;
  87. if (vc != rc) return vc - rc;
  88. }
  89. val= vp;
  90. ref= rp;
  91. if (*vp == '~') val++;
  92. if (*rp == '~') ref++;
  93. vl=0; if (isdigit(*val)) vl= strtol(val,(char**)&val,10);
  94. rl=0; if (isdigit(*ref)) rl= strtol(ref,(char**)&ref,10);
  95. if (vl == 0 && rl == 0)
  96. {
  97. if (*vp == '~' && *rp != '~') return -1;
  98. if (*vp != '~' && *rp == '~') return +1;
  99. }
  100. if (*vp == '~')
  101. vl *= -1;
  102. if (*rp == '~')
  103. rl *= -1;
  104. if (vl != rl) return vl - rl;
  105. if (!*val && !*ref) return 0;
  106. if (!*val)
  107. {
  108. if (*ref == '~')
  109. return +1;
  110. else
  111. return -1;
  112. }
  113. if (!*ref)
  114. {
  115. if (*val == '~')
  116. return -1;
  117. else
  118. return +1;
  119. }
  120. }
  121. }
  122. #endif
  123. bool RunTest(const char *File)
  124. {
  125. ifstream F(File,ios::in | ios::nocreate);
  126. if (!F != 0)
  127. return false;
  128. char Buffer[300];
  129. int CurLine = 0;
  130. while (1)
  131. {
  132. F.getline(Buffer,sizeof(Buffer));
  133. CurLine++;
  134. if (F.eof() != 0)
  135. return true;
  136. if (!F != 0)
  137. return _error->Error("Line %u in %s is too long",CurLine,File);
  138. // Comment
  139. if (Buffer[0] == '#' || Buffer[0] == 0)
  140. continue;
  141. // First version
  142. char *I;
  143. char *Start = Buffer;
  144. for (I = Buffer; *I != 0 && *I != ' '; I++);
  145. string A(Start, I - Start);
  146. if (*I == 0)
  147. return _error->Error("Invalid line %u",CurLine);
  148. // Second version
  149. I++;
  150. Start = I;
  151. for (I = Start; *I != 0 && *I != ' '; I++);
  152. string B(Start,I - Start);
  153. if (*I == 0 || I[1] == 0)
  154. return _error->Error("Invalid line %u",CurLine);
  155. // Result
  156. I++;
  157. int Expected = atoi(I);
  158. int Res = pkgVersionCompare(A.c_str(),B.c_str());
  159. int Res2 = verrevcmp(A.c_str(),B.c_str());
  160. cout << "'" << A << "' ? '" << B << "' = " << Res << " (= " << Expected << ") " << Res2 << endl;
  161. if (Res != Expected)
  162. _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected);
  163. // Check the reverse as well
  164. Expected = -1*Expected;
  165. Res = pkgVersionCompare(B.c_str(),A.c_str());
  166. Res2 = verrevcmp(B.c_str(),A.c_str());
  167. cout << "'" << B << "' ? '" << A << "' = " << Res << " (= " << Expected << ") " << Res2 << endl;
  168. if (Res != Expected)
  169. _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected);
  170. }
  171. }
  172. int main(int argc, char *argv[])
  173. {
  174. if (argc <= 1)
  175. {
  176. cerr << "You must specify a test file" << endl;
  177. return 0;
  178. }
  179. RunTest(argv[1]);
  180. // Print any errors or warnings found
  181. if (_error->empty() == false)
  182. {
  183. string Err;
  184. while (_error->empty() == false)
  185. {
  186. bool Type = _error->PopMessage(Err);
  187. if (Type == true)
  188. cout << "E: " << Err << endl;
  189. else
  190. cout << "W: " << Err << endl;
  191. }
  192. return 0;
  193. }
  194. }