Compare commits
10 commits
e41503ad2e
...
89e9465062
Author | SHA1 | Date | |
---|---|---|---|
![]() |
89e9465062 | ||
3bef2a97c0 | |||
21d15e0d0a | |||
![]() |
2de5098f34 | ||
![]() |
e4fe1c5740 | ||
0606189269 | |||
9451f29440 | |||
fd17180496 | |||
d67b34519f | |||
![]() |
b035e0018a |
10 changed files with 3174 additions and 172 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
doc/
|
||||||
test/output/
|
test/output/
|
||||||
test/*
|
test/*
|
||||||
!test/*.c
|
!test/*.c
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -63,6 +63,9 @@ libsemver.a: $(objs)
|
||||||
libsemver.so: $(objs)
|
libsemver.so: $(objs)
|
||||||
$(CC) -shared -o $@ $? $(LIBS)
|
$(CC) -shared -o $@ $? $(LIBS)
|
||||||
|
|
||||||
|
docs: Doxyfile $(hdrs)
|
||||||
|
doxygen
|
||||||
|
|
||||||
install: install_include install_shared install_static
|
install: install_include install_shared install_static
|
||||||
|
|
||||||
install_include: include/semver.h
|
install_include: include/semver.h
|
||||||
|
@ -80,12 +83,11 @@ install_shared: libsemver.so
|
||||||
test: libsemver.a
|
test: libsemver.a
|
||||||
$(MAKE) -C test
|
$(MAKE) -C test
|
||||||
|
|
||||||
testclean:
|
testclean: clean
|
||||||
$(MAKE) -C test clean
|
$(MAKE) -C test clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.a *.so *.o
|
rm -rf *.a *.so *.o doc
|
||||||
$(MAKE) -C test clean
|
|
||||||
|
|
||||||
.PHONY: all shared static clean install install_include \
|
.PHONY: all shared static clean install install_include \
|
||||||
install_static install_shared testclean test
|
install_static install_shared testclean test
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
bindir = $(DESTDIR)$(PREFIX)/bin
|
||||||
|
includedir = $(DESTDIR)$(PREFIX)/include
|
||||||
|
libdir = $(DESTDIR)$(PREFIX)/lib
|
||||||
|
sharedir = $(DESTDIR)$(PREFIX)/share
|
||||||
|
mandir = $(sharedir)/man
|
||||||
|
docdir = $(sharedir)/doc/libsemver
|
186
include/semver.h
186
include/semver.h
|
@ -1,94 +1,138 @@
|
||||||
|
/** \file semver.h
|
||||||
|
* \brief A Version manipulation library
|
||||||
|
*/
|
||||||
#include "epoch.h"
|
#include "epoch.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define u128 __uint128_t
|
#define u128 __uint128_t ///< A 128 bit unsigned integer
|
||||||
|
#define U12_MAX 4096 ///< The maximum size for semver fields
|
||||||
typedef struct {
|
|
||||||
uint16_t major;
|
|
||||||
} __Simple;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t major;
|
|
||||||
uint16_t minor;
|
|
||||||
} __Rapid;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t major;
|
|
||||||
uint16_t minor;
|
|
||||||
uint16_t patch;
|
|
||||||
} __SemVer;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t major;
|
|
||||||
uint16_t minor;
|
|
||||||
uint16_t patch;
|
|
||||||
uint16_t build;
|
|
||||||
} __Extended;
|
|
||||||
|
|
||||||
|
/** An enumeration representing the type of versioning being used */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Simple,
|
Simple, /**< A single numeric identifier, ie `Firefox 102` */
|
||||||
Rapid,
|
Rapid, /**< A two digit versioning scheme */
|
||||||
SemVer,
|
SemVer, /**< Ordinary `SemVer` versioning, ie `major.minor.patch` */
|
||||||
Extended,
|
Extended, /**< An extended semver type with an extra `build` field */
|
||||||
} VersionKindTag;
|
} VersionKindTag;
|
||||||
|
|
||||||
|
/** Represents a Git version control revision as a pre-release */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char hash[7];
|
char hash[7]; /**< The short form hash of a Git revision */
|
||||||
DateTime dt;
|
DateTime dt; /**< The date and time of the Git revision */
|
||||||
} GitRevision;
|
} GitRevision;
|
||||||
|
|
||||||
|
/** An enumeration representing the type of pre-release, if any */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Alpha,
|
Alpha,
|
||||||
Beta,
|
Beta,
|
||||||
ReleaseCandidate,
|
ReleaseCandidate, /**< An rc prerelease is the last stage in testing prior
|
||||||
GitRev,
|
to a final releas */
|
||||||
PRNone,
|
GitRev, /**< A Git version control revision used as a pre-release
|
||||||
|
`preview` */
|
||||||
|
PRNone, /**< Not a pre-release, or in other words a final release
|
||||||
|
version */
|
||||||
} PreReleaseTag;
|
} PreReleaseTag;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
any,
|
any,
|
||||||
arm,
|
arm,
|
||||||
arm64,
|
arm64,
|
||||||
loongson,
|
loongson,
|
||||||
mips32,
|
mips32,
|
||||||
mips64,
|
mips64,
|
||||||
powerepc,
|
powerepc,
|
||||||
powerpc64,
|
powerpc64,
|
||||||
riscv64,
|
riscv64,
|
||||||
s390x,
|
s390x,
|
||||||
sparc,
|
sparc,
|
||||||
sparc64,
|
sparc64,
|
||||||
x86,
|
x86,
|
||||||
x86_64,
|
x86_64,
|
||||||
} Arch;
|
} Arch;
|
||||||
|
|
||||||
|
/** A tagged union type storing a pre-release in one of several forms */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VersionKindTag vk_tag;
|
PreReleaseTag tag; /**< The tag field specifies the type of pre-release */
|
||||||
union {
|
union {
|
||||||
__Simple simple;
|
uint16_t alpha; /**< The numerical component of an `Alpha` pre-release */
|
||||||
__Rapid rapid;
|
uint16_t beta; /**< The numerical component of a `Beta` pre-release */
|
||||||
__SemVer semver;
|
uint16_t rc; /**< The numerical component of a release candidate */
|
||||||
__Extended extended;
|
GitRevision git; /**< A Git version control revision as a pre-release */
|
||||||
} vk_data;
|
};
|
||||||
PreReleaseTag pr_tag;
|
} PreRelease;
|
||||||
union {
|
|
||||||
uint16_t alpha;
|
/** Stores all relevant information to represent several different styles of versioning */
|
||||||
uint16_t beta;
|
typedef struct {
|
||||||
uint16_t rc;
|
VersionKindTag vk_tag; /**< Specifies the type of versioning scheme being usef */
|
||||||
GitRevision *git;
|
union {
|
||||||
} pr_data;
|
struct {
|
||||||
Arch arch;
|
uint16_t major;
|
||||||
|
} simple; /**< A single number versioning scheme */
|
||||||
|
struct {
|
||||||
|
uint16_t major; /**< The "series" number, representing significant
|
||||||
|
api changes */
|
||||||
|
uint16_t minor; /**< The api number. Any breaking change must bump
|
||||||
|
this number. */
|
||||||
|
} rapid; /**< A two number versioning scheme */
|
||||||
|
struct {
|
||||||
|
uint16_t major; /**< The "series" number, representing significant
|
||||||
|
api changes */
|
||||||
|
uint16_t minor; /**< The api number. Any breaking change must bump
|
||||||
|
this number. */
|
||||||
|
uint16_t patch; /**< Patches and bugfixes that do not break api */
|
||||||
|
} semver; /**< The traditional three digit semver scheme */
|
||||||
|
struct {
|
||||||
|
uint16_t major;
|
||||||
|
uint16_t minor;
|
||||||
|
uint16_t patch;
|
||||||
|
uint16_t build;
|
||||||
|
} extended; /**< An extended semver-like scheme with an extra
|
||||||
|
`build` identifier */
|
||||||
|
};
|
||||||
|
PreRelease pr; /**< The pre-release identifier, if any */
|
||||||
|
Arch arch; /**< The processor architecture this package is
|
||||||
|
compiled for */
|
||||||
} Version;
|
} Version;
|
||||||
|
|
||||||
|
/** Used to order Version structures */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CompGreater,
|
CompGreater,
|
||||||
CompEqual,
|
CompEqual,
|
||||||
CompLess,
|
CompLess,
|
||||||
CompNone,
|
CompNone,
|
||||||
} Comparison;
|
} Comparison;
|
||||||
|
|
||||||
u128 u128FromVersion(Version *self);
|
/**
|
||||||
Comparison compareVersion(Version *self, Version *other);
|
* Creates a 128 bit unsigned integer from the data structure in such a way that
|
||||||
int parseVersion(Version *self, const char *s);
|
* versions can be compared and ordered. The `major` number has it's bits shifted
|
||||||
char *versionToString(Version *self);
|
* by the furthest amount, followed by the `minor` (if it exists) and so on. The
|
||||||
|
* pre-release tag enum members each get their own bit, ordered in such a way that
|
||||||
|
* `PRNone` is considered greater than a release candidate and so on. The least
|
||||||
|
* significant 64 bits are taken up by the Unix timestamp of a git revision, if
|
||||||
|
* this is a Git pre-release
|
||||||
|
* ### Return values
|
||||||
|
* Returns the computed numerical representation
|
||||||
|
* \param self A `Version` struct to be converted
|
||||||
|
*/
|
||||||
|
u128 u128FromVersion(Version *self);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares `self` with `other` for purposes of ordering
|
||||||
|
* ### Return values
|
||||||
|
* Returns a `Comparison` enumeration value.
|
||||||
|
* \param self The first Version to be compared
|
||||||
|
* \param other The Version against which `self` will be compared
|
||||||
|
*/
|
||||||
|
Comparison compareVersion (Version *self, Version *other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a Version from a string
|
||||||
|
* ### Return values
|
||||||
|
* Returns 0 on success
|
||||||
|
* \param self A pointer to a memory region to store this Version structure
|
||||||
|
* \param s The string to be parsed
|
||||||
|
*/
|
||||||
|
int parseVersion (Version *self, const char *s);
|
||||||
|
|
||||||
|
char *versionToString(Version *self);
|
||||||
|
|
||||||
|
|
158
semver.c
158
semver.c
|
@ -13,46 +13,46 @@ u128 u128FromVersion(Version *self) {
|
||||||
|
|
||||||
switch (self->vk_tag) {
|
switch (self->vk_tag) {
|
||||||
case Simple:
|
case Simple:
|
||||||
out |= ((u128)self->vk_data.simple.major << (64 + 52));
|
out |= ((u128)self->simple.major << (64 + 52));
|
||||||
break;
|
break;
|
||||||
case Rapid:
|
case Rapid:
|
||||||
major = (uint64_t)self->vk_data.rapid.major << 52;
|
major = (uint64_t)self->rapid.major << 52;
|
||||||
minor = (uint64_t)self->vk_data.rapid.minor << 40;
|
minor = (uint64_t)self->rapid.minor << 40;
|
||||||
out = (u128)(major | minor) << 64;
|
out = (u128)(major | minor) << 64;
|
||||||
break;
|
break;
|
||||||
case SemVer:
|
case SemVer:
|
||||||
major = (uint64_t)self->vk_data.semver.major << 52;
|
major = (uint64_t)self->semver.major << 52;
|
||||||
minor = (uint64_t)self->vk_data.semver.minor << 40;
|
minor = (uint64_t)self->semver.minor << 40;
|
||||||
patch = (uint64_t)self->vk_data.semver.patch << 28;
|
patch = (uint64_t)self->semver.patch << 28;
|
||||||
out = (u128)(major | minor | patch) << 64;
|
out = (u128)(major | minor | patch) << 64;
|
||||||
break;
|
break;
|
||||||
case Extended:
|
case Extended:
|
||||||
major = (uint64_t)self->vk_data.extended.major << 52;
|
major = (uint64_t)self->extended.major << 52;
|
||||||
minor = (uint64_t)self->vk_data.extended.minor << 40;
|
minor = (uint64_t)self->extended.minor << 40;
|
||||||
patch = (uint64_t)self->vk_data.extended.patch << 28;
|
patch = (uint64_t)self->extended.patch << 28;
|
||||||
build = (uint64_t)self->vk_data.extended.build << 16;
|
build = (uint64_t)self->extended.build << 16;
|
||||||
out = (u128)(major | minor | patch | build) << 64;
|
out = (u128)(major | minor | patch | build) << 64;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (self->pr_tag) {
|
switch (self->pr.tag) {
|
||||||
case Alpha:
|
case Alpha:
|
||||||
out |= ((u128)010000 << 64);
|
out |= ((u128)010000 << 64);
|
||||||
pre = self->pr_data.alpha & mask;
|
pre = self->pr.alpha & mask;
|
||||||
out |= ((u128)pre << 64);
|
out |= ((u128)pre << 64);
|
||||||
break;
|
break;
|
||||||
case Beta:
|
case Beta:
|
||||||
out |= ((u128)020000 << 64);
|
out |= ((u128)020000 << 64);
|
||||||
pre = self->pr_data.beta & mask;
|
pre = self->pr.beta & mask;
|
||||||
out |= ((u128)pre << 64);
|
out |= ((u128)pre << 64);
|
||||||
break;
|
break;
|
||||||
case ReleaseCandidate:
|
case ReleaseCandidate:
|
||||||
out |= ((u128)040000 << 64);
|
out |= ((u128)040000 << 64);
|
||||||
pre = self->pr_data.rc & mask;
|
pre = self->pr.rc & mask;
|
||||||
out |= ((u128)pre << 64);
|
out |= ((u128)pre << 64);
|
||||||
break;
|
break;
|
||||||
case GitRev:
|
case GitRev:
|
||||||
out |= ((u128)01000 << 64);
|
out |= ((u128)01000 << 64);
|
||||||
ts = dateTimeGetTimestamp(&self->pr_data.git->dt);
|
ts = dateTimeGetTimestamp(&self->pr.git.dt);
|
||||||
out |= (u128)ts;
|
out |= (u128)ts;
|
||||||
break;
|
break;
|
||||||
case PRNone:
|
case PRNone:
|
||||||
|
@ -106,6 +106,83 @@ int parseArch(char *s) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t parseU12NonZero(char *vp, long *out) {
|
||||||
|
long val;
|
||||||
|
char *ep;
|
||||||
|
|
||||||
|
if (vp == NULL) {
|
||||||
|
*out = 0;
|
||||||
|
}
|
||||||
|
val = strtol(vp, &ep, 10);
|
||||||
|
if (vp != ep && ep == NULL && val <= U12_MAX && val > 0) {
|
||||||
|
*out = val;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseGitRev(char *vp, GitRevision *git) {
|
||||||
|
char hash[7];
|
||||||
|
int64_t ts;
|
||||||
|
char *hash_str, *ts_str, *ep;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
hash_str = strtok(vp, ".");
|
||||||
|
if (hash_str == NULL) return 1;
|
||||||
|
if (strnlen(hash_str, 8) != 7) return 2;
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
hash[i] = hash_str[i];
|
||||||
|
}
|
||||||
|
ts_str = strtok(NULL, ".");
|
||||||
|
if (ts_str == NULL) return 1;
|
||||||
|
ts = strtoll(ts_str, &ep, 10);
|
||||||
|
if (ts_str == ep || ep != NULL) return 3;
|
||||||
|
if (strtok(NULL, ".") != NULL) return 4;
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
git->hash[i] = hash[i];
|
||||||
|
}
|
||||||
|
dateTimeFromTimestampParts(&git->dt, ts, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parsePreRelease(PreRelease *pr, char *s) {
|
||||||
|
PreReleaseTag tag = PRNone;
|
||||||
|
long val = 0;
|
||||||
|
char v[50];
|
||||||
|
char *vp = (char *)v;
|
||||||
|
ssize_t len = strnlen(s, 52);
|
||||||
|
|
||||||
|
if (len > 50) return 1;
|
||||||
|
memcpy(s, vp, len);
|
||||||
|
if (strncasecmp(s, "alpha", 5) == 0) {
|
||||||
|
tag = Alpha;
|
||||||
|
vp = s + 5;
|
||||||
|
if (parseU12NonZero(vp, &val) != 0)
|
||||||
|
return 1;
|
||||||
|
pr->alpha = (uint16_t)val;
|
||||||
|
} else if (strncasecmp(s, "beta", 4) == 0) {
|
||||||
|
tag = Beta;
|
||||||
|
vp = s + 4;
|
||||||
|
if (parseU12NonZero(vp, &val) != 0)
|
||||||
|
return 1;
|
||||||
|
pr->beta = (uint16_t)val;
|
||||||
|
} else if (strncasecmp(s, "rc", 2) == 0) {
|
||||||
|
tag = ReleaseCandidate;
|
||||||
|
vp = s + 2;
|
||||||
|
if (parseU12NonZero(vp, &val) != 0)
|
||||||
|
return 1;
|
||||||
|
pr->rc = (uint16_t)val;
|
||||||
|
} else if (strncasecmp(s, "git_", 4) == 0) {
|
||||||
|
tag = GitRev;
|
||||||
|
vp = s + 4;
|
||||||
|
if (parseGitRev(vp, &pr->git) != 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pr->tag = tag;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int parseVersion(Version *self, const char *s) {
|
int parseVersion(Version *self, const char *s) {
|
||||||
// todo
|
// todo
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -123,53 +200,62 @@ char *versionToString(Version *self) {
|
||||||
}
|
}
|
||||||
switch (self->vk_tag) {
|
switch (self->vk_tag) {
|
||||||
case Simple:
|
case Simple:
|
||||||
snprintf(buf, 6, "%d", self->vk_data.simple.major);
|
snprintf(buf, 6, "%d", self->simple.major);
|
||||||
break;
|
break;
|
||||||
case Rapid:
|
case Rapid:
|
||||||
snprintf(buf, 13, "%d.%d", self->vk_data.rapid.major, self->vk_data.rapid.minor);
|
snprintf(buf, 13, "%d.%d", self->rapid.major, self->rapid.minor);
|
||||||
break;
|
break;
|
||||||
case SemVer:
|
case SemVer:
|
||||||
snprintf(
|
snprintf(
|
||||||
buf, 20, "%d.%d.%d",
|
buf, 20, "%d.%d.%d",
|
||||||
self->vk_data.semver.major,
|
self->semver.major,
|
||||||
self->vk_data.semver.minor,
|
self->semver.minor,
|
||||||
self->vk_data.semver.patch
|
self->semver.patch
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case Extended:
|
case Extended:
|
||||||
snprintf(
|
snprintf(
|
||||||
buf, 27, "%d.%d.%d.%d",
|
buf, 27, "%d.%d.%d.%d",
|
||||||
self->vk_data.extended.major,
|
self->extended.major,
|
||||||
self->vk_data.extended.minor,
|
self->extended.minor,
|
||||||
self->vk_data.extended.patch,
|
self->extended.patch,
|
||||||
self->vk_data.extended.build
|
self->extended.build
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (self->pr_tag) {
|
switch (self->pr.tag) {
|
||||||
case PRNone:
|
case PRNone:
|
||||||
snprintf(temp, 9, "-%s", archToString(self->arch));
|
snprintf(temp, 9, "-%s", archToString(self->arch));
|
||||||
break;
|
break;
|
||||||
case Alpha:
|
case Alpha:
|
||||||
snprintf(temp, 25, "_alpha%d-%s", self->pr_data.alpha, archToString(self->arch));
|
if (self->pr.alpha == 0)
|
||||||
|
snprintf(temp, 25, "_alpha-%s", archToString(self->arch));
|
||||||
|
else
|
||||||
|
snprintf(temp, 25, "_alpha%d-%s", self->pr.alpha, archToString(self->arch));
|
||||||
break;
|
break;
|
||||||
case Beta:
|
case Beta:
|
||||||
snprintf(temp, 25, "_beta%d-%s", self->pr_data.beta, archToString(self->arch));
|
if (self->pr.beta == 0)
|
||||||
|
snprintf(temp, 25, "_beta-%s", archToString(self->arch));
|
||||||
|
else
|
||||||
|
snprintf(temp, 25, "_beta%d-%s", self->pr.beta, archToString(self->arch));
|
||||||
break;
|
break;
|
||||||
case ReleaseCandidate:
|
case ReleaseCandidate:
|
||||||
snprintf(temp, 25, "_rc%d-%s", self->pr_data.rc, archToString(self->arch));
|
if (self->pr.rc == 0)
|
||||||
|
snprintf(temp, 25, "_rc-%s", archToString(self->arch));
|
||||||
|
else
|
||||||
|
snprintf(temp, 25, "_rc%d-%s", self->pr.rc, archToString(self->arch));
|
||||||
break;
|
break;
|
||||||
case GitRev:
|
case GitRev:
|
||||||
snprintf(
|
snprintf(
|
||||||
temp, 50, "_git_%c%c%c%c%c%c%c.%li-%s",
|
temp, 50, "_git_%c%c%c%c%c%c%c.%li-%s",
|
||||||
self->pr_data.git->hash[0],
|
self->pr.git.hash[0],
|
||||||
self->pr_data.git->hash[1],
|
self->pr.git.hash[1],
|
||||||
self->pr_data.git->hash[2],
|
self->pr.git.hash[2],
|
||||||
self->pr_data.git->hash[3],
|
self->pr.git.hash[3],
|
||||||
self->pr_data.git->hash[4],
|
self->pr.git.hash[4],
|
||||||
self->pr_data.git->hash[5],
|
self->pr.git.hash[5],
|
||||||
self->pr_data.git->hash[6],
|
self->pr.git.hash[6],
|
||||||
dateTimeGetTimestamp(&self->pr_data.git->dt),
|
dateTimeGetTimestamp(&self->pr.git.dt),
|
||||||
archToString(self->arch)
|
archToString(self->arch)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,74 +33,19 @@
|
||||||
include ../config.mk
|
include ../config.mk
|
||||||
|
|
||||||
CFLAGS += -I../include
|
CFLAGS += -I../include
|
||||||
LDLIBS += ../libhaggis.a
|
CFLAGS += -I../../libepoch/include
|
||||||
|
LDLIBS += ../libsemver.a
|
||||||
|
LIBS += ../../libepoch/libepoch.a
|
||||||
LDLIBS += $(LIBS)
|
LDLIBS += $(LIBS)
|
||||||
|
|
||||||
tests += store_u16
|
tests += u128_from_version
|
||||||
tests += load_u16
|
tests += compare
|
||||||
tests += store_u32
|
|
||||||
tests += load_u32
|
|
||||||
tests += store_u64
|
|
||||||
tests += load_u64
|
|
||||||
tests += store_header
|
|
||||||
tests += check_header
|
|
||||||
tests += store_device
|
|
||||||
tests += load_device
|
|
||||||
tests += store_md5
|
|
||||||
tests += load_md5
|
|
||||||
tests += store_sha1
|
|
||||||
tests += load_sha1
|
|
||||||
tests += store_sha256
|
|
||||||
tests += load_sha256
|
|
||||||
tests += init_file_md5
|
|
||||||
tests += init_file_sha1
|
|
||||||
tests += init_file_sha256
|
|
||||||
tests += store_file_md5
|
|
||||||
tests += load_file_md5
|
|
||||||
tests += store_file_sha1
|
|
||||||
tests += load_file_sha1
|
|
||||||
tests += store_file_sha256
|
|
||||||
tests += load_file_sha256
|
|
||||||
tests += fnv1a_hash_inode
|
|
||||||
tests += fnv1a_hash_str
|
|
||||||
tests += linkmap_init
|
|
||||||
tests += linkmap_put
|
|
||||||
tests += create_dir_node
|
|
||||||
tests += create_symlink_node
|
|
||||||
tests += create_fifo_node
|
|
||||||
tests += create_dev_node
|
|
||||||
tests += create_file_node
|
|
||||||
tests += mq_push_pop
|
|
||||||
tests += extract_dev_node
|
|
||||||
tests += extract_dir_node
|
|
||||||
tests += extract_fifo_node
|
|
||||||
tests += extract_file_node
|
|
||||||
tests += extract_symlink_node
|
|
||||||
tests += extract_hardlink_node
|
|
||||||
|
|
||||||
total != echo $(tests) | wc -w | awk '{ print $$1 }'
|
total != echo $(tests) | wc -w | awk '{ print $$1 }'
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: $(tests) output
|
test: $(tests) runner output
|
||||||
@echo -e "\n\t=== \e[0;33mRunning $(total) tests\e[0m ===\n"
|
./runner $(tests)
|
||||||
@idx=1 ; success=0 ; fail=0; skip=0; for t in $(tests) ; \
|
|
||||||
do printf "[%02i/$(total)] %-25s" $${idx} $${t} ; \
|
|
||||||
idx=$$(expr $${idx} + 1) ; \
|
|
||||||
./$${t} ; \
|
|
||||||
retval=$$? ; \
|
|
||||||
if [ $${retval} -eq 0 ] ; \
|
|
||||||
then echo -e '\e[0;32mSuccess\e[0m' ; \
|
|
||||||
success=$$(expr $${success} + 1) ; \
|
|
||||||
elif [ $${retval} -eq 255 ] ; \
|
|
||||||
then echo Skipped ; \
|
|
||||||
skip=$$(expr $${skip} + 1) ; \
|
|
||||||
else echo -e '\e[0;31mFailure\e[0m' ; \
|
|
||||||
fail=$$(expr $${fail} + 1) ; \
|
|
||||||
fi ; done || true ; \
|
|
||||||
if [ $${fail} == 0 ] ; \
|
|
||||||
then echo -e '\nResults: \e[0;32mOk\e[0m.' "$${success} succeeded; $${fail} failed; $${skip} skipped" ; \
|
|
||||||
else echo -e '\nResults: \e[0;31mFAILED\e[0m.' "$${success} succeeded; $${fail} failed; $${skip} skipped" ; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
output:
|
output:
|
||||||
@ [-d $@ ] 2>/dev/null || install -d $@
|
@ [-d $@ ] 2>/dev/null || install -d $@
|
||||||
|
|
31
test/compare.c
Normal file
31
test/compare.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "semver.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Version a, b;
|
||||||
|
|
||||||
|
a.vk_tag = SemVer;
|
||||||
|
a.semver.major = 3;
|
||||||
|
a.semver.minor = 14;
|
||||||
|
a.semver.patch = 0;
|
||||||
|
a.pr.tag = PRNone;
|
||||||
|
a.arch = x86_64;
|
||||||
|
b.vk_tag = Rapid;
|
||||||
|
b.rapid.major = 3;
|
||||||
|
b.rapid.minor = 14;
|
||||||
|
b.pr.tag = PRNone;
|
||||||
|
b.arch = x86_64;
|
||||||
|
assert(compareVersion(&a, &b) == CompEqual);
|
||||||
|
b.pr.tag = Alpha;
|
||||||
|
b.pr.alpha = 1;
|
||||||
|
assert(compareVersion(&a, &b) == CompGreater);
|
||||||
|
a.pr.tag = Beta;
|
||||||
|
a.pr.beta = 2;
|
||||||
|
assert(compareVersion(&a, &b) == CompGreater);
|
||||||
|
b.pr.tag = ReleaseCandidate;
|
||||||
|
b.pr.rc = 1;
|
||||||
|
assert(compareVersion(&a, &b) == CompLess);
|
||||||
|
a.arch = arm64;
|
||||||
|
assert(compareVersion(&a, &b) == CompNone);
|
||||||
|
return 0;
|
||||||
|
}
|
45
test/runner.c
Normal file
45
test/runner.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int i, pass = 0, fail = 0, skip = 0, total, ret, read = 0;
|
||||||
|
FILE *pipe;
|
||||||
|
char cmd[100], output[500];
|
||||||
|
|
||||||
|
total = argc-1;
|
||||||
|
printf("\n\t=== \033[0;33mRunning %i tests\033[0m ===\n", total);
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
snprintf(cmd, 100, "./%s", argv[i]);
|
||||||
|
printf("%-25s", argv[i]);
|
||||||
|
pipe = popen(cmd, "w");
|
||||||
|
read = fread(&output, 1, 500, pipe);
|
||||||
|
ret = pclose(pipe);
|
||||||
|
if (read) {
|
||||||
|
fail++;
|
||||||
|
printf("\033[0;31mFailed\033[0m\n");
|
||||||
|
fprintf(stderr, "%s\n", &output);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (WEXITSTATUS(ret)) {
|
||||||
|
case 0:
|
||||||
|
pass++;
|
||||||
|
printf("\033[0;32mSuccess\033[0m\n");
|
||||||
|
break;
|
||||||
|
case 255:
|
||||||
|
skip++;
|
||||||
|
printf("Skipped\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fail++;
|
||||||
|
printf("\033[0;31mFailed\033[0m\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fail) {
|
||||||
|
printf("\nResults: \033[0;31mFAILED\033[0m %i succeeded; %i failed; %i skipped\n",
|
||||||
|
pass, fail, skip);
|
||||||
|
} else {
|
||||||
|
printf("\nResults: \033[0;32mOk\033[0m %i succeeded; %i failed; %i skipped\n",
|
||||||
|
pass, fail, skip);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
19
test/u128_from_version.c
Normal file
19
test/u128_from_version.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "semver.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Version v;
|
||||||
|
u128 n;
|
||||||
|
uint64_t sn;
|
||||||
|
|
||||||
|
v.vk_tag = SemVer;
|
||||||
|
v.semver.major = 3;
|
||||||
|
v.semver.minor = 14;
|
||||||
|
v.semver.patch = 0;
|
||||||
|
v.pr.tag = PRNone;
|
||||||
|
v.arch = x86_64;
|
||||||
|
n = u128FromVersion(&v);
|
||||||
|
sn = (uint64_t)(n >> 64);
|
||||||
|
assert(sn == 0600340000000100000);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue