commit 7d5622a714f002a09878d888280ed329440fd1c2 Author: Nathan Fisher Date: Sat Feb 10 00:48:59 2024 -0500 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38088da --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +test/output/ +test/* +!test/*.c +!test/Makefile +*.o +*.a +*.so +*.so.* +*.core diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..98409b3 --- /dev/null +++ b/Makefile @@ -0,0 +1,91 @@ +# _,.---._ .-._ .--.-. ,--.--------. +# _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\ +# /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./ +# |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \ +# |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \ +# |==|,| | -|==| , '=' |==| - _ | |==|- | +# |==| '=' /\==\ - ,_ /|==| /\ , | |==|, | +# |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/ +# `-.`.____.' `--`--'' `--`./ `--` `--`--` +# _ __ ,---. .-._ .=-.-. _,.----. +# .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \ +# /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-' +# |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | . +# |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \ +# |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , | +# |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. / +# /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-' +# `--`---' `--` `--`./ `--``--`-` +# +# @(#)Copyright (c) 2024, Nathan D. Fisher. +# +# This is free software. It comes with NO WARRANTY. +# Permission to use, modify and distribute this source code +# is granted subject to the following conditions. +# 1/ that the above copyright notice and this notice +# are preserved in all copies and that due credit be given +# to the author. +# 2/ that any changes to this code are clearly commented +# as such so that the author does not get blamed for bugs +# other than his own. +# + +include config.mk + +.SUFFIXES: +.SUFFIXES: .o .c + +CFLAGS += -Wall -Werror +CFLAGS += -Iinclude +CFLAGS += -I../libepoch/include +CFLAGS += -fPIC +LIBS += ../libepoch/libepoch.a + +hdrs += include/semver.h + +srcs += semver.c + +objs = $(srcs:.c=.o) + +all: shared static + +shared: libsemver.so + +static: libsemver.a + +$(srcs): $(hdrs) + +$(binsrc): $(hdrs) $(srcs) + +libsemver.a: $(objs) + $(AR) rcs $@ $? + +libsemver.so: $(objs) + $(CC) -shared -o $@ $? $(LIBS) + +install: install_include install_shared install_static + +install_include: include/semver.h + @[ -d $(includedir) ] || install -d $(includedir) + install -m644 include/semver.h $(includedir)/ + +install_static: libsemver.a + @[ -d $(libdir) ] || install -d $(libdir) + install -m644 libhaggis.a $(libdir)/ + +install_shared: libsemver.so + @[ -d $(libdir) ] || install -d $(libdir) + install -m755 libhaggis.so $(libdir)/ + +test: libsemver.a + $(MAKE) -C test + +testclean: + $(MAKE) -C test clean + +clean: + rm -rf *.a *.so *.o + $(MAKE) -C test clean + +.PHONY: all shared static clean install install_include \ + install_static install_shared testclean test diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..cf42cad --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,5 @@ +-I +include +-I +../libepoch/include + diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..e69de29 diff --git a/include/semver.h b/include/semver.h new file mode 100644 index 0000000..28adb68 --- /dev/null +++ b/include/semver.h @@ -0,0 +1,93 @@ +#include "epoch.h" +#include + +#define u128 __uint128_t + +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; + +typedef enum { + Simple, + Rapid, + SemVer, + Extended, +} VersionKindTag; + +typedef struct { + char hash[7]; + DateTime dt; +} GitRevision; + +typedef enum { + Alpha, + Beta, + ReleaseCandidate, + GitRev, + PRNone, +} PreReleaseTag; + +typedef enum { + any, + arm, + arm64, + loongson, + mips32, + mips64, + powerepc, + powerpc64, + riscv64, + s390x, + sparc, + sparc64, + x86, + x86_64, +} Arch; + +typedef struct { + VersionKindTag vk_tag; + union { + __Simple simple; + __Rapid rapid; + __SemVer semver; + __Extended extended; + } vk_data; + PreReleaseTag pr_tag; + union { + uint16_t alpha; + uint16_t beta; + uint16_t rc; + GitRevision *git; + } pr_data; + Arch arch; +} Version; + +typedef enum { + CompGreater, + CompEqual, + CompLess, + CompNone, +} Comparison; + +u128 u128FromVersion(Version *self); +Comparison compareVersion(Version *self, Version *other); +int parseVersion(Version *self, const char *s); +char *versionToString(Version *self); diff --git a/semver.c b/semver.c new file mode 100644 index 0000000..40f5d24 --- /dev/null +++ b/semver.c @@ -0,0 +1,80 @@ +#include "semver.h" + +u128 u128FromVersion(Version *self) { + u128 out = 0; + uint16_t pre = 0, mask = 03777; + uint64_t major, minor, patch, build; + int64_t ts; + + switch (self->vk_tag) { + case Simple: + out |= ((u128)self->vk_data.simple.major << (64 + 52)); + break; + case Rapid: + major = (uint64_t)self->vk_data.rapid.major << 52; + minor = (uint64_t)self->vk_data.rapid.minor << 40; + out = (u128)(major | minor) << 64; + break; + case SemVer: + major = (uint64_t)self->vk_data.semver.major << 52; + minor = (uint64_t)self->vk_data.semver.minor << 40; + patch = (uint64_t)self->vk_data.semver.patch << 28; + out = (u128)(major | minor | patch) << 64; + break; + case Extended: + major = (uint64_t)self->vk_data.extended.major << 52; + minor = (uint64_t)self->vk_data.extended.minor << 40; + patch = (uint64_t)self->vk_data.extended.patch << 28; + build = (uint64_t)self->vk_data.extended.build << 16; + out = (u128)(major | minor | patch | build) << 64; + break; + default: + break; + } + switch (self->pr_tag) { + case Alpha: + out |= ((u128)010000 << 64); + pre = self->pr_data.alpha & mask; + out |= ((u128)pre << 64); + break; + case Beta: + out |= ((u128)020000 << 64); + pre = self->pr_data.beta & mask; + out |= ((u128)pre << 64); + break; + case ReleaseCandidate: + out |= ((u128)040000 << 64); + pre = self->pr_data.rc & mask; + out |= ((u128)pre << 64); + break; + case GitRev: + out |= ((u128)01000 << 64); + ts = dateTimeGetTimestamp(&self->pr_data.git->dt); + out |= (u128)ts; + break; + case PRNone: + out |= ((u128)0100000 << 64); + break; + default: + break; + } + return out; +} + +Comparison compareVersion(Version *self, Version *other) { + u128 a, b; + + if (self->arch != other->arch) + return CompNone; + a = u128FromVersion(self); + b = u128FromVersion(other); + if (a < b) + return CompLess; + else if (a == b) + return CompEqual; + else if (a > b) + return CompGreater; + else + return CompNone; +} + diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..1b492c1 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,110 @@ +# _,.---._ .-._ .--.-. ,--.--------. +# _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\ +# /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./ +# |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \ +# |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \ +# |==|,| | -|==| , '=' |==| - _ | |==|- | +# |==| '=' /\==\ - ,_ /|==| /\ , | |==|, | +# |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/ +# `-.`.____.' `--`--'' `--`./ `--` `--`--` +# _ __ ,---. .-._ .=-.-. _,.----. +# .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \ +# /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-' +# |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | . +# |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \ +# |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , | +# |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. / +# /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-' +# `--`---' `--` `--`./ `--``--`-` +# +# @(#)Copyright (c) 2023, Nathan D. Fisher. +# +# This is free software. It comes with NO WARRANTY. +# Permission to use, modify and distribute this source code +# is granted subject to the following conditions. +# 1/ that the above copyright notice and this notice +# are preserved in all copies and that due credit be given +# to the author. +# 2/ that any changes to this code are clearly commented +# as such so that the author does not get blamed for bugs +# other than his own. +# + +include ../config.mk + +CFLAGS += -I../include +LDLIBS += ../libhaggis.a +LDLIBS += $(LIBS) + +tests += store_u16 +tests += load_u16 +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 }' + +.PHONY: test +test: $(tests) output + @echo -e "\n\t=== \e[0;33mRunning $(total) tests\e[0m ===\n" + @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: + @ [-d $@ ] 2>/dev/null || install -d $@ + +.PHONY: clean +clean: + rm -rf $(tests) output/*