This source file includes following definitions.
- swap_prereleases
- versioncmp
#include "cache.h"
#include "string-list.h"
#define S_N 0x0
#define S_I 0x3
#define S_F 0x6
#define S_Z 0x9
#define CMP 2
#define LEN 3
static const struct string_list *prereleases;
static int initialized;
static int swap_prereleases(const void *p1_,
const void *p2_,
int *diff)
{
const char *p1 = p1_;
const char *p2 = p2_;
int i, i1 = -1, i2 = -1;
for (i = 0; i < prereleases->nr; i++) {
const char *suffix = prereleases->items[i].string;
if (i1 == -1 && starts_with(p1, suffix))
i1 = i;
if (i2 == -1 && starts_with(p2, suffix))
i2 = i;
}
if (i1 == -1 && i2 == -1)
return 0;
if (i1 >= 0 && i2 >= 0)
*diff = i1 - i2;
else if (i1 >= 0)
*diff = -1;
else
*diff = 1;
return 1;
}
int versioncmp(const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
unsigned char c1, c2;
int state, diff;
static const uint8_t next_state[] = {
S_N, S_I, S_Z,
S_N, S_I, S_I,
S_N, S_F, S_F,
S_N, S_F, S_Z
};
static const int8_t result_type[] = {
CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN,
CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP
};
if (p1 == p2)
return 0;
c1 = *p1++;
c2 = *p2++;
state = S_N + ((c1 == '0') + (isdigit (c1) != 0));
while ((diff = c1 - c2) == 0) {
if (c1 == '\0')
return diff;
state = next_state[state];
c1 = *p1++;
c2 = *p2++;
state += (c1 == '0') + (isdigit (c1) != 0);
}
if (!initialized) {
initialized = 1;
prereleases = git_config_get_value_multi("versionsort.prereleasesuffix");
}
if (prereleases && swap_prereleases(p1 - 1, p2 - 1, &diff))
return diff;
state = result_type[state * 3 + (((c2 == '0') + (isdigit (c2) != 0)))];
switch (state) {
case CMP:
return diff;
case LEN:
while (isdigit (*p1++))
if (!isdigit (*p2++))
return 1;
return isdigit (*p2) ? -1 : diff;
default:
return state;
}
}