]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - include/dpkdeps.h
Merge branch 'illwieckz/files'
[xonotic/netradiant.git] / include / dpkdeps.h
diff --git a/include/dpkdeps.h b/include/dpkdeps.h
new file mode 100644 (file)
index 0000000..424fbdc
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __DPKDEPS_H__
+#define __DPKDEPS_H__
+
+#include <locale>
+#include "string/string.h"
+
+// Comparaison function for version numbers
+// Implementation is based on dpkg's version comparison code (verrevcmp() and order())
+// http://anonscm.debian.org/gitweb/?p=dpkg/dpkg.git;a=blob;f=lib/dpkg/version.c;hb=74946af470550a3295e00cf57eca1747215b9311
+inline int char_weight(char c){
+       if (std::isdigit(c))
+               return 0;
+       else if (std::isalpha(c))
+               return c;
+       else if (c == '~')
+               return -1;
+       else if (c)
+               return c + 256;
+       else
+               return 0;
+}
+
+inline int DpkPakVersionCmp(const char* a, const char* b){
+       while (*a || *b) {
+               int firstDiff = 0;
+
+               while ((*a && !std::isdigit(*a)) || (*b && !std::isdigit(*b))) {
+                       int ac = char_weight(*a);
+                       int bc = char_weight(*b);
+
+                       if (ac != bc)
+                               return ac - bc;
+
+                       a++;
+                       b++;
+               }
+
+               while (*a == '0')
+                       a++;
+               while (*b == '0')
+                       b++;
+
+               while (std::isdigit(*a) && std::isdigit(*b)) {
+                       if (firstDiff == 0)
+                               firstDiff = *a - *b;
+                       a++;
+                       b++;
+               }
+
+               if (std::isdigit(*a))
+                       return 1;
+               if (std::isdigit(*b))
+                       return -1;
+               if (firstDiff)
+                       return firstDiff;
+       }
+
+       return false;
+}
+
+// release strings after using
+inline bool DpkReadDepsLine( const char *line, char **pakname, char **pakversion ){
+       const char* c = line;
+       const char* p_name;
+       const char* p_name_end;
+       const char* p_version;
+       const char* p_version_end;
+
+       *pakname = 0;
+       *pakversion = 0;
+
+       while ( std::isspace( *c ) && *c != '\0' ) ++c;
+       p_name = c;
+       while ( !std::isspace( *c ) && *c != '\0' ) ++c;
+       p_name_end = c;
+       while ( std::isspace( *c ) && *c != '\0' ) ++c;
+       p_version = c;
+       while ( !std::isspace( *c ) && *c != '\0' ) ++c;
+       p_version_end = c;
+
+       if ( p_name_end - p_name > 0 ){
+               *pakname = string_clone_range( StringRange( p_name, p_name_end ) );
+       } else return false;
+
+       if ( p_version_end - p_version > 0 ) {
+               *pakversion = string_clone_range( StringRange( p_version, p_version_end ) );
+       }
+       return true;
+}
+
+#endif