Compare commits
10 commits
0f1c0a755f
...
5d3d4658f5
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5d3d4658f5 | ||
![]() |
a59c411138 | ||
58c62d5d8a | |||
![]() |
5a640234c3 | ||
![]() |
d3f4aa04f3 | ||
0003f3678e | |||
9eeb0660e4 | |||
c2b926daf0 | |||
ea728b2487 | |||
![]() |
d798c5e56a |
14 changed files with 520 additions and 125 deletions
3
Makefile
3
Makefile
|
@ -83,12 +83,11 @@ install_shared: lib$(libname).so
|
|||
test: lib$(libname).a
|
||||
$(MAKE) -C test
|
||||
|
||||
testclean:
|
||||
testclean: clean
|
||||
$(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
|
||||
|
|
12
config.mk
12
config.mk
|
@ -0,0 +1,12 @@
|
|||
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/libepoch
|
||||
# We need an `echo` program that doesn't screw with terminal escape sequences.
|
||||
# This only matters if /bin/sh is a symlink to dash, as the echo builtin in dash
|
||||
# will screw with them and pass them as printed characters.
|
||||
ECHO = /bin/echo
|
||||
|
152
datetime.c
152
datetime.c
|
@ -1,5 +1,151 @@
|
|||
#include "epoch.h"
|
||||
/* _,.---._ .-._ .--.-. ,--.--------.
|
||||
* _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
* /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
* |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
* |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
* |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
* |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
* |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
* `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
* _ __ ,---. .-._ .=-.-. _,.----.
|
||||
* .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
* /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
* |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
* |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
* |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
* |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
* /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
* `--`---' `--` `--`./ `--``--`-`
|
||||
*
|
||||
* @(#)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.
|
||||
*/
|
||||
|
||||
int32_t dateTimeGetYear(DateTime *dt) {
|
||||
return dt->year.year;
|
||||
#include "epoch.h"
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
int32_t dateTimeGetYear(DateTime *self) {
|
||||
return self->year.year;
|
||||
}
|
||||
|
||||
int64_t dateTimeGetTimestampNaive(DateTime *self) {
|
||||
int64_t seconds = 0;
|
||||
Year year = (Year){ .tag = normalYear, .year = 1970 };
|
||||
Month month = January;
|
||||
int32_t oldyear = yearGetInner(&self->year);
|
||||
|
||||
if (oldyear < 1970) {
|
||||
while (yearGetInner(&year) > oldyear) {
|
||||
yearDecrement(&year);
|
||||
seconds -= yearGetSeconds(&year);
|
||||
}
|
||||
} else if (oldyear > 1970) {
|
||||
while (yearGetInner(&year) < oldyear) {
|
||||
seconds += yearGetSeconds(&year);
|
||||
yearIncrement(&year);
|
||||
}
|
||||
}
|
||||
while (month < self->month) {
|
||||
seconds += monthGetSeconds(month, &self->year);
|
||||
monthIncrement(&month);
|
||||
}
|
||||
seconds += ((int64_t)self->day - 1) * SECONDS_PER_DAY;
|
||||
seconds += (int64_t)self->hour * SECONDS_PER_HOUR;
|
||||
seconds += (int64_t)self->minute * 60;
|
||||
seconds += (int64_t)self->second;
|
||||
return seconds;
|
||||
}
|
||||
|
||||
int64_t dateTimeGetTimestamp(DateTime *self) {
|
||||
int64_t seconds = dateTimeGetTimestampNaive(self);
|
||||
seconds += timezoneAsSeconds(&self->zone);
|
||||
return seconds;
|
||||
}
|
||||
|
||||
void dateTimeGetTimespec(DateTime *self, struct timespec * ts) {
|
||||
ts->tv_nsec = self->nanoseconds;
|
||||
ts->tv_sec = (time_t)dateTimeGetTimestamp(self);
|
||||
}
|
||||
|
||||
Weekday dateTimeGetWeekday(DateTime *self) {
|
||||
int64_t ts = dateTimeGetTimestampNaive(self);
|
||||
ts /= SECONDS_PER_DAY;
|
||||
return ts % 7;
|
||||
}
|
||||
|
||||
void dateTimeFromTimestampParts(DateTime *self, int64_t seconds, int64_t nanoseconds) {
|
||||
int ret = 0;
|
||||
|
||||
self->nanoseconds = nanoseconds;
|
||||
self->zone.tag = UTC;
|
||||
if (seconds < 0) {
|
||||
yearNew(&self->year, 1969);
|
||||
while (seconds < yearGetSeconds(&self->year)) {
|
||||
seconds += yearGetSeconds(&self->year);
|
||||
yearDecrement(&self->year);
|
||||
}
|
||||
self->month = December;
|
||||
while (ret == 0) {
|
||||
if (-seconds < monthGetSeconds(self->month, &self->year)) break;
|
||||
seconds += monthGetSeconds(self->month, &self->year);
|
||||
ret = monthDecrement(&self->month);
|
||||
}
|
||||
ret = 0;
|
||||
self->day = monthGetDays(self->month, &self->year);
|
||||
while (self->day > 0 && seconds < -SECONDS_PER_DAY) {
|
||||
seconds += SECONDS_PER_DAY;
|
||||
self->day -=1;
|
||||
}
|
||||
self->hour = 23;
|
||||
while (self->hour > 0 && seconds < -SECONDS_PER_HOUR) {
|
||||
seconds += SECONDS_PER_HOUR;
|
||||
self->hour -= 1;
|
||||
}
|
||||
self->minute = 59;
|
||||
while (self->minute > 0 && seconds < -60) {
|
||||
seconds += 60;
|
||||
self->minute -= 1;
|
||||
}
|
||||
self->second = seconds + 60;
|
||||
} else if (seconds > 0) {
|
||||
yearNew(&self->year, 1970);
|
||||
while (yearGetSeconds(&self->year) < seconds) {
|
||||
seconds -= yearGetSeconds(&self->year);
|
||||
yearIncrement(&self->year);
|
||||
}
|
||||
self->month = January;
|
||||
while (ret == 0 && monthGetSeconds(self->month, &self->year) < seconds) {
|
||||
seconds -= (int64_t)monthGetSeconds(self->month, &self->year);
|
||||
ret = monthIncrement(&self->month);
|
||||
}
|
||||
self->day = seconds / SECONDS_PER_DAY + 1;
|
||||
seconds %= SECONDS_PER_DAY;
|
||||
self->hour = seconds / SECONDS_PER_HOUR;
|
||||
seconds %= SECONDS_PER_HOUR;
|
||||
self->minute = seconds / 60;
|
||||
seconds %= 60;
|
||||
self->second = seconds;
|
||||
} else {
|
||||
yearNew(&self->year, 1970);
|
||||
self->month = January;
|
||||
self->day = 1;
|
||||
self->hour = 0;
|
||||
self->minute = 0;
|
||||
self->second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void dateTimeFromTimespec(DateTime *self, struct timespec *ts) {
|
||||
dateTimeFromTimestampParts(self, ts->tv_sec, ts->tv_nsec);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,44 @@
|
|||
/* _,.---._ .-._ .--.-. ,--.--------.
|
||||
* _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
* /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
* |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
* |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
* |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
* |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
* |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
* `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
* _ __ ,---. .-._ .=-.-. _,.----.
|
||||
* .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
* /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
* |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
* |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
* |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
* |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
* /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
* `--`---' `--` `--`./ `--``--`-`
|
||||
*
|
||||
* @(#)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.
|
||||
*/
|
||||
|
||||
#ifndef LIBEPOCH_H
|
||||
#define LIBEPOCH_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SECONDS_PER_MINUTE 60
|
||||
#define SECONDS_PER_HOUR 60 * 60
|
||||
#define SECONDS_PER_DAY 60 * 60 * 24
|
||||
#define SECONDS_PER_HOUR 3600
|
||||
#define SECONDS_PER_DAY 86400
|
||||
|
||||
typedef enum {
|
||||
normalYear,
|
||||
|
@ -70,7 +103,7 @@ typedef struct {
|
|||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint8_t second;
|
||||
int64_t microseconds;
|
||||
int64_t nanoseconds;
|
||||
TimeZone zone;
|
||||
} DateTime;
|
||||
|
||||
|
@ -81,29 +114,40 @@ typedef enum {
|
|||
HourPrecision,
|
||||
MinutePrecision,
|
||||
SecondPrecision,
|
||||
MicrosecondPrecision,
|
||||
NanoSecondPrecision,
|
||||
} datetimePrecision;
|
||||
|
||||
void yearNew(Year *year, int32_t inner);
|
||||
uint16_t yearGetDays(Year *year);
|
||||
int64_t yearGetSeconds(Year *year);
|
||||
int32_t yearGetInner(Year *year);
|
||||
void yearIncrement(Year *year);
|
||||
void yearDecrement(Year *year);
|
||||
void yearNew (Year *self, int32_t inner);
|
||||
uint16_t yearGetDays (Year *self);
|
||||
int64_t yearGetSeconds (Year *self);
|
||||
int32_t yearGetInner (Year *self);
|
||||
void yearIncrement (Year *self);
|
||||
void yearDecrement (Year *self);
|
||||
|
||||
uint8_t monthGetDays(Month month, Year *year);
|
||||
uint32_t monthGetSeconds(Month month, Year *year);
|
||||
int monthIncrement(Month *month);
|
||||
int monthDecrement(Month *month);
|
||||
const char* monthName(Month month);
|
||||
const char* monthAbbr(Month month);
|
||||
int parseMonth(const char *s);
|
||||
uint8_t monthGetDays (Month self, Year *year);
|
||||
uint32_t monthGetSeconds (Month self, Year *year);
|
||||
int monthIncrement (Month *self);
|
||||
int monthDecrement (Month *self);
|
||||
const char* monthName (Month self);
|
||||
const char* monthAbbr (Month self);
|
||||
int parseMonth (const char *s);
|
||||
|
||||
const char* weekdayName(Weekday day);
|
||||
const char* weekdayAbbr(Weekday day);
|
||||
int parseWeekday(const char *s);
|
||||
const char* weekdayName (Weekday self);
|
||||
const char* weekdayAbbr (Weekday self);
|
||||
int parseWeekday (const char *s);
|
||||
|
||||
int offsetNew(TzOffset *offs, offsetSign sign, uint8_t hours, uint8_t minutes);
|
||||
void printTz(TimeZone *zone);
|
||||
int offsetNew (TzOffset *self, offsetSign sign,
|
||||
uint8_t hours, uint8_t minutes);
|
||||
void printTz (TimeZone *self);
|
||||
int64_t timezoneAsSeconds (TimeZone *self);
|
||||
|
||||
int32_t dateTimeGetYear (DateTime *self);
|
||||
int64_t dateTimeGetTimestampNaive (DateTime *self);
|
||||
int64_t dateTimeGetTimestamp (DateTime *self);
|
||||
void dateTimeGetTimespec (DateTime *self, struct timespec *ts);
|
||||
Weekday dateTimeGetWeekday (DateTime *self);
|
||||
void dateTimeFromTimestampParts (DateTime *self, int64_t seconds,
|
||||
int64_t nanoseconds);
|
||||
void dateTimeFromTimespec (DateTime *self, struct timespec *ts);
|
||||
|
||||
#endif // !LIBEPOCH_H
|
||||
|
|
60
month.c
60
month.c
|
@ -1,11 +1,43 @@
|
|||
/* _,.---._ .-._ .--.-. ,--.--------.
|
||||
* _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
* /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
* |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
* |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
* |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
* |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
* |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
* `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
* _ __ ,---. .-._ .=-.-. _,.----.
|
||||
* .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
* /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
* |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
* |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
* |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
* |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
* /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
* `--`---' `--` `--`./ `--``--`-`
|
||||
*
|
||||
* @(#)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 <stdint.h>
|
||||
#include <stddef.h> // NULL
|
||||
#include <string.h> // memcmp
|
||||
#include <strings.h>
|
||||
#include "epoch.h"
|
||||
|
||||
uint8_t monthGetDays(Month month, Year *year) {
|
||||
switch (month) {
|
||||
uint8_t monthGetDays(Month self, Year *year) {
|
||||
switch (self) {
|
||||
case January:
|
||||
case March:
|
||||
case May:
|
||||
|
@ -26,23 +58,23 @@ uint8_t monthGetDays(Month month, Year *year) {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t monthGetSeconds(Month month, Year *year) {
|
||||
return (int64_t)monthGetDays(month, year) * SECONDS_PER_DAY;
|
||||
uint32_t monthGetSeconds(Month self, Year *year) {
|
||||
return (int64_t)monthGetDays(self, year) * SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
int monthIncrement(Month *month) {
|
||||
if (*month == December)
|
||||
int monthIncrement(Month *self) {
|
||||
if (*self == December)
|
||||
return 1;
|
||||
else
|
||||
*month += 1;
|
||||
*self += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int monthDecrement(Month *month) {
|
||||
if (*month == January)
|
||||
int monthDecrement(Month *self) {
|
||||
if (*self == January)
|
||||
return 1;
|
||||
else
|
||||
*month -= 1;
|
||||
*self -= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -51,12 +83,12 @@ const char *MonthNames[] = { "January", "February", "March", "April", "May", "Ju
|
|||
const char *MonthAbbrs[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
|
||||
"Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
const char* monthName(Month month) {
|
||||
return MonthNames[month - 1];
|
||||
const char* monthName(Month self) {
|
||||
return MonthNames[self - 1];
|
||||
}
|
||||
|
||||
const char* monthAbbr(Month month) {
|
||||
return MonthAbbrs[month - 1];
|
||||
const char* monthAbbr(Month self) {
|
||||
return MonthAbbrs[self - 1];
|
||||
}
|
||||
|
||||
int parseMonth(const char *s) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
# /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
# `--`---' `--` `--`./ `--``--`-`
|
||||
#
|
||||
# @(#)Copyright (c) 2023, Nathan D. Fisher.
|
||||
# @(#)Copyright (c) 2024, Nathan D. Fisher.
|
||||
#
|
||||
# This is free software. It comes with NO WARRANTY.
|
||||
# Permission to use, modify and distribute this source code
|
||||
|
@ -33,74 +33,19 @@
|
|||
include ../config.mk
|
||||
|
||||
CFLAGS += -I../include
|
||||
LDLIBS += ../libhaggis.a
|
||||
LDLIBS += ../libepoch.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
|
||||
tests += dt2ts
|
||||
tests += dt2timespec
|
||||
tests += dtfromtimespec
|
||||
tests += parsemonth
|
||||
|
||||
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
|
||||
test: $(tests) runner output
|
||||
./runner $(tests)
|
||||
|
||||
output:
|
||||
@ [-d $@ ] 2>/dev/null || install -d $@
|
||||
|
|
23
test/dt2timespec.c
Normal file
23
test/dt2timespec.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "epoch.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
DateTime dt;
|
||||
struct timespec ts;
|
||||
|
||||
int main() {
|
||||
dt.zone.tag = UTC;
|
||||
yearNew(&dt.year, 2024);
|
||||
dt.month = February;
|
||||
dt.day = 6;
|
||||
dt.hour = 9;
|
||||
dt.minute = 28;
|
||||
dt.second = 42;
|
||||
dt.nanoseconds = 42;
|
||||
dateTimeGetTimespec(&dt, &ts);
|
||||
assert(ts.tv_sec == 1707211722);
|
||||
assert(ts.tv_nsec == 42);
|
||||
|
||||
return 0;
|
||||
}
|
21
test/dt2ts.c
Normal file
21
test/dt2ts.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "epoch.h"
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
DateTime dt;
|
||||
int64_t ts;
|
||||
|
||||
int main() {
|
||||
dt.zone.tag = UTC;
|
||||
yearNew(&dt.year, 2024);
|
||||
dt.month = February;
|
||||
dt.day = 6;
|
||||
dt.hour = 9;
|
||||
dt.minute = 28;
|
||||
dt.second = 42;
|
||||
dt.nanoseconds = 42;
|
||||
ts = dateTimeGetTimestamp(&dt);
|
||||
assert(ts == 1707211722);
|
||||
|
||||
return 0;
|
||||
}
|
21
test/dtfromtimespec.c
Normal file
21
test/dtfromtimespec.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "epoch.h"
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
int main() {
|
||||
struct timespec ts;
|
||||
DateTime dt;
|
||||
|
||||
ts.tv_nsec = 42;
|
||||
ts.tv_sec = 1706571482;
|
||||
dateTimeFromTimespec(&dt, &ts);
|
||||
assert(dt.year.year == 2024);
|
||||
assert(dt.month == January);
|
||||
assert(dt.day == 29);
|
||||
assert(dt.hour == 23);
|
||||
assert(dt.minute == 38);
|
||||
assert(dt.second == 02);
|
||||
assert(dt.nanoseconds == 42);
|
||||
assert(dt.zone.tag == UTC);
|
||||
return 0;
|
||||
}
|
11
test/parsemonth.c
Normal file
11
test/parsemonth.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "epoch.h"
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
Month m = parseMonth("February");
|
||||
assert(m == February);
|
||||
m = parseMonth("nov");
|
||||
assert(m == November);
|
||||
m = parseMonth("MARCH");
|
||||
assert(m == March);
|
||||
}
|
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;
|
||||
}
|
32
weekday.c
32
weekday.c
|
@ -1,3 +1,35 @@
|
|||
/* _,.---._ .-._ .--.-. ,--.--------.
|
||||
* _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
* /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
* |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
* |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
* |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
* |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
* |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
* `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
* _ __ ,---. .-._ .=-.-. _,.----.
|
||||
* .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
* /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
* |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
* |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
* |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
* |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
* /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
* `--`---' `--` `--`./ `--``--`-`
|
||||
*
|
||||
* @(#)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 "epoch.h"
|
||||
#include <strings.h>
|
||||
|
||||
|
|
72
year.c
72
year.c
|
@ -1,16 +1,48 @@
|
|||
/* _,.---._ .-._ .--.-. ,--.--------.
|
||||
* _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
* /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
* |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
* |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
* |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
* |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
* |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
* `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
* _ __ ,---. .-._ .=-.-. _,.----.
|
||||
* .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
* /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
* |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
* |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
* |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
* |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
* /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
* `--`---' `--` `--`./ `--``--`-`
|
||||
*
|
||||
* @(#)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 <stdint.h>
|
||||
#include "epoch.h"
|
||||
|
||||
void yearNew(Year *year, int32_t inner) {
|
||||
year->year = inner;
|
||||
void yearNew(Year *self, int32_t inner) {
|
||||
self->year = inner;
|
||||
if (inner % 4 == 0 && (inner % 100 != 0 || inner % 400 == 0))
|
||||
year->tag = leapYear;
|
||||
self->tag = leapYear;
|
||||
else
|
||||
year->tag = normalYear;
|
||||
self->tag = normalYear;
|
||||
}
|
||||
|
||||
uint16_t yearGetDays(Year *year) {
|
||||
switch (year->tag) {
|
||||
uint16_t yearGetDays(Year *self) {
|
||||
switch (self->tag) {
|
||||
case normalYear:
|
||||
return 365;
|
||||
case leapYear:
|
||||
|
@ -20,26 +52,26 @@ uint16_t yearGetDays(Year *year) {
|
|||
}
|
||||
}
|
||||
|
||||
int64_t yearGetSeconds(Year *year) {
|
||||
return (int64_t)yearGetDays(year) * SECONDS_PER_DAY;
|
||||
int64_t yearGetSeconds(Year *self) {
|
||||
return (int64_t)yearGetDays(self) * SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
int32_t yearGetInner(Year *year) {
|
||||
return year->year;
|
||||
int32_t yearGetInner(Year *self) {
|
||||
return self->year;
|
||||
}
|
||||
|
||||
void yearIncrement(Year *year) {
|
||||
year->year += 1;
|
||||
if (year->year % 4 == 0 && (year->year % 100 != 0 || year->year % 400 == 0))
|
||||
year->tag = leapYear;
|
||||
void yearIncrement(Year *self) {
|
||||
self->year += 1;
|
||||
if (self->year % 4 == 0 && (self->year % 100 != 0 || self->year % 400 == 0))
|
||||
self->tag = leapYear;
|
||||
else
|
||||
year->tag = normalYear;
|
||||
self->tag = normalYear;
|
||||
}
|
||||
|
||||
void yearDecrement(Year *year) {
|
||||
year->year -= 1;
|
||||
if (year->year % 4 == 0 && (year->year % 100 != 0 || year->year % 400 == 0))
|
||||
year->tag = leapYear;
|
||||
void yearDecrement(Year *self) {
|
||||
self->year -= 1;
|
||||
if (self->year % 4 == 0 && (self->year % 100 != 0 || self->year % 400 == 0))
|
||||
self->tag = leapYear;
|
||||
else
|
||||
year->tag = normalYear;
|
||||
self->tag = normalYear;
|
||||
}
|
||||
|
|
32
zone.c
32
zone.c
|
@ -1,3 +1,35 @@
|
|||
/* _,.---._ .-._ .--.-. ,--.--------.
|
||||
* _,..---._ ,-.' , - `. /==/ \ .-._/==/ //==/, - , -\
|
||||
* /==/, - \ /==/_, , - \|==|, \/ /, |==\ -\\==\.-. - ,-./
|
||||
* |==| _ _\==| .=. |==|- \| | \==\- \`--`\==\- \
|
||||
* |==| .=. |==|_ : ;=: - |==| , | -| `--`-' \==\_ \
|
||||
* |==|,| | -|==| , '=' |==| - _ | |==|- |
|
||||
* |==| '=' /\==\ - ,_ /|==| /\ , | |==|, |
|
||||
* |==|-, _`/ '.='. - .' /==/, | |- | /==/ -/
|
||||
* `-.`.____.' `--`--'' `--`./ `--` `--`--`
|
||||
* _ __ ,---. .-._ .=-.-. _,.----.
|
||||
* .-`.' ,`..--.' \ /==/ \ .-._ /==/_ /.' .' - \
|
||||
* /==/, - \==\-/\ \ |==|, \/ /, /==|, |/==/ , ,-'
|
||||
* |==| _ .=. /==/-|_\ | |==|- \| ||==| ||==|- | .
|
||||
* |==| , '=',\==\, - \ |==| , | -||==|- ||==|_ `-' \
|
||||
* |==|- '..'/==/ - ,| |==| - _ ||==| ,||==| _ , |
|
||||
* |==|, | /==/- /\ - \|==| /\ , ||==|- |\==\. /
|
||||
* /==/ - | \==\ _.\=\.-'/==/, | |- |/==/. / `-.`.___.-'
|
||||
* `--`---' `--` `--`./ `--``--`-`
|
||||
*
|
||||
* @(#)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 "epoch.h"
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
|
Loading…
Add table
Reference in a new issue