worldspawn/include/dpkdeps.h

92 lines
1.9 KiB
C++

#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